@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
|
@@ -28,12 +28,13 @@ import { getAutoWorktreePath, checkoutBranchWithStashGuard } from "./auto-worktr
|
|
|
28
28
|
import { readResourceVersion, cleanStaleRuntimeUnits } from "./auto-worktree.js";
|
|
29
29
|
import { worktreePath as getWorktreeDir, isInsideWorktreesDir } from "./worktree-manager.js";
|
|
30
30
|
import { emitWorktreeOrphaned } from "./worktree-telemetry.js";
|
|
31
|
+
import { queryJournal } from "./journal.js";
|
|
31
32
|
import { initMetrics } from "./metrics.js";
|
|
32
33
|
import { initRoutingHistory } from "./routing-history.js";
|
|
33
34
|
import { restoreHookState, resetHookState } from "./post-unit-hooks.js";
|
|
34
35
|
import { resetProactiveHealing, setLevelChangeCallback } from "./doctor-proactive.js";
|
|
35
36
|
import { snapshotSkills } from "./skill-discovery.js";
|
|
36
|
-
import { isDbAvailable, getMilestone, getAllMilestones, insertMilestone, openDatabase, getDbStatus } from "./gsd-db.js";
|
|
37
|
+
import { isDbAvailable, getMilestone, getAllMilestones, insertMilestone, openDatabase, getDbStatus, updateMilestoneStatus } from "./gsd-db.js";
|
|
37
38
|
import { isClosedStatus } from "./status-guards.js";
|
|
38
39
|
import { classifyMilestoneSummaryContent } from "./milestone-summary-classifier.js";
|
|
39
40
|
import { extractVerdict } from "./verdict-parser.js";
|
|
@@ -48,6 +49,7 @@ import { resolveProjectRootDbPath } from "./bootstrap/dynamic-tools.js";
|
|
|
48
49
|
import { validateDirectory } from "./validate-directory.js";
|
|
49
50
|
import { isCustomProvider, resolveDefaultSessionModel, resolveDynamicRoutingConfig, } from "./preferences-models.js";
|
|
50
51
|
import { getSessionModelOverride } from "./session-model-override.js";
|
|
52
|
+
import { setAutoActiveStatus } from "./auto-dashboard.js";
|
|
51
53
|
export function resolveIsolationNoneBranchCheckout(currentBranch, integrationBranch, isolationMode, isRepo) {
|
|
52
54
|
if (!isRepo || isolationMode !== "none")
|
|
53
55
|
return null;
|
|
@@ -112,6 +114,40 @@ export function reconcileProjectMilestonesFromDisk(basePath) {
|
|
|
112
114
|
return 0;
|
|
113
115
|
}
|
|
114
116
|
}
|
|
117
|
+
export function reconcileMergedMilestonesFromJournal(basePath) {
|
|
118
|
+
if (!isDbAvailable())
|
|
119
|
+
return 0;
|
|
120
|
+
const mergedAtByMilestone = new Map();
|
|
121
|
+
for (const entry of queryJournal(basePath, { eventType: "worktree-merged" })) {
|
|
122
|
+
const data = entry.data ?? {};
|
|
123
|
+
const milestoneId = typeof data.milestoneId === "string" ? data.milestoneId : null;
|
|
124
|
+
if (!milestoneId)
|
|
125
|
+
continue;
|
|
126
|
+
if (data.conflict === true)
|
|
127
|
+
continue;
|
|
128
|
+
const endedAt = typeof data.endedAt === "string" ? data.endedAt : entry.ts;
|
|
129
|
+
const previous = mergedAtByMilestone.get(milestoneId);
|
|
130
|
+
if (!previous || endedAt > previous)
|
|
131
|
+
mergedAtByMilestone.set(milestoneId, endedAt);
|
|
132
|
+
}
|
|
133
|
+
let closed = 0;
|
|
134
|
+
for (const [milestoneId, completedAt] of mergedAtByMilestone) {
|
|
135
|
+
const existing = getMilestone(milestoneId);
|
|
136
|
+
if (!existing) {
|
|
137
|
+
insertMilestone({ id: milestoneId, title: milestoneId, status: "complete" });
|
|
138
|
+
updateMilestoneStatus(milestoneId, "complete", completedAt);
|
|
139
|
+
closed++;
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
if (!isClosedStatus(existing.status)) {
|
|
143
|
+
updateMilestoneStatus(milestoneId, "complete", completedAt);
|
|
144
|
+
closed++;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (closed > 0)
|
|
148
|
+
invalidateAllCaches();
|
|
149
|
+
return closed;
|
|
150
|
+
}
|
|
115
151
|
export function decideSurvivorAction(hasSurvivorBranch, phase) {
|
|
116
152
|
if (!hasSurvivorBranch)
|
|
117
153
|
return "none";
|
|
@@ -129,6 +165,19 @@ export function resolveSurvivorRecoveryIsolationMode(isolationMode, phase) {
|
|
|
129
165
|
function isBlockingStrandedWorkAction(action) {
|
|
130
166
|
return action.kind === "in-progress-stranded-work" && action.blocksAuto;
|
|
131
167
|
}
|
|
168
|
+
function strandedWorkEvidence(args) {
|
|
169
|
+
const evidence = [];
|
|
170
|
+
if (args.branch && args.commitsAhead > 0) {
|
|
171
|
+
evidence.push(`branch ${args.branch} has ${args.commitsAhead} commit(s) ahead of ${args.mainBranch}`);
|
|
172
|
+
}
|
|
173
|
+
if (args.dirtyWorktree) {
|
|
174
|
+
evidence.push("the worktree has uncommitted changes");
|
|
175
|
+
}
|
|
176
|
+
if (evidence.length === 0) {
|
|
177
|
+
evidence.push("physical git evidence exists");
|
|
178
|
+
}
|
|
179
|
+
return evidence;
|
|
180
|
+
}
|
|
132
181
|
function detectWorktreeEvidence(basePath, milestoneId, hasChanges) {
|
|
133
182
|
const wtDir = getWorktreeDir(basePath, milestoneId);
|
|
134
183
|
const wtPath = getAutoWorktreePath(basePath, milestoneId);
|
|
@@ -148,16 +197,7 @@ function detectWorktreeEvidence(basePath, milestoneId, hasChanges) {
|
|
|
148
197
|
};
|
|
149
198
|
}
|
|
150
199
|
function strandedWorkMessage(args) {
|
|
151
|
-
const evidence =
|
|
152
|
-
if (args.branch && args.commitsAhead > 0) {
|
|
153
|
-
evidence.push(`branch ${args.branch} has ${args.commitsAhead} commit(s) ahead of ${args.mainBranch}`);
|
|
154
|
-
}
|
|
155
|
-
if (args.dirtyWorktree) {
|
|
156
|
-
evidence.push("the worktree has uncommitted changes");
|
|
157
|
-
}
|
|
158
|
-
if (evidence.length === 0) {
|
|
159
|
-
evidence.push("physical git evidence exists");
|
|
160
|
-
}
|
|
200
|
+
const evidence = strandedWorkEvidence(args);
|
|
161
201
|
const wtSuffix = args.worktreeDirExists
|
|
162
202
|
? ` Worktree directory at .gsd/worktrees/${args.milestoneId}/ holds live work.`
|
|
163
203
|
: "";
|
|
@@ -168,6 +208,37 @@ function strandedWorkMessage(args) {
|
|
|
168
208
|
wtSuffix +
|
|
169
209
|
` ${recovery} Park or discard explicitly if abandoning.`);
|
|
170
210
|
}
|
|
211
|
+
function formatStrandedWorkRecoveryMessage(action) {
|
|
212
|
+
const recoveryMode = action.recoveryMode === "worktree"
|
|
213
|
+
? "existing worktree"
|
|
214
|
+
: "milestone branch";
|
|
215
|
+
const evidence = strandedWorkEvidence({
|
|
216
|
+
branch: action.branch,
|
|
217
|
+
commitsAhead: action.commitsAhead ?? 0,
|
|
218
|
+
mainBranch: action.mainBranch ?? "main",
|
|
219
|
+
dirtyWorktree: action.dirtyWorktree ?? false,
|
|
220
|
+
});
|
|
221
|
+
const wtSuffix = action.worktreeDirExists
|
|
222
|
+
? ` Worktree directory at .gsd/worktrees/${action.milestoneId}/ holds live work.`
|
|
223
|
+
: "";
|
|
224
|
+
return (`Resuming saved milestone work for ${action.milestoneId}: ${evidence.join("; ")}.` +
|
|
225
|
+
wtSuffix +
|
|
226
|
+
` Adopting the ${recoveryMode} before dispatching new units. Park or discard explicitly if abandoning.`);
|
|
227
|
+
}
|
|
228
|
+
function formatStrandedWorkBlockerMessage(action, activeMilestoneId) {
|
|
229
|
+
const target = action.milestoneId;
|
|
230
|
+
const mode = action.recoveryMode === "worktree" ? "existing worktree" : "milestone branch";
|
|
231
|
+
const intro = activeMilestoneId
|
|
232
|
+
? `Stranded work for ${target} blocks auto-mode before ${activeMilestoneId}.`
|
|
233
|
+
: `Stranded work for ${target} blocks auto-mode, but that milestone is not active in project state.`;
|
|
234
|
+
return [
|
|
235
|
+
intro,
|
|
236
|
+
"Choose one explicit next step:",
|
|
237
|
+
`1. Recover it: run \`/gsd auto ${target}\` to adopt the ${mode}.`,
|
|
238
|
+
`2. Defer it: run \`/gsd park ${target} "reason"\`, then rerun \`/gsd auto\`.`,
|
|
239
|
+
`3. Abandon it: run \`/gsd rethink\` and explicitly discard ${target}.`,
|
|
240
|
+
].join("\n");
|
|
241
|
+
}
|
|
171
242
|
export function auditOrphanedMilestoneBranches(basePath, _isolationMode, gitDeps = {}) {
|
|
172
243
|
const recovered = [];
|
|
173
244
|
const warnings = [];
|
|
@@ -258,6 +329,7 @@ export function auditOrphanedMilestoneBranches(basePath, _isolationMode, gitDeps
|
|
|
258
329
|
kind: "in-progress-stranded-work",
|
|
259
330
|
milestoneId,
|
|
260
331
|
branch,
|
|
332
|
+
mainBranch,
|
|
261
333
|
commitsAhead,
|
|
262
334
|
dirtyWorktree: worktreeEvidence.dirty,
|
|
263
335
|
worktreeDirExists: worktreeEvidence.dirExists,
|
|
@@ -413,6 +485,7 @@ export function auditOrphanedMilestoneBranches(basePath, _isolationMode, gitDeps
|
|
|
413
485
|
pushAction({
|
|
414
486
|
kind: "in-progress-stranded-work",
|
|
415
487
|
milestoneId: m.id,
|
|
488
|
+
mainBranch,
|
|
416
489
|
commitsAhead: 0,
|
|
417
490
|
dirtyWorktree: true,
|
|
418
491
|
worktreeDirExists: worktreeEvidence.dirExists,
|
|
@@ -806,6 +879,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
806
879
|
await openProjectDbIfPresent(base);
|
|
807
880
|
registerAutoWorkerForSession(base);
|
|
808
881
|
reconcileProjectMilestonesFromDisk(base);
|
|
882
|
+
reconcileMergedMilestonesFromJournal(base);
|
|
809
883
|
// Clean stale runtime unit files for completed milestones (#887).
|
|
810
884
|
// DB-authoritative: when DB is available, require DB status to be closed
|
|
811
885
|
// before clearing runtime units. A SUMMARY file alone is no longer
|
|
@@ -840,7 +914,12 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
840
914
|
for (const msg of auditResult.recovered) {
|
|
841
915
|
ctx.ui.notify(`Orphan audit: ${msg}`, "info");
|
|
842
916
|
}
|
|
917
|
+
const deferredStrandedMessages = new Set(auditResult.actions
|
|
918
|
+
.filter(isBlockingStrandedWorkAction)
|
|
919
|
+
.map((action) => action.message));
|
|
843
920
|
for (const msg of auditResult.warnings) {
|
|
921
|
+
if (deferredStrandedMessages.has(msg))
|
|
922
|
+
continue;
|
|
844
923
|
const prefix = msg.startsWith("Stranded work") ? "" : "Orphan audit: ";
|
|
845
924
|
ctx.ui.notify(`${prefix}${msg}`, "warning");
|
|
846
925
|
}
|
|
@@ -900,15 +979,15 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
900
979
|
: strandedRecoveryAction;
|
|
901
980
|
if (blockingStrandedRecoveryAction) {
|
|
902
981
|
if (!state.activeMilestone) {
|
|
903
|
-
ctx.ui.notify(
|
|
982
|
+
ctx.ui.notify(formatStrandedWorkBlockerMessage(blockingStrandedRecoveryAction, null), "error");
|
|
904
983
|
return releaseLockAndReturn();
|
|
905
984
|
}
|
|
906
985
|
if (state.activeMilestone.id !== blockingStrandedRecoveryAction.milestoneId) {
|
|
907
|
-
ctx.ui.notify(
|
|
986
|
+
ctx.ui.notify(formatStrandedWorkBlockerMessage(blockingStrandedRecoveryAction, state.activeMilestone.id), "error");
|
|
908
987
|
return releaseLockAndReturn();
|
|
909
988
|
}
|
|
910
989
|
strandedRecoveryAction = blockingStrandedRecoveryAction;
|
|
911
|
-
ctx.ui.notify(
|
|
990
|
+
ctx.ui.notify(formatStrandedWorkRecoveryMessage(strandedRecoveryAction), "info");
|
|
912
991
|
}
|
|
913
992
|
if (process.env.GSD_HEADLESS === "1" &&
|
|
914
993
|
orphanAuditRecovered &&
|
|
@@ -1293,7 +1372,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
1293
1372
|
if (resolveSkillDiscoveryMode(base) !== "off") {
|
|
1294
1373
|
snapshotSkills();
|
|
1295
1374
|
}
|
|
1296
|
-
ctx
|
|
1375
|
+
setAutoActiveStatus(ctx, s.stepMode ? "next" : "auto");
|
|
1297
1376
|
ctx.ui.setWidget("gsd-health", undefined);
|
|
1298
1377
|
const modeLabel = s.stepMode ? "Step-mode" : "Auto-mode";
|
|
1299
1378
|
const pendingCount = (state.registry ?? []).filter((m) => m.status !== "complete" && m.status !== "parked").length;
|
|
@@ -83,7 +83,7 @@ export function clearInFlightTools() {
|
|
|
83
83
|
* from the tool handler. When these errors occur, retrying the same unit will
|
|
84
84
|
* produce the same failure, so the retry loop must be broken.
|
|
85
85
|
*/
|
|
86
|
-
const TOOL_INVOCATION_ERROR_RE = /Validation failed for tool|Expected ',' or '\}'(?: after property value)?(?: in JSON)?|Unexpected end of JSON|Unexpected token.*in JSON|does not provide an export named|Named export .* not found|Cannot find module|ERR_MODULE_NOT_FOUND|ERR_MODULE_NOT_EXPORTED|ERR_PACKAGE_PATH_NOT_EXPORTED/i;
|
|
86
|
+
const TOOL_INVOCATION_ERROR_RE = /Validation failed for tool|Input validation error|Invalid arguments for tool|MCP error -32602|No such tool available|Expected ',' or '\}'(?: after property value)?(?: in JSON)?|Unexpected end of JSON|Unexpected token.*in JSON|does not provide an export named|Named export .* not found|Cannot find module|ERR_MODULE_NOT_FOUND|ERR_MODULE_NOT_EXPORTED|ERR_PACKAGE_PATH_NOT_EXPORTED/i;
|
|
87
87
|
const DETERMINISTIC_POLICY_ERROR_RE = /(?:^|\b)(?:HARD BLOCK:|Blocked: \/gsd queue is a planning tool|Direct writes to \.gsd\/STATE\.md and \.gsd\/gsd\.db are blocked|This is a mechanical gate)/i;
|
|
88
88
|
/**
|
|
89
89
|
* Returns true if the error message indicates a deterministic invocation or
|
|
@@ -1,56 +1,6 @@
|
|
|
1
1
|
import { parseUnitId } from "./unit-id.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
"browser_click",
|
|
5
|
-
"browser_type",
|
|
6
|
-
"browser_fill_form",
|
|
7
|
-
"browser_click_ref",
|
|
8
|
-
"browser_fill_ref",
|
|
9
|
-
"browser_wait_for",
|
|
10
|
-
"browser_assert",
|
|
11
|
-
"browser_verify",
|
|
12
|
-
"browser_screenshot",
|
|
13
|
-
"browser_snapshot_refs",
|
|
14
|
-
"browser_find",
|
|
15
|
-
"browser_get_console_logs",
|
|
16
|
-
"browser_get_network_logs",
|
|
17
|
-
"browser_evaluate",
|
|
18
|
-
"browser_reload",
|
|
19
|
-
"browser_batch",
|
|
20
|
-
"browser_act",
|
|
21
|
-
];
|
|
22
|
-
export const AUTO_UNIT_SCOPED_TOOLS = {
|
|
23
|
-
"research-milestone": ["gsd_summary_save", "gsd_decision_save"],
|
|
24
|
-
"plan-milestone": ["gsd_plan_milestone", "gsd_decision_save", "gsd_requirement_update"],
|
|
25
|
-
"discuss-milestone": [
|
|
26
|
-
"gsd_summary_save",
|
|
27
|
-
"gsd_decision_save",
|
|
28
|
-
"gsd_requirement_save",
|
|
29
|
-
"gsd_requirement_update",
|
|
30
|
-
"gsd_plan_milestone",
|
|
31
|
-
"gsd_milestone_generate_id",
|
|
32
|
-
],
|
|
33
|
-
"discuss-slice": ["gsd_summary_save", "gsd_decision_save"],
|
|
34
|
-
"validate-milestone": ["gsd_validate_milestone", "gsd_reassess_roadmap", "subagent"],
|
|
35
|
-
"complete-milestone": ["gsd_complete_milestone", "subagent"],
|
|
36
|
-
"research-slice": ["gsd_summary_save", "gsd_decision_save"],
|
|
37
|
-
"plan-slice": ["gsd_plan_slice", "gsd_plan_task", "gsd_decision_save"],
|
|
38
|
-
"refine-slice": ["gsd_plan_slice", "gsd_plan_task", "gsd_decision_save"],
|
|
39
|
-
"replan-slice": ["gsd_replan_slice", "gsd_plan_task", "gsd_decision_save"],
|
|
40
|
-
"complete-slice": ["gsd_slice_complete", "gsd_task_reopen", "gsd_replan_slice", "gsd_decision_save", "gsd_requirement_update", "subagent"],
|
|
41
|
-
"reassess-roadmap": ["gsd_reassess_roadmap"],
|
|
42
|
-
"execute-task": ["gsd_task_complete", "gsd_decision_save"],
|
|
43
|
-
"execute-task-simple": ["gsd_task_complete", "gsd_decision_save"],
|
|
44
|
-
"reactive-execute": ["gsd_task_complete", "gsd_decision_save"],
|
|
45
|
-
"run-uat": ["gsd_summary_save", ...RUN_UAT_BROWSER_TOOL_NAMES],
|
|
46
|
-
"gate-evaluate": ["gsd_save_gate_result"],
|
|
47
|
-
"rewrite-docs": ["gsd_summary_save", "gsd_decision_save"],
|
|
48
|
-
"workflow-preferences": ["gsd_summary_save"],
|
|
49
|
-
"discuss-project": ["gsd_summary_save", "gsd_decision_save", "gsd_requirement_save"],
|
|
50
|
-
"discuss-requirements": ["gsd_requirement_save", "gsd_summary_save"],
|
|
51
|
-
"research-decision": ["gsd_summary_save"],
|
|
52
|
-
"research-project": ["gsd_summary_save", "gsd_decision_save"],
|
|
53
|
-
};
|
|
2
|
+
import { AUTO_UNIT_SCOPED_TOOLS, getForbiddenGsdToolReason, } from "./unit-tool-contracts.js";
|
|
3
|
+
export { AUTO_UNIT_SCOPED_TOOLS, RUN_UAT_BROWSER_TOOL_NAMES, } from "./unit-tool-contracts.js";
|
|
54
4
|
const WORKFLOW_TOOL_ALIASES = {
|
|
55
5
|
gsd_save_decision: "gsd_decision_save",
|
|
56
6
|
gsd_update_requirement: "gsd_requirement_update",
|
|
@@ -87,6 +37,7 @@ const SCOPED_GSD_LIFECYCLE_TOOLS = new Set([
|
|
|
87
37
|
]
|
|
88
38
|
.filter((tool) => tool.startsWith("gsd_"))
|
|
89
39
|
.map(canonicalWorkflowToolName));
|
|
40
|
+
export const GSD_PHASE_SCOPE_DISPLAY_REASON = "This GSD phase only allows its scoped workflow tools.";
|
|
90
41
|
function stripMcpToolPrefix(toolName) {
|
|
91
42
|
if (!toolName.startsWith("mcp__"))
|
|
92
43
|
return toolName;
|
|
@@ -102,11 +53,18 @@ export function isWorkflowAliasTool(toolName) {
|
|
|
102
53
|
}
|
|
103
54
|
function hardBlockReason(unitType, what) {
|
|
104
55
|
return [
|
|
105
|
-
`HARD BLOCK: unit "${unitType}"
|
|
56
|
+
`HARD BLOCK: Tool Contract failure for unit "${unitType}" — ${what}.`,
|
|
106
57
|
"This is a mechanical phase-boundary gate. You MUST NOT proceed, retry the same call,",
|
|
107
58
|
"or route around this block; the orchestrator owns phase transitions.",
|
|
108
59
|
].join(" ");
|
|
109
60
|
}
|
|
61
|
+
function hardBlock(unitType, what) {
|
|
62
|
+
return {
|
|
63
|
+
block: true,
|
|
64
|
+
reason: hardBlockReason(unitType, what),
|
|
65
|
+
displayReason: GSD_PHASE_SCOPE_DISPLAY_REASON,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
110
68
|
function allowedGsdToolsForUnit(unitType) {
|
|
111
69
|
return [...new Set((AUTO_UNIT_SCOPED_TOOLS[unitType] ?? [])
|
|
112
70
|
.filter((tool) => tool.startsWith("gsd_"))
|
|
@@ -142,20 +100,14 @@ function shouldBlockTaskCompletionScope(unitType, unitId, toolName, input) {
|
|
|
142
100
|
actualTask === expected.task) {
|
|
143
101
|
return { block: false };
|
|
144
102
|
}
|
|
145
|
-
return {
|
|
146
|
-
block: true,
|
|
147
|
-
reason: hardBlockReason(unitType, `gsd_task_complete may only complete the active task ${expected.milestone}/${expected.slice}/${expected.task}; requested ${actualMilestone}/${actualSlice}/${actualTask}`),
|
|
148
|
-
};
|
|
103
|
+
return hardBlock(unitType, `gsd_task_complete may only complete the active task ${expected.milestone}/${expected.slice}/${expected.task}; requested ${actualMilestone}/${actualSlice}/${actualTask}`);
|
|
149
104
|
}
|
|
150
105
|
export function shouldBlockAutoUnitToolCall(unitType, toolName, input, unitId) {
|
|
151
106
|
const scopedTools = AUTO_UNIT_SCOPED_TOOLS[unitType];
|
|
152
107
|
if (!scopedTools)
|
|
153
108
|
return { block: false };
|
|
154
109
|
if (isNativeWorkflowTool(toolName)) {
|
|
155
|
-
return
|
|
156
|
-
block: true,
|
|
157
|
-
reason: hardBlockReason(unitType, "native Workflow is not permitted inside a dispatched GSD auto-mode unit"),
|
|
158
|
-
};
|
|
110
|
+
return hardBlock(unitType, "native Workflow is not permitted inside a dispatched GSD auto-mode unit");
|
|
159
111
|
}
|
|
160
112
|
const taskScope = shouldBlockTaskCompletionScope(unitType, unitId, toolName, input);
|
|
161
113
|
if (taskScope.block)
|
|
@@ -166,8 +118,9 @@ export function shouldBlockAutoUnitToolCall(unitType, toolName, input, unitId) {
|
|
|
166
118
|
const allowedTools = allowedGsdToolsForUnit(unitType);
|
|
167
119
|
if (allowedTools.includes(canonicalTool))
|
|
168
120
|
return { block: false };
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
}
|
|
121
|
+
const forbiddenReason = getForbiddenGsdToolReason(unitType, canonicalTool);
|
|
122
|
+
if (forbiddenReason) {
|
|
123
|
+
return hardBlock(unitType, `GSD lifecycle tool "${canonicalTool}" is not permitted; ${forbiddenReason} Fix unit-tool-contracts.ts or the ${unitType} prompt.`);
|
|
124
|
+
}
|
|
125
|
+
return hardBlock(unitType, `GSD lifecycle tool "${canonicalTool}" is not permitted; allowed GSD tools: ${allowedTools.length > 0 ? allowedTools.join(", ") : "(none)"}`);
|
|
173
126
|
}
|
|
@@ -26,6 +26,7 @@ import { MILESTONE_ID_RE } from "./milestone-ids.js";
|
|
|
26
26
|
import { runWorktreePostCreateHook } from "./worktree-post-create-hook.js";
|
|
27
27
|
import { classifyProject } from "./detection.js";
|
|
28
28
|
import { nativeGetCurrentBranch, nativeDetectMainBranch, nativeWorkingTreeStatus, nativeAddAllWithExclusions, nativeCommit, nativeCheckoutBranch, nativeMergeSquash, nativeConflictFiles, nativeAddPaths, nativeRmForce, nativeBranchDelete, nativeBranchForceReset, nativeBranchExists, nativeDiffNumstat, nativeUpdateRef, nativeIsAncestor, nativeMergeAbort, nativeWorktreeList, nativeLsFiles, } from "./native-git-bridge.js";
|
|
29
|
+
import { CLOSEOUT_CONSISTENCY_BLOCKED_REASON, checkCloseoutConsistencyGate, formatCloseoutConsistencyBlock, } from "./closeout-consistency-gate.js";
|
|
29
30
|
import { gsdHome } from "./gsd-home.js";
|
|
30
31
|
import { createWorkspace } from "./workspace.js";
|
|
31
32
|
import { _finalizeProjectionForMergeImpl, _projectRootToWorktreeImpl, _projectWorktreeToRootImpl, } from "./worktree-state-projection.js";
|
|
@@ -1513,17 +1514,29 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
|
|
|
1513
1514
|
// symlink layout) — ATTACHing a WAL-mode file to itself corrupts the
|
|
1514
1515
|
// database (#2823).
|
|
1515
1516
|
if (isDbAvailable()) {
|
|
1517
|
+
const contract = resolveGsdPathContract(worktreeCwd, originalBasePath_);
|
|
1518
|
+
const worktreeDbPath = join(contract.worktreeGsd ?? join(worktreeCwd, ".gsd"), "gsd.db");
|
|
1519
|
+
const mainDbPath = contract.projectDb;
|
|
1516
1520
|
try {
|
|
1517
|
-
const
|
|
1518
|
-
|
|
1519
|
-
|
|
1521
|
+
const activeDbPath = getDbPath();
|
|
1522
|
+
if (activeDbPath && _shouldReconcileWorktreeDb(activeDbPath, mainDbPath)) {
|
|
1523
|
+
closeDatabase();
|
|
1524
|
+
if (!openDatabase(mainDbPath)) {
|
|
1525
|
+
throw new Error(`cannot open project DB at ${mainDbPath}`);
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1520
1528
|
if (_shouldReconcileWorktreeDb(worktreeDbPath, mainDbPath)) {
|
|
1521
1529
|
reconcileWorktreeDb(mainDbPath, worktreeDbPath);
|
|
1522
1530
|
}
|
|
1523
1531
|
}
|
|
1524
1532
|
catch (err) {
|
|
1525
|
-
|
|
1526
|
-
logError("worktree",
|
|
1533
|
+
const message = `DB reconciliation failed before milestone ${milestoneId} merge: ${err instanceof Error ? err.message : String(err)}`;
|
|
1534
|
+
logError("worktree", message);
|
|
1535
|
+
throw new GSDError(GSD_GIT_ERROR, `${message}. Recovery reason: ${CLOSEOUT_CONSISTENCY_BLOCKED_REASON}.`);
|
|
1536
|
+
}
|
|
1537
|
+
const closeoutGate = checkCloseoutConsistencyGate(milestoneId);
|
|
1538
|
+
if (!closeoutGate.ok) {
|
|
1539
|
+
throw new GSDError(GSD_GIT_ERROR, formatCloseoutConsistencyBlock(closeoutGate));
|
|
1527
1540
|
}
|
|
1528
1541
|
}
|
|
1529
1542
|
// 2. Get completed slices for commit message
|
|
@@ -64,7 +64,7 @@ import { initRegistry, convertDispatchRules } from "./rule-registry.js";
|
|
|
64
64
|
import { emitJournalEvent as _emitJournalEvent } from "./journal.js";
|
|
65
65
|
import { isClosedStatus } from "./status-guards.js";
|
|
66
66
|
import { MILESTONE_ID_RE } from "./milestone-ids.js";
|
|
67
|
-
import { updateProgressWidget as _updateProgressWidget, setCompletionProgressWidget, setAutoOutcomeWidget, updateSliceProgressCache, clearSliceProgressCache, unitVerb, } from "./auto-dashboard.js";
|
|
67
|
+
import { updateProgressWidget as _updateProgressWidget, setCompletionProgressWidget, setAutoOutcomeWidget, setAutoActiveStatus, updateSliceProgressCache, clearSliceProgressCache, unitVerb, } from "./auto-dashboard.js";
|
|
68
68
|
import { registerSigtermHandler as _registerSigtermHandler, deregisterSigtermHandler as _deregisterSigtermHandler, } from "./auto-supervisor.js";
|
|
69
69
|
import { isDbAvailable, getMilestone, getMilestoneSlices, getSlice, getTask, refreshOpenDatabaseFromDisk, } from "./gsd-db.js";
|
|
70
70
|
import { markLatestActiveForWorkerCanceled } from "./db/unit-dispatches.js";
|
|
@@ -86,7 +86,7 @@ function makeCmuxEmitters(pi) {
|
|
|
86
86
|
import { startUnitSupervision } from "./auto-timers.js";
|
|
87
87
|
import { runPostUnitVerification } from "./auto-verification.js";
|
|
88
88
|
import { autoCommitUnit, postUnitPreVerification, postUnitPostVerification, } from "./auto-post-unit.js";
|
|
89
|
-
import { bootstrapAutoSession, openProjectDbIfPresent } from "./auto-start.js";
|
|
89
|
+
import { bootstrapAutoSession, openProjectDbIfPresent, reconcileMergedMilestonesFromJournal, } from "./auto-start.js";
|
|
90
90
|
import { initHealthWidget } from "./health-widget.js";
|
|
91
91
|
import { runLegacyAutoLoop, runUokKernelLoop } from "./auto/loop.js";
|
|
92
92
|
import { resolveAgentEnd, resolveAgentEndCancelled, _resetPendingResolve, isSessionSwitchInFlight } from "./auto/resolve.js";
|
|
@@ -1601,6 +1601,20 @@ export function createWiredDispatchAdapter(ctx, pi, dispatchBasePath, session) {
|
|
|
1601
1601
|
}
|
|
1602
1602
|
return null;
|
|
1603
1603
|
}
|
|
1604
|
+
function shouldAdoptActiveMilestone(state, activeSession, activeDispatchBasePath) {
|
|
1605
|
+
const activeMilestoneId = state.activeMilestone?.id;
|
|
1606
|
+
const currentMilestoneId = activeSession?.currentMilestoneId;
|
|
1607
|
+
if (!activeSession || !activeMilestoneId || !currentMilestoneId || activeMilestoneId === currentMilestoneId) {
|
|
1608
|
+
return false;
|
|
1609
|
+
}
|
|
1610
|
+
const scopedWorktreeMilestone = (activeSession.basePath ? detectWorktreeName(activeSession.basePath) : null) ??
|
|
1611
|
+
detectWorktreeName(activeDispatchBasePath);
|
|
1612
|
+
if (scopedWorktreeMilestone && scopedWorktreeMilestone !== activeMilestoneId) {
|
|
1613
|
+
return false;
|
|
1614
|
+
}
|
|
1615
|
+
const currentMilestone = state.registry.find((milestone) => milestone.id === currentMilestoneId);
|
|
1616
|
+
return !!currentMilestone && isClosedStatus(currentMilestone.status);
|
|
1617
|
+
}
|
|
1604
1618
|
return {
|
|
1605
1619
|
async decideNextUnit(input) {
|
|
1606
1620
|
const state = input.stateSnapshot;
|
|
@@ -1609,6 +1623,9 @@ export function createWiredDispatchAdapter(ctx, pi, dispatchBasePath, session) {
|
|
|
1609
1623
|
return null;
|
|
1610
1624
|
const activeSession = input.session ?? session;
|
|
1611
1625
|
const activeDispatchBasePath = activeSession?.basePath || dispatchBasePath;
|
|
1626
|
+
if (activeSession && shouldAdoptActiveMilestone(state, activeSession, activeDispatchBasePath)) {
|
|
1627
|
+
activeSession.currentMilestoneId = active.id;
|
|
1628
|
+
}
|
|
1612
1629
|
const prefs = loadEffectiveGSDPreferences(activeDispatchBasePath)?.preferences;
|
|
1613
1630
|
// Derive session-derived dispatch inputs the same way phases.ts:runDispatch does
|
|
1614
1631
|
// (#5789). Prefer caller-supplied values when present so test harnesses and
|
|
@@ -1757,10 +1774,17 @@ export function createWiredAutoOrchestrationModule(ctx, pi, dispatchBasePath, ru
|
|
|
1757
1774
|
async reconcileBeforeDispatch() {
|
|
1758
1775
|
const activeBasePath = getLiveDispatchBasePath();
|
|
1759
1776
|
const result = await reconcileBeforeDispatch(activeBasePath);
|
|
1760
|
-
|
|
1777
|
+
// Failure-path summaries written by gsd_summary_save create
|
|
1778
|
+
// artifact-db-status-divergence blockers for tasks that are still
|
|
1779
|
+
// pending (gsd_task_complete never ran). These tasks can still be
|
|
1780
|
+
// dispatched and the drift self-heals once they complete successfully.
|
|
1781
|
+
const hardBlockers = result.blockers.filter((b) => !b.includes("has SUMMARY artifact while DB status is") &&
|
|
1782
|
+
!b.includes("has SUMMARY on disk while DB status is") &&
|
|
1783
|
+
!b.includes("has task SUMMARY artifacts but no DB tasks"));
|
|
1784
|
+
if (hardBlockers.length > 0) {
|
|
1761
1785
|
return {
|
|
1762
1786
|
ok: false,
|
|
1763
|
-
reason:
|
|
1787
|
+
reason: hardBlockers[0],
|
|
1764
1788
|
stateSnapshot: result.stateSnapshot,
|
|
1765
1789
|
};
|
|
1766
1790
|
}
|
|
@@ -2369,6 +2393,7 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
|
|
|
2369
2393
|
if (s.currentMilestoneId)
|
|
2370
2394
|
setActiveMilestoneId(base, s.currentMilestoneId);
|
|
2371
2395
|
await openProjectDbIfPresent(base);
|
|
2396
|
+
reconcileMergedMilestonesFromJournal(base);
|
|
2372
2397
|
registerAutoWorkerForSession(s, base);
|
|
2373
2398
|
// Re-register health level notification callback lost across process restart
|
|
2374
2399
|
setLevelChangeCallback((_from, to, summary) => {
|
|
@@ -2396,7 +2421,7 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
|
|
|
2396
2421
|
const loopDeps = buildLoopDeps(pi);
|
|
2397
2422
|
ensureOrchestrationModule(ctx, pi, s.basePath || base);
|
|
2398
2423
|
registerSigtermHandler(lockBase());
|
|
2399
|
-
ctx
|
|
2424
|
+
setAutoActiveStatus(ctx, s.stepMode ? "next" : "auto");
|
|
2400
2425
|
ctx.ui.setWidget("gsd-health", undefined);
|
|
2401
2426
|
ctx.ui.notify(s.stepMode ? "Step-mode resumed." : "Auto-mode resumed.", "info");
|
|
2402
2427
|
restoreHookState(s.basePath);
|
|
@@ -2641,7 +2666,7 @@ export async function dispatchHookUnit(ctx, pi, hookName, triggerUnitType, trigg
|
|
|
2641
2666
|
resetHookState();
|
|
2642
2667
|
await pauseAuto(ctx, pi);
|
|
2643
2668
|
}, hookHardTimeoutMs);
|
|
2644
|
-
ctx
|
|
2669
|
+
setAutoActiveStatus(ctx, s.stepMode ? "next" : "auto");
|
|
2645
2670
|
ctx.ui.notify(`Running post-unit hook: ${hookName}`, "info");
|
|
2646
2671
|
debugLog("dispatchHookUnit", {
|
|
2647
2672
|
phase: "send-message",
|
|
@@ -65,6 +65,9 @@ function readDetails(result) {
|
|
|
65
65
|
}
|
|
66
66
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- result shape varies by tool
|
|
67
67
|
function formatToolErrorText(result, details) {
|
|
68
|
+
if (typeof details?.displayReason === "string" && details.displayReason) {
|
|
69
|
+
return details.displayReason;
|
|
70
|
+
}
|
|
68
71
|
const message = details?.error
|
|
69
72
|
?? result?.content?.find((entry) => entry.type === "text")?.text
|
|
70
73
|
?? "unknown";
|
|
@@ -396,6 +399,88 @@ export function registerDbTools(pi) {
|
|
|
396
399
|
};
|
|
397
400
|
pi.registerTool(summarySaveTool);
|
|
398
401
|
registerAlias(pi, summarySaveTool, "gsd_save_summary", "gsd_summary_save");
|
|
402
|
+
// ─── gsd_uat_result_save ─────────────────────────────────────────────────
|
|
403
|
+
const uatResultSaveExecute = async (_toolCallId, params, _signal, _onUpdate, _ctx) => {
|
|
404
|
+
const { executeUatResultSave } = await loadWorkflowExecutors();
|
|
405
|
+
return executeUatResultSave(params, resolveWorkflowToolBasePath(_ctx, params));
|
|
406
|
+
};
|
|
407
|
+
const uatEvidenceRef = Type.Object({
|
|
408
|
+
kind: StringEnum(["gsd_uat_exec", "gsd_exec", "screenshot", "log", "url", "browser"], { description: "Evidence kind" }),
|
|
409
|
+
ref: Type.String({ description: "Evidence ID, approved .gsd path, or URL" }),
|
|
410
|
+
note: Type.Optional(Type.String({ description: "Short evidence note" })),
|
|
411
|
+
unitType: Type.Optional(Type.String({ description: "Unit that produced the evidence" })),
|
|
412
|
+
tool: Type.Optional(Type.String({ description: "Tool that produced the evidence" })),
|
|
413
|
+
executionId: Type.Optional(Type.String({ description: "Stable execution or artifact id" })),
|
|
414
|
+
});
|
|
415
|
+
const uatCheck = Type.Object({
|
|
416
|
+
id: Type.String({ description: "Stable check ID from the UAT spec" }),
|
|
417
|
+
description: Type.String({ description: "Check description" }),
|
|
418
|
+
mode: StringEnum(["artifact", "runtime", "browser", "human-follow-up"], { description: "Evidence mode" }),
|
|
419
|
+
result: StringEnum(["PASS", "FAIL", "NEEDS-HUMAN"], { description: "Check result" }),
|
|
420
|
+
evidence: Type.Optional(Type.Array(uatEvidenceRef, { description: "Objective evidence references" })),
|
|
421
|
+
notes: Type.Optional(Type.String({ description: "Observed result, failure notes, or human instruction" })),
|
|
422
|
+
nonAutomatable: Type.Optional(Type.Boolean({ description: "True when the check is explicitly non-automatable" })),
|
|
423
|
+
});
|
|
424
|
+
const toolPresentationBlock = Type.Object({
|
|
425
|
+
surface: Type.Optional(StringEnum(["provider-tools", "claude-code-sdk", "mcp", "hybrid"], { description: "Tool presentation surface" })),
|
|
426
|
+
model: Type.Optional(Type.Object({
|
|
427
|
+
provider: Type.Optional(Type.String()),
|
|
428
|
+
api: Type.Optional(Type.String()),
|
|
429
|
+
id: Type.Optional(Type.String()),
|
|
430
|
+
})),
|
|
431
|
+
presentedTools: Type.Optional(Type.Array(Type.String(), { description: "Tool names actually presented to the model" })),
|
|
432
|
+
blockedTools: Type.Optional(Type.Array(Type.Object({
|
|
433
|
+
name: Type.String(),
|
|
434
|
+
reason: Type.String(),
|
|
435
|
+
}), { description: "Tool names blocked from the model with reasons" })),
|
|
436
|
+
aliases: Type.Optional(Type.Array(Type.Object({
|
|
437
|
+
requested: Type.String(),
|
|
438
|
+
canonical: Type.String(),
|
|
439
|
+
}))),
|
|
440
|
+
fallbackToolsUsed: Type.Optional(Type.Array(Type.String())),
|
|
441
|
+
toolPresentationPlanId: Type.Optional(Type.String()),
|
|
442
|
+
notes: Type.Optional(Type.String()),
|
|
443
|
+
});
|
|
444
|
+
const uatResultSaveTool = {
|
|
445
|
+
name: "gsd_uat_result_save",
|
|
446
|
+
label: "Save UAT Result",
|
|
447
|
+
description: "Save a structured UAT result for a slice. Validates evidence, writes the ASSESSMENT artifact, " +
|
|
448
|
+
"records attempt history, and saves the aggregate UAT gate result.",
|
|
449
|
+
promptSnippet: "Save structured UAT checks, evidence, verdict, and tool-presentation proof",
|
|
450
|
+
promptGuidelines: [
|
|
451
|
+
"Call gsd_uat_result_save once after all UAT checks have been executed.",
|
|
452
|
+
"Every PASS or FAIL check must cite objective evidence, preferably a gsd_uat_exec evidence ID.",
|
|
453
|
+
"Include the presented and blocked tool set in presentation so tool timing is auditable.",
|
|
454
|
+
"Do not use raw gsd_summary_save as a substitute for UAT results.",
|
|
455
|
+
],
|
|
456
|
+
parameters: Type.Object({
|
|
457
|
+
milestoneId: Type.Optional(Type.String({ description: "Milestone ID (e.g. M001)" })),
|
|
458
|
+
sliceId: Type.Optional(Type.String({ description: "Slice ID (e.g. S01)" })),
|
|
459
|
+
uatType: Type.Optional(Type.String({ description: "Declared UAT mode" })),
|
|
460
|
+
verdict: Type.Optional(Type.String({ description: "Overall UAT verdict: PASS, FAIL, or PARTIAL" })),
|
|
461
|
+
checks: Type.Optional(Type.Array(uatCheck, { description: "Structured check results" })),
|
|
462
|
+
presentation: Type.Optional(toolPresentationBlock),
|
|
463
|
+
notes: Type.Optional(Type.String({ description: "Overall verdict rationale" })),
|
|
464
|
+
attempt: Type.Optional(Type.String({ description: "Attempt number or auto" })),
|
|
465
|
+
previousAttemptId: Type.Optional(Type.String({ description: "Prior attempt ID, when retrying" })),
|
|
466
|
+
}),
|
|
467
|
+
execute: uatResultSaveExecute,
|
|
468
|
+
renderCall(args, theme) {
|
|
469
|
+
let text = theme.fg("toolTitle", theme.bold("uat_result_save "));
|
|
470
|
+
text += theme.fg("accent", `${args.milestoneId ?? "?"}/${args.sliceId ?? "?"}`);
|
|
471
|
+
if (args.verdict)
|
|
472
|
+
text += theme.fg("dim", ` → ${args.verdict}`);
|
|
473
|
+
return new Text(text, 0, 0);
|
|
474
|
+
},
|
|
475
|
+
renderResult(result, _options, theme) {
|
|
476
|
+
const d = readDetails(result);
|
|
477
|
+
if (result.isError || d?.error) {
|
|
478
|
+
return new Text(theme.fg("error", formatToolErrorText(result, d)), 0, 0);
|
|
479
|
+
}
|
|
480
|
+
return new Text(theme.fg("success", `UAT ${d?.sliceId ?? ""}: ${d?.verdict ?? "saved"}`), 0, 0);
|
|
481
|
+
},
|
|
482
|
+
};
|
|
483
|
+
pi.registerTool(uatResultSaveTool);
|
|
399
484
|
// ─── gsd_milestone_generate_id (formerly gsd_generate_milestone_id) ────
|
|
400
485
|
const milestoneGenerateIdExecute = async (_toolCallId, _params, _signal, _onUpdate, _ctx) => {
|
|
401
486
|
try {
|
|
@@ -709,7 +794,7 @@ export function registerDbTools(pi) {
|
|
|
709
794
|
recommendation: Type.String({ description: "Option id the executor recommends." }),
|
|
710
795
|
recommendationRationale: Type.String({ description: "Why the recommendation — 1–2 sentences." }),
|
|
711
796
|
continueWithDefault: Type.Boolean({
|
|
712
|
-
description: "When true,
|
|
797
|
+
description: "When true, the recommendation is recorded as the default, but auto-mode still pauses until the user resolves via /gsd escalate resolve.",
|
|
713
798
|
}),
|
|
714
799
|
}, { description: "ADR-011 Phase 2: optional escalation payload. Only honored when phases.mid_execution_escalation is true." })),
|
|
715
800
|
verificationEvidence: Type.Optional(Type.Array(Type.Object({
|
|
@@ -750,7 +835,7 @@ export function registerDbTools(pi) {
|
|
|
750
835
|
sliceTitle: Type.String({ description: "Title of the slice" }),
|
|
751
836
|
oneLiner: Type.String({ description: "One-line summary of what the slice accomplished" }),
|
|
752
837
|
narrative: Type.String({ description: "Detailed narrative of what happened across all tasks" }),
|
|
753
|
-
verification: Type.String({ description: "What was verified across all tasks" }),
|
|
838
|
+
verification: Type.Optional(Type.String({ description: "What was verified across all tasks — if omitted, summary records verification as passed without detail." })),
|
|
754
839
|
uatContent: Type.String({ description: "UAT test content (markdown body)" }),
|
|
755
840
|
// ── Enrichment metadata (optional — defaults to empty) ────────────
|
|
756
841
|
deviations: Type.Optional(Type.String({ description: "Deviations from the slice plan, or 'None.'" })),
|
|
@@ -931,7 +1016,7 @@ export function registerDbTools(pi) {
|
|
|
931
1016
|
promptGuidelines: [
|
|
932
1017
|
"Use gsd_validate_milestone when all slices are done and the milestone needs validation before completion.",
|
|
933
1018
|
"Parameters: milestoneId, verdict, remediationRound, successCriteriaChecklist, sliceDeliveryAudit, crossSliceIntegration, requirementCoverage, verificationClasses (optional), verdictRationale, remediationPlan (optional).",
|
|
934
|
-
"If verification classes were planned, verificationClasses must
|
|
1019
|
+
"If verification classes were planned, verificationClasses must be a complete canonical table with one row for every applicable planned class using the exact class names Contract, Integration, Operational, and UAT. Do not submit a partial table.",
|
|
935
1020
|
"Planned verification text marked as none/not required/not applicable/N/A (including suffixed variants such as 'not required - backend-only') is treated as not applicable and does not require a class row.",
|
|
936
1021
|
"If verdict is 'needs-remediation', also provide remediationPlan and use gsd_reassess_roadmap to add remediation slices to the roadmap.",
|
|
937
1022
|
"On success, returns validationPath where VALIDATION.md was written.",
|
|
@@ -944,7 +1029,7 @@ export function registerDbTools(pi) {
|
|
|
944
1029
|
sliceDeliveryAudit: Type.String({ description: "Markdown table auditing each slice's claimed vs delivered output" }),
|
|
945
1030
|
crossSliceIntegration: Type.String({ description: "Markdown describing any cross-slice boundary mismatches" }),
|
|
946
1031
|
requirementCoverage: Type.String({ description: "Markdown describing any unaddressed requirements" }),
|
|
947
|
-
verificationClasses: Type.Optional(Type.String({ description: "
|
|
1032
|
+
verificationClasses: Type.Optional(Type.String({ description: "Complete markdown table describing verification class compliance and gaps; include one canonical row for every applicable planned class (Contract, Integration, Operational, UAT)" })),
|
|
948
1033
|
verdictRationale: Type.String({ description: "Why this verdict was chosen" }),
|
|
949
1034
|
remediationPlan: Type.Optional(Type.String({ description: "Remediation plan (required if verdict is needs-remediation)" })),
|
|
950
1035
|
}),
|