@zhuan-ai/zhuanspec 2.2.4 → 2.4.8

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 (103) hide show
  1. package/bin/zhuanspec-hook.js +3 -0
  2. package/dist/cli/hooks.d.ts +14 -0
  3. package/dist/cli/hooks.js +465 -0
  4. package/dist/cli/index.js +100 -0
  5. package/dist/commands/artifact-workflow.js +15 -34
  6. package/dist/commands/design.d.ts +42 -0
  7. package/dist/commands/design.js +337 -0
  8. package/dist/commands/progress.d.ts +32 -0
  9. package/dist/commands/progress.js +278 -0
  10. package/dist/commands/review.d.ts +32 -0
  11. package/dist/commands/review.js +472 -0
  12. package/dist/commands/validate.d.ts +14 -0
  13. package/dist/commands/validate.js +161 -10
  14. package/dist/core/archive.d.ts +1 -0
  15. package/dist/core/archive.js +45 -3
  16. package/dist/core/completions/command-registry.js +67 -0
  17. package/dist/core/configurators/slash/amazon-q.js +32 -2
  18. package/dist/core/configurators/slash/antigravity.js +8 -2
  19. package/dist/core/configurators/slash/auggie.js +16 -1
  20. package/dist/core/configurators/slash/base.js +1 -1
  21. package/dist/core/configurators/slash/claude.d.ts +4 -0
  22. package/dist/core/configurators/slash/claude.js +56 -1
  23. package/dist/core/configurators/slash/cline.js +8 -2
  24. package/dist/core/configurators/slash/codebuddy.js +22 -1
  25. package/dist/core/configurators/slash/codex.js +21 -0
  26. package/dist/core/configurators/slash/costrict.js +15 -0
  27. package/dist/core/configurators/slash/crush.js +22 -1
  28. package/dist/core/configurators/slash/cursor.js +22 -1
  29. package/dist/core/configurators/slash/factory.js +16 -1
  30. package/dist/core/configurators/slash/gemini.js +8 -2
  31. package/dist/core/configurators/slash/github-copilot.js +19 -1
  32. package/dist/core/configurators/slash/iflow.js +22 -1
  33. package/dist/core/configurators/slash/kilocode.js +4 -1
  34. package/dist/core/configurators/slash/opencode.js +27 -0
  35. package/dist/core/configurators/slash/qoder.d.ts +4 -0
  36. package/dist/core/configurators/slash/qoder.js +59 -1
  37. package/dist/core/configurators/slash/qwen.js +8 -2
  38. package/dist/core/configurators/slash/roocode.js +8 -2
  39. package/dist/core/configurators/slash/windsurf.js +8 -2
  40. package/dist/core/dashboard/metrics.d.ts +33 -0
  41. package/dist/core/dashboard/metrics.js +114 -0
  42. package/dist/core/hooks/collect-knowledge.d.ts +16 -0
  43. package/dist/core/hooks/collect-knowledge.js +203 -0
  44. package/dist/core/hooks/context-load-hook.d.ts +25 -0
  45. package/dist/core/hooks/context-load-hook.js +159 -0
  46. package/dist/core/hooks/deviation-check.d.ts +27 -0
  47. package/dist/core/hooks/deviation-check.js +403 -0
  48. package/dist/core/hooks/deviation-handler.d.ts +43 -0
  49. package/dist/core/hooks/deviation-handler.js +98 -0
  50. package/dist/core/hooks/init.d.ts +14 -0
  51. package/dist/core/hooks/init.js +244 -0
  52. package/dist/core/hooks/notify-milestone.d.ts +14 -0
  53. package/dist/core/hooks/notify-milestone.js +170 -0
  54. package/dist/core/hooks/post-apply.d.ts +29 -0
  55. package/dist/core/hooks/post-apply.js +173 -0
  56. package/dist/core/hooks/post-archive.d.ts +7 -0
  57. package/dist/core/hooks/post-archive.js +208 -0
  58. package/dist/core/hooks/pre-apply.d.ts +34 -0
  59. package/dist/core/hooks/pre-apply.js +139 -0
  60. package/dist/core/hooks/pre-archive.d.ts +7 -0
  61. package/dist/core/hooks/pre-archive.js +50 -0
  62. package/dist/core/hooks/record-progress.d.ts +49 -0
  63. package/dist/core/hooks/record-progress.js +494 -0
  64. package/dist/core/hooks/review-hooks.d.ts +89 -0
  65. package/dist/core/hooks/review-hooks.js +345 -0
  66. package/dist/core/hooks/review-orchestrator.d.ts +40 -0
  67. package/dist/core/hooks/review-orchestrator.js +146 -0
  68. package/dist/core/hooks/summarize.d.ts +15 -0
  69. package/dist/core/hooks/summarize.js +282 -0
  70. package/dist/core/hooks/user-input-hook.d.ts +25 -0
  71. package/dist/core/hooks/user-input-hook.js +179 -0
  72. package/dist/core/init.d.ts +8 -0
  73. package/dist/core/init.js +251 -23
  74. package/dist/core/parsers/requirement-blocks.js +13 -10
  75. package/dist/core/templates/agents-template.d.ts +1 -1
  76. package/dist/core/templates/agents-template.js +510 -243
  77. package/dist/core/templates/index.d.ts +1 -0
  78. package/dist/core/templates/index.js +1 -0
  79. package/dist/core/templates/skill-templates.js +46 -152
  80. package/dist/core/templates/slash-command-templates.d.ts +1 -1
  81. package/dist/core/templates/slash-command-templates.js +352 -20
  82. package/dist/core/templates/tasks-template.d.ts +7 -0
  83. package/dist/core/templates/tasks-template.js +130 -24
  84. package/dist/core/templates/tdd-tasks-template.d.ts +3 -0
  85. package/dist/core/templates/tdd-tasks-template.js +91 -38
  86. package/dist/core/templates/test-cases-template.d.ts +41 -0
  87. package/dist/core/templates/test-cases-template.js +128 -0
  88. package/dist/core/validation/strict-rules.d.ts +44 -5
  89. package/dist/core/validation/strict-rules.js +302 -8
  90. package/dist/core/validation/validator.js +52 -2
  91. package/dist/core/view.d.ts +1 -0
  92. package/dist/core/view.js +60 -2
  93. package/dist/mcp/index.d.ts +28 -0
  94. package/dist/mcp/index.js +31 -0
  95. package/dist/utils/file-system.d.ts +1 -0
  96. package/dist/utils/file-system.js +11 -0
  97. package/dist/utils/item-discovery.js +24 -2
  98. package/dist/utils/phase-utils.d.ts +36 -0
  99. package/dist/utils/phase-utils.js +117 -0
  100. package/package.json +22 -23
  101. package/schemas/spec-driven/schema.yaml +45 -31
  102. package/schemas/spec-driven/templates/spec.md +142 -5
  103. package/schemas/spec-driven/templates/tasks.md +73 -9
@@ -0,0 +1,345 @@
1
+ /**
2
+ * Review Hooks - Result Checkers for Review Phase
3
+ *
4
+ * Three independent hooks for Review phase (Phase 3):
5
+ * 1. code-review-result: Check code-review-expert skill output
6
+ * 2. unit-test-result: Check generate-mockito-unit-test-skill output
7
+ * 3. spec-consistency-result: Check spec-code-consistency output
8
+ *
9
+ * Each hook:
10
+ * - Reads skill output file
11
+ * - Extracts key metrics (Critical count, coverage, consistency)
12
+ * - Decides if fix loop is needed
13
+ * - Controls loop count (max 3)
14
+ */
15
+ import path from 'path';
16
+ import { FileSystemUtils } from '../../utils/file-system.js';
17
+ import { getBeijingTime } from './record-progress.js';
18
+ // Output file paths for skill results
19
+ const SKILL_OUTPUT_DIR = 'zhuanspec/.skill-outputs';
20
+ const CODE_REVIEW_OUTPUT = 'code-review-result.json';
21
+ const UNIT_TEST_OUTPUT = 'unit-test-result.json';
22
+ const SPEC_CONSISTENCY_OUTPUT = 'spec-consistency-result.json';
23
+ // Loop control
24
+ const MAX_LOOP_COUNT = 3;
25
+ export async function codeReviewResultCheck(changeId, skillOutput) {
26
+ const output = skillOutput || await readSkillOutput(changeId, CODE_REVIEW_OUTPUT);
27
+ if (!output) {
28
+ return {
29
+ pass: false,
30
+ needFix: false,
31
+ loopCount: 0,
32
+ metrics: { error: 'No skill output found' },
33
+ nextAction: 'stop',
34
+ fixPrompt: 'Code review skill output not found. Please run code-review-expert skill first.',
35
+ };
36
+ }
37
+ const loopCount = (output.loopCount || 0) + 1;
38
+ // Check Critical issues
39
+ if (output.criticalCount > 0) {
40
+ if (loopCount > MAX_LOOP_COUNT) {
41
+ // Loop limit reached, stop and report
42
+ return {
43
+ pass: false,
44
+ needFix: true,
45
+ loopCount: loopCount,
46
+ metrics: {
47
+ criticalCount: output.criticalCount,
48
+ importantCount: output.importantCount,
49
+ loopExceeded: true,
50
+ },
51
+ nextAction: 'stop',
52
+ fixPrompt: formatFixPrompt(output.issues.filter(i => i.level === 'critical'), loopCount),
53
+ };
54
+ }
55
+ // Need fix loop
56
+ return {
57
+ pass: false,
58
+ needFix: true,
59
+ loopCount: loopCount,
60
+ metrics: {
61
+ criticalCount: output.criticalCount,
62
+ importantCount: output.importantCount,
63
+ criticalIssues: output.issues.filter(i => i.level === 'critical'),
64
+ },
65
+ nextAction: 'fix',
66
+ fixPrompt: formatFixPrompt(output.issues.filter(i => i.level === 'critical'), loopCount),
67
+ };
68
+ }
69
+ // PASS: No critical issues
70
+ return {
71
+ pass: true,
72
+ needFix: false,
73
+ loopCount: loopCount,
74
+ metrics: {
75
+ criticalCount: 0,
76
+ importantCount: output.importantCount,
77
+ infoCount: output.infoCount,
78
+ sonarStatus: output.sonarStatus,
79
+ },
80
+ nextAction: 'continue',
81
+ };
82
+ }
83
+ export async function unitTestResultCheck(changeId, skillOutput) {
84
+ const output = skillOutput || await readSkillOutput(changeId, UNIT_TEST_OUTPUT);
85
+ if (!output) {
86
+ return {
87
+ pass: false,
88
+ needFix: false,
89
+ loopCount: 0,
90
+ metrics: { error: 'No skill output found' },
91
+ nextAction: 'stop',
92
+ fixPrompt: 'Unit test skill output not found. Please run generate-mockito-unit-test-skill first.',
93
+ };
94
+ }
95
+ const loopCount = (output.loopCount || 0) + 1;
96
+ // Check test pass and coverage
97
+ const testFailed = !output.testPassed || output.passRate < 100;
98
+ const coverageLow = output.coverage < output.coverageThreshold;
99
+ if (testFailed || coverageLow) {
100
+ if (loopCount > MAX_LOOP_COUNT) {
101
+ return {
102
+ pass: false,
103
+ needFix: true,
104
+ loopCount: loopCount,
105
+ metrics: {
106
+ testPassed: output.testPassed,
107
+ passRate: output.passRate,
108
+ coverage: output.coverage,
109
+ coverageThreshold: output.coverageThreshold,
110
+ loopExceeded: true,
111
+ },
112
+ nextAction: 'stop',
113
+ fixPrompt: formatUnitTestFixPrompt(output, loopCount),
114
+ };
115
+ }
116
+ return {
117
+ pass: false,
118
+ needFix: true,
119
+ loopCount: loopCount,
120
+ metrics: {
121
+ testPassed: output.testPassed,
122
+ passRate: output.passRate,
123
+ coverage: output.coverage,
124
+ coverageThreshold: output.coverageThreshold,
125
+ failedTests: output.failedTests,
126
+ },
127
+ nextAction: 'fix',
128
+ fixPrompt: formatUnitTestFixPrompt(output, loopCount),
129
+ };
130
+ }
131
+ // PASS: Tests passed and coverage meets threshold
132
+ return {
133
+ pass: true,
134
+ needFix: false,
135
+ loopCount: loopCount,
136
+ metrics: {
137
+ testPassed: true,
138
+ passRate: output.passRate,
139
+ coverage: output.coverage,
140
+ newTestsGenerated: output.newTestsGenerated,
141
+ },
142
+ nextAction: 'continue',
143
+ };
144
+ }
145
+ export async function specConsistencyResultCheck(changeId, skillOutput) {
146
+ const output = skillOutput || await readSkillOutput(changeId, SPEC_CONSISTENCY_OUTPUT);
147
+ if (!output) {
148
+ return {
149
+ pass: false,
150
+ needFix: false,
151
+ loopCount: 0,
152
+ metrics: { error: 'No skill output found' },
153
+ nextAction: 'stop',
154
+ fixPrompt: 'Spec-consistency skill output not found. Please run spec-code-consistency check first.',
155
+ };
156
+ }
157
+ const loopCount = (output.loopCount || 0) + 1;
158
+ // Check consistency coverage
159
+ const hasUncovered = output.uncoveredScenarios.length > 0;
160
+ if (hasUncovered) {
161
+ if (loopCount > MAX_LOOP_COUNT) {
162
+ return {
163
+ pass: false,
164
+ needFix: true,
165
+ loopCount: loopCount,
166
+ metrics: {
167
+ consistencyRate: output.consistencyRate,
168
+ totalScenarios: output.totalScenarios,
169
+ coveredScenarios: output.coveredScenarios,
170
+ loopExceeded: true,
171
+ },
172
+ nextAction: 'stop',
173
+ fixPrompt: formatConsistencyFixPrompt(output, loopCount),
174
+ };
175
+ }
176
+ return {
177
+ pass: false,
178
+ needFix: true,
179
+ loopCount: loopCount,
180
+ metrics: {
181
+ consistencyRate: output.consistencyRate,
182
+ uncoveredScenarios: output.uncoveredScenarios,
183
+ },
184
+ nextAction: 'fix',
185
+ fixPrompt: formatConsistencyFixPrompt(output, loopCount),
186
+ };
187
+ }
188
+ // PASS: All scenarios covered
189
+ return {
190
+ pass: true,
191
+ needFix: false,
192
+ loopCount: loopCount,
193
+ metrics: {
194
+ consistencyRate: 100,
195
+ totalRequirements: output.totalRequirements,
196
+ totalScenarios: output.totalScenarios,
197
+ coveredScenarios: output.coveredScenarios,
198
+ mapping: output.mapping,
199
+ },
200
+ nextAction: 'continue',
201
+ };
202
+ }
203
+ // ============================================================
204
+ // Helper Functions
205
+ // ============================================================
206
+ async function readSkillOutput(changeId, filename) {
207
+ const cwd = process.cwd();
208
+ const outputPath = path.join(cwd, SKILL_OUTPUT_DIR, changeId, filename);
209
+ try {
210
+ if (await FileSystemUtils.fileExists(outputPath)) {
211
+ const content = await FileSystemUtils.readFile(outputPath);
212
+ return JSON.parse(content);
213
+ }
214
+ }
215
+ catch {
216
+ // File not found or parse error
217
+ }
218
+ return null;
219
+ }
220
+ function formatFixPrompt(issues, loopCount) {
221
+ const issueList = issues.map(i => `- [${i.level.toUpperCase}] ${i.file}${i.line ? `:${i.line}` : ''}: ${i.message}`).join('\n');
222
+ return `
223
+ 🔄 Code Review Fix Loop (${loopCount}/${MAX_LOOP_COUNT})
224
+
225
+ 发现 ${issues.length} 个 Critical 问题需要修复:
226
+
227
+ ${issueList}
228
+
229
+ 请修复以上问题后,重新调用 code-review-expert skill 进行验证。
230
+ `;
231
+ }
232
+ function formatUnitTestFixPrompt(output, loopCount) {
233
+ const failedList = output.failedTests.length > 0
234
+ ? `\n失败的测试:\n${output.failedTests.map(t => `- ${t}`).join('\n')}`
235
+ : '';
236
+ return `
237
+ 🔄 Unit Test Fix Loop (${loopCount}/${MAX_LOOP_COUNT})
238
+
239
+ 测试状态:
240
+ - 通过率:${output.passRate}%
241
+ - 覆盖率:${output.coverage}%(阈值:${output.coverageThreshold}%)
242
+ ${failedList}
243
+
244
+ 请补充单元测试或修复失败的测试,然后重新调用 generate-mockito-unit-test-skill。
245
+ `;
246
+ }
247
+ function formatConsistencyFixPrompt(output, loopCount) {
248
+ const uncoveredList = output.uncoveredScenarios.map(s => `- ${s.requirementId}/${s.scenarioId}: ${s.description}`).join('\n');
249
+ return `
250
+ 🔄 Spec-Code Consistency Fix Loop (${loopCount}/${MAX_LOOP_COUNT})
251
+
252
+ 发现 ${output.uncoveredScenarios.length} 个未覆盖的 Scenario:
253
+
254
+ ${uncoveredList}
255
+
256
+ 请选择修复方向:
257
+ 1. 添加代码实现以覆盖这些 Scenario
258
+ 2. 或更新 Spec 描述以反映当前实现状态
259
+
260
+ 然后重新运行 spec-code-consistency 检查。
261
+ `;
262
+ }
263
+ // ============================================================
264
+ // Write Skill Output (for skill to call)
265
+ // ============================================================
266
+ export async function writeCodeReviewOutput(changeId, output) {
267
+ await writeSkillOutput(changeId, CODE_REVIEW_OUTPUT, output);
268
+ }
269
+ export async function writeUnitTestOutput(changeId, output) {
270
+ await writeSkillOutput(changeId, UNIT_TEST_OUTPUT, output);
271
+ }
272
+ export async function writeSpecConsistencyOutput(changeId, output) {
273
+ await writeSkillOutput(changeId, SPEC_CONSISTENCY_OUTPUT, output);
274
+ }
275
+ // Export generic write function for subagent use
276
+ export { writeSkillOutput };
277
+ async function writeSkillOutput(changeId, filename, data) {
278
+ const cwd = process.cwd();
279
+ const outputDir = path.join(cwd, SKILL_OUTPUT_DIR, changeId);
280
+ await FileSystemUtils.createDirectory(outputDir);
281
+ const outputPath = path.join(outputDir, filename);
282
+ await FileSystemUtils.writeFile(outputPath, JSON.stringify(data, null, 2));
283
+ }
284
+ export async function generateReviewReport(changeId, results) {
285
+ const report = `# Review Report: ${changeId}
286
+
287
+ **执行时间**: ${getBeijingTime()}
288
+ **执行者**: AI
289
+
290
+ ---
291
+
292
+ ## 1. Code Review 结果
293
+
294
+ | 指标 | 结果 |
295
+ |------|------|
296
+ | Critical 问题 | ${results.codeReview.metrics.criticalCount || 0} |
297
+ | Important 问题 | ${results.codeReview.metrics.importantCount || 0} |
298
+ | Info 问题 | ${results.codeReview.metrics.infoCount || 0} |
299
+ | 循环次数 | ${results.codeReview.loopCount} |
300
+ | 状态 | ${results.codeReview.pass ? '✅ PASS' : '❌ FAIL'} |
301
+
302
+ ---
303
+
304
+ ## 2. 单测验证结果
305
+
306
+ | 指标 | 结果 |
307
+ |------|------|
308
+ | 测试通过率 | ${results.unitTest.metrics.passRate || 0}% |
309
+ | 覆盖率 | ${results.unitTest.metrics.coverage || 0}% |
310
+ | 新增单测 | ${(results.unitTest.metrics.newTestsGenerated || []).length} 个 |
311
+ | 循环次数 | ${results.unitTest.loopCount} |
312
+ | 状态 | ${results.unitTest.pass ? '✅ PASS' : '❌ FAIL'} |
313
+
314
+ ---
315
+
316
+ ## 3. Spec-Code 一致性认证
317
+
318
+ | 指标 | 结果 |
319
+ |------|------|
320
+ | Requirements 数量 | ${results.specConsistency.metrics.totalRequirements || 0} |
321
+ | Scenario 数量 | ${results.specConsistency.metrics.totalScenarios || 0} |
322
+ | 一致性覆盖率 | ${results.specConsistency.metrics.consistencyRate || 0}% |
323
+ | 循环次数 | ${results.specConsistency.loopCount} |
324
+ | 状态 | ${results.specConsistency.pass ? '✅ PASS' : '❌ FAIL'} |
325
+
326
+ ---
327
+
328
+ ## 总体结论
329
+
330
+ **状态**: ${results.codeReview.pass && results.unitTest.pass && results.specConsistency.pass ? 'PASS' : 'FAIL'}
331
+ **可归档**: ${results.codeReview.pass && results.unitTest.pass && results.specConsistency.pass ? '是' : '否'}
332
+
333
+ ${results.codeReview.pass && results.unitTest.pass && results.specConsistency.pass
334
+ ? '**下一步**: 进入阶段 4(归档变更)'
335
+ : '**下一步**: 根据以上报告继续修复问题'}
336
+ `;
337
+ // Write report to change directory
338
+ const cwd = process.cwd();
339
+ const changeDir = path.join(cwd, 'zhuanspec', 'changes', changeId);
340
+ const reportPath = path.join(changeDir, 'review-report.md');
341
+ await FileSystemUtils.writeFile(reportPath, report);
342
+ return report;
343
+ }
344
+ export { MAX_LOOP_COUNT, };
345
+ //# sourceMappingURL=review-hooks.js.map
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Review Orchestrator - 三轨并行 Review 调度
3
+ *
4
+ * 使用 Agent 工具启动 3 个 subagent 并行执行:
5
+ * 1. Code Review subagent - 调用 code-review-expert skill
6
+ * 2. Unit Test subagent - 调用 generate-mockito-unit-test skill
7
+ * 3. Spec-Code Consistency subagent - 执行一致性检查
8
+ *
9
+ * 每个 subagent 内部自闭环修复(最多3轮),最后汇总报告
10
+ */
11
+ export interface ReviewOrchestratorOptions {
12
+ changeId: string;
13
+ parallel?: boolean;
14
+ }
15
+ export interface SubagentReport {
16
+ track: 'code-review' | 'unit-test' | 'spec-consistency';
17
+ reportFile: string;
18
+ passed: boolean;
19
+ loopCount: number;
20
+ }
21
+ /**
22
+ * Orchestrate three-track parallel review
23
+ *
24
+ * Note: This function returns prompts for subagents.
25
+ * The actual parallel execution should be done using Agent tool in the main conversation.
26
+ */
27
+ export declare function orchestrateReview(options: ReviewOrchestratorOptions): Promise<{
28
+ codeReviewPrompt: string;
29
+ unitTestPrompt: string;
30
+ specConsistencyPrompt: string;
31
+ }>;
32
+ /**
33
+ * Collect subagent reports and generate final review report
34
+ */
35
+ export declare function collectReports(changeId: string, reports: SubagentReport[]): Promise<string>;
36
+ /**
37
+ * Check if all three tracks passed
38
+ */
39
+ export declare function allTracksPassed(reports: SubagentReport[]): boolean;
40
+ //# sourceMappingURL=review-orchestrator.d.ts.map
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Review Orchestrator - 三轨并行 Review 调度
3
+ *
4
+ * 使用 Agent 工具启动 3 个 subagent 并行执行:
5
+ * 1. Code Review subagent - 调用 code-review-expert skill
6
+ * 2. Unit Test subagent - 调用 generate-mockito-unit-test skill
7
+ * 3. Spec-Code Consistency subagent - 执行一致性检查
8
+ *
9
+ * 每个 subagent 内部自闭环修复(最多3轮),最后汇总报告
10
+ */
11
+ import path from 'path';
12
+ import { FileSystemUtils } from '../../utils/file-system.js';
13
+ import { generateReviewReport } from './review-hooks.js';
14
+ /**
15
+ * Generate subagent prompts with self-contained loop instructions
16
+ */
17
+ function generateCodeReviewPrompt(changeId) {
18
+ return `
19
+ 执行 Code Review,发现 Critical 问题时启动修复循环:
20
+
21
+ ## 任务目标
22
+ 对 changeId=${changeId} 的代码变更进行生产级代码评审
23
+
24
+ ## 自闭环指令
25
+ 1. 执行 code-review-expert skill 进行代码审查
26
+ 2. 如果发现 Critical 问题,立即修复
27
+ 3. 修复后重新检查(最多3轮)
28
+ 4. 输出 code-review-result.json 报告到 zhuanspec/.skill-outputs/${changeId}/
29
+
30
+ ## 输出格式
31
+ {
32
+ "criticalCount": number,
33
+ "importantCount": number,
34
+ "infoCount": number,
35
+ "issues": [...],
36
+ "loopCount": number,
37
+ "finalStatus": "PASS" | "FAIL"
38
+ }
39
+ `;
40
+ }
41
+ function generateUnitTestPrompt(changeId) {
42
+ return `
43
+ 执行单元测试验证,失败时启动修复循环:
44
+
45
+ ## 任务目标
46
+ 为 changeId=${changeId} 的代码变更生成并验证单元测试
47
+
48
+ ## 自闭环指令
49
+ 1. 执行 generate-mockito-unit-test skill 生成单测
50
+ 2. 运行单测,检查通过率和覆盖率
51
+ 3. 如果失败或不达标,立即修复
52
+ 4. 修复后重新测试(最多3轮)
53
+ 5. 输出 unit-test-result.json 报告到 zhuanspec/.skill-outputs/${changeId}/
54
+
55
+ ## 输出格式
56
+ {
57
+ "testPassed": boolean,
58
+ "passRate": number,
59
+ "coverage": number,
60
+ "newTestsGenerated": [...],
61
+ "failedTests": [...],
62
+ "loopCount": number,
63
+ "finalStatus": "PASS" | "FAIL"
64
+ }
65
+ `;
66
+ }
67
+ function generateSpecConsistencyPrompt(changeId) {
68
+ return `
69
+ 执行 Spec-Code 一致性检查,发现未覆盖 Scenario 时启动修复循环:
70
+
71
+ ## 任务目标
72
+ 验证 changeId=${changeId} 的代码实现与 Spec Requirement 一致
73
+
74
+ ## 自闭环指令
75
+ 1. 解析 specs/*.md 中的所有 Requirement 和 Scenario
76
+ 2. 检查代码实现是否覆盖每个 Scenario
77
+ 3. 如果发现未覆盖,立即补充代码或更新 Spec
78
+ 4. 修复后重新检查(最多3轮)
79
+ 5. 输出 spec-consistency-result.json 报告到 zhuanspec/.skill-outputs/${changeId}/
80
+
81
+ ## 输出格式
82
+ {
83
+ "consistencyRate": number,
84
+ "totalRequirements": number,
85
+ "totalScenarios": number,
86
+ "coveredScenarios": number,
87
+ "uncoveredScenarios": [...],
88
+ "loopCount": number,
89
+ "finalStatus": "PASS" | "FAIL"
90
+ }
91
+ `;
92
+ }
93
+ /**
94
+ * Orchestrate three-track parallel review
95
+ *
96
+ * Note: This function returns prompts for subagents.
97
+ * The actual parallel execution should be done using Agent tool in the main conversation.
98
+ */
99
+ export async function orchestrateReview(options) {
100
+ const { changeId } = options;
101
+ // Ensure output directory exists
102
+ const cwd = process.cwd();
103
+ const outputDir = path.join(cwd, 'zhuanspec', '.skill-outputs', changeId);
104
+ await FileSystemUtils.createDirectory(outputDir);
105
+ return {
106
+ codeReviewPrompt: generateCodeReviewPrompt(changeId),
107
+ unitTestPrompt: generateUnitTestPrompt(changeId),
108
+ specConsistencyPrompt: generateSpecConsistencyPrompt(changeId),
109
+ };
110
+ }
111
+ /**
112
+ * Collect subagent reports and generate final review report
113
+ */
114
+ export async function collectReports(changeId, reports) {
115
+ const cwd = process.cwd();
116
+ const changeDir = path.join(cwd, 'zhuanspec', 'changes', changeId);
117
+ // Generate review report
118
+ const reportContent = await generateReviewReport(changeId, {
119
+ codeReview: {
120
+ pass: reports.find(r => r.track === 'code-review')?.passed ?? false,
121
+ needFix: false,
122
+ loopCount: reports.find(r => r.track === 'code-review')?.loopCount ?? 0,
123
+ metrics: {},
124
+ },
125
+ unitTest: {
126
+ pass: reports.find(r => r.track === 'unit-test')?.passed ?? false,
127
+ needFix: false,
128
+ loopCount: reports.find(r => r.track === 'unit-test')?.loopCount ?? 0,
129
+ metrics: {},
130
+ },
131
+ specConsistency: {
132
+ pass: reports.find(r => r.track === 'spec-consistency')?.passed ?? false,
133
+ needFix: false,
134
+ loopCount: reports.find(r => r.track === 'spec-consistency')?.loopCount ?? 0,
135
+ metrics: {},
136
+ },
137
+ });
138
+ return reportContent;
139
+ }
140
+ /**
141
+ * Check if all three tracks passed
142
+ */
143
+ export function allTracksPassed(reports) {
144
+ return reports.every(r => r.passed);
145
+ }
146
+ //# sourceMappingURL=review-orchestrator.js.map
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Stop Hook - Summarize Session Progress
3
+ *
4
+ * This hook runs when Claude Code session stops or pauses:
5
+ * 1. Summarize current wave completion status
6
+ * 2. Update ZHUANSPEC_CURRENT_TASK for next task
7
+ * 3. Check if tasks.md is complete → trigger Review phase
8
+ * 4. Generate events.json entries for key events
9
+ */
10
+ interface SummarizeOptions {
11
+ json?: boolean;
12
+ }
13
+ export declare function summarizeHook(options: SummarizeOptions): Promise<void>;
14
+ export {};
15
+ //# sourceMappingURL=summarize.d.ts.map