compose-kotlin-agent-skills について
コーディングAI向けのAndroid・Kotlin開発スキル集です。アーキテクチャ、Compose UI、テストのモジュールや、現行ツールチェーンの制約、反パターン、例を含みます。
主な機能
- 01アーキテクチャ、Compose UI、テストのモジュールガイド
- 02Kotlin 2.xとK2コンパイラーの規約
- 03MVI状態管理ルール
- 04ナビゲーション、アクセシビリティ、性能の資料
- 05反パターン一覧とサンプルプロジェクト
- 06スキル検証スクリプト
活用シーン
- 01AI生成Kotlinコードのレビュー
- 02Androidのアーキテクチャと状態管理の構築
- 03Compose UIの開発とテスト作成
- 04XMLからComposeへの移行計画
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ haidrrrry/ compose-kotlin-agent-skills --skill compose-kotlin-agent-skillsインストール後、Claude Code で/compose-kotlin-agent-skillsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
.gitattributesCITATION.cffAGENTS.mdCODE_OF_CONDUCT.mdCHANGELOG.mdLICENSECONTRIBUTING.mdROADMAP.mdREADME.mdSECURITY.md.github/pull_request_template.md.github/ISSUE_TEMPLATE/bug_report.mdfeature_request.mdnew_agent.md.github/workflows/skill-lint.ymlagents/_shared-snippet.mdREADME.mdaider.mdamazon-q.mdbolt.mdclaude.mdaugment.mdcline.mdcodex.mdcursor.mdcontinue.mdcopilot.mddeepseek.mddevin.mdfactory.md詳細
Android & Kotlin — エンタープライズ本番環境向けスキル(2026)
信頼できる Android エンジニアリングキットです。AnimatedClockJetpacl、Authenticator、RepLockの実践的なパターンを紹介します。
Android ライブラリ、音声アシスタント向けスキル、オンデバイス LLM SDK、Compose UI ライブラリではありません。 これはコーディング AI 向けの Markdownです。
.cursor/skills/または.claude/skills/にクローンしてください。README §「これは何ではないか」を参照してください。
メタインデックス: AGENTS.md · CI: python3 scripts/validate_skills.py
サブスキル(モジュール式)
| スキル | パス | 対象範囲 |
|---|---|---|
| アーキテクチャ | skills/android-kotlin-architecture/SKILL.md | MVI/MVVM、モジュール、UseCase、UDF |
| Compose UI | skills/android-kotlin-compose/SKILL.md | UI、エッジツーエッジ、パフォーマンス、モーション |
| テスト | skills/android-kotlin-testing/SKILL.md | Turbine、Compose テスト、Hilt のフェイク |
2026 年ツールチェーン — 必須要件
| ツール | 最小バージョン | 備考 |
|---|---|---|
| Kotlin | 2.0+ (2.1.x) | K2 コンパイラーのみ — K1 へのフォールバックなし |
| AGP | 9.0+ | Kotlin 組み込み、新しい DSL のデフォルト |
| Compose BOM | 2025.05+ | Material 3、strong skipping がデフォルト |
| Navigation | 3.x (2.9+ artifact) | 型安全な NavKey、@Serializable ルート |
| compileSdk / targetSdk | 35+ | エッジツーエッジが必須 |
| JDK | 17 | AGP 9 に必要 |
[versions]
kotlin = "2.1.20"
agp = "9.0.0"
compose-bom = "2025.05.00"
navigation = "2.9.0"
room = "2.7.1"
hilt = "2.56.2"
lifecycle = "2.9.0"
coroutines = "1.10.2"
Kotlin 2.x / K2 コンパイラーの制約
- K2 を有効にする —
kotlin.compiler.execution.strategyのデフォルトを使用します。Hilt/Room にはkaptではなくkspを使用してください。 - スマートキャスト — 安全でない
!!よりも、when (val x = state) { is Loaded -> ... }を優先してください。 - シールド階層 — 網羅的な
whenにするには、sealed interface UiState+data object Loading : UiStateを使用します。 - ID には
@JvmInline value classを使用します(@JvmInline value class UserId(val raw: String))。 - Compose に渡す UiState と UI モデルには、
@Immutable/@Stableを付けます。 - 明示的な API はライブラリでは任意です — 公開するモジュールで
kotlin { explicitApi() }を使用します。 - テスト内でコメントを付ける場合を除き、
!!は使用しないでください —requireNotNullまたは早期リターンを使用します。 - 状態には
data classの copy を使用します — UiState のフィールドをその場で変更してはいけません。
sealed interface AccountsUiState {
data object Loading : AccountsUiState
data class Ready(
val accounts: List<AccountUi>,
val query: String = ""
) : AccountsUiState
data class Error(@StringRes val messageRes: Int) : AccountsUiState
}
MVI のガードレール — 状態の更新はアトミックに
許可される変更: _state.update { it.copy(...) } または _state.update { prev -> ... }。
ViewModel で禁止されるもの:
// BANNED
_state.value = AccountsUiState(...) // naked assign
_state.value.accounts.add(item) // mutating list inside state
mutableStateOf / mutableStateListOf in VM // Compose scope only
viewModelScope.launch { _state.value = ... } // use update inside launch
必須パターン:
class AccountsViewModel @Inject constructor(
private val repository: AccountsRepository
) : ViewModel() {
private val _state = MutableStateFlow<AccountsUiState>(AccountsUiState.Loading)
val state: StateFlow<AccountsUiState> = _state.asStateFlow()
private val _effects = Channel<AccountsEffect>(Channel.BUFFERED)
val effects: Flow<AccountsEffect> = _effects.receiveAsFlow()
fun onEvent(event: AccountsEvent) {
when (event) {
AccountsEvent.Refresh -> refresh()
is AccountsEvent.QueryChanged -> _state.update { current ->
when (current) {
is AccountsUiState.Ready -> current.copy(query = event.query)
else -> current
}
}
}
}
private fun refresh() {
viewModelScope.launch {
_state.update { AccountsUiState.Loading }
repository.load()
.onSuccess { list ->
_state.update { AccountsUiState.Ready(accounts = list.map { it.toUi() }) }
}
.onFailure {
_state.update { AccountsUiState.Error(R.string.error_load_failed) }
}
}
}
}
UI での収集:
@Composable
fun AccountsRoute(vm: AccountsViewModel = hiltViewModel()) {
val state by vm.state.collectAsStateWithLifecycle()
LaunchedEffect(Unit) {
vm.effects.collect { effect -> /* one-shot: nav, snackbar */ }
}
AccountsScreen(state = state, onEvent = vm::onEvent)
}
Navigation 3 + エッジツーエッジ
@Serializable data object Home
@Serializable data class Detail(val id: String)
@Composable
fun AppNavHost(navController: NavHostController = rememberNavController()) {
NavHost(navController, startDestination = Home) {
composable<Home> { HomeScreen(onOpen = { navController.navigate(Detail(it)) }) }
composable<Detail> { entry ->
val route = entry.toRoute<Detail>()
DetailScreen(id = route.id)
}
}
}
- ルートには文字列パスではなく、
@Serializable型を使用します - ナビゲーション引数には ID を渡し、遷移先の ViewModel でモデルを取得します
- Activity で
enableEdgeToEdge()を呼び出します — Compose サブスキルを参照してください
詳細:references/07-navigation.md
禁止されるアンチパターン — AI のハルシネーションを参照
誤り/正解の組み合わせと行番号を含む完全な表:references/00-banned-antipatterns.md
エージェントが生成した Kotlin をレビューする前に読み込んでください。Compose 監査チェックリスト:skills/android-kotlin-compose/SKILL.md § レビューモード。
リファレンスの振り分け
| ファイル | トピック |
|---|---|
references/00-banned-antipatterns.md | 禁止事項のマスターテーブル — レビュー時に最初に読み込みます |
references/01-architecture.md | クリーンアーキテクチャ、MVVM、モジュール |
references/02-compose-ui.md | コンポジション、M3、テーマ設定 |
references/03-animations.md | モーション、Canvas |
references/04-coroutines-flow.md | Flow、エラー、キャンセル |
references/05-hilt-di.md | DI、スコープ |
references/06-room-db.md | Room、オフラインファースト |
references/07-navigation.md | Nav 3、ディープリンク |
references/08-kmp-cmp.md | KMP、expect/actual |
references/09-networking.md | Ktor、JWT |
references/10-performance.md | 再コンポジション、Coil、プロファイル |
references/11-testing.md | Turbine、UI テスト |
references/12-camera-mlkit.md | CameraX、ポーズ |
references/13-release-checklist.md | R8、Play Store |
references/14-datastore.md | DataStore、SP の移行、暗号化 |
references/15-paging3.md | Paging 3、RemoteMediator、asState() |
references/16-coil-image.md | Coil 3.4、AsyncImage、キャッシュ |
references/17-accessibility.md | TalkBack、セマンティクス、WCAG |
references/18-gradle-build-logic.md | コンベンションプラグイン、KSP、R8、ベースラインプロファイル |
references/19-xml-to-compose-migration.md | XML → Compose、RxJava → Flow |
プラットフォーム
ターゲット(ドキュメントで扱うもの): Android · Kotlin Multiplatform · Compose Multiplatform
ホスト(ドキュメントを読む場所): macOS · Linux · Windows — AI エージェントを実行できる場所ならどこでも
エージェントの互換性: 27 種類のインストールガイド → agents/README.md
リポジトリ:https://github.com/haidrrrry/compose-kotlin-agent-skills
必須のデフォルト(概要)
- 文字列:
stringResource/@StringRes— UI テキストのハードコードはゼロ - 状態: ViewModel
StateFlow+_state.update { } - UI: ステートレスなコンポーザブル、最初の省略可能なパラメーターは
modifier - リスト:
LazyColumn+ キー +contentType - DI:
@HiltViewModel+ コンストラクターインジェクション - テスト: フェイク + Turbine — テストのサブスキルを参照してください
PR 前の検証
python3 scripts/validate_skills.py --strict
非合理化への反論
| 言い訳 | 実態 |
|---|---|
| 「UiState は過剰」 | data object Loading は1行で済みます |
| 「キーは後で」 | スクロールやフォーカスが今すぐ壊れます |
| 「プロトタイプだからリポジトリは不要」 | プロトタイプもリリースされます |
| 「collectAsState で問題ない」 | バックグラウンドのコレクターがバッテリーを消耗します |
例
| パス | パターン |
|---|---|
examples/animated-clock/ | Canvas、rotate()、パーティクル |
examples/authenticator/ | Room Flow、combine、CompositionLocal テーマ |