kmp-feature-slice
Procedural KMP feature generation workflow — step-by-step creation of feature slices with typed errors, compose-arch compliance, and build verification. Use when scaffolding a new feature module in a KMP/Compose Multiplatform project.
What this skill does
# KMP Feature Slice Generator
Procedural workflow for generating complete KMP feature slices. Enforces strict creation order, typed error handling, and compose-arch compliance.
**Prerequisites**: Read `compose-arch` skill first — it is the SINGLE SOURCE OF TRUTH for architecture rules.
## Companion skills (versions live there — do not duplicate)
- Architecture rules + Component/View/Screen split — `compose-arch`.
- DI annotations (`@BindingContainer`, `@Provides`, `@AssistedInject`) — `metro-di-mobile` (Metro 1.0.0).
- Navigation primitives (`Value<T>`, `ChildStack`) — `decompose`.
- HTTP — `ktor-client` (3.4.3).
When generating a slice, **always read these companion skills first** for current versions and idioms; never inline a version here.
## Project conventions (project-level glue, NOT framework)
This skill references three helpers that are **project conventions**, not Decompose/Metro/Kotlin APIs. Define them once in your `:core:*` modules (or substitute equivalents) before following the steps. If your project already has equivalents under different names, mentally remap.
| Helper | Lives in | Minimal definition / stand-in |
|--------|----------|-------------------------------|
| `componentScope()` | `:core:component` (typical) | Extension on `ComponentContext` returning a `CoroutineScope` tied to component lifecycle. **Stand-in**: Decompose Essenty's `coroutineScope()` from `essenty-coroutines-extensions` — same semantics. |
| `runCatchingApp { ... }` | `:core:result` (typical) | Project-level `runCatching` variant that maps `Throwable` to `AppResult.Failure` (typed-error mapping inside). **Stand-in**: plain `kotlin.runCatching { ... }` returning `kotlin.Result<T>`. |
| `AppResult<T>` | `:core:result` (typical) | Project sealed result type — usually `sealed interface AppResult<out T> { data class Success<T>(val value: T); data class Failure(val error: AppError) }`. **Stand-in**: `kotlin.Result<T>`. |
If these don't exist yet in the project, create them once in `:core:component` / `:core:result` (or whatever module convention the host project uses) **before** generating feature slices. Do NOT inline them per-feature.
Below, treat any reference to `componentScope()` / `runCatchingApp` / `AppResult` as a call into these conventions — substitute the stand-ins listed above if the project hasn't adopted them.
## Phase 1: Input Collection (LOW FREEDOM)
Collect these inputs before generating any code:
| Input | Required | Example |
|-------|----------|---------|
| **Feature name** | Yes | `OrderHistory` |
| **Data sources** | Yes | `remote-only`, `local+remote`, `local-only` |
| **Target platforms** | Yes | `android,ios,desktop`, `android,ios,desktop,wasm`, `all` |
| **Error types** | Yes | `network,validation`, `network,auth,conflict` |
| **Has list/detail?** | Yes | `list-only`, `detail-only`, `list+detail` |
| **Navigation** | Yes | `stack` (full screen), `slot` (dialog/modal), `none` |
| **Needs pagination?** | No | `true/false` (default: false) |
| **Parent module path** | Yes | `feature/order-history` |
### Error Type Catalog
Select from these typed error categories (see `references/error-patterns.md` for sealed class templates):
| Error Type | When to Use |
|------------|-------------|
| `network` | API calls, timeouts, connectivity |
| `validation` | User input, form data |
| `auth` | Token expired, unauthorized |
| `conflict` | Concurrent modification, duplicate |
| `not-found` | Missing resource |
| `storage` | Database, file system errors |
| `permission` | OS-level permissions (camera, location) |
## Phase 2: File Manifest (ZERO FREEDOM)
Based on inputs, generate the exact file list. Every feature slice follows this structure:
### Mandatory Files (always created)
```
feature/<name>/
├── api/
│ └── src/commonMain/kotlin/
│ ├── <Name>Component.kt # Step 1: Interface
│ ├── <Name>Models.kt # Step 2: Domain models + error types
│ └── <Name>Repository.kt # Step 3: Repository interface (if data sources != none)
│
└── impl/
└── src/commonMain/kotlin/
├── component/
│ └── Default<Name>Component.kt # Step 7: Component implementation
├── domain/
│ ├── usecase/
│ │ └── Get<Name>UseCase.kt # Step 5: Primary use case
│ └── repository/
│ └── <Name>RepositoryImpl.kt # Step 6: Repository implementation
├── data/
│ └── datasource/
│ └── <Name>RemoteDataSource.kt # Step 4: Remote data source
├── view/
│ ├── <Name>ViewState.kt # Step 8: View state
│ ├── <Name>ViewEvent.kt # Step 9: View events
│ └── <Name>View.kt # Step 10: View (pure UI)
├── screen/
│ └── <Name>Screen.kt # Step 11: Screen (thin adapter)
└── di/
└── <Name>Module.kt # Step 12: DI module
```
### Conditional Files
| Condition | Additional Files | Insert at step |
|-----------|-----------------|---------------|
| `data-sources: local+remote` | `<Name>LocalDataSource.kt` | Step 4b — same step as RemoteDataSource |
| `local storage uses DataStore` (e.g. Settings-style features) | `commonMain` declares `expect` factory + interface; platform sourceSets supply actuals — typically `androidMain/.../<Name>Settings.android.kt` and `iosMain/.../<Name>Settings.ios.kt` (and `desktopMain` / `wasmJsMain` if targeted). Do NOT put DataStore construction in `commonMain`. | Step 4b — same step as LocalDataSource |
| `has: list+detail` | **Container** Component (`<Name>Component.kt`) owning `ChildStack<Config, Child>` + **two child Components**: `<Name>ListComponent.kt` and `<Name>DetailComponent.kt` (each with its own `viewState`/`Event`/`View`/`Screen`). Impl side mirrors with `Default<Name>Component`, `Default<Name>ListComponent`, `Default<Name>DetailComponent`. | Container interface at Step 1; child interfaces also at Step 1; container impl at Step 7 (drives `ChildStack`, exposes child factories); child impls at Step 7 (each owns its own state/use cases). View/State/Event/Screen for each child at Steps 8-11. |
| `pagination: true` | `<Name>Pager.kt` in `impl/domain/` | Step 5b — between Repository (Step 5) and Component (Step 7) |
| `navigation: stack` | Navigation config (`Config` sealed class + `ChildStack`) in `<Name>Component.kt` and `Default<Name>Component.kt` | Steps 1 + 7 |
| `navigation: slot` | Slot config in `<Name>Component.kt` and `Default<Name>Component.kt` | Steps 1 + 7 |
> **Component owning navigation alongside state.** A Component can expose BOTH `val viewState: Value<T>` AND `val childStack: Value<ChildStack<Config, Child>>`. They are independent fields.
>
> **List+detail uses the container pattern, not one Component with two states.** The container Component holds *only* the `ChildStack` and child factories — no `viewState` of its own. Each child Component (List, Detail) owns its own `viewState`, events, and use cases. This keeps each child testable in isolation and matches Decompose's `Children { }` rendering. A real example:
>
> ```kotlin
> // Container — navigation only, no viewState
> interface OrderHistoryComponent {
> val childStack: Value<ChildStack<*, Child>>
> sealed class Child {
> data class List(val component: OrderHistoryListComponent) : Child()
> data class Detail(val component: OrderHistoryDetailComponent) : Child()
> }
> }
>
> // Each child is a full Component with its own viewState
> interface OrderHistoryListComponent {
> val viewState: Value<OrderHistoryListViewState>
> fun obtainEvent(event: OrderHistoryListEvent)
> }
> ```
>
> Avoid the anti-pattern of a single Component carrying `viewState: Value<ListState>` + `detailViewState: Value<DetailState>` + manual show/hide flags — that scales poorly and breaks the one-Component-one-screen mental model.
### Gradle Files
```
feature/<name>/
├── api/
│ └── build.gradle.kts Related in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.