code-kmplisted
Install: claude install-skill tstapler/dotfiles
# KMP / Kotlin 2.2 Idiomatic Review
Apply this checklist when reviewing any diff containing `.kt` files in a KMP project (files in `commonMain`, `androidMain`, `iosMain`, `sharedLogic`, or `sharedUI` source sets).
## MUST FIX (block shipping if violated)
1. **[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.
2. **[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`.
3. **[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.
4. **[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.
5. **[ANTI-PATTERN]** `SqlDriver` must not be constructed directly in `commonMain`. Wrap all driver creation behind `interface DatabaseDriverFactory { fun createDriver(): SqlDriver }` with platform `actual` implementations.
6. **[NAMING]** Kotlin 2.2: `kotlinOptions {}` DSL is deprecated-to