@opengsd/gsd-pi 1.2.0-dev.955e4da0 → 1.2.0-dev.fb12b103
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 +7 -29
- 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/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/orchestrator.js +7 -5
- package/dist/resources/extensions/gsd/auto-dispatch.js +12 -1
- package/dist/resources/extensions/gsd/auto-model-selection.js +25 -6
- package/dist/resources/extensions/gsd/auto-post-unit.js +11 -2
- package/dist/resources/extensions/gsd/auto-prompts.js +15 -10
- package/dist/resources/extensions/gsd/auto-start.js +15 -10
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +18 -0
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +7 -16
- 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 +122 -20
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +6 -2
- 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/constants.js +0 -2
- package/dist/resources/extensions/gsd/crash-recovery.js +4 -12
- 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/error-classifier.js +9 -0
- package/dist/resources/extensions/gsd/exec-sandbox.js +30 -10
- package/dist/resources/extensions/gsd/guidance.js +98 -0
- package/dist/resources/extensions/gsd/guided-flow.js +17 -2
- 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/notification-store.js +11 -4
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +6 -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 +1 -1
- 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 +1 -1
- 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/recovery-classification.js +37 -94
- package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
- package/dist/resources/extensions/gsd/state.js +1 -20
- package/dist/resources/extensions/gsd/stop-notice.js +57 -0
- package/dist/resources/extensions/gsd/tool-surface-readiness.js +56 -0
- 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 +2 -1
- 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/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-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 +13 -13
- 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 +13 -13
- 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/node_modules/node-pty/build/Makefile +1 -1
- package/dist/web/standalone/node_modules/postcss/lib/container.js +18 -26
- package/dist/web/standalone/node_modules/postcss/lib/css-syntax-error.js +14 -47
- package/dist/web/standalone/node_modules/postcss/lib/declaration.js +4 -4
- package/dist/web/standalone/node_modules/postcss/lib/fromJSON.js +3 -3
- package/dist/web/standalone/node_modules/postcss/lib/input.js +29 -54
- package/dist/web/standalone/node_modules/postcss/lib/lazy-result.js +37 -47
- package/dist/web/standalone/node_modules/postcss/lib/map-generator.js +9 -26
- package/dist/web/standalone/node_modules/postcss/lib/no-work-result.js +55 -57
- package/dist/web/standalone/node_modules/postcss/lib/node.js +31 -99
- package/dist/web/standalone/node_modules/postcss/lib/parse.js +1 -1
- package/dist/web/standalone/node_modules/postcss/lib/parser.js +9 -10
- package/dist/web/standalone/node_modules/postcss/lib/postcss.js +12 -12
- package/dist/web/standalone/node_modules/postcss/lib/previous-map.js +11 -30
- package/dist/web/standalone/node_modules/postcss/lib/processor.js +7 -7
- package/dist/web/standalone/node_modules/postcss/lib/result.js +5 -5
- package/dist/web/standalone/node_modules/postcss/lib/rule.js +6 -6
- package/dist/web/standalone/node_modules/postcss/lib/stringifier.js +28 -69
- package/dist/web/standalone/node_modules/postcss/lib/tokenize.js +2 -6
- package/dist/web/standalone/node_modules/postcss/package.json +48 -48
- 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/dist/models.generated.d.ts +94 -382
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +149 -422
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- 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/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/orchestrator.ts +7 -5
- package/src/resources/extensions/gsd/auto-dispatch.ts +12 -0
- package/src/resources/extensions/gsd/auto-model-selection.ts +25 -5
- package/src/resources/extensions/gsd/auto-post-unit.ts +13 -2
- package/src/resources/extensions/gsd/auto-prompts.ts +40 -26
- package/src/resources/extensions/gsd/auto-start.ts +15 -10
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +19 -0
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +10 -17
- 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 +151 -15
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +6 -2
- 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/constants.ts +0 -3
- package/src/resources/extensions/gsd/crash-recovery.ts +3 -9
- 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/error-classifier.ts +11 -0
- package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
- package/src/resources/extensions/gsd/guidance.ts +139 -0
- package/src/resources/extensions/gsd/guided-flow.ts +16 -2
- 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/notification-store.ts +26 -3
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +6 -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 +1 -1
- 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 +1 -1
- 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/recovery-classification.ts +42 -96
- package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
- package/src/resources/extensions/gsd/state.ts +4 -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 +16 -19
- 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/destructive-confirmation.test.ts +303 -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/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/guidance.test.ts +125 -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/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/pre-execution-checks.test.ts +193 -1
- 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 +24 -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/tool-surface-readiness.ts +76 -0
- 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 +2 -1
- 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/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-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/web/standalone/.next/static/{C24pqUd-aru-l0Dp0gLZP → mU4QIDlpVHDdjDpeEKh5W}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{C24pqUd-aru-l0Dp0gLZP → mU4QIDlpVHDdjDpeEKh5W}/_ssgManifest.js +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** browser-tools — Pi Browser Automation Contract adapter. */
|
|
2
2
|
import { importExtensionModule } from "@gsd/pi-coding-agent";
|
|
3
3
|
import { closeManagedGsdBrowser, registerManagedGsdBrowserTools, warmUpManagedGsdBrowser } from "./engine/managed-gsd-browser.js";
|
|
4
|
-
import {
|
|
4
|
+
import { commitBrowserEngineResolution, resolveAmbientBrowserEngineResolution } from "./engine/selection.js";
|
|
5
5
|
import { setArtifactRootForCwd } from "./state.js";
|
|
6
6
|
import { detectWebApp } from "./web-app-detect.js";
|
|
7
7
|
let legacyRegistrationPromise = null;
|
|
@@ -130,12 +130,56 @@ function withBrowserArtifactCwdScope(pi) {
|
|
|
130
130
|
},
|
|
131
131
|
};
|
|
132
132
|
}
|
|
133
|
-
|
|
134
|
-
|
|
133
|
+
/** Daemon-connect budget when the probe-resolved managed engine is verified at session start. */
|
|
134
|
+
const PROBE_WARMUP_TIMEOUT_MS = 10_000;
|
|
135
|
+
async function registerBrowserTools(pi, ctx) {
|
|
136
|
+
const projectRoot = ctx.cwd || process.cwd();
|
|
137
|
+
const resolution = resolveAmbientBrowserEngineResolution(projectRoot);
|
|
138
|
+
let engine = resolution.engine;
|
|
135
139
|
if (engine === "off")
|
|
136
140
|
return;
|
|
141
|
+
// A probe-resolved managed engine is only a prediction that gsd-browser
|
|
142
|
+
// works — prove it by connecting the daemon before committing the session's
|
|
143
|
+
// tool registrations to it. Connect failure falls back to legacy Playwright
|
|
144
|
+
// (the failure mode that made ADR-024 freeze the old default) and commits
|
|
145
|
+
// the outcome so ambient readers see the engine actually in use. When eager
|
|
146
|
+
// warm-up is disabled the daemon-connect proof cannot run, so the probe
|
|
147
|
+
// default treats the managed engine as unprovable and falls back to legacy
|
|
148
|
+
// rather than registering it unverified. An explicit
|
|
149
|
+
// GSD_BROWSER_ENGINE=gsd-browser override skips the gate and is honored
|
|
150
|
+
// verbatim, matching prior behavior.
|
|
151
|
+
if (engine === "gsd-browser" && resolution.source === "probe" && !registeredEngine) {
|
|
152
|
+
if (isWarmUpDisabled()) {
|
|
153
|
+
engine = commitLegacyFallback(projectRoot, "warm-up disabled; managed engine unverifiable; using legacy Playwright");
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
const warmUp = await warmUpManagedGsdBrowser(ctx, AbortSignal.timeout(PROBE_WARMUP_TIMEOUT_MS));
|
|
157
|
+
if (!warmUp.ok) {
|
|
158
|
+
engine = commitLegacyFallback(projectRoot, `gsd-browser daemon connect failed (${warmUp.error}); using legacy Playwright`);
|
|
159
|
+
if (ctx.hasUI) {
|
|
160
|
+
ctx.ui.notify(`gsd-browser engine unavailable (${warmUp.error}); using Playwright browser tools for this session.`, "warning");
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
else if (warmUp.coverageWarning && ctx.hasUI) {
|
|
164
|
+
ctx.ui.notify(warmUp.coverageWarning, "warning");
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// Browser tool registrations are process-global and cannot be swapped once
|
|
169
|
+
// live. When an earlier session in this process already registered an engine
|
|
170
|
+
// and this project resolved a different one (per-project probe resolution can
|
|
171
|
+
// diverge across projects in a multi-session process), adopt the registered
|
|
172
|
+
// engine rather than throwing — a throw surfaces as "browser-tools failed to
|
|
173
|
+
// load" and leaves this session with no browser tools at all. Commit the
|
|
174
|
+
// adoption so ambient readers (UAT guidance, warm-up) describe the engine
|
|
175
|
+
// actually in use.
|
|
137
176
|
if (registeredEngine && registeredEngine !== engine) {
|
|
138
|
-
|
|
177
|
+
engine = registeredEngine;
|
|
178
|
+
commitBrowserEngineResolution(projectRoot, {
|
|
179
|
+
engine,
|
|
180
|
+
source: "probe",
|
|
181
|
+
reason: `browser tools already registered with ${engine} earlier in this process; adopting it`,
|
|
182
|
+
});
|
|
139
183
|
}
|
|
140
184
|
let registration;
|
|
141
185
|
if (engine === "legacy") {
|
|
@@ -165,27 +209,40 @@ async function registerBrowserTools(pi) {
|
|
|
165
209
|
throw error;
|
|
166
210
|
}
|
|
167
211
|
}
|
|
212
|
+
function commitLegacyFallback(projectRoot, reason) {
|
|
213
|
+
commitBrowserEngineResolution(projectRoot, { engine: "legacy", source: "probe", reason });
|
|
214
|
+
return "legacy";
|
|
215
|
+
}
|
|
168
216
|
function isWarmUpDisabled() {
|
|
169
217
|
const value = process.env.GSD_BROWSER_WARMUP?.trim().toLowerCase();
|
|
170
218
|
return value === "0" || value === "false" || value === "off";
|
|
171
219
|
}
|
|
172
220
|
/**
|
|
173
|
-
* Auto-initialize the managed gsd-browser engine
|
|
174
|
-
*
|
|
175
|
-
*
|
|
221
|
+
* Auto-initialize the managed gsd-browser engine when it was selected via the
|
|
222
|
+
* explicit GSD_BROWSER_ENGINE override, which registers without the
|
|
223
|
+
* daemon-connect gate. Best-effort and non-blocking: warm-up runs in the
|
|
224
|
+
* background and only surfaces a warning if it fails. Probe-resolved sessions
|
|
225
|
+
* already connected (or fell back) during registration, so they are excluded
|
|
226
|
+
* to avoid re-warming and double-notifying.
|
|
176
227
|
*/
|
|
177
228
|
function maybeWarmUpManagedEngine(pi, ctx) {
|
|
178
229
|
if (isWarmUpDisabled())
|
|
179
230
|
return;
|
|
180
|
-
if (resolveBrowserEngineMode() !== "gsd-browser")
|
|
181
|
-
return;
|
|
182
231
|
const projectRoot = ctx.cwd || process.cwd();
|
|
232
|
+
const resolution = resolveAmbientBrowserEngineResolution(projectRoot);
|
|
233
|
+
if (resolution.engine !== "gsd-browser" || resolution.source !== "env")
|
|
234
|
+
return;
|
|
183
235
|
if (!detectWebApp(projectRoot))
|
|
184
236
|
return;
|
|
185
237
|
void warmUpManagedGsdBrowser(ctx).then((result) => {
|
|
186
|
-
if (!
|
|
238
|
+
if (!ctx.hasUI)
|
|
239
|
+
return;
|
|
240
|
+
if (!result.ok) {
|
|
187
241
|
ctx.ui.notify(`gsd-browser auto-init failed: ${result.error}. Browser UAT tools will retry on first use; run /gsd doctor if this persists.`, "warning");
|
|
188
242
|
}
|
|
243
|
+
else if (result.coverageWarning) {
|
|
244
|
+
ctx.ui.notify(result.coverageWarning, "warning");
|
|
245
|
+
}
|
|
189
246
|
});
|
|
190
247
|
}
|
|
191
248
|
async function closeActiveBrowserEngines() {
|
|
@@ -198,14 +255,14 @@ async function closeActiveBrowserEngines() {
|
|
|
198
255
|
export default function (pi) {
|
|
199
256
|
pi.on("session_start", async (_event, ctx) => {
|
|
200
257
|
if (ctx.hasUI) {
|
|
201
|
-
void registerBrowserTools(pi)
|
|
258
|
+
void registerBrowserTools(pi, ctx)
|
|
202
259
|
.then(() => maybeWarmUpManagedEngine(pi, ctx))
|
|
203
260
|
.catch((error) => {
|
|
204
261
|
ctx.ui.notify(`browser-tools failed to load: ${error instanceof Error ? error.message : String(error)}`, "warning");
|
|
205
262
|
});
|
|
206
263
|
return;
|
|
207
264
|
}
|
|
208
|
-
await registerBrowserTools(pi);
|
|
265
|
+
await registerBrowserTools(pi, ctx);
|
|
209
266
|
maybeWarmUpManagedEngine(pi, ctx);
|
|
210
267
|
});
|
|
211
268
|
pi.on("session_shutdown", async () => {
|
|
@@ -24,6 +24,8 @@ import { markToolStart, markToolEnd } from "../gsd/auto.js";
|
|
|
24
24
|
import { markInteractiveElicitationStart, markInteractiveElicitationEnd, } from "../gsd/auto-tool-tracking.js";
|
|
25
25
|
import { discoverBrowserMcpServerName, discoverMcpServers, discoverMcpServerNames, discoverUserMcpServerNames, discoverWorkflowMcpServerName, computeMcpDisallowedTools, } from "../gsd/mcp-filter.js";
|
|
26
26
|
import { RUN_UAT_CLAUDE_NATIVE_TOOL_NAMES, RUN_UAT_FORBIDDEN_TOOL_NAMES, RUN_UAT_WORKFLOW_TOOL_NAMES, resolveToolPresentationPlan } from "../gsd/tool-presentation-plan.js";
|
|
27
|
+
import { getToolSurfaceReadinessError } from "../gsd/tool-surface-readiness.js";
|
|
28
|
+
import { hasBrowserContractPrefix } from "../shared/browser-contract.js";
|
|
27
29
|
import { showInterviewRound } from "../shared/tui.js";
|
|
28
30
|
export { buildFinalAssistantContent, extractToolResultsFromSdkUserMessage, handleClaudeCodePartialStreamEvent, mergePendingToolCalls, } from "./turn-assembler.js";
|
|
29
31
|
export function serverToolUseToToolCallLike(block) {
|
|
@@ -1289,7 +1291,7 @@ function browserMcpServerNameFromAllowedTools(allowedTools) {
|
|
|
1289
1291
|
const parsed = parseAllowedMcpToolName(toolName);
|
|
1290
1292
|
if (!parsed)
|
|
1291
1293
|
continue;
|
|
1292
|
-
if (parsed.server === "gsd-browser" || parsed.tool
|
|
1294
|
+
if (parsed.server === "gsd-browser" || hasBrowserContractPrefix(parsed.tool)) {
|
|
1293
1295
|
return parsed.server;
|
|
1294
1296
|
}
|
|
1295
1297
|
}
|
|
@@ -1303,7 +1305,7 @@ function workflowMcpServerNameFromAllowedTools(allowedTools) {
|
|
|
1303
1305
|
if (typeof toolName !== "string")
|
|
1304
1306
|
continue;
|
|
1305
1307
|
const parsed = parseAllowedMcpToolName(toolName);
|
|
1306
|
-
if (!parsed || parsed.server === browserServerName || parsed.tool
|
|
1308
|
+
if (!parsed || parsed.server === browserServerName || hasBrowserContractPrefix(parsed.tool))
|
|
1307
1309
|
continue;
|
|
1308
1310
|
return parsed.server;
|
|
1309
1311
|
}
|
|
@@ -1635,8 +1637,9 @@ async function pumpSdkMessages(model, context, options, stream) {
|
|
|
1635
1637
|
}
|
|
1636
1638
|
: {}),
|
|
1637
1639
|
});
|
|
1640
|
+
const workflowMcpServerName = workflowMcpServerNameFromAllowedTools(sdkOpts.allowedTools);
|
|
1638
1641
|
const prompt = buildPromptFromContext(context, {
|
|
1639
|
-
workflowMcpServerName
|
|
1642
|
+
workflowMcpServerName,
|
|
1640
1643
|
browserMcpServerName: browserMcpServerNameFromAllowedTools(sdkOpts.allowedTools),
|
|
1641
1644
|
});
|
|
1642
1645
|
const queryPrompt = buildSdkQueryPrompt(context, prompt);
|
|
@@ -1674,7 +1677,30 @@ async function pumpSdkMessages(model, context, options, stream) {
|
|
|
1674
1677
|
switch (msg.type) {
|
|
1675
1678
|
// -- Init --
|
|
1676
1679
|
case "system": {
|
|
1677
|
-
//
|
|
1680
|
+
// Tool Surface Readiness gate: the init message is the first (and
|
|
1681
|
+
// only) point where the session reports its live tool surface and
|
|
1682
|
+
// MCP server statuses. If the workflow server failed or has not
|
|
1683
|
+
// registered this Unit's required tools, abort before the first
|
|
1684
|
+
// model turn with a transient, recovery-classifiable error
|
|
1685
|
+
// (tool-unavailable → retry) instead of letting the model hit
|
|
1686
|
+
// "No such tool available" mid-Unit and improvise around it.
|
|
1687
|
+
const init = msg;
|
|
1688
|
+
if (init.subtype === "init") {
|
|
1689
|
+
const readinessError = getToolSurfaceReadinessError({
|
|
1690
|
+
unitType: gsdPhase,
|
|
1691
|
+
workflowServerName: workflowMcpServerName,
|
|
1692
|
+
observation: { tools: init.tools ?? [], mcpServers: init.mcp_servers ?? [] },
|
|
1693
|
+
});
|
|
1694
|
+
if (readinessError) {
|
|
1695
|
+
controller.abort();
|
|
1696
|
+
stream.push({
|
|
1697
|
+
type: "error",
|
|
1698
|
+
reason: "error",
|
|
1699
|
+
error: makeErrorMessage(modelId, readinessError),
|
|
1700
|
+
});
|
|
1701
|
+
return;
|
|
1702
|
+
}
|
|
1703
|
+
}
|
|
1678
1704
|
break;
|
|
1679
1705
|
}
|
|
1680
1706
|
// -- Streaming partial messages --
|
|
@@ -858,16 +858,18 @@ export class AutoOrchestrator {
|
|
|
858
858
|
// checks coexist: idempotency for the common immediate-repeat case,
|
|
859
859
|
// stuck-loop for the saturated-window case.
|
|
860
860
|
if (this.lastAdvanceKey === nextKey && matchingCount < STUCK_WINDOW_SIZE) {
|
|
861
|
+
// Unit already active — benign no-op. Return skipped so the loop re-polls
|
|
862
|
+
// without cancelling the in-flight unit (blocked+pause would force-cancel it).
|
|
861
863
|
this.clearPendingDispatch();
|
|
862
|
-
const
|
|
864
|
+
const skipped = { kind: "skipped", reason: "idempotent advance: unit already active" };
|
|
863
865
|
this.journalTransition({
|
|
864
|
-
name: "advance-
|
|
865
|
-
reason:
|
|
866
|
+
name: "advance-skipped",
|
|
867
|
+
reason: skipped.reason,
|
|
866
868
|
unitType: decision.unitType,
|
|
867
869
|
unitId: decision.unitId,
|
|
868
870
|
});
|
|
869
|
-
this.postAdvanceRecord(
|
|
870
|
-
return
|
|
871
|
+
this.postAdvanceRecord(skipped);
|
|
872
|
+
return skipped;
|
|
871
873
|
}
|
|
872
874
|
// Stuck-loop detection: when the ring is saturated with copies of
|
|
873
875
|
// `nextKey` (count >= STUCK_WINDOW_SIZE), the orchestrator has been
|
|
@@ -22,7 +22,8 @@ import { isAutoActive } from "./auto.js";
|
|
|
22
22
|
import { markDepthVerified } from "./bootstrap/write-gate.js";
|
|
23
23
|
import { ensureWorkflowPreferencesCaptured } from "./planning-depth.js";
|
|
24
24
|
import { MILESTONE_ID_RE } from "./milestone-ids.js";
|
|
25
|
-
import { getWorkflowTransportSupportError, getRequiredWorkflowToolsForAutoUnit, } from "./workflow-mcp.js";
|
|
25
|
+
import { getWorkflowTransportSupportError, getRequiredWorkflowToolsForAutoUnit, resolveWorkflowMcpProjectRoot, } from "./workflow-mcp.js";
|
|
26
|
+
import { prepareBrowserDaemonForUat } from "./browser-daemon-auto-prep.js";
|
|
26
27
|
import { PROJECT_RESEARCH_INFLIGHT_MARKER, } from "./project-research-policy.js";
|
|
27
28
|
import { isWorkflowPrefsCaptured, resolveDeepProjectSetupState, } from "./deep-project-setup-policy.js";
|
|
28
29
|
import { annotateBackgroundable } from "./delegation-policy.js";
|
|
@@ -540,6 +541,16 @@ export const DISPATCH_RULES = [
|
|
|
540
541
|
if (browserToolError) {
|
|
541
542
|
return { action: "stop", reason: browserToolError, level: "warning" };
|
|
542
543
|
}
|
|
544
|
+
const browserDaemonError = prepareBrowserDaemonForUat({
|
|
545
|
+
uatType,
|
|
546
|
+
sessionProvider,
|
|
547
|
+
sessionAuthMode,
|
|
548
|
+
sessionBaseUrl,
|
|
549
|
+
projectRoot: resolveWorkflowMcpProjectRoot(basePath),
|
|
550
|
+
});
|
|
551
|
+
if (browserDaemonError) {
|
|
552
|
+
return { action: "stop", reason: browserDaemonError, level: "warning" };
|
|
553
|
+
}
|
|
543
554
|
// Cap run-uat dispatch attempts to prevent infinite replay (#3624).
|
|
544
555
|
// Check before incrementing so an exhausted counter cannot create a
|
|
545
556
|
// no-progress skip loop that starves later dispatch rules.
|
|
@@ -839,15 +839,34 @@ export function resolveModelId(modelId, availableModels, currentProvider) {
|
|
|
839
839
|
if (providerMatch)
|
|
840
840
|
return providerMatch;
|
|
841
841
|
}
|
|
842
|
-
//
|
|
843
|
-
//
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
842
|
+
// Subscription/OAuth routes beat pay-per-token API when the same model ID
|
|
843
|
+
// exists on multiple providers. Order matters — first match wins.
|
|
844
|
+
for (const provider of BARE_ID_SUBSCRIPTION_PROVIDER_PRECEDENCE) {
|
|
845
|
+
const match = candidates.find(m => m.provider === provider);
|
|
846
|
+
if (match)
|
|
847
|
+
return match;
|
|
848
|
+
}
|
|
848
849
|
// Fall back to first non-extension candidate, or any candidate
|
|
849
850
|
return candidates.find(m => !EXTENSION_PROVIDERS.has(m.provider)) ?? candidates[0];
|
|
850
851
|
}
|
|
852
|
+
/**
|
|
853
|
+
* When a bare model ID exists on multiple providers, prefer subscription/OAuth
|
|
854
|
+
* routes over pay-per-token API keys. Matches PROVIDER_ROUTES in doctor-providers
|
|
855
|
+
* but applies when *both* sides are authenticated.
|
|
856
|
+
*
|
|
857
|
+
* Order rationale:
|
|
858
|
+
* - openai-codex before github-copilot: ChatGPT-native for shared GPT IDs
|
|
859
|
+
* - google-gemini-cli before github-copilot: first-party Gemini CLI
|
|
860
|
+
* - anthropic before github-copilot: first-party Claude API/OAuth over Copilot
|
|
861
|
+
* - github-copilot before openai/google: Copilot OAuth over platform API keys
|
|
862
|
+
*/
|
|
863
|
+
export const BARE_ID_SUBSCRIPTION_PROVIDER_PRECEDENCE = [
|
|
864
|
+
"openai-codex",
|
|
865
|
+
"google-gemini-cli",
|
|
866
|
+
"anthropic",
|
|
867
|
+
"github-copilot",
|
|
868
|
+
"google-antigravity",
|
|
869
|
+
];
|
|
851
870
|
/**
|
|
852
871
|
* Flat-rate providers charge the same per request regardless of model.
|
|
853
872
|
* Dynamic routing provides no cost benefit — it only degrades quality (#3453).
|
|
@@ -55,7 +55,7 @@ import { writeTurnGitTransaction } from "./uok/gitops.js";
|
|
|
55
55
|
import { isClosedStatus } from "./status-guards.js";
|
|
56
56
|
import { detectAbandonMilestone } from "./abandon-detect.js";
|
|
57
57
|
import { getPendingGate } from "./bootstrap/write-gate.js";
|
|
58
|
-
import { isDeterministicPolicyError } from "./auto-tool-tracking.js";
|
|
58
|
+
import { isDeterministicPolicyError, isToolUnavailableError } from "./auto-tool-tracking.js";
|
|
59
59
|
import { formatConnectedStepStack, formatPostUnitStatusCard } from "./auto-status-message.js";
|
|
60
60
|
import { clearProjectResearchInflightMarker, finalizeProjectResearchTimeout, } from "./project-research-policy.js";
|
|
61
61
|
import { validateArtifact } from "./schemas/validate.js";
|
|
@@ -1701,7 +1701,16 @@ export async function postUnitPreVerification(pctx, opts) {
|
|
|
1701
1701
|
ctx.ui.notify(`Artifact missing for ${s.currentUnit.type} ${s.currentUnit.id} — DB unavailable, skipping retry.${dbSkipDiag ? ` Expected: ${dbSkipDiag}` : ""}`, "error");
|
|
1702
1702
|
}
|
|
1703
1703
|
else if (!triggerArtifactVerified) {
|
|
1704
|
-
if (s.lastToolInvocationError) {
|
|
1704
|
+
if (s.lastToolInvocationError && isToolUnavailableError(s.lastToolInvocationError)) {
|
|
1705
|
+
// Tool-unavailable is the one transient invocation error: the
|
|
1706
|
+
// workflow MCP server registers its surface asynchronously, so a
|
|
1707
|
+
// Unit's first call can race the registration. Fall through to the
|
|
1708
|
+
// bounded verification retry instead of pausing.
|
|
1709
|
+
debugLog("postUnit", { phase: "tool-unavailable-retry", unitType: s.currentUnit.type, unitId: s.currentUnit.id, error: s.lastToolInvocationError });
|
|
1710
|
+
ctx.ui.notify(`Tool unavailable for ${s.currentUnit.type}: ${s.lastToolInvocationError}. The tool surface may still be registering — retrying.`, "warning");
|
|
1711
|
+
s.lastToolInvocationError = null;
|
|
1712
|
+
}
|
|
1713
|
+
else if (s.lastToolInvocationError) {
|
|
1705
1714
|
const isUserSkip = /queued user message/i.test(s.lastToolInvocationError);
|
|
1706
1715
|
const errMsg = isUserSkip
|
|
1707
1716
|
? `Tool skipped for ${s.currentUnit.type}: ${s.lastToolInvocationError}. Queued user message interrupted the turn — pausing auto-mode.`
|
|
@@ -21,7 +21,7 @@ import { getPendingGatesForTurn } from "./gsd-db.js";
|
|
|
21
21
|
import { assertGateCoverage, getGatesForTurn, } from "./gate-registry.js";
|
|
22
22
|
import { formatDecisionsCompact, formatRequirementsCompact } from "./structured-data-formatter.js";
|
|
23
23
|
import { readPhaseAnchor, formatAnchorForPrompt } from "./phase-anchor.js";
|
|
24
|
-
import { composeContextModeInstructions, composeContractedUnitContext, composeInlinedContext, composeUnitContext, } from "./unit-context-composer.js";
|
|
24
|
+
import { composeContextModeInstructions, composeContractedUnitContext, composeInlinedContext, composeToolSurfaceInstructions, composeUnitContext, } from "./unit-context-composer.js";
|
|
25
25
|
import { resolveManifest } from "./unit-context-manifest.js";
|
|
26
26
|
import { compileUnitContextContract } from "./tool-contract.js";
|
|
27
27
|
import { readCompactionSnapshot } from "./compaction-snapshot.js";
|
|
@@ -224,12 +224,14 @@ function renderContextModeBlockForPrompt(unitType, base, renderMode = "standalon
|
|
|
224
224
|
return `${contextMode}\n\n## Context Snapshot\nSource: \`.gsd/last-snapshot.md\`\n\n${snapshot.trimEnd()}`;
|
|
225
225
|
}
|
|
226
226
|
function prependContextModeToBlock(unitType, base, block, renderMode = "standalone") {
|
|
227
|
+
const toolSurface = composeToolSurfaceInstructions(unitType, { renderMode });
|
|
227
228
|
const contextMode = renderContextModeBlockForPrompt(unitType, base, renderMode);
|
|
228
|
-
|
|
229
|
+
const guidance = [toolSurface, contextMode].filter(Boolean).join("\n\n");
|
|
230
|
+
if (!guidance)
|
|
229
231
|
return block;
|
|
230
232
|
if (!block.trim())
|
|
231
|
-
return
|
|
232
|
-
return `${
|
|
233
|
+
return guidance;
|
|
234
|
+
return `${guidance}\n\n${block}`;
|
|
233
235
|
}
|
|
234
236
|
function requireUnitPromptContextContract(unitType) {
|
|
235
237
|
const result = compileUnitContextContract(unitType);
|
|
@@ -2146,6 +2148,9 @@ export async function buildPlanSlicePrompt(mid, _midTitle, sid, sTitle, base, le
|
|
|
2146
2148
|
`Either (a) add an earlier task that creates X on disk before the task that needs it, ` +
|
|
2147
2149
|
`or (b) if this task IS the one that creates X, move X from inputs to expected_output. ` +
|
|
2148
2150
|
`Do NOT put X in a task's expected_output if that task only reads or verifies X — only tasks that actually write X to disk should list it in expected_output.\n` +
|
|
2151
|
+
`- **"[file] X: ... GSD planning artifacts are projections preloaded as context / written by workflow tools"**: ` +
|
|
2152
|
+
`Remove X from the task's inputs, files, and expectedOutput entirely. Planning artifacts (anything under .gsd/, .planning/, or .audits/, or names like M001-CONTEXT.md / S01-PLAN.md) are preloaded as context and written by workflow tools — ` +
|
|
2153
|
+
`do NOT add a task that creates X and do NOT move X to expectedOutput.\n` +
|
|
2149
2154
|
`- **"[file] X: Task T_early reads X but it's created by task T_late (sequence violation)"**: ` +
|
|
2150
2155
|
`Either (a) reorder tasks so T_late (the creator) runs before T_early (the reader), ` +
|
|
2151
2156
|
`or (b) if T_late doesn't actually create X (it only reads/tests it), remove X from T_late's expected_output entirely.\n` +
|
|
@@ -3338,18 +3343,18 @@ opts) {
|
|
|
3338
3343
|
}
|
|
3339
3344
|
const inlinedTemplates = inlineTemplate("task-summary", "Task Summary");
|
|
3340
3345
|
trackPromptContext(contextTelemetry, "templates", "inline", inlinedTemplates);
|
|
3341
|
-
const prompt = loadPrompt("reactive-execute", {
|
|
3346
|
+
const prompt = prependContextModeToBlock("reactive-execute", base, loadPrompt("reactive-execute", {
|
|
3342
3347
|
workingDirectory: base,
|
|
3343
3348
|
milestoneId: mid,
|
|
3344
3349
|
milestoneTitle: midTitle,
|
|
3345
3350
|
sliceId: sid,
|
|
3346
3351
|
sliceTitle: sTitle,
|
|
3347
|
-
graphContext
|
|
3352
|
+
graphContext,
|
|
3348
3353
|
readyTaskCount: String(readyTaskIds.length),
|
|
3349
3354
|
readyTaskList: readyTaskListLines.join("\n"),
|
|
3350
3355
|
subagentPrompts: subagentSections.join("\n\n---\n\n"),
|
|
3351
3356
|
inlinedTemplates,
|
|
3352
|
-
});
|
|
3357
|
+
}));
|
|
3353
3358
|
emitPromptContextTelemetry("reactive-execute", contextTelemetry, prompt);
|
|
3354
3359
|
return prompt;
|
|
3355
3360
|
}
|
|
@@ -3489,17 +3494,17 @@ export async function buildGateEvaluatePrompt(mid, midTitle, sid, sTitle, base,
|
|
|
3489
3494
|
"```",
|
|
3490
3495
|
].join("\n"));
|
|
3491
3496
|
}
|
|
3492
|
-
return loadPrompt("gate-evaluate", {
|
|
3497
|
+
return prependContextModeToBlock("gate-evaluate", base, loadPrompt("gate-evaluate", {
|
|
3493
3498
|
workingDirectory: base,
|
|
3494
3499
|
milestoneId: mid,
|
|
3495
3500
|
milestoneTitle: midTitle,
|
|
3496
3501
|
sliceId: sid,
|
|
3497
3502
|
sliceTitle: sTitle,
|
|
3498
|
-
slicePlanContent:
|
|
3503
|
+
slicePlanContent: planContent,
|
|
3499
3504
|
gateCount: String(pending.length),
|
|
3500
3505
|
gateList: gateListLines.join("\n"),
|
|
3501
3506
|
subagentPrompts: subagentSections.join("\n\n---\n\n"),
|
|
3502
|
-
});
|
|
3507
|
+
}));
|
|
3503
3508
|
}
|
|
3504
3509
|
export async function buildRewriteDocsPrompt(mid, midTitle, activeSlice, base, overrides) {
|
|
3505
3510
|
const sid = activeSlice?.id;
|
|
@@ -25,7 +25,8 @@ import { ensureGitignore, untrackRuntimeFiles } from "./gitignore.js";
|
|
|
25
25
|
import { nativeIsRepo, nativeInit, nativeAddAll, nativeCommit, nativeGetCurrentBranch, nativeDetectMainBranch, nativeBranchList, nativeBranchExists, nativeBranchListMerged, nativeBranchDelete, nativeWorktreeRemove, nativeCommitCountBetween, nativeHasChanges, } from "./native-git-bridge.js";
|
|
26
26
|
import { GitServiceImpl } from "./git-service.js";
|
|
27
27
|
import { captureIntegrationBranch, detectWorktreeName, setActiveMilestoneId, } from "./worktree.js";
|
|
28
|
-
import { getAutoWorktreePath
|
|
28
|
+
import { getAutoWorktreePath } from "./auto-worktree.js";
|
|
29
|
+
import { checkoutBranchWithStashGuard } from "./worktree-git-recovery.js";
|
|
29
30
|
import { readResourceVersion, cleanStaleRuntimeUnits } from "./auto-worktree.js";
|
|
30
31
|
import { worktreePath as getWorktreeDir, isInsideWorktreesDir } from "./worktree-manager.js";
|
|
31
32
|
import { emitWorktreeOrphaned } from "./worktree-telemetry.js";
|
|
@@ -740,12 +741,14 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
740
741
|
// phase-specific planning model for a discuss turn (#2829).
|
|
741
742
|
//
|
|
742
743
|
// Precedence:
|
|
743
|
-
// 1) Explicit session override via /gsd model (this session)
|
|
744
|
-
// 2)
|
|
745
|
-
// 3)
|
|
744
|
+
// 1) Explicit session override via /gsd model or /gsd auto --model (this session)
|
|
745
|
+
// 2) GSD model preferences from PREFERENCES.md (validated against live auth)
|
|
746
|
+
// 3) Current session model from settings/session restore (if provider ready)
|
|
746
747
|
//
|
|
747
|
-
//
|
|
748
|
-
//
|
|
748
|
+
// PREFERENCES.md wins over the ambient session default (#3517) so /gsd auto
|
|
749
|
+
// does not stick on claude-code/claude-sonnet-4-6 when the user configured
|
|
750
|
+
// models via /gsd workflow-preferences or PREFERENCES.md. Custom providers
|
|
751
|
+
// still skip PREFERENCES.md entirely (#4122).
|
|
749
752
|
//
|
|
750
753
|
// Exception (#4122): when the session provider is a custom provider declared
|
|
751
754
|
// in ~/.gsd/agent/models.json (Ollama, vLLM, OpenAI-compatible proxy, etc.),
|
|
@@ -757,7 +760,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
757
760
|
const sessionProviderIsCustom = isCustomProvider(ctx.model?.provider);
|
|
758
761
|
const preferredModel = sessionProviderIsCustom
|
|
759
762
|
? null
|
|
760
|
-
: resolveDefaultSessionModel(ctx.model?.provider);
|
|
763
|
+
: resolveDefaultSessionModel(ctx.model?.provider, base);
|
|
761
764
|
// Validate the preferred model against the live registry + provider auth so
|
|
762
765
|
// an unconfigured PREFERENCES.md entry (no API key / OAuth) can't become the
|
|
763
766
|
// start-model snapshot. Without this, every subsequent unit would try to
|
|
@@ -780,8 +783,8 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
780
783
|
: null;
|
|
781
784
|
const startThinkingSnapshot = pi.getThinkingLevel();
|
|
782
785
|
const startModelSnapshot = manualSessionOverride
|
|
783
|
-
?? currentSessionModel
|
|
784
786
|
?? validatedPreferredModel
|
|
787
|
+
?? currentSessionModel
|
|
785
788
|
?? null;
|
|
786
789
|
try {
|
|
787
790
|
// Validate GSD_PROJECT_ID early so the user gets immediate feedback
|
|
@@ -1249,8 +1252,10 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
1249
1252
|
const normalized = p.replaceAll("\\", "/");
|
|
1250
1253
|
if (findWorktreeSegment(normalized) !== null)
|
|
1251
1254
|
return true;
|
|
1252
|
-
// The container directory itself (no trailing worktree name).
|
|
1253
|
-
return normalized.endsWith("/.gsd/worktrees")
|
|
1255
|
+
// The container directory itself (no trailing worktree name), in any layout.
|
|
1256
|
+
return normalized.endsWith("/.gsd/worktrees")
|
|
1257
|
+
|| normalized.endsWith("/.gsd-worktrees")
|
|
1258
|
+
|| /\/\.gsd\/projects\/[^/]+\/worktrees$/.test(normalized);
|
|
1254
1259
|
};
|
|
1255
1260
|
if (s.currentMilestoneId &&
|
|
1256
1261
|
(getIsolationMode(base) !== "none" || strandedRecoveryAction?.recoveryMode) &&
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* can distinguish "waiting for tool completion" from "truly idle".
|
|
5
5
|
*/
|
|
6
6
|
import { stripMcpToolPrefix } from "@gsd/pi-ai";
|
|
7
|
+
import { TOOL_SURFACE_NOT_READY } from "./tool-surface-readiness.js";
|
|
7
8
|
const inFlightTools = new Map();
|
|
8
9
|
/**
|
|
9
10
|
* Tools that block waiting for human input by design.
|
|
@@ -117,6 +118,14 @@ export function clearInFlightTools() {
|
|
|
117
118
|
*/
|
|
118
119
|
const TOOL_INVOCATION_ERROR_RE = /Validation failed for tool|Input validation error|Invalid arguments for tool|MCP error -32602|No such tool available|Expected ',' or '\}'(?: after property value)?(?: in JSON)?|Unexpected end of JSON|Unexpected token.*in JSON|does not provide an export named|Named export .* not found|Cannot find module|ERR_MODULE_NOT_FOUND|ERR_MODULE_NOT_EXPORTED|ERR_PACKAGE_PATH_NOT_EXPORTED/i;
|
|
119
120
|
const DETERMINISTIC_POLICY_ERROR_RE = /(?:^|\b)(?:HARD BLOCK:|Blocked: \/gsd queue is a planning tool|Direct writes to \.gsd\/STATE\.md and \.gsd\/gsd\.db are blocked|This is a mechanical gate)/i;
|
|
121
|
+
/**
|
|
122
|
+
* Matches the runtime's "tool not registered" error. Unlike the deterministic
|
|
123
|
+
* invocation failures above, this one is usually transient: the workflow MCP
|
|
124
|
+
* server registers its tool surface asynchronously after session start, so a
|
|
125
|
+
* Unit's first tool call can race the registration. Callers should retry
|
|
126
|
+
* (bounded) instead of breaking the loop.
|
|
127
|
+
*/
|
|
128
|
+
const TOOL_UNAVAILABLE_ERROR_RE = new RegExp(`No such tool available|${TOOL_SURFACE_NOT_READY}`, "i");
|
|
120
129
|
/**
|
|
121
130
|
* Returns true if the error message indicates a deterministic invocation or
|
|
122
131
|
* policy failure (as opposed to a normal tool execution error).
|
|
@@ -126,6 +135,15 @@ export function isToolInvocationError(errorMsg) {
|
|
|
126
135
|
return false;
|
|
127
136
|
return TOOL_INVOCATION_ERROR_RE.test(errorMsg) || isDeterministicPolicyError(errorMsg);
|
|
128
137
|
}
|
|
138
|
+
/**
|
|
139
|
+
* Returns true if the error message indicates the called tool was not on the
|
|
140
|
+
* session's tool surface (MCP startup race — see TOOL_UNAVAILABLE_ERROR_RE).
|
|
141
|
+
*/
|
|
142
|
+
export function isToolUnavailableError(errorMsg) {
|
|
143
|
+
if (!errorMsg)
|
|
144
|
+
return false;
|
|
145
|
+
return TOOL_UNAVAILABLE_ERROR_RE.test(errorMsg);
|
|
146
|
+
}
|
|
129
147
|
/**
|
|
130
148
|
* Returns true if the error message indicates the tool was skipped because
|
|
131
149
|
* a queued user message interrupted the turn (#3595). Retrying will produce
|
|
@@ -2,21 +2,12 @@ import { parseUnitId } from "./unit-id.js";
|
|
|
2
2
|
import { AUTO_UNIT_SCOPED_TOOLS, getForbiddenGsdToolReason, } from "./unit-tool-contracts.js";
|
|
3
3
|
import { WORKFLOW_TOOL_ALIAS_PAIRS, canonicalWorkflowSurfaceToolName, isWorkflowSurfaceAliasTool, stripMcpToolPrefix, } from "./workflow-tool-surface.js";
|
|
4
4
|
export { AUTO_UNIT_SCOPED_TOOLS, RUN_UAT_BROWSER_TOOL_NAMES, } from "./unit-tool-contracts.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
// from artifact sections. gsd_save_gate_result belongs to gate-evaluate, so keep
|
|
12
|
-
// blocking it here with a calm redirect to the section-write path.
|
|
13
|
-
const SECTION_CLOSE_GATE_UNIT_TYPES = new Set([
|
|
14
|
-
"execute-task",
|
|
15
|
-
"execute-task-simple",
|
|
16
|
-
"reactive-execute",
|
|
17
|
-
"complete-slice",
|
|
18
|
-
"validate-milestone",
|
|
19
|
-
]);
|
|
5
|
+
// Scope-class membership is declared per unit in the Unit Registry (ADR-033).
|
|
6
|
+
// EXECUTE_TASK_UNIT_TYPES = scopeClass "execute-task"; the section-close gate
|
|
7
|
+
// Set additionally includes scopeClass "section-close" — units whose completion
|
|
8
|
+
// handlers persist gate verdicts from artifact sections (gsd_save_gate_result
|
|
9
|
+
// belongs to gate-evaluate, so it is soft-blocked with a redirect below).
|
|
10
|
+
import { EXECUTE_TASK_UNIT_TYPES, SECTION_CLOSE_GATE_UNIT_TYPES, } from "./unit-registry.js";
|
|
20
11
|
const EXTRA_SCOPED_GSD_LIFECYCLE_TOOLS = [
|
|
21
12
|
"gsd_skip_slice",
|
|
22
13
|
"gsd_slice_reopen",
|
|
@@ -74,7 +65,7 @@ function allowedGsdToolsForUnit(unitType) {
|
|
|
74
65
|
function isNativeWorkflowTool(toolName) {
|
|
75
66
|
return stripMcpToolPrefix(toolName) === "Workflow";
|
|
76
67
|
}
|
|
77
|
-
function readStringField(input, camel, snake) {
|
|
68
|
+
export function readStringField(input, camel, snake) {
|
|
78
69
|
if (!input || typeof input !== "object")
|
|
79
70
|
return undefined;
|
|
80
71
|
const record = input;
|