create-principles-disciple 1.76.0 → 1.78.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.
Files changed (217) hide show
  1. package/console/dist/server/config/feature-flags.d.ts +25 -0
  2. package/console/dist/server/config/feature-flags.js +101 -0
  3. package/console/dist/server/index.js +16 -0
  4. package/console/dist/server/models/FeedbackReportConsoleModel.d.ts +49 -0
  5. package/console/dist/server/models/FeedbackReportConsoleModel.js +242 -0
  6. package/console/dist/server/routes/feedback-reports.d.ts +18 -0
  7. package/console/dist/server/routes/feedback-reports.js +165 -0
  8. package/console/dist/ui/App.js +2 -1
  9. package/console/dist/ui/api.d.ts +26 -2
  10. package/console/dist/ui/api.js +18 -1
  11. package/console/dist/ui/components/app-sidebar.js +2 -1
  12. package/console/dist/ui/components/error-boundary.js +9 -2
  13. package/console/dist/ui/i18n/en.json +67 -1
  14. package/console/dist/ui/i18n/zh-CN.json +67 -1
  15. package/console/dist/ui/pages/ReportProblemPage.d.ts +1 -0
  16. package/console/dist/ui/pages/ReportProblemPage.js +186 -0
  17. package/console/dist/ui/pages/ReportProblemValidators.d.ts +51 -0
  18. package/console/dist/ui/pages/ReportProblemValidators.js +114 -0
  19. package/console/dist/web/assets/app.css +18 -0
  20. package/console/dist/web/assets/app.js +1047 -125
  21. package/console/package.json +1 -0
  22. package/core/dist/runtime-v2/__tests__/architecture-regression.test.js +24 -1
  23. package/core/dist/runtime-v2/__tests__/architecture-regression.test.js.map +1 -1
  24. package/core/dist/runtime-v2/__tests__/feedback/create-report.test.d.ts +2 -0
  25. package/core/dist/runtime-v2/__tests__/feedback/create-report.test.d.ts.map +1 -0
  26. package/core/dist/runtime-v2/__tests__/feedback/create-report.test.js +402 -0
  27. package/core/dist/runtime-v2/__tests__/feedback/create-report.test.js.map +1 -0
  28. package/core/dist/runtime-v2/__tests__/feedback/privacy-preview.test.d.ts +2 -0
  29. package/core/dist/runtime-v2/__tests__/feedback/privacy-preview.test.d.ts.map +1 -0
  30. package/core/dist/runtime-v2/__tests__/feedback/privacy-preview.test.js +128 -0
  31. package/core/dist/runtime-v2/__tests__/feedback/privacy-preview.test.js.map +1 -0
  32. package/core/dist/runtime-v2/__tests__/feedback/redact-sensitive.test.d.ts +2 -0
  33. package/core/dist/runtime-v2/__tests__/feedback/redact-sensitive.test.d.ts.map +1 -0
  34. package/core/dist/runtime-v2/__tests__/feedback/redact-sensitive.test.js +231 -0
  35. package/core/dist/runtime-v2/__tests__/feedback/redact-sensitive.test.js.map +1 -0
  36. package/core/dist/runtime-v2/__tests__/feedback/render-github-url.test.d.ts +2 -0
  37. package/core/dist/runtime-v2/__tests__/feedback/render-github-url.test.d.ts.map +1 -0
  38. package/core/dist/runtime-v2/__tests__/feedback/render-github-url.test.js +102 -0
  39. package/core/dist/runtime-v2/__tests__/feedback/render-github-url.test.js.map +1 -0
  40. package/core/dist/runtime-v2/__tests__/feedback/render-markdown.test.d.ts +2 -0
  41. package/core/dist/runtime-v2/__tests__/feedback/render-markdown.test.d.ts.map +1 -0
  42. package/core/dist/runtime-v2/__tests__/feedback/render-markdown.test.js +130 -0
  43. package/core/dist/runtime-v2/__tests__/feedback/render-markdown.test.js.map +1 -0
  44. package/core/dist/runtime-v2/__tests__/workspace-guidance-migration.test.d.ts +2 -0
  45. package/core/dist/runtime-v2/__tests__/workspace-guidance-migration.test.d.ts.map +1 -0
  46. package/core/dist/runtime-v2/__tests__/workspace-guidance-migration.test.js +328 -0
  47. package/core/dist/runtime-v2/__tests__/workspace-guidance-migration.test.js.map +1 -0
  48. package/core/dist/runtime-v2/activation/__tests__/prompt-activation-reader-contract.test.d.ts +2 -0
  49. package/core/dist/runtime-v2/activation/__tests__/prompt-activation-reader-contract.test.d.ts.map +1 -0
  50. package/core/dist/runtime-v2/activation/__tests__/prompt-activation-reader-contract.test.js +343 -0
  51. package/core/dist/runtime-v2/activation/__tests__/prompt-activation-reader-contract.test.js.map +1 -0
  52. package/core/dist/runtime-v2/activation/index.d.ts +2 -0
  53. package/core/dist/runtime-v2/activation/index.d.ts.map +1 -1
  54. package/core/dist/runtime-v2/activation/index.js +1 -0
  55. package/core/dist/runtime-v2/activation/index.js.map +1 -1
  56. package/core/dist/runtime-v2/activation/prompt-activation-reader-contract.d.ts +34 -0
  57. package/core/dist/runtime-v2/activation/prompt-activation-reader-contract.d.ts.map +1 -0
  58. package/core/dist/runtime-v2/activation/prompt-activation-reader-contract.js +109 -0
  59. package/core/dist/runtime-v2/activation/prompt-activation-reader-contract.js.map +1 -0
  60. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js +13 -0
  61. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js.map +1 -1
  62. package/core/dist/runtime-v2/feature-flags/__tests__/plugin-surface-registry.test.d.ts +2 -0
  63. package/core/dist/runtime-v2/feature-flags/__tests__/plugin-surface-registry.test.d.ts.map +1 -0
  64. package/core/dist/runtime-v2/feature-flags/__tests__/plugin-surface-registry.test.js +141 -0
  65. package/core/dist/runtime-v2/feature-flags/__tests__/plugin-surface-registry.test.js.map +1 -0
  66. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.d.ts.map +1 -1
  67. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js +4 -1
  68. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js.map +1 -1
  69. package/core/dist/runtime-v2/feature-flags/index.d.ts +2 -0
  70. package/core/dist/runtime-v2/feature-flags/index.d.ts.map +1 -1
  71. package/core/dist/runtime-v2/feature-flags/index.js +1 -0
  72. package/core/dist/runtime-v2/feature-flags/index.js.map +1 -1
  73. package/core/dist/runtime-v2/feature-flags/plugin-surface-registry.d.ts +25 -0
  74. package/core/dist/runtime-v2/feature-flags/plugin-surface-registry.d.ts.map +1 -0
  75. package/core/dist/runtime-v2/feature-flags/plugin-surface-registry.js +233 -0
  76. package/core/dist/runtime-v2/feature-flags/plugin-surface-registry.js.map +1 -0
  77. package/core/dist/runtime-v2/feedback/create-report.d.ts +14 -0
  78. package/core/dist/runtime-v2/feedback/create-report.d.ts.map +1 -0
  79. package/core/dist/runtime-v2/feedback/create-report.js +257 -0
  80. package/core/dist/runtime-v2/feedback/create-report.js.map +1 -0
  81. package/core/dist/runtime-v2/feedback/feedback-types.d.ts +120 -0
  82. package/core/dist/runtime-v2/feedback/feedback-types.d.ts.map +1 -0
  83. package/core/dist/runtime-v2/feedback/feedback-types.js +243 -0
  84. package/core/dist/runtime-v2/feedback/feedback-types.js.map +1 -0
  85. package/core/dist/runtime-v2/feedback/index.d.ts +9 -0
  86. package/core/dist/runtime-v2/feedback/index.d.ts.map +1 -0
  87. package/core/dist/runtime-v2/feedback/index.js +11 -0
  88. package/core/dist/runtime-v2/feedback/index.js.map +1 -0
  89. package/core/dist/runtime-v2/feedback/internal-guards.d.ts +2 -0
  90. package/core/dist/runtime-v2/feedback/internal-guards.d.ts.map +1 -0
  91. package/core/dist/runtime-v2/feedback/internal-guards.js +6 -0
  92. package/core/dist/runtime-v2/feedback/internal-guards.js.map +1 -0
  93. package/core/dist/runtime-v2/feedback/privacy-preview.d.ts +14 -0
  94. package/core/dist/runtime-v2/feedback/privacy-preview.d.ts.map +1 -0
  95. package/core/dist/runtime-v2/feedback/privacy-preview.js +128 -0
  96. package/core/dist/runtime-v2/feedback/privacy-preview.js.map +1 -0
  97. package/core/dist/runtime-v2/feedback/redact-sensitive.d.ts +37 -0
  98. package/core/dist/runtime-v2/feedback/redact-sensitive.d.ts.map +1 -0
  99. package/core/dist/runtime-v2/feedback/redact-sensitive.js +272 -0
  100. package/core/dist/runtime-v2/feedback/redact-sensitive.js.map +1 -0
  101. package/core/dist/runtime-v2/feedback/render-github-url.d.ts +21 -0
  102. package/core/dist/runtime-v2/feedback/render-github-url.d.ts.map +1 -0
  103. package/core/dist/runtime-v2/feedback/render-github-url.js +57 -0
  104. package/core/dist/runtime-v2/feedback/render-github-url.js.map +1 -0
  105. package/core/dist/runtime-v2/feedback/render-markdown.d.ts +12 -0
  106. package/core/dist/runtime-v2/feedback/render-markdown.d.ts.map +1 -0
  107. package/core/dist/runtime-v2/feedback/render-markdown.js +166 -0
  108. package/core/dist/runtime-v2/feedback/render-markdown.js.map +1 -0
  109. package/core/dist/runtime-v2/feedback/safe-stringify.d.ts +6 -0
  110. package/core/dist/runtime-v2/feedback/safe-stringify.d.ts.map +1 -0
  111. package/core/dist/runtime-v2/feedback/safe-stringify.js +115 -0
  112. package/core/dist/runtime-v2/feedback/safe-stringify.js.map +1 -0
  113. package/core/dist/runtime-v2/index.d.ts +8 -1
  114. package/core/dist/runtime-v2/index.d.ts.map +1 -1
  115. package/core/dist/runtime-v2/index.js +12 -1
  116. package/core/dist/runtime-v2/index.js.map +1 -1
  117. package/core/dist/runtime-v2/workspace-guidance-migration.d.ts +12 -0
  118. package/core/dist/runtime-v2/workspace-guidance-migration.d.ts.map +1 -0
  119. package/core/dist/runtime-v2/workspace-guidance-migration.js +193 -0
  120. package/core/dist/runtime-v2/workspace-guidance-migration.js.map +1 -0
  121. package/core/package.json +4 -0
  122. package/package.json +1 -1
  123. package/plugin/dist/commands/context.js +5 -5
  124. package/plugin/dist/commands/strategy.d.ts +0 -1
  125. package/plugin/dist/commands/strategy.js +0 -14
  126. package/plugin/dist/core/runtime-v2-prompt-activation-reader.d.ts +4 -13
  127. package/plugin/dist/core/runtime-v2-prompt-activation-reader.js +36 -74
  128. package/plugin/dist/core/surface-guard.d.ts +27 -0
  129. package/plugin/dist/core/surface-guard.js +82 -0
  130. package/plugin/dist/core/workspace-guidance-migrator.d.ts +12 -0
  131. package/plugin/dist/core/workspace-guidance-migrator.js +141 -0
  132. package/plugin/dist/hooks/prompt.js +20 -143
  133. package/plugin/dist/i18n/commands.js +2 -14
  134. package/plugin/dist/index.d.ts +27 -0
  135. package/plugin/dist/index.js +180 -65
  136. package/plugin/dist/service/correction-observer-service.d.ts +11 -0
  137. package/plugin/dist/service/correction-observer-service.js +172 -0
  138. package/plugin/dist/service/evolution-worker.js +1 -110
  139. package/plugin/dist/types.d.ts +2 -2
  140. package/plugin/dist/types.js +3 -3
  141. package/plugin/templates/langs/en/core/BOOTSTRAP.md +5 -19
  142. package/plugin/templates/langs/en/principles/THINKING_OS.md +1 -1
  143. package/plugin/templates/langs/en/skills/admin/SKILL.md +2 -2
  144. package/plugin/templates/langs/en/skills/bootstrap-tools/SKILL.md +1 -1
  145. package/plugin/templates/langs/en/skills/init-strategy/SKILL.md +1 -1
  146. package/plugin/templates/langs/en/skills/pd-mentor/SKILL.md +8 -23
  147. package/plugin/templates/langs/en/skills/reflection/SKILL.md +2 -2
  148. package/plugin/templates/langs/en/skills/report/SKILL.md +1 -1
  149. package/plugin/templates/langs/zh/core/BOOTSTRAP.md +3 -16
  150. package/plugin/templates/langs/zh/principles/THINKING_OS.md +1 -1
  151. package/plugin/templates/langs/zh/skills/admin/SKILL.md +2 -2
  152. package/plugin/templates/langs/zh/skills/bootstrap-tools/SKILL.md +1 -1
  153. package/plugin/templates/langs/zh/skills/init-strategy/SKILL.md +1 -1
  154. package/plugin/templates/langs/zh/skills/pd-mentor/SKILL.md +7 -22
  155. package/plugin/templates/langs/zh/skills/reflection/SKILL.md +2 -2
  156. package/plugin/templates/langs/zh/skills/report/SKILL.md +1 -1
  157. package/plugin/templates/workspace/.principles/THINKING_OS.md +1 -1
  158. package/templates/langs/en/core/BOOTSTRAP.md +1 -1
  159. package/templates/langs/en/principles/THINKING_OS.md +1 -1
  160. package/templates/langs/en/skills/admin/SKILL.md +2 -2
  161. package/templates/langs/en/skills/pd-grooming/SKILL.md +1 -1
  162. package/templates/langs/en/skills/reflection/SKILL.md +2 -2
  163. package/templates/langs/en/skills/report/SKILL.md +1 -1
  164. package/templates/langs/zh/core/BOOTSTRAP.md +1 -1
  165. package/templates/langs/zh/principles/THINKING_OS.md +1 -1
  166. package/templates/langs/zh/skills/admin/SKILL.md +2 -2
  167. package/templates/langs/zh/skills/pd-grooming/SKILL.md +1 -1
  168. package/templates/langs/zh/skills/reflection/SKILL.md +2 -2
  169. package/templates/langs/zh/skills/report/SKILL.md +1 -1
  170. package/plugin/templates/langs/en/skills/ai-sprint-orchestration/EXAMPLES.md +0 -63
  171. package/plugin/templates/langs/en/skills/ai-sprint-orchestration/REFERENCE.md +0 -136
  172. package/plugin/templates/langs/en/skills/ai-sprint-orchestration/SKILL.md +0 -67
  173. package/plugin/templates/langs/en/skills/ai-sprint-orchestration/references/agent-registry.json +0 -143
  174. package/plugin/templates/langs/en/skills/ai-sprint-orchestration/references/specs/bugfix-complex-template.json +0 -107
  175. package/plugin/templates/langs/en/skills/ai-sprint-orchestration/references/specs/feature-complex-template.json +0 -107
  176. package/plugin/templates/langs/en/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal-verify.json +0 -95
  177. package/plugin/templates/langs/en/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal.json +0 -98
  178. package/plugin/templates/langs/en/skills/ai-sprint-orchestration/references/workflow-v1-acceptance-checklist.md +0 -58
  179. package/plugin/templates/langs/en/skills/ai-sprint-orchestration/references/workflow-v1.4-work-unit-handoff.md +0 -190
  180. package/plugin/templates/langs/en/skills/ai-sprint-orchestration/scripts/lib/archive.mjs +0 -310
  181. package/plugin/templates/langs/en/skills/ai-sprint-orchestration/scripts/lib/contract-enforcement.mjs +0 -683
  182. package/plugin/templates/langs/en/skills/ai-sprint-orchestration/scripts/lib/decision.mjs +0 -604
  183. package/plugin/templates/langs/en/skills/ai-sprint-orchestration/scripts/lib/state-store.mjs +0 -32
  184. package/plugin/templates/langs/en/skills/ai-sprint-orchestration/scripts/lib/task-specs.mjs +0 -707
  185. package/plugin/templates/langs/en/skills/ai-sprint-orchestration/scripts/run.mjs +0 -3455
  186. package/plugin/templates/langs/en/skills/evolve-system/SKILL.md +0 -46
  187. package/plugin/templates/langs/en/skills/manage-okr/SKILL.md +0 -96
  188. package/plugin/templates/langs/en/skills/pd-daily/SKILL.md +0 -199
  189. package/plugin/templates/langs/en/skills/pd-grooming/SKILL.md +0 -46
  190. package/plugin/templates/langs/zh/skills/ai-sprint-orchestration/EXAMPLES.md +0 -63
  191. package/plugin/templates/langs/zh/skills/ai-sprint-orchestration/REFERENCE.md +0 -136
  192. package/plugin/templates/langs/zh/skills/ai-sprint-orchestration/SKILL.md +0 -67
  193. package/plugin/templates/langs/zh/skills/ai-sprint-orchestration/references/agent-registry.json +0 -143
  194. package/plugin/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/bugfix-complex-template.json +0 -107
  195. package/plugin/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/feature-complex-template.json +0 -107
  196. package/plugin/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/nocturnal-trinity-quality-enhancement.json +0 -111
  197. package/plugin/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal-verify.json +0 -95
  198. package/plugin/templates/langs/zh/skills/ai-sprint-orchestration/references/specs/workflow-validation-minimal.json +0 -98
  199. package/plugin/templates/langs/zh/skills/ai-sprint-orchestration/references/workflow-v1-acceptance-checklist.md +0 -58
  200. package/plugin/templates/langs/zh/skills/ai-sprint-orchestration/references/workflow-v1.4-work-unit-handoff.md +0 -190
  201. package/plugin/templates/langs/zh/skills/ai-sprint-orchestration/runtime/.gitignore +0 -2
  202. package/plugin/templates/langs/zh/skills/ai-sprint-orchestration/scripts/lib/archive.mjs +0 -310
  203. package/plugin/templates/langs/zh/skills/ai-sprint-orchestration/scripts/lib/contract-enforcement.mjs +0 -683
  204. package/plugin/templates/langs/zh/skills/ai-sprint-orchestration/scripts/lib/decision.mjs +0 -604
  205. package/plugin/templates/langs/zh/skills/ai-sprint-orchestration/scripts/lib/state-store.mjs +0 -32
  206. package/plugin/templates/langs/zh/skills/ai-sprint-orchestration/scripts/lib/task-specs.mjs +0 -707
  207. package/plugin/templates/langs/zh/skills/ai-sprint-orchestration/scripts/run.mjs +0 -3455
  208. package/plugin/templates/langs/zh/skills/ai-sprint-orchestration/test/archive.test.mjs +0 -230
  209. package/plugin/templates/langs/zh/skills/ai-sprint-orchestration/test/contract-enforcement.test.mjs +0 -672
  210. package/plugin/templates/langs/zh/skills/ai-sprint-orchestration/test/decision.test.mjs +0 -1321
  211. package/plugin/templates/langs/zh/skills/ai-sprint-orchestration/test/run.test.mjs +0 -1435
  212. package/plugin/templates/langs/zh/skills/evolve-system/SKILL.md +0 -46
  213. package/plugin/templates/langs/zh/skills/manage-okr/SKILL.md +0 -109
  214. package/plugin/templates/langs/zh/skills/pd-daily/SKILL.md +0 -283
  215. package/plugin/templates/langs/zh/skills/pd-grooming/SKILL.md +0 -46
  216. package/plugin/templates/workspace/PLAN.md +0 -2
  217. package/templates/workspace/PLAN.md +0 -2
@@ -1,230 +0,0 @@
1
- import test from 'node:test';
2
- import assert from 'node:assert/strict';
3
- import fs from 'fs';
4
- import path from 'path';
5
- import os from 'os';
6
- import { fileURLToPath } from 'url';
7
- import { archiveRunById } from '../scripts/lib/archive.mjs';
8
-
9
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
10
-
11
- function makeMockRunDir() {
12
- const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'archive-test-'));
13
- const runDir = path.join(tmpDir, 'run');
14
-
15
- // Create minimal sprint structure
16
- fs.mkdirSync(path.join(runDir, 'stages', '01-investigate'), { recursive: true });
17
-
18
- const state = {
19
- runId: 'test-run-001',
20
- taskId: 'test-task',
21
- title: 'Test sprint',
22
- status: 'completed',
23
- currentStageIndex: 0,
24
- currentStage: 'investigate',
25
- currentRound: 1,
26
- createdAt: '2026-04-01T00:00:00.000Z',
27
- updatedAt: '2026-04-01T00:10:00.000Z',
28
- };
29
- fs.writeFileSync(path.join(runDir, 'sprint.json'), JSON.stringify(state, null, 2));
30
-
31
- // Scorecard
32
- fs.writeFileSync(path.join(runDir, 'stages', '01-investigate', 'scorecard.json'), JSON.stringify({
33
- stage: 'investigate',
34
- round: 1,
35
- outcome: 'advance',
36
- approvalCount: 2,
37
- blockerCount: 0,
38
- reviewerAVerdict: 'APPROVE',
39
- reviewerBVerdict: 'APPROVE',
40
- }));
41
-
42
- // Timeline
43
- fs.writeFileSync(path.join(runDir, 'timeline.md'), '# Timeline\n\n- 2026-04-01T00:00:00Z Started\n');
44
-
45
- return { tmpDir, runDir, state };
46
- }
47
-
48
- function cleanup(tmpDir) {
49
- fs.rmSync(tmpDir, { recursive: true, force: true });
50
- }
51
-
52
- test('archiveRun creates archive with all expected files', () => {
53
- const { tmpDir, runDir } = makeMockRunDir();
54
- const archiveDest = path.join(tmpDir, 'archive', 'test-run-001');
55
-
56
- try {
57
- // Monkey-patch sprintRoot to use our temp dir
58
- const result = archiveRunWithTmpRoot(runDir, 'test-run-001', tmpDir);
59
-
60
- assert.ok(fs.existsSync(result));
61
- assert.ok(fs.existsSync(path.join(result, 'archive-summary.md')));
62
- assert.ok(fs.existsSync(path.join(result, 'archive-meta.json')));
63
- assert.ok(fs.existsSync(path.join(result, 'sprint.json')));
64
- assert.ok(fs.existsSync(path.join(result, 'timeline.md')));
65
- assert.ok(fs.existsSync(path.join(result, 'stages', '01-investigate', 'scorecard.json')));
66
- assert.ok(fs.existsSync(path.join(result, 'git', 'branch.txt')));
67
-
68
- // Verify meta
69
- const meta = JSON.parse(fs.readFileSync(path.join(result, 'archive-meta.json'), 'utf8'));
70
- assert.equal(meta.status, 'completed');
71
- assert.equal(meta.runId, 'test-run-001');
72
- } finally {
73
- cleanup(tmpDir);
74
- }
75
- });
76
-
77
- test('archiveRun rejects second archive (idempotency)', () => {
78
- const { tmpDir, runDir } = makeMockRunDir();
79
-
80
- try {
81
- archiveRunWithTmpRoot(runDir, 'test-run-001', tmpDir);
82
- // Second call should throw
83
- let threw = false;
84
- try {
85
- archiveRunWithTmpRoot(runDir, 'test-run-001', tmpDir);
86
- } catch (e) {
87
- threw = true;
88
- assert.match(e.message, /Already archived/);
89
- }
90
- assert.ok(threw, 'Expected "Already archived" error on second archive');
91
- } finally {
92
- cleanup(tmpDir);
93
- }
94
- });
95
-
96
- test('archiveRunById throws for non-existent run', () => {
97
- assert.throws(() => archiveRunById('nonexistent-run-99999'), /Run not found/);
98
- });
99
-
100
- test('archive-summary.md contains stage progress table', () => {
101
- const { tmpDir, runDir } = makeMockRunDir();
102
-
103
- try {
104
- const result = archiveRunWithTmpRoot(runDir, 'test-run-001', tmpDir);
105
- const summary = fs.readFileSync(path.join(result, 'archive-summary.md'), 'utf8');
106
-
107
- assert.ok(summary.includes('Stage Progress'));
108
- assert.ok(summary.includes('investigate'));
109
- assert.ok(summary.includes('advance'));
110
- assert.ok(summary.includes('APPROVE'));
111
- assert.ok(summary.includes('Total wall time'));
112
- } finally {
113
- cleanup(tmpDir);
114
- }
115
- });
116
-
117
- test('archive handles empty stages gracefully', () => {
118
- const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'archive-test-'));
119
- const runDir = path.join(tmpDir, 'run');
120
-
121
- fs.mkdirSync(path.join(runDir, 'stages'), { recursive: true });
122
- fs.writeFileSync(path.join(runDir, 'sprint.json'), JSON.stringify({
123
- runId: 'empty-stages',
124
- taskId: 'test',
125
- title: 'Empty stages test',
126
- status: 'halted',
127
- currentStageIndex: 0,
128
- currentStage: 'investigate',
129
- currentRound: 1,
130
- haltReason: { type: 'test', details: 'just testing', blockers: [] },
131
- createdAt: '2026-04-01T00:00:00.000Z',
132
- updatedAt: '2026-04-01T00:05:00.000Z',
133
- }));
134
- fs.writeFileSync(path.join(runDir, 'timeline.md'), '# Timeline\n');
135
-
136
- try {
137
- const result = archiveRunWithTmpRoot(runDir, 'empty-stages', tmpDir);
138
- const summary = fs.readFileSync(path.join(result, 'archive-summary.md'), 'utf8');
139
- assert.ok(summary.includes('No stage scorecards found'));
140
- assert.ok(summary.includes('Halt Reason'));
141
- } finally {
142
- cleanup(tmpDir);
143
- }
144
- });
145
-
146
- /**
147
- * Helper: run archiveRun with a custom archive root (temp dir).
148
- * We directly call the module's archiveRun but override the archiveRoot.
149
- */
150
- function archiveRunWithTmpRoot(runDir, runId, tmpRoot) {
151
- const destDir = path.join(tmpRoot, 'archive', runId);
152
-
153
- // Check idempotency
154
- const metaPath = path.join(destDir, 'archive-meta.json');
155
- if (fs.existsSync(metaPath)) {
156
- const meta = JSON.parse(fs.readFileSync(metaPath, 'utf8'));
157
- if (meta.status === 'completed') {
158
- throw new Error(`Already archived: ${destDir}`);
159
- }
160
- fs.rmSync(destDir, { recursive: true, force: true });
161
- }
162
-
163
- const state = JSON.parse(fs.readFileSync(path.join(runDir, 'sprint.json'), 'utf8'));
164
-
165
- fs.mkdirSync(destDir, { recursive: true });
166
- try {
167
- fs.cpSync(runDir, destDir, { recursive: true });
168
- } catch {
169
- // Fallback
170
- }
171
-
172
- // Simulate git capture (just write a placeholder)
173
- const gitDir = path.join(destDir, 'git');
174
- fs.mkdirSync(gitDir, { recursive: true });
175
- fs.writeFileSync(path.join(gitDir, 'branch.txt'), 'test-branch\n');
176
- fs.writeFileSync(path.join(gitDir, 'log.txt'), 'abc123 test commit\n');
177
- fs.writeFileSync(path.join(gitDir, 'modified-files.txt'), 'src/test.ts\n');
178
- fs.writeFileSync(path.join(gitDir, 'diff.patch'), '');
179
- fs.writeFileSync(path.join(gitDir, 'status.txt'), 'M src/test.ts\n');
180
-
181
- // Generate summary inline (same logic as archive.mjs)
182
- const lines = [
183
- `# Sprint Archive: ${state.title || state.taskId}`,
184
- '',
185
- '## Identity',
186
- `- Run ID: ${state.runId}`,
187
- `- Task: ${state.taskId}`,
188
- `- Status: ${state.status}`,
189
- `- Archived at: ${new Date().toISOString()}`,
190
- '',
191
- '## Timeline',
192
- `- Created: ${state.createdAt}`,
193
- `- Updated: ${state.updatedAt}`,
194
- `- Total wall time: ${((Date.parse(state.updatedAt) - Date.parse(state.createdAt)) / 60000).toFixed(1)} minutes`,
195
- '',
196
- ];
197
-
198
- // Stage progress
199
- const stagesDir = path.join(destDir, 'stages');
200
- const stageEntries = [];
201
- if (fs.existsSync(stagesDir)) {
202
- for (const dir of fs.readdirSync(stagesDir).sort()) {
203
- const scPath = path.join(stagesDir, dir, 'scorecard.json');
204
- if (fs.existsSync(scPath)) {
205
- const sc = JSON.parse(fs.readFileSync(scPath, 'utf8'));
206
- stageEntries.push({ dir, ...sc });
207
- }
208
- }
209
- }
210
-
211
- lines.push('## Stage Progress');
212
- if (stageEntries.length > 0) {
213
- lines.push('| Stage | Outcome | Round | Approvals | Blockers | Reviewer A | Reviewer B |');
214
- lines.push('|-------|---------|-------|-----------|----------|-----------|-----------|');
215
- for (const s of stageEntries) {
216
- lines.push(`| ${s.dir} | ${s.outcome} | ${s.round} | ${s.approvalCount}/2 | ${s.blockerCount ?? 0} | ${s.reviewerAVerdict} | ${s.reviewerBVerdict} |`);
217
- }
218
- } else {
219
- lines.push('No stage scorecards found.');
220
- }
221
-
222
- if (state.haltReason) {
223
- lines.push('', '## Halt Reason', `- Type: ${state.haltReason.type}`, `- Details: ${state.haltReason.details}`);
224
- }
225
-
226
- fs.writeFileSync(path.join(destDir, 'archive-summary.md'), lines.join('\n') + '\n');
227
- fs.writeFileSync(metaPath, JSON.stringify({ runId, archivedAt: new Date().toISOString(), status: 'completed' }));
228
-
229
- return destDir;
230
- }