Skip to main content

implement-feature

The end-to-end workflow for adding a feature to Meshtastic-Android, in the order that keeps KMP source sets and the architecture intact. Use this whenever you start implementing a new feature or a sizeable behavior change, before writing any code.

Source facts

Repository
meshtastic/Meshtastic-Android
Last source activity
October 21, 2026 at 16:00
Detected SKILL.md language
English
Stars
1,911
Forks
536

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
implement-feature
description
The end-to-end workflow for adding a feature to Meshtastic-Android, in the order that keeps KMP source sets and the architecture intact. Use this whenever you start implementing a new feature or a sizeable behavior change, before writing any code.
# Skill: Implement a Feature ## Description A step-by-step workflow for implementing a new feature in the Meshtastic-Android codebase, ensuring KMP compatibility and proper architecture. ## Workflow ### 1. Update Dependencies & Aliases - Check `gradle/libs.versions.toml` before adding libraries. - Use `jetbrains-*` aliases for lifecycle/navigation/adaptive dependencies in `commonMain`. - Use `compose-multiplatform-*` aliases for CMP dependencies. ### 2. Define the State & ViewModels - Follow MVI/UDF patterns. - Extend shared ViewModel logic in `feature/<name>/src/commonMain/kotlin/org/meshtastic/feature/<name>/<Name>ViewModel.kt`. - Use `stateInWhileSubscribed` (from `core:ui`) for sharing state flows. - Keep the ViewModel free of Android framework dependencies. ### 3. Build the UI - Use Jetpack Compose Multiplatform (CMP). - Define strings in `core:resources` (see the `compose-ui` skill). - Support adaptive layouts (Large/XL breakpoints). ### 4. Wire Navigation & DI - Define typed route objects in `core:navigation`. - Export the navigation graph as an extension function on `EntryProviderScope<NavKey>` in `commonMain` (e.g., `fun EntryProviderScope<NavKey>.myFeatureGraph()`). - Add the required DI bindings via Koin Annotations (`@Factory`, `@Single`, `@KoinViewModel`) in `commonMain`. - **CRITICAL:** Ensure the module is registered in the app root graphs (`AppKoinModule.kt`, `DesktopKoinModule.kt`) and the navigation is injected into the root entry provider in the host shell. ### 5. Validate Platform Separation - If you need a platform-specific API (like camera or specific mapping SDK), define an interface in `commonMain`, implement it in the host shell, and inject it via `CompositionLocal` or Koin. ### 6. Verify Locally - Run the baseline checks (see `testing-ci` skill): ```bash ./gradlew spotlessApply spotlessCheck detekt detektTypeResolved assembleDebug test allTests ``` - Add `kmpSmokeCompile` to the command when the feature touches a KMP module (most features do) so cross-target compile failures surface before merge. - If the feature adds a new reflection-heavy dependency, add its keep rules to `config/proguard/shared-rules.pro` (both R8 and desktop ProGuard apply it), or to `androidApp/proguard-rules.pro` / `desktopApp/proguard-rules.pro` when only one platform needs them, then verify release builds: ```bash ./gradlew assembleFdroidRelease :desktopApp:runRelease ```
View on GitHub