@opengsd/gsd-pi 1.1.1-dev.3ea310e → 1.1.1-dev.595401e
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/resources/.managed-resources-content-hash +1 -1
- 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 +5 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +132 -8
- package/dist/resources/extensions/gsd/auto-prompts.js +68 -22
- package/dist/resources/extensions/gsd/auto-start.js +41 -12
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +2 -1
- package/dist/resources/extensions/gsd/auto.js +12 -5
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +82 -3
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +43 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +30 -9
- 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/handlers/core.js +1 -1
- 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 +5 -2
- package/dist/resources/extensions/gsd/guided-flow.js +29 -68
- package/dist/resources/extensions/gsd/memory-store.js +4 -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 +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/roadmap.js +18 -1
- package/dist/resources/extensions/gsd/state-reconciliation/index.js +6 -0
- package/dist/resources/extensions/gsd/state.js +3 -3
- package/dist/resources/extensions/gsd/templates/plan.md +3 -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/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 +1 -1
- package/dist/resources/extensions/gsd/workflow-mcp.js +5 -1
- package/dist/rtk.d.ts +7 -1
- package/dist/rtk.js +27 -11
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +7 -7
- 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/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 +7 -7
- 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 +3 -2
- 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 +89 -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-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 +86 -18
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +108 -40
- 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/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 +5 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +164 -7
- package/src/resources/extensions/gsd/auto-prompts.ts +102 -15
- package/src/resources/extensions/gsd/auto-start.ts +54 -14
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +2 -1
- package/src/resources/extensions/gsd/auto.ts +15 -4
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +89 -3
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +51 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +51 -14
- 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/handlers/core.ts +1 -1
- 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 +5 -2
- package/src/resources/extensions/gsd/guided-flow.ts +90 -82
- package/src/resources/extensions/gsd/memory-store.ts +4 -1
- 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/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 +3 -3
- 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 +37 -0
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +16 -3
- 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/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 +8 -0
- package/src/resources/extensions/gsd/tests/discuss-milestone-structured-questions.test.ts +31 -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/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/memory-maintenance.test.ts +39 -8
- 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/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/skill-activation.test.ts +55 -0
- 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-naming.test.ts +12 -2
- 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 +2 -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/tools/complete-task.ts +20 -2
- package/src/resources/extensions/gsd/tools/exec-tool.ts +130 -0
- 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 +67 -4
- 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 +1 -1
- package/src/resources/extensions/gsd/workflow-mcp.ts +5 -1
- /package/dist/web/standalone/.next/static/{xACmObbrDjwLriepRgaa9 → IDKjyRHLIaumjgonPcYiX}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{xACmObbrDjwLriepRgaa9 → IDKjyRHLIaumjgonPcYiX}/_ssgManifest.js +0 -0
|
@@ -45,6 +45,7 @@ import { classifyProject, type ProjectClassification } from "./detection.js";
|
|
|
45
45
|
import { hasBrowserRequiredText } from "./browser-evidence.js";
|
|
46
46
|
import { debugLog } from "./debug-logger.js";
|
|
47
47
|
import { buildSkillActivationBlock, buildSkillDiscoveryVars } from "./skill-activation.js";
|
|
48
|
+
import { findMilestoneIds } from "./milestone-ids.js";
|
|
48
49
|
|
|
49
50
|
export { buildSkillActivationBlock, buildSkillDiscoveryVars };
|
|
50
51
|
|
|
@@ -1428,7 +1429,7 @@ export async function checkNeedsRunUat(
|
|
|
1428
1429
|
// If the UAT file already contains a verdict, UAT has been run — skip
|
|
1429
1430
|
if (hasVerdict(uatContent)) continue;
|
|
1430
1431
|
// Also check the ASSESSMENT file — the run-uat prompt writes the verdict
|
|
1431
|
-
// there (via
|
|
1432
|
+
// there (via gsd_uat_result_save), not into the
|
|
1432
1433
|
// UAT spec file. Without this check the unit re-dispatches indefinitely.
|
|
1433
1434
|
const assessmentFile = resolveSliceFile(base, mid, sid, "ASSESSMENT");
|
|
1434
1435
|
if (assessmentFile) {
|
|
@@ -1482,21 +1483,84 @@ export async function checkNeedsRunUat(
|
|
|
1482
1483
|
* as a seed when present. The discussion agent interviews the user, writes
|
|
1483
1484
|
* a full CONTEXT.md, and the phase transitions to pre-planning automatically.
|
|
1484
1485
|
*/
|
|
1486
|
+
export interface DiscussMilestonePromptOptions {
|
|
1487
|
+
headless?: boolean;
|
|
1488
|
+
commitInstruction?: string;
|
|
1489
|
+
fastPathInstruction?: string;
|
|
1490
|
+
includeDraftSeed?: boolean;
|
|
1491
|
+
includeContextMode?: boolean;
|
|
1492
|
+
}
|
|
1493
|
+
|
|
1494
|
+
export async function buildDiscussMilestoneInlinedContext(mid: string, base: string): Promise<string> {
|
|
1495
|
+
const inlined: string[] = [];
|
|
1496
|
+
|
|
1497
|
+
const roadmapInline = await inlineFileOptional(
|
|
1498
|
+
resolveMilestoneFile(base, mid, "ROADMAP"),
|
|
1499
|
+
relMilestoneFile(base, mid, "ROADMAP"),
|
|
1500
|
+
"Milestone Roadmap",
|
|
1501
|
+
);
|
|
1502
|
+
if (roadmapInline) inlined.push(roadmapInline);
|
|
1503
|
+
|
|
1504
|
+
const contextInline = await inlineFileOptional(
|
|
1505
|
+
resolveMilestoneFile(base, mid, "CONTEXT"),
|
|
1506
|
+
relMilestoneFile(base, mid, "CONTEXT"),
|
|
1507
|
+
"Milestone Context",
|
|
1508
|
+
);
|
|
1509
|
+
if (contextInline) inlined.push(contextInline);
|
|
1510
|
+
|
|
1511
|
+
const researchInline = await inlineFileOptional(
|
|
1512
|
+
resolveMilestoneFile(base, mid, "RESEARCH"),
|
|
1513
|
+
relMilestoneFile(base, mid, "RESEARCH"),
|
|
1514
|
+
"Milestone Research",
|
|
1515
|
+
);
|
|
1516
|
+
if (researchInline) inlined.push(researchInline);
|
|
1517
|
+
|
|
1518
|
+
const decisionsPath = resolveGsdRootFile(base, "DECISIONS");
|
|
1519
|
+
if (existsSync(decisionsPath)) {
|
|
1520
|
+
const decisionsContent = await loadFile(decisionsPath);
|
|
1521
|
+
if (decisionsContent) {
|
|
1522
|
+
inlined.push(`### Decisions Register\nSource: \`${relGsdRootFile("DECISIONS")}\`\n\n${decisionsContent.trim()}`);
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
const milestoneIds = findMilestoneIds(base);
|
|
1527
|
+
const currentIndex = milestoneIds.indexOf(mid);
|
|
1528
|
+
const priorMilestoneIds = currentIndex >= 0 ? milestoneIds.slice(0, currentIndex) : milestoneIds;
|
|
1529
|
+
for (const priorMid of priorMilestoneIds) {
|
|
1530
|
+
const summaryInline = await inlineFileOptional(
|
|
1531
|
+
resolveMilestoneFile(base, priorMid, "SUMMARY"),
|
|
1532
|
+
relMilestoneFile(base, priorMid, "SUMMARY"),
|
|
1533
|
+
`${priorMid} Prior Milestone Summary`,
|
|
1534
|
+
);
|
|
1535
|
+
if (summaryInline) inlined.push(summaryInline);
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1538
|
+
return inlined.length > 0
|
|
1539
|
+
? `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`
|
|
1540
|
+
: "## Inlined Context\n\n_(no milestone context files found yet — go in blind and ask broad questions)_";
|
|
1541
|
+
}
|
|
1542
|
+
|
|
1485
1543
|
export async function buildDiscussMilestonePrompt(
|
|
1486
1544
|
mid: string,
|
|
1487
1545
|
midTitle: string,
|
|
1488
1546
|
base: string,
|
|
1489
1547
|
structuredQuestionsAvailable = "false",
|
|
1490
|
-
{
|
|
1548
|
+
{
|
|
1549
|
+
headless = false,
|
|
1550
|
+
commitInstruction = "Do not commit planning artifacts — .gsd/ is managed externally.",
|
|
1551
|
+
fastPathInstruction = "",
|
|
1552
|
+
includeDraftSeed = true,
|
|
1553
|
+
includeContextMode = true,
|
|
1554
|
+
}: DiscussMilestonePromptOptions = {},
|
|
1491
1555
|
): Promise<string> {
|
|
1492
|
-
const
|
|
1556
|
+
const contextTemplate = inlineTemplate("context", "Context");
|
|
1493
1557
|
|
|
1494
1558
|
if (headless) {
|
|
1495
1559
|
const roadmapPath = resolveMilestoneFile(base, mid, "ROADMAP");
|
|
1496
1560
|
const roadmapContent = roadmapPath ? await loadFile(roadmapPath) : null;
|
|
1497
1561
|
return loadPrompt("discuss-headless", {
|
|
1498
1562
|
seedContext: roadmapContent ?? "",
|
|
1499
|
-
inlinedTemplates:
|
|
1563
|
+
inlinedTemplates: contextTemplate,
|
|
1500
1564
|
workingDirectory: base,
|
|
1501
1565
|
milestoneId: mid,
|
|
1502
1566
|
contextPath: relMilestoneFile(base, mid, "CONTEXT"),
|
|
@@ -1505,7 +1569,9 @@ export async function buildDiscussMilestonePrompt(
|
|
|
1505
1569
|
});
|
|
1506
1570
|
}
|
|
1507
1571
|
|
|
1508
|
-
const
|
|
1572
|
+
const rawInlinedContext = await buildDiscussMilestoneInlinedContext(mid, base);
|
|
1573
|
+
const cappedInlinedContext = capPreamble(rawInlinedContext);
|
|
1574
|
+
const discussTemplates = [cappedInlinedContext, contextTemplate].join("\n\n---\n\n");
|
|
1509
1575
|
|
|
1510
1576
|
const basePrompt = loadPrompt("guided-discuss-milestone", {
|
|
1511
1577
|
workingDirectory: base,
|
|
@@ -1513,20 +1579,22 @@ export async function buildDiscussMilestonePrompt(
|
|
|
1513
1579
|
milestoneTitle: midTitle,
|
|
1514
1580
|
inlinedTemplates: discussTemplates,
|
|
1515
1581
|
structuredQuestionsAvailable,
|
|
1516
|
-
commitInstruction
|
|
1517
|
-
fastPathInstruction
|
|
1582
|
+
commitInstruction,
|
|
1583
|
+
fastPathInstruction,
|
|
1518
1584
|
});
|
|
1519
|
-
const promptWithContextMode =
|
|
1585
|
+
const promptWithContextMode = includeContextMode
|
|
1586
|
+
? prependContextModeToBlock("discuss-milestone", base, basePrompt)
|
|
1587
|
+
: basePrompt;
|
|
1520
1588
|
|
|
1521
1589
|
// If a CONTEXT-DRAFT.md exists, append it as seed material
|
|
1522
1590
|
const draftPath = resolveMilestoneFile(base, mid, "CONTEXT-DRAFT");
|
|
1523
1591
|
const draftContent = draftPath ? await loadFile(draftPath) : null;
|
|
1524
1592
|
|
|
1525
|
-
if (draftContent) {
|
|
1593
|
+
if (includeDraftSeed && draftContent) {
|
|
1526
1594
|
return `${promptWithContextMode}\n\n## Prior Discussion (Draft Seed)\n\nThe following draft was captured from a prior multi-milestone discussion. Use it as seed material — the user has already provided this context. Start with a brief reflection on what the draft covers, then probe for any gaps or open questions before writing the full CONTEXT.md.\n\n${draftContent}`;
|
|
1527
1595
|
}
|
|
1528
1596
|
|
|
1529
|
-
return
|
|
1597
|
+
return promptWithContextMode;
|
|
1530
1598
|
}
|
|
1531
1599
|
|
|
1532
1600
|
/**
|
|
@@ -2711,6 +2779,15 @@ export async function buildCompleteSlicePrompt(
|
|
|
2711
2779
|
sliceSummaryPath,
|
|
2712
2780
|
sliceUatPath,
|
|
2713
2781
|
gatesToClose,
|
|
2782
|
+
skillActivation: buildSkillActivationBlock({
|
|
2783
|
+
base,
|
|
2784
|
+
milestoneId: mid,
|
|
2785
|
+
milestoneTitle: midTitle,
|
|
2786
|
+
sliceId: sid,
|
|
2787
|
+
sliceTitle: sTitle,
|
|
2788
|
+
extraContext: [inlinedContext],
|
|
2789
|
+
unitType: "complete-slice",
|
|
2790
|
+
}),
|
|
2714
2791
|
});
|
|
2715
2792
|
}
|
|
2716
2793
|
|
|
@@ -2909,13 +2986,23 @@ export async function buildValidateMilestonePrompt(
|
|
|
2909
2986
|
if (isDbAvailable()) {
|
|
2910
2987
|
const milestone = getMilestone(mid);
|
|
2911
2988
|
if (milestone) {
|
|
2989
|
+
const escapeCell = (value: string) =>
|
|
2990
|
+
value.replace(/[\\|]/g, (char) => `\\${char}`).replace(/\r?\n/g, " ");
|
|
2912
2991
|
const classes: string[] = [];
|
|
2913
|
-
if (milestone.verification_contract) classes.push(
|
|
2914
|
-
if (milestone.verification_integration) classes.push(
|
|
2915
|
-
if (milestone.verification_operational) classes.push(
|
|
2916
|
-
if (milestone.verification_uat) classes.push(
|
|
2992
|
+
if (milestone.verification_contract) classes.push(`| Contract | ${escapeCell(milestone.verification_contract)} |`);
|
|
2993
|
+
if (milestone.verification_integration) classes.push(`| Integration | ${escapeCell(milestone.verification_integration)} |`);
|
|
2994
|
+
if (milestone.verification_operational) classes.push(`| Operational | ${escapeCell(milestone.verification_operational)} |`);
|
|
2995
|
+
if (milestone.verification_uat) classes.push(`| UAT | ${escapeCell(milestone.verification_uat)} |`);
|
|
2917
2996
|
if (classes.length > 0) {
|
|
2918
|
-
const verificationClasses =
|
|
2997
|
+
const verificationClasses = [
|
|
2998
|
+
"### Verification Classes (from planning)",
|
|
2999
|
+
"",
|
|
3000
|
+
"These verification tiers were defined during milestone planning. Every row in this table must appear in `verificationClasses` with the same canonical class name.",
|
|
3001
|
+
"",
|
|
3002
|
+
"| Class | Planned Check |",
|
|
3003
|
+
"| --- | --- |",
|
|
3004
|
+
...classes,
|
|
3005
|
+
].join("\n");
|
|
2919
3006
|
inlined.push(verificationClasses);
|
|
2920
3007
|
trackPromptContext(contextTelemetry, "verification-classes", "inline", verificationClasses);
|
|
2921
3008
|
}
|
|
@@ -101,6 +101,7 @@ import {
|
|
|
101
101
|
} from "./preferences-models.js";
|
|
102
102
|
import type { WorktreeLifecycle } from "./worktree-lifecycle.js";
|
|
103
103
|
import { getSessionModelOverride } from "./session-model-override.js";
|
|
104
|
+
import { setAutoActiveStatus } from "./auto-dashboard.js";
|
|
104
105
|
|
|
105
106
|
export interface BootstrapDeps {
|
|
106
107
|
shouldUseWorktreeIsolation: (basePath?: string) => boolean;
|
|
@@ -293,6 +294,7 @@ export interface OrphanAuditAction {
|
|
|
293
294
|
message: string;
|
|
294
295
|
severity: "info" | "warning";
|
|
295
296
|
branch?: string;
|
|
297
|
+
mainBranch?: string;
|
|
296
298
|
commitsAhead?: number;
|
|
297
299
|
dirtyWorktree?: boolean;
|
|
298
300
|
worktreeDirExists?: boolean;
|
|
@@ -311,6 +313,27 @@ function isBlockingStrandedWorkAction(action: OrphanAuditAction): boolean {
|
|
|
311
313
|
return action.kind === "in-progress-stranded-work" && action.blocksAuto;
|
|
312
314
|
}
|
|
313
315
|
|
|
316
|
+
function strandedWorkEvidence(args: {
|
|
317
|
+
branch?: string;
|
|
318
|
+
commitsAhead: number;
|
|
319
|
+
mainBranch: string;
|
|
320
|
+
dirtyWorktree: boolean;
|
|
321
|
+
}): string[] {
|
|
322
|
+
const evidence: string[] = [];
|
|
323
|
+
if (args.branch && args.commitsAhead > 0) {
|
|
324
|
+
evidence.push(
|
|
325
|
+
`branch ${args.branch} has ${args.commitsAhead} commit(s) ahead of ${args.mainBranch}`,
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
if (args.dirtyWorktree) {
|
|
329
|
+
evidence.push("the worktree has uncommitted changes");
|
|
330
|
+
}
|
|
331
|
+
if (evidence.length === 0) {
|
|
332
|
+
evidence.push("physical git evidence exists");
|
|
333
|
+
}
|
|
334
|
+
return evidence;
|
|
335
|
+
}
|
|
336
|
+
|
|
314
337
|
function detectWorktreeEvidence(
|
|
315
338
|
basePath: string,
|
|
316
339
|
milestoneId: string,
|
|
@@ -342,18 +365,7 @@ function strandedWorkMessage(args: {
|
|
|
342
365
|
worktreeDirExists: boolean;
|
|
343
366
|
recoveryMode: StrandedWorkRecoveryMode;
|
|
344
367
|
}): string {
|
|
345
|
-
const evidence
|
|
346
|
-
if (args.branch && args.commitsAhead > 0) {
|
|
347
|
-
evidence.push(
|
|
348
|
-
`branch ${args.branch} has ${args.commitsAhead} commit(s) ahead of ${args.mainBranch}`,
|
|
349
|
-
);
|
|
350
|
-
}
|
|
351
|
-
if (args.dirtyWorktree) {
|
|
352
|
-
evidence.push("the worktree has uncommitted changes");
|
|
353
|
-
}
|
|
354
|
-
if (evidence.length === 0) {
|
|
355
|
-
evidence.push("physical git evidence exists");
|
|
356
|
-
}
|
|
368
|
+
const evidence = strandedWorkEvidence(args);
|
|
357
369
|
|
|
358
370
|
const wtSuffix = args.worktreeDirExists
|
|
359
371
|
? ` Worktree directory at .gsd/worktrees/${args.milestoneId}/ holds live work.`
|
|
@@ -369,6 +381,26 @@ function strandedWorkMessage(args: {
|
|
|
369
381
|
);
|
|
370
382
|
}
|
|
371
383
|
|
|
384
|
+
function formatStrandedWorkRecoveryMessage(action: OrphanAuditAction): string {
|
|
385
|
+
const recoveryMode = action.recoveryMode === "worktree"
|
|
386
|
+
? "existing worktree"
|
|
387
|
+
: "milestone branch";
|
|
388
|
+
const evidence = strandedWorkEvidence({
|
|
389
|
+
branch: action.branch,
|
|
390
|
+
commitsAhead: action.commitsAhead ?? 0,
|
|
391
|
+
mainBranch: action.mainBranch ?? "main",
|
|
392
|
+
dirtyWorktree: action.dirtyWorktree ?? false,
|
|
393
|
+
});
|
|
394
|
+
const wtSuffix = action.worktreeDirExists
|
|
395
|
+
? ` Worktree directory at .gsd/worktrees/${action.milestoneId}/ holds live work.`
|
|
396
|
+
: "";
|
|
397
|
+
return (
|
|
398
|
+
`Resuming saved milestone work for ${action.milestoneId}: ${evidence.join("; ")}.` +
|
|
399
|
+
wtSuffix +
|
|
400
|
+
` Adopting the ${recoveryMode} before dispatching new units. Park or discard explicitly if abandoning.`
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
|
|
372
404
|
function formatStrandedWorkBlockerMessage(
|
|
373
405
|
action: OrphanAuditAction,
|
|
374
406
|
activeMilestoneId: string | null,
|
|
@@ -489,6 +521,7 @@ export function auditOrphanedMilestoneBranches(
|
|
|
489
521
|
kind: "in-progress-stranded-work",
|
|
490
522
|
milestoneId,
|
|
491
523
|
branch,
|
|
524
|
+
mainBranch,
|
|
492
525
|
commitsAhead,
|
|
493
526
|
dirtyWorktree: worktreeEvidence.dirty,
|
|
494
527
|
worktreeDirExists: worktreeEvidence.dirExists,
|
|
@@ -643,6 +676,7 @@ export function auditOrphanedMilestoneBranches(
|
|
|
643
676
|
pushAction({
|
|
644
677
|
kind: "in-progress-stranded-work",
|
|
645
678
|
milestoneId: m.id,
|
|
679
|
+
mainBranch,
|
|
646
680
|
commitsAhead: 0,
|
|
647
681
|
dirtyWorktree: true,
|
|
648
682
|
worktreeDirExists: worktreeEvidence.dirExists,
|
|
@@ -1158,7 +1192,13 @@ export async function bootstrapAutoSession(
|
|
|
1158
1192
|
for (const msg of auditResult.recovered) {
|
|
1159
1193
|
ctx.ui.notify(`Orphan audit: ${msg}`, "info");
|
|
1160
1194
|
}
|
|
1195
|
+
const deferredStrandedMessages = new Set(
|
|
1196
|
+
auditResult.actions
|
|
1197
|
+
.filter(isBlockingStrandedWorkAction)
|
|
1198
|
+
.map((action) => action.message),
|
|
1199
|
+
);
|
|
1161
1200
|
for (const msg of auditResult.warnings) {
|
|
1201
|
+
if (deferredStrandedMessages.has(msg)) continue;
|
|
1162
1202
|
const prefix = msg.startsWith("Stranded work") ? "" : "Orphan audit: ";
|
|
1163
1203
|
ctx.ui.notify(`${prefix}${msg}`, "warning");
|
|
1164
1204
|
}
|
|
@@ -1246,7 +1286,7 @@ export async function bootstrapAutoSession(
|
|
|
1246
1286
|
}
|
|
1247
1287
|
strandedRecoveryAction = blockingStrandedRecoveryAction;
|
|
1248
1288
|
ctx.ui.notify(
|
|
1249
|
-
|
|
1289
|
+
formatStrandedWorkRecoveryMessage(strandedRecoveryAction),
|
|
1250
1290
|
"info",
|
|
1251
1291
|
);
|
|
1252
1292
|
}
|
|
@@ -1718,7 +1758,7 @@ export async function bootstrapAutoSession(
|
|
|
1718
1758
|
snapshotSkills();
|
|
1719
1759
|
}
|
|
1720
1760
|
|
|
1721
|
-
ctx
|
|
1761
|
+
setAutoActiveStatus(ctx, s.stepMode ? "next" : "auto");
|
|
1722
1762
|
ctx.ui.setWidget("gsd-health", undefined);
|
|
1723
1763
|
const modeLabel = s.stepMode ? "Step-mode" : "Auto-mode";
|
|
1724
1764
|
const pendingCount = (state.registry ?? []).filter(
|
|
@@ -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
|
|
|
3
4
|
export const RUN_UAT_BROWSER_TOOL_NAMES = [
|
|
4
5
|
"browser_navigate",
|
|
@@ -44,7 +45,7 @@ export const AUTO_UNIT_SCOPED_TOOLS: Record<string, readonly string[]> = {
|
|
|
44
45
|
"execute-task": ["gsd_task_complete", "gsd_decision_save"],
|
|
45
46
|
"execute-task-simple": ["gsd_task_complete", "gsd_decision_save"],
|
|
46
47
|
"reactive-execute": ["gsd_task_complete", "gsd_decision_save"],
|
|
47
|
-
"run-uat": ["
|
|
48
|
+
"run-uat": [...RUN_UAT_WORKFLOW_TOOL_NAMES, "subagent", ...RUN_UAT_BROWSER_TOOL_NAMES],
|
|
48
49
|
"gate-evaluate": ["gsd_save_gate_result"],
|
|
49
50
|
"rewrite-docs": ["gsd_summary_save", "gsd_decision_save"],
|
|
50
51
|
"workflow-preferences": ["gsd_summary_save"],
|
|
@@ -205,6 +205,7 @@ import {
|
|
|
205
205
|
updateProgressWidget as _updateProgressWidget,
|
|
206
206
|
setCompletionProgressWidget,
|
|
207
207
|
setAutoOutcomeWidget,
|
|
208
|
+
setAutoActiveStatus,
|
|
208
209
|
updateSliceProgressCache,
|
|
209
210
|
clearSliceProgressCache,
|
|
210
211
|
describeNextUnit as _describeNextUnit,
|
|
@@ -2310,10 +2311,20 @@ export function createWiredAutoOrchestrationModule(
|
|
|
2310
2311
|
async reconcileBeforeDispatch() {
|
|
2311
2312
|
const activeBasePath = getLiveDispatchBasePath();
|
|
2312
2313
|
const result = await reconcileBeforeDispatch(activeBasePath);
|
|
2313
|
-
|
|
2314
|
+
// Failure-path summaries written by gsd_summary_save create
|
|
2315
|
+
// artifact-db-status-divergence blockers for tasks that are still
|
|
2316
|
+
// pending (gsd_task_complete never ran). These tasks can still be
|
|
2317
|
+
// dispatched and the drift self-heals once they complete successfully.
|
|
2318
|
+
const hardBlockers = result.blockers.filter(
|
|
2319
|
+
(b) =>
|
|
2320
|
+
!b.includes("has SUMMARY artifact while DB status is") &&
|
|
2321
|
+
!b.includes("has SUMMARY on disk while DB status is") &&
|
|
2322
|
+
!b.includes("has task SUMMARY artifacts but no DB tasks"),
|
|
2323
|
+
);
|
|
2324
|
+
if (hardBlockers.length > 0) {
|
|
2314
2325
|
return {
|
|
2315
2326
|
ok: false,
|
|
2316
|
-
reason:
|
|
2327
|
+
reason: hardBlockers[0],
|
|
2317
2328
|
stateSnapshot: result.stateSnapshot,
|
|
2318
2329
|
};
|
|
2319
2330
|
}
|
|
@@ -3022,7 +3033,7 @@ export async function startAuto(
|
|
|
3022
3033
|
ensureOrchestrationModule(ctx, pi, s.basePath || base);
|
|
3023
3034
|
registerSigtermHandler(lockBase());
|
|
3024
3035
|
|
|
3025
|
-
ctx
|
|
3036
|
+
setAutoActiveStatus(ctx, s.stepMode ? "next" : "auto");
|
|
3026
3037
|
ctx.ui.setWidget("gsd-health", undefined);
|
|
3027
3038
|
ctx.ui.notify(
|
|
3028
3039
|
s.stepMode ? "Step-mode resumed." : "Auto-mode resumed.",
|
|
@@ -3351,7 +3362,7 @@ export async function dispatchHookUnit(
|
|
|
3351
3362
|
await pauseAuto(ctx, pi);
|
|
3352
3363
|
}, hookHardTimeoutMs);
|
|
3353
3364
|
|
|
3354
|
-
ctx
|
|
3365
|
+
setAutoActiveStatus(ctx, s.stepMode ? "next" : "auto");
|
|
3355
3366
|
ctx.ui.notify(`Running post-unit hook: ${hookName}`, "info");
|
|
3356
3367
|
|
|
3357
3368
|
debugLog("dispatchHookUnit", {
|
|
@@ -413,6 +413,92 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
413
413
|
pi.registerTool(summarySaveTool);
|
|
414
414
|
registerAlias(pi, summarySaveTool, "gsd_save_summary", "gsd_summary_save");
|
|
415
415
|
|
|
416
|
+
// ─── gsd_uat_result_save ─────────────────────────────────────────────────
|
|
417
|
+
|
|
418
|
+
const uatResultSaveExecute = async (_toolCallId: string, params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
|
|
419
|
+
const { executeUatResultSave } = await loadWorkflowExecutors();
|
|
420
|
+
return executeUatResultSave(params, resolveWorkflowToolBasePath(_ctx, params));
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
const uatEvidenceRef = Type.Object({
|
|
424
|
+
kind: StringEnum(["gsd_uat_exec", "gsd_exec", "screenshot", "log", "url", "browser"], { description: "Evidence kind" }),
|
|
425
|
+
ref: Type.String({ description: "Evidence ID, approved .gsd path, or URL" }),
|
|
426
|
+
note: Type.Optional(Type.String({ description: "Short evidence note" })),
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
const uatCheck = Type.Object({
|
|
430
|
+
id: Type.String({ description: "Stable check ID from the UAT spec" }),
|
|
431
|
+
description: Type.String({ description: "Check description" }),
|
|
432
|
+
mode: StringEnum(["artifact", "runtime", "browser", "human-follow-up"], { description: "Evidence mode" }),
|
|
433
|
+
result: StringEnum(["PASS", "FAIL", "NEEDS-HUMAN"], { description: "Check result" }),
|
|
434
|
+
evidence: Type.Optional(Type.Array(uatEvidenceRef, { description: "Objective evidence references" })),
|
|
435
|
+
notes: Type.Optional(Type.String({ description: "Observed result, failure notes, or human instruction" })),
|
|
436
|
+
nonAutomatable: Type.Optional(Type.Boolean({ description: "True when the check is explicitly non-automatable" })),
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
const toolPresentationBlock = Type.Object({
|
|
440
|
+
surface: StringEnum(["provider-tools", "claude-code-sdk", "mcp", "hybrid"], { description: "Tool presentation surface" }),
|
|
441
|
+
model: Type.Optional(Type.Object({
|
|
442
|
+
provider: Type.Optional(Type.String()),
|
|
443
|
+
api: Type.Optional(Type.String()),
|
|
444
|
+
id: Type.Optional(Type.String()),
|
|
445
|
+
})),
|
|
446
|
+
presentedTools: Type.Array(Type.String(), { description: "Tool names actually presented to the model" }),
|
|
447
|
+
blockedTools: Type.Array(Type.Object({
|
|
448
|
+
name: Type.String(),
|
|
449
|
+
reason: Type.String(),
|
|
450
|
+
}), { description: "Tool names blocked from the model with reasons" }),
|
|
451
|
+
aliases: Type.Optional(Type.Array(Type.Object({
|
|
452
|
+
requested: Type.String(),
|
|
453
|
+
canonical: Type.String(),
|
|
454
|
+
}))),
|
|
455
|
+
fallbackToolsUsed: Type.Optional(Type.Array(Type.String())),
|
|
456
|
+
toolPresentationPlanId: Type.Optional(Type.String()),
|
|
457
|
+
notes: Type.Optional(Type.String()),
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
const uatResultSaveTool = {
|
|
461
|
+
name: "gsd_uat_result_save",
|
|
462
|
+
label: "Save UAT Result",
|
|
463
|
+
description:
|
|
464
|
+
"Save a structured UAT result for a slice. Validates evidence, writes the ASSESSMENT artifact, " +
|
|
465
|
+
"records attempt history, and saves the aggregate UAT gate result.",
|
|
466
|
+
promptSnippet: "Save structured UAT checks, evidence, verdict, and tool-presentation proof",
|
|
467
|
+
promptGuidelines: [
|
|
468
|
+
"Call gsd_uat_result_save once after all UAT checks have been executed.",
|
|
469
|
+
"Every PASS or FAIL check must cite objective evidence, preferably a gsd_uat_exec evidence ID.",
|
|
470
|
+
"Include the presented and blocked tool set in presentation so tool timing is auditable.",
|
|
471
|
+
"Do not use raw gsd_summary_save as a substitute for UAT results.",
|
|
472
|
+
],
|
|
473
|
+
parameters: Type.Object({
|
|
474
|
+
milestoneId: Type.String({ description: "Milestone ID (e.g. M001)" }),
|
|
475
|
+
sliceId: Type.String({ description: "Slice ID (e.g. S01)" }),
|
|
476
|
+
uatType: StringEnum(["artifact-driven", "browser-executable", "runtime-executable", "live-runtime", "mixed", "human-experience"], { description: "Declared UAT mode" }),
|
|
477
|
+
verdict: StringEnum(["PASS", "FAIL", "PARTIAL"], { description: "Overall UAT verdict" }),
|
|
478
|
+
checks: Type.Array(uatCheck, { description: "Structured check results" }),
|
|
479
|
+
presentation: toolPresentationBlock,
|
|
480
|
+
notes: Type.Optional(Type.String({ description: "Overall verdict rationale" })),
|
|
481
|
+
attempt: Type.Optional(Type.String({ description: "Attempt number or auto" })),
|
|
482
|
+
previousAttemptId: Type.Optional(Type.String({ description: "Prior attempt ID, when retrying" })),
|
|
483
|
+
}),
|
|
484
|
+
execute: uatResultSaveExecute,
|
|
485
|
+
renderCall(args: any, theme: any) {
|
|
486
|
+
let text = theme.fg("toolTitle", theme.bold("uat_result_save "));
|
|
487
|
+
text += theme.fg("accent", `${args.milestoneId ?? "?"}/${args.sliceId ?? "?"}`);
|
|
488
|
+
if (args.verdict) text += theme.fg("dim", ` → ${args.verdict}`);
|
|
489
|
+
return new Text(text, 0, 0);
|
|
490
|
+
},
|
|
491
|
+
renderResult(result: any, _options: any, theme: any) {
|
|
492
|
+
const d = readDetails(result);
|
|
493
|
+
if (result.isError || d?.error) {
|
|
494
|
+
return new Text(theme.fg("error", formatToolErrorText(result, d)), 0, 0);
|
|
495
|
+
}
|
|
496
|
+
return new Text(theme.fg("success", `UAT ${d?.sliceId ?? ""}: ${d?.verdict ?? "saved"}`), 0, 0);
|
|
497
|
+
},
|
|
498
|
+
};
|
|
499
|
+
|
|
500
|
+
pi.registerTool(uatResultSaveTool);
|
|
501
|
+
|
|
416
502
|
// ─── gsd_milestone_generate_id (formerly gsd_generate_milestone_id) ────
|
|
417
503
|
|
|
418
504
|
const milestoneGenerateIdExecute = async (_toolCallId: string, _params: any, _signal: AbortSignal | undefined, _onUpdate: unknown, _ctx: unknown) => {
|
|
@@ -746,7 +832,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
746
832
|
recommendation: Type.String({ description: "Option id the executor recommends." }),
|
|
747
833
|
recommendationRationale: Type.String({ description: "Why the recommendation — 1–2 sentences." }),
|
|
748
834
|
continueWithDefault: Type.Boolean({
|
|
749
|
-
description: "When true,
|
|
835
|
+
description: "When true, the recommendation is recorded as the default, but auto-mode still pauses until the user resolves via /gsd escalate resolve.",
|
|
750
836
|
}),
|
|
751
837
|
}, { description: "ADR-011 Phase 2: optional escalation payload. Only honored when phases.mid_execution_escalation is true." })),
|
|
752
838
|
verificationEvidence: Type.Optional(Type.Array(
|
|
@@ -1009,7 +1095,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
1009
1095
|
promptGuidelines: [
|
|
1010
1096
|
"Use gsd_validate_milestone when all slices are done and the milestone needs validation before completion.",
|
|
1011
1097
|
"Parameters: milestoneId, verdict, remediationRound, successCriteriaChecklist, sliceDeliveryAudit, crossSliceIntegration, requirementCoverage, verificationClasses (optional), verdictRationale, remediationPlan (optional).",
|
|
1012
|
-
"If verification classes were planned, verificationClasses must
|
|
1098
|
+
"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.",
|
|
1013
1099
|
"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.",
|
|
1014
1100
|
"If verdict is 'needs-remediation', also provide remediationPlan and use gsd_reassess_roadmap to add remediation slices to the roadmap.",
|
|
1015
1101
|
"On success, returns validationPath where VALIDATION.md was written.",
|
|
@@ -1022,7 +1108,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
1022
1108
|
sliceDeliveryAudit: Type.String({ description: "Markdown table auditing each slice's claimed vs delivered output" }),
|
|
1023
1109
|
crossSliceIntegration: Type.String({ description: "Markdown describing any cross-slice boundary mismatches" }),
|
|
1024
1110
|
requirementCoverage: Type.String({ description: "Markdown describing any unaddressed requirements" }),
|
|
1025
|
-
verificationClasses: Type.Optional(Type.String({ description: "
|
|
1111
|
+
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)" })),
|
|
1026
1112
|
verdictRationale: Type.String({ description: "Why this verdict was chosen" }),
|
|
1027
1113
|
remediationPlan: Type.Optional(Type.String({ description: "Remediation plan (required if verdict is needs-remediation)" })),
|
|
1028
1114
|
}),
|
|
@@ -25,6 +25,57 @@ async function loadContextModePreferences(baseDir: string) {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export function registerExecTools(pi: ExtensionAPI): void {
|
|
28
|
+
pi.registerTool({
|
|
29
|
+
name: "gsd_uat_exec",
|
|
30
|
+
label: "UAT Exec",
|
|
31
|
+
description:
|
|
32
|
+
"Run a UAT-scoped bash/node/python check with milestone/slice/check metadata. " +
|
|
33
|
+
"Uses the same capped .gsd/exec evidence store as gsd_exec, but rejects commands that mutate dependencies, git state, credentials, or destructive files.",
|
|
34
|
+
promptSnippet: "Run one UAT check and save typed evidence under .gsd/exec",
|
|
35
|
+
promptGuidelines: [
|
|
36
|
+
"Use gsd_uat_exec for each automated UAT check.",
|
|
37
|
+
"Every PASS/FAIL check saved by gsd_uat_result_save must reference objective evidence from this tool or another approved GSD evidence path.",
|
|
38
|
+
"Do not install packages, mutate git state, edit source files, or dump credentials during UAT.",
|
|
39
|
+
],
|
|
40
|
+
parameters: Type.Object({
|
|
41
|
+
milestoneId: Type.String({ description: "Milestone ID (e.g. M001)" }),
|
|
42
|
+
sliceId: Type.String({ description: "Slice ID (e.g. S01)" }),
|
|
43
|
+
checkId: Type.String({ description: "Stable check ID from the UAT spec (e.g. UAT-01)" }),
|
|
44
|
+
intent: Type.String({
|
|
45
|
+
description:
|
|
46
|
+
"UAT command intent. Use one canonical value: uat-artifact-check, uat-runtime-check, " +
|
|
47
|
+
"uat-browser-check, uat-service-start, or uat-log-inspection. Short aliases such as artifact, " +
|
|
48
|
+
"runtime, browser, service-start, and log-inspection are accepted.",
|
|
49
|
+
}),
|
|
50
|
+
runtime: Type.Optional(
|
|
51
|
+
Type.String({
|
|
52
|
+
description:
|
|
53
|
+
"Optional interpreter. Defaults to bash. Supported: bash, node, python; sh/shell, js/nodejs, and py/python3 aliases are accepted.",
|
|
54
|
+
}),
|
|
55
|
+
),
|
|
56
|
+
script: Type.Optional(Type.String({ description: "Script body. Keep output small (log the finding, not the data)." })),
|
|
57
|
+
command: Type.Optional(Type.String({ description: "Alias for script; defaults to bash when runtime is omitted." })),
|
|
58
|
+
cmd: Type.Optional(Type.String({ description: "Short alias for script." })),
|
|
59
|
+
code: Type.Optional(Type.String({ description: "Alias for script, useful for node/python snippets." })),
|
|
60
|
+
expected: Type.Optional(Type.String({ description: "Expected outcome for this UAT check." })),
|
|
61
|
+
timeout_ms: Type.Optional(
|
|
62
|
+
Type.Number({
|
|
63
|
+
description: "Per-invocation timeout (ms). Capped at 600000. Default from preferences.",
|
|
64
|
+
minimum: 1_000,
|
|
65
|
+
maximum: 600_000,
|
|
66
|
+
}),
|
|
67
|
+
),
|
|
68
|
+
}),
|
|
69
|
+
async execute(_toolCallId, params, _signal, _onUpdate, _ctx) {
|
|
70
|
+
const { executeUatExec } = await import("../tools/exec-tool.js");
|
|
71
|
+
const baseDir = resolveCtxCwd(_ctx);
|
|
72
|
+
return executeUatExec(params as Parameters<typeof executeUatExec>[0], {
|
|
73
|
+
baseDir,
|
|
74
|
+
preferences: await loadContextModePreferences(baseDir),
|
|
75
|
+
});
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
|
|
28
79
|
pi.registerTool({
|
|
29
80
|
name: "gsd_exec",
|
|
30
81
|
label: "Exec (Sandboxed)",
|