@opengsd/gsd-pi 1.1.1-dev.616a1a1 → 1.1.1-dev.9bb7453
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/dist/cli.js +3 -2
- package/dist/help-text.js +10 -6
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +495 -0
- package/dist/resources/extensions/browser-tools/engine/selection.js +16 -0
- package/dist/resources/extensions/browser-tools/extension-manifest.json +2 -2
- package/dist/resources/extensions/browser-tools/index.js +57 -9
- package/dist/resources/extensions/browser-tools/package.json +5 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +167 -16
- package/dist/resources/extensions/gsd/auto/orchestrator.js +0 -1
- package/dist/resources/extensions/gsd/auto/phases.js +4 -3
- package/dist/resources/extensions/gsd/auto-dashboard.js +92 -17
- package/dist/resources/extensions/gsd/auto-dispatch.js +44 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +134 -10
- package/dist/resources/extensions/gsd/auto-prompts.js +68 -22
- package/dist/resources/extensions/gsd/auto-recovery.js +4 -4
- package/dist/resources/extensions/gsd/auto-runtime-state.js +3 -0
- package/dist/resources/extensions/gsd/auto-start.js +94 -15
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +1 -1
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +2 -1
- package/dist/resources/extensions/gsd/auto.js +31 -6
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +83 -4
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +43 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +39 -14
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +16 -10
- package/dist/resources/extensions/gsd/browser-evidence.js +29 -2
- package/dist/resources/extensions/gsd/commands/catalog.js +6 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +6 -2
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +9 -5
- package/dist/resources/extensions/gsd/commands-handlers.js +76 -11
- package/dist/resources/extensions/gsd/commands-maintenance.js +172 -2
- package/dist/resources/extensions/gsd/commands-mcp-status.js +109 -60
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +3 -1
- package/dist/resources/extensions/gsd/commands-verdict.js +1 -1
- package/dist/resources/extensions/gsd/config-overlay.js +2 -1
- package/dist/resources/extensions/gsd/dashboard-overlay.js +21 -7
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +8 -0
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +2 -2
- package/dist/resources/extensions/gsd/error-classifier.js +2 -1
- package/dist/resources/extensions/gsd/escalation.js +4 -4
- package/dist/resources/extensions/gsd/exec-sandbox.js +2 -0
- package/dist/resources/extensions/gsd/forensics.js +74 -2
- package/dist/resources/extensions/gsd/gsd-db.js +42 -6
- package/dist/resources/extensions/gsd/guided-flow.js +30 -69
- package/dist/resources/extensions/gsd/mcp-filter.js +3 -0
- package/dist/resources/extensions/gsd/mcp-project-config.js +76 -84
- package/dist/resources/extensions/gsd/memory-store.js +4 -1
- package/dist/resources/extensions/gsd/migration-auto-check.js +2 -2
- package/dist/resources/extensions/gsd/post-unit-hooks.js +9 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +39 -0
- package/dist/resources/extensions/gsd/prompt-loader.js +7 -0
- package/dist/resources/extensions/gsd/prompts/forensics.md +61 -1
- package/dist/resources/extensions/gsd/prompts/gate-evaluate.md +3 -1
- package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +3 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/reactive-execute.md +3 -1
- package/dist/resources/extensions/gsd/prompts/run-uat.md +48 -24
- package/dist/resources/extensions/gsd/prompts/system.md +3 -1
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +3 -3
- package/dist/resources/extensions/gsd/rule-registry.js +428 -52
- package/dist/resources/extensions/gsd/safety/destructive-guard.js +3 -0
- package/dist/resources/extensions/gsd/skill-activation.js +20 -3
- package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +4 -2
- package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +1 -1
- package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +18 -1
- package/dist/resources/extensions/gsd/state-reconciliation/index.js +6 -0
- package/dist/resources/extensions/gsd/state.js +17 -14
- package/dist/resources/extensions/gsd/templates/plan.md +3 -1
- package/dist/resources/extensions/gsd/tool-presentation-plan.js +120 -0
- package/dist/resources/extensions/gsd/tools/complete-slice.js +15 -1
- package/dist/resources/extensions/gsd/tools/complete-task.js +11 -1
- package/dist/resources/extensions/gsd/tools/exec-tool.js +109 -0
- package/dist/resources/extensions/gsd/tools/plan-slice.js +14 -9
- package/dist/resources/extensions/gsd/tools/reopen-milestone.js +2 -2
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +46 -16
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +403 -3
- package/dist/resources/extensions/gsd/unit-context-manifest.js +8 -3
- package/dist/resources/extensions/gsd/validation-block-guard.js +2 -0
- package/dist/resources/extensions/gsd/verdict-parser.js +59 -15
- package/dist/resources/extensions/gsd/verification-gate.js +72 -1
- package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +3 -1
- package/dist/resources/extensions/gsd/workflow-mcp.js +5 -1
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +24 -0
- package/dist/resources/extensions/mcp-client/manager.js +31 -1
- package/dist/resources/extensions/shared/gsd-browser-cli.js +145 -0
- package/dist/rtk.d.ts +7 -1
- package/dist/rtk.js +27 -11
- package/dist/update-check.d.ts +15 -1
- package/dist/update-check.js +87 -12
- package/dist/update-cmd.d.ts +1 -0
- package/dist/update-cmd.js +53 -2
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +6 -6
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +6 -6
- package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/package.json +5 -3
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/dist/workflow.d.ts +14 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js +16 -0
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/dist/agent-session.d.ts +9 -0
- package/packages/gsd-agent-core/dist/agent-session.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/agent-session.js +32 -0
- package/packages/gsd-agent-core/dist/agent-session.js.map +1 -1
- package/packages/gsd-agent-core/dist/index.d.ts +1 -0
- package/packages/gsd-agent-core/dist/index.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/index.js +1 -0
- package/packages/gsd-agent-core/dist/index.js.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-compaction.d.ts +2 -0
- package/packages/gsd-agent-core/dist/session/agent-session-compaction.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-compaction.js +8 -2
- package/packages/gsd-agent-core/dist/session/agent-session-compaction.js.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts +7 -0
- package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-host.js.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.js +69 -1
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.js.map +1 -1
- package/packages/gsd-agent-core/dist/turn-latency.d.ts +47 -0
- package/packages/gsd-agent-core/dist/turn-latency.d.ts.map +1 -0
- package/packages/gsd-agent-core/dist/turn-latency.js +123 -0
- package/packages/gsd-agent-core/dist/turn-latency.js.map +1 -0
- package/packages/gsd-agent-core/package.json +6 -6
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts +21 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js +213 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts +2 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +10 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +92 -31
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +7 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.js +6 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.js +2 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js +5 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/remote-questions.d.ts.map +1 -1
- package/packages/mcp-server/dist/remote-questions.js +23 -9
- package/packages/mcp-server/dist/remote-questions.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +84 -2
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +3 -3
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +38 -0
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/agent.d.ts +5 -1
- package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent.js +2 -0
- package/packages/pi-agent-core/dist/agent.js.map +1 -1
- package/packages/pi-agent-core/dist/types.d.ts +3 -0
- package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/types.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/api-registry.d.ts +2 -0
- package/packages/pi-ai/dist/api-registry.d.ts.map +1 -1
- package/packages/pi-ai/dist/api-registry.js +23 -0
- package/packages/pi-ai/dist/api-registry.js.map +1 -1
- package/packages/pi-ai/dist/image-models.generated.d.ts +15 -0
- package/packages/pi-ai/dist/image-models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/image-models.generated.js +15 -0
- package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +406 -17
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +484 -116
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/stream.js +6 -6
- package/packages/pi-ai/dist/stream.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +2 -2
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +11 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/dist/terminal.d.ts +1 -0
- package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
- package/packages/pi-tui/dist/terminal.js +8 -4
- package/packages/pi-tui/dist/terminal.js.map +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +579 -0
- package/src/resources/extensions/browser-tools/engine/selection.ts +19 -0
- package/src/resources/extensions/browser-tools/extension-manifest.json +2 -2
- package/src/resources/extensions/browser-tools/index.ts +60 -9
- package/src/resources/extensions/browser-tools/package.json +5 -1
- package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +35 -0
- package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +33 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +196 -16
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +239 -63
- package/src/resources/extensions/gsd/auto/orchestrator.ts +0 -1
- package/src/resources/extensions/gsd/auto/phases.ts +5 -3
- package/src/resources/extensions/gsd/auto-dashboard.ts +98 -18
- package/src/resources/extensions/gsd/auto-dispatch.ts +53 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +166 -9
- package/src/resources/extensions/gsd/auto-prompts.ts +102 -15
- package/src/resources/extensions/gsd/auto-recovery.ts +4 -4
- package/src/resources/extensions/gsd/auto-runtime-state.ts +4 -0
- package/src/resources/extensions/gsd/auto-start.ts +112 -17
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +1 -1
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +2 -1
- package/src/resources/extensions/gsd/auto.ts +47 -5
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +90 -4
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +51 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +60 -19
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +21 -10
- package/src/resources/extensions/gsd/browser-evidence.ts +26 -2
- package/src/resources/extensions/gsd/commands/catalog.ts +6 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +6 -2
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +9 -5
- package/src/resources/extensions/gsd/commands-handlers.ts +76 -11
- package/src/resources/extensions/gsd/commands-maintenance.ts +197 -2
- package/src/resources/extensions/gsd/commands-mcp-status.ts +136 -58
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +4 -1
- package/src/resources/extensions/gsd/commands-verdict.ts +1 -1
- package/src/resources/extensions/gsd/config-overlay.ts +3 -1
- package/src/resources/extensions/gsd/dashboard-overlay.ts +28 -7
- package/src/resources/extensions/gsd/docs/preferences-reference.md +8 -0
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +2 -2
- package/src/resources/extensions/gsd/error-classifier.ts +2 -1
- package/src/resources/extensions/gsd/escalation.ts +4 -4
- package/src/resources/extensions/gsd/exec-sandbox.ts +4 -0
- package/src/resources/extensions/gsd/forensics.ts +99 -5
- package/src/resources/extensions/gsd/gsd-db.ts +46 -8
- package/src/resources/extensions/gsd/guided-flow.ts +91 -83
- package/src/resources/extensions/gsd/mcp-filter.ts +3 -0
- package/src/resources/extensions/gsd/mcp-project-config.ts +105 -88
- package/src/resources/extensions/gsd/memory-store.ts +4 -1
- package/src/resources/extensions/gsd/migration-auto-check.ts +2 -2
- package/src/resources/extensions/gsd/post-unit-hooks.ts +14 -1
- package/src/resources/extensions/gsd/preferences-types.ts +1 -1
- package/src/resources/extensions/gsd/preferences-validation.ts +36 -0
- package/src/resources/extensions/gsd/prompt-loader.ts +8 -0
- package/src/resources/extensions/gsd/prompts/forensics.md +61 -1
- package/src/resources/extensions/gsd/prompts/gate-evaluate.md +3 -1
- package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +3 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/reactive-execute.md +3 -1
- package/src/resources/extensions/gsd/prompts/run-uat.md +48 -24
- package/src/resources/extensions/gsd/prompts/system.md +3 -1
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +3 -3
- package/src/resources/extensions/gsd/rule-registry.ts +558 -58
- package/src/resources/extensions/gsd/rule-types.ts +2 -0
- package/src/resources/extensions/gsd/safety/destructive-guard.ts +3 -0
- package/src/resources/extensions/gsd/skill-activation.ts +20 -2
- package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +4 -2
- package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +1 -1
- package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +20 -0
- package/src/resources/extensions/gsd/state-reconciliation/index.ts +6 -0
- package/src/resources/extensions/gsd/state-reconciliation/types.ts +1 -0
- package/src/resources/extensions/gsd/state.ts +18 -14
- package/src/resources/extensions/gsd/templates/plan.md +3 -1
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +156 -4
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +123 -0
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +143 -2
- package/src/resources/extensions/gsd/tests/auto-start-project-milestone-reconcile.test.ts +24 -2
- package/src/resources/extensions/gsd/tests/browser-evidence.test.ts +142 -0
- package/src/resources/extensions/gsd/tests/commands-dispatcher-validation-block.test.ts +38 -3
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +6 -2
- package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/deep-planning-mode-dispatch.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +50 -13
- package/src/resources/extensions/gsd/tests/discuss-milestone-structured-questions.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +60 -0
- package/src/resources/extensions/gsd/tests/doctor-runtime-checks.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/escalation.test.ts +16 -27
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/exec-tool.test.ts +69 -0
- package/src/resources/extensions/gsd/tests/forensics-issue-routing.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/forensics-prompt-rendering.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/forensics-tool-scope.test.ts +69 -0
- package/src/resources/extensions/gsd/tests/gsd-rebuild.test.ts +199 -0
- package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +40 -1
- package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +86 -0
- package/src/resources/extensions/gsd/tests/guided-flow.test.ts +12 -9
- package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +66 -10
- package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +13 -6
- package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +100 -0
- package/src/resources/extensions/gsd/tests/mcp-status.test.ts +179 -0
- package/src/resources/extensions/gsd/tests/memory-maintenance.test.ts +39 -8
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/new-milestone-discuss-routing.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +54 -7
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +39 -1
- package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +179 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +53 -1
- package/src/resources/extensions/gsd/tests/prompt-loader-extension-dir.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +18 -1
- package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +7 -8
- package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/rule-registry.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +100 -0
- package/src/resources/extensions/gsd/tests/skill-activation.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +6 -2
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +191 -0
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +84 -10
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +12 -2
- package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/tui-header-lifecycle.test.ts +29 -6
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +29 -6
- package/src/resources/extensions/gsd/tests/validate-milestone-prompt-verification-classes.test.ts +6 -3
- package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +133 -0
- package/src/resources/extensions/gsd/tests/validation-block-guard.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/verification-gate.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp-auto-prep.test.ts +17 -2
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +213 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +25 -0
- package/src/resources/extensions/gsd/tool-presentation-plan.ts +167 -0
- package/src/resources/extensions/gsd/tools/complete-slice.ts +14 -1
- package/src/resources/extensions/gsd/tools/complete-task.ts +20 -2
- package/src/resources/extensions/gsd/tools/exec-tool.ts +130 -0
- package/src/resources/extensions/gsd/tools/plan-slice.ts +14 -9
- package/src/resources/extensions/gsd/tools/reopen-milestone.ts +2 -2
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +46 -15
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +489 -3
- package/src/resources/extensions/gsd/types.ts +69 -5
- package/src/resources/extensions/gsd/unit-context-manifest.ts +14 -5
- package/src/resources/extensions/gsd/validation-block-guard.ts +2 -0
- package/src/resources/extensions/gsd/verdict-parser.ts +54 -13
- package/src/resources/extensions/gsd/verification-gate.ts +87 -1
- package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +2 -1
- package/src/resources/extensions/gsd/workflow-mcp.ts +5 -1
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +26 -0
- package/src/resources/extensions/mcp-client/manager.ts +33 -1
- package/src/resources/extensions/mcp-client/tests/manager.test.ts +35 -0
- package/src/resources/extensions/shared/gsd-browser-cli.ts +172 -0
- /package/dist/web/standalone/.next/static/{L9N5SPFi7f-Ne4u2uXzCe → jBtwT9v1u2lUA3UEOy_ZH}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{L9N5SPFi7f-Ne4u2uXzCe → jBtwT9v1u2lUA3UEOy_ZH}/_ssgManifest.js +0 -0
|
@@ -118,6 +118,37 @@ function makeRepoWithMultipleStrandedMilestones(): string {
|
|
|
118
118
|
return base;
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
+
function makeRepoWithActiveMismatchAndStrandedTarget(): string {
|
|
122
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-targeted-stranded-bootstrap-"));
|
|
123
|
+
mkdirSync(join(base, ".gsd", "milestones", "M001"), { recursive: true });
|
|
124
|
+
mkdirSync(join(base, ".gsd", "milestones", "M002"), { recursive: true });
|
|
125
|
+
writeFileSync(
|
|
126
|
+
join(base, ".gsd", "PREFERENCES.md"),
|
|
127
|
+
"---\ngit:\n isolation: \"worktree\"\n---\n",
|
|
128
|
+
);
|
|
129
|
+
runGit(base, ["init"]);
|
|
130
|
+
runGit(base, ["config", "user.email", "test@test.com"]);
|
|
131
|
+
runGit(base, ["config", "user.name", "Test"]);
|
|
132
|
+
writeFileSync(join(base, "README.md"), "# test\n");
|
|
133
|
+
runGit(base, ["add", "-A"]);
|
|
134
|
+
runGit(base, ["commit", "-m", "init"]);
|
|
135
|
+
runGit(base, ["branch", "-M", "main"]);
|
|
136
|
+
|
|
137
|
+
runGit(base, ["checkout", "-b", "milestone/M002"]);
|
|
138
|
+
writeFileSync(join(base, "m002.txt"), "target stranded work\n");
|
|
139
|
+
runGit(base, ["add", "-A"]);
|
|
140
|
+
runGit(base, ["commit", "-m", "feat: M002 in progress"]);
|
|
141
|
+
runGit(base, ["checkout", "main"]);
|
|
142
|
+
runGit(base, ["worktree", "add", ".gsd/worktrees/M002", "milestone/M002"]);
|
|
143
|
+
|
|
144
|
+
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
145
|
+
insertMilestone({ id: "M001", title: "Incorrect active milestone", status: "active" });
|
|
146
|
+
insertMilestone({ id: "M002", title: "Target stranded milestone", status: "active" });
|
|
147
|
+
closeDatabase();
|
|
148
|
+
|
|
149
|
+
return base;
|
|
150
|
+
}
|
|
151
|
+
|
|
121
152
|
function makeRepoWithRecoveredCleanupAndStrandedMismatch(): string {
|
|
122
153
|
const base = mkdtempSync(join(tmpdir(), "gsd-headless-stranded-bootstrap-"));
|
|
123
154
|
mkdirSync(join(base, ".gsd", "milestones", "M001"), { recursive: true });
|
|
@@ -321,6 +352,9 @@ test("headless bootstrap checks stranded work before recovered-complete shortcut
|
|
|
321
352
|
const messages = notifications.map((entry) => entry.message).join("\n");
|
|
322
353
|
assert.equal(ready, false);
|
|
323
354
|
assert.match(messages, /Stranded work for M002 blocks auto-mode/);
|
|
355
|
+
assert.match(messages, /\/gsd auto M002/);
|
|
356
|
+
assert.match(messages, /\/gsd park M002 "reason"/);
|
|
357
|
+
assert.match(messages, /\/gsd rethink/);
|
|
324
358
|
assert.doesNotMatch(messages, /all milestones complete/);
|
|
325
359
|
} finally {
|
|
326
360
|
if (previousHeadless === undefined) {
|
|
@@ -409,6 +443,9 @@ test("bootstrap blocks active stranded recovery when another open milestone also
|
|
|
409
443
|
assert.equal(ready, false);
|
|
410
444
|
assert.deepEqual(adoptCalls, []);
|
|
411
445
|
assert.match(messages, /Stranded work for M002 blocks auto-mode before M001/);
|
|
446
|
+
assert.match(messages, /\/gsd auto M002/);
|
|
447
|
+
assert.match(messages, /\/gsd park M002 "reason"/);
|
|
448
|
+
assert.match(messages, /explicitly discard M002/);
|
|
412
449
|
} finally {
|
|
413
450
|
try {
|
|
414
451
|
closeDatabase();
|
|
@@ -418,6 +455,102 @@ test("bootstrap blocks active stranded recovery when another open milestone also
|
|
|
418
455
|
}
|
|
419
456
|
});
|
|
420
457
|
|
|
458
|
+
test("bootstrap honors explicit solo milestone lock when recovering stranded target worktree", async () => {
|
|
459
|
+
const base = makeRepoWithActiveMismatchAndStrandedTarget();
|
|
460
|
+
const previousCwd = process.cwd();
|
|
461
|
+
const previousLock = process.env.GSD_MILESTONE_LOCK;
|
|
462
|
+
const previousWorker = process.env.GSD_PARALLEL_WORKER;
|
|
463
|
+
const s = new AutoSession();
|
|
464
|
+
const adoptCalls: Array<{ milestoneId: string; mode: string }> = [];
|
|
465
|
+
const notifications: Array<{ message: string; level?: string }> = [];
|
|
466
|
+
|
|
467
|
+
try {
|
|
468
|
+
delete process.env.GSD_PARALLEL_WORKER;
|
|
469
|
+
process.env.GSD_MILESTONE_LOCK = "M002";
|
|
470
|
+
|
|
471
|
+
const ready = await bootstrapAutoSession(
|
|
472
|
+
s,
|
|
473
|
+
makeCtx(notifications) as any,
|
|
474
|
+
{
|
|
475
|
+
getThinkingLevel: () => "medium",
|
|
476
|
+
getActiveTools: () => [],
|
|
477
|
+
events: { emit: () => {} },
|
|
478
|
+
} as any,
|
|
479
|
+
base,
|
|
480
|
+
false,
|
|
481
|
+
false,
|
|
482
|
+
{
|
|
483
|
+
shouldUseWorktreeIsolation: () => false,
|
|
484
|
+
registerSigtermHandler: () => {},
|
|
485
|
+
registerAutoWorkerForSession: () => {},
|
|
486
|
+
lockBase: () => base,
|
|
487
|
+
buildLifecycle: () => ({
|
|
488
|
+
adoptSessionRoot: (sessionBase: string, originalBase?: string) => {
|
|
489
|
+
s.basePath = sessionBase;
|
|
490
|
+
if (originalBase !== undefined) {
|
|
491
|
+
s.originalBasePath = originalBase;
|
|
492
|
+
} else if (!s.originalBasePath) {
|
|
493
|
+
s.originalBasePath = sessionBase;
|
|
494
|
+
}
|
|
495
|
+
},
|
|
496
|
+
enterMilestone: () => ({ ok: true, mode: "worktree", path: base }),
|
|
497
|
+
adoptStrandedMilestone: (
|
|
498
|
+
milestoneId: string,
|
|
499
|
+
sessionBase: string,
|
|
500
|
+
_ctx: unknown,
|
|
501
|
+
opts: { mode: "worktree" | "branch" },
|
|
502
|
+
) => {
|
|
503
|
+
adoptCalls.push({ milestoneId, mode: opts.mode });
|
|
504
|
+
s.basePath = sessionBase;
|
|
505
|
+
s.originalBasePath = sessionBase;
|
|
506
|
+
s.strandedRecoveryIsolationMode = opts.mode;
|
|
507
|
+
return { ok: true, mode: opts.mode, path: sessionBase };
|
|
508
|
+
},
|
|
509
|
+
adoptOrphanWorktree: <T extends { merged: boolean }>(
|
|
510
|
+
_mid: string,
|
|
511
|
+
_base: string,
|
|
512
|
+
run: () => T,
|
|
513
|
+
): T => run(),
|
|
514
|
+
}) as any,
|
|
515
|
+
},
|
|
516
|
+
{
|
|
517
|
+
classification: "none",
|
|
518
|
+
lock: null,
|
|
519
|
+
pausedSession: null,
|
|
520
|
+
state: null,
|
|
521
|
+
recovery: null,
|
|
522
|
+
recoveryPrompt: null,
|
|
523
|
+
recoveryToolCallCount: 0,
|
|
524
|
+
artifactSatisfied: false,
|
|
525
|
+
hasResumableDiskState: false,
|
|
526
|
+
isBootstrapCrash: false,
|
|
527
|
+
},
|
|
528
|
+
);
|
|
529
|
+
|
|
530
|
+
const messages = notifications.map((entry) => entry.message).join("\n");
|
|
531
|
+
assert.equal(ready, true);
|
|
532
|
+
assert.deepEqual(adoptCalls, [{ milestoneId: "M002", mode: "worktree" }]);
|
|
533
|
+
assert.equal(s.currentMilestoneId, "M002");
|
|
534
|
+
assert.match(messages, /Resuming saved milestone work for M002/);
|
|
535
|
+
assert.doesNotMatch(messages, /blocks auto-mode before M001/);
|
|
536
|
+
assert.doesNotMatch(messages, /Stranded work for in-progress milestone M002/);
|
|
537
|
+
assert.ok(
|
|
538
|
+
notifications.some((entry) => entry.level === "info" && entry.message.includes("Resuming saved milestone work for M002")),
|
|
539
|
+
"active recovery should be presented as an info-level resume",
|
|
540
|
+
);
|
|
541
|
+
} finally {
|
|
542
|
+
if (previousLock === undefined) delete process.env.GSD_MILESTONE_LOCK;
|
|
543
|
+
else process.env.GSD_MILESTONE_LOCK = previousLock;
|
|
544
|
+
if (previousWorker === undefined) delete process.env.GSD_PARALLEL_WORKER;
|
|
545
|
+
else process.env.GSD_PARALLEL_WORKER = previousWorker;
|
|
546
|
+
try {
|
|
547
|
+
closeDatabase();
|
|
548
|
+
} catch {}
|
|
549
|
+
process.chdir(previousCwd);
|
|
550
|
+
rmSync(base, { recursive: true, force: true });
|
|
551
|
+
}
|
|
552
|
+
});
|
|
553
|
+
|
|
421
554
|
test("bootstrap adopts stranded active branch even when isolation is none", async () => {
|
|
422
555
|
const base = makeRepoWithStrandedActiveMilestone();
|
|
423
556
|
const previousCwd = process.cwd();
|
|
@@ -496,7 +629,11 @@ test("bootstrap adopts stranded active branch even when isolation is none", asyn
|
|
|
496
629
|
assert.equal(s.strandedRecoveryIsolationMode, "branch");
|
|
497
630
|
assert.match(
|
|
498
631
|
notifications.map((entry) => entry.message).join("\n"),
|
|
499
|
-
/
|
|
632
|
+
/Resuming saved milestone work for M001/,
|
|
633
|
+
);
|
|
634
|
+
assert.ok(
|
|
635
|
+
notifications.every((entry) => entry.level !== "warning" || !entry.message.includes("Stranded work for in-progress milestone M001")),
|
|
636
|
+
"adopting the active milestone should not emit a scary stranded-work warning",
|
|
500
637
|
);
|
|
501
638
|
} finally {
|
|
502
639
|
try {
|
|
@@ -585,7 +722,11 @@ test("bootstrap adopts stranded active branch before deep project setup", async
|
|
|
585
722
|
assert.equal(s.strandedRecoveryIsolationMode, "branch");
|
|
586
723
|
assert.match(
|
|
587
724
|
notifications.map((entry) => entry.message).join("\n"),
|
|
588
|
-
/
|
|
725
|
+
/Resuming saved milestone work for M001/,
|
|
726
|
+
);
|
|
727
|
+
assert.ok(
|
|
728
|
+
notifications.every((entry) => entry.level !== "warning" || !entry.message.includes("Stranded work for in-progress milestone M001")),
|
|
729
|
+
"adopting the active milestone should not emit a scary stranded-work warning",
|
|
589
730
|
);
|
|
590
731
|
} finally {
|
|
591
732
|
try {
|
|
@@ -4,13 +4,35 @@ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
6
6
|
|
|
7
|
-
import { closeDatabase, getAllMilestones, insertMilestone, isDbAvailable, openDatabase } from "../gsd-db.ts";
|
|
8
|
-
import { reconcileProjectMilestonesFromDisk } from "../auto-start.ts";
|
|
7
|
+
import { closeDatabase, getAllMilestones, getMilestone, insertMilestone, isDbAvailable, openDatabase } from "../gsd-db.ts";
|
|
8
|
+
import { reconcileMergedMilestonesFromJournal, reconcileProjectMilestonesFromDisk } from "../auto-start.ts";
|
|
9
|
+
import { emitWorktreeMerged } from "../worktree-telemetry.ts";
|
|
9
10
|
|
|
10
11
|
test.afterEach(() => {
|
|
11
12
|
if (isDbAvailable()) closeDatabase();
|
|
12
13
|
});
|
|
13
14
|
|
|
15
|
+
test("bootstrap reconciliation treats a successful worktree merge as milestone closed", () => {
|
|
16
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-merged-reconcile-"));
|
|
17
|
+
try {
|
|
18
|
+
mkdirSync(join(base, ".gsd"), { recursive: true });
|
|
19
|
+
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
20
|
+
insertMilestone({ id: "M001", title: "Merged Milestone", status: "active" });
|
|
21
|
+
|
|
22
|
+
emitWorktreeMerged(base, "M001", { reason: "milestone-complete", conflict: false });
|
|
23
|
+
|
|
24
|
+
const closed = reconcileMergedMilestonesFromJournal(base);
|
|
25
|
+
const row = getMilestone("M001");
|
|
26
|
+
|
|
27
|
+
assert.equal(closed, 1);
|
|
28
|
+
assert.equal(row?.status, "complete");
|
|
29
|
+
assert.ok(row?.completed_at);
|
|
30
|
+
} finally {
|
|
31
|
+
if (isDbAvailable()) closeDatabase();
|
|
32
|
+
rmSync(base, { recursive: true, force: true });
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
14
36
|
test("#5389: bootstrap reconciles PROJECT.md milestones that are missing from DB", () => {
|
|
15
37
|
const base = mkdtempSync(join(tmpdir(), "gsd-project-reconcile-"));
|
|
16
38
|
try {
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
// Project/App: gsd-pi
|
|
2
|
+
// File Purpose: Unit tests for hasBrowserRequiredText heading-depth section guard.
|
|
3
|
+
|
|
4
|
+
import { describe, test } from 'node:test';
|
|
5
|
+
import assert from 'node:assert/strict';
|
|
6
|
+
|
|
7
|
+
import { hasBrowserRequiredText } from '../browser-evidence.ts';
|
|
8
|
+
|
|
9
|
+
describe('hasBrowserRequiredText', () => {
|
|
10
|
+
test('detects browser requirement in a plain test-cases section', () => {
|
|
11
|
+
const text = [
|
|
12
|
+
'## Test Cases',
|
|
13
|
+
'',
|
|
14
|
+
'1. Open index.html in a browser and navigate to /dashboard.',
|
|
15
|
+
'',
|
|
16
|
+
].join('\n');
|
|
17
|
+
assert.ok(hasBrowserRequiredText(text), 'plain browser step should be detected');
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test('ignores browser mention under a top-level non-requirement heading', () => {
|
|
21
|
+
const text = [
|
|
22
|
+
'## Not Proven',
|
|
23
|
+
'',
|
|
24
|
+
'- Keyboard usability through a real browser.',
|
|
25
|
+
'- Browser console cleanliness.',
|
|
26
|
+
'',
|
|
27
|
+
].join('\n');
|
|
28
|
+
assert.ok(!hasBrowserRequiredText(text), 'browser mention under "Not Proven" should be ignored');
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test('sub-heading inside a non-requirement section does not re-enable detection', () => {
|
|
32
|
+
// BUG (pre-fix): ### sub-heading under ## Not Proven resets inNonRequirementSection
|
|
33
|
+
// to false, causing subsequent lines to be detected as browser requirements.
|
|
34
|
+
const text = [
|
|
35
|
+
'## Not Proven By This UAT',
|
|
36
|
+
'',
|
|
37
|
+
'- No live browser session was used.',
|
|
38
|
+
'',
|
|
39
|
+
'### Visual Checks',
|
|
40
|
+
'',
|
|
41
|
+
'- Browser visual polish deferred to next slice.',
|
|
42
|
+
'- Keyboard interaction in a real browser is not proven here.',
|
|
43
|
+
'',
|
|
44
|
+
].join('\n');
|
|
45
|
+
assert.ok(
|
|
46
|
+
!hasBrowserRequiredText(text),
|
|
47
|
+
'sub-heading under a non-requirement section must not re-enable browser detection',
|
|
48
|
+
);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test('requirement-level heading after non-requirement section re-enables detection', () => {
|
|
52
|
+
const text = [
|
|
53
|
+
'## Not Proven',
|
|
54
|
+
'',
|
|
55
|
+
'- Browser polish deferred.',
|
|
56
|
+
'',
|
|
57
|
+
'## Test Cases',
|
|
58
|
+
'',
|
|
59
|
+
'1. Launch browser and open localhost.',
|
|
60
|
+
'',
|
|
61
|
+
].join('\n');
|
|
62
|
+
assert.ok(
|
|
63
|
+
hasBrowserRequiredText(text),
|
|
64
|
+
'browser step under "Test Cases" (same depth as "Not Proven") must still be detected',
|
|
65
|
+
);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test('deferred sub-heading inside a requirement section scopes exclusion to its own block', () => {
|
|
69
|
+
const text = [
|
|
70
|
+
'## Test Cases',
|
|
71
|
+
'',
|
|
72
|
+
'1. Open browser at localhost.',
|
|
73
|
+
'',
|
|
74
|
+
'### Deferred: keyboard check',
|
|
75
|
+
'',
|
|
76
|
+
'- Keyboard UAT deferred to next slice.',
|
|
77
|
+
'',
|
|
78
|
+
'### Step 2: Verify DOM',
|
|
79
|
+
'',
|
|
80
|
+
'1. Navigate to /dashboard in the browser.',
|
|
81
|
+
'',
|
|
82
|
+
].join('\n');
|
|
83
|
+
assert.ok(
|
|
84
|
+
hasBrowserRequiredText(text),
|
|
85
|
+
'browser step under "Step 2" sub-heading must be detected after a sibling "Deferred" sub-heading',
|
|
86
|
+
);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test('deferred sub-heading at same depth as test cases does not escape to parent', () => {
|
|
90
|
+
const text = [
|
|
91
|
+
'## Test Cases',
|
|
92
|
+
'',
|
|
93
|
+
'### Deferred: responsive layout',
|
|
94
|
+
'',
|
|
95
|
+
'- Responsive layout check is deferred to S02.',
|
|
96
|
+
'',
|
|
97
|
+
].join('\n');
|
|
98
|
+
assert.ok(
|
|
99
|
+
!hasBrowserRequiredText(text),
|
|
100
|
+
'content under a "Deferred" sub-heading should be excluded from detection',
|
|
101
|
+
);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test('detects browser requirement written only in a heading', () => {
|
|
105
|
+
// Regression: the line-by-line scan previously skip-continued past headings,
|
|
106
|
+
// missing browser obligations expressed only in heading text.
|
|
107
|
+
const text = '## Open browser session at localhost\n';
|
|
108
|
+
assert.ok(hasBrowserRequiredText(text), 'browser requirement in heading text must be detected');
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test('heading that opens a non-requirement section is not itself detected as a requirement', () => {
|
|
112
|
+
const text = '## Not Proven\n\n- Some note.\n';
|
|
113
|
+
assert.ok(
|
|
114
|
+
!hasBrowserRequiredText(text),
|
|
115
|
+
'a non-requirement section heading should not trigger browser detection',
|
|
116
|
+
);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
test('returns false for empty text', () => {
|
|
120
|
+
assert.ok(!hasBrowserRequiredText(''), 'empty string returns false');
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
test('notes-for-tester heading with sub-headings stays non-requirement', () => {
|
|
124
|
+
const text = [
|
|
125
|
+
'## Notes for Tester',
|
|
126
|
+
'',
|
|
127
|
+
'### Browser Setup',
|
|
128
|
+
'',
|
|
129
|
+
'- Run this spec without a browser; a DOM harness is sufficient.',
|
|
130
|
+
'- Browser-based visual checks are deferred.',
|
|
131
|
+
'',
|
|
132
|
+
'### Follow-up Items',
|
|
133
|
+
'',
|
|
134
|
+
'- Track browser session evidence in S02.',
|
|
135
|
+
'',
|
|
136
|
+
].join('\n');
|
|
137
|
+
assert.ok(
|
|
138
|
+
!hasBrowserRequiredText(text),
|
|
139
|
+
'sub-headings under "Notes for Tester" should not re-enable browser detection',
|
|
140
|
+
);
|
|
141
|
+
});
|
|
142
|
+
});
|
|
@@ -40,10 +40,12 @@ function makeMockCtx(base: string): {
|
|
|
40
40
|
calls: NotifyCall[];
|
|
41
41
|
widgets: Array<[string, unknown]>;
|
|
42
42
|
statuses: Array<[string, string | undefined]>;
|
|
43
|
+
newSessions: Array<{ workspaceRoot?: string }>;
|
|
43
44
|
} {
|
|
44
45
|
const calls: NotifyCall[] = [];
|
|
45
46
|
const widgets: Array<[string, unknown]> = [];
|
|
46
47
|
const statuses: Array<[string, string | undefined]> = [];
|
|
48
|
+
const newSessions: Array<{ workspaceRoot?: string }> = [];
|
|
47
49
|
return {
|
|
48
50
|
ctx: {
|
|
49
51
|
cwd: base,
|
|
@@ -58,10 +60,15 @@ function makeMockCtx(base: string): {
|
|
|
58
60
|
statuses.push([key, value]);
|
|
59
61
|
},
|
|
60
62
|
},
|
|
63
|
+
newSession: async (options?: { workspaceRoot?: string }) => {
|
|
64
|
+
newSessions.push(options ?? {});
|
|
65
|
+
return { cancelled: false };
|
|
66
|
+
},
|
|
61
67
|
},
|
|
62
68
|
calls,
|
|
63
69
|
widgets,
|
|
64
70
|
statuses,
|
|
71
|
+
newSessions,
|
|
65
72
|
};
|
|
66
73
|
}
|
|
67
74
|
|
|
@@ -77,7 +84,10 @@ function makeMockPi(): { pi: any; messages: SentMessage[] } {
|
|
|
77
84
|
};
|
|
78
85
|
}
|
|
79
86
|
|
|
80
|
-
function seedValidationBlockedMilestone(
|
|
87
|
+
function seedValidationBlockedMilestone(
|
|
88
|
+
base: string,
|
|
89
|
+
status: "needs-attention" | "needs-remediation" = "needs-attention",
|
|
90
|
+
): void {
|
|
81
91
|
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
82
92
|
insertMilestone({ id: "M006", title: "Mark All Complete", status: "active" });
|
|
83
93
|
insertSlice({
|
|
@@ -91,9 +101,9 @@ function seedValidationBlockedMilestone(base: string): void {
|
|
|
91
101
|
insertAssessment({
|
|
92
102
|
path: "milestones/M006/M006-VALIDATION.md",
|
|
93
103
|
milestoneId: "M006",
|
|
94
|
-
status
|
|
104
|
+
status,
|
|
95
105
|
scope: "milestone-validation",
|
|
96
|
-
fullContent:
|
|
106
|
+
fullContent: `verdict: ${status}`,
|
|
97
107
|
});
|
|
98
108
|
invalidateStateCache();
|
|
99
109
|
}
|
|
@@ -155,6 +165,31 @@ test("dispatcher blocks workflow-advancing aliases while validation is blocked",
|
|
|
155
165
|
}
|
|
156
166
|
});
|
|
157
167
|
|
|
168
|
+
test("dispatcher allows reassess dispatch while validation needs remediation", async () => {
|
|
169
|
+
const base = makeBase();
|
|
170
|
+
try {
|
|
171
|
+
seedValidationBlockedMilestone(base, "needs-remediation");
|
|
172
|
+
const { ctx, calls, newSessions } = makeMockCtx(base);
|
|
173
|
+
const { pi, messages } = makeMockPi();
|
|
174
|
+
|
|
175
|
+
await handleGSDCommand("dispatch reassess", ctx, pi);
|
|
176
|
+
|
|
177
|
+
assert.equal(messages.length, 1);
|
|
178
|
+
assert.equal(messages[0].customType, "gsd-dispatch");
|
|
179
|
+
assert.equal(messages[0].display, false);
|
|
180
|
+
assert.match(messages[0].content, /UNIT: Reassess Roadmap/);
|
|
181
|
+
assert.ok(
|
|
182
|
+
calls.some((call) => call.kind === "info" && /Dispatching reassess-roadmap for M006\/S01/.test(call.message)),
|
|
183
|
+
`expected reassess dispatch notification, got: ${JSON.stringify(calls)}`,
|
|
184
|
+
);
|
|
185
|
+
assert.deepEqual(newSessions, [{ workspaceRoot: base }]);
|
|
186
|
+
} finally {
|
|
187
|
+
closeDatabase();
|
|
188
|
+
invalidateStateCache();
|
|
189
|
+
cleanup(base);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
|
|
158
193
|
test("dispatcher still allows recovery commands while validation is blocked", async () => {
|
|
159
194
|
const base = makeBase();
|
|
160
195
|
try {
|
|
@@ -399,8 +399,12 @@ test("handleVerdict needs-remediation override with --rationale rewrites verdict
|
|
|
399
399
|
assert.match(rewritten, /found missing slice/);
|
|
400
400
|
|
|
401
401
|
assert.ok(
|
|
402
|
-
calls.some((c) =>
|
|
403
|
-
"needs-remediation override should suggest
|
|
402
|
+
calls.some((c) => /\/gsd dispatch reassess/.test(c.message)),
|
|
403
|
+
"needs-remediation override should suggest the reassess dispatch follow-up",
|
|
404
|
+
);
|
|
405
|
+
assert.ok(
|
|
406
|
+
calls.every((c) => !/gsd_reassess_roadmap/.test(c.message)),
|
|
407
|
+
"needs-remediation override should not expose the internal tool name",
|
|
404
408
|
);
|
|
405
409
|
} finally {
|
|
406
410
|
closeDatabase();
|
|
@@ -12,6 +12,7 @@ import { tmpdir } from "node:os";
|
|
|
12
12
|
|
|
13
13
|
import { buildSliceSummaryExcerpt, buildCompleteMilestonePrompt, buildValidateMilestonePrompt } from "../auto-prompts.ts";
|
|
14
14
|
import { invalidateAllCaches } from "../cache.ts";
|
|
15
|
+
import { closeDatabase, insertMilestone, openDatabase } from "../gsd-db.ts";
|
|
15
16
|
|
|
16
17
|
// ─── Fixture helpers ──────────────────────────────────────────────────────
|
|
17
18
|
|
|
@@ -364,3 +365,32 @@ test("validate-milestone prompt uses slice excerpts and on-demand paths instead
|
|
|
364
365
|
"validate prompt must not inline full assessment traces",
|
|
365
366
|
);
|
|
366
367
|
});
|
|
368
|
+
|
|
369
|
+
test("validate-milestone prompt inlines planned verification classes as canonical rows", async (t) => {
|
|
370
|
+
const base = createBase();
|
|
371
|
+
t.after(() => {
|
|
372
|
+
try { closeDatabase(); } catch { /* ignore */ }
|
|
373
|
+
cleanup(base);
|
|
374
|
+
});
|
|
375
|
+
invalidateAllCaches();
|
|
376
|
+
|
|
377
|
+
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
378
|
+
insertMilestone({
|
|
379
|
+
id: "M001",
|
|
380
|
+
planning: {
|
|
381
|
+
verificationContract: "Local command exits 0.",
|
|
382
|
+
verificationOperational: "No long-running child process remains.",
|
|
383
|
+
},
|
|
384
|
+
});
|
|
385
|
+
writeRoadmap(base, makeRoadmap());
|
|
386
|
+
writeSummary(base, "S01", makeFatSummary("S01"));
|
|
387
|
+
writeSummary(base, "S02", makeFatSummary("S02"));
|
|
388
|
+
|
|
389
|
+
const prompt = await buildValidateMilestonePrompt("M001", "Test Milestone", base);
|
|
390
|
+
|
|
391
|
+
assert.match(prompt, /### Verification Classes \(from planning\)/);
|
|
392
|
+
assert.match(prompt, /Every row in this table must appear in `verificationClasses`/);
|
|
393
|
+
assert.match(prompt, /\| Class \| Planned Check \|/);
|
|
394
|
+
assert.match(prompt, /\| Contract \| Local command exits 0\. \|/);
|
|
395
|
+
assert.match(prompt, /\| Operational \| No long-running child process remains\. \|/);
|
|
396
|
+
});
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
insertMilestone,
|
|
21
21
|
insertSlice,
|
|
22
22
|
insertTask,
|
|
23
|
+
setSliceSummaryMd,
|
|
23
24
|
} from '../gsd-db.ts';
|
|
24
25
|
import { handleCompleteSlice } from '../tools/complete-slice.ts';
|
|
25
26
|
import type { CompleteSliceParams } from '../types.ts';
|
|
@@ -153,4 +154,45 @@ describe('complete-slice verification gate (#3580)', () => {
|
|
|
153
154
|
);
|
|
154
155
|
}
|
|
155
156
|
});
|
|
157
|
+
|
|
158
|
+
test('backfills prior verification narrative when verification is omitted on re-completion', async () => {
|
|
159
|
+
// Seed full_summary_md with a prior verification narrative (simulates a
|
|
160
|
+
// previous completion where the verification text was recorded).
|
|
161
|
+
const priorVerification = 'All 12 API integration tests pass — zero regressions detected.';
|
|
162
|
+
const priorSummary = [
|
|
163
|
+
'---',
|
|
164
|
+
'verification_result: passed',
|
|
165
|
+
'---',
|
|
166
|
+
'',
|
|
167
|
+
'# S01: Test Slice',
|
|
168
|
+
'',
|
|
169
|
+
'## What Happened',
|
|
170
|
+
'',
|
|
171
|
+
'narrative goes here',
|
|
172
|
+
'',
|
|
173
|
+
'## Verification',
|
|
174
|
+
'',
|
|
175
|
+
priorVerification,
|
|
176
|
+
'',
|
|
177
|
+
'## Requirements Advanced',
|
|
178
|
+
'',
|
|
179
|
+
].join('\n');
|
|
180
|
+
setSliceSummaryMd('M001', 'S01', priorSummary, '');
|
|
181
|
+
|
|
182
|
+
// Complete slice without providing verification — handler must backfill
|
|
183
|
+
// from the existing summary rather than writing an empty section.
|
|
184
|
+
const result = await handleCompleteSlice(
|
|
185
|
+
makeParams({ verification: undefined }),
|
|
186
|
+
basePath,
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
assert.ok(!('error' in result), `expected success, got: ${'error' in result ? (result as { error: string }).error : ''}`);
|
|
190
|
+
|
|
191
|
+
const { summaryPath } = result as { summaryPath: string };
|
|
192
|
+
const written = fs.readFileSync(summaryPath, 'utf8');
|
|
193
|
+
assert.ok(
|
|
194
|
+
written.includes(priorVerification),
|
|
195
|
+
`prior verification narrative must be preserved when verification is omitted; got:\n${written}`,
|
|
196
|
+
);
|
|
197
|
+
});
|
|
156
198
|
});
|
|
@@ -6,6 +6,7 @@ import test from "node:test";
|
|
|
6
6
|
import assert from "node:assert/strict";
|
|
7
7
|
|
|
8
8
|
import { GSDDashboardOverlay } from "../dashboard-overlay.ts";
|
|
9
|
+
import type { UnitMetrics } from "../metrics.ts";
|
|
9
10
|
import { assertFullOuterBorder } from "./tui-border-assertions.ts";
|
|
10
11
|
|
|
11
12
|
const fakeTheme = {
|
|
@@ -23,3 +24,47 @@ test("GSDDashboardOverlay renders inside the shared full border", (t) => {
|
|
|
23
24
|
assert.ok(lines.some((line) => line.startsWith("│")), "body rows should have side borders");
|
|
24
25
|
assert.match(lines.at(-1) ?? "", /^╰─+╯$/);
|
|
25
26
|
});
|
|
27
|
+
|
|
28
|
+
test("GSDDashboardOverlay reuses metrics aggregations until the unit count changes", (t) => {
|
|
29
|
+
const overlay = new GSDDashboardOverlay({ requestRender() {} }, fakeTheme as any, () => {});
|
|
30
|
+
t.after(() => overlay.dispose());
|
|
31
|
+
|
|
32
|
+
const firstUnits = [makeUnit("M001/S001/T001", 0.25)];
|
|
33
|
+
const firstMetrics = (overlay as any).ensureMetricsCache(firstUnits);
|
|
34
|
+
|
|
35
|
+
overlay.invalidate();
|
|
36
|
+
|
|
37
|
+
const sameCountUnits = [makeUnit("M001/S001/T002", 0.5)];
|
|
38
|
+
const sameCountMetrics = (overlay as any).ensureMetricsCache(sameCountUnits);
|
|
39
|
+
assert.equal(sameCountMetrics, firstMetrics, "same unit count should reuse cached metrics");
|
|
40
|
+
assert.equal(sameCountMetrics.totals.cost, 0.25);
|
|
41
|
+
|
|
42
|
+
const increasedCountMetrics = (overlay as any).ensureMetricsCache([
|
|
43
|
+
...sameCountUnits,
|
|
44
|
+
makeUnit("M001/S001/T003", 0.75),
|
|
45
|
+
]);
|
|
46
|
+
assert.notEqual(increasedCountMetrics, firstMetrics, "changed unit count should recompute metrics");
|
|
47
|
+
assert.equal(increasedCountMetrics.totals.units, 2);
|
|
48
|
+
assert.equal(increasedCountMetrics.totals.cost, 1.25);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
function makeUnit(id: string, cost: number): UnitMetrics {
|
|
52
|
+
return {
|
|
53
|
+
type: "execute-task",
|
|
54
|
+
id,
|
|
55
|
+
model: "claude-sonnet-4.5",
|
|
56
|
+
startedAt: 1000,
|
|
57
|
+
finishedAt: 2000,
|
|
58
|
+
tokens: {
|
|
59
|
+
input: 100,
|
|
60
|
+
output: 50,
|
|
61
|
+
cacheRead: 25,
|
|
62
|
+
cacheWrite: 10,
|
|
63
|
+
total: 185,
|
|
64
|
+
},
|
|
65
|
+
cost,
|
|
66
|
+
toolCalls: 1,
|
|
67
|
+
assistantMessages: 1,
|
|
68
|
+
userMessages: 1,
|
|
69
|
+
};
|
|
70
|
+
}
|