@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
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"version": "1.0.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"test": "node --test tests/*.test.mjs"
|
|
7
|
+
"test": "node --import ../gsd/tests/resolve-ts.mjs --experimental-strip-types --test tests/*.test.mjs"
|
|
8
8
|
},
|
|
9
9
|
"pi": {
|
|
10
10
|
"extensions": [
|
|
@@ -12,10 +12,14 @@
|
|
|
12
12
|
]
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
|
+
"@opengsd/gsd-browser": ">=0.1.27",
|
|
15
16
|
"playwright": ">=1.40.0",
|
|
16
17
|
"sharp": ">=0.33.0"
|
|
17
18
|
},
|
|
18
19
|
"peerDependenciesMeta": {
|
|
20
|
+
"@opengsd/gsd-browser": {
|
|
21
|
+
"optional": true
|
|
22
|
+
},
|
|
19
23
|
"playwright": {
|
|
20
24
|
"optional": true
|
|
21
25
|
},
|
|
@@ -15,10 +15,11 @@ import { homedir } from "node:os";
|
|
|
15
15
|
import { createRequire } from "node:module";
|
|
16
16
|
import { dirname, join } from "node:path";
|
|
17
17
|
import { PartialMessageBuilder, ZERO_USAGE, mapUsage } from "./partial-builder.js";
|
|
18
|
-
import { buildWorkflowMcpServers, resolveWorkflowMcpProjectRoot } from "../gsd/workflow-mcp.js";
|
|
19
|
-
import { buildProjectGsdMcpServers } from "../gsd/mcp-project-config.js";
|
|
18
|
+
import { buildWorkflowMcpServers, getRequiredWorkflowToolsForAutoUnit, resolveWorkflowMcpProjectRoot, } from "../gsd/workflow-mcp.js";
|
|
19
|
+
import { buildProjectGsdMcpServers, ensureProjectWorkflowMcpConfig } from "../gsd/mcp-project-config.js";
|
|
20
20
|
import { loadProjectGSDPreferences } from "../gsd/preferences.js";
|
|
21
|
-
import { discoverBrowserMcpServerName, discoverMcpServerNames, discoverWorkflowMcpServerName, computeMcpDisallowedTools } from "../gsd/mcp-filter.js";
|
|
21
|
+
import { discoverBrowserMcpServerName, discoverMcpServers, discoverMcpServerNames, discoverWorkflowMcpServerName, computeMcpDisallowedTools, } from "../gsd/mcp-filter.js";
|
|
22
|
+
import { RUN_UAT_CLAUDE_NATIVE_TOOL_NAMES, RUN_UAT_FORBIDDEN_TOOL_NAMES, RUN_UAT_WORKFLOW_TOOL_NAMES, resolveToolPresentationPlan } from "../gsd/tool-presentation-plan.js";
|
|
22
23
|
import { showInterviewRound } from "../shared/tui.js";
|
|
23
24
|
export function serverToolUseToToolCallLike(block) {
|
|
24
25
|
const argumentsValue = block.input && typeof block.input === "object" && !Array.isArray(block.input)
|
|
@@ -164,6 +165,32 @@ function extractMessageText(msg) {
|
|
|
164
165
|
}
|
|
165
166
|
return "";
|
|
166
167
|
}
|
|
168
|
+
const GSD_PHASE_PATTERNS = [
|
|
169
|
+
["run-uat", /\b(?:UNIT:\s*Run UAT|run-uat)\b/i],
|
|
170
|
+
["complete-milestone", /\b(?:UNIT:\s*Complete Milestone|complete-milestone)\b/i],
|
|
171
|
+
["validate-milestone", /\b(?:UNIT:\s*Validate Milestone|validate-milestone)\b/i],
|
|
172
|
+
["reassess-roadmap", /\b(?:UNIT:\s*Reassess Roadmap|reassess-roadmap)\b/i],
|
|
173
|
+
["complete-slice", /\b(?:UNIT:\s*Complete Slice|complete-slice)\b/i],
|
|
174
|
+
["replan-slice", /\b(?:UNIT:\s*Replan Slice|replan-slice)\b/i],
|
|
175
|
+
["plan-slice", /\b(?:UNIT:\s*Plan Slice|plan-slice|gsd_plan_slice)\b/i],
|
|
176
|
+
["plan-milestone", /\b(?:UNIT:\s*Plan Milestone|plan-milestone|gsd_plan_milestone)\b/i],
|
|
177
|
+
["execute-task", /\b(?:UNIT:\s*Execute Task|execute-task|execute-task-simple|reactive-execute)\b/i],
|
|
178
|
+
["gate-evaluate", /\b(?:UNIT:\s*Gate Evaluate|gate-evaluate|gsd_save_gate_result)\b/i],
|
|
179
|
+
["research-milestone", /\b(?:UNIT:\s*Research Milestone|research-milestone)\b/i],
|
|
180
|
+
["research-slice", /\b(?:UNIT:\s*Research Slice|research-slice)\b/i],
|
|
181
|
+
["discuss-milestone", /\b(?:Discuss milestone|discuss-milestone)\b/i],
|
|
182
|
+
];
|
|
183
|
+
export function inferGsdPhaseFromContext(context) {
|
|
184
|
+
const text = [
|
|
185
|
+
context.systemPrompt ?? "",
|
|
186
|
+
...context.messages.map((message) => extractMessageText(message)),
|
|
187
|
+
].join("\n");
|
|
188
|
+
for (const [phase, pattern] of GSD_PHASE_PATTERNS) {
|
|
189
|
+
if (pattern.test(text))
|
|
190
|
+
return phase;
|
|
191
|
+
}
|
|
192
|
+
return undefined;
|
|
193
|
+
}
|
|
167
194
|
/**
|
|
168
195
|
* Build a full conversational prompt from GSD's context messages.
|
|
169
196
|
*
|
|
@@ -1175,22 +1202,106 @@ function mapThinkingLevelToAnthropicEffort(level, modelId) {
|
|
|
1175
1202
|
return "high";
|
|
1176
1203
|
}
|
|
1177
1204
|
}
|
|
1178
|
-
function
|
|
1205
|
+
function parseAllowedMcpToolName(toolName) {
|
|
1206
|
+
const match = /^mcp__(.+)__(\*|[^*]+)$/.exec(toolName);
|
|
1207
|
+
return match?.[1] && match[2] ? { server: match[1], tool: match[2] } : undefined;
|
|
1208
|
+
}
|
|
1209
|
+
function browserMcpServerNameFromAllowedTools(allowedTools) {
|
|
1179
1210
|
if (!Array.isArray(allowedTools))
|
|
1180
1211
|
return undefined;
|
|
1181
1212
|
for (const toolName of allowedTools) {
|
|
1182
1213
|
if (typeof toolName !== "string")
|
|
1183
1214
|
continue;
|
|
1184
|
-
const
|
|
1185
|
-
if (
|
|
1186
|
-
|
|
1215
|
+
const parsed = parseAllowedMcpToolName(toolName);
|
|
1216
|
+
if (!parsed)
|
|
1217
|
+
continue;
|
|
1218
|
+
if (parsed.server === "gsd-browser" || parsed.tool.startsWith("browser_")) {
|
|
1219
|
+
return parsed.server;
|
|
1220
|
+
}
|
|
1187
1221
|
}
|
|
1188
1222
|
return undefined;
|
|
1189
1223
|
}
|
|
1190
|
-
function
|
|
1224
|
+
function workflowMcpServerNameFromAllowedTools(allowedTools) {
|
|
1191
1225
|
if (!Array.isArray(allowedTools))
|
|
1192
1226
|
return undefined;
|
|
1193
|
-
|
|
1227
|
+
const browserServerName = browserMcpServerNameFromAllowedTools(allowedTools);
|
|
1228
|
+
for (const toolName of allowedTools) {
|
|
1229
|
+
if (typeof toolName !== "string")
|
|
1230
|
+
continue;
|
|
1231
|
+
const parsed = parseAllowedMcpToolName(toolName);
|
|
1232
|
+
if (!parsed || parsed.server === browserServerName || parsed.tool.startsWith("browser_"))
|
|
1233
|
+
continue;
|
|
1234
|
+
return parsed.server;
|
|
1235
|
+
}
|
|
1236
|
+
return undefined;
|
|
1237
|
+
}
|
|
1238
|
+
function isRecord(value) {
|
|
1239
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
1240
|
+
}
|
|
1241
|
+
function isStringRecord(value) {
|
|
1242
|
+
return isRecord(value) && Object.values(value).every((entry) => typeof entry === "string");
|
|
1243
|
+
}
|
|
1244
|
+
function cloneSdkMcpServerConfig(config) {
|
|
1245
|
+
if (!isRecord(config))
|
|
1246
|
+
return undefined;
|
|
1247
|
+
const cloned = {};
|
|
1248
|
+
for (const key of ["type", "command", "cwd", "url"]) {
|
|
1249
|
+
if (typeof config[key] === "string")
|
|
1250
|
+
cloned[key] = config[key];
|
|
1251
|
+
}
|
|
1252
|
+
if (Array.isArray(config.args)) {
|
|
1253
|
+
cloned.args = config.args.filter((arg) => typeof arg === "string");
|
|
1254
|
+
}
|
|
1255
|
+
if (isStringRecord(config.env))
|
|
1256
|
+
cloned.env = { ...config.env };
|
|
1257
|
+
if (isStringRecord(config.headers))
|
|
1258
|
+
cloned.headers = { ...config.headers };
|
|
1259
|
+
if (isRecord(config.oauth))
|
|
1260
|
+
cloned.oauth = { ...config.oauth };
|
|
1261
|
+
return Object.keys(cloned).length > 0 ? cloned : undefined;
|
|
1262
|
+
}
|
|
1263
|
+
function resolveProjectMcpServerConfig(projectRoot, serverName, fallbackServers) {
|
|
1264
|
+
if (!serverName)
|
|
1265
|
+
return undefined;
|
|
1266
|
+
const projectServer = discoverMcpServers(projectRoot).find((server) => server.name === serverName);
|
|
1267
|
+
return cloneSdkMcpServerConfig(projectServer?.config) ?? cloneSdkMcpServerConfig(fallbackServers?.[serverName]);
|
|
1268
|
+
}
|
|
1269
|
+
function resolveProjectMcpServerConfigs(projectRoot, serverNames, fallbackServers) {
|
|
1270
|
+
const resolved = {};
|
|
1271
|
+
for (const serverName of serverNames) {
|
|
1272
|
+
const serverConfig = resolveProjectMcpServerConfig(projectRoot, serverName, fallbackServers);
|
|
1273
|
+
if (serverName && serverConfig)
|
|
1274
|
+
resolved[serverName] = serverConfig;
|
|
1275
|
+
}
|
|
1276
|
+
return Object.keys(resolved).length > 0 ? resolved : undefined;
|
|
1277
|
+
}
|
|
1278
|
+
function resolveExactWorkflowMcpToolsForPhase(gsdPhase, workflowServerName, workflowExplicitlyBlocked) {
|
|
1279
|
+
if (!gsdPhase || !workflowServerName || workflowExplicitlyBlocked)
|
|
1280
|
+
return [];
|
|
1281
|
+
const requiredTools = gsdPhase === "run-uat"
|
|
1282
|
+
? [...RUN_UAT_WORKFLOW_TOOL_NAMES]
|
|
1283
|
+
: getRequiredWorkflowToolsForAutoUnit(gsdPhase);
|
|
1284
|
+
const supportTools = gsdPhase === "run-uat" ? [] : ["gsd_milestone_status"];
|
|
1285
|
+
const requestedToolNames = [...new Set([...requiredTools, ...supportTools])];
|
|
1286
|
+
if (requestedToolNames.length === 0)
|
|
1287
|
+
return [];
|
|
1288
|
+
return resolveToolPresentationPlan({
|
|
1289
|
+
phase: gsdPhase,
|
|
1290
|
+
surface: "claude-code-sdk",
|
|
1291
|
+
workflowMcpServerName: workflowServerName,
|
|
1292
|
+
requestedToolNames,
|
|
1293
|
+
}).presentedToolNames;
|
|
1294
|
+
}
|
|
1295
|
+
export function autoInitClaudeCodeWorkflowMcp(cwd) {
|
|
1296
|
+
const projectRoot = resolveWorkflowMcpProjectRoot(cwd);
|
|
1297
|
+
try {
|
|
1298
|
+
ensureProjectWorkflowMcpConfig(projectRoot);
|
|
1299
|
+
}
|
|
1300
|
+
catch (err) {
|
|
1301
|
+
if (process.env.GSD_DEBUG === "1") {
|
|
1302
|
+
console.warn(`[claude-code] workflow MCP auto-init failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1194
1305
|
}
|
|
1195
1306
|
/**
|
|
1196
1307
|
* Build the options object passed to the Claude Agent SDK's `query()` call.
|
|
@@ -1204,7 +1315,7 @@ function browserMcpServerNameFromAllowedTools(allowedTools) {
|
|
|
1204
1315
|
* behaviour pass `permissionMode: "bypassPermissions"` explicitly.
|
|
1205
1316
|
*/
|
|
1206
1317
|
export function buildSdkOptions(modelId, prompt, overrides, extraOptions = {}) {
|
|
1207
|
-
const { reasoning, cwd, ...sdkExtraOptions } = extraOptions;
|
|
1318
|
+
const { reasoning, cwd, gsdPhase, ...sdkExtraOptions } = extraOptions;
|
|
1208
1319
|
const sdkCwd = typeof cwd === "string" && cwd.trim().length > 0 ? cwd : process.cwd();
|
|
1209
1320
|
// Claude Code runs in the milestone worktree for file/shell work, but workflow MCP
|
|
1210
1321
|
// config (.mcp.json) and server discovery live at the project root.
|
|
@@ -1283,13 +1394,38 @@ export function buildSdkOptions(modelId, prompt, overrides, extraOptions = {}) {
|
|
|
1283
1394
|
const browserMcpTools = !browserExplicitlyBlocked && browserServerName
|
|
1284
1395
|
? [`mcp__${browserServerName}__*`]
|
|
1285
1396
|
: [];
|
|
1286
|
-
const
|
|
1397
|
+
const phaseUsesBrowserMcp = !gsdPhase || gsdPhase === "run-uat";
|
|
1398
|
+
const allowedBrowserMcpTools = phaseUsesBrowserMcp ? browserMcpTools : [];
|
|
1399
|
+
const inlinePhaseMcpServers = gsdPhase
|
|
1400
|
+
? resolveProjectMcpServerConfigs(projectRoot, [
|
|
1401
|
+
workflowExplicitlyBlocked ? undefined : workflowServerName,
|
|
1402
|
+
phaseUsesBrowserMcp && !browserExplicitlyBlocked ? browserServerName : undefined,
|
|
1403
|
+
], defaultMcpServers.servers)
|
|
1404
|
+
: undefined;
|
|
1405
|
+
const sdkMcpServers = inlinePhaseMcpServers ?? filteredMcpServers;
|
|
1406
|
+
const strictMcpConfig = !!inlinePhaseMcpServers;
|
|
1407
|
+
// Strict phase configs inline the exact MCP servers GSD needs. Loading
|
|
1408
|
+
// project/local settings at the same time can duplicate those servers and
|
|
1409
|
+
// leave allowed mcp__... tools with no registered backing tool.
|
|
1410
|
+
const settingSources = strictMcpConfig ? [] : ["project", "local"];
|
|
1411
|
+
const exactWorkflowMcpTools = resolveExactWorkflowMcpToolsForPhase(gsdPhase, workflowServerName, workflowExplicitlyBlocked);
|
|
1412
|
+
const runUatDisallowedTools = gsdPhase === "run-uat" && workflowServerName
|
|
1413
|
+
? [
|
|
1414
|
+
...RUN_UAT_FORBIDDEN_TOOL_NAMES.filter((toolName) => !toolName.startsWith("mcp__")),
|
|
1415
|
+
"WebFetch",
|
|
1416
|
+
"Agent",
|
|
1417
|
+
`mcp__${workflowServerName}__gsd_exec`,
|
|
1418
|
+
`mcp__${workflowServerName}__gsd_summary_save`,
|
|
1419
|
+
`mcp__${workflowServerName}__gsd_save_gate_result`,
|
|
1420
|
+
]
|
|
1421
|
+
: [];
|
|
1287
1422
|
const disallowedTools = [...new Set([
|
|
1288
1423
|
"ToolSearch",
|
|
1289
|
-
...(workflowMcpTools.length > 0 ? ["AskUserQuestion"] : []),
|
|
1424
|
+
...(workflowMcpTools.length > 0 || exactWorkflowMcpTools.length > 0 ? ["AskUserQuestion"] : []),
|
|
1425
|
+
...runUatDisallowedTools,
|
|
1290
1426
|
...extraDisallowedTools,
|
|
1291
1427
|
])];
|
|
1292
|
-
const
|
|
1428
|
+
const standardClaudeTools = [
|
|
1293
1429
|
"Read",
|
|
1294
1430
|
"Write",
|
|
1295
1431
|
"Edit",
|
|
@@ -1299,8 +1435,19 @@ export function buildSdkOptions(modelId, prompt, overrides, extraOptions = {}) {
|
|
|
1299
1435
|
"Agent",
|
|
1300
1436
|
"WebFetch",
|
|
1301
1437
|
"WebSearch",
|
|
1302
|
-
...(workflowMcpTools.length > 0 ? gsdMcpTools : ["AskUserQuestion", ...browserMcpTools]),
|
|
1303
1438
|
];
|
|
1439
|
+
const allowedTools = gsdPhase === "run-uat"
|
|
1440
|
+
? [
|
|
1441
|
+
...RUN_UAT_CLAUDE_NATIVE_TOOL_NAMES,
|
|
1442
|
+
...(exactWorkflowMcpTools.length > 0 ? exactWorkflowMcpTools : []),
|
|
1443
|
+
...allowedBrowserMcpTools,
|
|
1444
|
+
]
|
|
1445
|
+
: [
|
|
1446
|
+
...standardClaudeTools,
|
|
1447
|
+
...exactWorkflowMcpTools,
|
|
1448
|
+
...(workflowMcpTools.length > 0 ? workflowMcpTools : ["AskUserQuestion"]),
|
|
1449
|
+
...allowedBrowserMcpTools,
|
|
1450
|
+
];
|
|
1304
1451
|
const supportsAdaptive = modelSupportsAdaptiveThinking(modelId);
|
|
1305
1452
|
const effort = reasoning && supportsAdaptive
|
|
1306
1453
|
? mapThinkingLevelToAnthropicEffort(reasoning, modelId)
|
|
@@ -1321,11 +1468,12 @@ export function buildSdkOptions(modelId, prompt, overrides, extraOptions = {}) {
|
|
|
1321
1468
|
cwd: sdkCwd,
|
|
1322
1469
|
permissionMode,
|
|
1323
1470
|
allowDangerouslySkipPermissions: permissionMode === "bypassPermissions",
|
|
1324
|
-
settingSources
|
|
1471
|
+
settingSources,
|
|
1325
1472
|
systemPrompt: { type: "preset", preset: "claude_code" },
|
|
1326
1473
|
disallowedTools,
|
|
1327
1474
|
...(allowedTools.length > 0 ? { allowedTools } : {}),
|
|
1328
|
-
...(
|
|
1475
|
+
...(sdkMcpServers ? { mcpServers: sdkMcpServers } : {}),
|
|
1476
|
+
...(strictMcpConfig ? { strictMcpConfig: true } : {}),
|
|
1329
1477
|
betas: (modelId.includes("sonnet")
|
|
1330
1478
|
|| modelId.includes("opus-4-7")
|
|
1331
1479
|
|| modelId.includes("opus-4.7")
|
|
@@ -1599,6 +1747,8 @@ async function pumpSdkMessages(model, context, options, stream) {
|
|
|
1599
1747
|
const onExternalToolCall = options?.onExternalToolCall;
|
|
1600
1748
|
const onExternalToolResult = options?.onExternalToolResult;
|
|
1601
1749
|
const cwd = resolveClaudeCodeCwd(options);
|
|
1750
|
+
autoInitClaudeCodeWorkflowMcp(cwd);
|
|
1751
|
+
const gsdPhase = inferGsdPhaseFromContext(context);
|
|
1602
1752
|
const canUseToolHandler = createClaudeCodeCanUseToolHandler(uiContext);
|
|
1603
1753
|
// When no UI is available (headless / auto-mode), auto-approve all
|
|
1604
1754
|
// tool requests. This replaces the old bypassPermissions workaround.
|
|
@@ -1606,6 +1756,7 @@ async function pumpSdkMessages(model, context, options, stream) {
|
|
|
1606
1756
|
?? (async (_toolName, _input, opts) => ({ behavior: "allow", toolUseID: opts.toolUseID }));
|
|
1607
1757
|
const sdkOpts = buildSdkOptions(modelId, "", { permissionMode }, {
|
|
1608
1758
|
cwd,
|
|
1759
|
+
gsdPhase,
|
|
1609
1760
|
reasoning: options?.reasoning,
|
|
1610
1761
|
canUseTool: canUseToolFallback,
|
|
1611
1762
|
...(uiContext
|
|
@@ -256,7 +256,6 @@ export class AutoOrchestrator {
|
|
|
256
256
|
this.status.activeUnit = { unitType: decision.unitType, unitId: decision.unitId };
|
|
257
257
|
this.status.phase = "running";
|
|
258
258
|
this.lastAdvanceKey = nextKey;
|
|
259
|
-
this.lastFinalizedUnitKey = null;
|
|
260
259
|
this.bumpTransition();
|
|
261
260
|
await this.deps.runtime.journalTransition({
|
|
262
261
|
name: "advance",
|
|
@@ -51,13 +51,13 @@ import { resolveManifest } from "../unit-context-manifest.js";
|
|
|
51
51
|
import { createWorktreeSafetyModule } from "../worktree-safety.js";
|
|
52
52
|
import { isSuspiciousGhostCompletion } from "../auto-unit-closeout.js";
|
|
53
53
|
import { decideVerificationRetry, verificationRetryKey } from "./verification-retry-policy.js";
|
|
54
|
-
import { buildPhaseHandoffOutcome, setAutoOutcomeWidget } from "../auto-dashboard.js";
|
|
54
|
+
import { buildPhaseHandoffOutcome, setAutoActiveStatus, setAutoOutcomeWidget } from "../auto-dashboard.js";
|
|
55
55
|
import { getConsecutiveDispatchBlocker } from "../dispatch-guard.js";
|
|
56
56
|
import { captureRootDirtySnapshot, detectRootWriteLeak, formatRootWriteLeakMessage, } from "../root-write-leak-guard.js";
|
|
57
57
|
import { classifyError, isTransient } from "../error-classifier.js";
|
|
58
58
|
export const STUCK_WINDOW_SIZE = 6;
|
|
59
59
|
const STUCK_RECOVERY_ATTEMPTS_KEY = "stuck_recovery_attempts";
|
|
60
|
-
const ZERO_TOOL_PROVIDER_ERROR_PREFIX_RE = /^(?:api error(?::|$|\s*\()|provider error(?::|$|\s*\()|request failed\b|(?:http\s*)?(?:429|500|502|503)\b|\b(?:econnreset|etimedout|econnrefused|epipe)\b|socket hang up\b|fetch failed\b|(?:network|connection|server) error(?::|$)|connection (?:reset|refused)(?::|$|\s+by\b)|dns\b.*(?:fail|error|timeout)|unexpected eof\b|stream idle timeout\b|partial response received\b|stream_exhausted\b|terminated(?::|$)|(?:connection|stream|request)\b.{0,40}\bterminated\b|other side closed\b|rate.?limit(?:ed| exceeded| reached| error)|too many requests\b|you(?:'ve| have) hit your limit\b|
|
|
60
|
+
const ZERO_TOOL_PROVIDER_ERROR_PREFIX_RE = /^(?:api error(?::|$|\s*\()|provider error(?::|$|\s*\()|request failed\b|(?:http\s*)?(?:429|500|502|503)\b|\b(?:econnreset|etimedout|econnrefused|epipe)\b|socket hang up\b|fetch failed\b|(?:network|connection|server) error(?::|$)|connection (?:reset|refused)(?::|$|\s+by\b)|dns\b.*(?:fail|error|timeout)|unexpected eof\b|stream idle timeout\b|partial response received\b|stream_exhausted\b|terminated(?::|$)|(?:connection|stream|request)\b.{0,40}\bterminated\b|other side closed\b|rate.?limit(?:ed| exceeded| reached| error)|too many requests\b|you(?:'ve| have) (?:hit|reached) your (?:\w+ )?limit\b|.*\b(?:usage|session|weekly|daily|monthly|quota) limit\b|limit\b.{0,40}\bresets?\b|out of extra usage\b|service.?unavailable\b|internal(?: server)? error(?::|$)|internal(?:[_-]server)?[_-]error\b|server[_-]error\b|(?:provider|server|api|model|codex|claude|openai|anthropic|gemini)\b.{0,80}\boverloaded\b|overloaded\b.{0,80}\b(?:provider|server|api|model)\b|context (?:window|length) exceed|context window exceed)/i;
|
|
61
61
|
const ZERO_TOOL_PROVIDER_ERROR_SIGNAL_RE = /(?:\b(?:http|status(?: code)?|code|error:)\s*(?:429|500|502|503)\b|\b(?:api|provider) error\s*[:(]?\s*(?:429|500|502|503)\b|\b(?:typeerror|error):\s*(?:fetch failed\b|socket hang up\b|terminated(?::|$)|connection (?:reset|refused)(?::|$|\s+by\b)|(?:network|connection|server) error(?::|$)|stream idle timeout\b|partial response received\b|unexpected eof\b)|\b(?:server_error|api_error|stream_exhausted(?:_without_result)?)\b|\b(?:econnreset|etimedout|econnrefused|epipe)\b|context (?:window|length) exceed|context window exceed)/i;
|
|
62
62
|
function classifyZeroToolProviderMessage(message) {
|
|
63
63
|
const firstLine = message.trim().split(/\r?\n/, 1)[0]?.trim() ?? "";
|
|
@@ -67,6 +67,7 @@ function classifyZeroToolProviderMessage(message) {
|
|
|
67
67
|
return null;
|
|
68
68
|
return classifyError(firstLine);
|
|
69
69
|
}
|
|
70
|
+
export const _classifyZeroToolProviderMessageForTest = classifyZeroToolProviderMessage;
|
|
70
71
|
export function resolveDispatchRecoveryAttempts(unitRecoveryCount, unitType, unitId) {
|
|
71
72
|
return (unitRecoveryCount.get(`${unitType}/${unitId}`) ?? 0) > 0
|
|
72
73
|
? 0
|
|
@@ -1582,7 +1583,7 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
1582
1583
|
const dispatchKey = `${unitType}/${unitId}`;
|
|
1583
1584
|
const nextDispatchCount = (s.unitDispatchCount.get(dispatchKey) ?? 0) + 1;
|
|
1584
1585
|
// Status bar (widget + preconditions deferred until after model selection — see #2899)
|
|
1585
|
-
ctx
|
|
1586
|
+
setAutoActiveStatus(ctx, s.stepMode ? "next" : "auto");
|
|
1586
1587
|
if (mid)
|
|
1587
1588
|
deps.updateSliceProgressCache(s.basePath, mid, state.activeSlice?.id);
|
|
1588
1589
|
// ── Safety harness: reset evidence + create checkpoint ──
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// gsd-pi + src/resources/extensions/gsd/auto-dashboard.ts - Auto-mode progress widget rendering and dashboard helpers.
|
|
2
2
|
import { getActiveHook } from "./post-unit-hooks.js";
|
|
3
|
-
import { getLedger } from "./metrics.js";
|
|
3
|
+
import { getLedger, getProjectTotals } from "./metrics.js";
|
|
4
4
|
import { getErrorMessage } from "./error-utils.js";
|
|
5
5
|
import { nativeIsRepo } from "./native-git-bridge.js";
|
|
6
6
|
import { isDbAvailable, getMilestoneSlices, getSliceTasks } from "./gsd-db.js";
|
|
@@ -196,6 +196,39 @@ export function formatRuntimeHealthSignal(record, now = Date.now()) {
|
|
|
196
196
|
export function shouldRenderRoadmapProgress(progress) {
|
|
197
197
|
return !!progress && progress.total > 0;
|
|
198
198
|
}
|
|
199
|
+
function widgetGridLabel(theme, text, color = "borderAccent") {
|
|
200
|
+
return theme.fg(color, theme.bold(text.toUpperCase()));
|
|
201
|
+
}
|
|
202
|
+
function widgetGridColumn(content, width) {
|
|
203
|
+
return padRightVisible(truncateToWidth(content, width, "…"), width);
|
|
204
|
+
}
|
|
205
|
+
function widgetGridColumns(theme, width, parts) {
|
|
206
|
+
if (parts.length === 0)
|
|
207
|
+
return "";
|
|
208
|
+
const gap = theme.fg("dim", " │ ");
|
|
209
|
+
const gapWidth = visibleWidth(gap) * (parts.length - 1);
|
|
210
|
+
const available = Math.max(parts.length * 8, width - gapWidth);
|
|
211
|
+
const base = Math.floor(available / parts.length);
|
|
212
|
+
let remaining = available - base * parts.length;
|
|
213
|
+
const columns = parts.map((part) => {
|
|
214
|
+
const columnWidth = base + (remaining > 0 ? 1 : 0);
|
|
215
|
+
remaining--;
|
|
216
|
+
return widgetGridColumn(part, columnWidth);
|
|
217
|
+
});
|
|
218
|
+
return truncateToWidth(columns.join(gap), width, "…");
|
|
219
|
+
}
|
|
220
|
+
function formatSmallWidgetSpend() {
|
|
221
|
+
const ledger = getLedger();
|
|
222
|
+
if (!ledger || ledger.units.length === 0)
|
|
223
|
+
return "--";
|
|
224
|
+
const totals = getProjectTotals(ledger.units);
|
|
225
|
+
const parts = [];
|
|
226
|
+
if (totals.tokens.total > 0)
|
|
227
|
+
parts.push(formatWidgetTokens(totals.tokens.total));
|
|
228
|
+
if (totals.cost > 0)
|
|
229
|
+
parts.push(`$${totals.cost.toFixed(2)}`);
|
|
230
|
+
return parts.length > 0 ? parts.join(" · ") : "--";
|
|
231
|
+
}
|
|
199
232
|
// ─── ETA Estimation ──────────────────────────────────────────────────────────
|
|
200
233
|
/**
|
|
201
234
|
* Estimate remaining time based on average unit duration from the metrics ledger.
|
|
@@ -369,8 +402,9 @@ export const hideFooter = (_tui, theme, footerData) => ({
|
|
|
369
402
|
invalidate() { },
|
|
370
403
|
dispose() { },
|
|
371
404
|
});
|
|
405
|
+
export const DEFAULT_WIDGET_MODE = "small";
|
|
372
406
|
const WIDGET_MODES = ["full", "small", "min", "off"];
|
|
373
|
-
let widgetMode =
|
|
407
|
+
let widgetMode = DEFAULT_WIDGET_MODE;
|
|
374
408
|
let widgetModeInitialized = false;
|
|
375
409
|
let widgetModePreferencePath = null;
|
|
376
410
|
function safeReadTextFile(path) {
|
|
@@ -473,10 +507,19 @@ export function getWidgetMode(projectPath, globalPath) {
|
|
|
473
507
|
}
|
|
474
508
|
/** Test-only reset for widget mode caching. */
|
|
475
509
|
export function _resetWidgetModeForTests() {
|
|
476
|
-
widgetMode =
|
|
510
|
+
widgetMode = DEFAULT_WIDGET_MODE;
|
|
477
511
|
widgetModeInitialized = false;
|
|
478
512
|
widgetModePreferencePath = null;
|
|
479
513
|
}
|
|
514
|
+
function clearAutoOutcomeWidget(ctx) {
|
|
515
|
+
if (!ctx.hasUI)
|
|
516
|
+
return;
|
|
517
|
+
ctx.ui.setWidget("gsd-outcome", undefined);
|
|
518
|
+
}
|
|
519
|
+
export function setAutoActiveStatus(ctx, status) {
|
|
520
|
+
ctx.ui.setStatus("gsd-auto", status);
|
|
521
|
+
clearAutoOutcomeWidget(ctx);
|
|
522
|
+
}
|
|
480
523
|
export function updateProgressWidget(ctx, unitType, unitId, state, accessors, tierBadge) {
|
|
481
524
|
if (!ctx.hasUI)
|
|
482
525
|
return;
|
|
@@ -495,7 +538,7 @@ export function updateProgressWidget(ctx, unitType, unitId, state, accessors, ti
|
|
|
495
538
|
ctx.ui.setStatus("gsd-step", undefined);
|
|
496
539
|
}
|
|
497
540
|
if (!accessors.isSessionSwitching()) {
|
|
498
|
-
ctx
|
|
541
|
+
clearAutoOutcomeWidget(ctx);
|
|
499
542
|
}
|
|
500
543
|
const verb = unitVerb(unitType);
|
|
501
544
|
const phaseLabel = unitPhaseLabel(unitType);
|
|
@@ -548,6 +591,7 @@ export function updateProgressWidget(ctx, unitType, unitId, state, accessors, ti
|
|
|
548
591
|
logWarning("dashboard", `DB status update failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
549
592
|
}
|
|
550
593
|
}, 15_000);
|
|
594
|
+
progressRefreshTimer.unref?.();
|
|
551
595
|
return {
|
|
552
596
|
render(width) {
|
|
553
597
|
if (cachedLines && cachedWidth === width)
|
|
@@ -631,26 +675,57 @@ export function updateProgressWidget(ctx, unitType, unitId, state, accessors, ti
|
|
|
631
675
|
cachedWidth = width;
|
|
632
676
|
return lines;
|
|
633
677
|
}
|
|
634
|
-
// ── Mode: small —
|
|
678
|
+
// ── Mode: small — dense horizontal grid ───────────────────────
|
|
635
679
|
if (widgetMode === "small") {
|
|
636
|
-
lines.
|
|
637
|
-
|
|
638
|
-
const target = task ? `${task.id}: ${task.title}` : unitId;
|
|
639
|
-
const actionLeft = `${pad}${theme.fg("accent", "▸")} ${theme.fg("accent", verb)} ${theme.fg("text", target)}`;
|
|
640
|
-
lines.push(rightAlign(actionLeft, theme.fg("dim", phaseLabel), width));
|
|
641
|
-
// Progress bar
|
|
680
|
+
lines.length = 0;
|
|
681
|
+
lines.push(...ui.bar());
|
|
642
682
|
const roadmapSlices = mid ? getRoadmapSlicesSync() : null;
|
|
683
|
+
const unitLabel = unitId || [mid?.id, slice?.id, task?.id].filter(Boolean).join("/");
|
|
684
|
+
const statusParts = [
|
|
685
|
+
spinner,
|
|
686
|
+
theme.fg("success", modeTag),
|
|
687
|
+
theme.fg(stateColor, activeState),
|
|
688
|
+
];
|
|
689
|
+
if (runtimeSignal?.summary) {
|
|
690
|
+
statusParts.push(theme.fg(healthColor, healthSummary));
|
|
691
|
+
}
|
|
692
|
+
else if (healthLevel !== "green") {
|
|
693
|
+
statusParts.push(`${theme.fg(healthColor, healthIcon)} ${theme.fg(healthColor, healthSummary)}`);
|
|
694
|
+
}
|
|
695
|
+
const timeValue = [elapsed, etaShort].filter(Boolean).join(" · ") || "--";
|
|
696
|
+
const rowOne = widgetGridColumns(theme, width, [
|
|
697
|
+
`${widgetGridLabel(theme, "status", "border")} ${statusParts.join(" ")}`,
|
|
698
|
+
`${widgetGridLabel(theme, "unit")} ${theme.fg("text", unitLabel || "--")}`,
|
|
699
|
+
`${widgetGridLabel(theme, "spend", "border")} ${theme.fg("dim", formatSmallWidgetSpend())}`,
|
|
700
|
+
`${widgetGridLabel(theme, "time")} ${theme.fg("dim", timeValue)}`,
|
|
701
|
+
]);
|
|
702
|
+
const target = task
|
|
703
|
+
? `${task.id}: ${task.title}`
|
|
704
|
+
: slice
|
|
705
|
+
? `${slice.id}: ${slice.title}`
|
|
706
|
+
: unitId;
|
|
707
|
+
let taskValue = task?.id ?? "--";
|
|
708
|
+
let sliceValue = slice?.id ?? "--";
|
|
643
709
|
if (shouldRenderRoadmapProgress(roadmapSlices)) {
|
|
644
710
|
const { done, total, activeSliceTasks } = roadmapSlices;
|
|
645
|
-
const barWidth = Math.max(
|
|
711
|
+
const barWidth = Math.max(4, Math.min(14, Math.floor(width * 0.12)));
|
|
646
712
|
const bar = renderProgressBar(theme, done, total, barWidth);
|
|
647
|
-
|
|
713
|
+
sliceValue = `${bar} ${theme.fg("text", `${done}/${total}`)}`;
|
|
648
714
|
if (activeSliceTasks && activeSliceTasks.total > 0) {
|
|
649
|
-
const
|
|
650
|
-
|
|
715
|
+
const taskNum = isHook
|
|
716
|
+
? Math.max(activeSliceTasks.done, 1)
|
|
717
|
+
: Math.min(activeSliceTasks.done + 1, activeSliceTasks.total);
|
|
718
|
+
taskValue = `${theme.fg("accent", `${taskNum}`)}${theme.fg("dim", `/${activeSliceTasks.total}`)}`;
|
|
651
719
|
}
|
|
652
|
-
lines.push(`${pad}${bar} ${meta}`);
|
|
653
720
|
}
|
|
721
|
+
const rowTwo = widgetGridColumns(theme, width, [
|
|
722
|
+
`${widgetGridLabel(theme, "phase", "border")} ${theme.fg("dim", unitType)}`,
|
|
723
|
+
`${widgetGridLabel(theme, "work")} ${theme.fg("text", target || "--")}`,
|
|
724
|
+
`${widgetGridLabel(theme, "task", "border")} ${taskValue}`,
|
|
725
|
+
`${widgetGridLabel(theme, "slice")} ${sliceValue}`,
|
|
726
|
+
]);
|
|
727
|
+
lines.push(rowOne);
|
|
728
|
+
lines.push(rowTwo);
|
|
654
729
|
lines.push(...ui.bar());
|
|
655
730
|
cachedLines = lines;
|
|
656
731
|
cachedWidth = width;
|
|
@@ -789,7 +864,7 @@ export function setCompletionProgressWidget(ctx, snapshot) {
|
|
|
789
864
|
if (!ctx.hasUI)
|
|
790
865
|
return;
|
|
791
866
|
const widgetKey = "gsd-progress";
|
|
792
|
-
ctx
|
|
867
|
+
clearAutoOutcomeWidget(ctx);
|
|
793
868
|
if (typeof ctx.ui?.setHeader === "function") {
|
|
794
869
|
ctx.ui.setHeader(() => ({
|
|
795
870
|
render() { return []; },
|
|
@@ -30,10 +30,12 @@ import { nativeHasChanges, nativeIsRepo, _resetHasChangesCache } from "./native-
|
|
|
30
30
|
import { debugLog, isDebugEnabled } from "./debug-logger.js";
|
|
31
31
|
import { resolveCanonicalMilestoneRoot } from "./worktree-manager.js";
|
|
32
32
|
import { resolveWorktreeProjectRoot } from "./worktree-root.js";
|
|
33
|
+
import { detectWorktreeName } from "./worktree.js";
|
|
33
34
|
import { probeGitConflictState } from "./git-conflict-state.js";
|
|
34
35
|
import { runTurnGitAction } from "./git-service.js";
|
|
35
36
|
import { parseUnitId } from "./unit-id.js";
|
|
36
37
|
import { resolveExpectedArtifactPath } from "./auto-artifact-paths.js";
|
|
38
|
+
import { checkCloseoutConsistencyGate, formatCloseoutConsistencyBlock, } from "./closeout-consistency-gate.js";
|
|
37
39
|
function resolveExistingExpectedArtifact(unitType, unitId, basePath) {
|
|
38
40
|
const artifactPath = resolveExpectedArtifactPath(unitType, unitId, basePath);
|
|
39
41
|
return artifactPath && existsSync(artifactPath) ? artifactPath : null;
|
|
@@ -178,6 +180,24 @@ function missingSliceStop(mid, phase) {
|
|
|
178
180
|
function isRegistryMilestoneComplete(state, mid) {
|
|
179
181
|
return state.registry.some((milestone) => milestone.id === mid && milestone.status === "complete");
|
|
180
182
|
}
|
|
183
|
+
function normalizeMilestoneScope(value) {
|
|
184
|
+
const trimmed = value?.trim();
|
|
185
|
+
if (!trimmed || !MILESTONE_ID_RE.test(trimmed))
|
|
186
|
+
return null;
|
|
187
|
+
return trimmed;
|
|
188
|
+
}
|
|
189
|
+
function resolveDispatchMilestoneScope(ctx) {
|
|
190
|
+
const sessionMilestone = normalizeMilestoneScope(ctx.session?.currentMilestoneId);
|
|
191
|
+
if (sessionMilestone)
|
|
192
|
+
return { id: sessionMilestone, source: "session.currentMilestoneId" };
|
|
193
|
+
const sessionWorktree = normalizeMilestoneScope(ctx.session?.basePath ? detectWorktreeName(ctx.session.basePath) : null);
|
|
194
|
+
if (sessionWorktree)
|
|
195
|
+
return { id: sessionWorktree, source: "session.basePath worktree" };
|
|
196
|
+
const baseWorktree = normalizeMilestoneScope(detectWorktreeName(ctx.basePath));
|
|
197
|
+
if (baseWorktree)
|
|
198
|
+
return { id: baseWorktree, source: "basePath worktree" };
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
181
201
|
function hasMilestonePassedDiscuss(basePath, mid) {
|
|
182
202
|
if (isDbAvailable()) {
|
|
183
203
|
try {
|
|
@@ -424,6 +444,7 @@ export const DISPATCH_RULES = [
|
|
|
424
444
|
unitType: "discuss-milestone",
|
|
425
445
|
unitId: mid,
|
|
426
446
|
prompt: await buildDiscussMilestonePrompt(mid, midTitle, basePath, structuredQuestionsAvailable, { headless: !!process.env.GSD_HEADLESS }),
|
|
447
|
+
pauseAfterDispatch: !process.env.GSD_HEADLESS,
|
|
427
448
|
};
|
|
428
449
|
},
|
|
429
450
|
},
|
|
@@ -559,6 +580,7 @@ export const DISPATCH_RULES = [
|
|
|
559
580
|
unitType: "discuss-milestone",
|
|
560
581
|
unitId: mid,
|
|
561
582
|
prompt: await buildDiscussMilestonePrompt(mid, midTitle, basePath, structuredQuestionsAvailable, { headless: !!process.env.GSD_HEADLESS }),
|
|
583
|
+
pauseAfterDispatch: !process.env.GSD_HEADLESS,
|
|
562
584
|
};
|
|
563
585
|
},
|
|
564
586
|
},
|
|
@@ -598,6 +620,7 @@ export const DISPATCH_RULES = [
|
|
|
598
620
|
unitType: "discuss-project",
|
|
599
621
|
unitId: "PROJECT",
|
|
600
622
|
prompt: await buildDiscussProjectPrompt(basePath, structuredQuestionsAvailable),
|
|
623
|
+
pauseAfterDispatch: !process.env.GSD_HEADLESS,
|
|
601
624
|
};
|
|
602
625
|
},
|
|
603
626
|
},
|
|
@@ -623,6 +646,7 @@ export const DISPATCH_RULES = [
|
|
|
623
646
|
unitType: "discuss-requirements",
|
|
624
647
|
unitId: "REQUIREMENTS",
|
|
625
648
|
prompt: await buildDiscussRequirementsPrompt(basePath, structuredQuestionsAvailable),
|
|
649
|
+
pauseAfterDispatch: !process.env.GSD_HEADLESS,
|
|
626
650
|
};
|
|
627
651
|
},
|
|
628
652
|
},
|
|
@@ -738,6 +762,7 @@ export const DISPATCH_RULES = [
|
|
|
738
762
|
unitType: "discuss-milestone",
|
|
739
763
|
unitId: mid,
|
|
740
764
|
prompt: await buildDiscussMilestonePrompt(mid, midTitle, basePath, structuredQuestionsAvailable, { headless: !!process.env.GSD_HEADLESS }),
|
|
765
|
+
pauseAfterDispatch: !process.env.GSD_HEADLESS,
|
|
741
766
|
};
|
|
742
767
|
},
|
|
743
768
|
},
|
|
@@ -1331,6 +1356,16 @@ export const DISPATCH_RULES = [
|
|
|
1331
1356
|
prompt: await buildCompleteMilestonePrompt(mid, midTitle, basePath),
|
|
1332
1357
|
};
|
|
1333
1358
|
}
|
|
1359
|
+
if (milestone) {
|
|
1360
|
+
const closeoutGate = checkCloseoutConsistencyGate(mid, { refreshFromDisk: true });
|
|
1361
|
+
if (!closeoutGate.ok) {
|
|
1362
|
+
return {
|
|
1363
|
+
action: "stop",
|
|
1364
|
+
reason: formatCloseoutConsistencyBlock(closeoutGate),
|
|
1365
|
+
level: "warning",
|
|
1366
|
+
};
|
|
1367
|
+
}
|
|
1368
|
+
}
|
|
1334
1369
|
}
|
|
1335
1370
|
return {
|
|
1336
1371
|
action: "stop",
|
|
@@ -1351,6 +1386,17 @@ import { getRegistry } from "./rule-registry.js";
|
|
|
1351
1386
|
* resolveDispatch directly without registry initialization).
|
|
1352
1387
|
*/
|
|
1353
1388
|
export async function resolveDispatch(ctx) {
|
|
1389
|
+
if (ctx.mid && isDbAvailable()) {
|
|
1390
|
+
const milestone = getMilestone(ctx.mid);
|
|
1391
|
+
if (milestone && isClosedStatus(milestone.status)) {
|
|
1392
|
+
return {
|
|
1393
|
+
action: "stop",
|
|
1394
|
+
reason: `Milestone ${ctx.mid} is closed (status: ${milestone.status}); auto-mode will not reopen or recover it implicitly. ` +
|
|
1395
|
+
"Use an explicit reopen command before planning or executing more work for this milestone.",
|
|
1396
|
+
level: "warning",
|
|
1397
|
+
};
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1354
1400
|
const activeMid = ctx.state.activeMilestone?.id;
|
|
1355
1401
|
if (activeMid && ctx.mid !== activeMid) {
|
|
1356
1402
|
return {
|
|
@@ -1360,6 +1406,15 @@ export async function resolveDispatch(ctx) {
|
|
|
1360
1406
|
level: "warning",
|
|
1361
1407
|
};
|
|
1362
1408
|
}
|
|
1409
|
+
const scopedMilestone = resolveDispatchMilestoneScope(ctx);
|
|
1410
|
+
if (scopedMilestone && ctx.mid !== scopedMilestone.id) {
|
|
1411
|
+
return {
|
|
1412
|
+
action: "stop",
|
|
1413
|
+
reason: `Dispatch milestone mismatch: context mid "${ctx.mid}" does not match ${scopedMilestone.source} "${scopedMilestone.id}". ` +
|
|
1414
|
+
"The active worktree/session and derived project state disagree; recover, park, or discard the stranded milestone before continuing.",
|
|
1415
|
+
level: "warning",
|
|
1416
|
+
};
|
|
1417
|
+
}
|
|
1363
1418
|
// Delegate to registry when available
|
|
1364
1419
|
try {
|
|
1365
1420
|
const registry = getRegistry();
|