@opengsd/gsd-pi 1.2.0-dev.955e4da0 → 1.2.0-dev.d6c5343c
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-style.d.ts +17 -0
- package/dist/cli-style.js +28 -0
- package/dist/cli.js +1 -1
- package/dist/headless-events.d.ts +4 -2
- package/dist/headless-events.js +14 -34
- package/dist/models-resolver.d.ts +3 -13
- package/dist/models-resolver.js +3 -22
- package/dist/resource-loader.js +2 -14
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +5 -4
- package/dist/resources/extensions/async-jobs/async-bash-tool.js +30 -64
- package/dist/resources/extensions/async-jobs/await-tool.js +80 -12
- package/dist/resources/extensions/async-jobs/index.js +65 -0
- package/dist/resources/extensions/async-jobs/job-manager.js +12 -1
- package/dist/resources/extensions/bg-shell/bg-shell-command.js +6 -6
- package/dist/resources/extensions/bg-shell/bg-shell-tool.js +10 -7
- package/dist/resources/extensions/bg-shell/overlay.js +9 -6
- package/dist/resources/extensions/bg-shell/process-manager.js +54 -25
- package/dist/resources/extensions/bg-shell/readiness-detector.js +11 -0
- package/dist/resources/extensions/bg-shell/utilities.js +3 -0
- package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +209 -88
- package/dist/resources/extensions/browser-tools/engine/selection.js +73 -5
- package/dist/resources/extensions/browser-tools/index.js +69 -12
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +30 -4
- package/dist/resources/extensions/gsd/auto/custom-verify-retry-store.js +17 -2
- package/dist/resources/extensions/gsd/auto/detect-stuck.js +33 -13
- package/dist/resources/extensions/gsd/auto/dispatch-history.js +105 -0
- package/dist/resources/extensions/gsd/auto/dispatch-key.js +37 -0
- package/dist/resources/extensions/gsd/auto/loop.js +4 -1
- package/dist/resources/extensions/gsd/auto/orchestrator.js +61 -44
- package/dist/resources/extensions/gsd/auto/phases.js +2 -2
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +8 -32
- package/dist/resources/extensions/gsd/auto-dispatch.js +40 -57
- package/dist/resources/extensions/gsd/auto-model-selection.js +25 -6
- package/dist/resources/extensions/gsd/auto-post-unit.js +23 -8
- package/dist/resources/extensions/gsd/auto-prompts.js +81 -19
- package/dist/resources/extensions/gsd/auto-start.js +18 -15
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +18 -0
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +12 -20
- package/dist/resources/extensions/gsd/auto-verification.js +9 -28
- package/dist/resources/extensions/gsd/auto-worktree.js +30 -90
- package/dist/resources/extensions/gsd/auto.js +4 -13
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +3 -2
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +23 -6
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +19 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +212 -48
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +303 -77
- package/dist/resources/extensions/gsd/branch-patterns.js +2 -0
- package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +83 -0
- package/dist/resources/extensions/gsd/browser-evidence.js +8 -2
- package/dist/resources/extensions/gsd/captures.js +4 -6
- package/dist/resources/extensions/gsd/consent-question.js +337 -0
- package/dist/resources/extensions/gsd/consent-verdict.js +63 -0
- package/dist/resources/extensions/gsd/constants.js +0 -2
- package/dist/resources/extensions/gsd/crash-recovery.js +4 -12
- package/dist/resources/extensions/gsd/db/queries.js +26 -0
- package/dist/resources/extensions/gsd/dispatch-guard.js +10 -35
- package/dist/resources/extensions/gsd/doctor-environment.js +2 -6
- package/dist/resources/extensions/gsd/doctor-format.js +9 -6
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +13 -15
- package/dist/resources/extensions/gsd/engine-hook-contract.js +70 -0
- package/dist/resources/extensions/gsd/error-classifier.js +9 -0
- package/dist/resources/extensions/gsd/exec-sandbox.js +30 -10
- package/dist/resources/extensions/gsd/files.js +33 -19
- package/dist/resources/extensions/gsd/guidance.js +158 -0
- package/dist/resources/extensions/gsd/guided-flow.js +17 -2
- package/dist/resources/extensions/gsd/markdown-renderer.js +10 -0
- package/dist/resources/extensions/gsd/mcp-filter.js +2 -19
- package/dist/resources/extensions/gsd/mcp-tool-name.js +5 -13
- package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +1 -1
- package/dist/resources/extensions/gsd/migrate/safety.js +4 -1
- package/dist/resources/extensions/gsd/milestone-closeout.js +13 -23
- package/dist/resources/extensions/gsd/notification-store.js +11 -4
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +6 -4
- package/dist/resources/extensions/gsd/parsers-legacy.js +16 -4
- package/dist/resources/extensions/gsd/paths.js +27 -0
- package/dist/resources/extensions/gsd/pre-execution-checks.js +91 -3
- package/dist/resources/extensions/gsd/preferences-models.js +14 -48
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/run-uat.md +6 -4
- package/dist/resources/extensions/gsd/prompts/system.md +5 -2
- package/dist/resources/extensions/gsd/provider-error-guidance.js +1 -5
- package/dist/resources/extensions/gsd/provider-switch-observer.js +1 -1
- package/dist/resources/extensions/gsd/publication.js +87 -0
- package/dist/resources/extensions/gsd/reactive-graph.js +8 -1
- package/dist/resources/extensions/gsd/recovery-classification.js +37 -94
- package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
- package/dist/resources/extensions/gsd/state.js +6 -20
- package/dist/resources/extensions/gsd/stop-notice.js +57 -0
- package/dist/resources/extensions/gsd/tool-presentation-plan.js +4 -4
- package/dist/resources/extensions/gsd/tool-surface-readiness.js +56 -0
- package/dist/resources/extensions/gsd/tools/complete-slice.js +20 -10
- package/dist/resources/extensions/gsd/tools/exec-tool.js +9 -7
- package/dist/resources/extensions/gsd/tools/plan-slice.js +12 -6
- package/dist/resources/extensions/gsd/uat-policy.js +42 -16
- package/dist/resources/extensions/gsd/unit-closeout.js +138 -0
- package/dist/resources/extensions/gsd/unit-context-composer.js +74 -1
- package/dist/resources/extensions/gsd/unit-context-manifest.js +4 -27
- package/dist/resources/extensions/gsd/unit-registry.js +337 -0
- package/dist/resources/extensions/gsd/unit-tool-contracts.js +9 -182
- package/dist/resources/extensions/gsd/verdict-parser.js +1 -1
- package/dist/resources/extensions/gsd/web-app-uat.js +45 -8
- package/dist/resources/extensions/gsd/workflow-tool-surface.js +1 -1
- package/dist/resources/extensions/gsd/worktree-git-recovery.js +15 -9
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +3 -2
- package/dist/resources/extensions/gsd/worktree-root.js +11 -0
- package/dist/resources/extensions/gsd/worktree-session-state.js +4 -5
- package/dist/resources/extensions/search-the-web/native-search.js +5 -3
- package/dist/resources/extensions/shared/browser-contract.js +59 -0
- package/dist/resources/extensions/shared/gsd-browser-cli.js +96 -5
- package/dist/resources/shared/package.json +3 -0
- package/dist/resources/skills/create-skill/references/executable-code.md +1 -1
- package/dist/resources/skills/create-skill/workflows/add-reference.md +8 -3
- package/dist/resources/skills/create-skill/workflows/add-script.md +4 -2
- package/dist/resources/skills/create-skill/workflows/add-template.md +3 -1
- package/dist/resources/skills/create-skill/workflows/add-workflow.md +8 -3
- package/dist/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
- package/dist/resources/skills/create-skill/workflows/verify-skill.md +9 -4
- package/dist/resources/skills/spike-wrap-up/SKILL.md +9 -9
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
- 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/api/update/route.js.nft.json +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 +12 -12
- package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
- 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/middleware-react-loadable-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/dist/web/standalone/.next/static/chunks/{796.cf859a427a2cb2ac.js → 796.e0bdc932325d7e03.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{webpack-fbea77b5f9953368.js → webpack-f0285ce91d4ec9ef.js} +1 -1
- package/dist/web/standalone/package.json +1 -1
- package/dist/worktree-cli.js +3 -6
- package/dist/worktree-status-banner.js +7 -15
- package/package.json +1 -1
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/dist/rpc.d.ts +1 -0
- package/packages/contracts/dist/rpc.d.ts.map +1 -1
- package/packages/contracts/dist/rpc.js.map +1 -1
- package/packages/contracts/dist/workflow.d.ts +4 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- 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/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +5 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +5 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +7 -0
- 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 +8 -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-chat-render.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +11 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +4 -4
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +3 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/cli.js +6 -3
- package/packages/mcp-server/dist/cli.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +8 -0
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +17 -1
- 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/harness/env/nodejs.d.ts +1 -0
- package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/harness/env/nodejs.js +34 -3
- package/packages/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
- package/packages/pi-agent-core/dist/index.d.ts +1 -0
- package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/index.js +3 -0
- package/packages/pi-agent-core/dist/index.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/README.md +1 -0
- package/packages/pi-ai/dist/image-models.generated.d.ts +2 -2
- package/packages/pi-ai/dist/image-models.generated.js +6 -6
- package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +35 -125
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +46 -120
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/package.json +3 -2
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +2 -2
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +19 -13
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/provider-readiness.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/provider-readiness.js +13 -6
- package/packages/pi-coding-agent/dist/core/provider-readiness.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +11 -0
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.js +53 -11
- package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/utils/shell.d.ts +28 -2
- package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/utils/shell.js +56 -10
- package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +9 -0
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/package.json +2 -2
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/src/resources/GSD-WORKFLOW.md +5 -4
- package/src/resources/extensions/async-jobs/async-bash-cancel.test.ts +360 -0
- package/src/resources/extensions/async-jobs/async-bash-tool.ts +33 -56
- package/src/resources/extensions/async-jobs/await-tool.test.ts +139 -0
- package/src/resources/extensions/async-jobs/await-tool.ts +82 -12
- package/src/resources/extensions/async-jobs/index.ts +79 -0
- package/src/resources/extensions/async-jobs/job-manager.ts +21 -1
- package/src/resources/extensions/bg-shell/bg-shell-command.ts +6 -6
- package/src/resources/extensions/bg-shell/bg-shell-tool.ts +10 -6
- package/src/resources/extensions/bg-shell/overlay.ts +9 -5
- package/src/resources/extensions/bg-shell/process-manager.ts +50 -25
- package/src/resources/extensions/bg-shell/readiness-detector.ts +12 -0
- package/src/resources/extensions/bg-shell/tests/lifecycle-and-utilities.test.ts +48 -1
- package/src/resources/extensions/bg-shell/utilities.ts +3 -0
- package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +265 -98
- package/src/resources/extensions/browser-tools/engine/selection.ts +90 -4
- package/src/resources/extensions/browser-tools/index.ts +71 -13
- package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +83 -13
- package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +29 -1
- package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +136 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +34 -4
- package/src/resources/extensions/gsd/auto/custom-verify-retry-store.ts +21 -3
- package/src/resources/extensions/gsd/auto/detect-stuck.ts +32 -9
- package/src/resources/extensions/gsd/auto/dispatch-history.ts +152 -0
- package/src/resources/extensions/gsd/auto/dispatch-key.ts +39 -0
- package/src/resources/extensions/gsd/auto/loop.ts +4 -1
- package/src/resources/extensions/gsd/auto/orchestrator.ts +70 -46
- package/src/resources/extensions/gsd/auto/phases.ts +2 -2
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +8 -32
- package/src/resources/extensions/gsd/auto-dispatch.ts +38 -52
- package/src/resources/extensions/gsd/auto-model-selection.ts +25 -5
- package/src/resources/extensions/gsd/auto-post-unit.ts +25 -8
- package/src/resources/extensions/gsd/auto-prompts.ts +118 -35
- package/src/resources/extensions/gsd/auto-start.ts +18 -17
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +19 -0
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +14 -21
- package/src/resources/extensions/gsd/auto-verification.ts +8 -26
- package/src/resources/extensions/gsd/auto-worktree.ts +30 -93
- package/src/resources/extensions/gsd/auto.ts +8 -15
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +3 -5
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +23 -6
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +24 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +251 -47
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +352 -84
- package/src/resources/extensions/gsd/branch-patterns.ts +3 -0
- package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +108 -0
- package/src/resources/extensions/gsd/browser-evidence.ts +18 -2
- package/src/resources/extensions/gsd/captures.ts +4 -6
- package/src/resources/extensions/gsd/consent-question.ts +416 -0
- package/src/resources/extensions/gsd/consent-verdict.ts +86 -0
- package/src/resources/extensions/gsd/constants.ts +0 -3
- package/src/resources/extensions/gsd/crash-recovery.ts +3 -9
- package/src/resources/extensions/gsd/db/queries.ts +37 -0
- package/src/resources/extensions/gsd/dispatch-guard.ts +8 -31
- package/src/resources/extensions/gsd/doctor-environment.ts +2 -7
- package/src/resources/extensions/gsd/doctor-format.ts +12 -7
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +13 -15
- package/src/resources/extensions/gsd/engine-hook-contract.ts +79 -0
- package/src/resources/extensions/gsd/error-classifier.ts +11 -0
- package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
- package/src/resources/extensions/gsd/files.ts +33 -12
- package/src/resources/extensions/gsd/guidance.ts +217 -0
- package/src/resources/extensions/gsd/guided-flow.ts +16 -2
- package/src/resources/extensions/gsd/markdown-renderer.ts +11 -0
- package/src/resources/extensions/gsd/mcp-filter.ts +2 -23
- package/src/resources/extensions/gsd/mcp-tool-name.ts +6 -11
- package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +1 -1
- package/src/resources/extensions/gsd/migrate/safety.ts +4 -1
- package/src/resources/extensions/gsd/milestone-closeout.ts +13 -23
- package/src/resources/extensions/gsd/notification-store.ts +26 -3
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +6 -4
- package/src/resources/extensions/gsd/parsers-legacy.ts +16 -4
- package/src/resources/extensions/gsd/paths.ts +33 -0
- package/src/resources/extensions/gsd/pre-execution-checks.ts +109 -3
- package/src/resources/extensions/gsd/preferences-models.ts +12 -47
- package/src/resources/extensions/gsd/prompts/complete-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/replan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/run-uat.md +6 -4
- package/src/resources/extensions/gsd/prompts/system.md +5 -2
- package/src/resources/extensions/gsd/provider-error-guidance.ts +4 -9
- package/src/resources/extensions/gsd/provider-switch-observer.ts +1 -1
- package/src/resources/extensions/gsd/publication.ts +122 -0
- package/src/resources/extensions/gsd/reactive-graph.ts +11 -1
- package/src/resources/extensions/gsd/recovery-classification.ts +42 -96
- package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
- package/src/resources/extensions/gsd/state.ts +9 -21
- package/src/resources/extensions/gsd/stop-notice.ts +75 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +101 -26
- package/src/resources/extensions/gsd/tests/browser-automation-contract-fixture.ts +39 -0
- package/src/resources/extensions/gsd/tests/browser-contract.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +144 -0
- package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +66 -1
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +8 -7
- package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/consent-question.test.ts +336 -0
- package/src/resources/extensions/gsd/tests/custom-verify-retry-store.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +10 -10
- package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +303 -0
- package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +273 -0
- package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/dynamic-bash-no-cap.test.ts +132 -0
- package/src/resources/extensions/gsd/tests/engine-hook-contract.test.ts +148 -0
- package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +193 -0
- package/src/resources/extensions/gsd/tests/exec-tool.test.ts +29 -1
- package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +35 -1
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/guidance.test.ts +148 -0
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +53 -11
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +73 -58
- package/src/resources/extensions/gsd/tests/integration/gsd-integration-fixture.ts +80 -0
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +199 -0
- package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +32 -1
- package/src/resources/extensions/gsd/tests/notification-store.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +167 -0
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +139 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +193 -1
- package/src/resources/extensions/gsd/tests/prompt-db.test.ts +124 -6
- package/src/resources/extensions/gsd/tests/provider-error-guidance.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/publication.test.ts +120 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/stop-notice.test.ts +70 -0
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +76 -0
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +155 -0
- package/src/resources/extensions/gsd/tests/uat-policy.test.ts +112 -29
- package/src/resources/extensions/gsd/tests/unit-closeout.test.ts +209 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +67 -2
- package/src/resources/extensions/gsd/tests/unit-registry.test.ts +163 -0
- package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +44 -1
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +358 -0
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +67 -1
- package/src/resources/extensions/gsd/tool-presentation-plan.ts +4 -4
- package/src/resources/extensions/gsd/tool-surface-readiness.ts +76 -0
- package/src/resources/extensions/gsd/tools/complete-slice.ts +20 -10
- package/src/resources/extensions/gsd/tools/exec-tool.ts +8 -7
- package/src/resources/extensions/gsd/tools/plan-slice.ts +12 -6
- package/src/resources/extensions/gsd/uat-policy.ts +62 -16
- package/src/resources/extensions/gsd/unit-closeout.ts +201 -0
- package/src/resources/extensions/gsd/unit-context-composer.ts +111 -1
- package/src/resources/extensions/gsd/unit-context-manifest.ts +4 -28
- package/src/resources/extensions/gsd/unit-registry.ts +412 -0
- package/src/resources/extensions/gsd/unit-tool-contracts.ts +27 -192
- package/src/resources/extensions/gsd/verdict-parser.ts +1 -1
- package/src/resources/extensions/gsd/web-app-uat.ts +51 -8
- package/src/resources/extensions/gsd/workflow-tool-surface.ts +4 -1
- package/src/resources/extensions/gsd/worktree-git-recovery.ts +15 -9
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +3 -8
- package/src/resources/extensions/gsd/worktree-root.ts +12 -0
- package/src/resources/extensions/gsd/worktree-session-state.ts +3 -5
- package/src/resources/extensions/search-the-web/native-search.ts +5 -3
- package/src/resources/extensions/shared/browser-contract.ts +66 -0
- package/src/resources/extensions/shared/gsd-browser-cli.ts +119 -5
- package/src/resources/shared/package.json +3 -0
- package/src/resources/skills/create-skill/references/executable-code.md +1 -1
- package/src/resources/skills/create-skill/workflows/add-reference.md +8 -3
- package/src/resources/skills/create-skill/workflows/add-script.md +4 -2
- package/src/resources/skills/create-skill/workflows/add-template.md +3 -1
- package/src/resources/skills/create-skill/workflows/add-workflow.md +8 -3
- package/src/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
- package/src/resources/skills/create-skill/workflows/verify-skill.md +9 -4
- package/src/resources/skills/spike-wrap-up/SKILL.md +9 -9
- package/dist/resources/extensions/gsd/user-input-boundary.js +0 -218
- package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +0 -173
- package/src/resources/extensions/gsd/user-input-boundary.ts +0 -216
- /package/dist/web/standalone/.next/static/{C24pqUd-aru-l0Dp0gLZP → jmTLg6xZmAuq_LIqKOxrH}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{C24pqUd-aru-l0Dp0gLZP → jmTLg6xZmAuq_LIqKOxrH}/_ssgManifest.js +0 -0
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// Project/App: gsd-pi
|
|
2
2
|
// File Purpose: ADR-015 Recovery Classification module for runtime failure taxonomy.
|
|
3
|
+
import { isToolUnavailableError } from "./auto-tool-tracking.js";
|
|
3
4
|
import { classifyError, isTransient } from "./error-classifier.js";
|
|
5
|
+
import { recoveryRemediation } from "./guidance.js";
|
|
4
6
|
import { ReconciliationFailedError } from "./state-reconciliation.js";
|
|
5
7
|
import { IllegalPhaseTransitionError } from "./state-transition-matrix.js";
|
|
6
8
|
export function classifyFailure(input) {
|
|
@@ -13,103 +15,44 @@ export function classifyFailure(input) {
|
|
|
13
15
|
: input.error instanceof IllegalPhaseTransitionError
|
|
14
16
|
? "illegal-transition"
|
|
15
17
|
: input.failureKind ?? inferFailureKind(message);
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
failureKind,
|
|
28
|
-
action: "stop",
|
|
29
|
-
reason: `Tool Contract failure${unitSuffix(input)}: ${message}`,
|
|
30
|
-
exitReason: "tool-contract",
|
|
31
|
-
remediation: "Fix the Unit Tool Contract or prompt so the Unit is only asked to use tools owned by its phase.",
|
|
32
|
-
};
|
|
33
|
-
case "deterministic-policy":
|
|
34
|
-
return {
|
|
35
|
-
failureKind,
|
|
36
|
-
action: "stop",
|
|
37
|
-
reason: `Deterministic policy failure${unitSuffix(input)}: ${message}`,
|
|
38
|
-
exitReason: "deterministic-policy",
|
|
39
|
-
remediation: "Resolve the policy blocker; retrying the same Unit will repeat the failure.",
|
|
40
|
-
};
|
|
41
|
-
case "lifecycle-progression":
|
|
42
|
-
return {
|
|
43
|
-
failureKind,
|
|
44
|
-
action: "stop",
|
|
45
|
-
reason: `Lifecycle progression failure${unitSuffix(input)}: ${message}`,
|
|
46
|
-
exitReason: "lifecycle-progression",
|
|
47
|
-
remediation: "Route to the required owning Unit or restore the missing artifact before advancing lifecycle state.",
|
|
48
|
-
};
|
|
49
|
-
case "stale-worker":
|
|
50
|
-
return {
|
|
51
|
-
failureKind,
|
|
52
|
-
action: "stop",
|
|
53
|
-
reason: `Stale worker failure${unitSuffix(input)}: ${message}`,
|
|
54
|
-
exitReason: "stale-worker",
|
|
55
|
-
remediation: "Clear or reconcile the stale worker before dispatching another Unit.",
|
|
56
|
-
};
|
|
57
|
-
case "worktree-invalid":
|
|
58
|
-
return {
|
|
59
|
-
failureKind,
|
|
60
|
-
action: "stop",
|
|
61
|
-
reason: `Worktree invalid${unitSuffix(input)}: ${message}`,
|
|
62
|
-
exitReason: "worktree-invalid",
|
|
63
|
-
remediation: "Repair or recreate the milestone worktree before launching source-writing Units.",
|
|
64
|
-
};
|
|
65
|
-
case "verification-drift":
|
|
66
|
-
return {
|
|
67
|
-
failureKind,
|
|
68
|
-
action: "escalate",
|
|
69
|
-
reason: `Verification drift${unitSuffix(input)}: ${message}`,
|
|
70
|
-
exitReason: "verification-drift",
|
|
71
|
-
remediation: "Inspect the verification artifact and reconcile the state snapshot before resuming.",
|
|
72
|
-
};
|
|
73
|
-
case "reconciliation-drift":
|
|
74
|
-
return {
|
|
75
|
-
failureKind,
|
|
76
|
-
action: "escalate",
|
|
77
|
-
reason: `Reconciliation drift${unitSuffix(input)}: ${message}`,
|
|
78
|
-
exitReason: "reconciliation-drift",
|
|
79
|
-
remediation: "Inspect the persistent or repair-failed drift kinds reported by the State Reconciliation Module before resuming.",
|
|
80
|
-
};
|
|
81
|
-
case "illegal-transition":
|
|
82
|
-
return {
|
|
83
|
-
failureKind,
|
|
84
|
-
action: "escalate",
|
|
85
|
-
reason: `Illegal phase transition${unitSuffix(input)}: ${message}`,
|
|
86
|
-
exitReason: "illegal-transition",
|
|
87
|
-
remediation: "A derived Phase edge rejected by the Phase Transition Invariant survived reconciliation; inspect deriveState and the State Reconciliation Module before resuming.",
|
|
88
|
-
};
|
|
89
|
-
case "provider": {
|
|
90
|
-
const providerClass = classifyError(message, input.retryAfterMs);
|
|
91
|
-
return {
|
|
92
|
-
failureKind,
|
|
93
|
-
action: isTransient(providerClass) ? "retry" : "escalate",
|
|
94
|
-
reason: message,
|
|
95
|
-
exitReason: `provider-${providerClass.kind}`,
|
|
96
|
-
remediation: isTransient(providerClass)
|
|
97
|
-
? "Retry after the provider/network condition clears."
|
|
98
|
-
: "Inspect provider credentials, model entitlement, or request shape.",
|
|
99
|
-
providerClass: providerClass.kind,
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
case "runtime-unknown":
|
|
103
|
-
return {
|
|
104
|
-
failureKind,
|
|
105
|
-
action: "escalate",
|
|
106
|
-
reason: message,
|
|
107
|
-
exitReason: "runtime-unknown",
|
|
108
|
-
remediation: "Inspect the runtime error and add a dedicated classification if it is repeatable.",
|
|
109
|
-
};
|
|
18
|
+
if (failureKind === "provider") {
|
|
19
|
+
const providerClass = classifyError(message, input.retryAfterMs);
|
|
20
|
+
const transient = isTransient(providerClass);
|
|
21
|
+
return {
|
|
22
|
+
failureKind,
|
|
23
|
+
action: transient ? "retry" : "escalate",
|
|
24
|
+
reason: message,
|
|
25
|
+
exitReason: `provider-${providerClass.kind}`,
|
|
26
|
+
remediation: recoveryRemediation(transient ? "provider-transient" : "provider-permanent"),
|
|
27
|
+
providerClass: providerClass.kind,
|
|
28
|
+
};
|
|
110
29
|
}
|
|
30
|
+
const { action, label } = FAILURE_TAXONOMY[failureKind];
|
|
31
|
+
return {
|
|
32
|
+
failureKind,
|
|
33
|
+
action,
|
|
34
|
+
reason: label ? `${label}${unitSuffix(input)}: ${message}` : message,
|
|
35
|
+
exitReason: failureKind,
|
|
36
|
+
remediation: recoveryRemediation(failureKind),
|
|
37
|
+
};
|
|
111
38
|
}
|
|
39
|
+
/** Per-kind action and reason label. Remediation lives in the Guidance module. */
|
|
40
|
+
const FAILURE_TAXONOMY = {
|
|
41
|
+
"tool-schema": { action: "stop", label: "Tool schema failure" },
|
|
42
|
+
"tool-contract": { action: "stop", label: "Tool Contract failure" },
|
|
43
|
+
"tool-unavailable": { action: "retry", label: "Tool unavailable" },
|
|
44
|
+
"deterministic-policy": { action: "stop", label: "Deterministic policy failure" },
|
|
45
|
+
"lifecycle-progression": { action: "stop", label: "Lifecycle progression failure" },
|
|
46
|
+
"stale-worker": { action: "stop", label: "Stale worker failure" },
|
|
47
|
+
"worktree-invalid": { action: "stop", label: "Worktree invalid" },
|
|
48
|
+
"verification-drift": { action: "escalate", label: "Verification drift" },
|
|
49
|
+
"reconciliation-drift": { action: "escalate", label: "Reconciliation drift" },
|
|
50
|
+
"illegal-transition": { action: "escalate", label: "Illegal phase transition" },
|
|
51
|
+
"runtime-unknown": { action: "escalate", label: null },
|
|
52
|
+
};
|
|
112
53
|
function inferFailureKind(message) {
|
|
54
|
+
if (isToolUnavailableError(message))
|
|
55
|
+
return "tool-unavailable";
|
|
113
56
|
if (/tool contract|auto-unit tool scope|phase-boundary gate|not permitted.*own/i.test(message))
|
|
114
57
|
return "tool-contract";
|
|
115
58
|
if (/lifecycle progression|required artifact|missing .*assessment|missing .*closeout|cannot legally (?:advance|progress)/i.test(message))
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One-shot confirmation token for destructive bash commands.
|
|
3
|
+
*
|
|
4
|
+
* The destructive-command guard hard-blocks classified commands (force push,
|
|
5
|
+
* rm -rf, SQL drop, etc.) in all modes. The block instructs the model to
|
|
6
|
+
* confirm via ask_user_questions and re-issue the command. This module is the
|
|
7
|
+
* missing escape hatch: it records the user's confirmation and lets the exact
|
|
8
|
+
* confirmed command through exactly once.
|
|
9
|
+
*
|
|
10
|
+
* Design constraints:
|
|
11
|
+
* - In-memory only, never persisted. A confirmation token written to disk
|
|
12
|
+
* could silently auto-approve a destructive command in a later session —
|
|
13
|
+
* confirmation must be re-obtained every process lifetime.
|
|
14
|
+
* - One-shot. Consuming a token clears it, so a second destructive command
|
|
15
|
+
* (even an identical one) re-blocks and re-prompts.
|
|
16
|
+
* - Command-bound. The token only matches the exact (normalized) command
|
|
17
|
+
* string the user confirmed. A reworded command re-blocks, which is safe.
|
|
18
|
+
* - Per basePath, so concurrent workspaces in one process never share tokens.
|
|
19
|
+
*
|
|
20
|
+
* Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
|
|
21
|
+
*/
|
|
22
|
+
import { resolve } from "node:path";
|
|
23
|
+
/**
|
|
24
|
+
* Question-id substring that marks an ask_user_questions call as a
|
|
25
|
+
* destructive-command confirmation. The tool_result handler promotes the
|
|
26
|
+
* pending command to a confirmed token when an affirmative answer arrives for
|
|
27
|
+
* a question whose id contains this marker.
|
|
28
|
+
*/
|
|
29
|
+
export const DESTRUCTIVE_CONFIRM_GATE_MARKER = "destructive_confirm";
|
|
30
|
+
const statesByBasePath = new Map();
|
|
31
|
+
function stateKey(basePath) {
|
|
32
|
+
return resolve(basePath);
|
|
33
|
+
}
|
|
34
|
+
function getState(basePath) {
|
|
35
|
+
const key = stateKey(basePath);
|
|
36
|
+
let state = statesByBasePath.get(key);
|
|
37
|
+
if (!state) {
|
|
38
|
+
state = { pendingCommand: null, confirmedCommand: null };
|
|
39
|
+
statesByBasePath.set(key, state);
|
|
40
|
+
}
|
|
41
|
+
return state;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Normalize a command for stable matching across block → confirm → retry.
|
|
45
|
+
* Trims surrounding whitespace and collapses internal runs of whitespace so
|
|
46
|
+
* cosmetic reformatting of the same command still matches the token.
|
|
47
|
+
*/
|
|
48
|
+
export function normalizeDestructiveCommand(command) {
|
|
49
|
+
return command.replace(/\s+/g, " ").trim();
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Whether an ask_user_questions question id is a destructive-confirm gate.
|
|
53
|
+
*/
|
|
54
|
+
export function isDestructiveConfirmGateId(questionId) {
|
|
55
|
+
return typeof questionId === "string" && questionId.includes(DESTRUCTIVE_CONFIRM_GATE_MARKER);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Record that a destructive command was blocked and is awaiting confirmation.
|
|
59
|
+
* Called by the guard at block time. Overwrites any prior pending command —
|
|
60
|
+
* only the most recently blocked command can be confirmed.
|
|
61
|
+
*/
|
|
62
|
+
export function requestDestructiveConfirmation(command, basePath = process.cwd()) {
|
|
63
|
+
const state = getState(basePath);
|
|
64
|
+
state.pendingCommand = normalizeDestructiveCommand(command);
|
|
65
|
+
// A fresh request invalidates any stale confirmed token for a different
|
|
66
|
+
// command so confirmation cannot leak across distinct destructive actions.
|
|
67
|
+
state.confirmedCommand = null;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Promote the pending command to a confirmed, one-shot token. Called by the
|
|
71
|
+
* tool_result handler when the user gives an affirmative answer to a
|
|
72
|
+
* destructive-confirm gate. Returns the confirmed command, or null if there
|
|
73
|
+
* was nothing pending (e.g. confirmation arrived without a preceding block).
|
|
74
|
+
*/
|
|
75
|
+
export function confirmDestructiveCommand(basePath = process.cwd()) {
|
|
76
|
+
const state = getState(basePath);
|
|
77
|
+
if (!state.pendingCommand)
|
|
78
|
+
return null;
|
|
79
|
+
state.confirmedCommand = state.pendingCommand;
|
|
80
|
+
state.pendingCommand = null;
|
|
81
|
+
return state.confirmedCommand;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Check whether the given command has been confirmed, consuming the token if
|
|
85
|
+
* so. Returns true exactly once per confirmation; subsequent calls (or a
|
|
86
|
+
* non-matching command) return false. Called by the guard before blocking.
|
|
87
|
+
*/
|
|
88
|
+
export function consumeDestructiveConfirmation(command, basePath = process.cwd()) {
|
|
89
|
+
const state = getState(basePath);
|
|
90
|
+
if (!state.confirmedCommand)
|
|
91
|
+
return false;
|
|
92
|
+
if (state.confirmedCommand !== normalizeDestructiveCommand(command))
|
|
93
|
+
return false;
|
|
94
|
+
state.confirmedCommand = null;
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Inspect the pending command without consuming it (diagnostics/tests).
|
|
99
|
+
*/
|
|
100
|
+
export function peekPendingDestructiveCommand(basePath = process.cwd()) {
|
|
101
|
+
return getState(basePath).pendingCommand;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Clear all destructive-confirmation state for a basePath (tests / flow reset).
|
|
105
|
+
*/
|
|
106
|
+
export function resetDestructiveConfirmation(basePath = process.cwd()) {
|
|
107
|
+
statesByBasePath.delete(stateKey(basePath));
|
|
108
|
+
}
|
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
// GSD Extension — State Derivation
|
|
4
4
|
// DB-authoritative runtime derivation with explicit legacy filesystem fallback.
|
|
5
5
|
// Pure TypeScript, zero Pi dependencies.
|
|
6
|
+
// Pre-migration fallback ONLY (ADR-017): deriveState must work on projects
|
|
7
|
+
// whose DB does not exist yet (before md-importer runs), so it parses markdown
|
|
8
|
+
// projections when `isDbAvailable()` is false or the DB has no rows. Once the
|
|
9
|
+
// DB is populated, decision reads go through gsd-db queries — these parsers
|
|
10
|
+
// must never be consulted when DB data is present.
|
|
6
11
|
import { parseRoadmap, parsePlan, } from './parsers-legacy.js';
|
|
7
12
|
import { parseSummary, loadFile, parseRequirementCounts, parseContextDependsOn, } from './files.js';
|
|
8
13
|
import { resolveMilestoneFile, resolveSlicePath, resolveSliceFile, resolveTaskFile, resolveTasksDir, resolveGsdRootFile, gsdRoot, } from './paths.js';
|
|
@@ -22,26 +27,7 @@ import { isDbAvailable, getAllMilestones, getMilestone, getMilestoneSlices, getS
|
|
|
22
27
|
import { wasWorkflowDatabaseOpenAttempted } from './db-workspace.js';
|
|
23
28
|
import { formatCompletePhaseNextAction, countUnmappedActiveRequirements } from './requirements-backlog.js';
|
|
24
29
|
import { classifyMilestoneReadiness, readinessNeedsDiscussion, } from './milestone-readiness.js';
|
|
25
|
-
|
|
26
|
-
return [
|
|
27
|
-
`Milestone ${milestoneId} is blocked because milestone validation returned needs-attention.`,
|
|
28
|
-
`Fix options:`,
|
|
29
|
-
`1. Review the validation details: \`/gsd status\``,
|
|
30
|
-
`2. If you fixed the missing evidence or issue, re-run milestone validation: \`/gsd validate-milestone\``,
|
|
31
|
-
`3. If the finding is acceptable, override it: \`/gsd verdict pass --rationale "why this is okay"\``,
|
|
32
|
-
`4. If this should wait, defer it explicitly: \`/gsd park ${milestoneId}\``,
|
|
33
|
-
`After validation or override passes, run \`/gsd auto\` to complete and merge the milestone.`,
|
|
34
|
-
].join("\n");
|
|
35
|
-
}
|
|
36
|
-
function formatNeedsRemediationBlocker(milestoneId) {
|
|
37
|
-
return [
|
|
38
|
-
`Milestone ${milestoneId} is blocked because milestone validation returned needs-remediation, but all slices are complete.`,
|
|
39
|
-
`Fix options:`,
|
|
40
|
-
`1. Run \`/gsd dispatch reassess\` to add remediation slices, then run \`/gsd auto\``,
|
|
41
|
-
`2. If the finding is acceptable, override it: \`/gsd verdict pass --rationale "why this is okay"\``,
|
|
42
|
-
`3. If this should wait, defer it explicitly: \`/gsd park ${milestoneId}\``,
|
|
43
|
-
].join("\n");
|
|
44
|
-
}
|
|
30
|
+
import { needsAttentionBlockerGuidance as formatNeedsAttentionBlocker, needsRemediationBlockerGuidance as formatNeedsRemediationBlocker, } from './guidance.js';
|
|
45
31
|
/**
|
|
46
32
|
* A "ghost" milestone directory contains only META.json (and no substantive
|
|
47
33
|
* files like CONTEXT, CONTEXT-DRAFT, ROADMAP, or SUMMARY). These appear when
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// Project/App: gsd-pi
|
|
2
|
+
// File Purpose: Stop Notice module — single owner of the auto/step-mode
|
|
3
|
+
// stop/pause notice vocabulary. Both sides of the wire live here: the
|
|
4
|
+
// formatters that produce the canonical prefixes (used by stopAuto/pauseAuto)
|
|
5
|
+
// and the classifiers that recognize them (used by the headless host to pick
|
|
6
|
+
// exit codes). Wording changes in this file keep emitter and detector in
|
|
7
|
+
// lockstep; round-trip tests enforce it.
|
|
8
|
+
/** A reason string of the form "Blocked: …" marks a blocked stop. */
|
|
9
|
+
export function isBlockedStopReason(reason) {
|
|
10
|
+
return /^Blocked:\s*/i.test(reason ?? "");
|
|
11
|
+
}
|
|
12
|
+
/** Strip the "Blocked: " marker for display. */
|
|
13
|
+
export function stopNoticeDisplayReason(reason) {
|
|
14
|
+
return (reason ?? "").replace(/^Blocked:\s*/i, "").trim();
|
|
15
|
+
}
|
|
16
|
+
export function stopNoticeKind(reason) {
|
|
17
|
+
return isBlockedStopReason(reason) ? "blocked" : "stopped";
|
|
18
|
+
}
|
|
19
|
+
/** Canonical stop-notice prefix: "Auto-mode blocked — reason" / "Auto-mode stopped". */
|
|
20
|
+
export function formatStopNoticePrefix(reason) {
|
|
21
|
+
const displayReason = stopNoticeDisplayReason(reason);
|
|
22
|
+
const prefix = stopNoticeKind(reason) === "blocked" ? "Auto-mode blocked" : "Auto-mode stopped";
|
|
23
|
+
return displayReason ? `${prefix} — ${displayReason}` : prefix;
|
|
24
|
+
}
|
|
25
|
+
// ─── Classification (headless host side) ────────────────────────────────
|
|
26
|
+
// The canonical lowercase prefixes the headless event loop recognizes in
|
|
27
|
+
// notify messages. Emitters above and ad-hoc emitters elsewhere must start
|
|
28
|
+
// their terminal notices with one of these.
|
|
29
|
+
export const PAUSED_NOTICE_PREFIXES = ["auto-mode paused", "step-mode paused"];
|
|
30
|
+
export const TERMINAL_NOTICE_PREFIXES = [
|
|
31
|
+
"auto-mode stopped",
|
|
32
|
+
"step-mode stopped",
|
|
33
|
+
"auto-mode complete",
|
|
34
|
+
"no active milestone",
|
|
35
|
+
"auto-mode idle",
|
|
36
|
+
];
|
|
37
|
+
/** Manual-resolution notices emitted before auto-mode can formally pause/stop. */
|
|
38
|
+
export function isManualResolutionNotice(message) {
|
|
39
|
+
return (message.includes("resolve manually and re-run /gsd auto") ||
|
|
40
|
+
message.includes("resolve conflicts manually and run /gsd auto to resume") ||
|
|
41
|
+
message.includes("resolve and run /gsd auto to resume"));
|
|
42
|
+
}
|
|
43
|
+
export function isPauseNotice(message) {
|
|
44
|
+
return PAUSED_NOTICE_PREFIXES.some((prefix) => message.startsWith(prefix));
|
|
45
|
+
}
|
|
46
|
+
export function isTerminalNotice(message) {
|
|
47
|
+
return TERMINAL_NOTICE_PREFIXES.some((prefix) => message.startsWith(prefix));
|
|
48
|
+
}
|
|
49
|
+
/** Pauses that do not require operator intervention in headless mode. */
|
|
50
|
+
export function isNonBlockingPauseNotice(message) {
|
|
51
|
+
return message.includes("idempotent advance: unit already active");
|
|
52
|
+
}
|
|
53
|
+
export function isBlockedNoticeMessage(message) {
|
|
54
|
+
return (message.includes("blocked:") ||
|
|
55
|
+
(isPauseNotice(message) && !isNonBlockingPauseNotice(message)) ||
|
|
56
|
+
isManualResolutionNotice(message));
|
|
57
|
+
}
|
|
@@ -4,7 +4,7 @@ import { RUN_UAT_BROWSER_TOOL_NAMES, RUN_UAT_READ_ONLY_TOOL_NAMES, RUN_UAT_TOOL_
|
|
|
4
4
|
import { toMcpToolName } from "./mcp-tool-name.js";
|
|
5
5
|
import { createToolSurfaceSnapshot } from "./tool-surface-snapshot.js";
|
|
6
6
|
import { uatTypeIncludesBrowser } from "./uat-policy.js";
|
|
7
|
-
import {
|
|
7
|
+
import { canonicalWorkflowToolName } from "./engine-hook-contract.js";
|
|
8
8
|
export { RUN_UAT_BROWSER_TOOL_NAMES, RUN_UAT_READ_ONLY_TOOL_NAMES, RUN_UAT_TOOL_PRESENTATION_PLAN_ID, RUN_UAT_WORKFLOW_TOOL_NAMES, } from "./unit-tool-contracts.js";
|
|
9
9
|
export const RUN_UAT_FORBIDDEN_TOOL_NAMES = [
|
|
10
10
|
"edit",
|
|
@@ -24,9 +24,9 @@ export const RUN_UAT_CLAUDE_NATIVE_TOOL_NAMES = [
|
|
|
24
24
|
"Glob",
|
|
25
25
|
"Grep",
|
|
26
26
|
];
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
27
|
+
// Normalizer seam lives in engine-hook-contract.ts; re-exported here for
|
|
28
|
+
// existing presentation importers (uat-run.ts).
|
|
29
|
+
export { canonicalWorkflowToolName };
|
|
30
30
|
export { parseMcpToolName } from "./mcp-tool-name.js";
|
|
31
31
|
export function toWorkflowMcpToolName(serverName, toolName) {
|
|
32
32
|
return toMcpToolName(serverName, canonicalWorkflowToolName(toolName));
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Project/App: gsd-pi
|
|
2
|
+
// File Purpose: Tool Contract module's runtime face — verify the live SDK tool surface covers a Unit's required workflow tools.
|
|
3
|
+
import { mcpToolMatchesBaseName } from "./mcp-tool-name.js";
|
|
4
|
+
import { getRequiredWorkflowToolsForUnit } from "./unit-tool-contracts.js";
|
|
5
|
+
import { isWorkflowToolSurfaceName } from "./workflow-tool-surface.js";
|
|
6
|
+
/**
|
|
7
|
+
* Stable phrase recognized as transient by auto-tool-tracking's
|
|
8
|
+
* isToolUnavailableError and error-classifier's transient buckets,
|
|
9
|
+
* which build their matchers from this constant.
|
|
10
|
+
*/
|
|
11
|
+
export const TOOL_SURFACE_NOT_READY = "workflow tool surface not ready";
|
|
12
|
+
/** MCP server statuses that will not self-heal within the session. */
|
|
13
|
+
const TERMINAL_MCP_SERVER_STATUSES = new Set(["failed", "needs-auth", "disabled"]);
|
|
14
|
+
/**
|
|
15
|
+
* Verify the live tool surface observed at SDK session init covers the Unit's
|
|
16
|
+
* required workflow tools. Complements the static pre-dispatch gate
|
|
17
|
+
* (getWorkflowTransportSupportError), which only proves the MCP launch config
|
|
18
|
+
* is discoverable — the workflow server connects asynchronously after session
|
|
19
|
+
* start, so the static gate cannot see whether the tools actually registered.
|
|
20
|
+
*
|
|
21
|
+
* Returns a transient, recovery-classifiable error (kind tool-unavailable →
|
|
22
|
+
* retry) when the workflow server failed or has not yet registered a required
|
|
23
|
+
* tool, so dispatch aborts before the first model turn instead of letting the
|
|
24
|
+
* Unit improvise around "No such tool available". Returns null when no
|
|
25
|
+
* workflow server is part of this session (native tool path), when the Unit
|
|
26
|
+
* requires no workflow tools, or when the surface is ready.
|
|
27
|
+
*/
|
|
28
|
+
export function getToolSurfaceReadinessError(input) {
|
|
29
|
+
const { unitType, workflowServerName, observation } = input;
|
|
30
|
+
if (!unitType || !workflowServerName)
|
|
31
|
+
return null;
|
|
32
|
+
const required = getRequiredWorkflowToolsForUnit(unitType).filter(isWorkflowToolSurfaceName);
|
|
33
|
+
if (required.length === 0)
|
|
34
|
+
return null;
|
|
35
|
+
const server = observation.mcpServers.find((entry) => entry.name === workflowServerName);
|
|
36
|
+
if (!server) {
|
|
37
|
+
return `${TOOL_SURFACE_NOT_READY} for ${unitType}: MCP server "${workflowServerName}" is absent from the init surface (not yet connected): ${required.join(", ")}`;
|
|
38
|
+
}
|
|
39
|
+
// The SDK does not wait for MCP servers before init — a still-connecting
|
|
40
|
+
// server reports "pending" there routinely, then registers within seconds,
|
|
41
|
+
// usually well before the Unit's first workflow tool call. Aborting on
|
|
42
|
+
// "pending" would fail the common healthy session, so it passes through;
|
|
43
|
+
// a genuine miss after pass-through still surfaces in-session as
|
|
44
|
+
// "No such tool available" and classifies tool-unavailable → bounded retry.
|
|
45
|
+
// Only statuses that cannot self-heal abort here.
|
|
46
|
+
if (server.status !== "connected" && !TERMINAL_MCP_SERVER_STATUSES.has(server.status)) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
const missing = required.filter((tool) => !observation.tools.some((name) => name === tool || mcpToolMatchesBaseName(name, tool)));
|
|
50
|
+
if (missing.length === 0)
|
|
51
|
+
return null;
|
|
52
|
+
const serverDetail = server.status === "connected"
|
|
53
|
+
? `MCP server "${workflowServerName}" is connected but has not registered`
|
|
54
|
+
: `MCP server "${workflowServerName}" status is "${server.status}" and it has not registered`;
|
|
55
|
+
return `${TOOL_SURFACE_NOT_READY} for ${unitType}: ${serverDetail}: ${missing.join(", ")}`;
|
|
56
|
+
}
|
|
@@ -17,10 +17,9 @@ import { gsdProjectionRoot, clearPathCache, resolveMilestoneFile } from "../path
|
|
|
17
17
|
import { resolveCanonicalMilestoneRoot } from "../worktree-manager.js";
|
|
18
18
|
import { checkOwnership, sliceUnitKey } from "../unit-ownership.js";
|
|
19
19
|
import { saveFile, clearParseCache } from "../files.js";
|
|
20
|
-
import {
|
|
20
|
+
import { classifyUatContent, escalatesArtifactUatToBrowser } from "../uat-policy.js";
|
|
21
21
|
import { invalidateStateCache } from "../state.js";
|
|
22
|
-
import { renderRoadmapFromDb } from "../markdown-renderer.js";
|
|
23
|
-
import { parseRoadmap } from "../parsers-legacy.js";
|
|
22
|
+
import { renderRoadmapFromDb, roadmapRenderMarksSliceDone } from "../markdown-renderer.js";
|
|
24
23
|
import { isStaleWrite } from "../auto/turn-epoch.js";
|
|
25
24
|
import { renderAllProjections } from "../workflow-projections.js";
|
|
26
25
|
import { writeManifest } from "../workflow-manifest.js";
|
|
@@ -55,9 +54,11 @@ function hasCompleteSliceArtifactContract(basePath, milestoneId, sliceId) {
|
|
|
55
54
|
join(gsdProjectionRoot(basePath), "milestones", milestoneId, `${milestoneId}-ROADMAP.md`);
|
|
56
55
|
if (!existsSync(roadmapPath))
|
|
57
56
|
return false;
|
|
57
|
+
// Projection-completeness check (ADR-017): the DB has already recorded the
|
|
58
|
+
// duplicate completion; this only verifies the rendered markdown artifacts
|
|
59
|
+
// exist and reflect it, deciding whether re-rendering is needed.
|
|
58
60
|
try {
|
|
59
|
-
|
|
60
|
-
return roadmap.slices.some((slice) => slice.id === sliceId && slice.done);
|
|
61
|
+
return roadmapRenderMarksSliceDone(readFileSync(roadmapPath, "utf-8"), sliceId);
|
|
61
62
|
}
|
|
62
63
|
catch {
|
|
63
64
|
return false;
|
|
@@ -288,10 +289,18 @@ export async function handleCompleteSlice(params, basePath) {
|
|
|
288
289
|
// `npx playwright test` via gsd_uat_exec, and live-runtime/mixed/
|
|
289
290
|
// browser-executable receive browser tools (UAT_MODE_POLICIES).
|
|
290
291
|
const uatContent = params.uatContent || "";
|
|
291
|
-
const
|
|
292
|
-
if (
|
|
292
|
+
const uatPolicy = classifyUatContent(uatContent);
|
|
293
|
+
if (escalatesArtifactUatToBrowser(uatPolicy)) {
|
|
294
|
+
// Distinguish an explicit artifact-driven declaration from a missing or
|
|
295
|
+
// unparseable one that merely *defaulted* to artifact-driven — telling an
|
|
296
|
+
// agent it "declared artifact-driven" when its declaration simply failed
|
|
297
|
+
// to parse sends it into a rewrite loop with the same unparseable format.
|
|
298
|
+
const staticOnlyClause = `which only runs static/file checks and would defer the browser work to a human`;
|
|
299
|
+
const modeClause = uatPolicy.modeDeclared
|
|
300
|
+
? `declares "UAT mode: artifact-driven", ${staticOnlyClause}`
|
|
301
|
+
: `has no parseable UAT mode declaration in its "## UAT Type" section (the declaration must be a bullet exactly like "- UAT mode: browser-executable"), so it defaults to "artifact-driven", ${staticOnlyClause}`;
|
|
293
302
|
return {
|
|
294
|
-
error: `UAT requires browser verification (opening a page in a browser, navigating to a page or localhost, screenshots) but
|
|
303
|
+
error: `UAT requires browser verification (opening a page in a browser, navigating to a page or localhost, screenshots) but ${modeClause}. Use a mode that actually verifies the UI: "browser-executable" (interactive browser tools), "runtime-executable" (a browser test command such as playwright), or a browser-inclusive "mixed"/"live-runtime". Re-author the UAT Type section and complete the slice again.`,
|
|
295
304
|
};
|
|
296
305
|
}
|
|
297
306
|
// ── Atomic completion cascade (guards + writes in one transaction) ───────
|
|
@@ -388,8 +397,9 @@ export async function handleCompleteSlice(params, basePath) {
|
|
|
388
397
|
await saveFile(uatPath, uatMd);
|
|
389
398
|
const roadmap = await renderRoadmapFromDb(artifactBasePath, params.milestoneId);
|
|
390
399
|
clearParseCache();
|
|
391
|
-
|
|
392
|
-
|
|
400
|
+
// Render verification (ADR-017): confirms the just-written projection
|
|
401
|
+
// reflects the DB completion; the DB row is already committed.
|
|
402
|
+
if (!roadmapRenderMarksSliceDone(roadmap.content, params.sliceId)) {
|
|
393
403
|
throw new Error(`roadmap render did not mark ${params.milestoneId}/${params.sliceId} complete`);
|
|
394
404
|
}
|
|
395
405
|
}
|
|
@@ -4,7 +4,7 @@ import { EXEC_DEFAULTS, runExecSandbox, } from "../exec-sandbox.js";
|
|
|
4
4
|
import { realpathSync } from "node:fs";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { isContextModeEnabled } from "../preferences-types.js";
|
|
7
|
-
import {
|
|
7
|
+
import { projectRootFromWorktreePath } from "../worktree-root.js";
|
|
8
8
|
import { contextModeDisabledResult } from "./context-mode-tool-result.js";
|
|
9
9
|
const UAT_EXEC_INTENTS = [
|
|
10
10
|
"uat-artifact-check",
|
|
@@ -142,13 +142,10 @@ function normalizeScanPath(value) {
|
|
|
142
142
|
}
|
|
143
143
|
function parseWorktreeBase(baseDir) {
|
|
144
144
|
const normalizedBase = normalizeScanPath(baseDir);
|
|
145
|
-
const
|
|
146
|
-
if (!
|
|
145
|
+
const originalRoot = projectRootFromWorktreePath(normalizedBase);
|
|
146
|
+
if (!originalRoot)
|
|
147
147
|
return null;
|
|
148
|
-
return {
|
|
149
|
-
originalRoot: normalizedBase.slice(0, segment.gsdIdx),
|
|
150
|
-
worktreeRoot: normalizedBase,
|
|
151
|
-
};
|
|
148
|
+
return { originalRoot, worktreeRoot: normalizedBase };
|
|
152
149
|
}
|
|
153
150
|
function pathInside(parent, target) {
|
|
154
151
|
const parentWithSep = parent.endsWith("/") ? parent : `${parent}/`;
|
|
@@ -345,6 +342,7 @@ function formatResult(result) {
|
|
|
345
342
|
exit_code: result.exit_code,
|
|
346
343
|
signal: result.signal,
|
|
347
344
|
timed_out: result.timed_out,
|
|
345
|
+
force_resolved: result.force_resolved,
|
|
348
346
|
duration_ms: result.duration_ms,
|
|
349
347
|
stdout_bytes: result.stdout_bytes,
|
|
350
348
|
stderr_bytes: result.stderr_bytes,
|
|
@@ -358,6 +356,10 @@ function formatResult(result) {
|
|
|
358
356
|
};
|
|
359
357
|
}
|
|
360
358
|
function formatExit(result) {
|
|
359
|
+
// force_resolved means a non-closing (D-state) child was force-resolved past its
|
|
360
|
+
// hard deadline rather than observed exiting; distinguish it from a clean timeout.
|
|
361
|
+
if (result.force_resolved)
|
|
362
|
+
return "timeout(force-killed)";
|
|
361
363
|
if (result.timed_out)
|
|
362
364
|
return "timeout";
|
|
363
365
|
if (result.signal)
|
|
@@ -12,7 +12,8 @@ import { writeManifest } from "../workflow-manifest.js";
|
|
|
12
12
|
import { appendEvent } from "../workflow-events.js";
|
|
13
13
|
import { logWarning } from "../workflow-logger.js";
|
|
14
14
|
import { validatePathOnlyPlanningFields, validatePlanningPathScope } from "../planning-path-scope.js";
|
|
15
|
-
import {
|
|
15
|
+
import { runTaskPathChecks } from "../pre-execution-checks.js";
|
|
16
|
+
import { resolveWorktreeProjectRoot } from "../worktree-root.js";
|
|
16
17
|
import { buildTaskFileName, gsdProjectionRoot } from "../paths.js";
|
|
17
18
|
import { loadEffectiveGSDPreferences } from "../preferences.js";
|
|
18
19
|
import { createRepositoryRegistryFromPreferences, defaultRepositoryTargets } from "../repository-registry.js";
|
|
@@ -193,11 +194,16 @@ function validateTaskPathsBeforePersist(params, basePath, defaultTargets, allowe
|
|
|
193
194
|
const additionalRoots = allowedRoots
|
|
194
195
|
.map((root) => resolve(root))
|
|
195
196
|
.filter((root) => root !== baseRoot);
|
|
196
|
-
const
|
|
197
|
-
const
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
197
|
+
const resolvedCanonicalRoot = resolve(resolveWorktreeProjectRoot(basePath));
|
|
198
|
+
const canonicalProjectRoot = resolvedCanonicalRoot !== baseRoot ? resolvedCanonicalRoot : undefined;
|
|
199
|
+
const hasContext = additionalRoots.length > 0 || canonicalProjectRoot !== undefined;
|
|
200
|
+
const context = hasContext
|
|
201
|
+
? {
|
|
202
|
+
...(additionalRoots.length > 0 ? { additionalRoots } : {}),
|
|
203
|
+
...(canonicalProjectRoot !== undefined ? { canonicalProjectRoot } : {}),
|
|
204
|
+
}
|
|
205
|
+
: undefined;
|
|
206
|
+
const checks = runTaskPathChecks(taskRows, basePath, context);
|
|
201
207
|
const blocking = checks.filter((check) => !check.passed && check.blocking);
|
|
202
208
|
if (blocking.length === 0)
|
|
203
209
|
return null;
|