prd-to-flutter 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/README.md +149 -0
  2. package/bin/p2f.mjs +18 -0
  3. package/dist/cli.js +203 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/commands/clean.js +35 -0
  6. package/dist/commands/clean.js.map +1 -0
  7. package/dist/commands/doctor.js +148 -0
  8. package/dist/commands/doctor.js.map +1 -0
  9. package/dist/commands/generate.js +120 -0
  10. package/dist/commands/generate.js.map +1 -0
  11. package/dist/commands/init.js +46 -0
  12. package/dist/commands/init.js.map +1 -0
  13. package/dist/commands/paths.js +58 -0
  14. package/dist/commands/paths.js.map +1 -0
  15. package/dist/commands/remove.js +23 -0
  16. package/dist/commands/remove.js.map +1 -0
  17. package/dist/commands/screenshots-audit.js +39 -0
  18. package/dist/commands/screenshots-audit.js.map +1 -0
  19. package/dist/commands/skills-install.js +21 -0
  20. package/dist/commands/skills-install.js.map +1 -0
  21. package/dist/commands/sync.js +84 -0
  22. package/dist/commands/sync.js.map +1 -0
  23. package/dist/commands/update.js +93 -0
  24. package/dist/commands/update.js.map +1 -0
  25. package/dist/core/existing-page-detector.js +463 -0
  26. package/dist/core/existing-page-detector.js.map +1 -0
  27. package/dist/core/fail-fast.js +50 -0
  28. package/dist/core/fail-fast.js.map +1 -0
  29. package/dist/core/feature-coverage-builder.js +667 -0
  30. package/dist/core/feature-coverage-builder.js.map +1 -0
  31. package/dist/core/flutter-project-scanner.js +393 -0
  32. package/dist/core/flutter-project-scanner.js.map +1 -0
  33. package/dist/core/implementation-plan-writer.js +190 -0
  34. package/dist/core/implementation-plan-writer.js.map +1 -0
  35. package/dist/core/logger.js +39 -0
  36. package/dist/core/logger.js.map +1 -0
  37. package/dist/core/package-info.js +33 -0
  38. package/dist/core/package-info.js.map +1 -0
  39. package/dist/core/paths.js +37 -0
  40. package/dist/core/paths.js.map +1 -0
  41. package/dist/core/playwright-capture.js +539 -0
  42. package/dist/core/playwright-capture.js.map +1 -0
  43. package/dist/core/playwright-cli.js +26 -0
  44. package/dist/core/playwright-cli.js.map +1 -0
  45. package/dist/core/playwright-install.js +40 -0
  46. package/dist/core/playwright-install.js.map +1 -0
  47. package/dist/core/prd-clone.js +131 -0
  48. package/dist/core/prd-clone.js.map +1 -0
  49. package/dist/core/prd-install.js +108 -0
  50. package/dist/core/prd-install.js.map +1 -0
  51. package/dist/core/profile.js +149 -0
  52. package/dist/core/profile.js.map +1 -0
  53. package/dist/core/project-doc-reader.js +252 -0
  54. package/dist/core/project-doc-reader.js.map +1 -0
  55. package/dist/core/report-writer.js +90 -0
  56. package/dist/core/report-writer.js.map +1 -0
  57. package/dist/core/route-name.js +60 -0
  58. package/dist/core/route-name.js.map +1 -0
  59. package/dist/core/run-context.js +160 -0
  60. package/dist/core/run-context.js.map +1 -0
  61. package/dist/core/screenshot-auditor.js +405 -0
  62. package/dist/core/screenshot-auditor.js.map +1 -0
  63. package/dist/core/screenshot-exploration-plan-writer.js +200 -0
  64. package/dist/core/screenshot-exploration-plan-writer.js.map +1 -0
  65. package/dist/core/semantic-model-builder.js +922 -0
  66. package/dist/core/semantic-model-builder.js.map +1 -0
  67. package/dist/core/skill-install.js +78 -0
  68. package/dist/core/skill-install.js.map +1 -0
  69. package/dist/core/stage-stub.js +24 -0
  70. package/dist/core/stage-stub.js.map +1 -0
  71. package/dist/core/task-index-writer.js +149 -0
  72. package/dist/core/task-index-writer.js.map +1 -0
  73. package/dist/core/update-checker.js +155 -0
  74. package/dist/core/update-checker.js.map +1 -0
  75. package/dist/core/vue-page-locator.js +748 -0
  76. package/dist/core/vue-page-locator.js.map +1 -0
  77. package/dist/core/vue-project-reader.js +116 -0
  78. package/dist/core/vue-project-reader.js.map +1 -0
  79. package/docs/artifacts-and-agent.md +203 -0
  80. package/docs/development.md +118 -0
  81. package/docs/usage.md +246 -0
  82. package/package.json +50 -0
  83. package/skills/p2f/SKILL.md +303 -0
  84. package/skills/p2f/references/page-layout-patterns.md +120 -0
  85. package/skills/p2f/references/youfi-flutter-guidelines.md +71 -0
package/docs/usage.md ADDED
@@ -0,0 +1,246 @@
1
+ # 使用流程
2
+
3
+ 本文档说明 p2f 的日常使用方式:初始化、同步、生成页面数据、审阅数据、交给 agent 实现。
4
+
5
+ ## 初始化
6
+
7
+ 在 YouFi Flutter 项目根目录执行,也就是包含 `pubspec.yaml` 和 `lib/app` 的目录:
8
+
9
+ ```bash
10
+ p2f init
11
+ ```
12
+
13
+ 初始化会创建:
14
+
15
+ ```text
16
+ .p2f-workspace/
17
+ prd-source/ # PRD 原型源码
18
+ project/ # Flutter 项目级共享快照
19
+ pages/ # 每个页面任务的数据、CLI 产物和 agent 产物
20
+ logs/ # init/sync 等系统命令日志
21
+ ```
22
+
23
+ 同时会把内置 skill 安装到 `.claude/skills/p2f` 和 `.codex/skills/p2f`。
24
+
25
+ ## 常用命令
26
+
27
+ | 命令 | 说明 |
28
+ | --- | --- |
29
+ | `p2f init` | 在当前项目创建 p2f 工作区,准备 PRD 源码本地副本、原型依赖、Playwright Chromium 和内置 p2f skill。 |
30
+ | `p2f sync` | 从 PRD 远端 `origin/master` 拉取最新代码,并覆盖当前项目的 `.p2f-workspace/prd-source`;不会 push。 |
31
+ | `p2f generate "<页面链接>"` | 生成结构化页面数据、JSON、源码范围和实现计划,供 agent 后续探索截图并实现页面;页面名默认从 URL 路由提取。 |
32
+ | `p2f paths --url "<页面链接>"` | 打印当前项目的 p2f 工作区、共享项目快照、pages 和任务目录路径。 |
33
+ | `p2f clean "<页面目录名称>"` | 删除指定页面目录,例如 `stock-detail`;不删除 `prd-source` 或共享项目快照。 |
34
+ | `p2f clean --url "<页面链接>"` | 从页面 URL 解析任务名并删除对应页面目录。 |
35
+ | `p2f clean --all` | 删除全部 `.p2f-workspace/pages`;不删除 `prd-source` 或共享项目快照。 |
36
+ | `p2f remove` | 删除当前项目里的 `.p2f-workspace/`、`.claude/skills/p2f` 和 `.codex/skills/p2f`。 |
37
+ | `p2f screenshots-audit --url "<页面链接>"` | 审计 agent 截图目录,识别重复截图和疑似截到原型平台壳层的错误截图。 |
38
+ | `p2f doctor` | 检查环境、skill、`.p2f-workspace/prd-source` 和 p2f 版本。 |
39
+ | `p2f doctor --offline` | 跳过远端网络检查,只检查本地状态。 |
40
+ | `p2f update --check` | 检查当前 p2f 是否有新版本,不安装。 |
41
+ | `p2f update` | 从公司 GitLab 最新 tag 重新全局安装 p2f CLI。 |
42
+ | `p2f skills-install` | 把当前 CLI 自带的 p2f skill 安装/更新到当前项目的 agent 目录。 |
43
+
44
+ ## 标准流程
45
+
46
+ 下面的 Stage 是人类和 agent 都必须遵守的执行流程。不要手工逐个执行 `sync-prd-source`、`capture-runtime` 这类内部子阶段;它们由对应命令自动执行并打印。
47
+
48
+ ### Stage 1:初始化环境
49
+
50
+ 首次使用或环境损坏时执行:
51
+
52
+ ```bash
53
+ p2f init
54
+ ```
55
+
56
+ 作用:
57
+
58
+ - 创建 `.p2f-workspace/`。
59
+ - 克隆或同步 PRD 原型源码到 `.p2f-workspace/prd-source`。
60
+ - 安装原型项目依赖。
61
+ - 安装 Playwright Chromium。
62
+ - 安装/更新内置 p2f skill 到 agent 目录。
63
+
64
+ 当前项目已经执行过 `p2f init` 且 `p2f doctor` 检查通过时,可以跳过。
65
+
66
+ ### Stage 2:同步 PRD 原型源码
67
+
68
+ 每次还原页面前执行:
69
+
70
+ ```bash
71
+ p2f sync
72
+ ```
73
+
74
+ 作用:
75
+
76
+ - 从 PRD 远端 `origin/master` 拉取最新原型代码。
77
+ - 重置当前项目的 `.p2f-workspace/prd-source`。
78
+ - 不会 push,不会修改 Flutter 业务代码。
79
+
80
+ ### Stage 3:采集单页数据和实现计划
81
+
82
+ 每个页面执行一次:
83
+
84
+ ```bash
85
+ p2f generate "<页面链接>"
86
+ ```
87
+
88
+ 例子:
89
+
90
+ ```bash
91
+ p2f generate "https://example.com/prototype/order-detail"
92
+ ```
93
+
94
+ 可选指定页面名:
95
+
96
+ ```bash
97
+ p2f generate --page "订单详情" "https://example.com/prototype/order-detail"
98
+ ```
99
+
100
+ 兼容旧用法:
101
+
102
+ ```bash
103
+ p2f generate "订单详情" "https://example.com/prototype/order-detail"
104
+ ```
105
+
106
+ 作用:
107
+
108
+ - 定位 Vue 页面入口和相关源码。
109
+ - 若原型页面存在产品文档 `.md` 或 prototype i18n JSON,同步到 `cli/source/` 并生成中文索引。
110
+ - 从 Vue 源码和原型产品文档整理 `cli/analysis/feature-coverage.md`。
111
+ - 用 Playwright 只采集运行态结构数据:DOM、a11y、computed styles、visible text、console 和 page error。
112
+ - 生成 `cli/analysis/screenshot-exploration-plan.md`,要求 agent 打开 live prototype 主动探索并补齐截图。
113
+ - 扫描 Flutter 项目,判断目标页面是否已经存在。
114
+ - 生成 `main.md`、`cli/analysis/implementation-plan.md`、`cli/output/generate-report.md` 和 `agent/manifest.json` 模板。
115
+
116
+ ### Stage 4:审阅数据
117
+
118
+ 实现前必须打开 `.p2f-workspace/pages/<task-name>/main.md`,按里面的路径审阅。先读 Markdown 摘要和计划,大型 JSON 按需读取,不要一次性把所有产物塞进上下文:
119
+
120
+ 1. `cli/analysis/page-summary.md`:确认页面类型和核心结构。
121
+ 2. `cli/analysis/feature-coverage.md`:确认源码/产品文档中的功能、状态、交互。
122
+ 3. `cli/source/product-docs-index.md`:如果存在产品文档,先阅读同步出的 `.md` 副本。
123
+ 4. `cli/source/prototype-i18n.md`:如果存在多语言,参考 key 和多语言文案对照。
124
+ 5. `cli/analysis/screenshot-exploration-plan.md`:agent 必须打开 live prototype 主动探索、截图并记录不可达状态。
125
+ 6. `cli/runtime/interactions.candidate.json`:只作为探索线索,不能当作完整交互覆盖,需要时再读取。
126
+ 7. `cli/analysis/implementation-plan.md`:确认目标 Flutter 文件、复用候选、风险点和不确定项。
127
+
128
+ 如果 Stage 4 发现关键状态缺截图,agent 先继续探索补图或记录不可达原因,不要直接开始实现。
129
+
130
+ 如果自动截图落入登录过期、重登上下文失效、权限拦截、错误账号、错误路由等非目标态,agent 必须在 `agent/runtime/agent-screenshot-exploration.json` 中标记为 `invalid-context` 或 `superseded`,不能继续把该截图作为实现基准。用户提供的手动截图或明确确认的目标态必须记录为 `manualBaselines`,并优先作为实现基准。
131
+
132
+ agent 生成的截图、探索日志、说明文件和实际修改的 Flutter 文件,都必须记录到 `agent/manifest.json`。
133
+
134
+ ### Stage 5:由 agent 实现 Flutter 页面
135
+
136
+ agent 必须基于 Stage 4 的数据实现页面。p2f CLI 不直接生成 Dart 页面代码。
137
+
138
+ 实现时优先使用:
139
+
140
+ - `main.md`
141
+ - `cli/source/product-docs-index.md`
142
+ - `cli/source/prototype-i18n.md`
143
+ - `cli/analysis/feature-coverage.md`
144
+ - `cli/analysis/screenshot-exploration-plan.md`
145
+ - `agent/screenshots/`
146
+ - `agent/runtime/agent-screenshot-exploration.json`
147
+ - `agent/manifest.json`
148
+ - `cli/analysis/ui-structure.md`
149
+ - `cli/analysis/implementation-plan.md`
150
+
151
+ `cli/runtime/dom.json`、`cli/runtime/computed-styles.json` 等大型 JSON 只在需要定位结构、样式或 selector 时读取相关片段。
152
+
153
+ 实现后在 YouFi Flutter 项目里运行必要检查,例如:
154
+
155
+ ```bash
156
+ flutter analyze
157
+ ```
158
+
159
+ 格式化 Dart 代码时只传 `.dart` 文件或 Dart 源码目录,不要把 `.p2f-workspace/pages/**` 下的 JSON、Markdown 或截图探索产物加入 `dart format` 参数。
160
+
161
+ ## 命令阶段
162
+
163
+ p2f 面向人类和 agent 共同使用。所有命令都可以手工执行;执行中的关键步骤会以 `Stage: ...` 打印,失败报告会包含失败阶段、失败动作、失败原因、已完成步骤、未完成步骤和建议方案。
164
+
165
+ | 命令 | 执行阶段 | 适用场景 |
166
+ | --- | --- | --- |
167
+ | `p2f init` | `sync-prd-source` -> `prd-install` -> `playwright-install` -> `skill-install` | 首次使用、PRD 依赖损坏、Chromium 缺失或需要重新安装内置 skill。 |
168
+ | `p2f sync` | `prd-sync-check` -> `prd-sync-update` | 从远端拉取 PRD 原型源码并重置 `.p2f-workspace/prd-source`,不安装依赖和 skill。 |
169
+ | `p2f generate` | `sync-prd-source` -> `read-flutter-docs` -> `read-vue-docs` -> `locate-vue-page` -> `build-feature-coverage` -> `capture-runtime` -> `build-semantic-model` -> `merge-feature-coverage` -> `write-screenshot-exploration-plan` -> `detect-existing-page` -> `write-implementation-plan` -> `write-report` | 采集单个页面结构化数据并生成 agent 截图探索与实现计划。 |
170
+ | `p2f paths` | `resolve-paths` | 查看 workspace、共享项目快照、pages、任务目录、CLI/agent 目录和 `main.md` 路径。 |
171
+ | `p2f clean "<页面目录名称>"` | `clean-pages` | 删除指定任务页面目录,例如 `p2f clean "stock-detail"`。 |
172
+ | `p2f clean --url "<页面链接>"` | `clean-pages` | 从页面 URL 解析任务名并删除对应页面目录。 |
173
+ | `p2f clean --all` | `clean-pages` | 删除全部 pages。 |
174
+ | `p2f remove` | `remove` | 删除 `.p2f-workspace/` 和当前项目下的 p2f agent skills;不卸载全局 CLI。 |
175
+ | `p2f screenshots-audit` | `screenshots-audit` | 扫描 agent 写入的 `agent/screenshots/`,输出重复图分组和疑似平台壳层截图告警。 |
176
+ | `p2f doctor` | `environment-checks` -> `skill-check` -> `prd-source-check` -> `update-check` | 检查环境、初始化状态和版本;`--offline` 会跳过网络检查。 |
177
+ | `p2f update --check` | `update-check` | 只检查是否有新版本。 |
178
+ | `p2f update` | `update-check` -> `update-install` | 检查 p2f CLI 版本,并用最新 tag 重新执行全局安装。 |
179
+ | `p2f skills-install` | `skill-install` | 安装/更新内置 p2f skill;不修改 PRD 源码和页面目录。 |
180
+
181
+ ## Generate 流程
182
+
183
+ `p2f generate` 是主流程,执行时会逐个打印下面这些阶段。任何关键阶段失败都会 fail-fast,不基于不完整信息继续生成实现计划。
184
+
185
+ | 阶段 | 作用 |
186
+ | --- | --- |
187
+ | `sync-prd-source` | 确保当前项目存在 `.p2f-workspace/prd-source`,并从 PRD 远端 `origin/master` 拉取最新代码后重置本地副本;不会 push。 |
188
+ | `read-flutter-docs` | 读取 YouFi Flutter 项目文档、目录结构、主题文件和路由信息,并提前写入共享快照 `.p2f-workspace/project/flutter-project.json`。 |
189
+ | `read-vue-docs` | 读取 PRD 原型项目结构、registry 和文档信息。 |
190
+ | `locate-vue-page` | 根据 URL 定位 Vue 页面入口、路由信息和相关源码文件;如果存在页面产品文档和 prototype i18n JSON,会复制到 `cli/source/` 并生成中文索引。 |
191
+ | `build-feature-coverage` | 从 Vue 入口、相关组件和原型产品文档整理功能、状态、交互覆盖清单。 |
192
+ | `capture-runtime` | 使用 Playwright 采集 DOM、a11y、computed styles、visible text、console 和 page error;采集前会校验目标路由、`is_mobile=1&app_simulator=1` 和 `.phone-screen`,避免把原型平台菜单 / 工作台壳层当成目标页面。此阶段不截图。 |
193
+ | `build-semantic-model` | 把运行态数据归纳为页面类型、结构块、设计 token 候选和候选交互。 |
194
+ | `merge-feature-coverage` | 将源码/文档识别出的交互补充进 agent 探索候选,减少 live-page 探索遗漏。 |
195
+ | `write-screenshot-exploration-plan` | 生成 agent 截图探索任务书,要求 agent 基于 live prototype 主动点击、滚动、补齐截图并记录探索日志。 |
196
+ | `detect-existing-page` | 基于 `read-flutter-docs` 阶段生成的共享快照判断目标 Flutter 页面是否已存在;输出 `exists`、`uncertain`、`missing` 三态、证据明细和低置信复核任务。 |
197
+ | `write-implementation-plan` | 输出 agent 可审阅的实现计划、风险点、不确定项和下一步。 |
198
+ | `write-report` | 输出本次任务报告。 |
199
+
200
+ `generate` 完成后,agent 必须读取任务目录里的数据再实现 Dart 页面,不应让 CLI 直接写页面代码。
201
+
202
+ 原型和设计稿页面的 Playwright 手机采集 viewport 固定为 `375x812`,与设计稿基准保持一致。
203
+
204
+ `build-feature-coverage` 只会从 `.vue` 模板和原型产品文档推导可执行交互;非 Vue 相关文件只作为来源记录,不会把 mock/config 数据、图表字段或 SVG 标签误当成可点击 tab。
205
+
206
+ `locate-vue-page` 会把当前页面显式声明的 `notes`、按 `view` 或 related Vue 组件名推导的 `prototype/notes/**/*.md`、以及按 `screenId` 命中的 `src/i18n/prototype/<screenId>.json` 同步到页面 CLI 产物目录:
207
+
208
+ - `cli/source/product-docs-index.md` / `cli/source/product-docs-index.json`
209
+ - `cli/source/product-docs/**`
210
+ - `cli/source/prototype-i18n.md` / `cli/source/prototype-i18n-index.json`
211
+ - `cli/source/i18n/<screenId>.json`
212
+
213
+ ## 项目结构 Profile
214
+
215
+ `p2f generate` 默认使用内置 `youfi-default` profile。若 Flutter App 或 PRD 原型目录移动,但框架/语法约定没有变,可以在 Flutter 项目根目录新增 `p2f.config.json`(或 `.p2f/config.json`)覆盖扫描路径,不需要改 CLI 代码。
216
+
217
+ 示例:
218
+
219
+ ```json
220
+ {
221
+ "profile": "youfi-default",
222
+ "flutter": {
223
+ "appRootCandidates": ["lib/app"],
224
+ "moduleRoots": ["lib/features"],
225
+ "routeFiles": {
226
+ "constants": ["lib/router/app_routes.dart"],
227
+ "pages": ["lib/router/app_pages.dart"]
228
+ },
229
+ "commonWidgetRoots": ["lib/shared/widgets"],
230
+ "translationRoots": ["lib/i18n"]
231
+ },
232
+ "prototype": {
233
+ "subprojectCandidates": ["frontend", "prototype", "."],
234
+ "viewsDirs": ["src/pages", "src/views"],
235
+ "registryFiles": [
236
+ { "path": "src/config/prdPageRegistry.js", "kind": "prototype" },
237
+ { "path": "src/config/specScreens.js", "kind": "spec" },
238
+ { "path": "src/config/designScreens.js", "kind": "design" }
239
+ ],
240
+ "notesRoots": ["notes", "docs/notes"],
241
+ "i18nPrototypeRoots": ["src/i18n/prototype"]
242
+ }
243
+ }
244
+ ```
245
+
246
+ 配置中的数组会替换默认数组;如果只是增加候选路径,需要把默认候选一起写上。若路由从 GetX `GetPage` 换成 GoRouter/AutoRoute,或原型 registry 语法彻底变化,仅改 profile 不够,需要新增 scanner adapter 后再发布 CLI。
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "prd-to-flutter",
3
+ "version": "0.1.0",
4
+ "private": false,
5
+ "description": "为 PRD 原型页面采集 YouFi Flutter 还原数据并生成实现计划的 CLI。",
6
+ "type": "module",
7
+ "p2f": {
8
+ "updateRepo": "git@code.nexita.net:inno/youfi/client/prd-to-flutter.git"
9
+ },
10
+ "bin": {
11
+ "p2f": "bin/p2f.mjs"
12
+ },
13
+ "main": "dist/cli.js",
14
+ "publishConfig": {
15
+ "registry": "https://registry.npmjs.org/"
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "bin",
20
+ "skills",
21
+ "docs",
22
+ "README.md"
23
+ ],
24
+ "scripts": {
25
+ "build": "npm run clean && tsc -p tsconfig.json",
26
+ "prepare": "npm run build",
27
+ "dev": "tsc -p tsconfig.json --watch",
28
+ "start": "node ./bin/p2f.mjs",
29
+ "release": "node scripts/release.mjs",
30
+ "release:patch": "node scripts/release.mjs patch",
31
+ "release:minor": "node scripts/release.mjs minor",
32
+ "release:major": "node scripts/release.mjs major",
33
+ "publish:npm": "node scripts/publish-npm.mjs",
34
+ "typecheck": "tsc -p tsconfig.json --noEmit",
35
+ "clean": "rm -rf dist"
36
+ },
37
+ "engines": {
38
+ "node": ">=20"
39
+ },
40
+ "dependencies": {
41
+ "commander": "^12.1.0",
42
+ "execa": "^9.4.0",
43
+ "picocolors": "^1.1.0",
44
+ "playwright": "^1.52.0"
45
+ },
46
+ "devDependencies": {
47
+ "@types/node": "^20.16.10",
48
+ "typescript": "^5.6.3"
49
+ }
50
+ }
@@ -0,0 +1,303 @@
1
+ ---
2
+ name: p2f
3
+ description: Use when restoring YouFi Flutter pages from PRD prototype links with the p2f CLI, including syncing PRD source, generating structured page data and implementation plans, performing agent-led live screenshot exploration, reviewing .p2f-workspace artifacts, and following YouFi routing/theme implementation rules.
4
+ metadata:
5
+ short-description: Restore YouFi pages from PRD prototypes
6
+ ---
7
+
8
+ # p2f
9
+
10
+ 当用户要求“用 p2f 还原页面”“根据 PRD 原型生成 Flutter 实现计划”“根据页面链接采集还原数据”时使用本 skill。
11
+
12
+ ## 用户入口
13
+
14
+ 用户通常会说:
15
+
16
+ ```text
17
+ 帮我用 p2f 还原 xxx 页面,页面链接为:xxxxx
18
+ ```
19
+
20
+ 从用户描述中解析:
21
+
22
+ - `prototypeUrl`:页面链接,即 `页面链接为` 后面的 URL 或路径,必填。
23
+ - `pageName`:页面名称,可选。用户未指定时,由 `p2f generate` 从 URL 路由自动提取。
24
+
25
+ 命令必须在 Flutter 项目根目录执行,也就是包含 `pubspec.yaml` 的目录。
26
+
27
+ ## 常用命令
28
+
29
+ ```bash
30
+ p2f init
31
+ p2f sync
32
+ p2f generate "<页面链接>"
33
+ p2f paths --url "<页面链接>"
34
+ p2f clean "<页面目录名称>"
35
+ p2f clean --url "<页面链接>"
36
+ p2f clean --all
37
+ p2f remove
38
+ p2f screenshots-audit --url "<页面链接>"
39
+ p2f doctor
40
+ p2f doctor --offline
41
+ p2f update --check
42
+ p2f update
43
+ ```
44
+
45
+ `p2f init` 会自动安装 PRD 依赖、Playwright Chromium 和内置 p2f skill,不需要手工执行 `npx playwright install chromium`。
46
+
47
+ 请直接使用 p2f 项目已安装的 Playwright。
48
+
49
+ ## 注意事项
50
+
51
+ 请不要修改 Flutter 项目已有代码的格式。
52
+
53
+ ## 执行流程
54
+
55
+ 下面的 Stage 是人类和 agent 都必须遵守的流程。不要手工逐个执行 `sync-prd-source`、`capture-runtime` 这类内部子阶段;它们由对应命令自动执行并打印。
56
+
57
+ ### Stage 1:初始化环境
58
+
59
+ 首次使用、环境损坏、Playwright Chromium 缺失或 skill 需要更新时,在 Flutter 项目根目录执行:
60
+
61
+ ```bash
62
+ p2f init
63
+ ```
64
+
65
+ 如果当前项目已经初始化且 `p2f doctor` 通过,可以跳过 Stage 1。
66
+
67
+ ### Stage 2:同步 PRD 原型源码
68
+
69
+ 每次还原页面前必须执行:
70
+
71
+ ```bash
72
+ p2f sync
73
+ ```
74
+
75
+ 如果失败,停止并向用户报告失败阶段、失败动作、失败原因和建议方案。
76
+
77
+ ### Stage 3:采集单页数据和实现计划
78
+
79
+ ```bash
80
+ p2f generate "<页面链接>"
81
+ ```
82
+
83
+ 该命令会自动从 URL 路由提取页面名,并执行内部子阶段:定位 Vue 页面、整理功能覆盖清单、采集运行态结构数据、生成 agent 截图探索计划、扫描 Flutter 目标页面、输出实现计划。
84
+
85
+ 采集阶段会自动附加 `is_mobile=1&app_simulator=1`,并校验最终页面确实进入目标路由的 `.phone-screen`。如果加载到原型平台菜单 / 工作台壳层,必须停止,不能把壳层当作页面数据。
86
+
87
+ 原型和设计稿页面的运行态采集 viewport 固定为 `375x812`。后续 agent 截图探索也必须按该基准处理,除非用户明确指定其他 viewport。
88
+
89
+ 如果用户明确指定页面名,使用:
90
+
91
+ ```bash
92
+ p2f generate --page "<页面名>" "<页面链接>"
93
+ ```
94
+
95
+ ### Stage 4:agent live-page 截图探索
96
+
97
+ 读取 `.p2f-workspace/pages/<task-name>/main.md`,并按顺序审阅。先读 Markdown 摘要和计划,大型 JSON 按需读取,不要一次性把所有产物塞进上下文:
98
+
99
+ 1. `cli/analysis/page-summary.md`:确认页面类型和核心结构。
100
+ 2. `cli/analysis/feature-coverage.md`:确认源码/产品文档中的功能、状态、交互。
101
+ 3. `cli/source/product-docs-index.md`:如果存在产品文档,先阅读同步出的 `.md` 副本。
102
+ 4. `cli/source/prototype-i18n.md`:如果存在多语言,参考 key 和多语言文案对照。
103
+ 5. `cli/analysis/screenshot-exploration-plan.md`:按计划打开 live prototype 主动探索并截图。
104
+ 6. `cli/runtime/interactions.candidate.json`:只作为探索线索,不能当作完整交互覆盖,需要时再读取。
105
+ 7. `cli/analysis/implementation-plan.md`:确认目标 Flutter 文件、复用候选、风险点和不确定项。
106
+
107
+ Stage 4 是实现前的强制步骤。agent 必须:
108
+
109
+ - 打开 `cli/analysis/screenshot-exploration-plan.md` 中的 `targetUrl`。
110
+ - 必须使用计划里的实际探索链接,不要回退到原始链接;实际探索链接已附加 `is_mobile=1&app_simulator=1`。
111
+ - 等待页面稳定后截图首屏。
112
+ - 主动滚动所有有意义的滚动容器。
113
+ - 主动寻找并探索 Tab、筛选、下拉、弹窗、底部抽屉、输入聚焦、展开/折叠、图表/详情切换、空态/错误态等状态。
114
+ - 不只依赖 `cli/runtime/interactions.candidate.json`;它只是线索。agent 必须根据 live UI、DOM、源码和 feature coverage 继续发现遗漏状态。
115
+ - 截图必须截 `.phone-screen` 元素,禁止保存整个浏览器 viewport 或整页截图。
116
+ - 如果截图里出现 TradeApp Workflow Hub、左侧平台菜单、搜索框、Docs/UI 规范/交互原型/设计稿入口,说明截错了,必须删除重截。
117
+ - 如果自动截图落入登录过期、重登上下文失效、权限拦截、错误账号、错误路由等非目标态,不要把该截图作为实现基准;必须在 `agent/runtime/agent-screenshot-exploration.json` 中把尝试标记为 `invalid-context` 或 `superseded`。
118
+ - 如果用户提供了手动截图或明确确认目标态,必须记录为 `manualBaselines`,并优先按该基准实现。
119
+ - 同一状态 UI 完全一致时不要保存重复 PNG,记录为 `no-effect` 或 `duplicate`。
120
+ - 将截图写入 `agent/screenshots/`。
121
+ - 将每次尝试、结果、截图路径和不可达原因写入 `agent/runtime/agent-screenshot-exploration.json`。
122
+ - 将截图、探索日志、说明文件和最终修改的 Flutter 文件登记到 `agent/manifest.json`。
123
+ - 截图完成后执行 `p2f screenshots-audit --url "<页面链接>"`,按 `cli/analysis/agent-screenshot-audit.md` 删除重复图并重截错误图。
124
+
125
+ 如果关键状态缺截图,先继续探索补图或记录不可达原因,不要直接开始实现。
126
+
127
+ ### Stage 5:实现 Flutter 页面
128
+
129
+ p2f CLI 不直接生成 Dart 页面代码;Dart 实现必须由 agent 根据 CLI 产物和 YouFi 项目规范完成。
130
+
131
+ 实现 Dart 前必须读取并遵守:
132
+
133
+ - `skills/p2f/references/youfi-flutter-guidelines.md`:YouFi Dart/Flutter 代码规范。
134
+ - `skills/p2f/references/page-layout-patterns.md`:CommonAppBar、安全区、滚动和撑满高度布局模式。
135
+ - 当前 Flutter 项目的本地规范文件,例如 `README.md`、`CLAUDE.md`、`analysis_options.yaml`、`theme_service.dart`、`base_get_view.dart`、`common_app_bar.dart`。
136
+
137
+ 实现时优先使用:
138
+
139
+ - `main.md`
140
+ - `cli/analysis/feature-coverage.md`
141
+ - `cli/analysis/screenshot-exploration-plan.md`
142
+ - `agent/screenshots/`
143
+ - `agent/runtime/agent-screenshot-exploration.json`
144
+ - `agent/manifest.json`
145
+ - `cli/analysis/text-style-map.md`
146
+ - `cli/analysis/ui-structure.md`
147
+ - `cli/analysis/implementation-plan.md`
148
+
149
+ `cli/runtime/dom.json`、`cli/runtime/computed-styles.json` 等大型 JSON 只在需要定位结构、样式或 selector 时读取相关片段。
150
+
151
+ 实现后在 YouFi Flutter 项目里运行必要检查,优先使用 `./scripts/check_code.sh lib`;也可以按场景运行 `dart analyze lib`、`flutter analyze` 或 `flutter test`。
152
+ 格式化 Dart 代码时只传 `.dart` 文件或 Dart 源码目录,不要把 `.p2f-workspace/pages/**` 下的 JSON、Markdown 或截图探索产物加入 `dart format` 参数。
153
+
154
+ ## 工作目录
155
+
156
+ ```text
157
+ .p2f-workspace/
158
+ prd-source/
159
+ project/
160
+ flutter-project.json
161
+ pages/
162
+ <task-name>/
163
+ main.md
164
+ cli/
165
+ source/
166
+ route-info.json
167
+ related-files.txt
168
+ vue-entry.txt
169
+ product-docs-index.md
170
+ product-docs-index.json
171
+ product-docs/
172
+ prototype-i18n.md
173
+ prototype-i18n-index.json
174
+ i18n/
175
+ runtime/
176
+ dom.json
177
+ accessibility.json
178
+ computed-styles.json
179
+ visible-text.txt
180
+ interactions.candidate.json
181
+ interactions.json
182
+ analysis/
183
+ feature-coverage.md
184
+ feature-coverage.json
185
+ screenshot-exploration-plan.md
186
+ screenshot-exploration-plan.json
187
+ text-style-map.md
188
+ text-style-map.json
189
+ output/
190
+ generate-report.md
191
+ runs/
192
+ agent/
193
+ manifest.json
194
+ screenshots/
195
+ runtime/
196
+ agent-screenshot-exploration.json
197
+ logs/
198
+ ```
199
+
200
+ `project/flutter-project.json` 是 Flutter 项目级共享快照,每次 `p2f generate` 会在 `read-flutter-docs` 阶段更新同一份;它不属于某个页面目录。页面级目录里只保留当前页面相关的 `cli/analysis/flutter-mapping.md`。
201
+
202
+ `<task-name>` 由原型页面 URL 的路由名解析得到。可用下面的命令查看精确路径:
203
+
204
+ ```bash
205
+ p2f paths --url "<页面链接>"
206
+ ```
207
+
208
+ `p2f clean "<页面目录名称>"` 只删除指定页面目录,例如 `p2f clean "stock-detail"`。`p2f clean --url "<页面链接>"` 会从 URL 解析页面目录名。`p2f clean --all` 删除全部 `.p2f-workspace/pages`。这些命令都不会删除 `prd-source`、`project/flutter-project.json` 或已安装的 skills。
209
+
210
+ `p2f remove` 删除当前项目里的所有 p2f 运行产物和内置 skill 副本,包括 `.p2f-workspace/`、`.claude/skills/p2f` 和 `.codex/skills/p2f`。它不会卸载全局 `p2f` CLI,也不会删除 `.claude` / `.codex` 下的其他文件。
211
+
212
+ ## 更新检查
213
+
214
+ - `p2f doctor` 会顺带检查 p2f 是否落后公司 GitLab 最新 tag;这只是提醒项,不负责安装。
215
+ - `p2f doctor --offline` 跳过 PRD 仓库新鲜度和 p2f 版本这类网络检查。
216
+ - `p2f update --check` 只检查新版本。
217
+ - `p2f update` 从公司 GitLab 最新 tag 重新全局安装 p2f CLI,行为和 `lark-cli update` 一致。
218
+
219
+ ## 命令阶段
220
+
221
+ p2f 面向人类和 agent 共同使用,所有命令都可以由人类直接执行。执行过程中会打印 `Stage: ...`,失败时必须按失败阶段、失败动作、失败原因、已完成步骤、未完成步骤和建议方案向用户说明。
222
+
223
+ - `p2f init`:`sync-prd-source` -> `prd-install` -> `playwright-install` -> `skill-install`。
224
+ - `p2f sync`:`prd-sync-check` -> `prd-sync-update`,从远端拉取 PRD 原型源码并重置 `.p2f-workspace/prd-source`,不会 push。
225
+ - `p2f generate`:`sync-prd-source` -> `read-flutter-docs` -> `read-vue-docs` -> `locate-vue-page` -> `build-feature-coverage` -> `capture-runtime` -> `build-semantic-model` -> `merge-feature-coverage` -> `write-screenshot-exploration-plan` -> `detect-existing-page` -> `write-implementation-plan` -> `write-report`。
226
+ - `read-flutter-docs` 会提前生成/更新 `.p2f-workspace/project/flutter-project.json`,后续 `detect-existing-page` 直接消费这份共享快照。
227
+ - `p2f paths`:`resolve-paths`,用于查看 workspace、共享项目快照、pages、任务目录、CLI/agent 目录和 `main.md` 路径。
228
+ - `p2f clean "<页面目录名称>"`:`clean-pages`,用于删除指定任务页面目录。
229
+ - `p2f clean --url "<页面链接>"`:`clean-pages`,从页面 URL 解析任务名并删除对应页面目录。
230
+ - `p2f clean --all`:`clean-pages`,用于删除全部 pages。
231
+ - `p2f remove`:`remove`,用于删除当前项目里的 `.p2f-workspace/` 和 p2f agent skills;不卸载全局 CLI。
232
+ - `p2f screenshots-audit --url "<页面链接>"`:`screenshots-audit`,用于审计 agent 截图目录中的重复图和疑似原型平台壳层截图。
233
+ - `p2f doctor`:`environment-checks` -> `skill-check` -> `prd-source-check` -> `update-check`。
234
+ - `p2f update --check`:`update-check`。
235
+ - `p2f update`:`update-check` -> `update-install`,检查 p2f CLI 版本并用最新 tag 重新执行全局安装。
236
+ - `p2f skills-install`:`skill-install`,用于安装/更新当前 CLI 自带的 p2f skill;不修改 PRD 源码和页面目录。
237
+
238
+ ## 主题文件
239
+
240
+ 原型主题输入:
241
+
242
+ - `.p2f-workspace/prd-source/src/style.scss`
243
+ - `.p2f-workspace/prd-source/src/tokens/design-tokens.js`
244
+
245
+ YouFi Flutter App 主题输入:
246
+
247
+ - `lib/app/services/theme_service.dart`
248
+
249
+ YouFi Flutter App 路由输入:
250
+
251
+ - `lib/app/routes/utils/app_routes.dart`:`AppRoutes` 路由常量。
252
+ - `lib/app/routes/utils/app_pages.dart`:`GetPage` 页面注册。
253
+
254
+ 实现文字样式时优先使用 `themeService.textStyles.*`,实现颜色时优先使用 `themeService.colors.*`。除非目标区域已有相同写法,否则不要为了贴合截图硬编码 `Color(0x...)`、十六进制颜色、字体大小或行高。
255
+
256
+ ## Flutter 实现参考
257
+
258
+ - Dart 实现前必须读取 `references/youfi-flutter-guidelines.md`。
259
+ - 普通页面、设置页、表单页、详情页或带底部操作区的页面,必须读取 `references/page-layout-patterns.md`。
260
+ - 截图还原不能凌驾于 App 规范之上。截图具体色值、字号、间距与现有 token 不完全一致时,优先选择最接近的 YouFi token,而不是硬编码。
261
+
262
+ ## 数据规则
263
+
264
+ 当前任务必须以 CLI 产物为准:
265
+
266
+ - `main.md` 说明本次任务涉及哪些源码文件和产物。
267
+ - `cli/source/product-docs-index.md` 记录从原型项目同步出的产品文档;如有 `cli/source/product-docs/**`,实现前必须阅读对应 `.md`。
268
+ - `cli/source/prototype-i18n.md` 记录 prototype i18n 文案摘要;如有 `cli/source/i18n/<screenId>.json`,实现翻译时必须参考原始 JSON。
269
+ - `cli/analysis/feature-coverage.md` 是源码/产品文档驱动的功能覆盖清单。实现前先读它,用来指导 agent live-page 截图探索;source/doc only 项需要尝试探索或记录不可达原因。
270
+ - `cli/analysis/feature-coverage.md` 的可执行交互只应来自 `.vue` 模板事件或产品文档;非 Vue 相关文件只作为来源记录,不能把 mock/config 数据、图表字段或 SVG 标签当成可点击 tab。
271
+ - `cli/analysis/screenshot-exploration-plan.md` 是 agent 截图探索任务书。实现前必须执行它,不能跳过。
272
+ - `agent/screenshots/` 保存 agent live-page 探索后的初始态、滚动分段、Tab、弹窗、下拉、输入聚焦等截图。`p2f generate` 不直接写截图。
273
+ - `agent/manifest.json` 记录 agent 生成的截图、探索日志、说明文件和修改的 Flutter 文件;agent 每次新增或修改产物都必须更新。
274
+ - `cli/analysis/agent-screenshot-audit.md` 是 `p2f screenshots-audit` 生成的截图审计报告,标出重复截图和疑似截到原型平台壳层的错误截图。实现前必须处理报告中的问题。
275
+ - `cli/runtime/interactions.candidate.json` 记录运行态 DOM 和源码/文档派生的可点击线索,包括类型、selector、文案、置信度和元素范围;它不是完整状态列表,按需读取。
276
+ - `cli/runtime/interactions.json` 是兼容占位文件。
277
+ - `agent/runtime/agent-screenshot-exploration.json` 记录 agent 实际探索过的交互、触发状态、截图结果和不可达原因。
278
+ - `cli/analysis/flutter-mapping.md` 记录 Flutter 页面存在性状态、证据明细和复核任务。若 `status=uncertain` 或 `agentReviewRequired=true`,必须先按其中的 Agent 复核任务确认已有页面或新增页面,不能直接改候选文件或创建新文件。
279
+ - `cli/analysis/text-style-map.md` 由新版 `cli/runtime/computed-styles.json` 生成,记录原型 CSS 字号/字重/行高到 YouFi `themeService.textStyles.*` 的映射。实现文本样式前必须先读它。
280
+ - `cli/analysis/implementation-plan.md` 记录建议修改的 Flutter 文件、复用候选、风险点和不确定项。
281
+ - `.p2f-workspace/project/flutter-project.json` 记录 Flutter 项目级模块、路由、公共组件、主题 token 和资源索引;这是截图前生成的共享快照,不要在单页页面目录中查找重复副本。
282
+
283
+ 如果关键产物缺失,先重新执行 `p2f generate`。如果重跑后仍缺失,停止并说明缺少哪些数据。
284
+
285
+ ## 实现规则
286
+
287
+ - 新建文件前必须判断 Flutter 页面是否已经存在;若 `flutter-mapping.md` 给出 `uncertain`,先完成复核任务并在实现说明中记录结论。
288
+ - 优先复用 App 已有模块、路由、控制器、组件、翻译和资源。
289
+ - 新增或修改路由时,只使用当前项目实际路由文件,优先检查 `lib/app/routes/app_routes.dart` / `lib/app/routes/app_pages.dart` 和 `lib/app/routes/utils/app_routes.dart` / `lib/app/routes/utils/app_pages.dart` 哪一组存在。
290
+ - 如果用户指定页面入口文件或模块,agent 实现时以用户指定为准,并在实现说明中记录。
291
+ - 颜色必须优先使用 `themeService.colors.*`,不要硬编码颜色值。
292
+ - 文字样式必须先按 `cli/analysis/text-style-map.md` 映射选择 `themeService.textStyles.*`,不要凭感觉选择 `bodyM/bodyR`,也不要硬编码字体大小和行高。
293
+ - 尺寸必须使用 ScreenUtil (`.w`、`.h`、`.sp`、`.r`) 或 `AppValues.*`。
294
+ - 普通二级页必须优先使用 `CommonAppBar`,并按页面需要设置 `backgroundColor` 与 `Scaffold.backgroundColor` 一致。
295
+ - 普通纵向页面必须考虑 `SafeArea`,且优先使用 `LayoutBuilder` + `SingleChildScrollView` + `ConstrainedBox(BoxConstraints(minHeight: constraints.maxHeight))` 保证短屏和长屏布局正确。
296
+ - 用户可见文本必须使用 `.tr`,并补齐三份翻译。
297
+ - 页面优先使用 `BaseGetView<T>` + `GetxController` + `.obs` / `Obx()`。
298
+ - `Obx` 必须局部化:只包直接读取 Rx 并需要刷新的最小 widget,禁止整页/大块静态 UI 外层套 `Obx`。
299
+ - 禁止在 `Obx` 中写 `controller.xxx.value;` 这种不参与渲染的空读;需要把 `.value` 用在当前 builder 返回的 widget 属性、文本或分支里。
300
+ - 子组件需要响应式状态时,在子组件内部加局部 `Obx`,或由父级 `Obx` 读取 `.value` 后传入普通值。
301
+ - Dart 文件和 Widget 命名必须跟随 App 现有风格。
302
+ - 单页内部复用的组件放在目标模块内,不轻易抽到公共层。
303
+ - 高风险修改必须先让用户确认,包括 `pubspec.yaml`、全局路由架构、全局主题、`analysis_options.yaml`、替换已有页面业务结构。