@opengsd/gsd-pi 1.1.1-dev.616a1a1 → 1.1.1-dev.75048e7
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 +55 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +134 -10
- package/dist/resources/extensions/gsd/auto-prompts.js +72 -22
- package/dist/resources/extensions/gsd/auto-recovery.js +7 -8
- 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 +18 -65
- package/dist/resources/extensions/gsd/auto-worktree.js +18 -5
- package/dist/resources/extensions/gsd/auto.js +31 -6
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +89 -4
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +43 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +56 -20
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +33 -38
- package/dist/resources/extensions/gsd/browser-evidence.js +29 -2
- package/dist/resources/extensions/gsd/closeout-consistency-gate.js +61 -0
- 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 +119 -176
- 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/milestone-closeout.js +3 -1
- package/dist/resources/extensions/gsd/pending-auto-start.js +0 -1
- 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 +33 -23
- 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/recovery-classification.js +20 -0
- 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-contract.js +5 -0
- package/dist/resources/extensions/gsd/tool-presentation-plan.js +143 -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 +483 -6
- package/dist/resources/extensions/gsd/unit-context-manifest.js +8 -3
- package/dist/resources/extensions/gsd/unit-tool-contracts.js +169 -0
- 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 -73
- 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 +5 -5
- 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 +5 -5
- 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/components/tool-execution.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +5 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.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 +42 -3
- 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/harness/agent-harness.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/harness/agent-harness.js +3 -1
- package/packages/pi-agent-core/dist/harness/agent-harness.js.map +1 -1
- package/packages/pi-agent-core/dist/harness/types.d.ts +1 -0
- package/packages/pi-agent-core/dist/harness/types.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/harness/types.js.map +1 -1
- package/packages/pi-agent-core/dist/types.d.ts +6 -1
- 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 +411 -39
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +504 -153
- 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/extensions/extension-upstream-types.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.js.map +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/dist/core/tools/bash.js +2 -2
- package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.js +3 -2
- package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/render-utils.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/tools/render-utils.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/render-utils.js +6 -0
- package/packages/pi-coding-agent/dist/core/tools/render-utils.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/write.js +3 -2
- package/packages/pi-coding-agent/dist/core/tools/write.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 +67 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +166 -9
- package/src/resources/extensions/gsd/auto-prompts.ts +106 -15
- package/src/resources/extensions/gsd/auto-recovery.ts +7 -7
- 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 +43 -73
- package/src/resources/extensions/gsd/auto-worktree.ts +23 -5
- package/src/resources/extensions/gsd/auto.ts +47 -5
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +96 -4
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +51 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +81 -25
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +70 -63
- package/src/resources/extensions/gsd/browser-evidence.ts +26 -2
- package/src/resources/extensions/gsd/closeout-consistency-gate.ts +137 -0
- 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 +215 -217
- 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/milestone-closeout.ts +3 -1
- package/src/resources/extensions/gsd/pending-auto-start.ts +0 -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 +33 -23
- 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/recovery-classification.ts +20 -0
- 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-recovery.test.ts +10 -2
- package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +4 -1
- 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/auto-warning-noise-regression.test.ts +12 -2
- package/src/resources/extensions/gsd/tests/browser-evidence.test.ts +142 -0
- package/src/resources/extensions/gsd/tests/check-auto-start-pending-gate.test.ts +9 -15
- package/src/resources/extensions/gsd/tests/check-auto-start-ready-guard.test.ts +26 -16
- package/src/resources/extensions/gsd/tests/commands-dispatcher-unmerged-milestone.test.ts +21 -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-complete-milestone-guard.test.ts +40 -1
- 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/gate-1b-orphan-discrimination.test.ts +31 -79
- 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-session-isolation.test.ts +5 -3
- package/src/resources/extensions/gsd/tests/guided-flow-state-rebuild.test.ts +40 -4
- 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/auto-worktree-milestone-merge.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +72 -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/merge-closeout-consistency-gate.test.ts +63 -0
- package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +10 -1
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +9 -1
- 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 +83 -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 +79 -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/run-uat-composer.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +36 -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 +493 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +40 -0
- package/src/resources/extensions/gsd/tool-contract.ts +6 -0
- package/src/resources/extensions/gsd/tool-presentation-plan.ts +223 -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 +589 -8
- 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/unit-tool-contracts.ts +186 -0
- 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 -73
- 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/src/resources/extensions/gsd/tests/gate-1b-recovery-bound-corrections.test.ts +0 -246
- package/src/resources/extensions/gsd/tests/gate-1b-recovery-bound.test.ts +0 -218
- /package/dist/web/standalone/.next/static/{L9N5SPFi7f-Ne4u2uXzCe → h4TGni4xJzlZjGkxaT6uU}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{L9N5SPFi7f-Ne4u2uXzCe → h4TGni4xJzlZjGkxaT6uU}/_ssgManifest.js +0 -0
|
@@ -91,10 +91,15 @@ import { nativeHasChanges, nativeIsRepo, _resetHasChangesCache } from "./native-
|
|
|
91
91
|
import { debugLog, isDebugEnabled } from "./debug-logger.js";
|
|
92
92
|
import { resolveCanonicalMilestoneRoot } from "./worktree-manager.js";
|
|
93
93
|
import { resolveWorktreeProjectRoot } from "./worktree-root.js";
|
|
94
|
+
import { detectWorktreeName } from "./worktree.js";
|
|
94
95
|
import { probeGitConflictState } from "./git-conflict-state.js";
|
|
95
96
|
import { runTurnGitAction } from "./git-service.js";
|
|
96
97
|
import { parseUnitId } from "./unit-id.js";
|
|
97
98
|
import { resolveExpectedArtifactPath } from "./auto-artifact-paths.js";
|
|
99
|
+
import {
|
|
100
|
+
checkCloseoutConsistencyGate,
|
|
101
|
+
formatCloseoutConsistencyBlock,
|
|
102
|
+
} from "./closeout-consistency-gate.js";
|
|
98
103
|
|
|
99
104
|
// ─── Types ────────────────────────────────────────────────────────────────
|
|
100
105
|
|
|
@@ -340,6 +345,29 @@ function isRegistryMilestoneComplete(state: GSDState, mid: string): boolean {
|
|
|
340
345
|
);
|
|
341
346
|
}
|
|
342
347
|
|
|
348
|
+
function normalizeMilestoneScope(value: string | null | undefined): string | null {
|
|
349
|
+
const trimmed = value?.trim();
|
|
350
|
+
if (!trimmed || !MILESTONE_ID_RE.test(trimmed)) return null;
|
|
351
|
+
return trimmed;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
function resolveDispatchMilestoneScope(
|
|
355
|
+
ctx: DispatchContext,
|
|
356
|
+
): { id: string; source: string } | null {
|
|
357
|
+
const sessionMilestone = normalizeMilestoneScope(ctx.session?.currentMilestoneId);
|
|
358
|
+
if (sessionMilestone) return { id: sessionMilestone, source: "session.currentMilestoneId" };
|
|
359
|
+
|
|
360
|
+
const sessionWorktree = normalizeMilestoneScope(
|
|
361
|
+
ctx.session?.basePath ? detectWorktreeName(ctx.session.basePath) : null,
|
|
362
|
+
);
|
|
363
|
+
if (sessionWorktree) return { id: sessionWorktree, source: "session.basePath worktree" };
|
|
364
|
+
|
|
365
|
+
const baseWorktree = normalizeMilestoneScope(detectWorktreeName(ctx.basePath));
|
|
366
|
+
if (baseWorktree) return { id: baseWorktree, source: "basePath worktree" };
|
|
367
|
+
|
|
368
|
+
return null;
|
|
369
|
+
}
|
|
370
|
+
|
|
343
371
|
function hasMilestonePassedDiscuss(basePath: string, mid: string): boolean {
|
|
344
372
|
if (isDbAvailable()) {
|
|
345
373
|
try {
|
|
@@ -598,6 +626,7 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
598
626
|
structuredQuestionsAvailable,
|
|
599
627
|
{ headless: !!process.env.GSD_HEADLESS },
|
|
600
628
|
),
|
|
629
|
+
pauseAfterDispatch: !process.env.GSD_HEADLESS,
|
|
601
630
|
};
|
|
602
631
|
},
|
|
603
632
|
},
|
|
@@ -748,6 +777,7 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
748
777
|
structuredQuestionsAvailable,
|
|
749
778
|
{ headless: !!process.env.GSD_HEADLESS },
|
|
750
779
|
),
|
|
780
|
+
pauseAfterDispatch: !process.env.GSD_HEADLESS,
|
|
751
781
|
};
|
|
752
782
|
},
|
|
753
783
|
},
|
|
@@ -781,6 +811,7 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
781
811
|
unitType: "discuss-project",
|
|
782
812
|
unitId: "PROJECT",
|
|
783
813
|
prompt: await buildDiscussProjectPrompt(basePath, structuredQuestionsAvailable),
|
|
814
|
+
pauseAfterDispatch: !process.env.GSD_HEADLESS,
|
|
784
815
|
};
|
|
785
816
|
},
|
|
786
817
|
},
|
|
@@ -802,6 +833,7 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
802
833
|
unitType: "discuss-requirements",
|
|
803
834
|
unitId: "REQUIREMENTS",
|
|
804
835
|
prompt: await buildDiscussRequirementsPrompt(basePath, structuredQuestionsAvailable),
|
|
836
|
+
pauseAfterDispatch: !process.env.GSD_HEADLESS,
|
|
805
837
|
};
|
|
806
838
|
},
|
|
807
839
|
},
|
|
@@ -916,6 +948,7 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
916
948
|
structuredQuestionsAvailable,
|
|
917
949
|
{ headless: !!process.env.GSD_HEADLESS },
|
|
918
950
|
),
|
|
951
|
+
pauseAfterDispatch: !process.env.GSD_HEADLESS,
|
|
919
952
|
};
|
|
920
953
|
},
|
|
921
954
|
},
|
|
@@ -1606,6 +1639,16 @@ export const DISPATCH_RULES: DispatchRule[] = [
|
|
|
1606
1639
|
prompt: await buildCompleteMilestonePrompt(mid, midTitle, basePath),
|
|
1607
1640
|
};
|
|
1608
1641
|
}
|
|
1642
|
+
if (milestone) {
|
|
1643
|
+
const closeoutGate = checkCloseoutConsistencyGate(mid, { refreshFromDisk: true });
|
|
1644
|
+
if (!closeoutGate.ok) {
|
|
1645
|
+
return {
|
|
1646
|
+
action: "stop",
|
|
1647
|
+
reason: formatCloseoutConsistencyBlock(closeoutGate),
|
|
1648
|
+
level: "warning",
|
|
1649
|
+
};
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1609
1652
|
}
|
|
1610
1653
|
return {
|
|
1611
1654
|
action: "stop",
|
|
@@ -1631,6 +1674,19 @@ import { getRegistry } from "./rule-registry.js";
|
|
|
1631
1674
|
export async function resolveDispatch(
|
|
1632
1675
|
ctx: DispatchContext,
|
|
1633
1676
|
): Promise<DispatchAction> {
|
|
1677
|
+
if (ctx.mid && isDbAvailable()) {
|
|
1678
|
+
const milestone = getMilestone(ctx.mid);
|
|
1679
|
+
if (milestone && isClosedStatus(milestone.status)) {
|
|
1680
|
+
return {
|
|
1681
|
+
action: "stop",
|
|
1682
|
+
reason:
|
|
1683
|
+
`Milestone ${ctx.mid} is closed (status: ${milestone.status}); auto-mode will not reopen or recover it implicitly. ` +
|
|
1684
|
+
"Use an explicit reopen command before planning or executing more work for this milestone.",
|
|
1685
|
+
level: "warning",
|
|
1686
|
+
};
|
|
1687
|
+
}
|
|
1688
|
+
}
|
|
1689
|
+
|
|
1634
1690
|
const activeMid = ctx.state.activeMilestone?.id;
|
|
1635
1691
|
if (activeMid && ctx.mid !== activeMid) {
|
|
1636
1692
|
return {
|
|
@@ -1642,6 +1698,17 @@ export async function resolveDispatch(
|
|
|
1642
1698
|
};
|
|
1643
1699
|
}
|
|
1644
1700
|
|
|
1701
|
+
const scopedMilestone = resolveDispatchMilestoneScope(ctx);
|
|
1702
|
+
if (scopedMilestone && ctx.mid !== scopedMilestone.id) {
|
|
1703
|
+
return {
|
|
1704
|
+
action: "stop",
|
|
1705
|
+
reason:
|
|
1706
|
+
`Dispatch milestone mismatch: context mid "${ctx.mid}" does not match ${scopedMilestone.source} "${scopedMilestone.id}". ` +
|
|
1707
|
+
"The active worktree/session and derived project state disagree; recover, park, or discard the stranded milestone before continuing.",
|
|
1708
|
+
level: "warning",
|
|
1709
|
+
};
|
|
1710
|
+
}
|
|
1711
|
+
|
|
1645
1712
|
// Delegate to registry when available
|
|
1646
1713
|
try {
|
|
1647
1714
|
const registry = getRegistry();
|
|
@@ -55,8 +55,10 @@ import { parseRoadmap as parseLegacyRoadmap } from "./parsers-legacy.js";
|
|
|
55
55
|
import { consumeSignal } from "./session-status-io.js";
|
|
56
56
|
import {
|
|
57
57
|
checkPostUnitHooks,
|
|
58
|
+
consumeHookFailure,
|
|
58
59
|
isRetryPending,
|
|
59
60
|
consumeRetryTrigger,
|
|
61
|
+
consumeGateBlock,
|
|
60
62
|
persistHookState,
|
|
61
63
|
resolveHookArtifactPath,
|
|
62
64
|
} from "./post-unit-hooks.js";
|
|
@@ -394,6 +396,50 @@ function stripKnownIdPrefix(value: string | undefined | null, id: string): strin
|
|
|
394
396
|
return raw;
|
|
395
397
|
}
|
|
396
398
|
|
|
399
|
+
function parseReactiveBatchTaskIds(unitId: string): string[] {
|
|
400
|
+
const { task: batchPart } = parseUnitId(unitId);
|
|
401
|
+
if (!batchPart?.startsWith("reactive+")) return [];
|
|
402
|
+
|
|
403
|
+
const rawIds = batchPart
|
|
404
|
+
.slice("reactive+".length)
|
|
405
|
+
.split(",")
|
|
406
|
+
.map((taskId) => taskId.trim().toUpperCase())
|
|
407
|
+
.filter(Boolean);
|
|
408
|
+
|
|
409
|
+
const unique = new Set<string>();
|
|
410
|
+
for (const taskId of rawIds) {
|
|
411
|
+
unique.add(taskId);
|
|
412
|
+
}
|
|
413
|
+
return [...unique];
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
function dedupePaths(values: string[]): string[] {
|
|
417
|
+
const seen = new Set<string>();
|
|
418
|
+
const result: string[] = [];
|
|
419
|
+
for (const value of values) {
|
|
420
|
+
if (!seen.has(value)) {
|
|
421
|
+
seen.add(value);
|
|
422
|
+
result.push(value);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
return result;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
function getPlannedKeyFiles(tasks: Array<
|
|
429
|
+
{ expected_output?: string[]; files?: string[]; key_files?: string[] }
|
|
430
|
+
>): string[] {
|
|
431
|
+
return dedupePaths(
|
|
432
|
+
tasks.flatMap((taskRow) => [
|
|
433
|
+
...(taskRow.expected_output ?? []),
|
|
434
|
+
...(taskRow.files ?? []),
|
|
435
|
+
...(taskRow.key_files ?? []),
|
|
436
|
+
]),
|
|
437
|
+
);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
export const _parseReactiveBatchTaskIdsForTest = parseReactiveBatchTaskIds;
|
|
441
|
+
export const _getPlannedKeyFilesForTest = getPlannedKeyFiles;
|
|
442
|
+
|
|
397
443
|
function resolveVerificationFailureMarkerPath(
|
|
398
444
|
unitType: string,
|
|
399
445
|
unitId: string,
|
|
@@ -481,6 +527,40 @@ async function buildTaskCommitContextForUnit(
|
|
|
481
527
|
};
|
|
482
528
|
}
|
|
483
529
|
|
|
530
|
+
async function buildReactiveTaskCommitContext(
|
|
531
|
+
_basePath: string,
|
|
532
|
+
unitId: string,
|
|
533
|
+
): Promise<TaskCommitContext | undefined> {
|
|
534
|
+
const { milestone: mid, slice: sid } = parseUnitId(unitId);
|
|
535
|
+
if (!mid || !sid || !isDbAvailable()) return undefined;
|
|
536
|
+
|
|
537
|
+
const batchTaskIds = parseReactiveBatchTaskIds(unitId);
|
|
538
|
+
if (batchTaskIds.length === 0) return undefined;
|
|
539
|
+
|
|
540
|
+
const milestone = getMilestone(mid);
|
|
541
|
+
const slice = getSlice(mid, sid);
|
|
542
|
+
const taskRows = batchTaskIds
|
|
543
|
+
.map((tid) => getTask(mid, sid, tid))
|
|
544
|
+
.filter((taskRow): taskRow is NonNullable<ReturnType<typeof getTask>> => taskRow !== null);
|
|
545
|
+
|
|
546
|
+
const keyFiles = getPlannedKeyFiles(taskRows);
|
|
547
|
+
if (taskRows.length === 0 || keyFiles.length === 0) return undefined;
|
|
548
|
+
|
|
549
|
+
const taskLabel = taskRows.map((row) => row.id).join(",");
|
|
550
|
+
|
|
551
|
+
return {
|
|
552
|
+
taskId: `${sid}/${taskLabel}`,
|
|
553
|
+
taskDisplayId: "reactive-batch",
|
|
554
|
+
taskTitle: `Reactive batch: ${taskLabel}`,
|
|
555
|
+
milestoneId: mid,
|
|
556
|
+
milestoneTitle: stripKnownIdPrefix(milestone?.title, mid),
|
|
557
|
+
sliceId: sid,
|
|
558
|
+
sliceTitle: stripKnownIdPrefix(slice?.title, sid),
|
|
559
|
+
oneLiner: `Reactive execute for ${taskLabel}`,
|
|
560
|
+
keyFiles,
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
|
|
484
564
|
async function runPostUnitGitHubSyncIfNeeded(
|
|
485
565
|
basePath: string,
|
|
486
566
|
unit: NonNullable<AutoSession["currentUnit"]>,
|
|
@@ -943,6 +1023,8 @@ export async function autoCommitUnit(
|
|
|
943
1023
|
|
|
944
1024
|
if (unitType === "execute-task") {
|
|
945
1025
|
taskContext = await buildTaskCommitContextForUnit(basePath, unitId);
|
|
1026
|
+
} else if (unitType === "reactive-execute") {
|
|
1027
|
+
taskContext = await buildReactiveTaskCommitContext(basePath, unitId);
|
|
946
1028
|
}
|
|
947
1029
|
|
|
948
1030
|
_resetHasChangesCache();
|
|
@@ -1005,6 +1087,21 @@ async function runCloseoutGitAction(
|
|
|
1005
1087
|
if (mid && sid && tid && isDbAvailable()) {
|
|
1006
1088
|
targetRepositories = getTask(mid, sid, tid)?.target_repositories;
|
|
1007
1089
|
}
|
|
1090
|
+
} else if (turnAction === "commit" && unit.type === "reactive-execute") {
|
|
1091
|
+
taskContext = await buildReactiveTaskCommitContext(s.basePath, unit.id);
|
|
1092
|
+
const { milestone: mid, slice: sid } = parseUnitId(unit.id);
|
|
1093
|
+
if (mid && sid && isDbAvailable()) {
|
|
1094
|
+
const repositories = new Set<string>();
|
|
1095
|
+
for (const tid of parseReactiveBatchTaskIds(unit.id)) {
|
|
1096
|
+
const taskRow = getTask(mid, sid, tid);
|
|
1097
|
+
for (const repoId of taskRow?.target_repositories ?? []) {
|
|
1098
|
+
repositories.add(repoId);
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
if (repositories.size > 0) {
|
|
1102
|
+
targetRepositories = [...repositories];
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1008
1105
|
}
|
|
1009
1106
|
|
|
1010
1107
|
// Invalidate the nativeHasChanges cache before auto-commit (#1853).
|
|
@@ -1436,12 +1533,24 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
1436
1533
|
const { milestone: sMid, slice: sSid, task: sTid } = parseUnitId(s.currentUnit.id);
|
|
1437
1534
|
|
|
1438
1535
|
// File change validation (execute-task only, after unit execution)
|
|
1439
|
-
if (safetyConfig.file_change_validation && s.currentUnit.type === "execute-task" && sMid && sSid && sTid
|
|
1536
|
+
if (safetyConfig.file_change_validation && s.currentUnit.type === "execute-task" && sMid && sSid && sTid) {
|
|
1440
1537
|
try {
|
|
1441
|
-
const
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1538
|
+
const sliceTaskRows = isDbAvailable()
|
|
1539
|
+
? getSliceTasks(sMid, sSid).filter((t) => isClosedStatus(t.status) || t.id === sTid)
|
|
1540
|
+
: [];
|
|
1541
|
+
|
|
1542
|
+
if (sliceTaskRows.length > 0) {
|
|
1543
|
+
const expectedOutput = getPlannedKeyFiles(
|
|
1544
|
+
sliceTaskRows.map((taskRow) => ({
|
|
1545
|
+
expected_output: taskRow.expected_output,
|
|
1546
|
+
files: taskRow.files,
|
|
1547
|
+
})),
|
|
1548
|
+
);
|
|
1549
|
+
const plannedFiles = getPlannedKeyFiles(
|
|
1550
|
+
sliceTaskRows.map((taskRow) => ({
|
|
1551
|
+
files: taskRow.files,
|
|
1552
|
+
})),
|
|
1553
|
+
);
|
|
1445
1554
|
const audit = validateFileChanges(s.basePath, expectedOutput, plannedFiles, safetyConfig.file_change_allowlist);
|
|
1446
1555
|
if (audit && audit.violations.length > 0) {
|
|
1447
1556
|
const warnings = audit.violations.filter(v => v.severity === "warning");
|
|
@@ -1455,6 +1564,30 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
1455
1564
|
);
|
|
1456
1565
|
}
|
|
1457
1566
|
}
|
|
1567
|
+
} else {
|
|
1568
|
+
const taskRow = getTask(sMid, sSid, sTid);
|
|
1569
|
+
if (taskRow) {
|
|
1570
|
+
const expectedOutput = taskRow.expected_output ?? [];
|
|
1571
|
+
const plannedFiles = taskRow.files ?? [];
|
|
1572
|
+
const audit = validateFileChanges(
|
|
1573
|
+
s.basePath,
|
|
1574
|
+
expectedOutput,
|
|
1575
|
+
plannedFiles,
|
|
1576
|
+
safetyConfig.file_change_allowlist,
|
|
1577
|
+
);
|
|
1578
|
+
if (audit && audit.violations.length > 0) {
|
|
1579
|
+
const warnings = audit.violations.filter(v => v.severity === "warning");
|
|
1580
|
+
for (const v of warnings) {
|
|
1581
|
+
logWarning("safety", `file-change: ${v.file} — ${v.reason}`);
|
|
1582
|
+
}
|
|
1583
|
+
if (warnings.length > 0) {
|
|
1584
|
+
ctx.ui.notify(
|
|
1585
|
+
`Safety: ${warnings.length} unexpected file change(s) outside task plan`,
|
|
1586
|
+
"warning",
|
|
1587
|
+
);
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1458
1591
|
}
|
|
1459
1592
|
} catch (e) {
|
|
1460
1593
|
debugLog("postUnit", { phase: "safety-file-change", error: String(e) });
|
|
@@ -2096,11 +2229,11 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
2096
2229
|
// ── Post-unit hooks ──
|
|
2097
2230
|
if (s.currentUnit && !s.stepMode) {
|
|
2098
2231
|
const hookUnit = checkPostUnitHooks(s.currentUnit.type, s.currentUnit.id, s.basePath);
|
|
2232
|
+
persistHookState(s.basePath);
|
|
2099
2233
|
if (hookUnit) {
|
|
2100
2234
|
if (s.currentUnit) {
|
|
2101
2235
|
await closeoutUnit(ctx, s.basePath, s.currentUnit.type, s.currentUnit.id, s.currentUnit.startedAt, buildSnapshotOpts(s.currentUnit.type, s.currentUnit.id));
|
|
2102
2236
|
}
|
|
2103
|
-
persistHookState(s.basePath);
|
|
2104
2237
|
|
|
2105
2238
|
return enqueueSidecar(
|
|
2106
2239
|
s, ctx,
|
|
@@ -2109,12 +2242,23 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
2109
2242
|
);
|
|
2110
2243
|
}
|
|
2111
2244
|
|
|
2245
|
+
const hookFailure = consumeHookFailure();
|
|
2246
|
+
if (hookFailure) {
|
|
2247
|
+
ctx.ui.notify(
|
|
2248
|
+
`Post-unit hook ${hookFailure.hookName} failed for ${hookFailure.unitId}: ${hookFailure.reason}. Pausing auto-mode.`,
|
|
2249
|
+
"warning",
|
|
2250
|
+
);
|
|
2251
|
+
await pauseAuto(ctx, pi);
|
|
2252
|
+
return "stopped";
|
|
2253
|
+
}
|
|
2254
|
+
|
|
2112
2255
|
// Check if a hook requested a retry of the trigger unit
|
|
2113
2256
|
if (isRetryPending()) {
|
|
2114
2257
|
const trigger = consumeRetryTrigger();
|
|
2115
2258
|
if (trigger) {
|
|
2259
|
+
persistHookState(s.basePath);
|
|
2116
2260
|
ctx.ui.notify(
|
|
2117
|
-
`Hook requested retry of ${trigger.unitType} ${trigger.unitId} — resetting
|
|
2261
|
+
`Hook requested retry of ${trigger.unitType} ${trigger.unitId} — resetting trigger unit state.`,
|
|
2118
2262
|
"info",
|
|
2119
2263
|
);
|
|
2120
2264
|
|
|
@@ -2134,8 +2278,8 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
2134
2278
|
await renderPlanCheckboxes(s.canonicalProjectRoot, mid, sid);
|
|
2135
2279
|
} catch (dbErr) {
|
|
2136
2280
|
// DB unavailable — fail explicitly rather than silently reverting to markdown mutation.
|
|
2137
|
-
// Use 'gsd recover' to
|
|
2138
|
-
logError("engine", `retry state-reset failed (DB unavailable): ${(dbErr as Error).message}. Run 'gsd recover' to
|
|
2281
|
+
// Use 'gsd recover --confirm' to import markdown into the DB if needed.
|
|
2282
|
+
logError("engine", `retry state-reset failed (DB unavailable): ${(dbErr as Error).message}. Run 'gsd recover --confirm' to import markdown into the DB.`);
|
|
2139
2283
|
}
|
|
2140
2284
|
}
|
|
2141
2285
|
|
|
@@ -2168,6 +2312,19 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
2168
2312
|
// Fall through to normal dispatch — deriveState will re-derive the unit
|
|
2169
2313
|
}
|
|
2170
2314
|
}
|
|
2315
|
+
|
|
2316
|
+
const gateBlock = consumeGateBlock();
|
|
2317
|
+
if (gateBlock) {
|
|
2318
|
+
persistHookState(s.basePath);
|
|
2319
|
+
const verdict = gateBlock.verdict ? ` verdict=${gateBlock.verdict};` : "";
|
|
2320
|
+
const artifact = gateBlock.artifact ? ` artifact=${gateBlock.artifact};` : "";
|
|
2321
|
+
const message =
|
|
2322
|
+
`Post-unit gate "${gateBlock.hookName}" blocked ${gateBlock.triggerUnitType} ${gateBlock.triggerUnitId}:` +
|
|
2323
|
+
`${verdict}${artifact} ${gateBlock.reason}. Run /gsd status to inspect, then /gsd auto after recovery.`;
|
|
2324
|
+
ctx.ui.notify(message, "warning");
|
|
2325
|
+
await pauseAuto(ctx, pi);
|
|
2326
|
+
return "stopped";
|
|
2327
|
+
}
|
|
2171
2328
|
}
|
|
2172
2329
|
|
|
2173
2330
|
// ── Fast-path stop detection (#3487) ──
|
|
@@ -45,6 +45,8 @@ import { classifyProject, type ProjectClassification } from "./detection.js";
|
|
|
45
45
|
import { hasBrowserRequiredText } from "./browser-evidence.js";
|
|
46
46
|
import { debugLog } from "./debug-logger.js";
|
|
47
47
|
import { buildSkillActivationBlock, buildSkillDiscoveryVars } from "./skill-activation.js";
|
|
48
|
+
import { findMilestoneIds } from "./milestone-ids.js";
|
|
49
|
+
import { buildRunUatPresentationForType, RUN_UAT_TOOL_PRESENTATION_PLAN_ID } from "./tool-presentation-plan.js";
|
|
48
50
|
|
|
49
51
|
export { buildSkillActivationBlock, buildSkillDiscoveryVars };
|
|
50
52
|
|
|
@@ -1428,7 +1430,7 @@ export async function checkNeedsRunUat(
|
|
|
1428
1430
|
// If the UAT file already contains a verdict, UAT has been run — skip
|
|
1429
1431
|
if (hasVerdict(uatContent)) continue;
|
|
1430
1432
|
// Also check the ASSESSMENT file — the run-uat prompt writes the verdict
|
|
1431
|
-
// there (via
|
|
1433
|
+
// there (via gsd_uat_result_save), not into the
|
|
1432
1434
|
// UAT spec file. Without this check the unit re-dispatches indefinitely.
|
|
1433
1435
|
const assessmentFile = resolveSliceFile(base, mid, sid, "ASSESSMENT");
|
|
1434
1436
|
if (assessmentFile) {
|
|
@@ -1482,21 +1484,84 @@ export async function checkNeedsRunUat(
|
|
|
1482
1484
|
* as a seed when present. The discussion agent interviews the user, writes
|
|
1483
1485
|
* a full CONTEXT.md, and the phase transitions to pre-planning automatically.
|
|
1484
1486
|
*/
|
|
1487
|
+
export interface DiscussMilestonePromptOptions {
|
|
1488
|
+
headless?: boolean;
|
|
1489
|
+
commitInstruction?: string;
|
|
1490
|
+
fastPathInstruction?: string;
|
|
1491
|
+
includeDraftSeed?: boolean;
|
|
1492
|
+
includeContextMode?: boolean;
|
|
1493
|
+
}
|
|
1494
|
+
|
|
1495
|
+
export async function buildDiscussMilestoneInlinedContext(mid: string, base: string): Promise<string> {
|
|
1496
|
+
const inlined: string[] = [];
|
|
1497
|
+
|
|
1498
|
+
const roadmapInline = await inlineFileOptional(
|
|
1499
|
+
resolveMilestoneFile(base, mid, "ROADMAP"),
|
|
1500
|
+
relMilestoneFile(base, mid, "ROADMAP"),
|
|
1501
|
+
"Milestone Roadmap",
|
|
1502
|
+
);
|
|
1503
|
+
if (roadmapInline) inlined.push(roadmapInline);
|
|
1504
|
+
|
|
1505
|
+
const contextInline = await inlineFileOptional(
|
|
1506
|
+
resolveMilestoneFile(base, mid, "CONTEXT"),
|
|
1507
|
+
relMilestoneFile(base, mid, "CONTEXT"),
|
|
1508
|
+
"Milestone Context",
|
|
1509
|
+
);
|
|
1510
|
+
if (contextInline) inlined.push(contextInline);
|
|
1511
|
+
|
|
1512
|
+
const researchInline = await inlineFileOptional(
|
|
1513
|
+
resolveMilestoneFile(base, mid, "RESEARCH"),
|
|
1514
|
+
relMilestoneFile(base, mid, "RESEARCH"),
|
|
1515
|
+
"Milestone Research",
|
|
1516
|
+
);
|
|
1517
|
+
if (researchInline) inlined.push(researchInline);
|
|
1518
|
+
|
|
1519
|
+
const decisionsPath = resolveGsdRootFile(base, "DECISIONS");
|
|
1520
|
+
if (existsSync(decisionsPath)) {
|
|
1521
|
+
const decisionsContent = await loadFile(decisionsPath);
|
|
1522
|
+
if (decisionsContent) {
|
|
1523
|
+
inlined.push(`### Decisions Register\nSource: \`${relGsdRootFile("DECISIONS")}\`\n\n${decisionsContent.trim()}`);
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
const milestoneIds = findMilestoneIds(base);
|
|
1528
|
+
const currentIndex = milestoneIds.indexOf(mid);
|
|
1529
|
+
const priorMilestoneIds = currentIndex >= 0 ? milestoneIds.slice(0, currentIndex) : milestoneIds;
|
|
1530
|
+
for (const priorMid of priorMilestoneIds) {
|
|
1531
|
+
const summaryInline = await inlineFileOptional(
|
|
1532
|
+
resolveMilestoneFile(base, priorMid, "SUMMARY"),
|
|
1533
|
+
relMilestoneFile(base, priorMid, "SUMMARY"),
|
|
1534
|
+
`${priorMid} Prior Milestone Summary`,
|
|
1535
|
+
);
|
|
1536
|
+
if (summaryInline) inlined.push(summaryInline);
|
|
1537
|
+
}
|
|
1538
|
+
|
|
1539
|
+
return inlined.length > 0
|
|
1540
|
+
? `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`
|
|
1541
|
+
: "## Inlined Context\n\n_(no milestone context files found yet — go in blind and ask broad questions)_";
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1485
1544
|
export async function buildDiscussMilestonePrompt(
|
|
1486
1545
|
mid: string,
|
|
1487
1546
|
midTitle: string,
|
|
1488
1547
|
base: string,
|
|
1489
1548
|
structuredQuestionsAvailable = "false",
|
|
1490
|
-
{
|
|
1549
|
+
{
|
|
1550
|
+
headless = false,
|
|
1551
|
+
commitInstruction = "Do not commit planning artifacts — .gsd/ is managed externally.",
|
|
1552
|
+
fastPathInstruction = "",
|
|
1553
|
+
includeDraftSeed = true,
|
|
1554
|
+
includeContextMode = true,
|
|
1555
|
+
}: DiscussMilestonePromptOptions = {},
|
|
1491
1556
|
): Promise<string> {
|
|
1492
|
-
const
|
|
1557
|
+
const contextTemplate = inlineTemplate("context", "Context");
|
|
1493
1558
|
|
|
1494
1559
|
if (headless) {
|
|
1495
1560
|
const roadmapPath = resolveMilestoneFile(base, mid, "ROADMAP");
|
|
1496
1561
|
const roadmapContent = roadmapPath ? await loadFile(roadmapPath) : null;
|
|
1497
1562
|
return loadPrompt("discuss-headless", {
|
|
1498
1563
|
seedContext: roadmapContent ?? "",
|
|
1499
|
-
inlinedTemplates:
|
|
1564
|
+
inlinedTemplates: contextTemplate,
|
|
1500
1565
|
workingDirectory: base,
|
|
1501
1566
|
milestoneId: mid,
|
|
1502
1567
|
contextPath: relMilestoneFile(base, mid, "CONTEXT"),
|
|
@@ -1505,7 +1570,9 @@ export async function buildDiscussMilestonePrompt(
|
|
|
1505
1570
|
});
|
|
1506
1571
|
}
|
|
1507
1572
|
|
|
1508
|
-
const
|
|
1573
|
+
const rawInlinedContext = await buildDiscussMilestoneInlinedContext(mid, base);
|
|
1574
|
+
const cappedInlinedContext = capPreamble(rawInlinedContext);
|
|
1575
|
+
const discussTemplates = [cappedInlinedContext, contextTemplate].join("\n\n---\n\n");
|
|
1509
1576
|
|
|
1510
1577
|
const basePrompt = loadPrompt("guided-discuss-milestone", {
|
|
1511
1578
|
workingDirectory: base,
|
|
@@ -1513,20 +1580,22 @@ export async function buildDiscussMilestonePrompt(
|
|
|
1513
1580
|
milestoneTitle: midTitle,
|
|
1514
1581
|
inlinedTemplates: discussTemplates,
|
|
1515
1582
|
structuredQuestionsAvailable,
|
|
1516
|
-
commitInstruction
|
|
1517
|
-
fastPathInstruction
|
|
1583
|
+
commitInstruction,
|
|
1584
|
+
fastPathInstruction,
|
|
1518
1585
|
});
|
|
1519
|
-
const promptWithContextMode =
|
|
1586
|
+
const promptWithContextMode = includeContextMode
|
|
1587
|
+
? prependContextModeToBlock("discuss-milestone", base, basePrompt)
|
|
1588
|
+
: basePrompt;
|
|
1520
1589
|
|
|
1521
1590
|
// If a CONTEXT-DRAFT.md exists, append it as seed material
|
|
1522
1591
|
const draftPath = resolveMilestoneFile(base, mid, "CONTEXT-DRAFT");
|
|
1523
1592
|
const draftContent = draftPath ? await loadFile(draftPath) : null;
|
|
1524
1593
|
|
|
1525
|
-
if (draftContent) {
|
|
1594
|
+
if (includeDraftSeed && draftContent) {
|
|
1526
1595
|
return `${promptWithContextMode}\n\n## Prior Discussion (Draft Seed)\n\nThe following draft was captured from a prior multi-milestone discussion. Use it as seed material — the user has already provided this context. Start with a brief reflection on what the draft covers, then probe for any gaps or open questions before writing the full CONTEXT.md.\n\n${draftContent}`;
|
|
1527
1596
|
}
|
|
1528
1597
|
|
|
1529
|
-
return
|
|
1598
|
+
return promptWithContextMode;
|
|
1530
1599
|
}
|
|
1531
1600
|
|
|
1532
1601
|
/**
|
|
@@ -2711,6 +2780,15 @@ export async function buildCompleteSlicePrompt(
|
|
|
2711
2780
|
sliceSummaryPath,
|
|
2712
2781
|
sliceUatPath,
|
|
2713
2782
|
gatesToClose,
|
|
2783
|
+
skillActivation: buildSkillActivationBlock({
|
|
2784
|
+
base,
|
|
2785
|
+
milestoneId: mid,
|
|
2786
|
+
milestoneTitle: midTitle,
|
|
2787
|
+
sliceId: sid,
|
|
2788
|
+
sliceTitle: sTitle,
|
|
2789
|
+
extraContext: [inlinedContext],
|
|
2790
|
+
unitType: "complete-slice",
|
|
2791
|
+
}),
|
|
2714
2792
|
});
|
|
2715
2793
|
}
|
|
2716
2794
|
|
|
@@ -2909,13 +2987,23 @@ export async function buildValidateMilestonePrompt(
|
|
|
2909
2987
|
if (isDbAvailable()) {
|
|
2910
2988
|
const milestone = getMilestone(mid);
|
|
2911
2989
|
if (milestone) {
|
|
2990
|
+
const escapeCell = (value: string) =>
|
|
2991
|
+
value.replace(/[\\|]/g, (char) => `\\${char}`).replace(/\r?\n/g, " ");
|
|
2912
2992
|
const classes: string[] = [];
|
|
2913
|
-
if (milestone.verification_contract) classes.push(
|
|
2914
|
-
if (milestone.verification_integration) classes.push(
|
|
2915
|
-
if (milestone.verification_operational) classes.push(
|
|
2916
|
-
if (milestone.verification_uat) classes.push(
|
|
2993
|
+
if (milestone.verification_contract) classes.push(`| Contract | ${escapeCell(milestone.verification_contract)} |`);
|
|
2994
|
+
if (milestone.verification_integration) classes.push(`| Integration | ${escapeCell(milestone.verification_integration)} |`);
|
|
2995
|
+
if (milestone.verification_operational) classes.push(`| Operational | ${escapeCell(milestone.verification_operational)} |`);
|
|
2996
|
+
if (milestone.verification_uat) classes.push(`| UAT | ${escapeCell(milestone.verification_uat)} |`);
|
|
2917
2997
|
if (classes.length > 0) {
|
|
2918
|
-
const verificationClasses =
|
|
2998
|
+
const verificationClasses = [
|
|
2999
|
+
"### Verification Classes (from planning)",
|
|
3000
|
+
"",
|
|
3001
|
+
"These verification tiers were defined during milestone planning. Every row in this table must appear in `verificationClasses` with the same canonical class name.",
|
|
3002
|
+
"",
|
|
3003
|
+
"| Class | Planned Check |",
|
|
3004
|
+
"| --- | --- |",
|
|
3005
|
+
...classes,
|
|
3006
|
+
].join("\n");
|
|
2919
3007
|
inlined.push(verificationClasses);
|
|
2920
3008
|
trackPromptContext(contextTelemetry, "verification-classes", "inline", verificationClasses);
|
|
2921
3009
|
}
|
|
@@ -3297,6 +3385,7 @@ export async function buildRunUatPrompt(
|
|
|
3297
3385
|
|
|
3298
3386
|
const uatResultPath = join(base, relSliceFile(base, mid, sliceId, "ASSESSMENT"));
|
|
3299
3387
|
const uatType = resolveEffectiveUatType(uatContent);
|
|
3388
|
+
const canonicalPresentation = JSON.stringify(buildRunUatPresentationForType(uatType), null, 2);
|
|
3300
3389
|
|
|
3301
3390
|
return loadPrompt("run-uat", {
|
|
3302
3391
|
workingDirectory: base,
|
|
@@ -3305,6 +3394,8 @@ export async function buildRunUatPrompt(
|
|
|
3305
3394
|
uatPath,
|
|
3306
3395
|
uatResultPath,
|
|
3307
3396
|
uatType,
|
|
3397
|
+
toolPresentationPlanId: RUN_UAT_TOOL_PRESENTATION_PLAN_ID,
|
|
3398
|
+
canonicalPresentation,
|
|
3308
3399
|
inlinedContext,
|
|
3309
3400
|
skillActivation: buildSkillActivationBlock({
|
|
3310
3401
|
base,
|
|
@@ -54,6 +54,7 @@ import { isGsdWorktreePath } from "./worktree-root.js";
|
|
|
54
54
|
import { resolveCanonicalMilestoneRoot } from "./worktree-manager.js";
|
|
55
55
|
import { hasImplementationArtifacts } from "./milestone-implementation-evidence.js";
|
|
56
56
|
import { loadAllCaptures, loadPendingCaptures } from "./captures.js";
|
|
57
|
+
import { checkCloseoutConsistencyGate } from "./closeout-consistency-gate.js";
|
|
57
58
|
|
|
58
59
|
// Re-export so existing consumers of auto-recovery.ts keep working.
|
|
59
60
|
export { resolveExpectedArtifactPath, diagnoseExpectedArtifact };
|
|
@@ -626,9 +627,8 @@ export function verifyExpectedArtifact(
|
|
|
626
627
|
if (summaryOutcome === "failure") return false;
|
|
627
628
|
const { milestone: mid } = parseUnitId(unitId);
|
|
628
629
|
if (mid && isDbAvailable()) {
|
|
629
|
-
const
|
|
630
|
-
if (!
|
|
631
|
-
if (!isClosedStatus(dbMilestone.status) && summaryOutcome !== "success") return false;
|
|
630
|
+
const closeoutGate = checkCloseoutConsistencyGate(mid, { refreshFromDisk: true });
|
|
631
|
+
if (!closeoutGate.ok) return false;
|
|
632
632
|
}
|
|
633
633
|
if (hasImplementationArtifacts(base, mid) === "absent") return false;
|
|
634
634
|
}
|
|
@@ -867,7 +867,7 @@ export function buildLoopRemediationSteps(
|
|
|
867
867
|
return [
|
|
868
868
|
` 1. Run \`gsd undo-task ${mid}/${sid}/${tid}\` to reset the task state`,
|
|
869
869
|
` 2. Resume auto-mode — it will re-execute the task`,
|
|
870
|
-
` 3. If the task keeps failing
|
|
870
|
+
` 3. If the task keeps failing and markdown should repopulate the DB, run \`gsd recover --confirm\``,
|
|
871
871
|
].join("\n");
|
|
872
872
|
}
|
|
873
873
|
case "plan-slice":
|
|
@@ -879,7 +879,7 @@ export function buildLoopRemediationSteps(
|
|
|
879
879
|
: relSliceFile(base, mid, sid, "RESEARCH");
|
|
880
880
|
return [
|
|
881
881
|
` 1. Write ${artifactRel} manually (or with the LLM in interactive mode)`,
|
|
882
|
-
` 2. Run \`gsd recover\` to
|
|
882
|
+
` 2. Run \`gsd recover --confirm\` to import the markdown into the DB`,
|
|
883
883
|
` 3. Resume auto-mode`,
|
|
884
884
|
].join("\n");
|
|
885
885
|
}
|
|
@@ -888,7 +888,7 @@ export function buildLoopRemediationSteps(
|
|
|
888
888
|
return [
|
|
889
889
|
` 1. Run \`gsd reset-slice ${mid}/${sid}\` to reset the slice and all its tasks`,
|
|
890
890
|
` 2. Resume auto-mode — it will re-execute incomplete tasks and re-complete the slice`,
|
|
891
|
-
` 3. If the slice keeps failing
|
|
891
|
+
` 3. If the slice keeps failing and markdown should repopulate the DB, run \`gsd recover --confirm\``,
|
|
892
892
|
].join("\n");
|
|
893
893
|
}
|
|
894
894
|
case "validate-milestone": {
|
|
@@ -896,7 +896,7 @@ export function buildLoopRemediationSteps(
|
|
|
896
896
|
const artifactRel = relMilestoneFile(base, mid, "VALIDATION");
|
|
897
897
|
return [
|
|
898
898
|
` 1. Write ${artifactRel} with verdict: pass`,
|
|
899
|
-
` 2. Run \`gsd recover\` to
|
|
899
|
+
` 2. Run \`gsd recover --confirm\` to import the markdown into the DB`,
|
|
900
900
|
` 3. Resume auto-mode`,
|
|
901
901
|
].join("\n");
|
|
902
902
|
}
|
|
@@ -42,6 +42,10 @@ export function isAutoPaused(): boolean {
|
|
|
42
42
|
return autoSession.paused;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
export function isAutoCompletionStopInProgress(): boolean {
|
|
46
|
+
return autoSession.completionStopInProgress;
|
|
47
|
+
}
|
|
48
|
+
|
|
45
49
|
export function markToolStart(toolCallId: string, toolName?: string): void {
|
|
46
50
|
markTrackedToolStart(toolCallId, autoSession.active, toolName);
|
|
47
51
|
}
|