$npx -y skills add rcosteira79/android-skills --skill android-devUse this skill as the baseline for ALL Android and Kotlin Multiplatform (KMP) work — whenever the user mentions Android, Kotlin (in an Android context), KMP, CMP, commonMain, androidMain, iosMain, AndroidManifest, Gradle, build.gradle, Hilt, Dagger, Room, Retrofit, Ktor, ViewMode
| 1 | # Android / KMP baseline |
| 2 | |
| 3 | House defaults — apply them without reminders or re-derivation; where the project's actual conventions differ, follow the project: |
| 4 | |
| 5 | - **DI:** Hilt + KSP (or `android-skills:koin` when the project uses Koin). **Async:** Coroutines/Flow — no `LiveData` in new code. **JSON:** `kotlinx.serialization`. **Images:** Coil. |
| 6 | - **Network/local:** Android uses Retrofit/OkHttp + Room; KMP shared uses Ktor + Room or SQLDelight. Retrofit is Android-only — never in a shared module. |
| 7 | - **Modules:** feature-vertical packages and modules; `:core:model` has zero Android deps; `:feature:*` modules never depend on each other. |
| 8 | - **Errors:** mapped to a domain type at the repository boundary — platform exceptions never leak past it; UI state explicitly models loading / success / error (see `android-skills:android-data-layer`). |
| 9 | |
| 10 | ## Skill routing |
| 11 | |
| 12 | Load the specific skill for the task, always with the **fully-qualified `android-skills:` prefix** — never the short name (`compose`, `koin`, …). |
| 13 | |
| 14 | | For | Load | |
| 15 | |---|---| |
| 16 | | Compose detail — stability, `remember`, modifiers, side effects, lists, animation, navigation | `android-skills:compose` | |
| 17 | | M3 UX — touch targets, adaptive/foldable layouts, accessibility & M3-compliance audit | `android-skills:android-ux` | |
| 18 | | Coroutines & Flow — operators, `Channel` vs `SharedFlow`, structured concurrency | `android-skills:kotlin-coroutines`, `android-skills:kotlin-flows` | |
| 19 | | Repository / data layer + error model | `android-skills:android-data-layer` | |
| 20 | | Networking | `android-skills:android-retrofit` (Android) · `android-skills:kmp-ktor` (KMP) | |
| 21 | | Paging | `android-skills:paging` | |
| 22 | | Image loading | `android-skills:coil-compose` | |
| 23 | | Preferences / typed local storage | `android-skills:datastore` | |
| 24 | | KMP `expect`/`actual` boundary design | `android-skills:kmp-boundaries` | |
| 25 | | RxJava → Coroutines/Flow migration | `android-skills:rxjava-migration` | |
| 26 | | Testing | `android-skills:android-testing` | |
| 27 | | DI with Koin | `android-skills:koin` | |
| 28 | | Build logic / convention plugins | `android-skills:android-gradle-logic` | |
| 29 | | Build speed, kapt → KSP | `android-skills:gradle-build-performance` | |
| 30 | | Debugging — Logcat, crashes, ANRs, profiling | `android-skills:android-debugging` | |
| 31 | | AOSP / AndroidX source lookup | `android-skills:android-source-search` | |
| 32 | | Multi-module visibility & module boundaries | `android-skills:modularization` | |
| 33 | | Platform PDF annotation / page-object editing (API 36.1 / SDK ext 18) | `android-skills:pdf-annotations` | |
| 34 | |
| 35 | ## New-project UI convention (greenfield) |
| 36 | |
| 37 | For a **new** project or feature with no established convention. In existing code, match what's already there — see *Reuse the project's existing mechanism* below. |
| 38 | |
| 39 | The UI layer is MVVM with an MVI-style state/effect split: |
| 40 | |
| 41 | - **One immutable `UiState` per screen**, exposed as `StateFlow<UiState>` and structured with the four buckets below. The content composable renders it and emits callbacks — nothing else. |
| 42 | - **One effects stream for fire-once imperatives** — navigate, snackbar/toast, scroll-to, share-sheet, haptics. Use `Channel(Channel.BUFFERED).receiveAsFlow()`, **not** `SharedFlow`: an effect emitted while the screen is backgrounded buffers and replays on resume instead of being dropped. Collect it in a `LaunchedEffect` (lifecycle-scoped via `repeatOnLifecycle`), never `collectAsStateWithLifecycle`. Channel-vs-`SharedFlow` rationale: `android-skills:kotlin-flows`. |
| 43 | - **State vs effect — "does it survive a config change?"** Anything still true after rotation / process death is **state** (an error to show = a field in `UiState`); anything the UI runs once and forgets is an **effect**. This is the `durable-state-over-events` rule in `compose/references/state-management.md`: keep durable things in state; the effect stream is only for one-shot imperatives. |
| 44 | - **Promote callbacks to a `@Stable Actions` interface at ~4–5+** (or when the same set is threaded through several composable layers). Below that, individual lambdas are simpler — don't abstract early. The ViewModel implements the interface; the |