Setup KMP App

This documentation was generated with the assistance of AI. Please report any inaccuracies.

iru-setup-kmp-app generates a complete, buildable Kotlin Multiplatform app for Android and iOS at the repository root: a Gradle Kotlin DSL build, a shared/ KMP module, an androidApp/ application module and an iosApp/ SwiftUI host app whose Xcode project is generated by XcodeGen. Its templates live in four reference files (gradle-templates.md, shared-templates.md, android-templates.md, ios-templates.md) and were verified against the real toolchain.

Purpose

The skill produces the scaffold contract that the KMP coding and gate skills (iru-kmp-code-one-task, iru-kmp-test, iru-kmp-coverage, iru-kmp-code-quality, iru-kmp-dokka, iru-kmp-bump-version) and iru-setup-kmp-github-workflows detect and call. It wires the version properties (VERSION_NAME/VERSION_CODE in gradle.properties), a version catalog, a shared/ module on the AGP com.android.kotlin.multiplatform.library plugin with iosArm64 and iosSimulatorArm64 targets producing a static Shared framework, an androidApp/ module with env-driven release signing, and an iosApp/ project driven by iosApp/project.yml. The ui input chooses between Compose Multiplatform (one App() in shared/commonMain) and native UI (shared logic only, with Jetpack Compose on Android and SwiftUI on iOS).

It also configures detekt, ktlint, Android Lint, Kover (aggregated at the root with an 80% koverVerify bound), Dokka 2, SwiftLint and an optional sonar {} block, with sample code and tests in every source set so coverage starts at 100%. Following the catalog’s UI contract (see Building user interfaces) it also writes a root .ui-quality.yml and UI test wiring: a GreetingScreenTest that captures .ui-screenshots/screen/GreetingScreen/ across states, left-to-right/right-to-left and light/dark on Android and iOS, with an accessibility check at the configured level. It announces whether it is scaffolding from scratch or updating an existing project, asks Update / Keep as is / Replace / Stop for each existing file group (unless on-existing decides), never overwrites hand-written source, and treats the JetBrains wizard’s single composeApp/ layout as foreign. Every toolchain version is looked up at run time, with a verified fallback table. Like iru-setup-android-app, it writes no publishing block.

Plugin

Shipped by the iru-kmp plugin of the ai-catalog marketplace (install with /plugin install iru-kmp@ai-catalog; see Plugins).

Invocation

/iru-setup-kmp-app

Optionally with args as key: value lines (see Inputs).

Inputs

Argument Required Description Default

ui

No

compose (Compose Multiplatform App() in shared/commonMain) or native (logic-only shared, Jetpack Compose in androidApp, SwiftUI in iosApp).

Asked (Compose Multiplatform recommended).

app-name

No

Launcher label on both platforms.

Asked (or the existing value when updating).

application-id

No

Android applicationId, reverse-DNS.

Asked.

bundle-id

No

iOS PRODUCT_BUNDLE_IDENTIFIER.

application-id

namespace

No

Kotlin base package (Android app package is <namespace>.android, shared Android namespace <namespace>.shared).

application-id

project-name

No

rootProject.name.

The repository name.

min-sdk, compile-sdk, target-sdk

No

Android SDK levels.

26; compile/target from the run-time lookup (fallback 37).

ios-deployment-target

No

Minimum iOS version.

Looked up from installed simulator runtimes (fallback 18.5).

version-name, version-code

No

Initial app version written to gradle.properties (VERSION_NAME x.y.z[-SNAPSHOT], integer VERSION_CODE).

1.0.0-SNAPSHOT / 1

team-id

No

Apple Developer Team ID written to Config.xcconfig.

Empty (filled in later or supplied by CI).

license, developer-name, developer-email, organization-url

No

Recorded in the report (and consumed later by iru-setup-readme); the license is asked via AskUserQuestion.

Asked.

open-source, visibility, ci

No

Shared bootstrap inputs; they only drive the sonar recommendation here.

open-source asked first when stand-alone.

sonar, sonar-organization, sonar-project-key, sonar-host-url

No

cloud, self-hosted or none; none omits the plugin and the sonar {} block.

Recommended from open-source/visibility/ci; coordinates default from the git remote.

accessibility

No

enforce, report, off or none — the automated accessibility level of the UI tests, written to .ui-quality.yml. Never asked stand-alone, just defaulted. none opts out entirely: no accessibility tooling is installed and the generated templates omit accessibility attributes (asked as "None — opt out entirely"). In mode: existing a prior level is never silently flipped.

enforce

distribution

No

none, internal or store; informational only (release jobs come from iru-setup-kmp-github-workflows).

store when open source, otherwise internal recommended.

mode

No

new or existing. existing never means "update silently".

Detected.

on-existing

No

ask, keep, update or replace; applied to every pre-existing file group without asking.

ask

Unknown keys from a full shared-args set (publish, ci-tests, pages, …​) are ignored and named in the report.

Outputs

  • Gradle build files: wrapper (gradlew, gradlew.bat, gradle/wrapper/* with distributionSha256Sum), settings.gradle.kts, root build.gradle.kts (Kover aggregation, optional sonar {}), gradle.properties, gradle/libs.versions.toml, detekt.yml, .editorconfig, .ui-quality.yml (accessibility, directions, themes).

  • shared/ module: build.gradle.kts and sample sources and tests in commonMain, commonTest, androidMain, androidHostTest, iosMain and iosTest (plus App.kt and MainViewController.kt for ui: compose). For ui: compose the UI test wiring too: commonTest uitest/UiScreenshots.kt, GreetingScreenTest.kt, and a Robolectric UiTest base class on the Android host.

  • androidApp/ module: build file, ProGuard rules, manifest, resources, MainActivity.kt and a Robolectric test (for ui: native also a GreetingScreenTest with createComposeRule() and a uitest/UiScreenshots.kt helper).

  • iosApp/: project.yml, Configuration/Config.xcconfig, .swiftlint.yml, Swift sources, Info.plist and iosAppTests (plus GreetingModel.swift, GreetingScreenTests.swift and an ImageRenderer-based UIScreenshots.swift helper for ui: native). The generated .xcodeproj and local.properties are never written.

  • A verification run (Step 7) of the build, the gate tasks and, on macOS, the iOS framework, XcodeGen and xcodebuild test steps, plus a UI-captures check that .ui-screenshots/screen/GreetingScreen/ holds one PNG per state × direction × theme per platform; anything not runnable (for example iOS captures on a non-macOS host) is reported as unverified.

  • A closing report with the resolved inputs, the setup mode, the per-group action (created / updated / replaced / kept as is, with .ui-quality.yml and its accessibility level listed), what was included or omitted and why, live versus fallback toolchain versions, and ignored keys.

Execution flow

flowchart TD A[Start /iru-setup-kmp-app] --> B["Step 0: Resolve args\n(key: value lines)"] B --> C["Step 1: Survey repository\nfor every file the skill owns"] C --> D{"Existing files\nfound?"} D -- none --> E["Announce: scaffolding from scratch"] D -- yes --> F["Announce: updating existing project\nper group Update / Keep / Replace / Stop\n(or on-existing)"] F -- Stop --> Z["Report and end"] C --> G{"Foreign layout?\ncomposeApp/, androidTarget(),\ncommitted .xcodeproj"} G -- yes --> H["Ask: add alongside or stop"] H -- stop --> Z E --> I["Step 2: Ask missing inputs\n(identity, license, ui, sonar, distribution)"] F --> I H -- alongside --> I I --> J["Step 3: Infer owner/repo\nfrom git remote origin"] J --> K["Step 4: Look up toolchain versions\n(fallback table if lookup fails)"] K --> L["Step 5: Read four reference files,\nfill placeholders"] L --> M["Step 6: Scaffold wrapper, Gradle files,\nshared/, androidApp/, iosApp/"] M --> N["Step 7: Verify via iru-gate-runner\n./gradlew build, gate tasks,\nmacOS: framework, xcodegen, xcodebuild test,\nUI captures check"] N --> O["Step 8: Report"]

Dependencies

Invokes

  • Setup Android App and Setup Apple App — not invoked; they are only cited as the conventions this skill mirrors.

  • No other catalog skill is invoked. Step 7’s verification commands are run through the Gate Runner agent.

Invoked by

  • Setup KMP Repository — Step 4 runs iru-setup-kmp-app (through an isolated skill executor) first in the chain, passing the resolved shared inputs as args.

  • Setup Repository — reaches it indirectly by delegating to iru-setup-kmp-repository. It can also be run directly by a person.

  • Gate Runner — runs Step 7’s Gradle, XcodeGen and xcodebuild verification commands so their long logs stay out of the caller’s context.

Source

SKILL.md on GitHub — the file this page was generated from.