sillyspec 3.10.0 → 3.10.2
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-resume/SKILL.md +5 -5
- package/.claude/skills/sillyspec-state/SKILL.md +1 -1
- package/package.json +1 -1
- package/src/run.js +69 -3
- package/src/stages/archive.js +14 -8
- package/src/stages/brainstorm.js +1 -1
- package/src/stages/execute.js +89 -34
- package/src/stages/index.js +9 -6
- package/src/stages/plan.js +0 -1
- package/src/stages/quick.js +20 -7
- package/src/stages/scan.js +40 -1
- package/src/stages/verify.js +35 -6
|
@@ -17,7 +17,7 @@ description: 恢复工作 — 从中断处继续
|
|
|
17
17
|
### 1. 读取 progress.json
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
sillyspec
|
|
20
|
+
sillyspec run resume --status 2>/dev/null
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
### 2. 如果有 progress.json
|
|
@@ -45,7 +45,7 @@ sillyspec progress show 2>/dev/null
|
|
|
45
45
|
|
|
46
46
|
**不需要执行 Git 操作或文件探测。** progress.json 已经包含所有信息。
|
|
47
47
|
|
|
48
|
-
使用 `sillyspec
|
|
48
|
+
使用 `sillyspec run resume --status` 查看。
|
|
49
49
|
|
|
50
50
|
然后问用户:
|
|
51
51
|
1. 直接继续执行下一步
|
|
@@ -80,7 +80,7 @@ cat .sillyspec/ROADMAP.md 2>/dev/null
|
|
|
80
80
|
|
|
81
81
|
检查各阶段状态并输出阶段进度表(同步骤 2 格式)。
|
|
82
82
|
|
|
83
|
-
同时**运行 `sillyspec
|
|
83
|
+
同时**运行 `sillyspec run resume --init`**,将探测到的信息写入 progress.json,后续命令执行时会自动更新。
|
|
84
84
|
|
|
85
85
|
#### 如果是普通变更(无 MASTER.md)
|
|
86
86
|
|
|
@@ -102,10 +102,10 @@ cat .sillyspec/ROADMAP.md 2>/dev/null
|
|
|
102
102
|
- 有部分 codebase 文档(如只有 STACK 和 STRUCTURE)→ 说明快扫或深扫中断
|
|
103
103
|
- 缺失的文档列表直接展示给用户,告知 `/sillyspec:scan` 会自动跳过已存在的文档
|
|
104
104
|
|
|
105
|
-
**同时运行 `sillyspec
|
|
105
|
+
**同时运行 `sillyspec run resume --init`** 记录推断的状态。
|
|
106
106
|
|
|
107
107
|
### 4. 关键原则
|
|
108
108
|
|
|
109
109
|
- **不需要 HANDOFF.json**。progress.json 是唯一的恢复数据源。
|
|
110
110
|
- **progress.json 不需要 Git 提交**(已在 .runtime/ 下,被 .gitignore 忽略)。
|
|
111
|
-
- **每次命令执行完自动更新 progress.json**(通过 `sillyspec
|
|
111
|
+
- **每次命令执行完自动更新 progress.json**(通过 `sillyspec run <stage> --done`),不需要用户手动保存。
|
package/package.json
CHANGED
package/src/run.js
CHANGED
|
@@ -174,6 +174,7 @@ export async function runCommand(args, cwd) {
|
|
|
174
174
|
const isSkip = flags.includes('--skip')
|
|
175
175
|
const isStatus = flags.includes('--status')
|
|
176
176
|
const isReset = flags.includes('--reset')
|
|
177
|
+
const isConfirm = flags.includes('--confirm')
|
|
177
178
|
|
|
178
179
|
// 解析 --output
|
|
179
180
|
let outputText = null
|
|
@@ -248,7 +249,7 @@ export async function runCommand(args, cwd) {
|
|
|
248
249
|
|
|
249
250
|
// --done
|
|
250
251
|
if (isDone) {
|
|
251
|
-
return await completeStep(pm, progress, stageName, cwd, outputText, inputText)
|
|
252
|
+
return await completeStep(pm, progress, stageName, cwd, outputText, inputText, { confirm: isConfirm })
|
|
252
253
|
}
|
|
253
254
|
|
|
254
255
|
// 默认:输出当前步骤
|
|
@@ -329,7 +330,7 @@ function validateMetadata(cwd, stageName) {
|
|
|
329
330
|
}
|
|
330
331
|
|
|
331
332
|
async function completeStep(pm, progress, stageName, cwd, outputText, inputText = null, options = {}) {
|
|
332
|
-
const { printNext = true } = options
|
|
333
|
+
const { printNext = true, confirm = false } = options
|
|
333
334
|
const stageData = progress.stages[stageName]
|
|
334
335
|
if (!stageData || !stageData.steps) {
|
|
335
336
|
console.error(`❌ 阶段 ${stageName} 未初始化`)
|
|
@@ -405,9 +406,74 @@ async function completeStep(pm, progress, stageName, cwd, outputText, inputText
|
|
|
405
406
|
// 验证:检查生成的文件是否包含 author 和 created_at
|
|
406
407
|
validateMetadata(cwd, stageName)
|
|
407
408
|
|
|
409
|
+
// archive 阶段 Step 2(确认归档)完成时自动执行归档移动
|
|
410
|
+
if (stageName === 'archive' && steps[currentIdx]?.name === '确认归档') {
|
|
411
|
+
if (confirm) {
|
|
412
|
+
const { renameSync } = await import('fs')
|
|
413
|
+
const changeName = progress.currentChange
|
|
414
|
+
if (!changeName) {
|
|
415
|
+
console.error('❌ 归档失败:未找到当前变更名(currentChange)')
|
|
416
|
+
process.exit(1)
|
|
417
|
+
}
|
|
418
|
+
const changesDir = join(cwd, '.sillyspec', 'changes')
|
|
419
|
+
const archiveDir = join(changesDir, 'archive')
|
|
420
|
+
const srcDir = join(changesDir, changeName)
|
|
421
|
+
const date = new Date().toISOString().slice(0, 10)
|
|
422
|
+
const destDir = join(archiveDir, `${date}-${changeName}`)
|
|
423
|
+
|
|
424
|
+
if (!existsSync(srcDir)) {
|
|
425
|
+
console.error(`❌ 归档失败:源目录不存在 ${srcDir}`)
|
|
426
|
+
process.exit(1)
|
|
427
|
+
}
|
|
428
|
+
if (existsSync(destDir)) {
|
|
429
|
+
console.error(`❌ 归档失败:目标目录已存在 ${destDir}`)
|
|
430
|
+
process.exit(1)
|
|
431
|
+
}
|
|
432
|
+
mkdirSync(archiveDir, { recursive: true })
|
|
433
|
+
renameSync(srcDir, destDir)
|
|
434
|
+
|
|
435
|
+
// 校验
|
|
436
|
+
if (!existsSync(destDir) || existsSync(srcDir)) {
|
|
437
|
+
console.error('❌ 归档校验失败:移动操作异常')
|
|
438
|
+
process.exit(1)
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// 清除 currentChange
|
|
442
|
+
progress.currentChange = null
|
|
443
|
+
console.log(`📦 已归档:${changeName} → archive/${date}-${changeName}/`)
|
|
444
|
+
} else {
|
|
445
|
+
console.log('⚠️ 请添加 --confirm 确认归档,例如:sillyspec run archive --done --confirm --output "确认归档"')
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// 辅助阶段(archive/scan/quick 等)完成后重置步骤,允许重复执行
|
|
450
|
+
const stageDef = stageRegistry[stageName]
|
|
451
|
+
if (stageDef?.auxiliary) {
|
|
452
|
+
const freshSteps = (stageDef.steps || []).map(s => ({
|
|
453
|
+
name: s.name,
|
|
454
|
+
status: 'pending',
|
|
455
|
+
output: null,
|
|
456
|
+
completedAt: null
|
|
457
|
+
}))
|
|
458
|
+
stageData.steps = freshSteps
|
|
459
|
+
stageData.status = 'pending'
|
|
460
|
+
stageData.completedAt = null
|
|
461
|
+
pm._write(cwd, progress)
|
|
462
|
+
}
|
|
463
|
+
|
|
408
464
|
const total = steps.length
|
|
409
465
|
console.log(`✅ ${stageName} 阶段已完成(${total}/${total} 步)`)
|
|
410
|
-
|
|
466
|
+
|
|
467
|
+
// 阶段完成后提示下一步
|
|
468
|
+
if (stageName === 'execute') {
|
|
469
|
+
console.log('\n👉 下一步:sillyspec run verify(验证通过后才能归档)')
|
|
470
|
+
} else if (stageName === 'verify') {
|
|
471
|
+
console.log('\n👉 下一步:sillyspec run archive(验证通过,可以归档了)')
|
|
472
|
+
} else if (stageName === 'archive') {
|
|
473
|
+
console.log('\n👉 归档完成!现在可以提交了:git commit -m "..."')
|
|
474
|
+
} else {
|
|
475
|
+
console.log(`\n下一步由你决定:sillyspec run <stage>(brainstorm/plan/execute/verify/archive 等)`)
|
|
476
|
+
}
|
|
411
477
|
return { stageCompleted: true, currentIdx, nextPendingIdx: -1 }
|
|
412
478
|
}
|
|
413
479
|
|
package/src/stages/archive.js
CHANGED
|
@@ -2,19 +2,19 @@ export const definition = {
|
|
|
2
2
|
name: 'archive',
|
|
3
3
|
title: '归档变更',
|
|
4
4
|
description: '规范沉淀,可追溯',
|
|
5
|
-
auxiliary: true,
|
|
6
5
|
steps: [
|
|
7
6
|
{
|
|
8
7
|
name: '任务完成度检查',
|
|
9
|
-
prompt: `检查
|
|
8
|
+
prompt: `检查 plan.md 中所有任务 checkbox 是否已勾选(plan.md 是任务完成的唯一真相源)。
|
|
10
9
|
|
|
11
10
|
### 操作
|
|
12
|
-
1. 读取 \`.sillyspec/changes/<change-name>/
|
|
13
|
-
2. 检查所有 checkbox 是否已勾选
|
|
14
|
-
3.
|
|
11
|
+
1. 读取 \`.sillyspec/changes/<change-name>/plan.md\`
|
|
12
|
+
2. 检查所有 \`- [x]\` checkbox 是否已勾选
|
|
13
|
+
3. 如果 plan.md 不存在,回退读取 tasks.md 作为备选
|
|
14
|
+
4. 如有遗漏 → 询问用户是否继续归档
|
|
15
15
|
|
|
16
16
|
### 输出
|
|
17
|
-
|
|
17
|
+
完成度报告(已勾选/总数 + 未完成任务列表)`,
|
|
18
18
|
outputHint: '完成度报告',
|
|
19
19
|
optional: false
|
|
20
20
|
},
|
|
@@ -25,9 +25,15 @@ export const definition = {
|
|
|
25
25
|
### 操作
|
|
26
26
|
1. 展示:变更目录名、包含的文件列表、生成总结
|
|
27
27
|
2. 请用户确认是否执行归档
|
|
28
|
-
3. 确认后:将
|
|
28
|
+
3. 确认后:将 \.sillyspec/changes/<change-name>/ 移动到 \.sillyspec/changes/archive/YYYY-MM-DD-<change-name>/
|
|
29
29
|
4. 确保所有 checkbox 都已勾选
|
|
30
30
|
|
|
31
|
+
### 归档执行
|
|
32
|
+
确认归档后,执行以下命令自动完成目录移动:
|
|
33
|
+
\ \ sillyspec run archive --done --confirm --output "确认归档"
|
|
34
|
+
- \`--confirm\` 标志会自动执行目录移动(原子操作)
|
|
35
|
+
- 不带 \`--confirm\` 则只提示需要确认
|
|
36
|
+
|
|
31
37
|
### 输出
|
|
32
38
|
归档确认`,
|
|
33
39
|
outputHint: '归档确认',
|
|
@@ -39,7 +45,7 @@ export const definition = {
|
|
|
39
45
|
|
|
40
46
|
### 操作
|
|
41
47
|
1. 如果 \`.sillyspec/ROADMAP.md\` 存在,标记对应 Phase 为已完成
|
|
42
|
-
2. \`git add .sillyspec/\` —
|
|
48
|
+
2. \`git add .sillyspec/changes/\` — 暂存归档结果(不要 commit,由用户通过统一提交工具处理)
|
|
43
49
|
3. 更新 progress.json:
|
|
44
50
|
- 清除当前变更信息(归档后不再活跃)
|
|
45
51
|
- 如果是主变更(有 MASTER.md),标记所有阶段为 ✅,然后清除
|
package/src/stages/brainstorm.js
CHANGED
|
@@ -245,7 +245,7 @@ design.md 文件路径 + 自审结果
|
|
|
245
245
|
- **proposal.md**:动机、变更范围、不在范围内、成功标准
|
|
246
246
|
- **requirements.md**:功能需求、用户场景(Given/When/Then 格式)、非功能需求
|
|
247
247
|
- **tasks.md**:任务列表(只列名称和对应文件路径,细节在 plan 阶段展开)
|
|
248
|
-
- \`git add .sillyspec/\` —
|
|
248
|
+
- \`git add .sillyspec/\` — 暂存规范文件(不要 commit)
|
|
249
249
|
|
|
250
250
|
### 输出
|
|
251
251
|
所有规范文件路径
|
package/src/stages/execute.js
CHANGED
|
@@ -69,6 +69,73 @@ Wave 分组 + 模型分配 + 确认模式 + 知识库匹配结果
|
|
|
69
69
|
}
|
|
70
70
|
]
|
|
71
71
|
|
|
72
|
+
// 全局验收步骤定义
|
|
73
|
+
const acceptanceSteps = [
|
|
74
|
+
{
|
|
75
|
+
name: '对照设计检查',
|
|
76
|
+
mode: 'acceptance',
|
|
77
|
+
prompt: `对照 design.md 检查所有实现是否与设计一致。
|
|
78
|
+
|
|
79
|
+
### 执行方式
|
|
80
|
+
本步骤由当前 agent 汇总执行,不需要为每个检查项启动独立子代理。
|
|
81
|
+
如需深入验证某个模块,可启动单个 QA 子代理统一处理。
|
|
82
|
+
|
|
83
|
+
### 操作
|
|
84
|
+
1. 读取 design.md(技术方案)
|
|
85
|
+
2. 逐一对照 design.md 中的设计要点与实际代码实现
|
|
86
|
+
3. 检查接口签名、数据结构、模块划分是否一致
|
|
87
|
+
4. 记录偏差项(偏差 ≠ 错误,可能是合理的实现调整)
|
|
88
|
+
|
|
89
|
+
### 输出
|
|
90
|
+
检查清单:每项设计要点的实现状态 ✅/⚠️/❌ + 偏差说明`,
|
|
91
|
+
outputHint: '设计对照检查清单',
|
|
92
|
+
optional: false
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
name: '运行测试',
|
|
96
|
+
mode: 'acceptance',
|
|
97
|
+
prompt: `运行所有测试,验证代码质量。
|
|
98
|
+
|
|
99
|
+
### 执行方式
|
|
100
|
+
本步骤由当前 agent 执行,不需要启动独立子代理。
|
|
101
|
+
|
|
102
|
+
### 操作
|
|
103
|
+
1. 读取 local.yaml 获取构建和测试命令
|
|
104
|
+
2. 运行测试套件(单元测试、集成测试)
|
|
105
|
+
3. 运行 lint 检查
|
|
106
|
+
4. 如果有测试失败 → 分析原因,标注是代码问题还是测试本身的问题
|
|
107
|
+
5. 汇总测试结果
|
|
108
|
+
|
|
109
|
+
### 输出
|
|
110
|
+
测试结果摘要:通过/失败/跳过数量 + 失败项分析`,
|
|
111
|
+
outputHint: '测试结果摘要',
|
|
112
|
+
optional: false
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
name: '代码审查',
|
|
116
|
+
mode: 'acceptance',
|
|
117
|
+
prompt: `对本次变更进行代码审查。
|
|
118
|
+
|
|
119
|
+
### 执行方式
|
|
120
|
+
本步骤由当前 agent 或一个 QA agent 汇总执行,不需要为每个文件启动独立子代理。
|
|
121
|
+
|
|
122
|
+
### 操作
|
|
123
|
+
1. 检查 git diff 查看所有变更
|
|
124
|
+
2. 审查要点:
|
|
125
|
+
- 代码风格是否符合 CONVENTIONS.md
|
|
126
|
+
- 是否有明显的 bug 或安全漏洞
|
|
127
|
+
- 是否有未处理的 TODO/FIXME
|
|
128
|
+
- 错误处理是否完善
|
|
129
|
+
- 是否有冗余代码或可简化的逻辑
|
|
130
|
+
3. 对照 ARCHITECTURE.md 检查架构合规性
|
|
131
|
+
|
|
132
|
+
### 输出
|
|
133
|
+
审查结果:问题列表(严重程度 + 建议修复方式)+ 总体评价`,
|
|
134
|
+
outputHint: '代码审查结果',
|
|
135
|
+
optional: true
|
|
136
|
+
}
|
|
137
|
+
]
|
|
138
|
+
|
|
72
139
|
// 固定后缀步骤定义
|
|
73
140
|
const fixedSuffix = [
|
|
74
141
|
{
|
|
@@ -90,11 +157,10 @@ const fixedSuffix = [
|
|
|
90
157
|
prompt: `所有任务完成后的收尾。
|
|
91
158
|
|
|
92
159
|
### 操作
|
|
93
|
-
1.
|
|
94
|
-
-
|
|
95
|
-
-
|
|
96
|
-
-
|
|
97
|
-
2. 提示 git add 暂存变更
|
|
160
|
+
1. 建议下一步:
|
|
161
|
+
- 运行 \`sillyspec run verify\` 进行验证(验证通过后才能归档)
|
|
162
|
+
- 如果发现问题需要修复,先修复再验证
|
|
163
|
+
- 用户也可以选择继续开发(不验证)
|
|
98
164
|
|
|
99
165
|
### 输出
|
|
100
166
|
用户选择 + 下一步命令
|
|
@@ -171,33 +237,15 @@ function parseWavesFromPlan(planContent) {
|
|
|
171
237
|
* 为 Wave 生成 prompt(强制子代理执行)
|
|
172
238
|
*/
|
|
173
239
|
function buildWavePrompt(wave, waveIndex, changeDir) {
|
|
174
|
-
//
|
|
175
|
-
const
|
|
240
|
+
// 构建任务摘要(不再内联完整蓝图,减少上下文污染)
|
|
241
|
+
const taskSummary = wave.tasks.map((t, ti) => {
|
|
176
242
|
const taskNum = String(t.index || (ti + 1)).padStart(2, '0')
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
if (taskFileExists) {
|
|
181
|
-
try { taskContent = readFileSync(taskFile, 'utf8').trim() } catch { taskContent = '(无法读取任务蓝图文件)' }
|
|
182
|
-
}
|
|
243
|
+
const taskRelPath = changeDir
|
|
244
|
+
? `.sillyspec/changes/${path.basename(changeDir)}/tasks/task-${taskNum}.md`
|
|
245
|
+
: `task-${taskNum}.md`
|
|
183
246
|
const fileInfo = t.file ? ` (${t.file})` : ''
|
|
184
|
-
return
|
|
185
|
-
|
|
186
|
-
${taskContent ? `蓝图内容:\n${taskContent}` : '(无蓝图文件,按任务描述执行)'}
|
|
187
|
-
|
|
188
|
-
操作:
|
|
189
|
-
1. 先读后写 — 读取要修改的文件,理解现有结构
|
|
190
|
-
2. 按 TDD 步骤实现
|
|
191
|
-
3. 运行对应测试确认通过
|
|
192
|
-
4. 报告改动文件和测试结果
|
|
193
|
-
|
|
194
|
-
铁律:
|
|
195
|
-
- 只做蓝图/任务描述里写的事,不增不减
|
|
196
|
-
- 蓝图有问题 → 报告问题,不要自己改
|
|
197
|
-
- 先写测试,再写代码
|
|
198
|
-
- grep 确认方法存在,不要编造
|
|
199
|
-
\`\`\``
|
|
200
|
-
}).join('\n\n')
|
|
247
|
+
return `task-${taskNum}: ${t.name}${fileInfo} → ${taskRelPath}`
|
|
248
|
+
}).join('\n')
|
|
201
249
|
|
|
202
250
|
const taskList = wave.tasks.map((t, ti) => {
|
|
203
251
|
const taskNum = String(t.index || (ti + 1)).padStart(2, '0')
|
|
@@ -218,10 +266,15 @@ ${taskContent ? `蓝图内容:\n${taskContent}` : '(无蓝图文件,按任
|
|
|
218
266
|
3. 勾选 plan.md 中的 checkbox
|
|
219
267
|
4. 记录改动文件和测试结果
|
|
220
268
|
|
|
221
|
-
###
|
|
222
|
-
|
|
269
|
+
### 任务摘要(按需读取完整蓝图)
|
|
270
|
+
为每个任务启动子代理时,**只需告知任务目标和蓝图文件路径,让子代理按需读取**:
|
|
271
|
+
|
|
272
|
+
${taskSummary}
|
|
223
273
|
|
|
224
|
-
|
|
274
|
+
子代理 prompt 要点:
|
|
275
|
+
1. 任务目标(简短描述)
|
|
276
|
+
2. 蓝图文件路径(让子代理自行读取详情)
|
|
277
|
+
3. 编码铁律:先读后写、TDD、不编造方法、只做蓝图里写的事
|
|
225
278
|
|
|
226
279
|
### Wave 开始前
|
|
227
280
|
1. 读取 design.md 的「编码铁律」章节(如果存在),严格遵守
|
|
@@ -252,6 +305,7 @@ ${taskList}
|
|
|
252
305
|
运行 sillyspec run execute --done --input "用户原始反馈" --output "Wave ${waveIndex} 结果摘要"`
|
|
253
306
|
}
|
|
254
307
|
|
|
308
|
+
|
|
255
309
|
/**
|
|
256
310
|
* 动态构建 execute 步骤列表
|
|
257
311
|
* @param {string|null} planFilePath - plan 文件路径,null 则用默认 3 Wave
|
|
@@ -278,10 +332,11 @@ export function buildExecuteSteps(planFilePath = null) {
|
|
|
278
332
|
|
|
279
333
|
const waveSteps = waves.map((wave, i) => ({
|
|
280
334
|
name: `Wave ${i + 1} 执行`,
|
|
335
|
+
mode: 'implementation',
|
|
281
336
|
prompt: buildWavePrompt(wave, i + 1, changeDir),
|
|
282
337
|
outputHint: `Wave ${i + 1} 执行结果`,
|
|
283
338
|
optional: false
|
|
284
339
|
}))
|
|
285
340
|
|
|
286
|
-
return [...fixedPrefix, ...waveSteps, ...fixedSuffix]
|
|
341
|
+
return [...fixedPrefix, ...waveSteps, ...acceptanceSteps, ...fixedSuffix]
|
|
287
342
|
}
|
package/src/stages/index.js
CHANGED
|
@@ -10,18 +10,21 @@ import { definition as archive } from './archive.js'
|
|
|
10
10
|
import { definition as status } from './status.js'
|
|
11
11
|
import { definition as doctor } from './doctor.js'
|
|
12
12
|
|
|
13
|
+
// 标记辅助阶段
|
|
14
|
+
const auxiliaryFlag = { auxiliary: true }
|
|
15
|
+
|
|
13
16
|
export const stageRegistry = {
|
|
14
17
|
brainstorm,
|
|
15
18
|
propose,
|
|
16
19
|
plan,
|
|
17
20
|
execute,
|
|
18
21
|
verify,
|
|
19
|
-
scan,
|
|
20
|
-
quick,
|
|
21
|
-
explore,
|
|
22
|
-
archive,
|
|
23
|
-
status,
|
|
24
|
-
doctor
|
|
22
|
+
scan: { ...scan, ...auxiliaryFlag },
|
|
23
|
+
quick: { ...quick, ...auxiliaryFlag },
|
|
24
|
+
explore: { ...explore, ...auxiliaryFlag },
|
|
25
|
+
archive: { ...archive, ...auxiliaryFlag },
|
|
26
|
+
status: { ...status, ...auxiliaryFlag },
|
|
27
|
+
doctor: { ...doctor, ...auxiliaryFlag }
|
|
25
28
|
}
|
|
26
29
|
|
|
27
30
|
// 辅助命令(在没有 progress.json 时也可执行)
|
package/src/stages/plan.js
CHANGED
package/src/stages/quick.js
CHANGED
|
@@ -17,8 +17,21 @@ export const definition = {
|
|
|
17
17
|
6. 如有 \`--change\`,加载设计文档:\`cat .sillyspec/changes/<变更名>/design.md 2>/dev/null\`(理解设计意图)
|
|
18
18
|
7. 如有需要,查询知识库:\`cat .sillyspec/knowledge/INDEX.md 2>/dev/null\`
|
|
19
19
|
|
|
20
|
+
### 创建任务记录(必须执行)
|
|
21
|
+
理解完任务后,立即创建记录文件:
|
|
22
|
+
1. \`git config user.name\` 获取用户名
|
|
23
|
+
2. 无 \`--change\`:创建 \.sillyspec/quicklog/QUICKLOG-<git用户名>.md\`(已存在则追加),写入:
|
|
24
|
+
\`\`\`
|
|
25
|
+
## YYYY-MM-DD HH:mm:ss — <一句话任务描述>
|
|
26
|
+
状态:进行中
|
|
27
|
+
文件:<预估要改的文件>
|
|
28
|
+
\`\`\`
|
|
29
|
+
3. 有 \`--change\`:在 \`.sillyspec/changes/<变更名>/tasks.md\` 追加未勾选的 task
|
|
30
|
+
|
|
31
|
+
这样 Gate 检测到 \.sillyspec/\` 下有变更,就不会拦截后续的代码修改。
|
|
32
|
+
|
|
20
33
|
### 输出
|
|
21
|
-
任务理解 +
|
|
34
|
+
任务理解 + 上下文摘要 + quicklog 已创建`,
|
|
22
35
|
outputHint: '任务理解',
|
|
23
36
|
optional: false
|
|
24
37
|
},
|
|
@@ -43,14 +56,14 @@ export const definition = {
|
|
|
43
56
|
optional: false
|
|
44
57
|
},
|
|
45
58
|
{
|
|
46
|
-
name: '
|
|
47
|
-
prompt: `Git
|
|
59
|
+
name: '暂存和更新记录',
|
|
60
|
+
prompt: `Git 暂存并更新任务记录。
|
|
48
61
|
|
|
49
62
|
### 操作
|
|
50
|
-
1. \`git add -A\` —
|
|
51
|
-
2.
|
|
52
|
-
-
|
|
53
|
-
-
|
|
63
|
+
1. \`git add -A\` — 暂存改动文件(不要 commit,由用户通过统一提交工具处理)
|
|
64
|
+
2. 更新 Step 1 创建的记录:
|
|
65
|
+
- 无 \`--change\`:更新 QUICKLOG 条目,将「状态:进行中」改为「状态:已完成」,补充实际改动文件和结果摘要
|
|
66
|
+
- 有 \`--change\`:勾选 tasks.md 中对应的 task checkbox
|
|
54
67
|
3. QUICKLOG 轮转:超过 500 行则重命名为 \`QUICKLOG-<USER>-YYYY-MM-DD.md\`
|
|
55
68
|
4. 如果发现项目特有的坑,追加到 \`.sillyspec/knowledge/uncategorized.md\`
|
|
56
69
|
5. 任务比预期复杂 → 建议用完整流程
|
package/src/stages/scan.js
CHANGED
|
@@ -119,6 +119,45 @@ TESTING.md、CONCERNS.md、PROJECT.md 路径`,
|
|
|
119
119
|
outputHint: '三份文档路径',
|
|
120
120
|
optional: false
|
|
121
121
|
},
|
|
122
|
+
{
|
|
123
|
+
name: '生成本地配置',
|
|
124
|
+
prompt: `自动生成 .sillyspec/.runtime/local.yaml 本地配置文件。
|
|
125
|
+
|
|
126
|
+
### 操作
|
|
127
|
+
1. 检查 .sillyspec/.runtime/local.yaml 是否已存在,已存在则跳过(提示"local.yaml 已存在,跳过生成")
|
|
128
|
+
2. 根据项目类型生成默认配置:
|
|
129
|
+
- **Node.js**(有 package.json):build: "npm run build", test: "npm test", lint: "npm run lint", type: nodejs
|
|
130
|
+
- **Maven**(有 pom.xml):build: "mvn compile", test: "mvn test", lint: "mvn checkstyle:check", type: maven
|
|
131
|
+
- **Gradle**(有 build.gradle):build: "./gradlew build", test: "./gradlew test", type: gradle
|
|
132
|
+
- **通用项目**:只写注释模板, type: generic
|
|
133
|
+
3. 确保目录存在:mkdir -p .sillyspec/.runtime
|
|
134
|
+
4. 原子写入(先写 tmp 文件再 rename)
|
|
135
|
+
|
|
136
|
+
### 文件格式
|
|
137
|
+
\`\`\`yaml
|
|
138
|
+
# SillySpec 本地配置(自动生成,可手动修改)
|
|
139
|
+
project:
|
|
140
|
+
type: nodejs # nodejs/maven/gradle/generic
|
|
141
|
+
|
|
142
|
+
commands:
|
|
143
|
+
build: "npm run build"
|
|
144
|
+
test: "npm test"
|
|
145
|
+
lint: "npm run lint"
|
|
146
|
+
|
|
147
|
+
# 测试策略:full=全量测试, module=只测变更模块, skip=跳过测试
|
|
148
|
+
test_strategy: module
|
|
149
|
+
|
|
150
|
+
# 模块测试路径映射(可选)
|
|
151
|
+
# module_paths:
|
|
152
|
+
# user-service: "user/"
|
|
153
|
+
# order-service: "order/"
|
|
154
|
+
\`\`\`
|
|
155
|
+
|
|
156
|
+
### 输出
|
|
157
|
+
local.yaml 生成结果(已存在/已生成)`,
|
|
158
|
+
outputHint: 'local.yaml 生成状态',
|
|
159
|
+
optional: false
|
|
160
|
+
},
|
|
122
161
|
{
|
|
123
162
|
name: '自检和提交',
|
|
124
163
|
prompt: `验证扫描完整性,清理并提交。
|
|
@@ -127,7 +166,7 @@ TESTING.md、CONCERNS.md、PROJECT.md 路径`,
|
|
|
127
166
|
1. 检查 7 份文档是否全部生成
|
|
128
167
|
2. 自检门控:ARCHITECTURE(技术栈+Schema摘要)、CONVENTIONS(隐形规则+代码风格)、STRUCTURE(目录结构)、INTEGRATIONS(外部依赖)、TESTING(测试现状)、CONCERNS(技术债务)、PROJECT(项目概览)
|
|
129
168
|
3. 清理:\`rm -f .sillyspec/docs/<project>/scan/_env-detect.md\`
|
|
130
|
-
4. \`git add
|
|
169
|
+
4. \`git add .sillyspec/\` — 暂存扫描结果(不要 commit,由用户通过统一提交工具处理)
|
|
131
170
|
|
|
132
171
|
### 输出
|
|
133
172
|
扫描完整性报告
|
package/src/stages/verify.js
CHANGED
|
@@ -58,9 +58,38 @@ export const definition = {
|
|
|
58
58
|
},
|
|
59
59
|
{
|
|
60
60
|
name: '对照设计检查',
|
|
61
|
-
prompt:
|
|
62
|
-
|
|
63
|
-
###
|
|
61
|
+
prompt: `先运行自动探针,再对照 design.md 检查实现一致性。**design.md 是唯一 truth source,不符合 design.md 的实现 = Bug。**
|
|
62
|
+
|
|
63
|
+
### 自动探针(必须先执行)
|
|
64
|
+
在检查前,依次运行以下三个探针,将结果作为验证输入:
|
|
65
|
+
|
|
66
|
+
**探针 1:未实现标记扫描**
|
|
67
|
+
在项目源码目录中搜索未实现标记:
|
|
68
|
+
\`\`\`bash
|
|
69
|
+
grep -rn "尚未实现\|TODO\|FIXME\|HACK\|XXX" <源码目录>/ --include="*.java" --include="*.js" --include="*.ts" --include="*.jsx" --include="*.tsx" --include="*.py"
|
|
70
|
+
\`\`\`
|
|
71
|
+
记录每个匹配的文件、行号和内容。
|
|
72
|
+
|
|
73
|
+
**探针 2:设计关键词覆盖探针**
|
|
74
|
+
1. 读取 design.md,从中提取所有能力关键词(如"登录"、"导出"、"批量"、"删除"、"搜索"等动作词)
|
|
75
|
+
2. 对每个关键词,在源码目录中 grep 确认是否有对应的实现代码:
|
|
76
|
+
\`\`\`bash
|
|
77
|
+
grep -rl "<关键词>" <源码目录>/ --include="*.java" --include="*.js" --include="*.ts" --include="*.jsx" --include="*.tsx" --include="*.py"
|
|
78
|
+
\`\`\`
|
|
79
|
+
3. 如果某个关键词在源码中完全没有匹配,标记为 ⚠️ 可能未实现
|
|
80
|
+
|
|
81
|
+
**探针 3:验收标准测试覆盖探针**
|
|
82
|
+
1. 读取变更目录下的 tasks.md,提取所有 checkbox 任务
|
|
83
|
+
2. 对每个 task,检查对应模块目录下是否存在测试文件(*test*、*spec*、*Test*、*Spec*)
|
|
84
|
+
3. 没有测试文件的 task 标记为 ⚠️ 缺少测试
|
|
85
|
+
|
|
86
|
+
### 探针结果处理
|
|
87
|
+
- 将三个探针的结果汇总为「探针报告」
|
|
88
|
+
- 如果探针发现问题(未实现标记、关键词缺失、测试缺失),在最终验证报告中明确标注
|
|
89
|
+
- 探针发现的问题不等同于验证失败,但必须在报告中列出
|
|
90
|
+
|
|
91
|
+
### 设计一致性检查
|
|
92
|
+
基于探针结果,继续检查:
|
|
64
93
|
1. 架构决策是否遵循
|
|
65
94
|
2. 文件变更清单是否一致
|
|
66
95
|
3. 数据模型是否符合
|
|
@@ -68,7 +97,7 @@ export const definition = {
|
|
|
68
97
|
5. **Reverse Sync 检查**:如果发现实现合理但 design.md 未覆盖,先更新 design.md 补充遗漏
|
|
69
98
|
|
|
70
99
|
### 输出
|
|
71
|
-
|
|
100
|
+
探针报告 + 设计一致性检查结果`,
|
|
72
101
|
outputHint: '设计一致性报告',
|
|
73
102
|
optional: false
|
|
74
103
|
},
|
|
@@ -126,8 +155,8 @@ export const definition = {
|
|
|
126
155
|
验证报告 markdown + 下一步命令
|
|
127
156
|
|
|
128
157
|
### 注意
|
|
129
|
-
- PASS →
|
|
130
|
-
- FAIL →
|
|
158
|
+
- PASS → 运行 \`sillyspec run archive\` 归档
|
|
159
|
+
- FAIL → 修复后运行 \`sillyspec run verify\` 重新验证`,
|
|
131
160
|
outputHint: '验证报告',
|
|
132
161
|
optional: false
|
|
133
162
|
}
|