claude-coding-flow 1.5.0 → 1.6.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.
- package/bin/flow.js +26 -30
- package/commands/bug-fix.md +6 -0
- package/commands/code-gen.md +35 -5
- package/commands/doc-gen.md +57 -7
- package/dashboard/static/app.js +1 -1
- package/dashboard/static/style.css +0 -3
- package/package.json +1 -1
package/bin/flow.js
CHANGED
|
@@ -98,38 +98,34 @@ function init() {
|
|
|
98
98
|
if (!settings.permissions.allow) settings.permissions.allow = [];
|
|
99
99
|
|
|
100
100
|
const allowPatterns = [
|
|
101
|
-
//
|
|
102
|
-
"
|
|
103
|
-
|
|
104
|
-
"Bash(
|
|
105
|
-
|
|
106
|
-
"Bash(
|
|
107
|
-
|
|
108
|
-
"Bash(find .worktree/ *)",
|
|
109
|
-
"Bash(find src/ *)",
|
|
110
|
-
// Read-only: grep
|
|
111
|
-
"Bash(grep -rn * --include=*.java --include=*.kt --include=*.py --include=*.js --include=*.ts --include=*.swift --include=*.dart)",
|
|
112
|
-
// Read-only: python3 one-liners (ID gen, JSON parsing, date)
|
|
113
|
-
"Bash(python3 -c *)",
|
|
114
|
-
// Read-only: ls / cat / test
|
|
115
|
-
"Bash(ls *)",
|
|
116
|
-
"Bash(test -f *)",
|
|
117
|
-
// Write: mkdir / cp for worktree
|
|
118
|
-
"Bash(mkdir -p .worktree/ *)",
|
|
119
|
-
"Bash(cp .worktree/ *)",
|
|
120
|
-
"Bash(cp docs/ .worktree/ *)",
|
|
121
|
-
// Write: rm temp
|
|
122
|
-
"Bash(rm -rf .worktree/code-gen/temp)",
|
|
123
|
-
// Write: date
|
|
101
|
+
// Basic tools
|
|
102
|
+
"Edit", "Write", "Read",
|
|
103
|
+
// Shell read-only
|
|
104
|
+
"Bash(ls*)", "Bash(cat *)", "Bash(head*)", "Bash(tail*)",
|
|
105
|
+
"Bash(find *)", "Bash(grep*)", "Bash(wc *)", "Bash(echo *)",
|
|
106
|
+
"Bash(test -f *)", "Bash(tree *)",
|
|
107
|
+
// Date
|
|
124
108
|
"Bash(date *)",
|
|
109
|
+
// File operations
|
|
110
|
+
"Bash(mkdir *)", "Bash(cp *)", "Bash(mv *)", "Bash(rm *)", "Bash(touch *)",
|
|
111
|
+
// Python
|
|
112
|
+
"Bash(python3 *)", "Bash(python *)", "Bash(pip3 install *)", "Bash(pip install *)",
|
|
113
|
+
// Server
|
|
114
|
+
"Bash(uvicorn *)",
|
|
115
|
+
// Java
|
|
116
|
+
"Bash(javac *)", "Bash(java *)",
|
|
117
|
+
// Git (covers all subcommands)
|
|
118
|
+
"Bash(git *)",
|
|
119
|
+
// Network
|
|
120
|
+
"Bash(curl *)",
|
|
121
|
+
// Cd (covers compound commands like "cd ... && find ...")
|
|
122
|
+
"Bash(cd *)",
|
|
123
|
+
// Skill
|
|
124
|
+
"Skill(update-config)",
|
|
125
125
|
// Build commands
|
|
126
|
-
"Bash(npm run build:*)",
|
|
127
|
-
"Bash(
|
|
128
|
-
"Bash(
|
|
129
|
-
"Bash(go build ./...)",
|
|
130
|
-
"Bash(make build)",
|
|
131
|
-
"Bash(./gradlew assembleDebug)",
|
|
132
|
-
"Bash(./mvnw compile)",
|
|
126
|
+
"Bash(npm run build:*)", "Bash(npx tsc --noEmit)",
|
|
127
|
+
"Bash(cargo check)", "Bash(go build ./...)", "Bash(make build)",
|
|
128
|
+
"Bash(./gradlew assembleDebug)", "Bash(./mvnw compile)",
|
|
133
129
|
];
|
|
134
130
|
|
|
135
131
|
let added = 0;
|
package/commands/bug-fix.md
CHANGED
|
@@ -7,6 +7,12 @@ model: inherit
|
|
|
7
7
|
|
|
8
8
|
你是一位 Bug 定位专家,通过任务链追溯 bug 源头并修复。
|
|
9
9
|
|
|
10
|
+
## 核心设计理念
|
|
11
|
+
|
|
12
|
+
本 skill 是**增量 + 可溯源**模式的标准实现:
|
|
13
|
+
- **增量**:定位到 bug 后做最小化修改,不重写不相关的代码
|
|
14
|
+
- **可溯源**:沿任务链溯源——bug-fix 任务 → code-gen 任务(通过 related_task_id) → doc-gen 任务(通过 dev_doc) → 原始需求。通过 code-gen 的 changes.diff 快照快速理解已有代码,无需盲目全文搜索
|
|
15
|
+
|
|
10
16
|
## 语言要求
|
|
11
17
|
|
|
12
18
|
- 交流用**中文**,代码/变量/函数名用**英文**
|
package/commands/code-gen.md
CHANGED
|
@@ -144,6 +144,25 @@ d. 若为空 → `prev_task_id: null`
|
|
|
144
144
|
cd $(git rev-parse --show-toplevel) && find .worktree/code-gen/ -name "task.json" -exec grep -l "{前序develop.md路径}" {} \;
|
|
145
145
|
```
|
|
146
146
|
|
|
147
|
+
### 可溯源链路(增量开发的核心)
|
|
148
|
+
|
|
149
|
+
增量模式下,通过以下链路快速定位已有代码,避免盲目全文搜索:
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
当前 develop.md(D2)
|
|
153
|
+
→ related_task_id → 前序 develop.md(D1)
|
|
154
|
+
→ 匹配 dev_doc 的 code-gen 任务(E1 的任务)
|
|
155
|
+
→ snapshots/changes.diff(E1 的代码快照)
|
|
156
|
+
→ 快照中涉及的文件 = 增量开发的出发点
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**溯源步骤**:
|
|
160
|
+
1. 读取当前 develop.md 所属 doc-gen 任务的 `related_task_id`,定位前序 doc-gen 任务
|
|
161
|
+
2. 读取前序 doc-gen 任务的 `output_doc`(D1 路径)
|
|
162
|
+
3. 在 code-gen 中搜索 `dev_doc` 匹配 D1 的任务(E1 的 code-gen 任务)
|
|
163
|
+
4. 读取 E1 任务的 `snapshots/changes.diff`,获取已生成的文件列表和代码
|
|
164
|
+
5. E1 快照中涉及的文件就是本次增量开发需要修改的文件集合
|
|
165
|
+
|
|
147
166
|
4. 更新 module.json(如新建)
|
|
148
167
|
|
|
149
168
|
### 阶段进度更新
|
|
@@ -154,8 +173,12 @@ cd $(git rev-parse --show-toplevel) && find .worktree/code-gen/ -name "task.json
|
|
|
154
173
|
|
|
155
174
|
**A. 开发文档** → 读取 develop.md + 同目录 `images/index.yaml`
|
|
156
175
|
- 失败时回退原始需求文档,仍失败则提示用户
|
|
157
|
-
- **增量模式**(prev_task_id
|
|
158
|
-
-
|
|
176
|
+
- **增量模式**(prev_task_id 不为空):
|
|
177
|
+
- 通过可溯源链路定位 E1 的 code-gen 任务和 changes.diff 快照
|
|
178
|
+
- 对比 D1 和 D2 中标记了 `[新增]`/`[修改]`/`[删除]` 的章节,只针对变更章节生成代码
|
|
179
|
+
- E1 快照中涉及的文件 = 本次需要增删改的文件出发点
|
|
180
|
+
- 读取这些文件的当前代码,在此基础上做增量修改
|
|
181
|
+
- **关联需求参考**:develop.md 所属 doc-gen 任务的 `related_task_id` 不为空时,沿可溯源链路找到对应的 code-gen 任务,加载其 `changes.diff` 和已生成代码作为参考基准。关联需求的代码结构、命名风格、工具类使用应优先复用,保持代码一致性
|
|
159
182
|
|
|
160
183
|
**B. API 文档** → 直接从 develop.md 的"接口调用"章节提取,无需额外读取。develop.md 已包含接口地址、方法、请求参数、响应字段等信息。无此章节时标记「API 信息缺失」继续
|
|
161
184
|
|
|
@@ -199,10 +222,12 @@ cd $(git rev-parse --show-toplevel) && find skills/ -name "*.md" -type f 2>/dev/
|
|
|
199
222
|
|
|
200
223
|
**`changes.diff` 必须是真实 git diff 输出,禁止中文摘要/省略代码行。**
|
|
201
224
|
|
|
225
|
+
**快照错误静默处理**:文件可能未 git add/commit,`git diff --no-index` 会返回 exit code 1(表示有差异,非报错)。所有快照相关 git 命令末尾加 `|| true` 静默处理,禁止向用户展示 Error。
|
|
226
|
+
|
|
202
227
|
1. `mkdir -p .worktree/code-gen/{模块}/{任务}/snapshots/`
|
|
203
228
|
2. **逐文件判断跟踪状态**,必须分开执行,禁止用 `;` 或 `||` 拼合:
|
|
204
|
-
- 已跟踪文件(`git ls-files --
|
|
205
|
-
- 未跟踪文件:`git diff --no-index /dev/null {文件名}`
|
|
229
|
+
- 已跟踪文件(`git ls-files -- {文件}` 输出非空):`git diff HEAD -- {文件列表} || true`
|
|
230
|
+
- 未跟踪文件:`git diff --no-index /dev/null {文件名} || true`
|
|
206
231
|
3. 将 Bash 原始输出 Write 到 `changes.diff`
|
|
207
232
|
|
|
208
233
|
排除:.worktree/、.DS_Store、docs/、*.md 配置文件、.dashboard/、无关文件。
|
|
@@ -212,7 +237,12 @@ cd $(git rev-parse --show-toplevel) && find skills/ -name "*.md" -type f 2>/dev/
|
|
|
212
237
|
- **关联需求优先参考**:如果有关联的 code-gen 任务,优先复用其代码结构、类名、方法签名、工具类和组件,保持风格一致
|
|
213
238
|
- **UI 100% 还原**:对照 index.yaml 设计稿,布局/颜色/字号/间距/圆角/阴影等所有视觉属性像素级一致
|
|
214
239
|
- 优先编辑现有文件,复用已有工具类和组件
|
|
215
|
-
-
|
|
240
|
+
- **API 注释强制要求**:API 文档中的字段说明必须在代码中以中文注释体现。具体要求:
|
|
241
|
+
- 请求参数:每个字段的说明、类型、必填、长度限制 → 注释在参数声明上方
|
|
242
|
+
- 响应参数:每个字段的说明、类型 → 注释在字段声明上方
|
|
243
|
+
- 枚举值:API 文档中的枚举常量说明 → 注释在枚举定义处
|
|
244
|
+
- 接口地址和方法:注释在请求函数/方法上方
|
|
245
|
+
- 错误码:文档中列出的错误码 → 注释在错误处理逻辑处
|
|
216
246
|
- 不引入不必要抽象;安全第一;简洁优于通用;只在系统边界校验
|
|
217
247
|
|
|
218
248
|
### 设计稿绝对还原规则
|
package/commands/doc-gen.md
CHANGED
|
@@ -82,6 +82,7 @@ docs/
|
|
|
82
82
|
"phases": [{"phase": 1, "name": "信息收集", "status": "running", "started_at": "{timestamp}", "completed_at": null}],
|
|
83
83
|
"requirement_doc": "{文件名}", "sketch_folder": "{目录名}", "api_doc": "{文件名或null}",
|
|
84
84
|
"output_doc": "{需求名}-develop.md",
|
|
85
|
+
"input_changes": null,
|
|
85
86
|
"related_task_id": null, "created_at": "{timestamp}", "updated_at": "{timestamp}"}
|
|
86
87
|
```
|
|
87
88
|
|
|
@@ -128,20 +129,39 @@ find docs/images/ -mindepth 1 -maxdepth 1 -type d 2>/dev/null
|
|
|
128
129
|
find docs/apis/ -name "*.md" -type f 2>/dev/null
|
|
129
130
|
```
|
|
130
131
|
|
|
131
|
-
### 第三步:AskUserQuestion
|
|
132
|
+
### 第三步:AskUserQuestion 收集
|
|
132
133
|
|
|
133
|
-
|
|
134
|
+
#### 全量模式(无前序任务或用户选全新生成)
|
|
135
|
+
|
|
136
|
+
**动态选项规则**(需求文档 — 必填输入):0 个 → AskUserQuestion 提供 `稍后提供`(description:"稍后手动提供路径");1-3 个 → AskUserQuestion 列出全部 + `自定义输入`,有文件时剩余空位可补充 `读取全部`;4+ 个 → 文字列出全部(带编号)+ AskUserQuestion(`输入序号` + `自定义输入`)。
|
|
137
|
+
|
|
138
|
+
**动态选项规则**(图片、API — 可选输入,**必须始终包含 `无` 选项**):0 个 → AskUserQuestion 提供选项 `无`(description:"暂不指定")+ `稍后提供`(description:"稍后手动提供路径");1-2 个 → AskUserQuestion 列出全部 + `无`(description:"暂不指定")+ `自定义输入`;3+ 个 → 文字列出全部(带编号)+ AskUserQuestion(`输入序号` + `无`(description:"暂不指定")+ `自定义输入`)。
|
|
134
139
|
|
|
135
140
|
**第一批(3问,每问单独 AskUserQuestion)**:
|
|
136
|
-
1. header=需求文档:扫描 `docs/prds/` 下 `.md`
|
|
137
|
-
2. header=图片:扫描 `docs/images/`
|
|
138
|
-
3. header=API:扫描 `docs/apis/` 下 `.md`
|
|
141
|
+
1. header=需求文档:扫描 `docs/prds/` 下 `.md` 文件,按必填输入规则
|
|
142
|
+
2. header=图片:扫描 `docs/images/` 下子文件夹,按可选输入规则
|
|
143
|
+
3. header=API:扫描 `docs/apis/` 下 `.md` 文件,按可选输入规则
|
|
139
144
|
|
|
140
145
|
**第二批(1问)**:
|
|
141
|
-
4. header=增量:`全新生成` /
|
|
146
|
+
4. header=增量:`全新生成` / `增量更新`(仅当模块内存在前序任务时显示此选项,否则直接全量生成)
|
|
142
147
|
|
|
143
148
|
收集完毕 → AskUserQuestion(header=确认,options=`确认开始` / `需要修改`)→ 确认后进入处理。
|
|
144
149
|
|
|
150
|
+
#### 增量模式(有前序任务且用户选增量更新)
|
|
151
|
+
|
|
152
|
+
**核心原则:只有用户提供了变更版本的输入,才会在 develop.md 中生成对应的增量。未变更的输入沿用前序任务,对应章节原样保留。**
|
|
153
|
+
|
|
154
|
+
1. **识别前序任务**:读取模块内最新任务的 task.json,获取其 requirement_doc、sketch_folder、api_doc、output_doc 路径
|
|
155
|
+
|
|
156
|
+
2. **自动推断变更输入**:根据第一批收集结果自动判断,无需再单独询问。用户选了具体文件 → 该输入有变更;用户选了"无" → 该输入沿用前序任务
|
|
157
|
+
- requirement_doc 非空 → `requirement: true`
|
|
158
|
+
- sketch_folder 非空 → `images: true`
|
|
159
|
+
- api_doc 非空 → `api: true`
|
|
160
|
+
|
|
161
|
+
3. **AskUserQuestion(header=确认)**:展示 `前序任务: {task_id}` + `变更输入: {有变更的项}` + `沿用输入: {未变更的项}` + options=`确认开始` / `需要修改`
|
|
162
|
+
|
|
163
|
+
收集完毕后,task.json 的 `input_changes` 字段写入:`{"requirement": true/false, "images": true/false, "api": true/false}`
|
|
164
|
+
|
|
145
165
|
---
|
|
146
166
|
|
|
147
167
|
## 处理阶段
|
|
@@ -252,7 +272,35 @@ find docs/apis/ -name "*.md" -type f 2>/dev/null
|
|
|
252
272
|
|
|
253
273
|
### 增量模式
|
|
254
274
|
|
|
255
|
-
|
|
275
|
+
**核心原则:按输入维度增量,只处理变更的输入。**
|
|
276
|
+
|
|
277
|
+
读取 task.json 的 `input_changes` 字段,确定哪些输入有变更:
|
|
278
|
+
|
|
279
|
+
**1. 读取前序任务产物**
|
|
280
|
+
- 前序 develop.md(D1):全文读取,作为 D2 的基础
|
|
281
|
+
- 前序 task.json:获取 requirement_doc、sketch_folder、api_doc 路径
|
|
282
|
+
|
|
283
|
+
**2. 按输入维度处理**
|
|
284
|
+
|
|
285
|
+
| 变更输入 | 处理方式 |
|
|
286
|
+
|----------|----------|
|
|
287
|
+
| requirement=true | diff 旧需求文档 vs 新需求文档 → 定位受影响章节 → 在 D2 中标记 `[修改]`/`[新增]`/`[删除]` |
|
|
288
|
+
| requirement=false | D1 中需求相关章节原样保留 |
|
|
289
|
+
| images=true | 重新处理图片/Figma → 更新页面结构分析、组件清单、交互行为等图片相关章节 |
|
|
290
|
+
| images=false | D1 中图片相关章节原样保留 |
|
|
291
|
+
| api=true | diff 旧 API 文档 vs 新 API 文档 → 更新接口调用、数据流等 API 相关章节 |
|
|
292
|
+
| api=false | D1 中 API 相关章节原样保留 |
|
|
293
|
+
|
|
294
|
+
**3. D2 章节标记规则**
|
|
295
|
+
|
|
296
|
+
- 变更输入影响的章节:`<span style="color:red">[修改]</span>` / `[新增]` / `[删除]`
|
|
297
|
+
- 未变更输入对应的章节:原样复制,不加标记
|
|
298
|
+
- 保留 D1 中的人工修改内容
|
|
299
|
+
|
|
300
|
+
**4. D2 的 output_doc 和 related_task_id**
|
|
301
|
+
|
|
302
|
+
- `output_doc`: 新文件名(如 `{需求名}-v2-develop.md`)
|
|
303
|
+
- `related_task_id`: 前序 doc-gen 任务的 task_id
|
|
256
304
|
|
|
257
305
|
### 文件拷贝
|
|
258
306
|
|
|
@@ -272,9 +320,11 @@ cp {引用的 API 文档} .worktree/doc-gen/{模块}/{任务}/apis/
|
|
|
272
320
|
- 图片资源: index.yaml, 本地图片 {n} 张, Figma 链接 {n} 个
|
|
273
321
|
- API 资源: index.yaml, API 文档 {n} 个
|
|
274
322
|
- 关联任务: {task_id 或 "无"}
|
|
323
|
+
- 输入变更: {全量 或 "requirement:变更, images:沿用, api:变更"}
|
|
275
324
|
|
|
276
325
|
## 处理结果
|
|
277
326
|
- 章节匹配: {统计} | 控件提取: {总数} | API 接口: {总数} | 开发文档: {文件名}
|
|
327
|
+
- 增量范围: {全量生成 或 "仅更新 requirement+api 相关章节, images 章节沿用 D1"}
|
|
278
328
|
```
|
|
279
329
|
|
|
280
330
|
### 完成
|
package/dashboard/static/app.js
CHANGED
|
@@ -204,7 +204,7 @@ function renderCodeGenCard(task) {
|
|
|
204
204
|
const bugBadges = (task.bug_fix_details || []).map(b => {
|
|
205
205
|
const statusText = b.status === "resolved" ? "已解决" : "未解决";
|
|
206
206
|
const cls = b.status === "resolved" ? "resolved" : "unresolved";
|
|
207
|
-
return `<span class="cross-badge traces-to" title="Bug: ${esc(b.title)} (${statusText})">Bug: ${esc(b.title)} (${statusText})</span>`;
|
|
207
|
+
return `<span class="cross-badge traces-to" title="Bug: ${esc(b.title)} (${statusText})">Bug: ${esc(b.title)} (${statusText}) · ${esc(b.id)}</span>`;
|
|
208
208
|
}).join("");
|
|
209
209
|
|
|
210
210
|
return `<div class="task-card" data-id="${task.id}" data-type="code-gen">
|