@opengsd/gsd-pi 1.1.1-dev.616a1a1 → 1.1.1-dev.9bb7453
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +3 -2
- package/dist/help-text.js +10 -6
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +495 -0
- package/dist/resources/extensions/browser-tools/engine/selection.js +16 -0
- package/dist/resources/extensions/browser-tools/extension-manifest.json +2 -2
- package/dist/resources/extensions/browser-tools/index.js +57 -9
- package/dist/resources/extensions/browser-tools/package.json +5 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +167 -16
- package/dist/resources/extensions/gsd/auto/orchestrator.js +0 -1
- package/dist/resources/extensions/gsd/auto/phases.js +4 -3
- package/dist/resources/extensions/gsd/auto-dashboard.js +92 -17
- package/dist/resources/extensions/gsd/auto-dispatch.js +44 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +134 -10
- package/dist/resources/extensions/gsd/auto-prompts.js +68 -22
- package/dist/resources/extensions/gsd/auto-recovery.js +4 -4
- package/dist/resources/extensions/gsd/auto-runtime-state.js +3 -0
- package/dist/resources/extensions/gsd/auto-start.js +94 -15
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +1 -1
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +2 -1
- package/dist/resources/extensions/gsd/auto.js +31 -6
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +83 -4
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +43 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +39 -14
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +16 -10
- package/dist/resources/extensions/gsd/browser-evidence.js +29 -2
- package/dist/resources/extensions/gsd/commands/catalog.js +6 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +6 -2
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +9 -5
- package/dist/resources/extensions/gsd/commands-handlers.js +76 -11
- package/dist/resources/extensions/gsd/commands-maintenance.js +172 -2
- package/dist/resources/extensions/gsd/commands-mcp-status.js +109 -60
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +3 -1
- package/dist/resources/extensions/gsd/commands-verdict.js +1 -1
- package/dist/resources/extensions/gsd/config-overlay.js +2 -1
- package/dist/resources/extensions/gsd/dashboard-overlay.js +21 -7
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +8 -0
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +2 -2
- package/dist/resources/extensions/gsd/error-classifier.js +2 -1
- package/dist/resources/extensions/gsd/escalation.js +4 -4
- package/dist/resources/extensions/gsd/exec-sandbox.js +2 -0
- package/dist/resources/extensions/gsd/forensics.js +74 -2
- package/dist/resources/extensions/gsd/gsd-db.js +42 -6
- package/dist/resources/extensions/gsd/guided-flow.js +30 -69
- package/dist/resources/extensions/gsd/mcp-filter.js +3 -0
- package/dist/resources/extensions/gsd/mcp-project-config.js +76 -84
- package/dist/resources/extensions/gsd/memory-store.js +4 -1
- package/dist/resources/extensions/gsd/migration-auto-check.js +2 -2
- package/dist/resources/extensions/gsd/post-unit-hooks.js +9 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +39 -0
- package/dist/resources/extensions/gsd/prompt-loader.js +7 -0
- package/dist/resources/extensions/gsd/prompts/forensics.md +61 -1
- package/dist/resources/extensions/gsd/prompts/gate-evaluate.md +3 -1
- package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +3 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/reactive-execute.md +3 -1
- package/dist/resources/extensions/gsd/prompts/run-uat.md +48 -24
- package/dist/resources/extensions/gsd/prompts/system.md +3 -1
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +3 -3
- package/dist/resources/extensions/gsd/rule-registry.js +428 -52
- package/dist/resources/extensions/gsd/safety/destructive-guard.js +3 -0
- package/dist/resources/extensions/gsd/skill-activation.js +20 -3
- package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +4 -2
- package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +1 -1
- package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +18 -1
- package/dist/resources/extensions/gsd/state-reconciliation/index.js +6 -0
- package/dist/resources/extensions/gsd/state.js +17 -14
- package/dist/resources/extensions/gsd/templates/plan.md +3 -1
- package/dist/resources/extensions/gsd/tool-presentation-plan.js +120 -0
- package/dist/resources/extensions/gsd/tools/complete-slice.js +15 -1
- package/dist/resources/extensions/gsd/tools/complete-task.js +11 -1
- package/dist/resources/extensions/gsd/tools/exec-tool.js +109 -0
- package/dist/resources/extensions/gsd/tools/plan-slice.js +14 -9
- package/dist/resources/extensions/gsd/tools/reopen-milestone.js +2 -2
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +46 -16
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +403 -3
- package/dist/resources/extensions/gsd/unit-context-manifest.js +8 -3
- package/dist/resources/extensions/gsd/validation-block-guard.js +2 -0
- package/dist/resources/extensions/gsd/verdict-parser.js +59 -15
- package/dist/resources/extensions/gsd/verification-gate.js +72 -1
- package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +3 -1
- package/dist/resources/extensions/gsd/workflow-mcp.js +5 -1
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +24 -0
- package/dist/resources/extensions/mcp-client/manager.js +31 -1
- package/dist/resources/extensions/shared/gsd-browser-cli.js +145 -0
- package/dist/rtk.d.ts +7 -1
- package/dist/rtk.js +27 -11
- package/dist/update-check.d.ts +15 -1
- package/dist/update-check.js +87 -12
- package/dist/update-cmd.d.ts +1 -0
- package/dist/update-cmd.js +53 -2
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +6 -6
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +6 -6
- package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/package.json +5 -3
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/dist/workflow.d.ts +14 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js +16 -0
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/dist/agent-session.d.ts +9 -0
- package/packages/gsd-agent-core/dist/agent-session.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/agent-session.js +32 -0
- package/packages/gsd-agent-core/dist/agent-session.js.map +1 -1
- package/packages/gsd-agent-core/dist/index.d.ts +1 -0
- package/packages/gsd-agent-core/dist/index.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/index.js +1 -0
- package/packages/gsd-agent-core/dist/index.js.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-compaction.d.ts +2 -0
- package/packages/gsd-agent-core/dist/session/agent-session-compaction.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-compaction.js +8 -2
- package/packages/gsd-agent-core/dist/session/agent-session-compaction.js.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts +7 -0
- package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-host.js.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.js +69 -1
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.js.map +1 -1
- package/packages/gsd-agent-core/dist/turn-latency.d.ts +47 -0
- package/packages/gsd-agent-core/dist/turn-latency.d.ts.map +1 -0
- package/packages/gsd-agent-core/dist/turn-latency.js +123 -0
- package/packages/gsd-agent-core/dist/turn-latency.js.map +1 -0
- package/packages/gsd-agent-core/package.json +6 -6
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts +21 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js +213 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts +2 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +10 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +92 -31
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +7 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.js +6 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-command-handlers.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.js +2 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js +5 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/remote-questions.d.ts.map +1 -1
- package/packages/mcp-server/dist/remote-questions.js +23 -9
- package/packages/mcp-server/dist/remote-questions.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +84 -2
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +3 -3
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +38 -0
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/agent.d.ts +5 -1
- package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent.js +2 -0
- package/packages/pi-agent-core/dist/agent.js.map +1 -1
- package/packages/pi-agent-core/dist/types.d.ts +3 -0
- package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/types.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/api-registry.d.ts +2 -0
- package/packages/pi-ai/dist/api-registry.d.ts.map +1 -1
- package/packages/pi-ai/dist/api-registry.js +23 -0
- package/packages/pi-ai/dist/api-registry.js.map +1 -1
- package/packages/pi-ai/dist/image-models.generated.d.ts +15 -0
- package/packages/pi-ai/dist/image-models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/image-models.generated.js +15 -0
- package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +406 -17
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +484 -116
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/stream.js +6 -6
- package/packages/pi-ai/dist/stream.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +2 -2
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +11 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/dist/terminal.d.ts +1 -0
- package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
- package/packages/pi-tui/dist/terminal.js +8 -4
- package/packages/pi-tui/dist/terminal.js.map +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +579 -0
- package/src/resources/extensions/browser-tools/engine/selection.ts +19 -0
- package/src/resources/extensions/browser-tools/extension-manifest.json +2 -2
- package/src/resources/extensions/browser-tools/index.ts +60 -9
- package/src/resources/extensions/browser-tools/package.json +5 -1
- package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +35 -0
- package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +33 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +196 -16
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +239 -63
- package/src/resources/extensions/gsd/auto/orchestrator.ts +0 -1
- package/src/resources/extensions/gsd/auto/phases.ts +5 -3
- package/src/resources/extensions/gsd/auto-dashboard.ts +98 -18
- package/src/resources/extensions/gsd/auto-dispatch.ts +53 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +166 -9
- package/src/resources/extensions/gsd/auto-prompts.ts +102 -15
- package/src/resources/extensions/gsd/auto-recovery.ts +4 -4
- package/src/resources/extensions/gsd/auto-runtime-state.ts +4 -0
- package/src/resources/extensions/gsd/auto-start.ts +112 -17
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +1 -1
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +2 -1
- package/src/resources/extensions/gsd/auto.ts +47 -5
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +90 -4
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +51 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +60 -19
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +21 -10
- package/src/resources/extensions/gsd/browser-evidence.ts +26 -2
- package/src/resources/extensions/gsd/commands/catalog.ts +6 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +6 -2
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +9 -5
- package/src/resources/extensions/gsd/commands-handlers.ts +76 -11
- package/src/resources/extensions/gsd/commands-maintenance.ts +197 -2
- package/src/resources/extensions/gsd/commands-mcp-status.ts +136 -58
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +4 -1
- package/src/resources/extensions/gsd/commands-verdict.ts +1 -1
- package/src/resources/extensions/gsd/config-overlay.ts +3 -1
- package/src/resources/extensions/gsd/dashboard-overlay.ts +28 -7
- package/src/resources/extensions/gsd/docs/preferences-reference.md +8 -0
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +2 -2
- package/src/resources/extensions/gsd/error-classifier.ts +2 -1
- package/src/resources/extensions/gsd/escalation.ts +4 -4
- package/src/resources/extensions/gsd/exec-sandbox.ts +4 -0
- package/src/resources/extensions/gsd/forensics.ts +99 -5
- package/src/resources/extensions/gsd/gsd-db.ts +46 -8
- package/src/resources/extensions/gsd/guided-flow.ts +91 -83
- package/src/resources/extensions/gsd/mcp-filter.ts +3 -0
- package/src/resources/extensions/gsd/mcp-project-config.ts +105 -88
- package/src/resources/extensions/gsd/memory-store.ts +4 -1
- package/src/resources/extensions/gsd/migration-auto-check.ts +2 -2
- package/src/resources/extensions/gsd/post-unit-hooks.ts +14 -1
- package/src/resources/extensions/gsd/preferences-types.ts +1 -1
- package/src/resources/extensions/gsd/preferences-validation.ts +36 -0
- package/src/resources/extensions/gsd/prompt-loader.ts +8 -0
- package/src/resources/extensions/gsd/prompts/forensics.md +61 -1
- package/src/resources/extensions/gsd/prompts/gate-evaluate.md +3 -1
- package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +3 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/reactive-execute.md +3 -1
- package/src/resources/extensions/gsd/prompts/run-uat.md +48 -24
- package/src/resources/extensions/gsd/prompts/system.md +3 -1
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +3 -3
- package/src/resources/extensions/gsd/rule-registry.ts +558 -58
- package/src/resources/extensions/gsd/rule-types.ts +2 -0
- package/src/resources/extensions/gsd/safety/destructive-guard.ts +3 -0
- package/src/resources/extensions/gsd/skill-activation.ts +20 -2
- package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +4 -2
- package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +1 -1
- package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +20 -0
- package/src/resources/extensions/gsd/state-reconciliation/index.ts +6 -0
- package/src/resources/extensions/gsd/state-reconciliation/types.ts +1 -0
- package/src/resources/extensions/gsd/state.ts +18 -14
- package/src/resources/extensions/gsd/templates/plan.md +3 -1
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +156 -4
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +123 -0
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +143 -2
- package/src/resources/extensions/gsd/tests/auto-start-project-milestone-reconcile.test.ts +24 -2
- package/src/resources/extensions/gsd/tests/browser-evidence.test.ts +142 -0
- package/src/resources/extensions/gsd/tests/commands-dispatcher-validation-block.test.ts +38 -3
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +6 -2
- package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/deep-planning-mode-dispatch.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +50 -13
- package/src/resources/extensions/gsd/tests/discuss-milestone-structured-questions.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +60 -0
- package/src/resources/extensions/gsd/tests/doctor-runtime-checks.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/escalation.test.ts +16 -27
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/exec-tool.test.ts +69 -0
- package/src/resources/extensions/gsd/tests/forensics-issue-routing.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/forensics-prompt-rendering.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/forensics-tool-scope.test.ts +69 -0
- package/src/resources/extensions/gsd/tests/gsd-rebuild.test.ts +199 -0
- package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +40 -1
- package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +86 -0
- package/src/resources/extensions/gsd/tests/guided-flow.test.ts +12 -9
- package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +66 -10
- package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +13 -6
- package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +100 -0
- package/src/resources/extensions/gsd/tests/mcp-status.test.ts +179 -0
- package/src/resources/extensions/gsd/tests/memory-maintenance.test.ts +39 -8
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/new-milestone-discuss-routing.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +54 -7
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +39 -1
- package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +179 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +53 -1
- package/src/resources/extensions/gsd/tests/prompt-loader-extension-dir.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +18 -1
- package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +7 -8
- package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/rule-registry.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +100 -0
- package/src/resources/extensions/gsd/tests/skill-activation.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +6 -2
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +191 -0
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +84 -10
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +12 -2
- package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/tui-header-lifecycle.test.ts +29 -6
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +29 -6
- package/src/resources/extensions/gsd/tests/validate-milestone-prompt-verification-classes.test.ts +6 -3
- package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +133 -0
- package/src/resources/extensions/gsd/tests/validation-block-guard.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/verification-gate.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp-auto-prep.test.ts +17 -2
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +213 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +25 -0
- package/src/resources/extensions/gsd/tool-presentation-plan.ts +167 -0
- package/src/resources/extensions/gsd/tools/complete-slice.ts +14 -1
- package/src/resources/extensions/gsd/tools/complete-task.ts +20 -2
- package/src/resources/extensions/gsd/tools/exec-tool.ts +130 -0
- package/src/resources/extensions/gsd/tools/plan-slice.ts +14 -9
- package/src/resources/extensions/gsd/tools/reopen-milestone.ts +2 -2
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +46 -15
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +489 -3
- package/src/resources/extensions/gsd/types.ts +69 -5
- package/src/resources/extensions/gsd/unit-context-manifest.ts +14 -5
- package/src/resources/extensions/gsd/validation-block-guard.ts +2 -0
- package/src/resources/extensions/gsd/verdict-parser.ts +54 -13
- package/src/resources/extensions/gsd/verification-gate.ts +87 -1
- package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +2 -1
- package/src/resources/extensions/gsd/workflow-mcp.ts +5 -1
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +26 -0
- package/src/resources/extensions/mcp-client/manager.ts +33 -1
- package/src/resources/extensions/mcp-client/tests/manager.test.ts +35 -0
- package/src/resources/extensions/shared/gsd-browser-cli.ts +172 -0
- /package/dist/web/standalone/.next/static/{L9N5SPFi7f-Ne4u2uXzCe → jBtwT9v1u2lUA3UEOy_ZH}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{L9N5SPFi7f-Ne4u2uXzCe → jBtwT9v1u2lUA3UEOy_ZH}/_ssgManifest.js +0 -0
|
@@ -32,7 +32,7 @@ import { isDbAvailable, getDbPath, refreshOpenDatabaseFromDisk, getTask, getSlic
|
|
|
32
32
|
import { renderPlanCheckboxes, renderRoadmapFromDb } from "./markdown-renderer.js";
|
|
33
33
|
import { parseRoadmap as parseLegacyRoadmap } from "./parsers-legacy.js";
|
|
34
34
|
import { consumeSignal } from "./session-status-io.js";
|
|
35
|
-
import { checkPostUnitHooks, isRetryPending, consumeRetryTrigger, persistHookState, resolveHookArtifactPath, } from "./post-unit-hooks.js";
|
|
35
|
+
import { checkPostUnitHooks, consumeHookFailure, isRetryPending, consumeRetryTrigger, consumeGateBlock, persistHookState, resolveHookArtifactPath, } from "./post-unit-hooks.js";
|
|
36
36
|
import { hasPendingCaptures, loadPendingCaptures, revertExecutorResolvedCaptures } from "./captures.js";
|
|
37
37
|
import { debugLog } from "./debug-logger.js";
|
|
38
38
|
import { runSafely } from "./auto-utils.js";
|
|
@@ -323,6 +323,41 @@ function stripKnownIdPrefix(value, id) {
|
|
|
323
323
|
return raw.slice(id.length + 1).trim() || undefined;
|
|
324
324
|
return raw;
|
|
325
325
|
}
|
|
326
|
+
function parseReactiveBatchTaskIds(unitId) {
|
|
327
|
+
const { task: batchPart } = parseUnitId(unitId);
|
|
328
|
+
if (!batchPart?.startsWith("reactive+"))
|
|
329
|
+
return [];
|
|
330
|
+
const rawIds = batchPart
|
|
331
|
+
.slice("reactive+".length)
|
|
332
|
+
.split(",")
|
|
333
|
+
.map((taskId) => taskId.trim().toUpperCase())
|
|
334
|
+
.filter(Boolean);
|
|
335
|
+
const unique = new Set();
|
|
336
|
+
for (const taskId of rawIds) {
|
|
337
|
+
unique.add(taskId);
|
|
338
|
+
}
|
|
339
|
+
return [...unique];
|
|
340
|
+
}
|
|
341
|
+
function dedupePaths(values) {
|
|
342
|
+
const seen = new Set();
|
|
343
|
+
const result = [];
|
|
344
|
+
for (const value of values) {
|
|
345
|
+
if (!seen.has(value)) {
|
|
346
|
+
seen.add(value);
|
|
347
|
+
result.push(value);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return result;
|
|
351
|
+
}
|
|
352
|
+
function getPlannedKeyFiles(tasks) {
|
|
353
|
+
return dedupePaths(tasks.flatMap((taskRow) => [
|
|
354
|
+
...(taskRow.expected_output ?? []),
|
|
355
|
+
...(taskRow.files ?? []),
|
|
356
|
+
...(taskRow.key_files ?? []),
|
|
357
|
+
]));
|
|
358
|
+
}
|
|
359
|
+
export const _parseReactiveBatchTaskIdsForTest = parseReactiveBatchTaskIds;
|
|
360
|
+
export const _getPlannedKeyFilesForTest = getPlannedKeyFiles;
|
|
326
361
|
function resolveVerificationFailureMarkerPath(unitType, unitId, basePath) {
|
|
327
362
|
const { milestone: mid, slice: sid, task: tid } = parseUnitId(unitId);
|
|
328
363
|
switch (unitType) {
|
|
@@ -402,6 +437,34 @@ async function buildTaskCommitContextForUnit(basePath, unitId) {
|
|
|
402
437
|
issueNumber: ghIssueNumber,
|
|
403
438
|
};
|
|
404
439
|
}
|
|
440
|
+
async function buildReactiveTaskCommitContext(_basePath, unitId) {
|
|
441
|
+
const { milestone: mid, slice: sid } = parseUnitId(unitId);
|
|
442
|
+
if (!mid || !sid || !isDbAvailable())
|
|
443
|
+
return undefined;
|
|
444
|
+
const batchTaskIds = parseReactiveBatchTaskIds(unitId);
|
|
445
|
+
if (batchTaskIds.length === 0)
|
|
446
|
+
return undefined;
|
|
447
|
+
const milestone = getMilestone(mid);
|
|
448
|
+
const slice = getSlice(mid, sid);
|
|
449
|
+
const taskRows = batchTaskIds
|
|
450
|
+
.map((tid) => getTask(mid, sid, tid))
|
|
451
|
+
.filter((taskRow) => taskRow !== null);
|
|
452
|
+
const keyFiles = getPlannedKeyFiles(taskRows);
|
|
453
|
+
if (taskRows.length === 0 || keyFiles.length === 0)
|
|
454
|
+
return undefined;
|
|
455
|
+
const taskLabel = taskRows.map((row) => row.id).join(",");
|
|
456
|
+
return {
|
|
457
|
+
taskId: `${sid}/${taskLabel}`,
|
|
458
|
+
taskDisplayId: "reactive-batch",
|
|
459
|
+
taskTitle: `Reactive batch: ${taskLabel}`,
|
|
460
|
+
milestoneId: mid,
|
|
461
|
+
milestoneTitle: stripKnownIdPrefix(milestone?.title, mid),
|
|
462
|
+
sliceId: sid,
|
|
463
|
+
sliceTitle: stripKnownIdPrefix(slice?.title, sid),
|
|
464
|
+
oneLiner: `Reactive execute for ${taskLabel}`,
|
|
465
|
+
keyFiles,
|
|
466
|
+
};
|
|
467
|
+
}
|
|
405
468
|
async function runPostUnitGitHubSyncIfNeeded(basePath, unit) {
|
|
406
469
|
if (unit.type === "complete-milestone")
|
|
407
470
|
return;
|
|
@@ -761,6 +824,9 @@ export async function autoCommitUnit(basePath, unitType, unitId, ctx) {
|
|
|
761
824
|
if (unitType === "execute-task") {
|
|
762
825
|
taskContext = await buildTaskCommitContextForUnit(basePath, unitId);
|
|
763
826
|
}
|
|
827
|
+
else if (unitType === "reactive-execute") {
|
|
828
|
+
taskContext = await buildReactiveTaskCommitContext(basePath, unitId);
|
|
829
|
+
}
|
|
764
830
|
_resetHasChangesCache();
|
|
765
831
|
if (LIFECYCLE_ONLY_UNITS.has(unitType)) {
|
|
766
832
|
return null;
|
|
@@ -812,6 +878,22 @@ async function runCloseoutGitAction(pctx, unit, opts) {
|
|
|
812
878
|
targetRepositories = getTask(mid, sid, tid)?.target_repositories;
|
|
813
879
|
}
|
|
814
880
|
}
|
|
881
|
+
else if (turnAction === "commit" && unit.type === "reactive-execute") {
|
|
882
|
+
taskContext = await buildReactiveTaskCommitContext(s.basePath, unit.id);
|
|
883
|
+
const { milestone: mid, slice: sid } = parseUnitId(unit.id);
|
|
884
|
+
if (mid && sid && isDbAvailable()) {
|
|
885
|
+
const repositories = new Set();
|
|
886
|
+
for (const tid of parseReactiveBatchTaskIds(unit.id)) {
|
|
887
|
+
const taskRow = getTask(mid, sid, tid);
|
|
888
|
+
for (const repoId of taskRow?.target_repositories ?? []) {
|
|
889
|
+
repositories.add(repoId);
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
if (repositories.size > 0) {
|
|
893
|
+
targetRepositories = [...repositories];
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
}
|
|
815
897
|
// Invalidate the nativeHasChanges cache before auto-commit (#1853).
|
|
816
898
|
// The cache has a 10-second TTL and is keyed by basePath. A stale
|
|
817
899
|
// `false` result causes autoCommit to skip staging entirely.
|
|
@@ -1206,12 +1288,19 @@ export async function postUnitPreVerification(pctx, opts) {
|
|
|
1206
1288
|
if (safetyConfig.enabled) {
|
|
1207
1289
|
const { milestone: sMid, slice: sSid, task: sTid } = parseUnitId(s.currentUnit.id);
|
|
1208
1290
|
// File change validation (execute-task only, after unit execution)
|
|
1209
|
-
if (safetyConfig.file_change_validation && s.currentUnit.type === "execute-task" && sMid && sSid && sTid
|
|
1291
|
+
if (safetyConfig.file_change_validation && s.currentUnit.type === "execute-task" && sMid && sSid && sTid) {
|
|
1210
1292
|
try {
|
|
1211
|
-
const
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1293
|
+
const sliceTaskRows = isDbAvailable()
|
|
1294
|
+
? getSliceTasks(sMid, sSid).filter((t) => isClosedStatus(t.status) || t.id === sTid)
|
|
1295
|
+
: [];
|
|
1296
|
+
if (sliceTaskRows.length > 0) {
|
|
1297
|
+
const expectedOutput = getPlannedKeyFiles(sliceTaskRows.map((taskRow) => ({
|
|
1298
|
+
expected_output: taskRow.expected_output,
|
|
1299
|
+
files: taskRow.files,
|
|
1300
|
+
})));
|
|
1301
|
+
const plannedFiles = getPlannedKeyFiles(sliceTaskRows.map((taskRow) => ({
|
|
1302
|
+
files: taskRow.files,
|
|
1303
|
+
})));
|
|
1215
1304
|
const audit = validateFileChanges(s.basePath, expectedOutput, plannedFiles, safetyConfig.file_change_allowlist);
|
|
1216
1305
|
if (audit && audit.violations.length > 0) {
|
|
1217
1306
|
const warnings = audit.violations.filter(v => v.severity === "warning");
|
|
@@ -1223,6 +1312,23 @@ export async function postUnitPreVerification(pctx, opts) {
|
|
|
1223
1312
|
}
|
|
1224
1313
|
}
|
|
1225
1314
|
}
|
|
1315
|
+
else {
|
|
1316
|
+
const taskRow = getTask(sMid, sSid, sTid);
|
|
1317
|
+
if (taskRow) {
|
|
1318
|
+
const expectedOutput = taskRow.expected_output ?? [];
|
|
1319
|
+
const plannedFiles = taskRow.files ?? [];
|
|
1320
|
+
const audit = validateFileChanges(s.basePath, expectedOutput, plannedFiles, safetyConfig.file_change_allowlist);
|
|
1321
|
+
if (audit && audit.violations.length > 0) {
|
|
1322
|
+
const warnings = audit.violations.filter(v => v.severity === "warning");
|
|
1323
|
+
for (const v of warnings) {
|
|
1324
|
+
logWarning("safety", `file-change: ${v.file} — ${v.reason}`);
|
|
1325
|
+
}
|
|
1326
|
+
if (warnings.length > 0) {
|
|
1327
|
+
ctx.ui.notify(`Safety: ${warnings.length} unexpected file change(s) outside task plan`, "warning");
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1226
1332
|
}
|
|
1227
1333
|
catch (e) {
|
|
1228
1334
|
debugLog("postUnit", { phase: "safety-file-change", error: String(e) });
|
|
@@ -1754,18 +1860,25 @@ export async function postUnitPostVerification(pctx) {
|
|
|
1754
1860
|
// ── Post-unit hooks ──
|
|
1755
1861
|
if (s.currentUnit && !s.stepMode) {
|
|
1756
1862
|
const hookUnit = checkPostUnitHooks(s.currentUnit.type, s.currentUnit.id, s.basePath);
|
|
1863
|
+
persistHookState(s.basePath);
|
|
1757
1864
|
if (hookUnit) {
|
|
1758
1865
|
if (s.currentUnit) {
|
|
1759
1866
|
await closeoutUnit(ctx, s.basePath, s.currentUnit.type, s.currentUnit.id, s.currentUnit.startedAt, buildSnapshotOpts(s.currentUnit.type, s.currentUnit.id));
|
|
1760
1867
|
}
|
|
1761
|
-
persistHookState(s.basePath);
|
|
1762
1868
|
return enqueueSidecar(s, ctx, { kind: "hook", unitType: hookUnit.unitType, unitId: hookUnit.unitId, prompt: hookUnit.prompt, model: hookUnit.model }, { hookName: hookUnit.hookName });
|
|
1763
1869
|
}
|
|
1870
|
+
const hookFailure = consumeHookFailure();
|
|
1871
|
+
if (hookFailure) {
|
|
1872
|
+
ctx.ui.notify(`Post-unit hook ${hookFailure.hookName} failed for ${hookFailure.unitId}: ${hookFailure.reason}. Pausing auto-mode.`, "warning");
|
|
1873
|
+
await pauseAuto(ctx, pi);
|
|
1874
|
+
return "stopped";
|
|
1875
|
+
}
|
|
1764
1876
|
// Check if a hook requested a retry of the trigger unit
|
|
1765
1877
|
if (isRetryPending()) {
|
|
1766
1878
|
const trigger = consumeRetryTrigger();
|
|
1767
1879
|
if (trigger) {
|
|
1768
|
-
|
|
1880
|
+
persistHookState(s.basePath);
|
|
1881
|
+
ctx.ui.notify(`Hook requested retry of ${trigger.unitType} ${trigger.unitId} — resetting trigger unit state.`, "info");
|
|
1769
1882
|
await s.orchestration?.retryActiveUnit({
|
|
1770
1883
|
unitType: trigger.unitType,
|
|
1771
1884
|
unitId: trigger.unitId,
|
|
@@ -1781,8 +1894,8 @@ export async function postUnitPostVerification(pctx) {
|
|
|
1781
1894
|
}
|
|
1782
1895
|
catch (dbErr) {
|
|
1783
1896
|
// DB unavailable — fail explicitly rather than silently reverting to markdown mutation.
|
|
1784
|
-
// Use 'gsd recover' to
|
|
1785
|
-
logError("engine", `retry state-reset failed (DB unavailable): ${dbErr.message}. Run 'gsd recover' to
|
|
1897
|
+
// Use 'gsd recover --confirm' to import markdown into the DB if needed.
|
|
1898
|
+
logError("engine", `retry state-reset failed (DB unavailable): ${dbErr.message}. Run 'gsd recover --confirm' to import markdown into the DB.`);
|
|
1786
1899
|
}
|
|
1787
1900
|
}
|
|
1788
1901
|
// 2. Delete SUMMARY.md for the task
|
|
@@ -1812,6 +1925,17 @@ export async function postUnitPostVerification(pctx) {
|
|
|
1812
1925
|
// Fall through to normal dispatch — deriveState will re-derive the unit
|
|
1813
1926
|
}
|
|
1814
1927
|
}
|
|
1928
|
+
const gateBlock = consumeGateBlock();
|
|
1929
|
+
if (gateBlock) {
|
|
1930
|
+
persistHookState(s.basePath);
|
|
1931
|
+
const verdict = gateBlock.verdict ? ` verdict=${gateBlock.verdict};` : "";
|
|
1932
|
+
const artifact = gateBlock.artifact ? ` artifact=${gateBlock.artifact};` : "";
|
|
1933
|
+
const message = `Post-unit gate "${gateBlock.hookName}" blocked ${gateBlock.triggerUnitType} ${gateBlock.triggerUnitId}:` +
|
|
1934
|
+
`${verdict}${artifact} ${gateBlock.reason}. Run /gsd status to inspect, then /gsd auto after recovery.`;
|
|
1935
|
+
ctx.ui.notify(message, "warning");
|
|
1936
|
+
await pauseAuto(ctx, pi);
|
|
1937
|
+
return "stopped";
|
|
1938
|
+
}
|
|
1815
1939
|
}
|
|
1816
1940
|
// ── Fast-path stop detection (#3487) ──
|
|
1817
1941
|
// Before waiting for triage, check if any PENDING captures contain explicit
|
|
@@ -30,6 +30,7 @@ import { classifyProject } from "./detection.js";
|
|
|
30
30
|
import { hasBrowserRequiredText } from "./browser-evidence.js";
|
|
31
31
|
import { debugLog } from "./debug-logger.js";
|
|
32
32
|
import { buildSkillActivationBlock, buildSkillDiscoveryVars } from "./skill-activation.js";
|
|
33
|
+
import { findMilestoneIds } from "./milestone-ids.js";
|
|
33
34
|
export { buildSkillActivationBlock, buildSkillDiscoveryVars };
|
|
34
35
|
// ─── Preamble Cap ─────────────────────────────────────────────────────────────
|
|
35
36
|
/**
|
|
@@ -1270,7 +1271,7 @@ export async function checkNeedsRunUat(base, mid, state, prefs) {
|
|
|
1270
1271
|
if (hasVerdict(uatContent))
|
|
1271
1272
|
continue;
|
|
1272
1273
|
// Also check the ASSESSMENT file — the run-uat prompt writes the verdict
|
|
1273
|
-
// there (via
|
|
1274
|
+
// there (via gsd_uat_result_save), not into the
|
|
1274
1275
|
// UAT spec file. Without this check the unit re-dispatches indefinitely.
|
|
1275
1276
|
const assessmentFile = resolveSliceFile(base, mid, sid, "ASSESSMENT");
|
|
1276
1277
|
if (assessmentFile) {
|
|
@@ -1325,21 +1326,44 @@ export async function checkNeedsRunUat(base, mid, state, prefs) {
|
|
|
1325
1326
|
}
|
|
1326
1327
|
return null;
|
|
1327
1328
|
}
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
const
|
|
1329
|
+
export async function buildDiscussMilestoneInlinedContext(mid, base) {
|
|
1330
|
+
const inlined = [];
|
|
1331
|
+
const roadmapInline = await inlineFileOptional(resolveMilestoneFile(base, mid, "ROADMAP"), relMilestoneFile(base, mid, "ROADMAP"), "Milestone Roadmap");
|
|
1332
|
+
if (roadmapInline)
|
|
1333
|
+
inlined.push(roadmapInline);
|
|
1334
|
+
const contextInline = await inlineFileOptional(resolveMilestoneFile(base, mid, "CONTEXT"), relMilestoneFile(base, mid, "CONTEXT"), "Milestone Context");
|
|
1335
|
+
if (contextInline)
|
|
1336
|
+
inlined.push(contextInline);
|
|
1337
|
+
const researchInline = await inlineFileOptional(resolveMilestoneFile(base, mid, "RESEARCH"), relMilestoneFile(base, mid, "RESEARCH"), "Milestone Research");
|
|
1338
|
+
if (researchInline)
|
|
1339
|
+
inlined.push(researchInline);
|
|
1340
|
+
const decisionsPath = resolveGsdRootFile(base, "DECISIONS");
|
|
1341
|
+
if (existsSync(decisionsPath)) {
|
|
1342
|
+
const decisionsContent = await loadFile(decisionsPath);
|
|
1343
|
+
if (decisionsContent) {
|
|
1344
|
+
inlined.push(`### Decisions Register\nSource: \`${relGsdRootFile("DECISIONS")}\`\n\n${decisionsContent.trim()}`);
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
const milestoneIds = findMilestoneIds(base);
|
|
1348
|
+
const currentIndex = milestoneIds.indexOf(mid);
|
|
1349
|
+
const priorMilestoneIds = currentIndex >= 0 ? milestoneIds.slice(0, currentIndex) : milestoneIds;
|
|
1350
|
+
for (const priorMid of priorMilestoneIds) {
|
|
1351
|
+
const summaryInline = await inlineFileOptional(resolveMilestoneFile(base, priorMid, "SUMMARY"), relMilestoneFile(base, priorMid, "SUMMARY"), `${priorMid} Prior Milestone Summary`);
|
|
1352
|
+
if (summaryInline)
|
|
1353
|
+
inlined.push(summaryInline);
|
|
1354
|
+
}
|
|
1355
|
+
return inlined.length > 0
|
|
1356
|
+
? `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`
|
|
1357
|
+
: "## Inlined Context\n\n_(no milestone context files found yet — go in blind and ask broad questions)_";
|
|
1358
|
+
}
|
|
1359
|
+
export async function buildDiscussMilestonePrompt(mid, midTitle, base, structuredQuestionsAvailable = "false", { headless = false, commitInstruction = "Do not commit planning artifacts — .gsd/ is managed externally.", fastPathInstruction = "", includeDraftSeed = true, includeContextMode = true, } = {}) {
|
|
1360
|
+
const contextTemplate = inlineTemplate("context", "Context");
|
|
1337
1361
|
if (headless) {
|
|
1338
1362
|
const roadmapPath = resolveMilestoneFile(base, mid, "ROADMAP");
|
|
1339
1363
|
const roadmapContent = roadmapPath ? await loadFile(roadmapPath) : null;
|
|
1340
1364
|
return loadPrompt("discuss-headless", {
|
|
1341
1365
|
seedContext: roadmapContent ?? "",
|
|
1342
|
-
inlinedTemplates:
|
|
1366
|
+
inlinedTemplates: contextTemplate,
|
|
1343
1367
|
workingDirectory: base,
|
|
1344
1368
|
milestoneId: mid,
|
|
1345
1369
|
contextPath: relMilestoneFile(base, mid, "CONTEXT"),
|
|
@@ -1347,24 +1371,28 @@ export async function buildDiscussMilestonePrompt(mid, midTitle, base, structure
|
|
|
1347
1371
|
multiMilestoneCommitInstruction: "Do not commit planning artifacts — .gsd/ is managed externally.",
|
|
1348
1372
|
});
|
|
1349
1373
|
}
|
|
1350
|
-
const
|
|
1374
|
+
const rawInlinedContext = await buildDiscussMilestoneInlinedContext(mid, base);
|
|
1375
|
+
const cappedInlinedContext = capPreamble(rawInlinedContext);
|
|
1376
|
+
const discussTemplates = [cappedInlinedContext, contextTemplate].join("\n\n---\n\n");
|
|
1351
1377
|
const basePrompt = loadPrompt("guided-discuss-milestone", {
|
|
1352
1378
|
workingDirectory: base,
|
|
1353
1379
|
milestoneId: mid,
|
|
1354
1380
|
milestoneTitle: midTitle,
|
|
1355
1381
|
inlinedTemplates: discussTemplates,
|
|
1356
1382
|
structuredQuestionsAvailable,
|
|
1357
|
-
commitInstruction
|
|
1358
|
-
fastPathInstruction
|
|
1383
|
+
commitInstruction,
|
|
1384
|
+
fastPathInstruction,
|
|
1359
1385
|
});
|
|
1360
|
-
const promptWithContextMode =
|
|
1386
|
+
const promptWithContextMode = includeContextMode
|
|
1387
|
+
? prependContextModeToBlock("discuss-milestone", base, basePrompt)
|
|
1388
|
+
: basePrompt;
|
|
1361
1389
|
// If a CONTEXT-DRAFT.md exists, append it as seed material
|
|
1362
1390
|
const draftPath = resolveMilestoneFile(base, mid, "CONTEXT-DRAFT");
|
|
1363
1391
|
const draftContent = draftPath ? await loadFile(draftPath) : null;
|
|
1364
|
-
if (draftContent) {
|
|
1392
|
+
if (includeDraftSeed && draftContent) {
|
|
1365
1393
|
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}`;
|
|
1366
1394
|
}
|
|
1367
|
-
return
|
|
1395
|
+
return promptWithContextMode;
|
|
1368
1396
|
}
|
|
1369
1397
|
/**
|
|
1370
1398
|
* Build a prompt for the workflow-preferences unit type (deep mode).
|
|
@@ -2351,6 +2379,15 @@ export async function buildCompleteSlicePrompt(mid, midTitle, sid, sTitle, base,
|
|
|
2351
2379
|
sliceSummaryPath,
|
|
2352
2380
|
sliceUatPath,
|
|
2353
2381
|
gatesToClose,
|
|
2382
|
+
skillActivation: buildSkillActivationBlock({
|
|
2383
|
+
base,
|
|
2384
|
+
milestoneId: mid,
|
|
2385
|
+
milestoneTitle: midTitle,
|
|
2386
|
+
sliceId: sid,
|
|
2387
|
+
sliceTitle: sTitle,
|
|
2388
|
+
extraContext: [inlinedContext],
|
|
2389
|
+
unitType: "complete-slice",
|
|
2390
|
+
}),
|
|
2354
2391
|
});
|
|
2355
2392
|
}
|
|
2356
2393
|
export async function buildCompleteMilestonePrompt(mid, midTitle, base, level) {
|
|
@@ -2531,17 +2568,26 @@ export async function buildValidateMilestonePrompt(mid, midTitle, base, level) {
|
|
|
2531
2568
|
if (isDbAvailable()) {
|
|
2532
2569
|
const milestone = getMilestone(mid);
|
|
2533
2570
|
if (milestone) {
|
|
2571
|
+
const escapeCell = (value) => value.replace(/[\\|]/g, (char) => `\\${char}`).replace(/\r?\n/g, " ");
|
|
2534
2572
|
const classes = [];
|
|
2535
2573
|
if (milestone.verification_contract)
|
|
2536
|
-
classes.push(
|
|
2574
|
+
classes.push(`| Contract | ${escapeCell(milestone.verification_contract)} |`);
|
|
2537
2575
|
if (milestone.verification_integration)
|
|
2538
|
-
classes.push(
|
|
2576
|
+
classes.push(`| Integration | ${escapeCell(milestone.verification_integration)} |`);
|
|
2539
2577
|
if (milestone.verification_operational)
|
|
2540
|
-
classes.push(
|
|
2578
|
+
classes.push(`| Operational | ${escapeCell(milestone.verification_operational)} |`);
|
|
2541
2579
|
if (milestone.verification_uat)
|
|
2542
|
-
classes.push(
|
|
2580
|
+
classes.push(`| UAT | ${escapeCell(milestone.verification_uat)} |`);
|
|
2543
2581
|
if (classes.length > 0) {
|
|
2544
|
-
const verificationClasses =
|
|
2582
|
+
const verificationClasses = [
|
|
2583
|
+
"### Verification Classes (from planning)",
|
|
2584
|
+
"",
|
|
2585
|
+
"These verification tiers were defined during milestone planning. Every row in this table must appear in `verificationClasses` with the same canonical class name.",
|
|
2586
|
+
"",
|
|
2587
|
+
"| Class | Planned Check |",
|
|
2588
|
+
"| --- | --- |",
|
|
2589
|
+
...classes,
|
|
2590
|
+
].join("\n");
|
|
2545
2591
|
inlined.push(verificationClasses);
|
|
2546
2592
|
trackPromptContext(contextTelemetry, "verification-classes", "inline", verificationClasses);
|
|
2547
2593
|
}
|
|
@@ -802,7 +802,7 @@ export function buildLoopRemediationSteps(unitType, unitId, base) {
|
|
|
802
802
|
return [
|
|
803
803
|
` 1. Run \`gsd undo-task ${mid}/${sid}/${tid}\` to reset the task state`,
|
|
804
804
|
` 2. Resume auto-mode — it will re-execute the task`,
|
|
805
|
-
` 3. If the task keeps failing
|
|
805
|
+
` 3. If the task keeps failing and markdown should repopulate the DB, run \`gsd recover --confirm\``,
|
|
806
806
|
].join("\n");
|
|
807
807
|
}
|
|
808
808
|
case "plan-slice":
|
|
@@ -814,7 +814,7 @@ export function buildLoopRemediationSteps(unitType, unitId, base) {
|
|
|
814
814
|
: relSliceFile(base, mid, sid, "RESEARCH");
|
|
815
815
|
return [
|
|
816
816
|
` 1. Write ${artifactRel} manually (or with the LLM in interactive mode)`,
|
|
817
|
-
` 2. Run \`gsd recover\` to
|
|
817
|
+
` 2. Run \`gsd recover --confirm\` to import the markdown into the DB`,
|
|
818
818
|
` 3. Resume auto-mode`,
|
|
819
819
|
].join("\n");
|
|
820
820
|
}
|
|
@@ -824,7 +824,7 @@ export function buildLoopRemediationSteps(unitType, unitId, base) {
|
|
|
824
824
|
return [
|
|
825
825
|
` 1. Run \`gsd reset-slice ${mid}/${sid}\` to reset the slice and all its tasks`,
|
|
826
826
|
` 2. Resume auto-mode — it will re-execute incomplete tasks and re-complete the slice`,
|
|
827
|
-
` 3. If the slice keeps failing
|
|
827
|
+
` 3. If the slice keeps failing and markdown should repopulate the DB, run \`gsd recover --confirm\``,
|
|
828
828
|
].join("\n");
|
|
829
829
|
}
|
|
830
830
|
case "validate-milestone": {
|
|
@@ -833,7 +833,7 @@ export function buildLoopRemediationSteps(unitType, unitId, base) {
|
|
|
833
833
|
const artifactRel = relMilestoneFile(base, mid, "VALIDATION");
|
|
834
834
|
return [
|
|
835
835
|
` 1. Write ${artifactRel} with verdict: pass`,
|
|
836
|
-
` 2. Run \`gsd recover\` to
|
|
836
|
+
` 2. Run \`gsd recover --confirm\` to import the markdown into the DB`,
|
|
837
837
|
` 3. Resume auto-mode`,
|
|
838
838
|
].join("\n");
|
|
839
839
|
}
|
|
@@ -20,6 +20,9 @@ export function isAutoActive() {
|
|
|
20
20
|
export function isAutoPaused() {
|
|
21
21
|
return autoSession.paused;
|
|
22
22
|
}
|
|
23
|
+
export function isAutoCompletionStopInProgress() {
|
|
24
|
+
return autoSession.completionStopInProgress;
|
|
25
|
+
}
|
|
23
26
|
export function markToolStart(toolCallId, toolName) {
|
|
24
27
|
markTrackedToolStart(toolCallId, autoSession.active, toolName);
|
|
25
28
|
}
|
|
@@ -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
|