code-kmp
Idiomatic review for Kotlin Multiplatform (KMP) with Kotlin 2.x — expect/actual discipline, Swift boundary safety, ViewModel lifecycle, SQLDelight conventions
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Idiomatic review for Kotlin Multiplatform (KMP) with Kotlin 2.x — expect/actual discipline, Swift boundary safety, ViewModel lifecycle, SQLDelight conventions
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
Apply idiomatic, well-structured Python development practices. Use when writing, reviewing, or refactoring Python code. Covers type annotations, package management with uv, Pydantic DTOs, Typer CLIs, pytest patterns, PEP 8 style, architecture, and type-driven design.
How to manage Python dependencies with UV — inline script metadata (PEP 723), project mode, tool running, and when to use each approach. Always use UV; never pip directly.
Use when receiving code review feedback (especially if unclear or technically questionable), when completing tasks or major features requiring review before proceeding, or before making any completion/success claims. Covers four practices — receiving feedback with technical rigor, requesting reviews via code-reviewer subagent, verification gates requiring evidence before claims, and security/API-compat awareness. Essential for subagent-driven development, pull requests, and preventing false completion claims.
Synthesize knowledge from multiple sources into Zettelkasten notes for Logseq. Use when creating wiki pages, integrating academic research, or building interconnected knowledge with [[links]] and
Survey a Google Drive's actual folder structure, apply a PARA-lite organization framework, and produce (then safely execute) a concrete reorganization plan — deduping, sweeping root-level clutter, and fixing misnested folders.
Idiomatic review for Rust — async/Tokio daemon design, ports-and-adapters trait boundaries, and thiserror/anyhow error handling. Use when reviewing or writing Rust code that defines async trait "ports" (dependency-inversion boundaries), runs a single-threaded Tokio daemon (current_thread runtime + LocalSet/spawn_local), or crosses a wire/domain type boundary. Covers async fn in traits vs async-trait, Rc/RefCell vs Arc/Mutex, tokio::select! cancel-safety, blocking calls in async context, thiserror-vs-anyhow error typing, wire/domain type separation, and common anti-patterns (clone in hot loops, overly generic port bounds). NOT for pure performance/profiling work (see rust-profiling, rust-perf-tuning, rust-memory-optimization, rust-parallel-processing) or unsafe/CLI/wasm-bindgen review (no dedicated skill yet — use the sdd:6-verify research-agent fallback for those).
| name | code-kmp |
| description | Idiomatic review for Kotlin Multiplatform (KMP) with Kotlin 2.x — expect/actual discipline, Swift boundary safety, ViewModel lifecycle, SQLDelight conventions |
| user-invocable | false |
Apply this checklist when reviewing any diff containing .kt files in a KMP project (files in commonMain, androidMain, iosMain, sharedLogic, or sharedUI source sets).
[ERROR] Do not throw raw exceptions from suspend fun exposed to iOS. Wrap in a sealed class result type before crossing the Kotlin → Swift boundary; Kotlin exceptions thrown from coroutines surface as untyped crashes in Swift.
[ERROR] Do not collect StateFlow directly in Swift via collect {}. Use KMP-NativeCoroutines, SKIE, or an explicit iosMain bridge with DisposableHandle.dispose() called from Swift deinit.
[ANTI-PATTERN] iOS ViewModel scope must be cancelled on dismiss. Every ViewModel must expose fun clear() that cancels its SupervisorJob. Swift callers must call viewModel.clear() from deinit. Without this, coroutines leak silently on iOS.
[ANTI-PATTERN] Do not use expect class for types that need fakes (repositories, helpers, services). Use interface in commonMain with class Foo : Interface in each platform source set. expect class blocks unit-testing with fakes.
[ANTI-PATTERN] SqlDriver must not be constructed directly in commonMain. Wrap all driver creation behind interface DatabaseDriverFactory { fun createDriver(): SqlDriver } with platform actual implementations.
[NAMING] Kotlin 2.2: kotlinOptions {} DSL is deprecated-to-error. Migrate all compiler flag configuration to compilerOptions {} inside kotlin {}. This breaks builds on Kotlin 2.2+.
[STYLE] Domain model data class instances in commonMain must not use java.time.*, java.util.Date, or any platform Uri. Use kotlinx-datetime (Instant, LocalDate) for all timestamp fields.
[ANTI-PATTERN] Business logic must not leak into actual declarations. actual blocks are pure platform wiring (driver init, file paths, clock access). Logic that enters an actual block cannot be tested in commonTest.
[NAMING] expect/actual files: use identical file names across source sets (e.g., TimeProvider.kt in commonMain, TimeProvider.android.kt in androidMain). The compiler allows mismatched names but maintainers can't find actual implementations without searching.
[STYLE] ViewModels expose a single StateFlow<UiState> and a single dispatch(action: Action). Use SharedFlow<Event>(replay=0) for one-shot navigation/snackbar events. Never expose MutableStateFlow or MutableSharedFlow from a ViewModel's public API.
[PERF] Use SharingStarted.WhileSubscribed(5_000) on stateIn calls, not Eagerly. This stops upstream producers after the last subscriber leaves, prevents wasted work on iOS when views are not collecting.
[STYLE] Every query in a SQLDelight .sq file must have a meaningful label (e.g., selectUserById:). Labels generate typed Kotlin functions. Unlabelled queries require raw execute() calls that lose compile-time safety.
[STYLE] Koin DSL (module { single { } / factory { } }) is preferred over a hand-rolled AppContainer when the DI graph exceeds ~7 nodes. Koin does not use reflection and is safe on Kotlin/Native.
[STYLE] Do not use the deprecated context(Foo) context receivers syntax (Kotlin 1.x experiment). It is being removed (KT-72994). Use explicit parameters or wait for the stable context parameters feature in Kotlin 2.2+.
[PERF] All data class fields used as map keys must implement stable hashCode/equals. KMP value classes (@JvmInline) give zero-cost wrappers on JVM but add a boxing step on Kotlin/Native — profile before adding to hot paths.