一键导入
compose
Jetpack Compose guidance and audit for RIPDPI — state, recomposition, modifiers, navigation, theming, performance, and scored quality reports.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Jetpack Compose guidance and audit for RIPDPI — state, recomposition, modifiers, navigation, theming, performance, and scored quality reports.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Use this skill to generate well-branded interfaces and assets for RIPDPI (an Android-native, Compose-first VPN and DPI-bypass app), either for production or throwaway prototypes/mocks/etc. Contains essential design guidelines, colors, type, fonts, brand-ship icons, and an interactive UI kit of every public composable from the live ui/components tree.
Use when managing the Rust workspace, adding/removing crates, editing workspace dependencies, running cargo nextest/audit/deny, configuring Cargo profiles for Android cross-compilation, debugging Cargo.lock churn, migrating crate edition, or wiring Gradle to cargo via the ripdpi.android.rust-native plugin.
Use when modifying the diagnostics scan pipeline, ScanRequest/ScanReport types, ProbeTask families, ripdpi-monitor-engine / ripdpi-diagnostics-* crates, strategy-probe candidates, the diagnostics catalog (packs/profiles), wire-schema contracts between Rust and Kotlin, DIAGNOSTICS_ENGINE_SCHEMA_VERSION, golden contract tests, or adding a new probe type / profile. Triggers on diagnostics scans, strategy probes, automatic audit, dpi-detector profiles, or anything in core/diagnostics or native/rust/crates/ripdpi-monitor-*.
Android-specific Rust build, verification, and packaging — per-target 16 KiB page alignment, size-optimized release profile, ELF symbol allowlist, .so size budgets, NDK 29 specifics. Use when modifying .cargo/config.toml for Android targets, the workspace [profile.release] / [profile.android-jni] block, or when verifying a built .so before release.
Telemetry and observability discipline for the RIPDPI Android Rust stack — control-plane vs data-plane logging, bounded flume event queues, atomic counters, snapshot polling, readiness callbacks, and deterministic JSON contracts. Use when authoring or modifying telemetry emission code, the bounded event ring, the Kotlin-side telemetry consumer, or any per-packet logging.
Custom detekt rules, DI/privacy/suppression guardrails, detekt.yml configuration, and false-positive triage.
| name | compose |
| description | Jetpack Compose guidance and audit for RIPDPI — state, recomposition, modifiers, navigation, theming, performance, and scored quality reports. |
| user-invokable | true |
| argument-hint | [audit [scope: full|performance|state|side-effects|api] [module: :app|all]] |
Two modes in one skill:
Non-opinionated, practical guidance for writing correct, performant Compose code —
across Android, Desktop, iOS, and Web. Covers Jetpack Compose and Compose Multiplatform.
Backed by analysis of actual source code from androidx/androidx and
JetBrains/compose-multiplatform-core.
When helping with Compose code, follow this checklist:
references/design-to-compose.mdreferences/animation.md for recipesRead the relevant reference file(s) from references/ before answering:
| Topic | Reference File |
|---|---|
@State, remember, mutableStateOf, derivedStateOf, snapshotFlow | references/state-management.md |
| State hoisting decisions (local / hoisted / plain-holder / ViewModel) | references/state-hoisting.md |
| Screen state-holder vs plain UI composable split for previewability/testing | references/state-holder-vs-viewmodel.md |
StateFlow / SharedFlow / Channel modeling, update { }, stateIn placement | references/state-event-flow.md |
| Deferred state reads (provider lambdas, block-form modifiers) for scroll/animation perf | references/deferred-reads.md |
| Structuring composables, slots, extraction, preview | references/view-composition.md |
Slot API design for reusable components (xxxContent: @Composable () -> Unit) | references/slot-api.md |
Modifier ordering, custom modifiers, Modifier.Node | references/modifiers.md |
LaunchedEffect, DisposableEffect, SideEffect, rememberCoroutineScope | references/side-effects.md |
CompositionLocal, LocalContext, LocalDensity, custom locals | references/composition-locals.md |
LazyColumn, LazyRow, LazyGrid, Pager, keys, content types | references/lists-scrolling.md |
NavHost, type-safe routes, deep links, shared element transitions | references/navigation.md |
animate*AsState, AnimatedVisibility, Crossfade, transitions | references/animation.md |
MaterialTheme, ColorScheme, dynamic color, Typography, shapes | references/theming-material3.md |
| Recomposition skipping, stability, baseline profiles, benchmarking | references/performance.md |
| Semantics, content descriptions, traversal order, testing | references/accessibility.md |
| Removed/replaced APIs, migration paths from older Compose versions | references/deprecated-patterns.md |
Styles API (experimental): Style {}, MutableStyleState, Modifier.styleable() | references/styles-experimental.md |
| Figma/screenshot decomposition, design tokens, spacing, modifier ordering | references/design-to-compose.md |
| Production crash patterns, defensive coding, state/performance rules | references/production-crash-playbook.md |
Compose Multiplatform, expect/actual, resources (Res.*), migration | references/multiplatform.md |
| Desktop (Window, Tray, MenuBar), iOS (UIKitView), Web (ComposeViewport) | references/platform-specifics.md |
When referencing Compose internals, point to the exact source file:
// See: compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composer.kt
Compose thinks in three phases: Composition → Layout → Drawing. State reads in each phase only trigger work for that phase and later ones.
Recomposition is frequent and cheap — but only if you help the compiler skip unchanged scopes. Use stable types, avoid allocations in composable bodies.
Modifier order matters. Modifier.padding(16.dp).background(Color.Red) is visually different from Modifier.background(Color.Red).padding(16.dp).
State should live as low as possible and be hoisted only as high as needed. Don't put everything in a ViewModel just because you can.
Side effects exist to bridge Compose's declarative world with imperative APIs. Use the right one for the job — misusing them causes bugs that are hard to trace.
Compose Multiplatform shares the runtime but not the platform. UI code in commonMain is portable. Platform-specific APIs (LocalContext, BackHandler, Window) require expect/actual or conditional source sets.
When you need to verify how something works internally, read references/source-code/index.md. It maps each Compose runtime/UI/Foundation/Material3/Navigation/CMP source file to its upstream URL on androidx/androidx@androidx-main or JetBrains/compose-multiplatform-core@jb-main. Fetch the file directly with WebFetch or gh api.
Two-layer approach:
references/state-management.md)references/source-code/index.md to the upstream fileInvoke when the user asks to audit the Jetpack Compose codebase, review Compose architecture or quality, rate the codebase with scores, or establish a pre-release quality baseline.
Rubric version: v1. Read the active Kotlin and Compose BOM versions from gradle/libs.versions.toml; never reuse versions embedded in an older audit. Determine Strong Skipping behavior from that active Kotlin version and the project compiler configuration.
Four scored categories: Performance, State Management, Side Effects, Composable API Quality.
Out of scope in v1: Material 3 compliance (defer to material-3 skill), accessibility scoring, UI test coverage, CMP-specific rules, Wear OS / TV / Auto / Glance, build performance.
Always return a short chat summary with the overall score, category scores, worst issues, and top fixes. Write a repository report only when the user explicitly requests a persistent artifact; use the path they name, or default to the ignored build/reports/compose/compose-audit-<YYYY-MM-DD>.md.
references/canonical-sources.md. The report template requires a References: line per finding.0-3 scores for repeated or systemic problems, not isolated mistakes.9-10 unless the repo is consistently strong across the category.Before starting the audit:
Read .agents/skills/compose-performance/SKILL.md to absorb the known quick-wins list, existing TrackRecomposition instrumentation, and annotation conventions. Issues already tracked there should appear in "Known Open Items", not as new findings, unless they remain unfixed.
Compiler reports: use ./gradlew :app:compileGithubFullDebugKotlin -Pripdpi.composeReports=true (NOT the init.gradle script). This non-signing compile task writes app/build/compose-reports/ and app/build/compose-metrics/ through ripdpi.android.compose.gradle.kts.
Module scope: :app is the only Compose module. Do not search :core:data, :core:diagnostics, :core:engine, :core:service, or :core:detection for @Composable definitions.
Design system: RipDpiThemeTokens is the project's custom wrapper over MaterialTheme. RipDpiTheme calls MaterialTheme internally — this is correct, not a deviation.
Existing stability setup: The project has app/compose-stability.conf marking external types stable, and @Immutable/@Stable on all UI model classes. Run compiler reports to get the actual skippable% before applying measured ceilings.
:app (app/src/main/kotlin/com/poyka/ripdpi/).Fast-fail check: grep for androidx.compose in build.gradle* or libs.versions.toml, and for setContent { or @Composable under src/.
Identify: Gradle modules, Compose source roots, shared UI/component packages, theme/design-system packages, screen packages, state holder/ViewModel areas, test and preview locations, baseline-profile modules.
Look for: @Composable functions, reusable UI components, screens and routes, ViewModel usage, remember/rememberSaveable/mutableStateOf, collectAsStateWithLifecycle, LaunchedEffect/DisposableEffect/SideEffect, LazyColumn/LazyRow/items.
If subagents are available, parallelize category scans and merge findings.
Primary path:
REPO_ROOT=$(git rev-parse --show-toplevel)
cd "$REPO_ROOT" && ./gradlew :app:compileGithubFullDebugKotlin -Pripdpi.composeReports=true --no-daemon
Use a 600-second timeout.
Collect the reports:
find app/build/compose-reports/ app/build/compose-metrics/ \
\( -name '*-classes.txt' -o -name '*-composables.txt' -o -name '*-composables.csv' -o -name '*-module.json' \)
Extract: unstable classes, non-skippable named composables, module-wide skippability counts. Compute named-only skippability from *-composables.csv (filter isLambda == "0").
Fallback if convention plugin fails:
./gradlew :app:compileGithubFullDebugKotlin \
--init-script .agents/skills/compose/scripts/compose-reports.init.gradle \
--no-daemon --quiet
Output goes to app/build/compose_audit/.
If both fail: proceed with source-inferred findings, set Compiler diagnostics used: no in the report, reduce confidence by one level, and label all stability claims as inferred.
Use the rubric in references/scoring.md and heuristics in references/search-playbook.md.
Performance: expensive work in composition, avoidable recomposition, lazy list keys, bad state-read timing, unstable or overly broad reads, backwards writes.
State Management: hoisting correctness, single source of truth, reusable stateless seams, correct remember vs rememberSaveable, lifecycle-aware observable collection.
Side Effects: side effects incorrectly done in composition, correct effect API choice, effect keys, stale lambda capture, cleanup correctness, lifecycle-aware effect behavior.
Composable API Quality (focus on ui/components/, not every leaf screen): modifier presence and placement, parameter order, explicit over implicit configuration, meaningful defaults, avoiding MutableState<T> parameters in reusable APIs.
Before deducting points: read the file where the smell appears; confirm it's not a false positive; check for compensating patterns elsewhere; distinguish one-off mistakes from systemic patterns; for stability findings, cite the compiler report line as evidence.
| Score | Status |
|---|---|
| 0-3 | fail |
| 4-6 | needs work |
| 7-8 | solid |
| 9-10 | excellent |
Use weights in references/scoring.md to compute the overall score.
Measured ceilings are mandatory. When compiler reports are available, apply the Performance ceiling from references/scoring.md and show the math:
Performance ceiling check:
skippable% = 186/273 = 68.1% -> falls in 50-70% band -> cap at 4
qualitative score: 7
applied score: 4 (ceiling lowered from 7)
Use references/report-template.md. The report must include: overall score, category score table, top critical findings, category-by-category reasoning, evidence file paths, prioritized remediation list, Known Open Items cross-referencing the quick-wins checklist from .agents/skills/compose-performance/SKILL.md, and an optional note to run material-3 if design issues are suspected.
Only write the report when the user requested persistence. Use their explicit destination, or create build/reports/compose/compose-audit-<YYYY-MM-DD>.md; do not add a root-level report by default.
Include: overall score (and delta vs. prior reports), one-line judgment per category with applied ceiling, compiler-report highlights (Strong Skipping on/off, skippable%, unstable shared types), top three actionable fixes (concrete change, file path + line numbers, official doc URL, expected impact), and whether a material-3 audit is worth running next.
When a persistent report was requested, the top-three fixes in chat MUST be the same items as the report's Prioritized Fixes list.
LaunchedEffect(Unit) on its own — the "run once" pattern is idiomatic. Only flag it when the body captures a value that may change without rememberUpdatedState.RipDpiThemeTokens usage — it is the correct design system access pattern.references/scoring.md — per-rule rubric with inline citationsreferences/search-playbook.md — search patterns and red-flag heuristicsreferences/report-template.md — required structure when a persistent report is requestedreferences/canonical-sources.md — the official URLs every deduction must citereferences/diagnostics.md — Gradle/code snippets for compiler reports, stability config, baseline profiles, R8 checks.agents/skills/compose/scripts/compose-reports.init.gradle — Gradle init script fallback