claude-coding-flow 1.3.2 → 1.4.1

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.
package/bin/flow.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  const fs = require("fs");
4
4
  const path = require("path");
5
- const { spawn } = require("child_process");
5
+ const { execSync, spawn } = require("child_process");
6
6
 
7
7
  const PKG_ROOT = path.resolve(__dirname, "..");
8
8
  const CWD = process.cwd();
@@ -35,7 +35,20 @@ function mkdirp(dir) {
35
35
  function init() {
36
36
  console.log(yellow("flow init"));
37
37
 
38
- // Copy skill commands -> .claude/commands/
38
+ // 1. git init
39
+ const gitDir = path.join(CWD, ".git");
40
+ if (!fs.existsSync(gitDir)) {
41
+ try {
42
+ execSync("git init", { cwd: CWD, stdio: "pipe" });
43
+ console.log(green(" initialized: git repository"));
44
+ } catch (e) {
45
+ console.log(red(` git init failed: ${e.message}`));
46
+ }
47
+ } else {
48
+ console.log(yellow(" skip (exists): git repository"));
49
+ }
50
+
51
+ // 2. Copy skill commands -> .claude/commands/
39
52
  const commandsSrc = path.join(PKG_ROOT, "commands");
40
53
  const commandsDest = path.join(CWD, ".claude", "commands");
41
54
 
@@ -54,7 +67,7 @@ function init() {
54
67
  }
55
68
  }
56
69
 
57
- // Copy dashboard -> .dashboard/
70
+ // 3. Copy dashboard -> .dashboard/
58
71
  const dashSrc = path.join(PKG_ROOT, "dashboard");
59
72
  const dashDest = path.join(CWD, ".dashboard");
60
73
 
@@ -66,8 +79,10 @@ function init() {
66
79
  console.log(yellow(" skip (exists): .dashboard/"));
67
80
  }
68
81
 
69
- // Create directories
70
- mkdirp(path.join(CWD, "docs"));
82
+ // 4. Create directories
83
+ mkdirp(path.join(CWD, "docs", "apis"));
84
+ mkdirp(path.join(CWD, "docs", "images"));
85
+ mkdirp(path.join(CWD, "docs", "prds"));
71
86
  mkdirp(path.join(CWD, "skills"));
72
87
  mkdirp(path.join(CWD, ".worktree"));
73
88
 
@@ -89,9 +104,7 @@ function startDashboard() {
89
104
  if (fs.existsSync(requirements)) {
90
105
  console.log(yellow("Installing dashboard dependencies..."));
91
106
  try {
92
- require("child_process").execSync(`pip3 install -r "${requirements}"`, {
93
- stdio: "inherit",
94
- });
107
+ execSync(`pip3 install -r "${requirements}"`, { stdio: "inherit" });
95
108
  } catch {}
96
109
  }
97
110
 
@@ -20,8 +20,7 @@ model: inherit
20
20
  ### 目录结构
21
21
 
22
22
  ```
23
- .worktree/bug-fix/{模块名}-{module_id}/
24
- ├── module.json
23
+ .worktree/bug-fix/
25
24
  └── {bug标题}-{task_id}/
26
25
  ├── task.json
27
26
  ├── log.md
@@ -30,11 +29,11 @@ model: inherit
30
29
 
31
30
  ### 文件格式
32
31
 
33
- **module.json**:`{"id": "{module_id}", "name": "{模块名}", "type": "bug-fix", "created_at": "{timestamp}"}`
32
+ **JSON 文件更新规则**:task.json、module.json 等数据文件用 **Read 改字段 Write** 整体重写,禁止用 Edit(单行 JSON 无法保证 old_string 唯一匹配)。log.md 追加内容用 Edit。
34
33
 
35
34
  **task.json**:
36
35
  ```json
37
- {"id": "{task_id}", "module_id": "{module_id}", "title": "{标题}", "type": "bug-fix",
36
+ {"id": "{task_id}", "module_id": null, "title": "{标题}", "type": "bug-fix",
38
37
  "status": "running", "current_phase": 1, "prev_task_id": null,
39
38
  "phases": [
40
39
  {"phase": 1, "name": "定位", "status": "running", "started_at": "{ts}", "completed_at": null},
@@ -50,8 +49,7 @@ model: inherit
50
49
  ### ID 生成
51
50
 
52
51
  ```bash
53
- python3 -c "import datetime,random; print(f'mod-{datetime.date.today().strftime(\"%Y%m%d\")}-{random.randbytes(2).hex()}')"
54
- python3 -c "import datetime,random; print(f'task-{datetime.date.today().strftime(\"%Y%m%d\")}-{random.randbytes(2).hex()}')"
52
+ python3 -c "import datetime,random; print(f'bug-task-{datetime.date.today().strftime(\"%Y%m%d\")}-{random.randbytes(2).hex()}')"
55
53
  ```
56
54
 
57
55
  ---
@@ -73,53 +71,80 @@ python3 -c "import datetime,random; print(f'task-{datetime.date.today().strftime
73
71
  ### 前置
74
72
 
75
73
  ```bash
76
- cat .worktree/code-gen/*/module.json 2>/dev/null | python3 -c "import sys,json; [print(f'{m[\"id\"]} {m[\"name\"]}') for l in sys.stdin for m in [json.loads(l)] if m.get('type','code-gen')=='code-gen']" 2>/dev/null
74
+ cd $(git rev-parse --show-toplevel) && for f in $(find .worktree/code-gen -name module.json 2>/dev/null); do python3 -c "import json; m=json.load(open('$f')); print(f'{m[\"id\"]} {m[\"name\"]}')"; done 2>/dev/null
77
75
  ```
78
76
 
79
77
  ### 第一步:选择 code-gen 模块
80
78
 
81
- 有模块 → AskUserQuestion(header=模块,options=模块列表 + "全局搜索",最多3个已有);无模块 → 文字提问。
79
+ **动态选项规则**:1-3 → AskUserQuestion 列出全部 + `全局搜索` + `自定义输入`;4+ 个 → 文字列出全部(带编号)+ AskUserQuestion(`输入序号` + `全局搜索` + `自定义输入`)。**无模块时直接输出文字提问"请输入模块名称",禁止使用 AskUserQuestion,不推荐、不猜测模块名。**
82
80
 
83
81
  ### 第二步:选择溯源起点任务
84
82
 
85
83
  ```bash
86
- cat .worktree/code-gen/{模块名}-{module_id}/*/task.json 2>/dev/null | python3 -c "import sys,json; [print(f'{t[\"id\"]} {t[\"title\"]} prev={t.get(\"prev_task_id\") or \"无\"}') for l in sys.stdin for t in [json.loads(l)]]" 2>/dev/null
84
+ cd $(git rev-parse --show-toplevel) && for f in $(find .worktree/code-gen/{模块名}-{module_id} -name "task.json"); do python3 -c "import json; t=json.load(open('$f')); print(f'{t[\"id\"]} {t[\"title\"]} prev={t.get(\"prev_task_id\") or \"无\"}')"; done
87
85
  ```
88
86
 
89
- AskUserQuestion(header=溯源起点):每个任务一个选项 + "从首个任务开始"。选具体任务→从该任务沿 prev_task_id 向前溯源;选首个→从链头向后遍历。
87
+ **动态选项规则**:1-3 个 → AskUserQuestion 列出全部 + `从首个任务开始`;4+ 个 → 文字列出全部(带编号)+ AskUserQuestion(`输入序号` + `从首个任务开始`)。选具体任务→从该任务沿 prev_task_id 向前溯源;选首个→从链头向后遍历。无任务时直接从源码搜索。
90
88
 
91
89
  ### 第三步:Bug 描述
92
90
 
93
- 文字提问:`请详细描述你遇到的 Bug(现象、复现步骤、期望行为等)。`
94
-
95
- ### 第四步:bug-fix 模块
96
-
97
- 选已有 bug-fix 模块或新建(module.json 含 `type: "bug-fix"`)。
91
+ 直接文字提问:`请详细描述你遇到的 Bug(现象、复现步骤、期望行为等)。`
98
92
 
99
93
  ### 创建任务
100
94
 
101
95
  1. 生成 task_id
102
- 2. `mkdir -p .worktree/bug-fix/{模块名}-{module_id}/{bug标题}-{task_id}/snapshots`
96
+ 2. `mkdir -p .worktree/bug-fix/{bug标题}-{task_id}/snapshots`
103
97
  3. 写入 task.json(related_task_id=溯源起点的 code-gen task_id,related_module_id=code-gen 模块 ID)
104
98
  4. `date '+%Y-%m-%d %H:%M:%S'` 获取时间戳,阶段一设为 running
105
99
 
106
100
  ### 定位逻辑
107
101
 
108
- **A. 指定任务向前溯源**:起始任务 → prev_task → ... → 链头,每个任务读 changes.diff + log.md + dev_doc,搜索 bug 关键词。
102
+ 按以下优先级逐步定位:
103
+
104
+ **1. 优先:读取开发日志和代码快照**
105
+
106
+ 从溯源起点任务开始,优先读取 code-gen 任务的 `log.md` 和 `snapshots/changes.diff`:
107
+ - `log.md`:包含需求收集、方案规划、代码生成全流程,可快速锁定 bug 引入环节(如用户补充信息、方案决策)
108
+ - `changes.diff`:包含实际代码变更,直接搜索 bug 关键词定位代码位置
109
+
110
+ 按任务链顺序读取:链头 → 后续任务 → ... → 溯源起点。找到第一个引入 bug 关键词的任务即定位成功。
109
111
 
110
- **B. 从首个任务向后遍历**:按 prev_task_id 构建链 → 从链头逐个向后检查 changes.diff + log.md → 记录源头。
112
+ **2. 补充:全局搜索**
111
113
 
112
- **C. 全局搜索**:
114
+ 当日志和快照未定位到时,搜索源码:
113
115
  ```bash
114
116
  grep -rn "{关键词}" --include="*.java" --include="*.kt" --include="*.py" --include="*.js" --include="*.ts" --include="*.swift" --include="*.dart"
115
- grep -rn "{关键词}" .worktree/code-gen/*/snapshots/changes.diff
116
117
  ```
117
118
 
119
+ **3. 需求溯源**(定位到代码位置后必须执行):
120
+ 找到引入 bug 的 code-gen 任务后,继续向上追溯完整链路:
121
+ 1. 读取该 code-gen 任务的 `dev_doc` 字段,定位对应的 doc-gen 任务
122
+ 2. 读取 doc-gen 任务的 `task.json` + `log.md`,获取原始需求信息
123
+ 3. 如果 doc-gen 任务有 `related_task_id`,继续向上追溯关联的 doc-gen 任务
124
+ 4. 读取 code-gen 任务的 `log.md`,查看阶段一的需求收集阶段用户是否有补充信息导致 bug 引入
125
+
126
+ 溯源结果记录到 source_info:
127
+ - `root_requirement`: 原始需求文档名
128
+ - `root_doc_gen_task`: 源头 doc-gen 任务 ID
129
+ - `root_code_gen_task`: 引入 bug 的 code-gen 任务 ID
130
+ - `introduction_context`: bug 是在哪个环节被引入的(如"用户补充需求: xxx")
131
+ - `full_chain`: 完整溯源链路(doc-gen → code-gen → bug 代码位置)
132
+
118
133
  ### 定位结果
119
134
 
120
- 更新 task.json source_info:`{requirement, iteration, task_id, location, detail}`
135
+ 更新 task.json source_info:`{requirement, iteration, task_id, location, detail, root_requirement, root_doc_gen_task, root_code_gen_task, introduction_context, full_chain}`
136
+
137
+ 日志写入:Bug 描述 → 定位路径(范围+关键词) → 定位过程 → 需求溯源链路 → 定位结果(源头任务/需求/引入环节/位置/原因)
121
138
 
122
- 日志写入:Bug 描述 → 定位路径(范围+关键词) → 定位过程 → 定位结果(源头任务/需求/位置/原因)
139
+ ### 回写关联
140
+
141
+ 定位完成后,将 bug-fix 任务 ID 回写到源头 code-gen 任务的 task.json:
142
+ ```python
143
+ # 读取源头 code-gen 任务的 task.json
144
+ # 在其中追加 bug_fix_refs 字段(数组)
145
+ # 如果不存在则创建,已存在则追加 bug-fix task_id
146
+ {"bug_fix_refs": ["bug-task-20260524-xxxx"]}
147
+ ```
123
148
 
124
149
  ---
125
150
 
@@ -138,8 +163,11 @@ grep -rn "{关键词}" .worktree/code-gen/*/snapshots/changes.diff
138
163
  3. **真实 git diff 快照**(Bash 执行,禁止手写/中文摘要):
139
164
  ```bash
140
165
  mkdir -p {快照目录}
141
- git diff HEAD -- {文件列表} > {快照目录}/changes.diff
142
166
  ```
167
+ **逐文件判断跟踪状态**,必须分开执行,禁止用 `;` 或 `||` 拼合:
168
+ - 已跟踪文件(`git ls-files --error-unmatch {文件} 2>/dev/null` 成功):`git diff HEAD -- {文件列表}`
169
+ - 未跟踪文件:`git diff --no-index /dev/null {文件名}`
170
+ 将 Bash 原始输出追加到 `{快照目录}/changes.diff`
143
171
  4. log.md:修复方案 + 变更文件表
144
172
 
145
173
  ---
@@ -32,6 +32,8 @@ model: inherit
32
32
 
33
33
  ### 文件格式
34
34
 
35
+ **JSON 文件更新规则**:task.json、module.json 等数据文件用 **Read → 改字段 → Write** 整体重写,禁止用 Edit(单行 JSON 无法保证 old_string 唯一匹配)。log.md 追加内容用 Edit。
36
+
35
37
  **module.json**:`{"id": "{module_id}", "name": "{模块名}", "type": "code-gen", "created_at": "{timestamp}"}`
36
38
 
37
39
  **task.json**:
@@ -53,8 +55,8 @@ model: inherit
53
55
  ### ID 生成
54
56
 
55
57
  ```bash
56
- python3 -c "import datetime,random; print(f'mod-{datetime.date.today().strftime(\"%Y%m%d\")}-{random.randbytes(2).hex()}')"
57
- python3 -c "import datetime,random; print(f'task-{datetime.date.today().strftime(\"%Y%m%d\")}-{random.randbytes(2).hex()}')"
58
+ python3 -c "import datetime,random; print(f'code-mod-{datetime.date.today().strftime(\"%Y%m%d\")}-{random.randbytes(2).hex()}')"
59
+ python3 -c "import datetime,random; print(f'code-task-{datetime.date.today().strftime(\"%Y%m%d\")}-{random.randbytes(2).hex()}')"
58
60
  ```
59
61
 
60
62
  ### 文档位置解析
@@ -86,7 +88,7 @@ python3 -c "import datetime,random; print(f'task-{datetime.date.today().strftime
86
88
  ### 前置
87
89
 
88
90
  ```bash
89
- cat .worktree/code-gen/*/module.json 2>/dev/null
91
+ cd $(git rev-parse --show-toplevel) && for f in $(find .worktree/code-gen -name module.json 2>/dev/null); do python3 -c "import json; m=json.load(open('$f')); print(f'{m[\"id\"]} {m[\"name\"]}')"; done 2>/dev/null
90
92
  ```
91
93
 
92
94
  ### AskUserQuestion 规则
@@ -95,28 +97,32 @@ cat .worktree/code-gen/*/module.json 2>/dev/null
95
97
 
96
98
  ### 第一步:选择模块
97
99
 
98
- 有模块 → AskUserQuestion(header=模块,options=模块列表 + "新建模块",最多展示3个已有);无模块文字提问"请输入模块名称"
100
+ **动态选项规则**:1-3 → AskUserQuestion 列出全部 + `自定义输入`;4+ 文字列出全部(带编号)+ AskUserQuestion(`输入序号` + `自定义输入`)。**无模块时直接输出文字提问"请输入模块名称",禁止使用 AskUserQuestion,不推荐、不猜测模块名。**
99
101
 
100
102
  ### 第一步半:扫描模块资源
101
103
 
102
104
  ```bash
103
- find .worktree/ -name "*-develop.md" -type f 2>/dev/null
104
- find .worktree/ -name "index.yaml" -path "*/images/*" -type f 2>/dev/null
105
+ cd $(git rev-parse --show-toplevel) && find .worktree/ -name "*-develop.md" -type f 2>/dev/null && find .worktree/ -name "index.yaml" -path "*/images/*" -type f 2>/dev/null
105
106
  ```
106
107
 
107
- ### 第二步:文字提问任务标题
108
+ ### 第二步:直接文字提问任务标题
109
+
110
+ **禁止使用 AskUserQuestion**,直接输出文字提问,由用户自由输入。不推荐、不猜测标题。
108
111
 
109
112
  ### 第三步:AskUserQuestion(两批)
110
113
 
111
- **第一批(4问)**:
112
- 1. header=开发文档:**动态选项** — 有 develop.md 时列出文件(最多3个 + 自定义路径),无则 `无开发文档` + `自定义路径`
113
- 2. header=Plan:`是` / `否(推荐)`
114
- 3. header=API:`无接口文档` / `读取 docs/ 全部文件`
115
- 4. header=设计:**动态选项** 有图片时按任务分组列出(`{任务标题} 的草图 (n张)`)+ `无设计稿` + `Figma 链接`,无图片时 `无设计稿` + `Figma 链接` + `本地图片`
114
+ **动态选项规则**:0 个 → 禁止 AskUserQuestion,直接文字提问;1-3 个 → AskUserQuestion 列出全部 + `自定义输入`;4+ 个 → 文字列出全部(带编号)+ AskUserQuestion(`输入序号` + `自定义输入`)。
115
+
116
+ **第一批(2问)**:
117
+ 1. header=开发文档:扫描 develop.md 文件,按上述规则
118
+ 2. header=Plan:`否(推荐)` / `是`
119
+
120
+ **第二批(1问)**:
121
+ 3. header=补充:`无补充` / `有补充`
116
122
 
117
- **第二批(1问)**:header=补充:`无补充` / `有补充`
123
+ **设计稿和 API**:不单独询问,阶段二自动从 develop.md 读取。设计稿从同目录 `images/index.yaml` 读取,API 信息从 develop.md 的"接口调用"章节直接提取。
118
124
 
119
- 收集完毕 → 展示信息确认清单 用户确认后进入阶段二。
125
+ 收集完毕 → AskUserQuestion(header=确认,options=`确认开始` / `需要修改`)→ 确认后进入阶段二。
120
126
 
121
127
  ---
122
128
 
@@ -126,7 +132,7 @@ find .worktree/ -name "index.yaml" -path "*/images/*" -type f 2>/dev/null
126
132
 
127
133
  1. 生成 task_id
128
134
  2. `mkdir -p .worktree/code-gen/{模块名}-{module_id}/{任务标题}-{task_id}`
129
- 3. Write task.json(7阶段全 pending)
135
+ 3. Write task.json(阶段1 completed,阶段2 running,其余 pending)
130
136
 
131
137
  **自动关联前序任务**(开发文档来自 doc-gen 时):
132
138
  a. 定位 develop.md 所属 doc-gen 任务
@@ -135,7 +141,7 @@ c. 若不为空 → 找前序 doc-gen 的 develop.md → 搜索 code-gen 中 `de
135
141
  d. 若为空 → `prev_task_id: null`
136
142
 
137
143
  ```bash
138
- find .worktree/code-gen/ -name "task.json" -exec grep -l "{前序develop.md路径}" {} \;
144
+ cd $(git rev-parse --show-toplevel) && find .worktree/code-gen/ -name "task.json" -exec grep -l "{前序develop.md路径}" {} \;
139
145
  ```
140
146
 
141
147
  4. 更新 module.json(如新建)
@@ -149,8 +155,9 @@ find .worktree/code-gen/ -name "task.json" -exec grep -l "{前序develop.md路
149
155
  **A. 开发文档** → 读取 develop.md + 同目录 `images/index.yaml`
150
156
  - 失败时回退原始需求文档,仍失败则提示用户
151
157
  - **增量模式**(prev_task_id 不为空):读前序 changes.diff + 已涉及文件,只针对 `[新增]`/`[修改]` 章节生成代码
158
+ - **关联需求参考**:develop.md 所属 doc-gen 任务的 `related_task_id` 不为空时,沿关联链找到对应的 code-gen 任务,加载其 `changes.diff` 和已生成代码作为参考基准。关联需求的代码结构、命名风格、工具类使用应优先复用,保持代码一致性
152
159
 
153
- **B. API 文档** → docs/ 按位置解析,失败标记「API 文档缺失」继续
160
+ **B. API 文档** → 直接从 develop.md 的"接口调用"章节提取,无需额外读取。develop.md 已包含接口地址、方法、请求参数、响应字段等信息。无此章节时标记「API 信息缺失」继续
154
161
 
155
162
  **C. 设计稿** → 优先读 index.yaml
156
163
  - Figma URL:提取 fileKey/nodeId → Figma MCP get_metadata → get_design_context
@@ -158,6 +165,9 @@ find .worktree/code-gen/ -name "task.json" -exec grep -l "{前序develop.md路
158
165
  - 无 index.yaml:回退用户直接输入
159
166
 
160
167
  **D. Skill 约束** → 递归扫描 `skills/*.md` + `CLAUDE.md`,逐条应用。log.md 只记文件名和更新时间。
168
+ ```bash
169
+ cd $(git rev-parse --show-toplevel) && find skills/ -name "*.md" -type f 2>/dev/null
170
+ ```
161
171
 
162
172
  ---
163
173
 
@@ -179,7 +189,7 @@ find .worktree/code-gen/ -name "task.json" -exec grep -l "{前序develop.md路
179
189
 
180
190
  ⚠️ 闭环规则:每个 ⚠️ 必须在阶段四解决 + 阶段六回顾,不允许标记后不跟进。
181
191
 
182
- 等待用户确认后进入编码。
192
+ 展示方案后直接进入阶段四编码,无需确认。
183
193
 
184
194
  ---
185
195
 
@@ -190,19 +200,41 @@ find .worktree/code-gen/ -name "task.json" -exec grep -l "{前序develop.md路
190
200
  **`changes.diff` 必须是真实 git diff 输出,禁止中文摘要/省略代码行。**
191
201
 
192
202
  1. `mkdir -p .worktree/code-gen/{模块}/{任务}/snapshots/`
193
- 2. 已跟踪文件:`git diff HEAD -- {文件列表}`
194
- 3. 未跟踪文件:`git diff --no-index /dev/null {文件名}`
195
- 4. Bash 原始输出 Write `changes.diff`
203
+ 2. **逐文件判断跟踪状态**,必须分开执行,禁止用 `;` `||` 拼合:
204
+ - 已跟踪文件(`git ls-files --error-unmatch {文件} 2>/dev/null` 成功):`git diff HEAD -- {文件列表}`
205
+ - 未跟踪文件:`git diff --no-index /dev/null {文件名}`
206
+ 3. 将 Bash 原始输出 Write 到 `changes.diff`
196
207
 
197
- 排除:.worktree/、.DS_Store、docs/、*.md 配置文件、dashboard/、无关文件。
208
+ 排除:.worktree/、.DS_Store、docs/、*.md 配置文件、.dashboard/、无关文件。
198
209
 
199
210
  ### 编码原则
200
211
 
212
+ - **关联需求优先参考**:如果有关联的 code-gen 任务,优先复用其代码结构、类名、方法签名、工具类和组件,保持风格一致
201
213
  - **UI 100% 还原**:对照 index.yaml 设计稿,布局/颜色/字号/间距/圆角/阴影等所有视觉属性像素级一致
202
214
  - 优先编辑现有文件,复用已有工具类和组件
203
215
  - 接口字段注释:根据 API 文档为每个字段生成中文注释
204
216
  - 不引入不必要抽象;安全第一;简洁优于通用;只在系统边界校验
205
217
 
218
+ ### 设计稿绝对还原规则
219
+
220
+ **当阶段二加载了 Figma design context 或图片时,必须 100% 按照设计信息实现界面,禁止任何自行替换或简化:**
221
+
222
+ | 维度 | 强制要求 |
223
+ |------|----------|
224
+ | 布局方式 | Figma 用绝对定位就用绝对定位,用 flex 就用 flex,必须忠实还原 |
225
+ | 图片资源 | Figma MCP 返回的图片/图标 URL 必须**下载并引用**,禁止用 SVG/代码自行近似替代 |
226
+ | 精确像素值 | 宽高、间距、圆角、字号、字重等所有数值必须与 Figma 返回数据**完全一致** |
227
+ | 字体 | Figma 指定的字体必须通过 CDN 加载(如 Google Fonts),禁止省略或用系统字体替代 |
228
+ | 元素结构 | Figma 中的分组/嵌套关系必须保持,禁止拆分、重组或合并 |
229
+ | 颜色值 | 必须使用 Figma 返回的精确颜色值(hex/rgba),禁止近似替换 |
230
+ | 容器尺寸 | Dialog/Frame 等容器必须使用 Figma 指定的固定宽高,禁止靠内容撑开 |
231
+
232
+ **违反示例(禁止):**
233
+ - Figma 返回 `<img src="asset_url"/>` → 自行改用 `<svg>` 近似 ❌
234
+ - Figma 返回 `position: absolute; top: 45px` → 改用 `margin-top: 29px` 流式布局 ❌
235
+ - Figma 指定 `font-family: 'Inter'` → 省略字体加载,用系统字体 ❌
236
+ - Figma 指定 `height: 426px` → 不设固定高度靠内容撑开 ❌
237
+
206
238
  ---
207
239
 
208
240
  ## 阶段五:编译校验