原生 → Flutter 迁移
将正在运行的原生应用迁移至一个 Flutter 代码库。本技能采用 先创建文档,再基于文档实现,且仅当独立评审人批准后才进入下一步 的方式。假设输入仅为原生源代码文件夹。所有分析报告、PRD、规范和指令都会由本技能在每一步中自动创建。
为什么要这样做
- 两个应用都在运行中。 如果迁移后现有用户在登录、支付或存储数据中丢失任何一项,那就算是失败。因此,“任何操作系统上的用户都不能失去功能”是所有决策的首要前提。
- 源代码是唯一的真理。 凭记忆或推测写入的值在实际设备上必然会出错。所有数值、字符串、API和行为都必须附带源文件的
文件:行作为依据;没有依据时,请标注(推测)。 - 文档必须先达成一致,才能并行实现。 若要让多个模块Agent同时工作,它们各自需要读取的规范必须已经确定。如果规范悬而未决,同一界面会被修改两次(已有实例:在功能实现后又为了匹配UI而重新修改了整个界面 → 本技能会在实现之前就创建设计规范)。
- 编写者与审查者分离。 我们不信任实现方的报告,而是让位于独立上下文中的评审人直接比对代码与规范,只有通过审批才能进入下一步。
输入模式
启动时需确定模式。各阶段组成相同,但在每个阶段内要做的事情不同。不同模式之间的差异请参见各参考文件中的“按模式”章节。
| 模式 | 输入 | 核心差异 |
|---|---|---|
| BOTH | iOS项目 + Android项目 | 找出两个操作系统之间的业务/UI差异并归一化决定。确定UI基准平台,管理异常。两个操作系统的现有用户均需迁移。 |
| IOS_ONLY | 仅iOS项目 | 无差异决策。但需为新Android平台设计空白部分(如返回键、运行时权限、通知渠道、系统栏、应用ID/签名/新应用注册等)。 |
| ANDROID_ONLY | 仅Android项目 | 与上相反。需为新iOS平台设计空白部分(如Info.plist权限描述、APNs/entitlements、滑动返回手势、签名/配置文件/App Store新注册等)。 |
即使在单一操作系统模式下,也应单独询问Flutter产物的目标平台(仅原始OS / 双OS都支持)。
角色
| 角色 | 由谁担任 | 负责内容 |
|---|---|---|
| 编排者 | 本会话(我) | 阶段推进、Agent指令分发与汇总、公共文件修改、整体测试与构建、向用户汇报 |
| 编写/实现Agent | 子Agent(默认 model: opus,用户可指定其他模型) | 负责分配范围内的分析、文档、代码编写 |
| 评审人 | 默认 model: fable 子Agent(独立上下文)。用户可接入外部模型(GPT、Gemini等) | 直接比对文档/代码与原始代码、规范,批准或要求修改 |
| 用户 | 决策者 | 制定策略、UI/UX选择、真机确认、管理账户/密钥/商店操作 |
评审人与协作规则(仅追加的日志、仅以自己名义批准、同一修订需双方批准、评审人交接)请见 references/collaboration.md。使用外部模型时,由用户转发消息,因此采用基于文件的日志进行交互。
阶段地图
每个阶段产出交付物,并且必须通过关卡才能进入下一步。进入每个阶段时,请阅读对应的参考文件。
| # | 阶段 | 交付物(位于 <ws>/docs/ 下) | 关卡 | 要读的文件 |
|---|---|---|---|---|
| 0 | 启动与环境确认 | 00-kickoff.md(模式、目标平台、架构、原则、待定决策列表) | 用户确认 | references/00-kickoff.md |
| 1 | 源代码分析 | analysis/<os>_analysis.md、analysis/api_inventory.md、analysis/screen_inventory.md、(BOTH) analysis/business_diff.md / (单OS) analysis/new_platform_gaps.md | 评审人批准 | references/01-analysis.md |
| 2 | PRD | prd.md(决策表D编号、API契约、界面/功能需求、迁移/安全、阶段/关卡、验收场景)+ logs/prd_log.md | 评审人与我声明同一修订已完成 + 用户决策已反映 | references/02-prd.md |
| 3 | UI清单与设计规范 | design/<os>_ui_inventory.md、design_spec.md(令牌、组件、资源、字符串、按界面、平台异常、真机确认清单)、decisions.md(U编号)+ logs/design_log.md | 每个界面需双方批准 | references/03-design-spec.md |
| 4 | 实现指令 | impl_plan.md(架构约定、Phase/模块/层的工作ID、逆向引用表) | 评审人批准,无遗漏 | references/04-impl-plan.md |
| 5 | 公共基础与平台POC | Flutter项目、flavor/env、core(网络、错误、MVI、设计系统、字符串、资源、路由)、平台适配器/插件 | 真机POC通过 | references/05-build.md |
| 6 | 按模块实现 | 每个模块:data → domain → presentation → test、logs/impl_log.md | 每个模块需评审人批准 | references/05-build.md |
| 7 | 集成测试与修复 | 全部测试通过、覆盖率关卡、构建成功 | 零失败 | references/05-build.md |
| 8 | 真机QA循环 | qa_device_checklist.md、用户反馈 → U决策 → 修改 → 文档同步 | 用户声明“完成” | references/06-device-qa.md |
| 9 | 签名与发布 | 签名/配置文件、Firebase、CI、release_runbook.md(新OS需新注册) | 原始OS:相同应用ID/证书/更高版本号 / 新OS:可新签名/上传 | references/07-release.md |
| 10 | 维护文档 | <flutter>/docs/01~07、README.md | 评审人批准 | references/08-maintenance-docs.md |
如果收到跳过某些阶段的请求(例如:“分析已完成,从PRD开始”),需检查上一阶段的交付物是否存在;若缺失则告知缺少了什么,然后按用户决定继续。如果收到针对已实现功能的Flutter应用按原始UI调整的请求,请遵循 references/05-build.md 中的“变体路径”。
必须遵守的原则
这些原则会被抄写到每个阶段文档的开头,使所有Agent基于统一标准进行判断。
- 禁止阻止现有用户使用。 如果一个决定导致某侧操作系统的用户无法登录、支付或使用资产,那么这个决定就是错误的。对于触及现有数据的验证(如登录格式检查)要宽松,新输入策略需与服务器端一致。
- 默认不修改服务器。 除非另有指示,所有问题应在现有API契约内解决。必须依赖服务器的改进应作为“开放问题”分开处理。
- 不复制缺陷。 不要以“对等性”为由将原始bug迁移过来。应确定预期结果并通过回归测试固定。如果用户可见的结果改变,必须将其列入决策列表并得到用户确认。
- UI基准OS(仅适用于BOTH模式、迁移期间)。 若视觉效果不同,使用基准OS的值。需询问用户以哪个OS为基准,不设默认值。此原则仅在迁移原生代码期间生效。迁移完成后,切换为“当前Flutter行为是基准,变更需用户决定”(第10阶段)。异常仅限三种:(a) 遵循基准OS会导致另一OS用户无法使用功能或破坏平台特有行为;(b) 基准OS行为与PRD决策冲突;(c) 基准OS值存在明显bug(保留视觉,仅纠正行为)。
- 必须注明依据。 原始代码的
文件:行。无依据的值标注(推测),需在真机上验证的值标注(真机),源代码中完全没有而需新定义的值标注(新定义)。 - 不引入原始代码中不存在的内容。 不要因为“看起来更好”就引入原始应用中不存在的外部SDK、外部服务或额外配置(如商业安全SDK、通知邮件地址)。应优先移植原始实现方式;如需更改,请连同原因一起询问用户。
- 不得随意删除可见文本或功能。 即使原始提示文本看起来与实际行为不符,也不要删除它,而应询问用户(是保留文本,还是调整行为以匹配文本)。
- 决策保留ID。 PRD决策用
D-n,用户UX决策用U-n。如果决策发生变化,需同时更新代码、测试、规范和决策记录。每个工作轮次结束时,使文档与代码保持同步。 - 不输出秘密值。 密钥库密码、API密钥等仅通过文件传递,不在对话或日志中显示。哪些文件可以提交到仓库取决于用户策略(见
references/07-release.md)。
Agent操作规则
- 范围所有权。 模块Agent只能修改自己模块的文件夹。如果需要修改公共文件(core、app、依赖项、资源、字符串),不直接修改,而是在最终报告中的“公共请求”部分记录。由编排者汇总后一次性反映。这是在并行工作中防止冲突最廉价的方法。
- 测试时机。 当按顺序逐个模块进行时,Agent需运行自己模块的测试。当按并行波浪(wave)进行多个模块时,Agent只需让自己文件夹的
dart analyze通过,而整体flutter test和构建则在波浪结束后由编排者一次性运行。多个Agent同时写入同一build/目录会导致工具崩溃。 - 评审人不信任报告。 评审指令中需包含“不要依赖工作Agent的报告,直接比较代码与规范”。评审人不修改代码。
- 简短报告。 Agent的最终报告应有行数限制(模板位于
templates/)。较长的内容应写入日志文件。 - 并行执行。 独立的分析、模块和文档工作应通过多次Agent调用同时启动。由于本技能被调用本身即代表同意多Agent并行,因此当波浪较大时,可使用工作流工具(编写→评审→修改流水线)。在开始前,用一行信息告知用户波浪大小和所用模型。
- 恢复。 每个日志文件顶部保留进度状态表,并始终保持最新。如果会话中断,仅读取
00-kickoff.md和各日志的进度状态表即可继续。
需向用户询问的时机
以下事项不由我自行决定。应提供选项和推荐方案(附依据)并简要呈现,等待用户答复。
- 启动问题列表(
references/00-kickoff.md) - 业务差异中用户可见结果会发生变化的部分、需要服务器确认的部分
- UI基准OS及其异常涉及功能或视觉发生重大变化的部分
- 引入原始代码中没有的库/服务、删除原始功能/文本
- 需要账户的操作(Apple Developer、Play Console、Firebase控制台)、秘密值存放位置
- 仓库提交策略、远程仓库是否公开
如果用户回复“按推荐执行”,将推荐方案记入决策(U编号)后继续执行。
阶段结束报告
每个阶段结束时,仅向用户简要报告以下内容:创建的文档(路径)、评审结果(指出数量、已采纳/已驳回及原因)、需要用户决策的事项(含推荐方案)、下一步骤。对于未验证的内容,需注明“未验证”。
参考文件
| 文件 | 使用时机 |
|---|---|
references/00-kickoff.md | 开始时 |
references/01-analysis.md | 源代码分析 |
references/02-prd.md | PRD编写与达成一致 |
references/03-design-spec.md | UI清单与设计规范 |
references/04-impl-plan.md | 实现指令 |
references/05-build.md | 公共基础、模块实现、集成测试 |
references/06-device-qa.md | 真机QA循环 |
references/07-release.md | 签名、flavor、Firebase、CI、发布 |
references/08-maintenance-docs.md | 维护文档 |
references/collaboration.md | 协作编写、评审、交接规则 |
references/pitfalls.md | 实际迁移中曾出现过的问题与预防方法——第5阶段后随时查阅 |
templates/*.md | Agent指令、评审指令、报告格式 |