sillyspec 3.20.2 → 3.20.3
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/.claude/skills/sillyspec-archive/SKILL.md +1 -5
- package/.claude/skills/sillyspec-auto/SKILL.md +2 -8
- package/.claude/skills/sillyspec-brainstorm/SKILL.md +1 -28
- package/.claude/skills/sillyspec-commit/SKILL.md +3 -4
- package/.claude/skills/sillyspec-continue/SKILL.md +4 -5
- package/.claude/skills/sillyspec-doctor/SKILL.md +3 -12
- package/.claude/skills/sillyspec-execute/SKILL.md +2 -15
- package/.claude/skills/sillyspec-explore/SKILL.md +1 -14
- package/.claude/skills/sillyspec-plan/SKILL.md +36 -5
- package/.claude/skills/sillyspec-propose/SKILL.md +0 -4
- package/.claude/skills/sillyspec-quick/SKILL.md +1 -5
- package/.claude/skills/sillyspec-resume/SKILL.md +66 -23
- package/.claude/skills/sillyspec-scan/SKILL.md +1 -5
- package/.claude/skills/sillyspec-state/SKILL.md +8 -8
- package/.claude/skills/sillyspec-status/SKILL.md +1 -5
- package/.claude/skills/sillyspec-verify/SKILL.md +1 -5
- package/.claude/skills/sillyspec-workspace/SKILL.md +3 -11
- package/.sillyspec/changes/archive/2026-04-08-derive-state/design.md +97 -0
- package/.sillyspec/changes/archive/2026-04-08-derive-state/plan.md +51 -0
- package/.sillyspec/changes/archive/2026-04-08-derive-state/proposal.md +29 -0
- package/.sillyspec/changes/archive/2026-04-08-derive-state/requirements.md +34 -0
- package/.sillyspec/changes/archive/2026-04-08-derive-state/tasks.md +13 -0
- package/.sillyspec/changes/archive/2026-04-08-derive-state/verify-result.md +43 -0
- package/.sillyspec/changes/auto-mode/design.md +50 -0
- package/.sillyspec/changes/auto-mode/proposal.md +19 -0
- package/.sillyspec/changes/auto-mode/requirements.md +21 -0
- package/.sillyspec/changes/auto-mode/tasks.md +7 -0
- package/.sillyspec/changes/brainstorm-archive/2026-04-05-dashboard-design.md +206 -0
- package/.sillyspec/changes/brainstorm-archive/2026-04-05-unified-docs-design.md +199 -0
- package/.sillyspec/changes/dashboard/design.md +219 -0
- package/.sillyspec/changes/dashboard/design.md.braindraft +206 -0
- package/.sillyspec/changes/run-command-design/design.md +1230 -0
- package/.sillyspec/changes/unified-docs-design/design.md +199 -0
- package/.sillyspec/docs/sillyspec/scan/.gitkeep +0 -0
- package/.sillyspec/knowledge/INDEX.md +8 -0
- package/.sillyspec/knowledge/uncategorized.md +3 -0
- package/.sillyspec/plans/2026-04-05-dashboard.md +737 -0
- package/.sillyspec/projects/sillyspec.yaml +3 -0
- package/README.md +11 -13
- package/SKILL.md +40 -44
- package/dist/steps/brainstorm/01-load-context.md +30 -0
- package/dist/steps/brainstorm/02-reuse-check.md +6 -0
- package/dist/steps/brainstorm/03-prototype-analysis.md +11 -0
- package/dist/steps/brainstorm/04-module-split.md +23 -0
- package/dist/steps/brainstorm/05-dialog-explore.md +8 -0
- package/dist/steps/brainstorm/06-propose-approaches.md +3 -0
- package/dist/steps/brainstorm/07-present-design.md +3 -0
- package/dist/steps/brainstorm/08-write-design.md +21 -0
- package/dist/steps/brainstorm/09-self-review.md +15 -0
- package/dist/steps/brainstorm/10-user-confirm.md +3 -0
- package/dist/steps/brainstorm/11-output-spec.md +7 -0
- package/dist/steps/brainstorm/manifest.yaml +26 -0
- package/dist/steps/execute/01-load-context.md +41 -0
- package/dist/steps/execute/02-scan-conventions.md +47 -0
- package/dist/steps/execute/03-skill-mcp.md +19 -0
- package/dist/steps/execute/04-assign-task.md +22 -0
- package/dist/steps/execute/04b-prompt-template.md +54 -0
- package/dist/steps/execute/05-write-test.md +7 -0
- package/dist/steps/execute/06-write-code.md +8 -0
- package/dist/steps/execute/07-run-test.md +26 -0
- package/dist/steps/execute/08-fix-issues.md +28 -0
- package/dist/steps/execute/09-next-task.md +33 -0
- package/dist/steps/execute/manifest.yaml +28 -0
- package/dist/steps/plan/01-load-context.md +22 -0
- package/dist/steps/plan/02-anchor-confirm.md +1 -0
- package/dist/steps/plan/03-expand-tasks.md +33 -0
- package/dist/steps/plan/04-mark-order.md +15 -0
- package/dist/steps/plan/05-e2e-planning.md +17 -0
- package/dist/steps/plan/06-self-check.md +16 -0
- package/dist/steps/plan/07-save.md +1 -0
- package/dist/steps/plan/manifest.yaml +18 -0
- package/dist/steps/scan/01-env-detect.md +51 -0
- package/dist/steps/scan/02-tech-stack.md +16 -0
- package/dist/steps/scan/03-conventions.md +16 -0
- package/dist/steps/scan/04-structure.md +19 -0
- package/dist/steps/scan/05-quality.md +18 -0
- package/dist/steps/scan/06-complete.md +49 -0
- package/dist/steps/scan/manifest.yaml +16 -0
- package/dist/steps/verify/01-load-specs.md +28 -0
- package/dist/steps/verify/02-check-tasks.md +1 -0
- package/dist/steps/verify/03-check-design.md +6 -0
- package/dist/steps/verify/04-run-tests.md +7 -0
- package/dist/steps/verify/05-e2e-tests.md +27 -0
- package/dist/steps/verify/05b-e2e-fix.md +33 -0
- package/dist/steps/verify/06-code-quality.md +25 -0
- package/dist/steps/verify/07-lint-check.md +27 -0
- package/dist/steps/verify/08-output-report.md +14 -0
- package/dist/steps/verify/manifest.yaml +22 -0
- package/package.json +1 -7
- package/packages/dashboard/dist/assets/{index-Bq_Z2hne.js → index-D1EVTLmc.js} +1264 -1264
- package/packages/dashboard/dist/assets/index-DGe8CqeP.css +1 -0
- package/packages/dashboard/dist/index.html +2 -2
- package/packages/dashboard/package-lock.json +6 -6
- package/packages/dashboard/server/executor.js +1 -1
- package/packages/dashboard/server/index.js +18 -98
- package/packages/dashboard/server/parser.js +71 -139
- package/packages/dashboard/server/watcher.js +6 -14
- package/packages/dashboard/src/App.vue +185 -418
- package/packages/dashboard/src/components/ActionBar.vue +1 -10
- package/packages/dashboard/src/components/CommandPalette.vue +1 -5
- package/packages/dashboard/src/components/DocPreview.vue +8 -105
- package/packages/dashboard/src/components/DocTree.vue +19 -75
- package/packages/dashboard/src/components/PipelineStage.vue +2 -22
- package/packages/dashboard/src/components/PipelineView.vue +5 -32
- package/packages/dashboard/src/components/ProjectOverview.vue +139 -113
- package/packages/dashboard/src/components/StageBadge.vue +3 -17
- package/packages/dashboard/src/components/StepCard.vue +2 -7
- package/packages/dashboard/src/composables/useDashboard.js +0 -28
- package/src/derive.js +147 -0
- package/src/index.js +40 -688
- package/src/init.js +63 -119
- package/src/migrate.js +7 -7
- package/src/progress.js +248 -1474
- package/src/run.js +302 -3008
- package/src/setup.js +64 -2
- package/src/stages/archive.js +17 -123
- package/src/stages/brainstorm.js +48 -454
- package/src/stages/doctor.js +46 -99
- package/src/stages/execute.js +59 -420
- package/src/stages/index.js +18 -12
- package/src/stages/plan.js +189 -492
- package/src/stages/propose.js +11 -70
- package/src/stages/quick.js +13 -52
- package/src/stages/scan.js +68 -485
- package/src/stages/status.js +1 -1
- package/src/stages/verify.js +16 -203
- package/src/step.js +543 -0
- package/.claude/skills/sillyspec-knowledge/SKILL.md +0 -270
- package/.husky/pre-push +0 -13
- package/CLAUDE.md +0 -18
- package/docs/brainstorm-plan-contract.md +0 -64
- package/docs/plan-execute-contract.md +0 -123
- package/docs/platform-scan-protocol.md +0 -298
- package/docs/revision-mode.md +0 -115
- package/docs/sillyspec/file-lifecycle/known-implementation-gaps.md +0 -99
- package/docs/sillyspec/file-lifecycle/platform-workflows-sync.md +0 -218
- package/docs/sillyspec/file-lifecycle/stage-artifacts.md +0 -167
- package/docs/sillyspec/file-lifecycle/storage-and-state.md +0 -148
- package/docs/sillyspec/file-lifecycle/worktree-and-guard.md +0 -193
- package/docs/sillyspec/file-lifecycle.md +0 -125
- package/docs/workflow-contract-regression.md +0 -106
- package/docs/worktree-isolation.md +0 -252
- package/packages/dashboard/dist/assets/index-O2W5RV4z.css +0 -1
- package/packages/dashboard/dist/prototype-dashboard.html +0 -836
- package/packages/dashboard/dist/prototype-overview.html +0 -256
- package/packages/dashboard/public/prototype-dashboard.html +0 -836
- package/packages/dashboard/public/prototype-overview.html +0 -256
- package/packages/dashboard/src/components/HResizeHandle.vue +0 -48
- package/packages/dashboard/src/components/ProjectCard.vue +0 -187
- package/packages/dashboard/src/components/VResizeHandle.vue +0 -61
- package/packages/dashboard/src/composables/useLayout.js +0 -131
- package/src/brainstorm-postcheck.js +0 -158
- package/src/change-list.js +0 -52
- package/src/change-risk-profile.js +0 -352
- package/src/classify-change.js +0 -73
- package/src/constants.js +0 -70
- package/src/contract-matrix.js +0 -278
- package/src/db.js +0 -201
- package/src/endpoint-extractor.js +0 -315
- package/src/hooks/claude-pre-tool-use.cjs +0 -125
- package/src/hooks/worktree-guard.js +0 -761
- package/src/knowledge-match.js +0 -130
- package/src/modules.js +0 -482
- package/src/scan-postcheck.js +0 -383
- package/src/stage-contract.js +0 -700
- package/src/stages/brainstorm-auto.js +0 -229
- package/src/stages/explore.js +0 -34
- package/src/stages/knowledge.js +0 -498
- package/src/stages/plan-postcheck.js +0 -513
- package/src/sync.js +0 -497
- package/src/task-review.js +0 -346
- package/src/workflow.js +0 -785
- package/src/worktree-apply.js +0 -549
- package/src/worktree.js +0 -932
- package/templates/workflows/archive-impact.yaml +0 -79
- package/templates/workflows/scan-docs.yaml +0 -132
- package/test/brainstorm-plan-contract.test.mjs +0 -273
- package/test/check-syntax.mjs +0 -26
- package/test/cli-top-level-aliases.test.mjs +0 -174
- package/test/contract-artifacts.test.mjs +0 -323
- package/test/decision-supersede.test.mjs +0 -277
- package/test/knowledge-match.test.mjs +0 -231
- package/test/plan-execute-contract.test.mjs +0 -330
- package/test/plan-optimization.test.mjs +0 -572
- package/test/platform-artifacts.test.mjs +0 -190
- package/test/platform-failure-samples.test.mjs +0 -199
- package/test/platform-recovery-chain.test.mjs +0 -179
- package/test/platform-recovery.test.mjs +0 -167
- package/test/platform-scan-p0.test.mjs +0 -175
- package/test/revision-v1.test.mjs +0 -1145
- package/test/run-sanitize-project-name.test.mjs +0 -51
- package/test/run-scan-postcheck-fail.test.mjs +0 -64
- package/test/run-scan-project-parse.test.mjs +0 -200
- package/test/run-tests.mjs +0 -48
- package/test/scan-docs-yaml-placeholders.test.mjs +0 -84
- package/test/scan-knowledge.test.mjs +0 -175
- package/test/scan-paths.test.mjs +0 -68
- package/test/scan-postcheck-project-priority.test.mjs +0 -85
- package/test/scan-postcheck.test.mjs +0 -197
- package/test/scan-workflow-anyfailed-block.test.mjs +0 -52
- package/test/spec-dir.test.mjs +0 -206
- package/test/stage-contract-failed-post-check.test.mjs +0 -102
- package/test/stage-contract.test.mjs +0 -299
- package/test/stage-definitions.test.mjs +0 -39
- package/test/wait-gates.test.mjs +0 -501
- package/test/workflow-spec-base.test.mjs +0 -142
- package/test/worktree-guard.test.mjs +0 -136
- package/test/worktree-native-overlay.test.mjs +0 -188
package/src/stages/execute.js
CHANGED
|
@@ -1,86 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'fs'
|
|
2
2
|
import path from 'path'
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* 校验 plan.md 是否满足 execute 执行契约
|
|
6
|
-
* @param {string} planContent - plan.md 文件内容
|
|
7
|
-
* @returns {{ ok: boolean, errors: string[], warnings: string[], tasks: object[], waves: object[] }}
|
|
8
|
-
*/
|
|
9
|
-
export function validatePlanForExecute(planContent) {
|
|
10
|
-
const errors = []
|
|
11
|
-
const warnings = []
|
|
12
|
-
|
|
13
|
-
if (!planContent || !planContent.trim()) {
|
|
14
|
-
return { ok: false, errors: ['plan.md 内容为空'], warnings, tasks: [], waves: [] }
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const waves = parseWavesFromPlan(planContent)
|
|
18
|
-
|
|
19
|
-
// 收集所有 task
|
|
20
|
-
const allTasks = []
|
|
21
|
-
for (const wave of waves) {
|
|
22
|
-
for (const task of wave.tasks) {
|
|
23
|
-
allTasks.push(task)
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// 检查 1: 至少有一个 checkbox task
|
|
28
|
-
if (allTasks.length === 0) {
|
|
29
|
-
errors.push('plan.md 中没有找到 checkbox task(格式: "- [ ] task-XX: 任务名")')
|
|
30
|
-
return { ok: false, errors, warnings, tasks: allTasks, waves }
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// 检查 2: task id 唯一性
|
|
34
|
-
const idCounts = {}
|
|
35
|
-
for (const task of allTasks) {
|
|
36
|
-
if (task.index != null) {
|
|
37
|
-
const key = `task-${task.index}`
|
|
38
|
-
idCounts[key] = (idCounts[key] || 0) + 1
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
for (const [id, count] of Object.entries(idCounts)) {
|
|
42
|
-
if (count > 1) {
|
|
43
|
-
errors.push(`task id 重复: ${id} 出现 ${count} 次`)
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// 检查 3: task id 连续性(从 1 开始)
|
|
48
|
-
const ids = allTasks
|
|
49
|
-
.map(t => t.index)
|
|
50
|
-
.filter(i => i != null)
|
|
51
|
-
.sort((a, b) => a - b)
|
|
52
|
-
if (ids.length > 0) {
|
|
53
|
-
const expected = Array.from({ length: ids.length }, (_, i) => ids[0] + i)
|
|
54
|
-
// 只检查以 task-01 起始的情况(常见模式)
|
|
55
|
-
if (ids[0] === 1) {
|
|
56
|
-
for (let i = 0; i < ids.length; i++) {
|
|
57
|
-
if (ids[i] !== i + 1) {
|
|
58
|
-
errors.push(`task id 不连续: 期望 task-${String(i + 1).padStart(2, '0')}, 实际 task-${String(ids[i]).padStart(2, '0')}`)
|
|
59
|
-
break
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// 检查 4: task name 非空
|
|
66
|
-
for (const task of allTasks) {
|
|
67
|
-
if (!task.name || !task.name.trim()) {
|
|
68
|
-
errors.push(`task-${String(task.index || '?').padStart(2, '0')}: 任务名为空`)
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// 检查 5: task 无 id 的 warning(不限制只在有 id 时检查)
|
|
73
|
-
for (const wave of waves) {
|
|
74
|
-
for (const task of wave.tasks) {
|
|
75
|
-
if (task.index == null) {
|
|
76
|
-
warnings.push(`Wave ${wave.index}: task "${task.name}" 没有 task id(建议格式 task-XX: 名称)`)
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return { ok: errors.length === 0, errors, warnings, tasks: allTasks, waves }
|
|
82
|
-
}
|
|
83
|
-
|
|
84
4
|
export const definition = {
|
|
85
5
|
name: 'execute',
|
|
86
6
|
title: '波次执行',
|
|
@@ -116,65 +36,11 @@ const fixedPrefix = [
|
|
|
116
36
|
4. 读取 local.yaml(构建命令)
|
|
117
37
|
5. 加载 CODEBASE-OVERVIEW.md
|
|
118
38
|
|
|
119
|
-
### 模块文档加载
|
|
120
|
-
6. 读取 \`.sillyspec/docs/<project>/modules/_module-map.yaml\`(不存在则跳过以下步骤)
|
|
121
|
-
7. 根据 plan.md 中的任务文件路径匹配 _module-map.yaml 中的模块
|
|
122
|
-
8. 读取匹配到的 \`.sillyspec/docs/<project>/modules/<module>.md\`
|
|
123
|
-
9. 实现代码时遵循模块文档中描述的接口约定、数据流和依赖关系
|
|
124
|
-
10. **利用模块索引快速定位源码**:
|
|
125
|
-
- 用 entrypoints 字段直接找到模块对外 API 的源码位置
|
|
126
|
-
- 用 main_symbols 字段找到核心类/函数的定义位置
|
|
127
|
-
- 子代理优先读模块卡片理解语义,再读 entrypoints/main_symbols 对应的源码
|
|
128
|
-
|
|
129
|
-
### 符号影响面扩展检查
|
|
130
|
-
11. **符号影响面扫描**(Critical — execute 前必做):
|
|
131
|
-
- 读取所有 tasks/task-NN.md,提取每个任务涉及的修改文件
|
|
132
|
-
- 对每个修改文件,检查是否涉及以下变更类型:
|
|
133
|
-
- class 构造函数参数变更(新增/删除/修改参数)
|
|
134
|
-
- 接口(interface)定义变更
|
|
135
|
-
- DTO / 类型定义变更
|
|
136
|
-
- API client 方法签名变更
|
|
137
|
-
- 函数/方法签名变更(参数增删改)
|
|
138
|
-
- 如果涉及上述变更类型,执行调用点搜索:
|
|
139
|
-
\`\`\`bash
|
|
140
|
-
rg "new ClassName\(" src/
|
|
141
|
-
rg "ClassName\(" src/
|
|
142
|
-
rg "methodName\(" src/
|
|
143
|
-
rg "import.*from.*filePath" src/
|
|
144
|
-
\`\`\`
|
|
145
|
-
- 将搜索到的调用点与 plan.md 和 tasks/task-NN.md 的 allowed_paths 对比
|
|
146
|
-
- **发现调用点不在任何 task 的 allowed_paths 中 → 直接阻断 execute**
|
|
147
|
-
- 报告:列出每个受影响符号、调用点位置、是否在任务范围内
|
|
148
|
-
- 如果调用点不在范围内但任务明确写了"不改原因",记录但不阻断
|
|
149
|
-
|
|
150
39
|
### 输出
|
|
151
|
-
|
|
40
|
+
已加载的上下文摘要`,
|
|
152
41
|
outputHint: '上下文摘要',
|
|
153
42
|
optional: false
|
|
154
43
|
},
|
|
155
|
-
{
|
|
156
|
-
name: '确认 worktree 路径',
|
|
157
|
-
prompt: `确认当前 worktree 状态,提取隔离路径。
|
|
158
|
-
|
|
159
|
-
### 操作
|
|
160
|
-
1. 运行 \`sillyspec worktree meta <change-name>\` 读取 meta.json
|
|
161
|
-
2. 从输出中提取 worktreePath、branch、mode 字段
|
|
162
|
-
3. 确认 worktree 目录存在(如果是 worktree/native-worktree 模式)
|
|
163
|
-
|
|
164
|
-
### 铁律
|
|
165
|
-
- **worktree 已由 CLI 在 execute 阶段启动时自动创建,不要自行创建或跳过**
|
|
166
|
-
- **后续所有子代理的 cwd 必须设为该 worktree 路径**
|
|
167
|
-
- 如果 meta.json 不存在(说明创建失败),停止并报错
|
|
168
|
-
- **不要自行检查 git dirty/uncommitted 状态来判断是否可以进入 worktree,CLI 已自动处理**
|
|
169
|
-
|
|
170
|
-
### 输出
|
|
171
|
-
worktree 路径 + 分支名 + 模式
|
|
172
|
-
|
|
173
|
-
### 完成后执行
|
|
174
|
-
sillyspec run execute --done --output "worktree 路径 + 分支名 + 模式"`,
|
|
175
|
-
outputHint: 'worktree 路径 + 分支名 + 模式',
|
|
176
|
-
optional: false
|
|
177
|
-
},
|
|
178
44
|
{
|
|
179
45
|
name: '确认执行范围',
|
|
180
46
|
prompt: `解析任务,确认执行范围和确认模式。
|
|
@@ -187,90 +53,19 @@ sillyspec run execute --done --output "worktree 路径 + 分支名 + 模式"`,
|
|
|
187
53
|
- 简单修改 → 快速模型
|
|
188
54
|
- 文档/写作 → 写作模型
|
|
189
55
|
3. 用户在 tasks.md 中的 [model:xxx] 标签优先
|
|
190
|
-
4.
|
|
191
|
-
-
|
|
192
|
-
-
|
|
193
|
-
-
|
|
56
|
+
4. 询问用户执行确认频率:
|
|
57
|
+
- 每个 Wave 确认 — 每个 Wave 完成后展示结果
|
|
58
|
+
- AI 自主判断 — BLOCKED 或计划外变更时才询问
|
|
59
|
+
- 全自动 — 全部自动执行
|
|
194
60
|
5. 查询知识库:读取 \`.sillyspec/knowledge/INDEX.md\`,根据 Task 关键词匹配
|
|
195
61
|
|
|
196
|
-
### 知识命中报告
|
|
197
|
-
{KNOWLEDGE_HIT_REPORT}
|
|
198
|
-
|
|
199
|
-
如上所示的知识条目与本次任务相关。请阅读这些条目以获取项目约定和已知模式。
|
|
200
|
-
如无命中条目(Status: no matches),跳过本节。
|
|
201
|
-
|
|
202
|
-
### 铁律
|
|
203
|
-
- **不要询问用户确认频率**,确认模式由 CLI \`--confirm-mode\` 参数决定
|
|
204
|
-
- 如果未检测到 \`--confirm-mode\`,默认使用 wave 模式`,
|
|
205
|
-
outputHint: 'Wave 分组 + 模型分配',
|
|
206
|
-
optional: false
|
|
207
|
-
}
|
|
208
|
-
]
|
|
209
|
-
|
|
210
|
-
// 全局验收步骤定义
|
|
211
|
-
const acceptanceSteps = [
|
|
212
|
-
{
|
|
213
|
-
name: '对照设计检查',
|
|
214
|
-
mode: 'acceptance',
|
|
215
|
-
prompt: `对照 design.md 检查所有实现是否与设计一致。
|
|
216
|
-
|
|
217
|
-
### 执行方式
|
|
218
|
-
本步骤由当前 agent 汇总执行,不需要为每个检查项启动独立子代理。
|
|
219
|
-
如需深入验证某个模块,可启动单个 QA 子代理统一处理。
|
|
220
|
-
|
|
221
|
-
### 操作
|
|
222
|
-
1. 读取 design.md(技术方案)
|
|
223
|
-
2. 逐一对照 design.md 中的设计要点与实际代码实现
|
|
224
|
-
3. 检查接口签名、数据结构、模块划分是否一致
|
|
225
|
-
4. 记录偏差项(偏差 ≠ 错误,可能是合理的实现调整)
|
|
226
|
-
|
|
227
62
|
### 输出
|
|
228
|
-
|
|
229
|
-
outputHint: '设计对照检查清单',
|
|
230
|
-
optional: false
|
|
231
|
-
},
|
|
232
|
-
{
|
|
233
|
-
name: '运行测试',
|
|
234
|
-
mode: 'acceptance',
|
|
235
|
-
prompt: `运行所有测试,验证代码质量。
|
|
236
|
-
|
|
237
|
-
### 执行方式
|
|
238
|
-
本步骤由当前 agent 执行,不需要启动独立子代理。
|
|
63
|
+
Wave 分组 + 模型分配 + 确认模式 + 知识库匹配结果
|
|
239
64
|
|
|
240
|
-
###
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
3. 运行 lint 检查
|
|
244
|
-
4. 如果有测试失败 → 分析原因,标注是代码问题还是测试本身的问题
|
|
245
|
-
5. 汇总测试结果
|
|
246
|
-
|
|
247
|
-
### 输出
|
|
248
|
-
测试结果摘要:通过/失败/跳过数量 + 失败项分析`,
|
|
249
|
-
outputHint: '测试结果摘要',
|
|
65
|
+
### 注意
|
|
66
|
+
- 默认推荐"每个 Wave 确认"`,
|
|
67
|
+
outputHint: 'Wave 分组 + 模型分配',
|
|
250
68
|
optional: false
|
|
251
|
-
},
|
|
252
|
-
{
|
|
253
|
-
name: '代码审查',
|
|
254
|
-
mode: 'acceptance',
|
|
255
|
-
prompt: `对本次变更进行代码审查。
|
|
256
|
-
|
|
257
|
-
### 执行方式
|
|
258
|
-
本步骤由当前 agent 或一个 QA agent 汇总执行,不需要为每个文件启动独立子代理。
|
|
259
|
-
|
|
260
|
-
### 操作
|
|
261
|
-
1. 检查 git diff 查看所有变更
|
|
262
|
-
2. 审查要点:
|
|
263
|
-
- 代码风格是否符合 CONVENTIONS.md
|
|
264
|
-
- 是否有明显的 bug 或安全漏洞
|
|
265
|
-
- 是否有未处理的 TODO/FIXME
|
|
266
|
-
- 错误处理是否完善
|
|
267
|
-
- 是否有冗余代码或可简化的逻辑
|
|
268
|
-
3. 对照 ARCHITECTURE.md 检查架构合规性
|
|
269
|
-
|
|
270
|
-
### 输出
|
|
271
|
-
审查结果:问题列表(严重程度 + 建议修复方式)+ 总体评价`,
|
|
272
|
-
outputHint: '代码审查结果',
|
|
273
|
-
optional: true
|
|
274
69
|
}
|
|
275
70
|
]
|
|
276
71
|
|
|
@@ -281,7 +76,7 @@ const fixedSuffix = [
|
|
|
281
76
|
prompt: `检查本轮执行产生的新知识。
|
|
282
77
|
|
|
283
78
|
### 操作
|
|
284
|
-
1. 检查
|
|
79
|
+
1. 检查 \`.sillyspec/knowledge/uncategorized.md\` 中待确认条目
|
|
285
80
|
2. 如有 → 提示用户审阅
|
|
286
81
|
3. 用户确认后改为 [已确认],可归类到专题文件
|
|
287
82
|
|
|
@@ -294,60 +89,19 @@ const fixedSuffix = [
|
|
|
294
89
|
name: '完成确认',
|
|
295
90
|
prompt: `所有任务完成后的收尾。
|
|
296
91
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
**自动审计流程(不需要用户确认代码):**
|
|
305
|
-
|
|
306
|
-
1. 运行 \`sillyspec worktree assess <change-name>\` 自动风险审计
|
|
307
|
-
2. 系统自动检查:
|
|
308
|
-
- patch --check 是否通过
|
|
309
|
-
- 变更是否在 allowed_paths 内
|
|
310
|
-
- 主工作区 baseline 是否变化
|
|
311
|
-
- 是否有高风险文件(lockfile/migration/配置/入口)
|
|
312
|
-
- diff 规模是否异常
|
|
313
|
-
3. 输出 Apply Decision:
|
|
314
|
-
|
|
315
|
-
\`\`\`
|
|
316
|
-
Worktree Apply Decision
|
|
317
|
-
────────────────────────
|
|
318
|
-
Decision: SAFE | WARNING | BLOCKED
|
|
319
|
-
Changed files: N
|
|
320
|
-
Additions: +N Deletions: -N
|
|
321
|
-
Risky files: none | <list>
|
|
322
|
-
Action: auto-applied | blocked
|
|
323
|
-
\`\`\`
|
|
324
|
-
|
|
325
|
-
4. **SAFE** → 自动 \`sillyspec worktree apply <change-name>\` + cleanup
|
|
326
|
-
5. **WARNING** → 自动 apply(有警告但不阻断)+ cleanup
|
|
327
|
-
6. **BLOCKED** → 不 apply,输出原因,提示用户检查:
|
|
328
|
-
- \`sillyspec worktree diff <change-name>\` 查看具体变更
|
|
329
|
-
- \`sillyspec worktree cleanup <change-name>\` 丢弃
|
|
330
|
-
7. 建议下一步:\`sillyspec run verify\`
|
|
331
|
-
|
|
332
|
-
### 操作(mode = native-worktree,用户已有的 linked worktree)
|
|
333
|
-
1. 同上自动审计流程
|
|
334
|
-
2. SAFE/WARNING → \`sillyspec worktree apply <change-name>\`
|
|
335
|
-
3. **不要运行 cleanup**
|
|
336
|
-
4. 输出 Worktree: kept
|
|
337
|
-
5. 建议下一步:\`sillyspec run verify\`
|
|
338
|
-
|
|
339
|
-
### 操作(mode = in-place-fallback,降级模式无隔离目录)
|
|
340
|
-
1. 展示本次执行摘要(\`git diff\` 查看变更)
|
|
341
|
-
2. 跳过 apply 和 cleanup
|
|
342
|
-
3. 输出 Worktree: none
|
|
343
|
-
4. 建议下一步:\`sillyspec run verify\`
|
|
92
|
+
### 操作
|
|
93
|
+
1. 询问用户下一步:
|
|
94
|
+
- 验证 → sillyspec run verify
|
|
95
|
+
- 归档 → /sillyspec:archive
|
|
96
|
+
- 继续开发
|
|
97
|
+
2. 提示 git add 暂存变更
|
|
344
98
|
|
|
345
99
|
### 输出
|
|
346
|
-
|
|
100
|
+
用户选择 + 下一步命令
|
|
347
101
|
|
|
348
102
|
### 注意
|
|
349
103
|
- 完成后运行 \`sillyspec run execute --done\` 即可自动推进阶段`,
|
|
350
|
-
outputHint: '
|
|
104
|
+
outputHint: '用户选择',
|
|
351
105
|
optional: false
|
|
352
106
|
}
|
|
353
107
|
]
|
|
@@ -374,9 +128,7 @@ function parseWavesFromPlan(planContent) {
|
|
|
374
128
|
|
|
375
129
|
const taskMatch = line.match(/^[-*]\s*\[[ x]\]\s*(.+)/)
|
|
376
130
|
if (taskMatch) {
|
|
377
|
-
const taskNoMatch = taskMatch[1].match(/\btask-(\d+)\b/i)
|
|
378
131
|
currentTask = {
|
|
379
|
-
index: taskNoMatch ? parseInt(taskNoMatch[1], 10) : null,
|
|
380
132
|
name: taskMatch[1].trim(),
|
|
381
133
|
file: '',
|
|
382
134
|
steps: '',
|
|
@@ -414,195 +166,86 @@ function parseWavesFromPlan(planContent) {
|
|
|
414
166
|
}
|
|
415
167
|
|
|
416
168
|
/**
|
|
417
|
-
* 为 Wave 生成 prompt
|
|
169
|
+
* 为 Wave 生成 prompt
|
|
418
170
|
*/
|
|
419
|
-
function buildWavePrompt(wave, waveIndex, changeDir
|
|
420
|
-
// ── Contract Matrix:检查是否有 provider/consumer 契约需要注入 ──
|
|
421
|
-
let contractInjection = ''
|
|
422
|
-
if (changeDir) {
|
|
423
|
-
try {
|
|
424
|
-
const { buildContractMatrix, buildConsumerInjection } = require('../contract-matrix.js')
|
|
425
|
-
const planFile = path.join(changeDir, 'plan.md')
|
|
426
|
-
if (existsSync(planFile)) {
|
|
427
|
-
const planContent = readFileSync(planFile, 'utf8')
|
|
428
|
-
const contracts = buildContractMatrix(planContent, changeDir)
|
|
429
|
-
if (contracts.length > 0) {
|
|
430
|
-
// 收集本 wave 所有 task 的注入内容
|
|
431
|
-
const waveTasks = wave.tasks.map((t, ti) => {
|
|
432
|
-
const num = String(t.index || (ti + 1)).padStart(2, '0')
|
|
433
|
-
return `task-${num}`
|
|
434
|
-
})
|
|
435
|
-
const relevantContracts = contracts.filter(c => waveTasks.includes(c.consumer))
|
|
436
|
-
if (relevantContracts.length > 0) {
|
|
437
|
-
contractInjection = `
|
|
438
|
-
### API Contract Matrix
|
|
439
|
-
本 Wave 存在前端/后端跨 task 契约:
|
|
440
|
-
${relevantContracts.map(c => `- **${c.consumer}** 消费 **${c.provider}** 产出的 API`).join('\n')}
|
|
441
|
-
`
|
|
442
|
-
// 为每个 consumer task 生成详细注入
|
|
443
|
-
for (const taskName of waveTasks) {
|
|
444
|
-
const injection = buildConsumerInjection(changeDir, join(changeDir, '..', '..'), taskName, contracts)
|
|
445
|
-
if (injection) {
|
|
446
|
-
contractInjection += `
|
|
447
|
-
### 子代理 ${taskName} 的契约注入
|
|
448
|
-
为 ${taskName} 启动子代理时,在子代理 prompt 末尾追加以下内容:
|
|
449
|
-
|
|
450
|
-
<contract-injection>
|
|
451
|
-
${injection}
|
|
452
|
-
</contract-injection>
|
|
453
|
-
`
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
} catch {}
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
// 构建任务摘要(不再内联完整蓝图,减少上下文污染)
|
|
463
|
-
const taskSummary = wave.tasks.map((t, ti) => {
|
|
464
|
-
const taskNum = String(t.index || (ti + 1)).padStart(2, '0')
|
|
465
|
-
const taskRelPath = changeDir
|
|
466
|
-
? `.sillyspec/changes/${path.basename(changeDir)}/tasks/task-${taskNum}.md`
|
|
467
|
-
: `task-${taskNum}.md`
|
|
468
|
-
const fileInfo = t.file ? ` (${t.file})` : ''
|
|
469
|
-
return `task-${taskNum}: ${t.name}${fileInfo} → ${taskRelPath}`
|
|
470
|
-
}).join('\n')
|
|
471
|
-
|
|
171
|
+
function buildWavePrompt(wave, waveIndex, changeDir) {
|
|
472
172
|
const taskList = wave.tasks.map((t, ti) => {
|
|
473
173
|
const taskNum = String(t.index || (ti + 1)).padStart(2, '0')
|
|
174
|
+
const taskFile = changeDir ? `${changeDir}/tasks/task-${taskNum}.md` : ''
|
|
175
|
+
const taskFileExists = taskFile && existsSync(taskFile)
|
|
474
176
|
let s = `- [ ] ${t.name}`
|
|
475
177
|
if (t.file) s += ` (${t.file})`
|
|
178
|
+
if (taskFileExists) {
|
|
179
|
+
try {
|
|
180
|
+
const taskContent = readFileSync(taskFile, 'utf8').trim()
|
|
181
|
+
s += `
|
|
182
|
+
\n### 📋 任务蓝图(task-${taskNum}.md)\n${taskContent}`
|
|
183
|
+
} catch (e) {
|
|
184
|
+
s += `
|
|
185
|
+
\n### 📋 任务蓝图(task-${taskNum}.md)\n⚠️ 读取失败: ${e.message}`
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (t.reference) s += `\n 参考: ${t.reference}`
|
|
189
|
+
if (t.steps) s += `\n 步骤: ${t.steps}`
|
|
476
190
|
return s
|
|
477
191
|
}).join('\n')
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
调用 Task 工具启动子代理时,**workdir 参数是强制必传的**。
|
|
484
|
-
不传 workdir 会导致子代理把文件写到主工作区而非 worktree,破坏隔离。
|
|
485
|
-
|
|
486
|
-
\`\`\`json
|
|
487
|
-
{
|
|
488
|
-
"subagent_type": "general",
|
|
489
|
-
"workdir": "${worktreePath}",
|
|
490
|
-
"prompt": "在此编写任务描述..."
|
|
491
|
-
}
|
|
492
|
-
\`\`\`
|
|
493
|
-
|
|
494
|
-
### 注意
|
|
495
|
-
蓝图文件(tasks.md / design.md / proposal.md / requirements.md)在主工作区 .sillyspec/changes/<change>/ 下,它们可能不在 worktree 中。读取蓝图时使用主工作区路径,不要拼接到 worktree 路径下。
|
|
496
|
-
`
|
|
497
|
-
: ''
|
|
498
|
-
|
|
192
|
+
const { join } = path
|
|
193
|
+
const hasTaskBlueprints = changeDir && existsSync(join(changeDir, 'tasks'))
|
|
194
|
+
const taskBlueprintRule = hasTaskBlueprints
|
|
195
|
+
? '每个任务有独立的 task-N.md 蓝图——只做蓝图里写的事,不要实现蓝图之外的功能。如果蓝图有问题,**停下来反馈**,不要自己改。问题归因:实现困难 → task 蓝图没写好 → plan 没做好 → design 有缺陷。'
|
|
196
|
+
: '如果发现 plan 不合理,**停下来反馈**,不要自己改方案。问题归因:实现困难 → plan 没做好 → design 有缺陷。'
|
|
499
197
|
return `## Wave ${waveIndex}: 执行以下任务
|
|
500
198
|
|
|
501
|
-
## 执行方式(必须严格遵守)
|
|
502
|
-
|
|
503
|
-
**每个任务必须由独立子代理执行,你不要自己写代码。**
|
|
504
|
-
|
|
505
|
-
你的角色是调度者 + 审查者:
|
|
506
|
-
1. 为每个任务启动一个子代理(Agent tool),同 Wave 内可并行
|
|
507
|
-
2. 子代理完成后审查结果
|
|
508
|
-
3. 勾选 plan.md 中的 checkbox
|
|
509
|
-
4. 记录改动文件和测试结果
|
|
510
|
-
|
|
511
|
-
${worktreeSection}
|
|
512
|
-
### 任务摘要(按需读取完整蓝图)
|
|
513
|
-
为每个任务启动子代理时,**只需告知任务目标和蓝图文件路径,让子代理按需读取**:
|
|
514
|
-
|
|
515
|
-
${taskSummary}
|
|
516
|
-
|
|
517
|
-
子代理 prompt 要点:
|
|
518
|
-
1. 任务目标(简短描述)
|
|
519
|
-
2. 蓝图文件路径(让子代理自行读取详情)
|
|
520
|
-
3. 编码铁律:先读后写、TDD、不编造方法、只做蓝图里写的事、遵守边界处理规则、不超出 allowed_paths
|
|
521
|
-
4. 如存在模块文档(.sillyspec/docs/*/modules/),按需读取涉及模块的 <module>.md 参考接口约定和数据流
|
|
522
|
-
|
|
523
199
|
### Wave 开始前
|
|
524
200
|
1. 读取 design.md 的「编码铁律」章节(如果存在),严格遵守
|
|
525
201
|
2. 读取 plan.md 了解全局任务划分和依赖关系
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
202
|
+
2. 确认本 Wave 的输入/输出契约(前置 Wave 产出了什么,本 Wave 需要消费什么)
|
|
203
|
+
3. 检查前置 Wave 的产出是否完整(文件是否存在、测试是否通过)
|
|
204
|
+
4. **上下文分层加载**:
|
|
529
205
|
- 🔥 热上下文:design.md 编码铁律 + 当前 Wave 任务(必须加载)
|
|
530
206
|
- 🌡️ 温上下文:CONVENTIONS.md + ARCHITECTURE.md(需要时加载)
|
|
531
207
|
- ❄️ 冷上下文:其他变更的 design.md、历史 plan.md(不要主动加载,除非明确需要)
|
|
532
|
-
|
|
208
|
+
|
|
533
209
|
### 本 Wave 任务
|
|
534
210
|
${taskList}
|
|
535
211
|
|
|
536
|
-
###
|
|
537
|
-
1.
|
|
538
|
-
2.
|
|
212
|
+
### 执行要求
|
|
213
|
+
1. 按任务顺序执行,同一 Wave 内任务可并行
|
|
214
|
+
2. 铁律:先读后写、grep 确认方法存在、不编造、TDD
|
|
215
|
+
3. **禁止发散思维**:你是代码搬运工,严格按任务描述执行,不增不减不改。${taskBlueprintRule}
|
|
216
|
+
4. **Reverse Sync**:发现 Bug 或实现与 design.md/task-N.md 不一致时,先检查是代码错了还是文档有遗漏,有遗漏则先修文档再修代码。
|
|
539
217
|
3. **不要频繁编译!** 编译很慢,只在以下情况运行:
|
|
540
218
|
- 写了大量代码后需要验证语法正确性
|
|
541
219
|
- 最后一个 Wave 完成后做一次全量编译验证
|
|
542
220
|
- 用户明确要求编译时
|
|
543
|
-
4.
|
|
544
|
-
|
|
221
|
+
4. 单个任务完成后只跑**对应模块的单元测试**(TDD 绿灯确认),不要跑全量编译
|
|
222
|
+
5. 每个任务完成后:
|
|
223
|
+
- 勾选 task-N.md 中的验收标准 checkbox
|
|
224
|
+
- 勾选 plan.md / tasks.md 中对应任务的 checkbox
|
|
545
225
|
- 记录改动文件和测试结果
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
### Task Review Gate(必须执行,不可跳过)
|
|
549
|
-
|
|
550
|
-
每个子代理完成后、勾选 checkbox **之前**,你必须创建 task review。
|
|
551
|
-
|
|
552
|
-
**操作步骤:**
|
|
553
|
-
1. 读取当前 task 的 git diff(从 task 开始到完成的变更)
|
|
554
|
-
2. 对照 plan.md 中该 task 的描述和 tasks/task-XX.md(如果存在)检查实现是否符合要求
|
|
555
|
-
3. 写入 review.json 文件
|
|
556
|
-
4. **只有 review.json 写入成功后,才允许勾选 plan.md 中的 checkbox**
|
|
557
|
-
|
|
558
|
-
**review.json 路径:**
|
|
559
|
-
|
|
560
|
-
task-XX 对应:.sillyspec/.runtime/execute-runs/{EXECUTE_RUN_ID}/tasks/task-XX/review.json
|
|
561
|
-
|
|
562
|
-
本 execute run 的固定 ID 是:{EXECUTE_RUN_ID}
|
|
563
|
-
**所有 task 的 review.json 必须使用这个 ID,不要自行创建新目录。**
|
|
564
|
-
|
|
565
|
-
**review.json 必填字段:**
|
|
566
|
-
|
|
567
|
-
{ "schemaVersion": 1, "task": "task-XX", "base": "<git-base-commit>", "head": "<git-head-commit>",
|
|
568
|
-
"changedFiles": ["src/foo.js"], "specVerdict": "pass|fail|cannot_verify",
|
|
569
|
-
"qualityVerdict": "pass|fail|cannot_verify", "reviewerNotes": "评审说明",
|
|
570
|
-
"requiredEvidence": [] }
|
|
571
|
-
|
|
572
|
-
**评审铁律:**
|
|
573
|
-
- 不信任 implementer 自报结果,对照 diff 和 task brief 验证
|
|
574
|
-
- 只看当前 task 的 diff,不做全仓库漫游审查
|
|
575
|
-
- \`cannot_verify\` 只在确实无法验证且有待补充证据时使用,且 requiredEvidence 必须非空
|
|
576
|
-
- \`sillyspec run execute --done\` 会校验所有 task 的 review.json,缺失或 fail 会阻断完成
|
|
226
|
+
6. 遇到 BLOCKED → 记录原因,选择:重试/跳过/停止
|
|
577
227
|
|
|
578
228
|
### 完成后
|
|
579
|
-
|
|
580
|
-
- 在变更文件中搜索所有 router 注册路径(@router.get/post/put/delete)
|
|
581
|
-
- 将端点清单写入 .sillyspec/.runtime/contract-artifacts/<task-name>/endpoints.json
|
|
582
|
-
- 格式: { "task": "task-XX", "type": "backend_endpoints", "endpoints": [{ "method": "GET", "path": "/api/ppm/xxx" }] }
|
|
583
|
-
2. 运行 sillyspec run execute --done --input "用户原始反馈" --output "Wave ${waveIndex} 结果摘要"`
|
|
229
|
+
运行 sillyspec run execute --done --input "用户原始反馈" --output "Wave ${waveIndex} 结果摘要"`
|
|
584
230
|
}
|
|
585
231
|
|
|
586
232
|
/**
|
|
587
233
|
* 动态构建 execute 步骤列表
|
|
588
234
|
* @param {string|null} planFilePath - plan 文件路径,null 则用默认 3 Wave
|
|
589
|
-
* @param {{ worktreePath?: string, noWorktree?: boolean }} options
|
|
590
235
|
* @returns {Array} 步骤列表
|
|
591
236
|
*/
|
|
592
|
-
export function buildExecuteSteps(planFilePath = null
|
|
593
|
-
const noWorktree = !!options.noWorktree
|
|
237
|
+
export function buildExecuteSteps(planFilePath = null) {
|
|
594
238
|
let waves
|
|
595
239
|
let changeDir = null
|
|
596
240
|
|
|
597
241
|
if (planFilePath && existsSync(planFilePath)) {
|
|
598
242
|
const planContent = readFileSync(planFilePath, 'utf8')
|
|
599
|
-
// Plan → Execute 契约由 plan 阶段完成时的 postcheck 把关(run.js completeStep),
|
|
600
|
-
// 此处只负责解析 waves,避免 buildExecuteSteps 与进程退出耦合。
|
|
601
243
|
waves = parseWavesFromPlan(planContent)
|
|
244
|
+
// 从 planFilePath 推导 changeDir: .sillyspec/changes/<name>/plan.md
|
|
602
245
|
changeDir = path.dirname(planFilePath)
|
|
603
246
|
}
|
|
604
247
|
|
|
605
|
-
//
|
|
248
|
+
// 如果没解析出 Wave,生成默认 3 个
|
|
606
249
|
if (!waves || waves.length === 0) {
|
|
607
250
|
waves = []
|
|
608
251
|
for (let i = 1; i <= 3; i++) {
|
|
@@ -610,16 +253,12 @@ export function buildExecuteSteps(planFilePath = null, options = {}) {
|
|
|
610
253
|
}
|
|
611
254
|
}
|
|
612
255
|
|
|
613
|
-
// 尝试获取 worktree 路径(可能由前缀步骤创建)
|
|
614
|
-
const worktreePath = options.worktreePath || null
|
|
615
|
-
|
|
616
256
|
const waveSteps = waves.map((wave, i) => ({
|
|
617
257
|
name: `Wave ${i + 1} 执行`,
|
|
618
|
-
|
|
619
|
-
prompt: buildWavePrompt(wave, i + 1, changeDir, worktreePath),
|
|
258
|
+
prompt: buildWavePrompt(wave, i + 1, changeDir),
|
|
620
259
|
outputHint: `Wave ${i + 1} 执行结果`,
|
|
621
260
|
optional: false
|
|
622
261
|
}))
|
|
623
262
|
|
|
624
|
-
return [...fixedPrefix, ...waveSteps, ...
|
|
263
|
+
return [...fixedPrefix, ...waveSteps, ...fixedSuffix]
|
|
625
264
|
}
|
package/src/stages/index.js
CHANGED
|
@@ -1,29 +1,35 @@
|
|
|
1
1
|
import { definition as brainstorm } from './brainstorm.js'
|
|
2
|
+
import { definition as propose } from './propose.js'
|
|
2
3
|
import { definition as plan } from './plan.js'
|
|
3
4
|
import { definition as execute } from './execute.js'
|
|
4
5
|
import { definition as verify } from './verify.js'
|
|
5
6
|
import { definition as scan } from './scan.js'
|
|
6
7
|
import { definition as quick } from './quick.js'
|
|
7
|
-
import { definition as explore } from './explore.js'
|
|
8
8
|
import { definition as archive } from './archive.js'
|
|
9
9
|
import { definition as status } from './status.js'
|
|
10
10
|
import { definition as doctor } from './doctor.js'
|
|
11
11
|
|
|
12
|
-
// 标记辅助阶段
|
|
13
|
-
const auxiliaryFlag = { auxiliary: true }
|
|
14
|
-
|
|
15
12
|
export const stageRegistry = {
|
|
16
13
|
brainstorm,
|
|
14
|
+
propose,
|
|
17
15
|
plan,
|
|
18
16
|
execute,
|
|
19
17
|
verify,
|
|
20
|
-
scan
|
|
21
|
-
quick
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
18
|
+
scan,
|
|
19
|
+
quick,
|
|
20
|
+
archive,
|
|
21
|
+
status,
|
|
22
|
+
doctor
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// 流程阶段顺序,用于 getNextStage
|
|
26
|
+
const stageOrder = ['brainstorm', 'plan', 'execute', 'verify']
|
|
27
|
+
|
|
28
|
+
export function getNextStage(currentStage) {
|
|
29
|
+
const index = stageOrder.indexOf(currentStage)
|
|
30
|
+
if (index === -1 || index >= stageOrder.length - 1) return null
|
|
31
|
+
return stageOrder[index + 1]
|
|
26
32
|
}
|
|
27
33
|
|
|
28
|
-
//
|
|
29
|
-
export const auxiliaryStages = ['scan', 'quick', '
|
|
34
|
+
// 辅助命令(不影响流程阶段推进)
|
|
35
|
+
export const auxiliaryStages = ['scan', 'quick', 'archive', 'status', 'doctor']
|