@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
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
// Project/App: gsd-pi
|
|
2
|
+
// File Purpose: Resolve phase-aware tool surfaces for GSD model presentations.
|
|
3
|
+
|
|
4
|
+
export type ToolPresentationSurface = "provider-tools" | "claude-code-sdk" | "mcp" | "hybrid";
|
|
5
|
+
|
|
6
|
+
export interface ToolPresentationModel {
|
|
7
|
+
provider?: string;
|
|
8
|
+
api?: string;
|
|
9
|
+
id?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface ToolPresentationPlan {
|
|
13
|
+
phase: string;
|
|
14
|
+
surface: ToolPresentationSurface;
|
|
15
|
+
model?: ToolPresentationModel;
|
|
16
|
+
allowedToolNames: string[];
|
|
17
|
+
presentedToolNames: string[];
|
|
18
|
+
blockedToolNames: Array<{ name: string; reason: string }>;
|
|
19
|
+
aliases: Array<{ requested: string; canonical: string }>;
|
|
20
|
+
diagnostics: string[];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const RUN_UAT_WORKFLOW_TOOL_NAMES = [
|
|
24
|
+
"gsd_uat_exec",
|
|
25
|
+
"gsd_uat_result_save",
|
|
26
|
+
"gsd_resume",
|
|
27
|
+
"gsd_milestone_status",
|
|
28
|
+
"gsd_journal_query",
|
|
29
|
+
] as const;
|
|
30
|
+
|
|
31
|
+
export const RUN_UAT_FORBIDDEN_TOOL_NAMES = [
|
|
32
|
+
"edit",
|
|
33
|
+
"write",
|
|
34
|
+
"gsd_exec",
|
|
35
|
+
"gsd_summary_save",
|
|
36
|
+
"gsd_save_gate_result",
|
|
37
|
+
"search-the-web",
|
|
38
|
+
"WebSearch",
|
|
39
|
+
"Bash",
|
|
40
|
+
"Write",
|
|
41
|
+
"Edit",
|
|
42
|
+
"mcp__gsd-workflow__*",
|
|
43
|
+
] as const;
|
|
44
|
+
|
|
45
|
+
export const RUN_UAT_CLAUDE_NATIVE_TOOL_NAMES = [
|
|
46
|
+
"Read",
|
|
47
|
+
"Glob",
|
|
48
|
+
"Grep",
|
|
49
|
+
] as const;
|
|
50
|
+
|
|
51
|
+
const WORKFLOW_ALIAS_TO_CANONICAL: Record<string, string> = {
|
|
52
|
+
gsd_save_decision: "gsd_decision_save",
|
|
53
|
+
gsd_update_requirement: "gsd_requirement_update",
|
|
54
|
+
gsd_save_requirement: "gsd_requirement_save",
|
|
55
|
+
gsd_save_summary: "gsd_summary_save",
|
|
56
|
+
gsd_generate_milestone_id: "gsd_milestone_generate_id",
|
|
57
|
+
gsd_milestone_plan: "gsd_plan_milestone",
|
|
58
|
+
gsd_slice_plan: "gsd_plan_slice",
|
|
59
|
+
gsd_task_plan: "gsd_plan_task",
|
|
60
|
+
gsd_slice_replan: "gsd_replan_slice",
|
|
61
|
+
gsd_complete_slice: "gsd_slice_complete",
|
|
62
|
+
gsd_milestone_complete: "gsd_complete_milestone",
|
|
63
|
+
gsd_milestone_validate: "gsd_validate_milestone",
|
|
64
|
+
gsd_roadmap_reassess: "gsd_reassess_roadmap",
|
|
65
|
+
gsd_complete_task: "gsd_task_complete",
|
|
66
|
+
gsd_reopen_task: "gsd_task_reopen",
|
|
67
|
+
gsd_reopen_slice: "gsd_slice_reopen",
|
|
68
|
+
gsd_reopen_milestone: "gsd_milestone_reopen",
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export function canonicalWorkflowToolName(toolName: string): string {
|
|
72
|
+
const mcp = parseMcpToolName(toolName);
|
|
73
|
+
const baseName = mcp?.tool ?? toolName;
|
|
74
|
+
return WORKFLOW_ALIAS_TO_CANONICAL[baseName] ?? baseName;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function parseMcpToolName(toolName: string): { server: string; tool: string } | null {
|
|
78
|
+
if (!toolName.startsWith("mcp__")) return null;
|
|
79
|
+
const toolSeparator = toolName.indexOf("__", "mcp__".length);
|
|
80
|
+
if (toolSeparator < 0) return null;
|
|
81
|
+
return {
|
|
82
|
+
server: toolName.slice("mcp__".length, toolSeparator),
|
|
83
|
+
tool: toolName.slice(toolSeparator + 2),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function toWorkflowMcpToolName(serverName: string, toolName: string): string {
|
|
88
|
+
return `mcp__${serverName}__${canonicalWorkflowToolName(toolName)}`;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function dedupe(values: readonly string[]): string[] {
|
|
92
|
+
return [...new Set(values)];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function addBlockedTool(
|
|
96
|
+
blocked: ToolPresentationPlan["blockedToolNames"],
|
|
97
|
+
name: string,
|
|
98
|
+
reason: string,
|
|
99
|
+
): void {
|
|
100
|
+
if (!blocked.some((entry) => entry.name === name)) {
|
|
101
|
+
blocked.push({ name, reason });
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function buildRunUatCanonicalToolNames(options: { includeBrowserTools?: readonly string[] } = {}): string[] {
|
|
106
|
+
return dedupe([
|
|
107
|
+
...RUN_UAT_WORKFLOW_TOOL_NAMES,
|
|
108
|
+
...(options.includeBrowserTools ?? []),
|
|
109
|
+
]);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function resolveToolPresentationPlan(options: {
|
|
113
|
+
phase: string;
|
|
114
|
+
surface: ToolPresentationSurface;
|
|
115
|
+
model?: ToolPresentationModel;
|
|
116
|
+
workflowMcpServerName?: string | null;
|
|
117
|
+
requestedToolNames?: readonly string[];
|
|
118
|
+
availableToolNames?: readonly string[];
|
|
119
|
+
includeBrowserTools?: readonly string[];
|
|
120
|
+
}): ToolPresentationPlan {
|
|
121
|
+
const requested = options.requestedToolNames ?? (
|
|
122
|
+
options.phase === "run-uat"
|
|
123
|
+
? buildRunUatCanonicalToolNames({ includeBrowserTools: options.includeBrowserTools })
|
|
124
|
+
: []
|
|
125
|
+
);
|
|
126
|
+
const available = new Set(options.availableToolNames ?? requested);
|
|
127
|
+
const aliases: ToolPresentationPlan["aliases"] = [];
|
|
128
|
+
const blockedToolNames: ToolPresentationPlan["blockedToolNames"] = [];
|
|
129
|
+
const allowed: string[] = [];
|
|
130
|
+
|
|
131
|
+
for (const name of requested) {
|
|
132
|
+
const canonical = canonicalWorkflowToolName(name);
|
|
133
|
+
if (canonical !== name) aliases.push({ requested: name, canonical });
|
|
134
|
+
if (!available.has(name) && !available.has(canonical)) {
|
|
135
|
+
addBlockedTool(blockedToolNames, canonical, "not registered or provider-incompatible");
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
allowed.push(canonical);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const allowedToolNames = dedupe(allowed);
|
|
142
|
+
const workflowServerName = options.workflowMcpServerName || "gsd-workflow";
|
|
143
|
+
const presentedToolNames = options.surface === "claude-code-sdk" || options.surface === "mcp"
|
|
144
|
+
? allowedToolNames.map((name) =>
|
|
145
|
+
name.startsWith("gsd_") || name === "ask_user_questions"
|
|
146
|
+
? toWorkflowMcpToolName(workflowServerName, name)
|
|
147
|
+
: name
|
|
148
|
+
)
|
|
149
|
+
: allowedToolNames;
|
|
150
|
+
|
|
151
|
+
if (options.phase === "run-uat") {
|
|
152
|
+
for (const forbidden of RUN_UAT_FORBIDDEN_TOOL_NAMES) {
|
|
153
|
+
addBlockedTool(blockedToolNames, forbidden, "forbidden during run-uat");
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
phase: options.phase,
|
|
159
|
+
surface: options.surface,
|
|
160
|
+
model: options.model,
|
|
161
|
+
allowedToolNames,
|
|
162
|
+
presentedToolNames,
|
|
163
|
+
blockedToolNames,
|
|
164
|
+
aliases,
|
|
165
|
+
diagnostics: [],
|
|
166
|
+
};
|
|
167
|
+
}
|
|
@@ -217,7 +217,7 @@ ${params.narrative}
|
|
|
217
217
|
|
|
218
218
|
## Verification
|
|
219
219
|
|
|
220
|
-
${params.verification}
|
|
220
|
+
${params.verification ?? ""}
|
|
221
221
|
|
|
222
222
|
## Requirements Advanced
|
|
223
223
|
|
|
@@ -440,6 +440,19 @@ export async function handleCompleteSlice(
|
|
|
440
440
|
const parsed = parseRequirementSection(existingSummaryMd, "Requirements Invalidated or Re-scoped", "what");
|
|
441
441
|
if (parsed.length > 0) effectiveParams.requirementsInvalidated = parsed as Array<{ id: string; what: string }>;
|
|
442
442
|
}
|
|
443
|
+
if (effectiveParams.verification === undefined) {
|
|
444
|
+
const headingLine = "## Verification\n\n";
|
|
445
|
+
const start = existingSummaryMd.indexOf(headingLine);
|
|
446
|
+
if (start !== -1) {
|
|
447
|
+
const contentStart = start + headingLine.length;
|
|
448
|
+
const nextHeading = existingSummaryMd.indexOf("\n\n## ", contentStart);
|
|
449
|
+
const prior = nextHeading === -1
|
|
450
|
+
? existingSummaryMd.slice(contentStart)
|
|
451
|
+
: existingSummaryMd.slice(contentStart, nextHeading);
|
|
452
|
+
const trimmed = prior.trim();
|
|
453
|
+
if (trimmed) effectiveParams.verification = trimmed;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
443
456
|
}
|
|
444
457
|
|
|
445
458
|
// Render summary markdown
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
import { join } from "node:path";
|
|
14
14
|
|
|
15
|
-
import type { CompleteTaskParams } from "../types.js";
|
|
15
|
+
import type { CompleteTaskParams, EscalationArtifact } from "../types.js";
|
|
16
16
|
import { isClosedStatus } from "../status-guards.js";
|
|
17
17
|
import {
|
|
18
18
|
transaction,
|
|
@@ -48,6 +48,14 @@ export interface CompleteTaskResult {
|
|
|
48
48
|
sliceId: string;
|
|
49
49
|
milestoneId: string;
|
|
50
50
|
summaryPath: string;
|
|
51
|
+
escalation?: {
|
|
52
|
+
artifactPath: string;
|
|
53
|
+
question: string;
|
|
54
|
+
options: EscalationArtifact["options"];
|
|
55
|
+
recommendation: string;
|
|
56
|
+
recommendationRationale: string;
|
|
57
|
+
continueWithDefault: boolean;
|
|
58
|
+
};
|
|
51
59
|
/**
|
|
52
60
|
* True when this call re-completed an already-closed task from a turn that
|
|
53
61
|
* had been superseded by timeout recovery or cancellation. The underlying
|
|
@@ -407,9 +415,18 @@ export async function handleCompleteTask(
|
|
|
407
415
|
// overwrite it; gate rows are UPSERT-keyed per task and will also be
|
|
408
416
|
// overwritten. This restores the invariant that deriveState() sees a
|
|
409
417
|
// consistent "task not done" view so the loop re-dispatches the task.
|
|
418
|
+
let escalationMetadata: CompleteTaskResult["escalation"] | undefined;
|
|
410
419
|
if (validatedEscalationArtifact) {
|
|
411
420
|
try {
|
|
412
|
-
writeEscalationArtifact(artifactBasePath, validatedEscalationArtifact);
|
|
421
|
+
const escalationPath = writeEscalationArtifact(artifactBasePath, validatedEscalationArtifact);
|
|
422
|
+
escalationMetadata = {
|
|
423
|
+
artifactPath: escalationPath,
|
|
424
|
+
question: validatedEscalationArtifact.question,
|
|
425
|
+
options: validatedEscalationArtifact.options,
|
|
426
|
+
recommendation: validatedEscalationArtifact.recommendation,
|
|
427
|
+
recommendationRationale: validatedEscalationArtifact.recommendationRationale,
|
|
428
|
+
continueWithDefault: validatedEscalationArtifact.continueWithDefault,
|
|
429
|
+
};
|
|
413
430
|
} catch (escalationErr) {
|
|
414
431
|
const msg = `complete-task escalation write failed for ${params.milestoneId}/${params.sliceId}/${params.taskId}: ${(escalationErr as Error).message}`;
|
|
415
432
|
logWarning("tool", msg);
|
|
@@ -477,6 +494,7 @@ export async function handleCompleteTask(
|
|
|
477
494
|
sliceId: params.sliceId,
|
|
478
495
|
milestoneId: params.milestoneId,
|
|
479
496
|
summaryPath,
|
|
497
|
+
...(escalationMetadata ? { escalation: escalationMetadata } : {}),
|
|
480
498
|
...(projectionStale ? { stale: true } : {}),
|
|
481
499
|
};
|
|
482
500
|
}
|
|
@@ -20,6 +20,7 @@ export interface ExecToolParams {
|
|
|
20
20
|
cmd?: unknown;
|
|
21
21
|
code?: unknown;
|
|
22
22
|
purpose?: string;
|
|
23
|
+
metadata?: Record<string, unknown>;
|
|
23
24
|
timeout_ms?: number;
|
|
24
25
|
}
|
|
25
26
|
|
|
@@ -33,6 +34,44 @@ export interface ExecToolDeps {
|
|
|
33
34
|
generateId?: () => string;
|
|
34
35
|
}
|
|
35
36
|
|
|
37
|
+
export type UatExecIntent =
|
|
38
|
+
| "uat-artifact-check"
|
|
39
|
+
| "uat-runtime-check"
|
|
40
|
+
| "uat-browser-check"
|
|
41
|
+
| "uat-service-start"
|
|
42
|
+
| "uat-log-inspection";
|
|
43
|
+
|
|
44
|
+
export interface UatExecToolParams extends ExecToolParams {
|
|
45
|
+
milestoneId?: unknown;
|
|
46
|
+
sliceId?: unknown;
|
|
47
|
+
checkId?: unknown;
|
|
48
|
+
intent?: unknown;
|
|
49
|
+
expected?: unknown;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const UAT_EXEC_INTENTS: readonly UatExecIntent[] = [
|
|
53
|
+
"uat-artifact-check",
|
|
54
|
+
"uat-runtime-check",
|
|
55
|
+
"uat-browser-check",
|
|
56
|
+
"uat-service-start",
|
|
57
|
+
"uat-log-inspection",
|
|
58
|
+
] as const;
|
|
59
|
+
|
|
60
|
+
const UAT_EXEC_INTENT_ALIASES: Record<string, UatExecIntent> = {
|
|
61
|
+
artifact: "uat-artifact-check",
|
|
62
|
+
"artifact-driven": "uat-artifact-check",
|
|
63
|
+
runtime: "uat-runtime-check",
|
|
64
|
+
"runtime-executable": "uat-runtime-check",
|
|
65
|
+
"live-runtime": "uat-runtime-check",
|
|
66
|
+
browser: "uat-browser-check",
|
|
67
|
+
"browser-executable": "uat-browser-check",
|
|
68
|
+
service: "uat-service-start",
|
|
69
|
+
"service-start": "uat-service-start",
|
|
70
|
+
log: "uat-log-inspection",
|
|
71
|
+
logs: "uat-log-inspection",
|
|
72
|
+
"log-inspection": "uat-log-inspection",
|
|
73
|
+
};
|
|
74
|
+
|
|
36
75
|
export function buildExecOptions(
|
|
37
76
|
baseDir: string,
|
|
38
77
|
cfg: ContextModeConfig | undefined,
|
|
@@ -112,6 +151,39 @@ function normalizeScript(params: ExecToolParams): string | ToolExecutionResult {
|
|
|
112
151
|
return paramError("script is required and must be a non-empty string");
|
|
113
152
|
}
|
|
114
153
|
|
|
154
|
+
function normalizeRequiredString(value: unknown, field: string): string | ToolExecutionResult {
|
|
155
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
156
|
+
return paramError(`${field} is required and must be a non-empty string`);
|
|
157
|
+
}
|
|
158
|
+
return value.trim();
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function normalizeUatIntent(value: unknown): UatExecIntent | ToolExecutionResult {
|
|
162
|
+
if (typeof value !== "string") {
|
|
163
|
+
return paramError(`intent is required and must be one of: ${UAT_EXEC_INTENTS.join(", ")}`);
|
|
164
|
+
}
|
|
165
|
+
const normalized = value.trim().toLowerCase();
|
|
166
|
+
if ((UAT_EXEC_INTENTS as readonly string[]).includes(normalized)) return normalized as UatExecIntent;
|
|
167
|
+
const alias = UAT_EXEC_INTENT_ALIASES[normalized];
|
|
168
|
+
if (alias) return alias;
|
|
169
|
+
return paramError(`invalid intent "${value}" — must be one of: ${UAT_EXEC_INTENTS.join(", ")}`);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function rejectUatScript(script: string): string | null {
|
|
173
|
+
const patterns: Array<{ re: RegExp; reason: string }> = [
|
|
174
|
+
{ re: /\b(?:npm|pnpm|yarn|bun)\s+(?:i|install|add|remove|update|upgrade)\b/i, reason: "package dependency mutation is not allowed during UAT" },
|
|
175
|
+
{ re: /\b(?:pip|pip3|python\s+-m\s+pip)\s+install\b/i, reason: "package dependency mutation is not allowed during UAT" },
|
|
176
|
+
{ re: /\bgit\s+(?:add|commit|push|reset|checkout|switch|merge|rebase|clean|rm|mv|tag|branch)\b/i, reason: "git mutations are not allowed during UAT" },
|
|
177
|
+
{ re: /\brm\s+-[^\n\r;|&]*r[^\n\r;|&]*f\b/i, reason: "destructive filesystem cleanup is not allowed during UAT" },
|
|
178
|
+
{ re: /\b(?:env|printenv)\b(?:\s|$)/i, reason: "dumping environment variables is not allowed during UAT" },
|
|
179
|
+
{ re: /\bcat\s+\.env(?:\b|\.|$)/i, reason: "reading credential files is not allowed during UAT" },
|
|
180
|
+
];
|
|
181
|
+
for (const pattern of patterns) {
|
|
182
|
+
if (pattern.re.test(script)) return pattern.reason;
|
|
183
|
+
}
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
|
|
115
187
|
function isToolExecutionResult(value: unknown): value is ToolExecutionResult {
|
|
116
188
|
return typeof value === "object" && value !== null && Array.isArray((value as { content?: unknown }).content);
|
|
117
189
|
}
|
|
@@ -266,6 +338,7 @@ export async function executeGsdExec(
|
|
|
266
338
|
runtime,
|
|
267
339
|
script,
|
|
268
340
|
...(typeof params.purpose === "string" ? { purpose: params.purpose } : {}),
|
|
341
|
+
...(params.metadata && typeof params.metadata === "object" ? { metadata: params.metadata } : {}),
|
|
269
342
|
...(typeof params.timeout_ms === "number" ? { timeout_ms: params.timeout_ms } : {}),
|
|
270
343
|
},
|
|
271
344
|
opts,
|
|
@@ -281,6 +354,63 @@ export async function executeGsdExec(
|
|
|
281
354
|
}
|
|
282
355
|
}
|
|
283
356
|
|
|
357
|
+
export async function executeUatExec(
|
|
358
|
+
params: UatExecToolParams,
|
|
359
|
+
deps: ExecToolDeps,
|
|
360
|
+
): Promise<ToolExecutionResult> {
|
|
361
|
+
const milestoneId = normalizeRequiredString(params.milestoneId, "milestoneId");
|
|
362
|
+
if (isToolExecutionResult(milestoneId)) return milestoneId;
|
|
363
|
+
const sliceId = normalizeRequiredString(params.sliceId, "sliceId");
|
|
364
|
+
if (isToolExecutionResult(sliceId)) return sliceId;
|
|
365
|
+
const checkId = normalizeRequiredString(params.checkId, "checkId");
|
|
366
|
+
if (isToolExecutionResult(checkId)) return checkId;
|
|
367
|
+
const intent = normalizeUatIntent(params.intent);
|
|
368
|
+
if (isToolExecutionResult(intent)) return intent;
|
|
369
|
+
const script = normalizeScript(params);
|
|
370
|
+
if (isToolExecutionResult(script)) return script;
|
|
371
|
+
const rejected = rejectUatScript(script);
|
|
372
|
+
if (rejected) {
|
|
373
|
+
return {
|
|
374
|
+
content: [{ type: "text", text: `Error: gsd_uat_exec blocked command — ${rejected}` }],
|
|
375
|
+
details: { operation: "gsd_uat_exec", error: "uat_exec_policy_block", reason: rejected },
|
|
376
|
+
isError: true,
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
const result = await executeGsdExec(
|
|
381
|
+
{
|
|
382
|
+
...params,
|
|
383
|
+
script,
|
|
384
|
+
purpose: typeof params.purpose === "string" && params.purpose.trim().length > 0
|
|
385
|
+
? params.purpose
|
|
386
|
+
: `UAT ${milestoneId}/${sliceId}/${checkId} (${intent})`,
|
|
387
|
+
metadata: {
|
|
388
|
+
kind: "uat_exec",
|
|
389
|
+
milestoneId,
|
|
390
|
+
sliceId,
|
|
391
|
+
checkId,
|
|
392
|
+
intent,
|
|
393
|
+
...(typeof params.expected === "string" && params.expected.trim().length > 0
|
|
394
|
+
? { expected: params.expected.trim() }
|
|
395
|
+
: {}),
|
|
396
|
+
},
|
|
397
|
+
},
|
|
398
|
+
deps,
|
|
399
|
+
);
|
|
400
|
+
const details = result.details ?? {};
|
|
401
|
+
return {
|
|
402
|
+
...result,
|
|
403
|
+
details: {
|
|
404
|
+
...details,
|
|
405
|
+
operation: "gsd_uat_exec",
|
|
406
|
+
milestoneId,
|
|
407
|
+
sliceId,
|
|
408
|
+
checkId,
|
|
409
|
+
intent,
|
|
410
|
+
},
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
|
|
284
414
|
function formatResult(result: ExecSandboxResult): ToolExecutionResult {
|
|
285
415
|
const headerLines = [
|
|
286
416
|
`gsd_exec[${result.id}] runtime=${result.runtime} exit=${formatExit(result)} duration=${result.duration_ms}ms`,
|
|
@@ -355,15 +355,9 @@ export async function handlePlanSlice(
|
|
|
355
355
|
deleteTask(params.milestoneId, params.sliceId, taskId);
|
|
356
356
|
}
|
|
357
357
|
|
|
358
|
+
const existingTaskById = new Map(existingTasks.map((task) => [task.id, task]));
|
|
358
359
|
for (const task of params.tasks) {
|
|
359
|
-
|
|
360
|
-
id: task.taskId,
|
|
361
|
-
sliceId: params.sliceId,
|
|
362
|
-
milestoneId: params.milestoneId,
|
|
363
|
-
title: task.title,
|
|
364
|
-
status: "pending",
|
|
365
|
-
});
|
|
366
|
-
upsertTaskPlanning(params.milestoneId, params.sliceId, task.taskId, {
|
|
360
|
+
const planning = {
|
|
367
361
|
title: task.title,
|
|
368
362
|
description: task.description,
|
|
369
363
|
estimate: task.estimate,
|
|
@@ -374,7 +368,18 @@ export async function handlePlanSlice(
|
|
|
374
368
|
observabilityImpact: task.observabilityImpact ?? "",
|
|
375
369
|
fullPlanMd: task.fullPlanMd,
|
|
376
370
|
targetRepositories: task.targetRepositories ?? params.targetRepositories ?? defaultTargets,
|
|
377
|
-
}
|
|
371
|
+
};
|
|
372
|
+
const existingTask = existingTaskById.get(task.taskId);
|
|
373
|
+
if (!existingTask || !isClosedStatus(existingTask.status)) {
|
|
374
|
+
insertTask({
|
|
375
|
+
id: task.taskId,
|
|
376
|
+
sliceId: params.sliceId,
|
|
377
|
+
milestoneId: params.milestoneId,
|
|
378
|
+
title: task.title,
|
|
379
|
+
status: "pending",
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
upsertTaskPlanning(params.milestoneId, params.sliceId, task.taskId, planning);
|
|
378
383
|
}
|
|
379
384
|
|
|
380
385
|
// Seed quality gate rows inside the transaction — all-or-nothing with
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
getMilestone,
|
|
14
14
|
getMilestoneSlices,
|
|
15
15
|
getSliceTasks,
|
|
16
|
-
|
|
16
|
+
reopenMilestoneStatus,
|
|
17
17
|
updateSliceStatus,
|
|
18
18
|
updateTaskStatus,
|
|
19
19
|
transaction,
|
|
@@ -69,7 +69,7 @@ export async function handleReopenMilestone(
|
|
|
69
69
|
return;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
reopenMilestoneStatus(params.milestoneId);
|
|
73
73
|
|
|
74
74
|
const slices = getMilestoneSlices(params.milestoneId);
|
|
75
75
|
slicesResetCount = slices.length;
|
|
@@ -78,18 +78,10 @@ function getRequiredVerificationClasses(milestoneId: string): string[] {
|
|
|
78
78
|
return required;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const artifact = getArtifact(artifactPath);
|
|
86
|
-
if (artifact?.full_content) chunks.push(artifact.full_content);
|
|
87
|
-
|
|
88
|
-
const assessmentPath = resolveSliceFile(basePath, milestoneId, slice.id, "ASSESSMENT");
|
|
89
|
-
const assessmentContent = assessmentPath ? await loadFile(assessmentPath) : null;
|
|
90
|
-
if (assessmentContent) chunks.push(assessmentContent);
|
|
91
|
-
}
|
|
92
|
-
return chunks.join("\n\n");
|
|
81
|
+
function hasRuntimeExecutableUatEvidenceText(text: string): boolean {
|
|
82
|
+
if (!/\buatType:\s*runtime-executable\b/i.test(text)) return false;
|
|
83
|
+
if (!/\bverdict:\s*PASS\b/i.test(text)) return false;
|
|
84
|
+
return /^\|\s*[^|\n]+\s*\|\s*runtime\s*\|\s*PASS\s*\|[^|\n]*\bgsd_uat_exec\b/mi.test(text);
|
|
93
85
|
}
|
|
94
86
|
|
|
95
87
|
async function browserEvidenceGateRequiresAttention(
|
|
@@ -114,7 +106,38 @@ async function browserEvidenceGateRequiresAttention(
|
|
|
114
106
|
]);
|
|
115
107
|
if (!hasBrowserRequiredText(requirementText)) return false;
|
|
116
108
|
|
|
117
|
-
|
|
109
|
+
// Collect per-slice evidence so the runtime bypass is checked independently
|
|
110
|
+
// for each slice. Concatenating all slices before checking would allow runtime
|
|
111
|
+
// evidence from one slice to cover another slice's browser requirements.
|
|
112
|
+
const sliceEvidencePairs: Array<{ sliceRequirementText: string; evidenceText: string }> = [];
|
|
113
|
+
for (const slice of slices) {
|
|
114
|
+
const chunks: string[] = [];
|
|
115
|
+
const artifactPath = `milestones/${params.milestoneId}/slices/${slice.id}/${slice.id}-ASSESSMENT.md`;
|
|
116
|
+
const artifact = getArtifact(artifactPath);
|
|
117
|
+
if (artifact?.full_content) chunks.push(artifact.full_content);
|
|
118
|
+
const assessmentPath = resolveSliceFile(basePath, params.milestoneId, slice.id, "ASSESSMENT");
|
|
119
|
+
const assessmentContent = assessmentPath ? await loadFile(assessmentPath) : null;
|
|
120
|
+
if (assessmentContent) chunks.push(assessmentContent);
|
|
121
|
+
sliceEvidencePairs.push({
|
|
122
|
+
sliceRequirementText: compactTextParts([slice.demo, slice.goal, slice.success_criteria]),
|
|
123
|
+
evidenceText: chunks.join("\n\n"),
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
const persistedEvidence = sliceEvidencePairs.map((s) => s.evidenceText).join("\n\n");
|
|
127
|
+
|
|
128
|
+
// Runtime bypass: each slice whose own requirement text has browser-observable
|
|
129
|
+
// criteria must have its own runtime-executable UAT evidence. When no individual
|
|
130
|
+
// slice has slice-level browser requirements (e.g., they come from milestone-level
|
|
131
|
+
// fields only), fall back to checking whether any slice has runtime evidence.
|
|
132
|
+
const browserRequiringSlices = sliceEvidencePairs.filter((s) =>
|
|
133
|
+
hasBrowserRequiredText(s.sliceRequirementText),
|
|
134
|
+
);
|
|
135
|
+
const runtimeBypasses =
|
|
136
|
+
browserRequiringSlices.length > 0
|
|
137
|
+
? browserRequiringSlices.every((s) => hasRuntimeExecutableUatEvidenceText(s.evidenceText))
|
|
138
|
+
: sliceEvidencePairs.some((s) => hasRuntimeExecutableUatEvidenceText(s.evidenceText));
|
|
139
|
+
if (runtimeBypasses) return false;
|
|
140
|
+
|
|
118
141
|
const validationEvidence = compactTextParts([
|
|
119
142
|
params.successCriteriaChecklist,
|
|
120
143
|
params.verificationClasses,
|
|
@@ -184,14 +207,22 @@ export async function handleValidateMilestone(
|
|
|
184
207
|
const requiredClasses = getRequiredVerificationClasses(params.milestoneId);
|
|
185
208
|
if (requiredClasses.length > 0) {
|
|
186
209
|
const verificationClasses = params.verificationClasses ?? "";
|
|
187
|
-
const
|
|
210
|
+
const missingClasses = requiredClasses.filter(
|
|
188
211
|
(className) => !new RegExp(`\\b${className}\\b`, "i").test(verificationClasses),
|
|
189
212
|
);
|
|
190
|
-
if (
|
|
213
|
+
if (missingClasses.length === 1) {
|
|
214
|
+
const missingClass = missingClasses[0];
|
|
191
215
|
return {
|
|
192
216
|
error: `verificationClasses must include canonical row "${missingClass}" because this milestone planned ${missingClass.toLowerCase()} verification`,
|
|
193
217
|
};
|
|
194
218
|
}
|
|
219
|
+
if (missingClasses.length > 1) {
|
|
220
|
+
const quotedClasses = missingClasses.map((className) => `"${className}"`).join(", ");
|
|
221
|
+
const plannedClasses = missingClasses.map((className) => className.toLowerCase()).join(", ");
|
|
222
|
+
return {
|
|
223
|
+
error: `verificationClasses must include canonical rows ${quotedClasses} because this milestone planned ${plannedClasses} verification`,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
195
226
|
}
|
|
196
227
|
|
|
197
228
|
const artifactBasePath = resolveCanonicalMilestoneRoot(basePath, params.milestoneId);
|