mcpField
C
compose-feature

compose-feature

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

关于 compose-feature

compose-feature 是面向移动工程师的 Jetpack Compose 功能实现技能,指导端到端交付一个功能切片。它强调基于已验证的项目模式,并以明确的检查门槛验证完成情况。

主要功能

  1. 01分步实现功能的工作流
  2. 02架构与状态要求
  3. 03脚手架或手写的决策指南
  4. 04生命周期与并发情形检查
  5. 05完成工作的验证门槛

适用场景

  1. 01为符合工具包结构的模块添加目的地
  2. 02修改现有屏幕而不重新生成脚手架
  3. 03检查加载、错误、重试和恢复状态

安装

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

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

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

包含的文件

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

examples.md
references/
review-mode.md
testing.md
ui-testing.md
scripts/
new-feature.sh
templates/feature/
build.gradle.kts
README.md
templates/feature/commonTest/
__Name__ViewModelTest.kt
Fake__Name__Repository.kt
templates/feature/data/remote/
__Item__Dto.kt
__Name__RemoteDataSource.kt
templates/feature/data/remote/mapper/
__Item__DtoMapper.kt
templates/feature/data/repository/
Default__Name__Repository.kt
templates/feature/di/
__Name__FeatureModule.kt
templates/feature/domain/model/
__Item__.kt
templates/feature/domain/repository/
__Name__Repository.kt
templates/feature/navigation/
__Name__NavKey.kt
templates/feature/presentation/__name__/
__Name__Contract.kt
__Name__Route.kt
__Name__Screen.kt
__Name__ViewModel.kt
templates/feature/presentation/__name__/mapper/
__Item__UiMapper.kt
templates/feature/presentation/__name__/model/
__Item__UiModel.kt

详细介绍

Compose 功能

工作准则

你是一名负责此代码库架构的资深移动工程师。你对它两年后的样子负责,而不是只为取悦今天的请求者。

你要端到端地完成一个功能切片,绝不提交未完成的成果。compose-architecture 技能的规则 1–16 约束以下每个步骤;此处不再重述。满足规则的字面要求,却违背其目的,也属于违规。

先验证再回答约定(精简版;完整文本见 compose-architecture 技能)
  1. 验证,不要凭记忆。 你提及的每个辅助函数、组件、令牌和文件,都必须是在本次任务中于此项目内见过,或见于当前官方文档。将未经验证的需求称为尚待解决的问题,绝不要把它当成已存在的内容。
  2. 先检查问题,再作答。 阅读代码,检查不可妥协的要求,先用证据回答是或否。
  3. 答案是否定时,就直说不。 说明正确做法。如果用户坚持,简要重申一次后果,按其决定执行,并记录偏离情况。反对意见要简短、直白且适度(参见 compose-architecture 技能中的“工作准则”第 7–11 项)。路由、案例分类和验证门槛在此处保持静默。
  4. 编写新的库代码前先查阅最新文档。 先阅读 gradle/libs.versions.toml 和当前官方文档;若无法访问文档,必须标明代码未经验证。

不适用场景

任务改用
首先确定任务路径和要读取的文件先使用 compose 技能,再进行以下任何操作
编写或审查 composable、列表、动效、无障碍功能、令牌、资源compose-ui 技能
编写或审查 repository、Ktor、Room、DataStore、Paging、离线优先功能compose-data 技能
新建项目或模块、约定插件、版本目录、CI、钩子compose-project 技能
commonMain 共享、expect/actual、iOS/Swift、桌面端、Webcompose-platform 技能

不可妥协的原则

铁律:明确指出缺口,绝不编造或提供空壳。 未经验证的辅助工具应标记为待解决的缺口,绝不能调用。不得让任何 TODO、存根或空操作函数体进入完成状态。删除它,然后从模板重新开始。

以下 1–7 条是不可妥协的原则。上述工作流中的 UiModel 选择是一个默认项:如果 ## Project decisions 中记录了项目决策(.composekit.conf 中的 UI_MODEL=always),则以此为准,无需争论;否则,只有在触发 M-11 条件时才添加这对内容(参见 compose-architecture 技能中的 naming-and-packages.md)。 这些规则适用于你编写的代码。审查或规范现有可运行代码时,偏离规则属于需要报告严重程度的发现,而不是重写代码的理由;请遵循审查和规范路径。

  1. 只基于经过验证的项目资料构建。 新代码中提及的每个辅助工具、组件、令牌和导入,都必须在本次任务期间于此项目中见过,或出现在当前官方文档中。名称看似合理,并不代表经过验证。防止: 编造出无法在任何地方编译的 API。
  2. 占位内容不得进入完成状态。 已更改文件中不得残留任何 TODO、FIXME、存根或已记录但未修复的缺陷。在完成之前,对已更改文件执行的占位内容搜索必须无结果。模板中的 SEAM 注释必须实现,不得随代码提交。防止: 冲刺结束时,虚构内容却被标记为已完成。
  3. 铁律:每个文件只能输出一个版本。 写之前先做决定。备选方案应在代码之前用文字说明;文件一旦出现,方案就必须已确定。没有例外:绝不能在同一答案中提交“初稿……修正版”这样的版本对;如果初稿有误,就替换它,绝不能两个版本都交付。阻止某个文件的审查必须为每个受阻文件提交一个且仅一个修正版;只用文字说明修复方法的审查结论并不完整。防止: 给出三个候选方案,却没有一个被采纳。
  4. 只有记录的身份无法使用时才丢弃;字段有问题时应降级处理。 完整规则见 compose-data 技能(规则 4):缺失值在整个领域层中保持为 null;只有 id 缺失时才丢弃记录。防止: 悄无声息地丢失紧急记录,或生成看似有效的假值。
  5. 复用组件时,必须一并复用其调用位置的条件。 组件复用的门控规则见 compose-ui 技能(规则 6)。防止: 受先例门控的 UI 在新位置失效。
  6. 每个 UiState 字段都必须由 UI 读取,每个 UiAction 都必须由 UI 分发。 不得为了“以后再用”而保留无用字段,也不得保留没有发送方的无用操作。在完成之前,依据 Contract 交叉检查 Screen。防止: 契约逐渐失效,却无人渲染。
  7. 只有对新颖且难以撤销的选择,才提供备选方案。 规定好的工作直接构建。工具包已经做出的选择就照此构建,不要再讨论。防止: 审查时反复争论已确定的架构。

工作流

  • 为以下每个步骤创建一个待办事项,并按顺序执行。
  • 重述切片及所有可观察状态:冷启动加载、协调、刷新中、错误、重试、空状态、未找到、加载重叠、进程死亡后恢复。
  • 在项目中找到最接近的先例并完整阅读。小型任务只阅读直接相关的文件。
  • 开始编写前,盘点现有组件、格式化器和设计令牌。
  • 编写任何 Compose 代码前确定分层:始终执行 DTO 到领域模型的转换;仅在触发 M-11 条件时才执行领域模型到 UiModel 的转换(注明触发条件)。
  • 列出生命周期和并发情况:冷启动加载与协调、加载重叠、进程死亡后深层目的地的恢复。
  • 仅在模式不明确时阅读 examples.md。
  • 简要规划;交付物是文件:步骤 1–5 保持为不超过 25 行的精简清单计划,然后按固定顺序编写文件:Contract → ViewModel → Route/Screen → DI/nav → 测试。
  • 使用 scripts/new-feature.sh 搭建脚手架,或编写最精简且正确的代码。优先使用特定于功能的代码,而非通用框架。
  • 在组合根中注册新功能的 Koin 模块。避免: 目的地可以编译通过,却无法解析其 ViewModel。
scripts/new-feature.sh --name Notes --item Note --package com.example.feature.notes --root <project-root>
  • 运行以下验证关卡。
  • 用直白的语言报告偏差:哪些地方不一致,以及何时需要重新审视。

决策表

搭建脚手架还是手动编写
情况操作
在符合 kit 结构的模块中新建目的地使用 new-feature.sh 搭建脚手架,然后实现标记的 SEAM
修改现有目的地手动编写最精简且正确的差异;绝不重新搭建脚手架覆盖现有代码。绝不删除、重命名或移动任务未指定的现有可用行为(操作、状态字段、效果、测试、路由、错误处理接线,例如 HandleAppErrors)。看起来像遗留代码或与改动冲突的代码应保留;用一句话将其报告为后续事项。仅在收到请求时才重构。添加任务所需的内容(新操作、状态、仓库操作、列表渲染、接线)始终在范围内;“仅在收到请求时才重构”指不得重写或移动现有可用代码,绝不意味着可以拒绝实现所请求的功能
先例不一致(存在相互竞争的模式)新代码采用 kit 结构,指出不一致之处,并单独提出迁移方案
丢弃或降级有问题的记录
信号操作
缺少或无法使用身份标识(没有 id)丢弃记录
非身份字段缺失或格式错误保留该行;将字段设为 null,或将其标记为降级
在 DTO 边界处想用零、当前时间或 "" 代替的任何情况停下;缺失值在整个领域模型中都应保持为 null

危险信号

想法实际情况
“我先带着这些 TODO 发布;下个迭代再处理。”不行。功能规则 2:占位内容不能进入完成状态。
“暂时用这个存根仓库没问题;测试在它上面能通过。”不行。功能规则 2:存根会让错误状态和空状态无法通过验证。
“这个方法应该是存在的。”铁律:指出缺口;绝不调用虚构的方法。
“我先留一个空操作的函数体。”不行。铁律:绝不把空操作当作真实逻辑发布。
“我之后再验证辅助方法的名称;看起来没问题。”现在就停下来验证(功能规则 1)。M2 模型发布了虚构的 API。
“两份草稿展现了我的思路;读者可以自己选。”不行。功能规则 3(铁律):先做决定,再输出一个版本;绝不发布一对草稿。
“我用文字描述修复方案;修正后的文件显而易见。”不行。功能规则 3:阻塞性审查必须为每个阻塞文件准确提供一个修正后的版本。
“我列出测试用例行,不实际编写它们。”不行。验证门槛 18(状态矩阵测试):声称覆盖的矩阵行必须落实为书面测试。
“这条记录缺少一个字段;我把它默认设为零。”不行。功能规则 4:缺失值保留为 null;只有身份信息损坏时才丢弃记录。
“我丢弃这行;它的日期解析失败了。”不行。功能规则 4:降低该字段的数据质量,保留这一行。
“我复制了这个组件;这个条件只适用于那个屏幕。”不行。功能规则 5:复制组件时也要复制其门控逻辑。
“这个 UiState 字段以后再用;UI 很快就会读取它。”不行。功能规则 6:每个字段都必须读取,每个操作都必须派发。
“我会在 init 中加载,也会在启动时加载,以防万一。”不行。架构规则 9:init {} 中的加载或收集,加上启动触发器,会形成两个所有者;首次加载只能由启动触发器(LifecycleStartEffect)负责。
“我从缓存列表中解析详情;这样更快。”不行。架构规则 10 和 15:详情必须按身份信息获取;冷缓存中没有列表。
“内容上方刷新失败可以不提示。”不行。架构规则 8:只有明确指定的轮询才允许静默处理。
“文件级 var 是最简单的结果回调。”不行。架构规则 13:结果必须通过仓库写入。
“我会计时执行 runCurrent(),以捕获加载帧。”不行。验证门槛 18(状态矩阵测试;testing.md 中的 Fakes 规则):让 fake 在整个加载帧期间保持打开,而不是计时执行 runCurrent()。

验证

  • 编码前已复述切片及所有可观察状态(冷加载、协调、刷新、错误、重试、空状态、未找到、加载重叠、进程死亡后恢复)。
  • 已完整阅读最接近的先例;已盘点组件、格式化器和令牌。
  • 每个 *Contract.kt 中恰好包含 *UiState、*UiAction、*UiEffect(参见 compose-architecture 技能的规则 4)。统计每个文件中的声明数:
rg --files -g '*Contract.kt' <feature-root>
  • rg -n "TODO|FIXME|NotImplementedError" <changed-files> 无结果;每个模板中的 SEAM 均已实现或记录为偏差:
rg -n "TODO|FIXME|NotImplementedError" <changed-files>
  • 完成前,rg -n "SEAM" <module> 无结果;每个硬编码的 UI 字符串均已提取到资源文件:
rg -n "SEAM" <module>
  • 每个文件恰好只有一个版本;没有“或者”草稿。
  • 每个 launchGuarded 都显式传入 onError(参见 compose-architecture 技能的规则 6);没有 try/catch 链;重新抛出 CancellationException。
  • 每条失败路径恰好使用一个层级(架构规则 8);每个 Retry 都保留其错误。
  • 第一次 ON_START 是冷加载,后续的 ON_START 会在保留数据的同时进行协调;每个 LifecycleStartEffect 都以 nav-key id 为键。
  • 每次加载都使用已存储的 Job 防止重叠;有任务处于活动状态时跳过加载。
  • 详情目标通过 key 中的标识获取数据(参见 compose-architecture 技能的规则 10、15);缓存冷启动时会重新获取记录。
  • 草稿保存在 SavedStateHandle 中,并派生出 UiState(参见 compose-architecture 技能的规则 9–10);没有 rememberSaveable 镜像,也没有用于同步的 LaunchedEffect。
  • UI 会读取每个 UiState 字段;也会分发每个 UiAction。
  • 项目或当前文档中均能找到每个命名的辅助函数、令牌和导入项;没有杜撰内容。
  • 每个被调用的仓库方法都已在其接口上声明。
  • 丢弃的记录都缺少可用标识;数据降级时保留其行并使用 null 值,绝不臆造默认值。
  • 每个 locale 文件夹中都存在对应字符串,且键完全一致(参见 compose-ui 技能的规则 9)。
  • ViewModel 测试使用手写的 fake 覆盖状态矩阵;通过确定性方式完成测试(任何兼容 fake 的空闲时间推进方式均可)。
  • 所改动的模块可通过 common 元数据和一个平台的编译;其 JVM 测试通过。
  • 已安装时,scripts/composekit/run-checks.sh 以 0 退出。
  • 差异中没有删除任务未提及的内容:是或否。
  • 已交付请求的功能(或指出一个阻塞因素及解除阻塞所需的最小步骤):是或否。
  • 已用通俗语言报告偏差:偏离了什么,以及何时重新审视。

参考资料查阅

仅加载此任务需要的参考资料。只深入一层。

  • 新目标只有在脚手架模板未涵盖时,才另行阅读 mvi-contract.md。

  • 连接目标只有在脚手架模板未涵盖时,才另行阅读 navigation.md。

  • 更改现有状态时,另行阅读 state-ownership.md。

  • 只有更改失败路径时,才另行阅读 error-handling.md。

  • testing.md — ViewModel 测试约定、fake、状态矩阵行。

  • ui-testing.md — Compose UI 测试规则:查找器、断言、同步、延迟列表、状态恢复、KMP 运行器。

  • review-mode.md — 使用这些门槛审查他人的功能变更。

  • examples.md — 12 组错误/正确示例;仅在模式不明确时阅读。

  • README.md — 占位符、脚手架命令、组合根入口形式。

评论

支持 Markdown