ADB-based RIPDPI device/emulator debugging: build/install/launch, logcat filtering, fixture port-forwarding, instrumented tests, crash/ANR triage. Use when debugging on a real device or emulator.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
RIPDPI's own Compose conventions: ViewModel pattern, Route/Screen split, DataStore->StateFlow, RipDpiThemeTokens. Use for how this app does Compose, not generic Compose API questions (see compose).
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
설치 방법 보기설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.
RIPDPI uses Jetpack Compose with Material 3 and a sealed-class navigation system. State flows from DataStore through ViewModels to Composables via StateFlow + collectAsStateWithLifecycle().
Diagnostics UI is a current hotspot in this repo. It layers internal UI models over shared diagnostics contracts, exposes stable automation tags through RipDpiTestTags, and routes callback-style actions such as opening Advanced Settings or candidate-detail sheets through screen-level parameters.
DataStore (proto) -> ViewModel (StateFlow + combine) -> Composable (collectAsStateWithLifecycle)
User action -> ViewModel method -> DataStore.updateData { } or ServiceManager.start/stop
One-shot effects -> Channel<Effect> -> receiveAsFlow() -> LaunchedEffect collector
Routes are defined as a sealed class in app/.../ui/navigation/Route.kt.
Route sealed class with route string, @StringRes titleRes, optional iconRoute.topLevel listRoute.all listcomposable(Route.YourRoute.route) { ... } in RipDpiNavHost.ktnavController.navigate(Route.YourRoute.route) { launchSingleTop = true; restoreState = true }launchSingleTop = true and restoreState = true for all navigationsisTopLevelDestination() routesclass ExampleViewModel(application: Application) : AndroidViewModel(application) {
// State: combine multiple sources into single UI state
val uiState: StateFlow<UiState> = combine(
application.settingsStore.data,
_localState,
) { settings, local -> UiState(/*...*/) }
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000), UiState())
// Effects: one-shot events (navigation, snackbar, permission requests)
private val _effects = Channel<Effect>(Channel.BUFFERED)
val effects = _effects.receiveAsFlow()
// Actions: public methods called by Composables
fun onAction() { viewModelScope.launch { /* ... */ } }
}
SharingStarted.WhileSubscribed(5_000) for all StateFlow exportsAndroidViewModel (not plain ViewModel) when DataStore access neededMutex for thread-safe state transitions (see MainViewModel.toggleService)Channel<Effect> for one-shot UI events, collected via LaunchedEffect// Route composable: connects ViewModel to screen
@Composable
fun ExampleRoute(viewModel: ExampleViewModel, navController: NavController) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
ExampleScreen(uiState = uiState, onAction = viewModel::onAction)
}
// Screen composable: pure UI, no ViewModel reference
@Composable
fun ExampleScreen(uiState: UiState, onAction: () -> Unit) { /* ... */ }
collectAsStateWithLifecycle() (not collectAsState())RipDpiThemeTokens for colors, spacing, typography| ViewModel | Location | Purpose |
|---|---|---|
MainViewModel | activities/MainViewModel.kt | Connection state, VPN/proxy toggle, metrics |
ConfigViewModel | activities/ConfigViewModel.kt | Proxy config presets, draft editing, validation |
SettingsViewModel | activities/SettingsViewModel.kt | App settings, theme, DataStore persistence |
DiagnosticsViewModel | activities/DiagnosticsViewModel.kt | Diagnostics scan orchestration, history, export/share state, and strategy-probe presentation |
activities/DiagnosticsUi* support files instead of recomputing report metadata directly in composables.app/src/main/kotlin/com/poyka/ripdpi/ui/testing/RipDpiTestTags.kt for any new externally exercised UI.onOpenAdvancedSettings, onSelectCandidate, and sheet-dismiss actions through Route/Screen parameters rather than letting deep child composables navigate directly.| Mistake | Fix |
|---|---|
Using collectAsState() | Use collectAsStateWithLifecycle() for lifecycle awareness |
| Passing ViewModel to Screen composable | Pass uiState and callbacks; keep Screen stateless |
| Hardcoding colors/spacing | Use RipDpiThemeTokens and Material 3 theme |
Missing WhileSubscribed(5_000) | Required for proper lifecycle handling in all StateFlow exports |
| Creating ViewModel in Composable | Use viewModel() in Route composable or pass from NavHost |
compose (.agents/skills/compose/SKILL.md):
General Jetpack Compose API reference (guidance docs plus a live-fetch index into the
actual androidx source) and the scored RIPDPI Compose quality audit.
Use for questions about how Compose APIs work internally, correct API usage patterns,
recomposition mechanics, Modifier ordering, side-effects, performance, or accessibility.아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.
로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.
아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.
ADB-based RIPDPI device/emulator debugging: build/install/launch, logcat filtering, fixture port-forwarding, instrumented tests, crash/ANR triage. Use when debugging on a real device or emulator.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
RIPDPI Appium launch-contract reference: start routes and permission/service/data presets. Use when a test launches to the wrong screen or a new automation route is added. General flakiness: appium-test-debug.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
RIPDPI Appium test authoring: page objects, resource-id locators, assertions, wait tiers. Use when writing a new Appium test or page object, or adding coverage for a new screen.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
RIPDPI Appium failure triage: flaky tests, locator/session/wait issues, screenshot and element-tree debugging. Use when an Appium test fails or is flaky.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Add or modify a GitHub Actions job. Use when editing a file under .github/workflows/. Not for running a workflow locally (local-ci-act) or release signing (release-signing).
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Conservative review of end-user legal exposure from diagnostics targets and probe hosts, by jurisdiction. Use when shipping or editing diagnostics target lists, probe hosts, or bootstrap endpoints.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.