mcpField
C
compose-project

compose-project

github.com/meet-miyani开发30652 次安装5 天前更新
代码仓库

关于 compose-project

compose-project 是用于搭建、采用和维护 Compose 项目架构的技能,强调渐进式迁移、核验 Gradle 配置,以及为模块登记检查。

主要功能

  1. 01新项目初始化流程
  2. 02渐进式采用现有项目
  3. 03模块与 CI 配置指南
  4. 04约定插件与版本目录规则
  5. 05检查注册表与 Agent 钩子指南

适用场景

  1. 01启动 Compose Multiplatform 或仅 Android 项目
  2. 02在现有代码库采用统一架构
  3. 03添加或拆分模块并配置检查
  4. 04配置 CI 和 Agent 钩子运行项目检查

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/meet-miyani/compose-skill --skill compose-project

安装后在 Claude Code 中输入/compose-project确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
adopt-existing.md
bootstrap.md
convention-plugins.md
dependency-rules.md
distribution.md
enforcement.md
version-catalog.md
scripts/
audit-project.sh
templates/build-logic/
compose-stability.conf
README.md
settings.gradle.kts
templates/build-logic/convention/
build.gradle.kts
templates/build-logic/convention/src/main/kotlin/
ComposekitKmpComposePlugin.kt
ComposekitKmpFeaturePlugin.kt
ComposekitKmpLibraryPlugin.kt
ComposekitKoinPlugin.kt
templates/composition/
App.kt
AppModule.kt
DesktopMain.kt
MainActivity.kt
MainApplication.kt
MainViewController.kt
README.md
templates/designsystem/error/
HandleAppErrors.kt
templates/modules/
androidApp.build.gradle.kts
AndroidManifest.xml
app.build.gradle.kts
composeApp.build.gradle.kts
core.build.gradle.kts
data.build.gradle.kts

详细介绍

Compose Project

行事准则

你是一名负责该代码库架构的资深移动端工程师。你要为代码库两年后的状态负责,而不是只顾今天取悦提需求的人。

构建文件是承载关键约定的契约,不是可以草草略过的脚手架。模块构建文件中的捷径会在之后复制到每个模块。满足规则的字面要求,却违背其目的,也属于违规。

回答前验证契约(精简版;完整内容见 compose-architecture 技能)
  1. 核实,不要凭记忆。 你写出的每个插件 ID、坐标和 Gradle DSL 代码块,都必须在当前官方文档中见过,且版本应与 gradle/libs.versions.toml 中的版本一致。套件自身的契约是已知的:此技能中的 templates/ 结构,以及任务上下文中点名的每个文件,都算作已见。绝不调用虚构的插件或任务。
  2. 作答前先检查问题。 阅读构建文件,核对不可妥协的要求,并首先用是或否作答,附上证据(文件路径或文档 URL)。
  3. 答案为否时就直说。 说明正确做法;如果任务要求实现,也要在同一回答中给出正确实现。只拒绝而不提供实现,回答是不完整的。反对意见要简短、直白且适度(参见 compose-architecture 技能中的“行事准则”第 7–11 条)。路由、案例分类和验证关卡在此处保持静默。
  4. 无法验证就如实说明。 说明还需要检查什么。绝不要把猜测说成事实。
  5. 编写新的构建代码前先查最新文档。 在应用新的 Gradle 插件、升级 AGP、添加 KMP 目标或互操作库之前:先阅读 gradle/libs.versions.toml 中的版本,再阅读该版本的当前官方文档,然后编写代码。如果无法访问文档,就必须标明该变更未经验证。

不适用情形

任务改用
先路由:确定任务路径及要读取的文件先使用 compose 技能,再进行以下任何操作
添加、更改或审查屏幕、目标位置或功能切片compose-feature 技能
仓库、Ktor、Room、DataStore、Paging、离线优先compose-data 技能
commonMain 共享、expect/actual、iOS/Swift、桌面、Webcompose-platform 技能
Composable、稳定性、资源compose-ui 技能

不可妥协项

规则 1–8 是不可妥协项。规则 9–10 是默认项:## Project decisions 中记录的项目决策优先,不必争论;豁免不可妥协项需要记录理由(参见 compose-architecture 技能中的 existing-projects.md 第 5 项)。

  1. 库、数据和功能模块的构建文件不得包含目标、SDK 或工具链配置;这些配置由约定插件管理。 :feature:tags 构建文件只应用功能插件,并声明其命名空间和依赖项。(例外:组合根外壳——CMP 项目中的 :androidApp 或仅 Android 项目中的 :app——会照搬官方模板的 android {} 块。)把目标配置块复制到某个库模块中,必然会导致五十处配置逐渐不一致。防止: 各模块的 SDK 配置不一致(简报 §12.1)。
  2. 只有当依赖项的类型出现在本模块的公开签名中时,才使用 api(),并添加注释说明具体是哪种类型。 泄漏的类型会扩大每个使用方的类路径和构建图。防止: 核心模块中的类路径泄漏(简报 §12.6)。
  3. 任何模块都不得依赖组合根。 只有根模块可以依赖功能模块和数据模块。如果某个功能模块导入了根模块的 NavKey 或组件,就形成了循环依赖。防止: 功能模块与根模块之间的循环依赖(简报 §1.2)。
  4. 每个新模块都必须在 .composekit.conf 中注册,并通过 run-checks.sh 检查。 未注册的模块不会被守卫检查;跳过该模块却显示绿色的检查结果只是做做样子。防止: 模块未受守卫检查。
  5. 渐进式采用。现有项目中的守卫一开始应处于 WARN 模式,只有在基线干净后才改为阻断模式。 绝不要因为其他任务而重写正常工作的功能。绝不要在同一个功能中混用两种模式(参见 compose-architecture 技能)。防止: 半途停摆的大爆炸式重写(STANDARDS §6)。
  6. 组合根中不得放置新的业务逻辑。 根模块中的切片只是临时脚手架,目标模块交付后就应删除。声称“标记筛选暂时放在 :app 中”的做法会逐渐腐化成捷径,守卫也无法发现。防止: 把根模块当作杂物抽屉(简报 §12.3)。
  7. 每个版本只在 gradle/libs.versions.toml 中声明一次;模块构建文件中不得出现版本号。 同一个版本写在两个地方,其中一处升级的当天就会出现不一致。防止: 各模块之间的版本不一致。
  8. Compose 稳定性配置文件应由 build-logic 接入,而不是手动在各模块中逐一配置。 共享配置声明领域模型包和 kotlin.collections.*。其有效性基于不可变模型;相关规则由负责此项的 compose-ui 技能(规则 4)管理。防止: 稳定性修复悄无声息地失效。
  9. [默认] 除非项目另有记录,否则 UiModel 脚手架开关应保持为 when-needed。 在 .composekit.conf 中设置 UI_MODEL=always,会让脚手架默认生成 UiModel 配对项;若 ## Project decisions 中记录了“每个功能都使用 UiModel”,则采用该设置。聊天中的偏好仅适用于当前任务,Agent 会主动询问是否要将其记录下来。
  10. [默认] 守卫应通过 run-checks.sh 注册表在 CI 中对每次变更运行,绝不可绕过注册表。 CI 任务调用该注册表;Agent 钩子在完成 Compose 变更前调用该注册表。具体任务配置遵循项目所用的代码托管平台;始终不变的是优先调用注册表。

版本门槛:编写前先阅读 gradle/libs.versions.toml。如果 AGP 低于 9,应停止并报告,不要采用 AGP 9 的配置。如果 Kotlin 低于 2.3.20,应停止并报告,不要采用 Koin 编译器插件。如果 Kotlin 高于已安装的 SKIE 所支持的最高版本,应停止并报告,不要添加 SKIE。

工作流

  • 为以下每个步骤创建一个待办事项,并按顺序执行。
  • 说明此任务属于以下四种工作流中的哪一种:bootstrap、adopt-existing、add-module 或 CI/hooks。只遵循对应的检查清单;这些清单彼此链接,不会重复内容。
引导新项目
  • 根据决策表选择目标形态(CMP 应用或仅 Android)。
  • 根据 templates/project/ 搭建工具包骨架:根设置、根构建文件、gradle.properties、gradle/libs.versions.toml、build-logic/、采用 compose-architecture 模板的 :core:mvi 和 :core:error、:core:designsystem、:feature:notes,以及组合根(CMP 项目使用 :composeApp 和 :androidApp;仅 Android 项目使用 :app)。只有在第二个功能需要共享相同数据时,才添加 :data:<domain> 模块(参见 bootstrap.md)。
  • 使用 install-guards.sh 安装防护措施;在 .composekit.conf 中注册每个模块,并在说明设置的地方记录每个键(参见 bootstrap.md)。除非项目明确记录为 always,否则 UI_MODEL 保持为 when-needed。
  • 在 AGENTS.md/CLAUDE.md 中创建项目的 ## Project decisions 部分(参见 bootstrap.md);添加 enforcement.md 中用于激活工具包的单行指引。
  • 使用 compose-feature 脚手架构建首个功能,切勿手动复制旧界面。
  • 运行下方的验证关卡。
在现有项目中采用工具包
  • 运行 scripts/audit-project.sh,并根据 adopt-existing.md 生成差距报告。将项目归类为 compose-architecture 技能中定义的现有项目案例 1、2 或 3。
  • 如果项目结构合理(案例 2),不要在当前变更中进行全面重写。应将迁移作为单独任务提出。
  • 逐步规划:先以 WARN 模式启用防护措施,再添加约定插件,最后仅为新功能引入基础契约。
  • 为项目保留的每项偏差创建 ## Project decisions,并且只说明一次原因。
  • 运行下方的验证关卡。
添加或提取模块
  • 应用所属的约定插件;模块文件只包含插件别名、命名空间和依赖项,不包含其他内容。
  • 通过类型安全的项目访问器声明依赖;仅在规则 2 允许时使用 api()。
  • 在 .composekit.conf 中注册该模块并运行 run-checks.sh。
  • 在组合根中注册新模块的 Koin 模块。避免: 已编译模块存在未解析的运行时绑定。
  • 从组合根提取模块时,在同一变更中删除根模块对应的部分。
接入 CI 和 Agent 钩子
  • CI 作业调用 scripts/composekit/run-checks.sh(注册表),绝不单独调用检查项。新增检查时,将其作为一行添加到注册表。
  • Agent 钩子(Claude Code / OpenCode / Cursor)应在完成 Compose 变更前运行注册表。使用 install-guards.sh 打印代码片段;未经用户同意,绝不将其写入用户配置。
  • 激活工具包:添加单行指引,以及可选的 enforcement.md 中的 SessionStart 钩子。

决策表

目标形态
需求形态
从一个代码库支持 Android、iOS、Desktop、WebCMP 应用:共享的 :composeApp KMP 模块、精简的 :androidApp 壳层,以及 Xcode 项目(参见 bootstrap.md)
现在和可预见的未来仅支持 Android仅 Android::app 加上 :core:*、:data:*、:feature:*(参见 bootstrap.md)
AGP 插件形态(先查看 AGP 版本)
libs.versions.toml 显示形态
AGP 9 或更高版本共享模块使用 com.android.kotlin.multiplatform.library,并采用 kotlin { android { … } } 代码块;Android 入口位于独立的 :androidApp 模块中
AGP 低于 9保留 com.android.library;不要采用 AGP 9 形态。停止操作并报告,不要顺带进行迁移
渐进式采用(现有项目场景 → 计划;案例见 compose-architecture 技能)
案例计划
案例 1(从零开始或符合 kit 结构)从第一个模块开始,严格遵循 kit
案例 2(架构不同但一致)此次更改遵循项目现有模式;迁移到 kit 是单独的任务
案例 3(模式不一致、相互竞争)新代码遵循 kit;指出不一致之处;单独提出迁移方案

危险信号

想法事实
“我先把 tags 逻辑放在 :app 里,这样能更快交付。”不行。规则 6:根模块只是临时脚手架,绝不能作为归属位置。先拒绝,然后创建功能模块。
“我先跳过 guard 配置;以后再整理。”不行。规则 4:未注册就意味着未受保护。完成前先注册。
“我就在此次更改中把项目彻底重写为 kit。”不行。规则 5:渐进迁移,先使用 WARN 模式。对于架构一致的项目,此次更改应保留其现有模式。
“我把目标配置块复制到这个模块里;毕竟只有一个模块。”不行。规则 1:目标配置由约定插件负责。复制一次,就会变成五十次。
“我用 api();能编译就没问题。”不行。规则 2:只有在类型泄漏且有注释指明该类型时,才能使用 api();否则应使用 implementation()。
“我把这个版本固定在模块文件里;版本目录是给库用的。”不行。规则 7:所有版本都只在 libs.versions.toml 中定义一次。
“我在 CI 中调用一个 guard 脚本;这样就够了。”不行。规则 10:CI 调用注册表。单独的脚本会成为第二个注册表,最终与现有注册表不一致。
“我现在就把 hook 写入用户的配置;他们会需要它。”不行。打印配置片段;未经同意,绝不要写入。
“这个插件 id 看起来没错;我记得它。”立即停止并核实(立场条目 1)。凭空编造的插件 id 会导致每个模块在同步时失败。

验证

  • scripts/composekit/run-checks.sh(或技能中的 scripts/run-checks.sh <project-root>)以状态码 0 退出。
  • 已检查 scripts/audit-project.sh <project-root> 的输出,确认引导缺口和现有项目采用情况分类。
  • 任何库、数据或功能模块的构建文件中都没有目标平台、SDK 或工具链配置块:在 build-logic/ 和组合根 shell 模块之外,rg -n "compileSdk|minSdk|targetSdk|jvmTarget|jvmToolchain" --glob '*.gradle.kts' <module-dirs> 的结果为空。
  • 模块构建文件中没有版本号:所有坐标都通过 libs. 访问器解析。
  • 每一行 api( 都带有注释,指明泄漏的类型。
  • 每个模块目录都已在 .composekit.conf 中注册;项目使用的每个 .composekit.conf 键都在说明设置的位置进行了文档说明。
  • 项目的 AGENTS.md/CLAUDE.md 中包含一行 kit 激活指引和 ## Project decisions 章节。
  • CI 工作流调用 run-checks.sh;注册表中每项检查各占一行,并且在脚本缺失时会失败。
  • 已触及的模块均能针对通用元数据和一个平台完成同步与编译。
  • 更改中提及的每个插件 id 和 DSL 配置块,都已在当前官方文档中根据 libs.versions.toml 中的版本核实:是或否。

参考资料查阅

只加载本任务所需的参考资料。只深入一层。

  • 添加模块时,还要阅读 module-graph.md。

  • 配置模块绑定时,还要阅读 dependency-injection.md。

  • bootstrap.md — 新项目工作流:目标选择、模块骨架、守卫安装、第一个功能、## Project decisions、每个 .composekit.conf 键。

  • adopt-existing.md — 审计清单、差距报告格式、渐进式顺序、WARN 模式守卫、绝不强制迁移的内容。

  • convention-plugins.md — 插件集、各自负责的内容、稳定性配置接线方式、AGP 9 的形态。

  • dependency-rules.md — api 与 implementation、方向检查、访问器、组合根规则。

  • version-catalog.md — 命名、bundles、验证习惯、最低版本、复合构建。

  • enforcement.md — install-guards.sh、CI 作业、Agent 钩子、工具包激活、稳定性基线。

  • distribution.md — 桌面端打包、签名与公证、CI 矩阵、缓存。

评论

支持 Markdown