@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
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { parseUnitId } from "./unit-id.js";
|
|
2
|
+
import { RUN_UAT_WORKFLOW_TOOL_NAMES } from "./tool-presentation-plan.js";
|
|
2
3
|
export const RUN_UAT_BROWSER_TOOL_NAMES = [
|
|
3
4
|
"browser_navigate",
|
|
4
5
|
"browser_click",
|
|
@@ -42,7 +43,7 @@ export const AUTO_UNIT_SCOPED_TOOLS = {
|
|
|
42
43
|
"execute-task": ["gsd_task_complete", "gsd_decision_save"],
|
|
43
44
|
"execute-task-simple": ["gsd_task_complete", "gsd_decision_save"],
|
|
44
45
|
"reactive-execute": ["gsd_task_complete", "gsd_decision_save"],
|
|
45
|
-
"run-uat": ["
|
|
46
|
+
"run-uat": [...RUN_UAT_WORKFLOW_TOOL_NAMES, "subagent", ...RUN_UAT_BROWSER_TOOL_NAMES],
|
|
46
47
|
"gate-evaluate": ["gsd_save_gate_result"],
|
|
47
48
|
"rewrite-docs": ["gsd_summary_save", "gsd_decision_save"],
|
|
48
49
|
"workflow-preferences": ["gsd_summary_save"],
|
|
@@ -64,7 +64,7 @@ import { initRegistry, convertDispatchRules } from "./rule-registry.js";
|
|
|
64
64
|
import { emitJournalEvent as _emitJournalEvent } from "./journal.js";
|
|
65
65
|
import { isClosedStatus } from "./status-guards.js";
|
|
66
66
|
import { MILESTONE_ID_RE } from "./milestone-ids.js";
|
|
67
|
-
import { updateProgressWidget as _updateProgressWidget, setCompletionProgressWidget, setAutoOutcomeWidget, updateSliceProgressCache, clearSliceProgressCache, unitVerb, } from "./auto-dashboard.js";
|
|
67
|
+
import { updateProgressWidget as _updateProgressWidget, setCompletionProgressWidget, setAutoOutcomeWidget, setAutoActiveStatus, updateSliceProgressCache, clearSliceProgressCache, unitVerb, } from "./auto-dashboard.js";
|
|
68
68
|
import { registerSigtermHandler as _registerSigtermHandler, deregisterSigtermHandler as _deregisterSigtermHandler, } from "./auto-supervisor.js";
|
|
69
69
|
import { isDbAvailable, getMilestone, getMilestoneSlices, getSlice, getTask, refreshOpenDatabaseFromDisk, } from "./gsd-db.js";
|
|
70
70
|
import { markLatestActiveForWorkerCanceled } from "./db/unit-dispatches.js";
|
|
@@ -86,7 +86,7 @@ function makeCmuxEmitters(pi) {
|
|
|
86
86
|
import { startUnitSupervision } from "./auto-timers.js";
|
|
87
87
|
import { runPostUnitVerification } from "./auto-verification.js";
|
|
88
88
|
import { autoCommitUnit, postUnitPreVerification, postUnitPostVerification, } from "./auto-post-unit.js";
|
|
89
|
-
import { bootstrapAutoSession, openProjectDbIfPresent } from "./auto-start.js";
|
|
89
|
+
import { bootstrapAutoSession, openProjectDbIfPresent, reconcileMergedMilestonesFromJournal, } from "./auto-start.js";
|
|
90
90
|
import { initHealthWidget } from "./health-widget.js";
|
|
91
91
|
import { runLegacyAutoLoop, runUokKernelLoop } from "./auto/loop.js";
|
|
92
92
|
import { resolveAgentEnd, resolveAgentEndCancelled, _resetPendingResolve, isSessionSwitchInFlight } from "./auto/resolve.js";
|
|
@@ -1601,6 +1601,20 @@ export function createWiredDispatchAdapter(ctx, pi, dispatchBasePath, session) {
|
|
|
1601
1601
|
}
|
|
1602
1602
|
return null;
|
|
1603
1603
|
}
|
|
1604
|
+
function shouldAdoptActiveMilestone(state, activeSession, activeDispatchBasePath) {
|
|
1605
|
+
const activeMilestoneId = state.activeMilestone?.id;
|
|
1606
|
+
const currentMilestoneId = activeSession?.currentMilestoneId;
|
|
1607
|
+
if (!activeSession || !activeMilestoneId || !currentMilestoneId || activeMilestoneId === currentMilestoneId) {
|
|
1608
|
+
return false;
|
|
1609
|
+
}
|
|
1610
|
+
const scopedWorktreeMilestone = (activeSession.basePath ? detectWorktreeName(activeSession.basePath) : null) ??
|
|
1611
|
+
detectWorktreeName(activeDispatchBasePath);
|
|
1612
|
+
if (scopedWorktreeMilestone && scopedWorktreeMilestone !== activeMilestoneId) {
|
|
1613
|
+
return false;
|
|
1614
|
+
}
|
|
1615
|
+
const currentMilestone = state.registry.find((milestone) => milestone.id === currentMilestoneId);
|
|
1616
|
+
return !!currentMilestone && isClosedStatus(currentMilestone.status);
|
|
1617
|
+
}
|
|
1604
1618
|
return {
|
|
1605
1619
|
async decideNextUnit(input) {
|
|
1606
1620
|
const state = input.stateSnapshot;
|
|
@@ -1609,6 +1623,9 @@ export function createWiredDispatchAdapter(ctx, pi, dispatchBasePath, session) {
|
|
|
1609
1623
|
return null;
|
|
1610
1624
|
const activeSession = input.session ?? session;
|
|
1611
1625
|
const activeDispatchBasePath = activeSession?.basePath || dispatchBasePath;
|
|
1626
|
+
if (activeSession && shouldAdoptActiveMilestone(state, activeSession, activeDispatchBasePath)) {
|
|
1627
|
+
activeSession.currentMilestoneId = active.id;
|
|
1628
|
+
}
|
|
1612
1629
|
const prefs = loadEffectiveGSDPreferences(activeDispatchBasePath)?.preferences;
|
|
1613
1630
|
// Derive session-derived dispatch inputs the same way phases.ts:runDispatch does
|
|
1614
1631
|
// (#5789). Prefer caller-supplied values when present so test harnesses and
|
|
@@ -1757,10 +1774,17 @@ export function createWiredAutoOrchestrationModule(ctx, pi, dispatchBasePath, ru
|
|
|
1757
1774
|
async reconcileBeforeDispatch() {
|
|
1758
1775
|
const activeBasePath = getLiveDispatchBasePath();
|
|
1759
1776
|
const result = await reconcileBeforeDispatch(activeBasePath);
|
|
1760
|
-
|
|
1777
|
+
// Failure-path summaries written by gsd_summary_save create
|
|
1778
|
+
// artifact-db-status-divergence blockers for tasks that are still
|
|
1779
|
+
// pending (gsd_task_complete never ran). These tasks can still be
|
|
1780
|
+
// dispatched and the drift self-heals once they complete successfully.
|
|
1781
|
+
const hardBlockers = result.blockers.filter((b) => !b.includes("has SUMMARY artifact while DB status is") &&
|
|
1782
|
+
!b.includes("has SUMMARY on disk while DB status is") &&
|
|
1783
|
+
!b.includes("has task SUMMARY artifacts but no DB tasks"));
|
|
1784
|
+
if (hardBlockers.length > 0) {
|
|
1761
1785
|
return {
|
|
1762
1786
|
ok: false,
|
|
1763
|
-
reason:
|
|
1787
|
+
reason: hardBlockers[0],
|
|
1764
1788
|
stateSnapshot: result.stateSnapshot,
|
|
1765
1789
|
};
|
|
1766
1790
|
}
|
|
@@ -2369,6 +2393,7 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
|
|
|
2369
2393
|
if (s.currentMilestoneId)
|
|
2370
2394
|
setActiveMilestoneId(base, s.currentMilestoneId);
|
|
2371
2395
|
await openProjectDbIfPresent(base);
|
|
2396
|
+
reconcileMergedMilestonesFromJournal(base);
|
|
2372
2397
|
registerAutoWorkerForSession(s, base);
|
|
2373
2398
|
// Re-register health level notification callback lost across process restart
|
|
2374
2399
|
setLevelChangeCallback((_from, to, summary) => {
|
|
@@ -2396,7 +2421,7 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
|
|
|
2396
2421
|
const loopDeps = buildLoopDeps(pi);
|
|
2397
2422
|
ensureOrchestrationModule(ctx, pi, s.basePath || base);
|
|
2398
2423
|
registerSigtermHandler(lockBase());
|
|
2399
|
-
ctx
|
|
2424
|
+
setAutoActiveStatus(ctx, s.stepMode ? "next" : "auto");
|
|
2400
2425
|
ctx.ui.setWidget("gsd-health", undefined);
|
|
2401
2426
|
ctx.ui.notify(s.stepMode ? "Step-mode resumed." : "Auto-mode resumed.", "info");
|
|
2402
2427
|
restoreHookState(s.basePath);
|
|
@@ -2641,7 +2666,7 @@ export async function dispatchHookUnit(ctx, pi, hookName, triggerUnitType, trigg
|
|
|
2641
2666
|
resetHookState();
|
|
2642
2667
|
await pauseAuto(ctx, pi);
|
|
2643
2668
|
}, hookHardTimeoutMs);
|
|
2644
|
-
ctx
|
|
2669
|
+
setAutoActiveStatus(ctx, s.stepMode ? "next" : "auto");
|
|
2645
2670
|
ctx.ui.notify(`Running post-unit hook: ${hookName}`, "info");
|
|
2646
2671
|
debugLog("dispatchHookUnit", {
|
|
2647
2672
|
phase: "send-message",
|
|
@@ -396,6 +396,85 @@ export function registerDbTools(pi) {
|
|
|
396
396
|
};
|
|
397
397
|
pi.registerTool(summarySaveTool);
|
|
398
398
|
registerAlias(pi, summarySaveTool, "gsd_save_summary", "gsd_summary_save");
|
|
399
|
+
// ─── gsd_uat_result_save ─────────────────────────────────────────────────
|
|
400
|
+
const uatResultSaveExecute = async (_toolCallId, params, _signal, _onUpdate, _ctx) => {
|
|
401
|
+
const { executeUatResultSave } = await loadWorkflowExecutors();
|
|
402
|
+
return executeUatResultSave(params, resolveWorkflowToolBasePath(_ctx, params));
|
|
403
|
+
};
|
|
404
|
+
const uatEvidenceRef = Type.Object({
|
|
405
|
+
kind: StringEnum(["gsd_uat_exec", "gsd_exec", "screenshot", "log", "url", "browser"], { description: "Evidence kind" }),
|
|
406
|
+
ref: Type.String({ description: "Evidence ID, approved .gsd path, or URL" }),
|
|
407
|
+
note: Type.Optional(Type.String({ description: "Short evidence note" })),
|
|
408
|
+
});
|
|
409
|
+
const uatCheck = Type.Object({
|
|
410
|
+
id: Type.String({ description: "Stable check ID from the UAT spec" }),
|
|
411
|
+
description: Type.String({ description: "Check description" }),
|
|
412
|
+
mode: StringEnum(["artifact", "runtime", "browser", "human-follow-up"], { description: "Evidence mode" }),
|
|
413
|
+
result: StringEnum(["PASS", "FAIL", "NEEDS-HUMAN"], { description: "Check result" }),
|
|
414
|
+
evidence: Type.Optional(Type.Array(uatEvidenceRef, { description: "Objective evidence references" })),
|
|
415
|
+
notes: Type.Optional(Type.String({ description: "Observed result, failure notes, or human instruction" })),
|
|
416
|
+
nonAutomatable: Type.Optional(Type.Boolean({ description: "True when the check is explicitly non-automatable" })),
|
|
417
|
+
});
|
|
418
|
+
const toolPresentationBlock = Type.Object({
|
|
419
|
+
surface: StringEnum(["provider-tools", "claude-code-sdk", "mcp", "hybrid"], { description: "Tool presentation surface" }),
|
|
420
|
+
model: Type.Optional(Type.Object({
|
|
421
|
+
provider: Type.Optional(Type.String()),
|
|
422
|
+
api: Type.Optional(Type.String()),
|
|
423
|
+
id: Type.Optional(Type.String()),
|
|
424
|
+
})),
|
|
425
|
+
presentedTools: Type.Array(Type.String(), { description: "Tool names actually presented to the model" }),
|
|
426
|
+
blockedTools: Type.Array(Type.Object({
|
|
427
|
+
name: Type.String(),
|
|
428
|
+
reason: Type.String(),
|
|
429
|
+
}), { description: "Tool names blocked from the model with reasons" }),
|
|
430
|
+
aliases: Type.Optional(Type.Array(Type.Object({
|
|
431
|
+
requested: Type.String(),
|
|
432
|
+
canonical: Type.String(),
|
|
433
|
+
}))),
|
|
434
|
+
fallbackToolsUsed: Type.Optional(Type.Array(Type.String())),
|
|
435
|
+
toolPresentationPlanId: Type.Optional(Type.String()),
|
|
436
|
+
notes: Type.Optional(Type.String()),
|
|
437
|
+
});
|
|
438
|
+
const uatResultSaveTool = {
|
|
439
|
+
name: "gsd_uat_result_save",
|
|
440
|
+
label: "Save UAT Result",
|
|
441
|
+
description: "Save a structured UAT result for a slice. Validates evidence, writes the ASSESSMENT artifact, " +
|
|
442
|
+
"records attempt history, and saves the aggregate UAT gate result.",
|
|
443
|
+
promptSnippet: "Save structured UAT checks, evidence, verdict, and tool-presentation proof",
|
|
444
|
+
promptGuidelines: [
|
|
445
|
+
"Call gsd_uat_result_save once after all UAT checks have been executed.",
|
|
446
|
+
"Every PASS or FAIL check must cite objective evidence, preferably a gsd_uat_exec evidence ID.",
|
|
447
|
+
"Include the presented and blocked tool set in presentation so tool timing is auditable.",
|
|
448
|
+
"Do not use raw gsd_summary_save as a substitute for UAT results.",
|
|
449
|
+
],
|
|
450
|
+
parameters: Type.Object({
|
|
451
|
+
milestoneId: Type.String({ description: "Milestone ID (e.g. M001)" }),
|
|
452
|
+
sliceId: Type.String({ description: "Slice ID (e.g. S01)" }),
|
|
453
|
+
uatType: StringEnum(["artifact-driven", "browser-executable", "runtime-executable", "live-runtime", "mixed", "human-experience"], { description: "Declared UAT mode" }),
|
|
454
|
+
verdict: StringEnum(["PASS", "FAIL", "PARTIAL"], { description: "Overall UAT verdict" }),
|
|
455
|
+
checks: Type.Array(uatCheck, { description: "Structured check results" }),
|
|
456
|
+
presentation: toolPresentationBlock,
|
|
457
|
+
notes: Type.Optional(Type.String({ description: "Overall verdict rationale" })),
|
|
458
|
+
attempt: Type.Optional(Type.String({ description: "Attempt number or auto" })),
|
|
459
|
+
previousAttemptId: Type.Optional(Type.String({ description: "Prior attempt ID, when retrying" })),
|
|
460
|
+
}),
|
|
461
|
+
execute: uatResultSaveExecute,
|
|
462
|
+
renderCall(args, theme) {
|
|
463
|
+
let text = theme.fg("toolTitle", theme.bold("uat_result_save "));
|
|
464
|
+
text += theme.fg("accent", `${args.milestoneId ?? "?"}/${args.sliceId ?? "?"}`);
|
|
465
|
+
if (args.verdict)
|
|
466
|
+
text += theme.fg("dim", ` → ${args.verdict}`);
|
|
467
|
+
return new Text(text, 0, 0);
|
|
468
|
+
},
|
|
469
|
+
renderResult(result, _options, theme) {
|
|
470
|
+
const d = readDetails(result);
|
|
471
|
+
if (result.isError || d?.error) {
|
|
472
|
+
return new Text(theme.fg("error", formatToolErrorText(result, d)), 0, 0);
|
|
473
|
+
}
|
|
474
|
+
return new Text(theme.fg("success", `UAT ${d?.sliceId ?? ""}: ${d?.verdict ?? "saved"}`), 0, 0);
|
|
475
|
+
},
|
|
476
|
+
};
|
|
477
|
+
pi.registerTool(uatResultSaveTool);
|
|
399
478
|
// ─── gsd_milestone_generate_id (formerly gsd_generate_milestone_id) ────
|
|
400
479
|
const milestoneGenerateIdExecute = async (_toolCallId, _params, _signal, _onUpdate, _ctx) => {
|
|
401
480
|
try {
|
|
@@ -709,7 +788,7 @@ export function registerDbTools(pi) {
|
|
|
709
788
|
recommendation: Type.String({ description: "Option id the executor recommends." }),
|
|
710
789
|
recommendationRationale: Type.String({ description: "Why the recommendation — 1–2 sentences." }),
|
|
711
790
|
continueWithDefault: Type.Boolean({
|
|
712
|
-
description: "When true,
|
|
791
|
+
description: "When true, the recommendation is recorded as the default, but auto-mode still pauses until the user resolves via /gsd escalate resolve.",
|
|
713
792
|
}),
|
|
714
793
|
}, { description: "ADR-011 Phase 2: optional escalation payload. Only honored when phases.mid_execution_escalation is true." })),
|
|
715
794
|
verificationEvidence: Type.Optional(Type.Array(Type.Object({
|
|
@@ -750,7 +829,7 @@ export function registerDbTools(pi) {
|
|
|
750
829
|
sliceTitle: Type.String({ description: "Title of the slice" }),
|
|
751
830
|
oneLiner: Type.String({ description: "One-line summary of what the slice accomplished" }),
|
|
752
831
|
narrative: Type.String({ description: "Detailed narrative of what happened across all tasks" }),
|
|
753
|
-
verification: Type.String({ description: "What was verified across all tasks" }),
|
|
832
|
+
verification: Type.Optional(Type.String({ description: "What was verified across all tasks — if omitted, summary records verification as passed without detail." })),
|
|
754
833
|
uatContent: Type.String({ description: "UAT test content (markdown body)" }),
|
|
755
834
|
// ── Enrichment metadata (optional — defaults to empty) ────────────
|
|
756
835
|
deviations: Type.Optional(Type.String({ description: "Deviations from the slice plan, or 'None.'" })),
|
|
@@ -931,7 +1010,7 @@ export function registerDbTools(pi) {
|
|
|
931
1010
|
promptGuidelines: [
|
|
932
1011
|
"Use gsd_validate_milestone when all slices are done and the milestone needs validation before completion.",
|
|
933
1012
|
"Parameters: milestoneId, verdict, remediationRound, successCriteriaChecklist, sliceDeliveryAudit, crossSliceIntegration, requirementCoverage, verificationClasses (optional), verdictRationale, remediationPlan (optional).",
|
|
934
|
-
"If verification classes were planned, verificationClasses must
|
|
1013
|
+
"If verification classes were planned, verificationClasses must be a complete canonical table with one row for every applicable planned class using the exact class names Contract, Integration, Operational, and UAT. Do not submit a partial table.",
|
|
935
1014
|
"Planned verification text marked as none/not required/not applicable/N/A (including suffixed variants such as 'not required - backend-only') is treated as not applicable and does not require a class row.",
|
|
936
1015
|
"If verdict is 'needs-remediation', also provide remediationPlan and use gsd_reassess_roadmap to add remediation slices to the roadmap.",
|
|
937
1016
|
"On success, returns validationPath where VALIDATION.md was written.",
|
|
@@ -944,7 +1023,7 @@ export function registerDbTools(pi) {
|
|
|
944
1023
|
sliceDeliveryAudit: Type.String({ description: "Markdown table auditing each slice's claimed vs delivered output" }),
|
|
945
1024
|
crossSliceIntegration: Type.String({ description: "Markdown describing any cross-slice boundary mismatches" }),
|
|
946
1025
|
requirementCoverage: Type.String({ description: "Markdown describing any unaddressed requirements" }),
|
|
947
|
-
verificationClasses: Type.Optional(Type.String({ description: "
|
|
1026
|
+
verificationClasses: Type.Optional(Type.String({ description: "Complete markdown table describing verification class compliance and gaps; include one canonical row for every applicable planned class (Contract, Integration, Operational, UAT)" })),
|
|
948
1027
|
verdictRationale: Type.String({ description: "Why this verdict was chosen" }),
|
|
949
1028
|
remediationPlan: Type.Optional(Type.String({ description: "Remediation plan (required if verdict is needs-remediation)" })),
|
|
950
1029
|
}),
|
|
@@ -20,6 +20,49 @@ async function loadContextModePreferences(baseDir) {
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
export function registerExecTools(pi) {
|
|
23
|
+
pi.registerTool({
|
|
24
|
+
name: "gsd_uat_exec",
|
|
25
|
+
label: "UAT Exec",
|
|
26
|
+
description: "Run a UAT-scoped bash/node/python check with milestone/slice/check metadata. " +
|
|
27
|
+
"Uses the same capped .gsd/exec evidence store as gsd_exec, but rejects commands that mutate dependencies, git state, credentials, or destructive files.",
|
|
28
|
+
promptSnippet: "Run one UAT check and save typed evidence under .gsd/exec",
|
|
29
|
+
promptGuidelines: [
|
|
30
|
+
"Use gsd_uat_exec for each automated UAT check.",
|
|
31
|
+
"Every PASS/FAIL check saved by gsd_uat_result_save must reference objective evidence from this tool or another approved GSD evidence path.",
|
|
32
|
+
"Do not install packages, mutate git state, edit source files, or dump credentials during UAT.",
|
|
33
|
+
],
|
|
34
|
+
parameters: Type.Object({
|
|
35
|
+
milestoneId: Type.String({ description: "Milestone ID (e.g. M001)" }),
|
|
36
|
+
sliceId: Type.String({ description: "Slice ID (e.g. S01)" }),
|
|
37
|
+
checkId: Type.String({ description: "Stable check ID from the UAT spec (e.g. UAT-01)" }),
|
|
38
|
+
intent: Type.String({
|
|
39
|
+
description: "UAT command intent. Use one canonical value: uat-artifact-check, uat-runtime-check, " +
|
|
40
|
+
"uat-browser-check, uat-service-start, or uat-log-inspection. Short aliases such as artifact, " +
|
|
41
|
+
"runtime, browser, service-start, and log-inspection are accepted.",
|
|
42
|
+
}),
|
|
43
|
+
runtime: Type.Optional(Type.String({
|
|
44
|
+
description: "Optional interpreter. Defaults to bash. Supported: bash, node, python; sh/shell, js/nodejs, and py/python3 aliases are accepted.",
|
|
45
|
+
})),
|
|
46
|
+
script: Type.Optional(Type.String({ description: "Script body. Keep output small (log the finding, not the data)." })),
|
|
47
|
+
command: Type.Optional(Type.String({ description: "Alias for script; defaults to bash when runtime is omitted." })),
|
|
48
|
+
cmd: Type.Optional(Type.String({ description: "Short alias for script." })),
|
|
49
|
+
code: Type.Optional(Type.String({ description: "Alias for script, useful for node/python snippets." })),
|
|
50
|
+
expected: Type.Optional(Type.String({ description: "Expected outcome for this UAT check." })),
|
|
51
|
+
timeout_ms: Type.Optional(Type.Number({
|
|
52
|
+
description: "Per-invocation timeout (ms). Capped at 600000. Default from preferences.",
|
|
53
|
+
minimum: 1_000,
|
|
54
|
+
maximum: 600_000,
|
|
55
|
+
})),
|
|
56
|
+
}),
|
|
57
|
+
async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
|
|
58
|
+
const { executeUatExec } = await import("../tools/exec-tool.js");
|
|
59
|
+
const baseDir = resolveCtxCwd(_ctx);
|
|
60
|
+
return executeUatExec(params, {
|
|
61
|
+
baseDir,
|
|
62
|
+
preferences: await loadContextModePreferences(baseDir),
|
|
63
|
+
});
|
|
64
|
+
},
|
|
65
|
+
});
|
|
23
66
|
pi.registerTool({
|
|
24
67
|
name: "gsd_exec",
|
|
25
68
|
label: "Exec (Sandboxed)",
|
|
@@ -11,7 +11,7 @@ import { canonicalToolName, clearDiscussionFlowState, isDepthConfirmationAnswer,
|
|
|
11
11
|
import { resolveManifest } from "../unit-context-manifest.js";
|
|
12
12
|
import { isBlockedStateFile, isBashWriteToStateFile, BLOCKED_WRITE_ERROR } from "../write-intercept.js";
|
|
13
13
|
import { loadFile, saveFile, formatContinue } from "../files.js";
|
|
14
|
-
import { clearToolInvocationError, getAutoRuntimeSnapshot, isAutoActive, isAutoPaused, markToolEnd, markToolStart, recordToolInvocationError } from "../auto-runtime-state.js";
|
|
14
|
+
import { clearToolInvocationError, getAutoRuntimeSnapshot, isAutoActive, isAutoCompletionStopInProgress, isAutoPaused, markToolEnd, markToolStart, recordToolInvocationError } from "../auto-runtime-state.js";
|
|
15
15
|
import { checkToolCallLoop, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
|
|
16
16
|
import { maybePauseAutoForApprovalGate, resetPendingGatePauseGuard } from "./pending-gate-pause.js";
|
|
17
17
|
import { saveActivityLog } from "../activity-log.js";
|
|
@@ -28,7 +28,9 @@ import { approvalGateIdForUnit, isExplicitApprovalResponse, shouldPauseForUserAp
|
|
|
28
28
|
import { applyUnitSkillVisibility, unitHasSkillManifest } from "../skill-scope.js";
|
|
29
29
|
import { getGuidedUnitContext } from "../guided-unit-context.js";
|
|
30
30
|
import { registerPlanMilestoneSchemaRecovery } from "./plan-milestone-schema-recovery.js";
|
|
31
|
-
import { AUTO_UNIT_SCOPED_TOOLS, isWorkflowAliasTool } from "../auto-unit-tool-scope.js";
|
|
31
|
+
import { AUTO_UNIT_SCOPED_TOOLS, RUN_UAT_BROWSER_TOOL_NAMES, isWorkflowAliasTool } from "../auto-unit-tool-scope.js";
|
|
32
|
+
import { filterToolsForProvider } from "../model-router.js";
|
|
33
|
+
import { RUN_UAT_WORKFLOW_TOOL_NAMES } from "../tool-presentation-plan.js";
|
|
32
34
|
let approvalQuestionAbortInFlight = false;
|
|
33
35
|
async function loadWelcomeScreenModule() {
|
|
34
36
|
const candidates = [];
|
|
@@ -104,6 +106,7 @@ export const MINIMAL_GSD_TOOL_NAMES = [
|
|
|
104
106
|
"gsd_resume",
|
|
105
107
|
"gsd_milestone_status",
|
|
106
108
|
"gsd_checkpoint_db",
|
|
109
|
+
"gsd_plan_milestone",
|
|
107
110
|
"memory_query",
|
|
108
111
|
"capture_thought",
|
|
109
112
|
];
|
|
@@ -187,6 +190,9 @@ export function buildMinimalGsdToolSet(activeToolNames) {
|
|
|
187
190
|
return withPreservedShimTools([...new Set([...preserved, ...minimal])]);
|
|
188
191
|
}
|
|
189
192
|
export function buildMinimalAutoGsdToolSet(activeToolNames, unitType, registeredToolNames = activeToolNames) {
|
|
193
|
+
if (unitType === "run-uat") {
|
|
194
|
+
return buildRunUatGsdToolSet(activeToolNames, registeredToolNames);
|
|
195
|
+
}
|
|
190
196
|
const unitTools = unitType ? AUTO_UNIT_SCOPED_TOOLS[unitType] ?? [] : [];
|
|
191
197
|
const autoBaseTools = new Set(MINIMAL_AUTO_BASE_TOOL_NAMES);
|
|
192
198
|
const availableBaseTools = registeredToolNames.filter((name) => autoBaseTools.has(name));
|
|
@@ -197,6 +203,10 @@ export function buildMinimalAutoGsdToolSet(activeToolNames, unitType, registered
|
|
|
197
203
|
const scoped = resolveScopedToolNames([...activeToolNames, ...registeredToolNames], [...MINIMAL_GSD_TOOL_NAMES, ...unitTools]);
|
|
198
204
|
return withPreservedShimTools([...new Set([...preserved, ...scoped])]);
|
|
199
205
|
}
|
|
206
|
+
export function buildRunUatGsdToolSet(activeToolNames, registeredToolNames = activeToolNames) {
|
|
207
|
+
const scoped = resolveScopedToolNames([...activeToolNames, ...registeredToolNames], [...RUN_UAT_WORKFLOW_TOOL_NAMES, "subagent", ...RUN_UAT_BROWSER_TOOL_NAMES]);
|
|
208
|
+
return [...new Set(scoped)];
|
|
209
|
+
}
|
|
200
210
|
export function buildMinimalGsdWorkflowToolSet(activeToolNames, registeredToolNames = activeToolNames) {
|
|
201
211
|
const autoBaseTools = new Set(MINIMAL_AUTO_BASE_TOOL_NAMES);
|
|
202
212
|
const availableBaseTools = registeredToolNames.filter((name) => autoBaseTools.has(name));
|
|
@@ -414,8 +424,9 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
414
424
|
registerPlanMilestoneSchemaRecovery(pi);
|
|
415
425
|
pi.on("session_start", async (_event, ctx) => {
|
|
416
426
|
const basePath = contextBasePath(ctx);
|
|
427
|
+
const preserveCloseoutSurface = isAutoCompletionStopInProgress();
|
|
417
428
|
initSessionNotifications(ctx);
|
|
418
|
-
if (!isAutoActive()) {
|
|
429
|
+
if (!isAutoActive() && !preserveCloseoutSurface) {
|
|
419
430
|
const { initHealthWidget } = await import("../health-widget.js");
|
|
420
431
|
initHealthWidget(ctx);
|
|
421
432
|
}
|
|
@@ -435,14 +446,17 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
435
446
|
process.env.GSD_SHOW_TOKEN_COST = prefs?.preferences.show_token_cost ? "1" : "";
|
|
436
447
|
}
|
|
437
448
|
catch { /* non-fatal */ }
|
|
438
|
-
|
|
449
|
+
if (!preserveCloseoutSurface) {
|
|
450
|
+
await installWelcomeHeader(ctx);
|
|
451
|
+
}
|
|
439
452
|
await loadToolApiKeysForSession();
|
|
440
|
-
if (isAutoActive()) {
|
|
453
|
+
if (isAutoActive() || preserveCloseoutSurface) {
|
|
441
454
|
ctx.ui.setWidget("gsd-health", undefined);
|
|
442
455
|
}
|
|
443
456
|
});
|
|
444
457
|
pi.on("session_switch", async (_event, ctx) => {
|
|
445
458
|
const basePath = contextBasePath(ctx);
|
|
459
|
+
const preserveCloseoutSurface = isAutoCompletionStopInProgress();
|
|
446
460
|
initSessionNotifications(ctx);
|
|
447
461
|
resetWriteGateState(basePath);
|
|
448
462
|
resetToolCallLoopGuard();
|
|
@@ -454,7 +468,7 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
454
468
|
await applyCompactionThresholdOverride(ctx);
|
|
455
469
|
await prepareWorkflowMcpForHookContext(ctx, basePath);
|
|
456
470
|
await loadToolApiKeysForSession();
|
|
457
|
-
if (!isAutoActive()) {
|
|
471
|
+
if (!isAutoActive() && !preserveCloseoutSurface) {
|
|
458
472
|
ctx.ui.setWidget("gsd-progress", undefined);
|
|
459
473
|
ctx.ui.setWidget("gsd-outcome", undefined);
|
|
460
474
|
const { initHealthWidget } = await import("../health-widget.js");
|
|
@@ -836,10 +850,8 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
836
850
|
if (result.block)
|
|
837
851
|
return result;
|
|
838
852
|
});
|
|
839
|
-
// ── Safety harness: evidence collection + destructive command
|
|
853
|
+
// ── Safety harness: evidence collection + destructive command blocking ──
|
|
840
854
|
pi.on("tool_call", async (event, ctx) => {
|
|
841
|
-
if (!isAutoActive())
|
|
842
|
-
return;
|
|
843
855
|
markToolStart(event.toolCallId, event.toolName);
|
|
844
856
|
safetyRecordToolCall(event.toolCallId, event.toolName, event.input);
|
|
845
857
|
// Persist immediately at dispatch so a mid-unit re-dispatch — which calls
|
|
@@ -854,14 +866,23 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
854
866
|
saveEvidenceToDisk(callDash.basePath, cMid, cSid, cTid);
|
|
855
867
|
}
|
|
856
868
|
}
|
|
857
|
-
// Destructive command classification
|
|
869
|
+
// Destructive command classification + hard gate in all modes.
|
|
858
870
|
if (isToolCallEventType("bash", event)) {
|
|
859
871
|
const classification = classifyCommand(event.input.command);
|
|
860
872
|
if (classification.destructive) {
|
|
873
|
+
const reason = [
|
|
874
|
+
"HARD BLOCK: destructive Bash command requires explicit human confirmation.",
|
|
875
|
+
`Detected: ${classification.labels.join(", ")}`,
|
|
876
|
+
"Run this via ask_user_questions, wait for the user's response,",
|
|
877
|
+
"then issue the command only when confirmed in the current turn.",
|
|
878
|
+
].join(" ");
|
|
861
879
|
safetyLogWarning("safety", `destructive command: ${classification.labels.join(", ")}`, {
|
|
862
880
|
command: String(event.input.command).slice(0, 200),
|
|
863
881
|
});
|
|
864
|
-
|
|
882
|
+
if (ctx) {
|
|
883
|
+
await maybePauseAutoForApprovalGate(ctx, pi, isAutoActive(), "Depth confirmation is waiting for your answer — pausing auto-mode.");
|
|
884
|
+
}
|
|
885
|
+
return { block: true, reason };
|
|
865
886
|
}
|
|
866
887
|
}
|
|
867
888
|
});
|
|
@@ -1123,21 +1144,25 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
1123
1144
|
const fullToolsRequested = isFullGsdToolSurfaceRequested();
|
|
1124
1145
|
const dropAliases = !fullToolsRequested;
|
|
1125
1146
|
const dropBrowser = !fullToolsRequested && !isBrowserToolSurfaceRequested();
|
|
1126
|
-
const
|
|
1147
|
+
const aliasFilteredCompatible = compatible.filter((name) => !(dropAliases && isWorkflowAliasTool(name)));
|
|
1148
|
+
const providerCompatible = aliasFilteredCompatible.filter((name) => !(dropBrowser && isBrowserTool(name)));
|
|
1127
1149
|
const surfaceReduced = providerCompatible.length !== compatible.length;
|
|
1128
1150
|
if (fullToolsRequested) {
|
|
1129
1151
|
return surfaceReduced ? { toolNames: providerCompatible } : undefined;
|
|
1130
1152
|
}
|
|
1131
1153
|
const registeredToolNames = resolveRegisteredToolNames(pi, event.activeToolNames);
|
|
1154
|
+
const compatibleRegisteredToolNames = filterToolsForProvider(registeredToolNames, event.selectedModelApi, event.selectedModelProvider).compatible.filter((name) => !(dropAliases && isWorkflowAliasTool(name)));
|
|
1132
1155
|
const guidedUnit = getGuidedUnitContext();
|
|
1133
|
-
const requestScoped = buildRequestScopedGsdToolSet(providerCompatible, event.requestCustomMessages, registeredToolNames, guidedUnit?.unitType);
|
|
1156
|
+
const requestScoped = buildRequestScopedGsdToolSet(guidedUnit?.unitType === "run-uat" ? aliasFilteredCompatible : providerCompatible, event.requestCustomMessages, guidedUnit?.unitType === "run-uat" ? compatibleRegisteredToolNames : registeredToolNames, guidedUnit?.unitType);
|
|
1134
1157
|
if (requestScoped) {
|
|
1135
1158
|
return { toolNames: requestScoped };
|
|
1136
1159
|
}
|
|
1137
1160
|
const dash = getAutoRuntimeSnapshot();
|
|
1138
1161
|
if (dash.active && dash.currentUnit) {
|
|
1139
1162
|
return {
|
|
1140
|
-
toolNames: buildMinimalAutoGsdToolSet(providerCompatible, dash.currentUnit.type,
|
|
1163
|
+
toolNames: buildMinimalAutoGsdToolSet(dash.currentUnit.type === "run-uat" ? aliasFilteredCompatible : providerCompatible, dash.currentUnit.type, dash.currentUnit.type === "run-uat"
|
|
1164
|
+
? compatibleRegisteredToolNames
|
|
1165
|
+
: resolveRegisteredToolNames(pi, event.activeToolNames)),
|
|
1141
1166
|
};
|
|
1142
1167
|
}
|
|
1143
1168
|
if (isGeneralGsdToolScopingRequested()) {
|
|
@@ -565,6 +565,7 @@ const PLANNING_SUBAGENT_TOOLS = new Set(["subagent", "task"]);
|
|
|
565
565
|
* manifests still declare per-unit subsets via ToolsPolicy.allowedSubagents.
|
|
566
566
|
*/
|
|
567
567
|
const PLANNING_DISPATCH_AGENT_REGISTRY = {
|
|
568
|
+
mnemo: { readOnlySpecialist: true },
|
|
568
569
|
scout: { readOnlySpecialist: true },
|
|
569
570
|
planner: { readOnlySpecialist: true },
|
|
570
571
|
reviewer: { readOnlySpecialist: true },
|
|
@@ -574,7 +575,7 @@ const PLANNING_DISPATCH_AGENT_REGISTRY = {
|
|
|
574
575
|
export const ALLOWED_PLANNING_DISPATCH_AGENTS = new Set(Object.entries(PLANNING_DISPATCH_AGENT_REGISTRY)
|
|
575
576
|
.filter(([, metadata]) => metadata.readOnlySpecialist)
|
|
576
577
|
.map(([agentId]) => agentId));
|
|
577
|
-
let
|
|
578
|
+
let warnedMissingControlledDispatchAgentClasses = false;
|
|
578
579
|
function isReadOnlySpecialist(agentId) {
|
|
579
580
|
const metadata = PLANNING_DISPATCH_AGENT_REGISTRY[agentId];
|
|
580
581
|
return metadata?.readOnlySpecialist === true;
|
|
@@ -582,12 +583,16 @@ function isReadOnlySpecialist(agentId) {
|
|
|
582
583
|
function allowedPlanningDispatchAgentsList() {
|
|
583
584
|
return [...ALLOWED_PLANNING_DISPATCH_AGENTS].join(", ");
|
|
584
585
|
}
|
|
585
|
-
function
|
|
586
|
-
|
|
586
|
+
function allowsControlledSubagentDispatch(policy) {
|
|
587
|
+
return ((policy.mode === "planning-dispatch" || policy.mode === "verification") &&
|
|
588
|
+
Array.isArray(policy.allowedSubagents));
|
|
589
|
+
}
|
|
590
|
+
function warnMissingControlledDispatchAgentClasses(unitType, mode, toolName) {
|
|
591
|
+
if (warnedMissingControlledDispatchAgentClasses)
|
|
587
592
|
return;
|
|
588
|
-
|
|
593
|
+
warnedMissingControlledDispatchAgentClasses = true;
|
|
589
594
|
// TODO(#5060): Remove this migration shim once all subagent/task callers are verified to forward agent identities.
|
|
590
|
-
const message = `[write-gate]
|
|
595
|
+
const message = `[write-gate] controlled-dispatch: shouldBlockPlanningUnit called for tool "${toolName}" ` +
|
|
591
596
|
`on unit "${unitType}" without agentClasses - stale caller; blocking dispatch.`;
|
|
592
597
|
console.warn(message);
|
|
593
598
|
logWarning("intercept", message, {
|
|
@@ -653,8 +658,9 @@ function blockReason(unitType, mode, what) {
|
|
|
653
658
|
* - "docs" → like "planning" but also allows writes to paths
|
|
654
659
|
* matching `allowedPathGlobs` relative to basePath.
|
|
655
660
|
* - "verification"
|
|
656
|
-
* → allows Bash for project verification commands,
|
|
657
|
-
* writes restricted to .gsd
|
|
661
|
+
* → allows Bash for project verification commands, keeps
|
|
662
|
+
* writes restricted to .gsd/, and permits subagent dispatch
|
|
663
|
+
* only when the manifest declares allowedSubagents.
|
|
658
664
|
*
|
|
659
665
|
* `pathOrCommand` is the file path for write/edit-shaped tools and the
|
|
660
666
|
* shell command for bash. Other tools ignore this argument.
|
|
@@ -695,7 +701,7 @@ export function shouldBlockPlanningUnit(toolName, pathOrCommand, basePath, unitT
|
|
|
695
701
|
if (tool.startsWith("gsd_"))
|
|
696
702
|
return { block: false };
|
|
697
703
|
if (PLANNING_SUBAGENT_TOOLS.has(tool)) {
|
|
698
|
-
if (policy
|
|
704
|
+
if (allowsControlledSubagentDispatch(policy)) {
|
|
699
705
|
const requested = (agentClasses ?? []).map(a => a.trim()).filter(Boolean);
|
|
700
706
|
const dispatchContract = compileSubagentPermissionContract(policy);
|
|
701
707
|
const allowedSubagents = dispatchContract.allowedSubagents;
|
|
@@ -704,7 +710,7 @@ export function shouldBlockPlanningUnit(toolName, pathOrCommand, basePath, unitT
|
|
|
704
710
|
// agent identities yet. Block and warn so stale callers surface in telemetry
|
|
705
711
|
// instead of silently bypassing the gate.
|
|
706
712
|
if (agentClasses === undefined) {
|
|
707
|
-
|
|
713
|
+
warnMissingControlledDispatchAgentClasses(unitType, policy.mode, tool);
|
|
708
714
|
return {
|
|
709
715
|
block: true,
|
|
710
716
|
reason: blockReason(unitType, policy.mode, `subagent dispatch blocked: stale caller did not supply agent identities for "${tool}"; update extractSubagentAgentClasses to handle this input shape`),
|
|
@@ -720,7 +726,7 @@ export function shouldBlockPlanningUnit(toolName, pathOrCommand, basePath, unitT
|
|
|
720
726
|
if (globallyDisallowed) {
|
|
721
727
|
return {
|
|
722
728
|
block: true,
|
|
723
|
-
reason: blockReason(unitType, policy.mode, `subagent dispatch of "${globallyDisallowed}" not permitted; only read-only specialists (${allowedPlanningDispatchAgentsList()}) may be dispatched from
|
|
729
|
+
reason: blockReason(unitType, policy.mode, `subagent dispatch of "${globallyDisallowed}" not permitted; only read-only specialists (${allowedPlanningDispatchAgentsList()}) may be dispatched from ${policy.mode} units`),
|
|
724
730
|
};
|
|
725
731
|
}
|
|
726
732
|
const disallowedByPolicy = requested.find(a => !allowed.has(a));
|
|
@@ -1,17 +1,44 @@
|
|
|
1
1
|
// Project/App: gsd-pi
|
|
2
2
|
// File Purpose: Shared browser-observable UAT requirement and evidence detection.
|
|
3
|
-
export const BROWSER_REQUIREMENT_RE = /\b(?:
|
|
3
|
+
export const BROWSER_REQUIREMENT_RE = /\b(?:file:\/\/|localhost|playwright|chrome|screenshot|snapshot|browser_(?:assert|batch|find|verify|snapshot_refs))\b|\b(?:open|launch|navigate|load|visit|serve|start)\b.{0,80}\b(?:browser|page|localhost|file:\/\/)\b|\bbrowser\s+(?:check|session|test|uat|tool|automation|interaction|flow)\b/i;
|
|
4
4
|
export const NO_BROWSER_EVIDENCE_RE = /\b(?:no|without|not|wasn'?t|isn'?t)\s+(?:automated\s+)?(?:live\s+)?browser(?:\s+(?:session|test|uat))?|\bno\s+automated\s+browser\b|\bnot\s+conducted\b/i;
|
|
5
5
|
export const BROWSER_RUNTIME_RE = /\b(?:browser|playwright|chrome|camoufox|browser_(?:assert|batch|find|verify|snapshot_refs)|screenshot|snapshot|file:\/\/|localhost)\b/i;
|
|
6
6
|
export const BROWSER_ACTION_RE = /\b(?:open(?:ed)?|navigate(?:d)?|click(?:ed)?|type(?:d)?|reload(?:ed)?|capture(?:d)?|screenshot|snapshot)\b/i;
|
|
7
7
|
export const BROWSER_ASSERTION_RE = /\b(?:assert(?:ed|ion)?|observed|confirmed|verified|expected|visible|text|count|label|strikethrough|localstorage|screenshot|snapshot|passed)\b/i;
|
|
8
|
+
const NON_REQUIREMENT_BROWSER_HEADING_RE = /^(?:not\s+proven|not\s+covered|out\s+of\s+scope|deferred|follow-?ups?|known\s+limitations|notes\s+for\s+tester)\b/i;
|
|
9
|
+
const NON_REQUIREMENT_BROWSER_LINE_RE = /\b(?:deferred|not\s+proven|not\s+covered|out\s+of\s+scope|future\s+slice|follow-?up|no\s+(?:live\s+)?browser|without\s+(?:a\s+)?browser|not\s+(?:a\s+)?browser)\b/i;
|
|
8
10
|
export function compactTextParts(parts) {
|
|
9
11
|
return parts.flatMap((part) => Array.isArray(part) ? part : [part])
|
|
10
12
|
.filter((part) => typeof part === "string" && part.trim().length > 0)
|
|
11
13
|
.join("\n");
|
|
12
14
|
}
|
|
13
15
|
export function hasBrowserRequiredText(text) {
|
|
14
|
-
|
|
16
|
+
let inNonRequirementSection = false;
|
|
17
|
+
let nonRequirementDepth = 0;
|
|
18
|
+
for (const line of text.split(/\r?\n/)) {
|
|
19
|
+
const headingMatch = line.match(/^(#{1,6})\s+(.+?)\s*$/);
|
|
20
|
+
if (headingMatch) {
|
|
21
|
+
const depth = headingMatch[1].length;
|
|
22
|
+
const title = headingMatch[2] ?? "";
|
|
23
|
+
// Only update section context when at the same or higher level than the
|
|
24
|
+
// heading that opened the non-requirement zone. A sub-heading deeper than
|
|
25
|
+
// the opening heading must not escape or re-enter the zone on its own.
|
|
26
|
+
if (!inNonRequirementSection || depth <= nonRequirementDepth) {
|
|
27
|
+
inNonRequirementSection = NON_REQUIREMENT_BROWSER_HEADING_RE.test(title);
|
|
28
|
+
nonRequirementDepth = inNonRequirementSection ? depth : 0;
|
|
29
|
+
}
|
|
30
|
+
// Check the heading title itself — section state is already updated, so
|
|
31
|
+
// we correctly skip headings that opened a non-requirement zone.
|
|
32
|
+
if (!inNonRequirementSection && BROWSER_REQUIREMENT_RE.test(title))
|
|
33
|
+
return true;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if (inNonRequirementSection || NON_REQUIREMENT_BROWSER_LINE_RE.test(line))
|
|
37
|
+
continue;
|
|
38
|
+
if (BROWSER_REQUIREMENT_RE.test(line))
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
return false;
|
|
15
42
|
}
|
|
16
43
|
export function hasBrowserEvidenceText(text) {
|
|
17
44
|
if (!text.trim())
|
|
@@ -3,7 +3,7 @@ import { join, resolve } from "node:path";
|
|
|
3
3
|
import { loadRegistry } from "../workflow-templates.js";
|
|
4
4
|
import { gsdHome } from "../gsd-home.js";
|
|
5
5
|
import { VISUAL_BRIEF_MODES } from "../../visual-brief/prompts.js";
|
|
6
|
-
export const GSD_COMMAND_DESCRIPTION = "GSD — Git Ship Done: /gsd help|start|templates|next|auto|stop|pause|status|widget|visualize|brief|report|queue|quick|discuss|capture|triage|dispatch|verdict|history|undo|undo-task|reset-slice|rate|skip|export|cleanup|closeout|model|mode|prefs|config|keys|hooks|run-hook|skill-health|doctor|debug|logs|forensics|changelog|migrate|remote|steer|knowledge|memory|new-milestone|new-project|parallel|cmux|park|unpark|init|setup|onboarding|inspect|extensions|update|upgrade|fast|mcp|rethink|workflow|codebase|notifications|ship|do|usage|context|session-report|backlog|pr-branch|add-tests|scan|language|worktree|eval-review";
|
|
6
|
+
export const GSD_COMMAND_DESCRIPTION = "GSD — Git Ship Done: /gsd help|start|templates|next|auto|stop|pause|status|widget|visualize|brief|report|queue|quick|discuss|capture|triage|dispatch|verdict|history|undo|undo-task|reset-slice|rate|skip|export|cleanup|closeout|rebuild|model|mode|prefs|config|keys|hooks|run-hook|skill-health|doctor|debug|logs|forensics|changelog|migrate|remote|steer|knowledge|memory|new-milestone|new-project|parallel|cmux|park|unpark|init|setup|onboarding|inspect|extensions|update|upgrade|fast|mcp|rethink|workflow|codebase|notifications|ship|do|usage|context|session-report|backlog|pr-branch|add-tests|scan|language|worktree|eval-review";
|
|
7
7
|
export const TOP_LEVEL_SUBCOMMANDS = [
|
|
8
8
|
{ cmd: "help", desc: "Categorized command reference with descriptions" },
|
|
9
9
|
{ cmd: "next", desc: "Explicit step mode — run one unit, then pause" },
|
|
@@ -32,6 +32,7 @@ export const TOP_LEVEL_SUBCOMMANDS = [
|
|
|
32
32
|
{ cmd: "export", desc: "Alias for /gsd report" },
|
|
33
33
|
{ cmd: "cleanup", desc: "Remove merged branches or snapshots" },
|
|
34
34
|
{ cmd: "closeout", desc: "Recover failed git closeout actions (status, retry, resolve)" },
|
|
35
|
+
{ cmd: "rebuild", desc: "Rebuild markdown projections from the canonical DB" },
|
|
35
36
|
{ cmd: "model", desc: "Switch the active session model or open a picker" },
|
|
36
37
|
{ cmd: "mode", desc: "Switch workflow mode (solo/team)" },
|
|
37
38
|
{ cmd: "prefs", desc: "Manage preferences (model selection, timeouts, etc.)" },
|
|
@@ -201,6 +202,10 @@ const NESTED_COMPLETIONS = {
|
|
|
201
202
|
{ cmd: "retry", desc: "Retry the latest failed closeout git action" },
|
|
202
203
|
{ cmd: "resolve", desc: "Mark closeout resolved after the worktree is clean" },
|
|
203
204
|
],
|
|
205
|
+
rebuild: [
|
|
206
|
+
{ cmd: "markdown", desc: "Rebuild markdown projections from the canonical DB" },
|
|
207
|
+
{ cmd: "database", desc: "Reserved for DB-native rebuilds; does not import markdown" },
|
|
208
|
+
],
|
|
204
209
|
knowledge: [
|
|
205
210
|
{ cmd: "rule", desc: "Add a project rule (always/never do X)" },
|
|
206
211
|
{ cmd: "pattern", desc: "Add a code pattern to follow" },
|
|
@@ -51,6 +51,7 @@ export function showHelp(ctx, args = "") {
|
|
|
51
51
|
" /gsd keys API key manager (LLM + tool keys)",
|
|
52
52
|
" /gsd doctor Diagnose and repair .gsd/ state",
|
|
53
53
|
" /gsd closeout Recover failed git closeout actions",
|
|
54
|
+
" /gsd rebuild Rebuild markdown projections from the DB [markdown]",
|
|
54
55
|
"",
|
|
55
56
|
"Use /gsd help full for the complete command reference.",
|
|
56
57
|
];
|
|
@@ -68,7 +69,7 @@ export function showHelp(ctx, args = "") {
|
|
|
68
69
|
" /gsd new-milestone Create milestone from headless context (used by gsd headless)",
|
|
69
70
|
" /gsd new-project Bootstrap a new project (use --deep for staged project-level discovery)",
|
|
70
71
|
" /gsd quick Execute a quick task without full planning overhead",
|
|
71
|
-
" /gsd dispatch Dispatch a specific phase directly [research|plan|execute|complete|uat|replan]",
|
|
72
|
+
" /gsd dispatch Dispatch a specific phase directly [research|plan|execute|complete|validate|reassess|uat|replan]",
|
|
72
73
|
" /gsd verdict <v> Override milestone validation verdict [pass|needs-attention|needs-remediation] [--milestone Mxxx] [--rationale \"...\"]",
|
|
73
74
|
" /gsd parallel Parallel milestone orchestration [start|status|stop|pause|resume|merge|watch]",
|
|
74
75
|
" /gsd workflow Custom workflow lifecycle [new|run|list|validate|pause|resume]",
|
|
@@ -132,7 +133,7 @@ export function showHelp(ctx, args = "") {
|
|
|
132
133
|
" /gsd skill-health Skill lifecycle dashboard",
|
|
133
134
|
" /gsd extensions Manage extensions [list|enable|disable|info]",
|
|
134
135
|
" /gsd fast Toggle OpenAI service tier [on|off|flex|status]",
|
|
135
|
-
" /gsd mcp MCP server management [status|check|test|enable|disable|import|delete|init]",
|
|
136
|
+
" /gsd mcp MCP server management [status|check|discover|test|enable|disable|import|delete|init]",
|
|
136
137
|
"",
|
|
137
138
|
"MAINTENANCE",
|
|
138
139
|
" /gsd doctor Diagnose and repair .gsd/ state [audit|fix|heal] [scope]",
|
|
@@ -141,6 +142,9 @@ export function showHelp(ctx, args = "") {
|
|
|
141
142
|
" /gsd export Alias for /gsd report",
|
|
142
143
|
" /gsd cleanup Remove merged branches or snapshots [branches|snapshots]",
|
|
143
144
|
" /gsd closeout Recover failed git closeout actions [status|retry|resolve] [unit-id]",
|
|
145
|
+
" /gsd rebuild markdown Rebuild markdown projections from the canonical DB",
|
|
146
|
+
" /gsd rebuild database Reserved for DB-native rebuilds; does not import markdown",
|
|
147
|
+
" /gsd recover --confirm Import markdown into the DB after DB loss/corruption",
|
|
144
148
|
" /gsd worktree Manage worktrees from the TUI [list|merge|clean|remove]",
|
|
145
149
|
" /gsd migrate Migrate .planning/ (v1) to DB-backed .gsd/ with backup + audit",
|
|
146
150
|
" /gsd remote Control remote auto-mode [slack|discord|status|disconnect]",
|