gsd-pi 2.22.0 → 2.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -1
- package/dist/cli.js +74 -7
- package/dist/headless.d.ts +25 -0
- package/dist/headless.js +454 -0
- package/dist/help-text.js +47 -0
- package/dist/mcp-server.d.ts +20 -3
- package/dist/mcp-server.js +21 -1
- package/dist/models-resolver.d.ts +32 -0
- package/dist/models-resolver.js +50 -0
- package/dist/resource-loader.js +64 -9
- package/dist/resources/extensions/bg-shell/output-formatter.ts +36 -16
- package/dist/resources/extensions/bg-shell/process-manager.ts +6 -4
- package/dist/resources/extensions/bg-shell/types.ts +33 -1
- package/dist/resources/extensions/browser-tools/capture.ts +18 -16
- package/dist/resources/extensions/browser-tools/index.ts +20 -0
- package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +25 -0
- package/dist/resources/extensions/browser-tools/tools/action-cache.ts +216 -0
- package/dist/resources/extensions/browser-tools/tools/codegen.ts +274 -0
- package/dist/resources/extensions/browser-tools/tools/device.ts +183 -0
- package/dist/resources/extensions/browser-tools/tools/extract.ts +229 -0
- package/dist/resources/extensions/browser-tools/tools/injection-detect.ts +221 -0
- package/dist/resources/extensions/browser-tools/tools/network-mock.ts +244 -0
- package/dist/resources/extensions/browser-tools/tools/pdf.ts +92 -0
- package/dist/resources/extensions/browser-tools/tools/state-persistence.ts +202 -0
- package/dist/resources/extensions/browser-tools/tools/visual-diff.ts +209 -0
- package/dist/resources/extensions/browser-tools/tools/zoom.ts +104 -0
- package/dist/resources/extensions/gsd/auto-dashboard.ts +2 -0
- package/dist/resources/extensions/gsd/auto-dispatch.ts +51 -2
- package/dist/resources/extensions/gsd/auto-prompts.ts +73 -0
- package/dist/resources/extensions/gsd/auto-recovery.ts +51 -2
- package/dist/resources/extensions/gsd/auto-worktree.ts +15 -3
- package/dist/resources/extensions/gsd/auto.ts +560 -52
- package/dist/resources/extensions/gsd/captures.ts +49 -0
- package/dist/resources/extensions/gsd/commands.ts +194 -11
- package/dist/resources/extensions/gsd/complexity.ts +1 -0
- package/dist/resources/extensions/gsd/dashboard-overlay.ts +54 -2
- package/dist/resources/extensions/gsd/diff-context.ts +73 -80
- package/dist/resources/extensions/gsd/doctor.ts +76 -12
- package/dist/resources/extensions/gsd/exit-command.ts +2 -2
- package/dist/resources/extensions/gsd/forensics.ts +95 -52
- package/dist/resources/extensions/gsd/gitignore.ts +1 -0
- package/dist/resources/extensions/gsd/guided-flow.ts +85 -5
- package/dist/resources/extensions/gsd/index.ts +34 -1
- package/dist/resources/extensions/gsd/mcp-server.ts +33 -12
- package/dist/resources/extensions/gsd/parallel-eligibility.ts +233 -0
- package/dist/resources/extensions/gsd/parallel-merge.ts +156 -0
- package/dist/resources/extensions/gsd/parallel-orchestrator.ts +496 -0
- package/dist/resources/extensions/gsd/post-unit-hooks.ts +2 -1
- package/dist/resources/extensions/gsd/preferences.ts +65 -1
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +86 -0
- package/dist/resources/extensions/gsd/prompts/execute-task.md +5 -0
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +104 -1
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -0
- package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/system.md +2 -1
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +70 -0
- package/dist/resources/extensions/gsd/provider-error-pause.ts +29 -2
- package/dist/resources/extensions/gsd/roadmap-slices.ts +41 -1
- package/dist/resources/extensions/gsd/session-forensics.ts +36 -2
- package/dist/resources/extensions/gsd/session-status-io.ts +197 -0
- package/dist/resources/extensions/gsd/state.ts +72 -30
- package/dist/resources/extensions/gsd/templates/milestone-validation.md +62 -0
- package/dist/resources/extensions/gsd/tests/agent-end-provider-error.test.ts +81 -0
- package/dist/resources/extensions/gsd/tests/auto-budget-alerts.test.ts +20 -3
- package/dist/resources/extensions/gsd/tests/auto-lock-creation.test.ts +186 -0
- package/dist/resources/extensions/gsd/tests/auto-preflight.test.ts +1 -0
- package/dist/resources/extensions/gsd/tests/auto-recovery.test.ts +264 -0
- package/dist/resources/extensions/gsd/tests/auto-skip-loop.test.ts +123 -0
- package/dist/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +34 -0
- package/dist/resources/extensions/gsd/tests/complete-milestone.test.ts +8 -1
- package/dist/resources/extensions/gsd/tests/derive-state-db.test.ts +9 -15
- package/dist/resources/extensions/gsd/tests/derive-state-deps.test.ts +9 -0
- package/dist/resources/extensions/gsd/tests/derive-state-draft.test.ts +8 -0
- package/dist/resources/extensions/gsd/tests/derive-state.test.ts +14 -0
- package/dist/resources/extensions/gsd/tests/doctor.test.ts +58 -0
- package/dist/resources/extensions/gsd/tests/in-flight-tool-tracking.test.ts +17 -6
- package/dist/resources/extensions/gsd/tests/integration/headless-command.ts +534 -0
- package/dist/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +8 -0
- package/dist/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +5 -5
- package/dist/resources/extensions/gsd/tests/parallel-orchestration.test.ts +656 -0
- package/dist/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +354 -0
- package/dist/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +1 -0
- package/dist/resources/extensions/gsd/tests/roadmap-slices.test.ts +43 -1
- package/dist/resources/extensions/gsd/tests/triage-dispatch.test.ts +120 -0
- package/dist/resources/extensions/gsd/tests/triage-resolution.test.ts +203 -2
- package/dist/resources/extensions/gsd/tests/validate-milestone.test.ts +316 -0
- package/dist/resources/extensions/gsd/tests/visualizer-overlay.test.ts +8 -3
- package/dist/resources/extensions/gsd/tests/worker-registry.test.ts +148 -0
- package/dist/resources/extensions/gsd/triage-resolution.ts +83 -0
- package/dist/resources/extensions/gsd/types.ts +15 -1
- package/dist/resources/extensions/gsd/visualizer-overlay.ts +8 -1
- package/dist/resources/extensions/gsd/workspace-index.ts +34 -6
- package/dist/resources/extensions/subagent/index.ts +5 -0
- package/dist/resources/extensions/subagent/worker-registry.ts +99 -0
- package/dist/update-check.d.ts +9 -0
- package/dist/update-check.js +97 -0
- package/package.json +6 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +16 -7
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/azure-openai-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/azure-openai-responses.js +12 -4
- package/packages/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/google-vertex.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/google-vertex.js +21 -9
- package/packages/pi-ai/dist/providers/google-vertex.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.js +12 -4
- package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.js +12 -4
- package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
- package/packages/pi-ai/src/providers/anthropic.ts +21 -8
- package/packages/pi-ai/src/providers/azure-openai-responses.ts +16 -4
- package/packages/pi-ai/src/providers/google-vertex.ts +32 -17
- package/packages/pi-ai/src/providers/openai-completions.ts +16 -4
- package/packages/pi-ai/src/providers/openai-responses.ts +16 -4
- package/packages/pi-coding-agent/dist/core/agent-session.js +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash-background.test.d.ts +10 -0
- package/packages/pi-coding-agent/dist/core/tools/bash-background.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/bash-background.test.js +79 -0
- package/packages/pi-coding-agent/dist/core/tools/bash-background.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +18 -0
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.js +77 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/core/tools/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/index.js +1 -1
- package/packages/pi-coding-agent/dist/core/tools/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +1 -1
- package/packages/pi-coding-agent/src/core/settings-manager.ts +2 -2
- package/packages/pi-coding-agent/src/core/tools/bash-background.test.ts +91 -0
- package/packages/pi-coding-agent/src/core/tools/bash.ts +83 -1
- package/packages/pi-coding-agent/src/core/tools/index.ts +1 -0
- package/packages/pi-coding-agent/src/index.ts +1 -0
- package/scripts/postinstall.js +7 -109
- package/src/resources/extensions/bg-shell/output-formatter.ts +36 -16
- package/src/resources/extensions/bg-shell/process-manager.ts +6 -4
- package/src/resources/extensions/bg-shell/types.ts +33 -1
- package/src/resources/extensions/browser-tools/capture.ts +18 -16
- package/src/resources/extensions/browser-tools/index.ts +20 -0
- package/src/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +25 -0
- package/src/resources/extensions/browser-tools/tools/action-cache.ts +216 -0
- package/src/resources/extensions/browser-tools/tools/codegen.ts +274 -0
- package/src/resources/extensions/browser-tools/tools/device.ts +183 -0
- package/src/resources/extensions/browser-tools/tools/extract.ts +229 -0
- package/src/resources/extensions/browser-tools/tools/injection-detect.ts +221 -0
- package/src/resources/extensions/browser-tools/tools/network-mock.ts +244 -0
- package/src/resources/extensions/browser-tools/tools/pdf.ts +92 -0
- package/src/resources/extensions/browser-tools/tools/state-persistence.ts +202 -0
- package/src/resources/extensions/browser-tools/tools/visual-diff.ts +209 -0
- package/src/resources/extensions/browser-tools/tools/zoom.ts +104 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +2 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +51 -2
- package/src/resources/extensions/gsd/auto-prompts.ts +73 -0
- package/src/resources/extensions/gsd/auto-recovery.ts +51 -2
- package/src/resources/extensions/gsd/auto-worktree.ts +15 -3
- package/src/resources/extensions/gsd/auto.ts +560 -52
- package/src/resources/extensions/gsd/captures.ts +49 -0
- package/src/resources/extensions/gsd/commands.ts +194 -11
- package/src/resources/extensions/gsd/complexity.ts +1 -0
- package/src/resources/extensions/gsd/dashboard-overlay.ts +54 -2
- package/src/resources/extensions/gsd/diff-context.ts +73 -80
- package/src/resources/extensions/gsd/doctor.ts +76 -12
- package/src/resources/extensions/gsd/exit-command.ts +2 -2
- package/src/resources/extensions/gsd/forensics.ts +95 -52
- package/src/resources/extensions/gsd/gitignore.ts +1 -0
- package/src/resources/extensions/gsd/guided-flow.ts +85 -5
- package/src/resources/extensions/gsd/index.ts +34 -1
- package/src/resources/extensions/gsd/mcp-server.ts +33 -12
- package/src/resources/extensions/gsd/parallel-eligibility.ts +233 -0
- package/src/resources/extensions/gsd/parallel-merge.ts +156 -0
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +496 -0
- package/src/resources/extensions/gsd/post-unit-hooks.ts +2 -1
- package/src/resources/extensions/gsd/preferences.ts +65 -1
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +86 -0
- package/src/resources/extensions/gsd/prompts/execute-task.md +5 -0
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +104 -1
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -0
- package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/system.md +2 -1
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +70 -0
- package/src/resources/extensions/gsd/provider-error-pause.ts +29 -2
- package/src/resources/extensions/gsd/roadmap-slices.ts +41 -1
- package/src/resources/extensions/gsd/session-forensics.ts +36 -2
- package/src/resources/extensions/gsd/session-status-io.ts +197 -0
- package/src/resources/extensions/gsd/state.ts +72 -30
- package/src/resources/extensions/gsd/templates/milestone-validation.md +62 -0
- package/src/resources/extensions/gsd/tests/agent-end-provider-error.test.ts +81 -0
- package/src/resources/extensions/gsd/tests/auto-budget-alerts.test.ts +20 -3
- package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +186 -0
- package/src/resources/extensions/gsd/tests/auto-preflight.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +264 -0
- package/src/resources/extensions/gsd/tests/auto-skip-loop.test.ts +123 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +8 -1
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +9 -15
- package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/derive-state-draft.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/doctor.test.ts +58 -0
- package/src/resources/extensions/gsd/tests/in-flight-tool-tracking.test.ts +17 -6
- package/src/resources/extensions/gsd/tests/integration/headless-command.ts +534 -0
- package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +5 -5
- package/src/resources/extensions/gsd/tests/parallel-orchestration.test.ts +656 -0
- package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +354 -0
- package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +43 -1
- package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +120 -0
- package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +203 -2
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +316 -0
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +8 -3
- package/src/resources/extensions/gsd/tests/worker-registry.test.ts +148 -0
- package/src/resources/extensions/gsd/triage-resolution.ts +83 -0
- package/src/resources/extensions/gsd/types.ts +15 -1
- package/src/resources/extensions/gsd/visualizer-overlay.ts +8 -1
- package/src/resources/extensions/gsd/workspace-index.ts +34 -6
- package/src/resources/extensions/subagent/index.ts +5 -0
- package/src/resources/extensions/subagent/worker-registry.ts +99 -0
|
@@ -248,31 +248,24 @@ async function main(): Promise<void> {
|
|
|
248
248
|
}
|
|
249
249
|
}
|
|
250
250
|
|
|
251
|
-
// ─── Test 5: Requirements counting from DB content
|
|
252
|
-
console.log('\n=== derive-state-db: requirements from
|
|
251
|
+
// ─── Test 5: Requirements counting from disk (DB no longer used for content) ─
|
|
252
|
+
console.log('\n=== derive-state-db: requirements from disk content ===');
|
|
253
253
|
{
|
|
254
254
|
const base = createFixtureBase();
|
|
255
255
|
try {
|
|
256
256
|
// Write minimal milestone dir (needed for milestone discovery)
|
|
257
257
|
mkdirSync(join(base, '.gsd', 'milestones', 'M001'), { recursive: true });
|
|
258
|
-
//
|
|
259
|
-
|
|
260
|
-
openDatabase(':memory:');
|
|
261
|
-
insertArtifactRow('REQUIREMENTS.md', REQUIREMENTS_CONTENT, {
|
|
262
|
-
artifact_type: 'requirements',
|
|
263
|
-
});
|
|
258
|
+
// Write REQUIREMENTS.md to disk (DB content is no longer used by deriveState)
|
|
259
|
+
writeFile(base, 'REQUIREMENTS.md', REQUIREMENTS_CONTENT);
|
|
264
260
|
|
|
265
261
|
invalidateStateCache();
|
|
266
262
|
const state = await deriveState(base);
|
|
267
263
|
|
|
268
|
-
// Requirements should come from
|
|
269
|
-
assertEq(state.requirements?.active, 2, 'req-from-
|
|
270
|
-
assertEq(state.requirements?.validated, 1, 'req-from-
|
|
271
|
-
assertEq(state.requirements?.total, 3, 'req-from-
|
|
272
|
-
|
|
273
|
-
closeDatabase();
|
|
264
|
+
// Requirements should come from disk
|
|
265
|
+
assertEq(state.requirements?.active, 2, 'req-from-disk: requirements.active = 2');
|
|
266
|
+
assertEq(state.requirements?.validated, 1, 'req-from-disk: requirements.validated = 1');
|
|
267
|
+
assertEq(state.requirements?.total, 3, 'req-from-disk: requirements.total = 3');
|
|
274
268
|
} finally {
|
|
275
|
-
closeDatabase();
|
|
276
269
|
cleanup(base);
|
|
277
270
|
}
|
|
278
271
|
}
|
|
@@ -310,6 +303,7 @@ async function main(): Promise<void> {
|
|
|
310
303
|
mkdirSync(join(base, '.gsd', 'milestones', 'M001'), { recursive: true });
|
|
311
304
|
mkdirSync(join(base, '.gsd', 'milestones', 'M002'), { recursive: true });
|
|
312
305
|
writeFile(base, 'milestones/M001/M001-ROADMAP.md', completedRoadmap);
|
|
306
|
+
writeFile(base, 'milestones/M001/M001-VALIDATION.md', `---\nverdict: pass\nremediation_round: 0\n---\n\n# Validation\nPassed.`);
|
|
313
307
|
writeFile(base, 'milestones/M001/M001-SUMMARY.md', summaryContent);
|
|
314
308
|
writeFile(base, 'milestones/M002/M002-ROADMAP.md', activeRoadmap);
|
|
315
309
|
|
|
@@ -26,6 +26,12 @@ function writeMilestoneSummary(base: string, mid: string, content: string): void
|
|
|
26
26
|
writeFileSync(join(dir, `${mid}-SUMMARY.md`), content);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
function writeMilestoneValidation(base: string, mid: string): void {
|
|
30
|
+
const dir = join(base, '.gsd', 'milestones', mid);
|
|
31
|
+
mkdirSync(dir, { recursive: true });
|
|
32
|
+
writeFileSync(join(dir, `${mid}-VALIDATION.md`), `---\nverdict: pass\nremediation_round: 0\n---\n\n# Validation\nPassed.`);
|
|
33
|
+
}
|
|
34
|
+
|
|
29
35
|
/**
|
|
30
36
|
* Creates M00x-CONTEXT.md with a valid YAML frontmatter block.
|
|
31
37
|
* frontmatter is the raw YAML lines between the --- delimiters.
|
|
@@ -120,6 +126,7 @@ async function main(): Promise<void> {
|
|
|
120
126
|
- [x] **S01: Done** \`risk:low\` \`depends:[]\`
|
|
121
127
|
> After this: Done.
|
|
122
128
|
`);
|
|
129
|
+
writeMilestoneValidation(base, 'M001');
|
|
123
130
|
writeMilestoneSummary(base, 'M001', '# M001 Summary\n\nFirst milestone is complete.');
|
|
124
131
|
|
|
125
132
|
// M002: depends on M001, now unblocked
|
|
@@ -252,6 +259,7 @@ async function main(): Promise<void> {
|
|
|
252
259
|
- [x] **S01: Done** \`risk:low\` \`depends:[]\`
|
|
253
260
|
> After this: Done.
|
|
254
261
|
`);
|
|
262
|
+
writeMilestoneValidation(base, 'M002');
|
|
255
263
|
writeMilestoneSummary(base, 'M002', '# M002 Summary\n\nSecond milestone is complete.');
|
|
256
264
|
|
|
257
265
|
const state = await deriveState(base);
|
|
@@ -321,6 +329,7 @@ async function main(): Promise<void> {
|
|
|
321
329
|
- [x] **S01: Done** \`risk:low\` \`depends:[]\`
|
|
322
330
|
> After this: Done.
|
|
323
331
|
`);
|
|
332
|
+
writeMilestoneValidation(base, 'M004-0zjrg0');
|
|
324
333
|
writeMilestoneSummary(base, 'M004-0zjrg0', '# M004-0zjrg0 Summary\n\nComplete.');
|
|
325
334
|
|
|
326
335
|
// M005-b0m2hl: depends on M004-0zjrg0 (lowercase hex suffix)
|
|
@@ -54,6 +54,12 @@ function writeMilestoneSummary(base: string, mid: string, content: string): void
|
|
|
54
54
|
writeFileSync(join(dir, `${mid}-SUMMARY.md`), content);
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
function writeMilestoneValidation(base: string, mid: string): void {
|
|
58
|
+
const dir = join(base, '.gsd', 'milestones', mid);
|
|
59
|
+
mkdirSync(dir, { recursive: true });
|
|
60
|
+
writeFileSync(join(dir, `${mid}-VALIDATION.md`), `---\nverdict: pass\nremediation_round: 0\n---\n\n# Validation\nPassed.`);
|
|
61
|
+
}
|
|
62
|
+
|
|
57
63
|
function cleanup(base: string): void {
|
|
58
64
|
rmSync(base, { recursive: true, force: true });
|
|
59
65
|
}
|
|
@@ -143,6 +149,7 @@ async function main(): Promise<void> {
|
|
|
143
149
|
- [x] **S01: Done** \`risk:low\` \`depends:[]\`
|
|
144
150
|
> After this: Done.
|
|
145
151
|
`);
|
|
152
|
+
writeMilestoneValidation(base, 'M001');
|
|
146
153
|
writeMilestoneSummary(base, 'M001', '# M001 Summary\n\nFirst milestone complete.');
|
|
147
154
|
|
|
148
155
|
// M002: only CONTEXT-DRAFT.md
|
|
@@ -178,6 +185,7 @@ async function main(): Promise<void> {
|
|
|
178
185
|
- [x] **S01: Done** \`risk:low\` \`depends:[]\`
|
|
179
186
|
> After this: Done.
|
|
180
187
|
`);
|
|
188
|
+
writeMilestoneValidation(base, 'M001');
|
|
181
189
|
writeMilestoneSummary(base, 'M001', '# M001 Summary\n\nComplete.');
|
|
182
190
|
|
|
183
191
|
// M002: draft only — should become active with needs-discussion
|
|
@@ -38,6 +38,12 @@ function writeMilestoneSummary(base: string, mid: string, content: string): void
|
|
|
38
38
|
writeFileSync(join(dir, `${mid}-SUMMARY.md`), content);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
function writeMilestoneValidation(base: string, mid: string, verdict: string = 'pass'): void {
|
|
42
|
+
const dir = join(base, '.gsd', 'milestones', mid);
|
|
43
|
+
mkdirSync(dir, { recursive: true });
|
|
44
|
+
writeFileSync(join(dir, `${mid}-VALIDATION.md`), `---\nverdict: ${verdict}\nremediation_round: 0\n---\n\n# Validation\nValidated.`);
|
|
45
|
+
}
|
|
46
|
+
|
|
41
47
|
function writeRequirements(base: string, content: string): void {
|
|
42
48
|
writeFileSync(join(base, '.gsd', 'REQUIREMENTS.md'), content);
|
|
43
49
|
}
|
|
@@ -285,6 +291,7 @@ Continue from step 2.
|
|
|
285
291
|
> After this: Done.
|
|
286
292
|
`);
|
|
287
293
|
|
|
294
|
+
writeMilestoneValidation(base, 'M001');
|
|
288
295
|
writeMilestoneSummary(base, 'M001', `# M001 Summary\n\nMilestone complete.`);
|
|
289
296
|
|
|
290
297
|
const state = await deriveState(base);
|
|
@@ -381,6 +388,7 @@ Continue from step 2.
|
|
|
381
388
|
> After this: Done.
|
|
382
389
|
`);
|
|
383
390
|
|
|
391
|
+
writeMilestoneValidation(base, 'M001');
|
|
384
392
|
writeMilestoneSummary(base, 'M001', `# M001 Summary\n\nFirst milestone complete.`);
|
|
385
393
|
|
|
386
394
|
// M002: active (has incomplete slices)
|
|
@@ -486,6 +494,8 @@ Continue from step 2.
|
|
|
486
494
|
> After this: S02 complete.
|
|
487
495
|
`);
|
|
488
496
|
|
|
497
|
+
writeMilestoneValidation(base, 'M001');
|
|
498
|
+
|
|
489
499
|
const state = await deriveState(base);
|
|
490
500
|
|
|
491
501
|
assertEq(state.phase, 'completing-milestone', 'completing-ms: phase is completing-milestone');
|
|
@@ -521,6 +531,7 @@ Continue from step 2.
|
|
|
521
531
|
> After this: Done.
|
|
522
532
|
`);
|
|
523
533
|
|
|
534
|
+
writeMilestoneValidation(base, 'M001');
|
|
524
535
|
writeMilestoneSummary(base, 'M001', `# M001 Summary\n\nMilestone is complete.`);
|
|
525
536
|
|
|
526
537
|
const state = await deriveState(base);
|
|
@@ -550,6 +561,7 @@ Continue from step 2.
|
|
|
550
561
|
- [x] **S01: Done** \`risk:low\` \`depends:[]\`
|
|
551
562
|
> After this: Done.
|
|
552
563
|
`);
|
|
564
|
+
writeMilestoneValidation(base, 'M001');
|
|
553
565
|
writeMilestoneSummary(base, 'M001', `# M001 Summary\n\nFirst milestone complete.`);
|
|
554
566
|
|
|
555
567
|
// M002: all slices done, no summary → completing-milestone
|
|
@@ -566,6 +578,8 @@ Continue from step 2.
|
|
|
566
578
|
> After this: Done.
|
|
567
579
|
`);
|
|
568
580
|
|
|
581
|
+
writeMilestoneValidation(base, 'M002');
|
|
582
|
+
|
|
569
583
|
// M003: has incomplete slices → pending (M002 is active)
|
|
570
584
|
writeRoadmap(base, 'M003', `# M003: Third Milestone
|
|
571
585
|
|
|
@@ -585,6 +585,64 @@ Discovered an issue.
|
|
|
585
585
|
rmSync(dtBase, { recursive: true, force: true });
|
|
586
586
|
}
|
|
587
587
|
|
|
588
|
+
// ─── unresolvable_dependency: range syntax dep warns ─────────────────
|
|
589
|
+
console.log("\n=== doctor: unresolvable_dependency warns for leftover range ID ===");
|
|
590
|
+
{
|
|
591
|
+
// Simulate a roadmap where expandDependencies did NOT expand (pre-fix stored artifact)
|
|
592
|
+
// by writing a dep that looks like a range but doesn't match any real slice.
|
|
593
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-doctor-udep-"));
|
|
594
|
+
const mDir2 = join(base, ".gsd", "milestones", "M001");
|
|
595
|
+
const sDir2 = join(mDir2, "slices", "S01");
|
|
596
|
+
const tDir2 = join(sDir2, "tasks");
|
|
597
|
+
mkdirSync(tDir2, { recursive: true });
|
|
598
|
+
writeFileSync(join(mDir2, "M001-ROADMAP.md"), [
|
|
599
|
+
"# M001: Test",
|
|
600
|
+
"",
|
|
601
|
+
"## Slices",
|
|
602
|
+
"- [x] **S01: Done** `risk:low` `depends:[]`",
|
|
603
|
+
" > After this: done",
|
|
604
|
+
"- [ ] **S02: Blocked** `risk:low` `depends:[S99]`",
|
|
605
|
+
" > After this: also done",
|
|
606
|
+
].join("\n") + "\n");
|
|
607
|
+
writeFileSync(join(sDir2, "S01-PLAN.md"), "# S01\n\n**Goal:** g\n**Demo:** d\n\n## Tasks\n- [x] **T01: t** `est:5m`\n");
|
|
608
|
+
writeFileSync(join(tDir2, "T01-SUMMARY.md"), "---\nid: T01\nparent: S01\nmilestone: M001\n---\n# T01\n## What Happened\nDone.\n");
|
|
609
|
+
|
|
610
|
+
const r = await runGSDDoctor(base, { fix: false });
|
|
611
|
+
const udepIssues = r.issues.filter(i => i.code === "unresolvable_dependency");
|
|
612
|
+
assertTrue(udepIssues.length > 0, "unresolvable_dependency fires for unknown dep S99");
|
|
613
|
+
assertEq(udepIssues[0]?.severity, "warning", "severity is warning");
|
|
614
|
+
assertTrue(udepIssues[0]?.message.includes("S99"), "message names the bad dep");
|
|
615
|
+
|
|
616
|
+
rmSync(base, { recursive: true, force: true });
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
// ─── unresolvable_dependency: valid deps do not warn ─────────────────
|
|
620
|
+
console.log("\n=== doctor: no unresolvable_dependency for valid deps ===");
|
|
621
|
+
{
|
|
622
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-doctor-udep-ok-"));
|
|
623
|
+
const mDir2 = join(base, ".gsd", "milestones", "M001");
|
|
624
|
+
const sDir2 = join(mDir2, "slices", "S01");
|
|
625
|
+
const tDir2 = join(sDir2, "tasks");
|
|
626
|
+
mkdirSync(tDir2, { recursive: true });
|
|
627
|
+
writeFileSync(join(mDir2, "M001-ROADMAP.md"), [
|
|
628
|
+
"# M001: Test",
|
|
629
|
+
"",
|
|
630
|
+
"## Slices",
|
|
631
|
+
"- [x] **S01: Done** `risk:low` `depends:[]`",
|
|
632
|
+
" > After this: done",
|
|
633
|
+
"- [ ] **S02: Next** `risk:low` `depends:[S01]`",
|
|
634
|
+
" > After this: next done",
|
|
635
|
+
].join("\n") + "\n");
|
|
636
|
+
writeFileSync(join(sDir2, "S01-PLAN.md"), "# S01\n\n**Goal:** g\n**Demo:** d\n\n## Tasks\n- [x] **T01: t** `est:5m`\n");
|
|
637
|
+
writeFileSync(join(tDir2, "T01-SUMMARY.md"), "---\nid: T01\nparent: S01\nmilestone: M001\n---\n# T01\n## What Happened\nDone.\n");
|
|
638
|
+
|
|
639
|
+
const r = await runGSDDoctor(base, { fix: false });
|
|
640
|
+
const udepIssues = r.issues.filter(i => i.code === "unresolvable_dependency");
|
|
641
|
+
assertEq(udepIssues.length, 0, "no unresolvable_dependency for valid S01 dep");
|
|
642
|
+
|
|
643
|
+
rmSync(base, { recursive: true, force: true });
|
|
644
|
+
}
|
|
645
|
+
|
|
588
646
|
report();
|
|
589
647
|
}
|
|
590
648
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* In-flight tool tracking tests — verifies that markToolStart/markToolEnd
|
|
3
|
-
* correctly manage the in-flight tools
|
|
3
|
+
* correctly manage the in-flight tools map used by the idle watchdog to
|
|
4
4
|
* distinguish "agent waiting on long-running tool" from "agent is idle".
|
|
5
5
|
*
|
|
6
6
|
* Background: The idle watchdog checks every 15s for agent progress. Without
|
|
@@ -8,12 +8,15 @@
|
|
|
8
8
|
* can run 20+ minutes for evaluations, deployments, test suites) are falsely
|
|
9
9
|
* declared idle and interrupted by recovery steering messages.
|
|
10
10
|
*
|
|
11
|
-
* The fix hooks tool_execution_start/end events to track active tool calls
|
|
12
|
-
* When tools are in-flight
|
|
13
|
-
*
|
|
11
|
+
* The fix hooks tool_execution_start/end events to track active tool calls
|
|
12
|
+
* with start timestamps. When tools are in-flight and started recently
|
|
13
|
+
* (< idleTimeoutMs), the watchdog resets lastProgressAt instead of triggering
|
|
14
|
+
* idle recovery. When a tool has been in-flight for longer than idleTimeoutMs,
|
|
15
|
+
* it is treated as stuck (e.g., `command &` keeping stdout open) and recovery
|
|
16
|
+
* proceeds anyway.
|
|
14
17
|
*/
|
|
15
18
|
|
|
16
|
-
import { markToolStart, markToolEnd, isAutoActive } from "../auto.ts";
|
|
19
|
+
import { markToolStart, markToolEnd, isAutoActive, getOldestInFlightToolAgeMs } from "../auto.ts";
|
|
17
20
|
import { createTestContext } from './test-helpers.ts';
|
|
18
21
|
|
|
19
22
|
const { assertEq, assertTrue, report } = createTestContext();
|
|
@@ -49,9 +52,17 @@ const { assertEq, assertTrue, report } = createTestContext();
|
|
|
49
52
|
// ═══ Integration contract: expected exports from auto.ts ═════════════════════
|
|
50
53
|
|
|
51
54
|
{
|
|
52
|
-
console.log("\n=== auto.ts exports markToolStart and
|
|
55
|
+
console.log("\n=== auto.ts exports markToolStart, markToolEnd, and getOldestInFlightToolAgeMs ===");
|
|
53
56
|
assertEq(typeof markToolStart, "function", "markToolStart should be a function");
|
|
54
57
|
assertEq(typeof markToolEnd, "function", "markToolEnd should be a function");
|
|
58
|
+
assertEq(typeof getOldestInFlightToolAgeMs, "function", "getOldestInFlightToolAgeMs should be a function");
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
{
|
|
62
|
+
console.log("\n=== getOldestInFlightToolAgeMs: returns 0 when no tools in-flight ===");
|
|
63
|
+
// When auto-mode is inactive, inFlightTools map is empty → age is 0
|
|
64
|
+
const age = getOldestInFlightToolAgeMs();
|
|
65
|
+
assertEq(age, 0, "should return 0 when no tools are in-flight");
|
|
55
66
|
}
|
|
56
67
|
|
|
57
68
|
{
|