@opengsd/gsd-pi 1.2.0-dev.b1abb545 → 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 +5 -2
- 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/models.js +9 -0
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +38 -6
- package/dist/resources/extensions/gsd/auto/orchestrator.js +40 -9
- package/dist/resources/extensions/gsd/auto/phases.js +6 -1
- 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 +19 -8
- package/dist/resources/extensions/gsd/auto-prompts.js +15 -10
- package/dist/resources/extensions/gsd/auto-start.js +21 -21
- 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-repair.js +10 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +35 -352
- package/dist/resources/extensions/gsd/auto.js +8 -20
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +3 -2
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +32 -12
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +19 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +151 -20
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +30 -4
- 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 +5 -15
- package/dist/resources/extensions/gsd/closeout-recovery.js +3 -2
- package/dist/resources/extensions/gsd/commands/catalog.js +6 -62
- 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/engine.js +755 -0
- package/dist/resources/extensions/gsd/db/queries.js +372 -0
- package/dist/resources/extensions/gsd/db/sql-constants.js +11 -0
- package/dist/resources/extensions/gsd/db/writers/cascades.js +194 -0
- package/dist/resources/extensions/gsd/db/writers/import-restore.js +182 -0
- package/dist/resources/extensions/gsd/db/writers/memory.js +149 -0
- package/dist/resources/extensions/gsd/db/writers/reconcile.js +458 -0
- package/dist/resources/extensions/gsd/db/writers/status.js +70 -0
- package/dist/resources/extensions/gsd/doctor-environment.js +5 -11
- package/dist/resources/extensions/gsd/doctor-format.js +9 -6
- package/dist/resources/extensions/gsd/doctor-git-checks.js +4 -3
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +21 -16
- 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/git-service.js +1 -0
- package/dist/resources/extensions/gsd/gitignore.js +3 -0
- package/dist/resources/extensions/gsd/gsd-db.js +171 -2048
- package/dist/resources/extensions/gsd/guidance.js +98 -0
- package/dist/resources/extensions/gsd/guided-flow.js +51 -5
- 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 +20 -9
- package/dist/resources/extensions/gsd/migration-auto-check.js +24 -3
- package/dist/resources/extensions/gsd/model-cost-table.js +1 -0
- package/dist/resources/extensions/gsd/model-router.js +3 -0
- package/dist/resources/extensions/gsd/notification-store.js +11 -4
- package/dist/resources/extensions/gsd/parallel-merge.js +14 -11
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +11 -7
- package/dist/resources/extensions/gsd/paths.js +37 -24
- 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/preferences.js +14 -0
- 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 +41 -87
- package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +37 -4
- package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +7 -2
- package/dist/resources/extensions/gsd/safety/file-change-validator.js +10 -0
- package/dist/resources/extensions/gsd/state-transition-matrix.js +38 -0
- package/dist/resources/extensions/gsd/state.js +1 -20
- package/dist/resources/extensions/gsd/status-guards.js +56 -8
- 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/complete-slice.js +24 -43
- package/dist/resources/extensions/gsd/tools/exec-tool.js +10 -8
- package/dist/resources/extensions/gsd/tools/plan-slice.js +12 -6
- package/dist/resources/extensions/gsd/tools/reopen-milestone.js +11 -29
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +14 -33
- package/dist/resources/extensions/gsd/tools/skip-slice.js +18 -36
- package/dist/resources/extensions/gsd/uat-policy.js +2 -1
- package/dist/resources/extensions/gsd/undo.js +8 -7
- 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 +293 -0
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +9 -1
- package/dist/resources/extensions/gsd/worktree-manager.js +45 -28
- package/dist/resources/extensions/gsd/worktree-placement.js +59 -0
- package/dist/resources/extensions/gsd/worktree-reentry.js +12 -8
- package/dist/resources/extensions/gsd/worktree-root.js +28 -6
- package/dist/resources/extensions/gsd/worktree-safety.js +8 -5
- package/dist/resources/extensions/gsd/worktree-session-state.js +12 -11
- 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/gsd-browser/SKILL.md +1 -1
- 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 +10 -10
- 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/boot/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +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/api/visualizer/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 +10 -10
- package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
- package/dist/web/standalone/.next/server/chunks/{5047.js → 5942.js} +2 -2
- 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 -11
- 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 +8 -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 +46 -21
- 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/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 +478 -484
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +500 -533
- 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/capability-patches.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.js +3 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.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 +5 -2
- 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/models.ts +9 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +40 -4
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +28 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -1
- package/src/resources/extensions/gsd/auto/orchestrator.ts +46 -10
- package/src/resources/extensions/gsd/auto/phases.ts +10 -1
- 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 +25 -7
- package/src/resources/extensions/gsd/auto-prompts.ts +40 -26
- package/src/resources/extensions/gsd/auto-start.ts +21 -22
- 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-repair.ts +13 -2
- package/src/resources/extensions/gsd/auto-worktree.ts +41 -364
- package/src/resources/extensions/gsd/auto.ts +20 -24
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +3 -5
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +33 -12
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +24 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +180 -15
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +29 -3
- 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 +5 -16
- package/src/resources/extensions/gsd/closeout-recovery.ts +2 -1
- package/src/resources/extensions/gsd/commands/catalog.ts +6 -68
- 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/engine.ts +809 -0
- package/src/resources/extensions/gsd/db/queries.ts +453 -0
- package/src/resources/extensions/gsd/db/sql-constants.ts +12 -0
- package/src/resources/extensions/gsd/db/writers/cascades.ts +237 -0
- package/src/resources/extensions/gsd/db/writers/import-restore.ts +310 -0
- package/src/resources/extensions/gsd/db/writers/memory.ts +220 -0
- package/src/resources/extensions/gsd/db/writers/reconcile.ts +500 -0
- package/src/resources/extensions/gsd/db/writers/status.ts +88 -0
- package/src/resources/extensions/gsd/doctor-environment.ts +5 -13
- package/src/resources/extensions/gsd/doctor-format.ts +12 -7
- package/src/resources/extensions/gsd/doctor-git-checks.ts +3 -3
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +22 -17
- 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/git-service.ts +1 -0
- package/src/resources/extensions/gsd/gitignore.ts +3 -0
- package/src/resources/extensions/gsd/gsd-db.ts +173 -2373
- package/src/resources/extensions/gsd/guidance.ts +139 -0
- package/src/resources/extensions/gsd/guided-flow.ts +50 -5
- 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 +18 -7
- package/src/resources/extensions/gsd/migration-auto-check.ts +28 -3
- package/src/resources/extensions/gsd/model-cost-table.ts +1 -0
- package/src/resources/extensions/gsd/model-router.ts +3 -0
- package/src/resources/extensions/gsd/notification-store.ts +26 -3
- package/src/resources/extensions/gsd/parallel-merge.ts +12 -9
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +10 -7
- package/src/resources/extensions/gsd/paths.ts +42 -22
- 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/preferences.ts +18 -0
- 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 +47 -88
- package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +36 -4
- package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +7 -2
- package/src/resources/extensions/gsd/safety/file-change-validator.ts +14 -0
- package/src/resources/extensions/gsd/state-transition-matrix.ts +42 -0
- package/src/resources/extensions/gsd/state.ts +4 -21
- package/src/resources/extensions/gsd/status-guards.ts +59 -8
- package/src/resources/extensions/gsd/stop-notice.ts +75 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +123 -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/auto-paused-ui-cleanup.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/auto-post-unit-evidence-crossref-4909.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-worktree-repair.test.ts +4 -2
- 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 +44 -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/evidence-xref-gsd-exec.test.ts +157 -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/file-change-validator.test.ts +33 -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 +58 -15
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +74 -59
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +3 -2
- 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/migration-auto-check.test.ts +85 -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/recovery-classification-illegal-transition.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +248 -1
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/session-switch-clears-pending-autostart.test.ts +108 -0
- package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +43 -6
- package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/status-guards.test.ts +38 -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/tests/worktree-lifecycle.test.ts +41 -4
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +22 -1
- package/src/resources/extensions/gsd/tests/worktree-placement.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +12 -6
- package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +42 -0
- package/src/resources/extensions/gsd/tool-surface-readiness.ts +76 -0
- package/src/resources/extensions/gsd/tools/complete-slice.ts +23 -58
- package/src/resources/extensions/gsd/tools/exec-tool.ts +9 -8
- package/src/resources/extensions/gsd/tools/plan-slice.ts +12 -6
- package/src/resources/extensions/gsd/tools/reopen-milestone.ts +11 -38
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +14 -42
- package/src/resources/extensions/gsd/tools/skip-slice.ts +18 -44
- package/src/resources/extensions/gsd/uat-policy.ts +2 -1
- package/src/resources/extensions/gsd/undo.ts +9 -8
- 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 +314 -0
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +10 -1
- package/src/resources/extensions/gsd/worktree-manager.ts +47 -28
- package/src/resources/extensions/gsd/worktree-placement.ts +63 -0
- package/src/resources/extensions/gsd/worktree-reentry.ts +10 -7
- package/src/resources/extensions/gsd/worktree-root.ts +29 -6
- package/src/resources/extensions/gsd/worktree-safety.ts +8 -5
- package/src/resources/extensions/gsd/worktree-session-state.ts +11 -11
- 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/gsd-browser/SKILL.md +1 -1
- package/src/resources/skills/spike-wrap-up/SKILL.md +9 -9
- /package/dist/web/standalone/.next/static/{3PtrU9qGPEXwNLWkIyiqk → mU4QIDlpVHDdjDpeEKh5W}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{3PtrU9qGPEXwNLWkIyiqk → 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 () => {
|
|
@@ -37,6 +37,15 @@ export const CLAUDE_CODE_MODELS = [
|
|
|
37
37
|
contextWindow: 1_000_000,
|
|
38
38
|
maxTokens: 128_000,
|
|
39
39
|
},
|
|
40
|
+
{
|
|
41
|
+
id: "claude-fable-5",
|
|
42
|
+
name: "Claude Fable 5 (via Claude Code)",
|
|
43
|
+
reasoning: true,
|
|
44
|
+
input: ["text", "image"],
|
|
45
|
+
cost: ZERO_COST,
|
|
46
|
+
contextWindow: 1_000_000,
|
|
47
|
+
maxTokens: 128_000,
|
|
48
|
+
},
|
|
40
49
|
{
|
|
41
50
|
id: "claude-sonnet-4-6",
|
|
42
51
|
name: "Claude Sonnet 4.6 (via Claude Code)",
|
|
@@ -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) {
|
|
@@ -1242,6 +1244,8 @@ function modelSupportsAdaptiveThinking(modelId) {
|
|
|
1242
1244
|
|| modelId.includes("opus-4.7")
|
|
1243
1245
|
|| modelId.includes("opus-4-8")
|
|
1244
1246
|
|| modelId.includes("opus-4.8")
|
|
1247
|
+
|| modelId.includes("fable-5")
|
|
1248
|
+
|| modelId.includes("fable.5")
|
|
1245
1249
|
|| modelId.includes("sonnet-4-6")
|
|
1246
1250
|
|| modelId.includes("sonnet-4.6")
|
|
1247
1251
|
|| modelId.includes("sonnet-4-7")
|
|
@@ -1263,7 +1267,9 @@ function mapThinkingLevelToAnthropicEffort(level, modelId) {
|
|
|
1263
1267
|
if (modelId.includes("opus-4-7")
|
|
1264
1268
|
|| modelId.includes("opus-4.7")
|
|
1265
1269
|
|| modelId.includes("opus-4-8")
|
|
1266
|
-
|| modelId.includes("opus-4.8")
|
|
1270
|
+
|| modelId.includes("opus-4.8")
|
|
1271
|
+
|| modelId.includes("fable-5")
|
|
1272
|
+
|| modelId.includes("fable.5"))
|
|
1267
1273
|
return "xhigh";
|
|
1268
1274
|
if (modelId.includes("opus-4-6") || modelId.includes("opus-4.6"))
|
|
1269
1275
|
return "max";
|
|
@@ -1285,7 +1291,7 @@ function browserMcpServerNameFromAllowedTools(allowedTools) {
|
|
|
1285
1291
|
const parsed = parseAllowedMcpToolName(toolName);
|
|
1286
1292
|
if (!parsed)
|
|
1287
1293
|
continue;
|
|
1288
|
-
if (parsed.server === "gsd-browser" || parsed.tool
|
|
1294
|
+
if (parsed.server === "gsd-browser" || hasBrowserContractPrefix(parsed.tool)) {
|
|
1289
1295
|
return parsed.server;
|
|
1290
1296
|
}
|
|
1291
1297
|
}
|
|
@@ -1299,7 +1305,7 @@ function workflowMcpServerNameFromAllowedTools(allowedTools) {
|
|
|
1299
1305
|
if (typeof toolName !== "string")
|
|
1300
1306
|
continue;
|
|
1301
1307
|
const parsed = parseAllowedMcpToolName(toolName);
|
|
1302
|
-
if (!parsed || parsed.server === browserServerName || parsed.tool
|
|
1308
|
+
if (!parsed || parsed.server === browserServerName || hasBrowserContractPrefix(parsed.tool))
|
|
1303
1309
|
continue;
|
|
1304
1310
|
return parsed.server;
|
|
1305
1311
|
}
|
|
@@ -1564,7 +1570,9 @@ export function buildSdkOptions(modelId, prompt, overrides, extraOptions = {}) {
|
|
|
1564
1570
|
|| modelId.includes("opus-4-7")
|
|
1565
1571
|
|| modelId.includes("opus-4.7")
|
|
1566
1572
|
|| modelId.includes("opus-4-8")
|
|
1567
|
-
|| modelId.includes("opus-4.8")
|
|
1573
|
+
|| modelId.includes("opus-4.8")
|
|
1574
|
+
|| modelId.includes("fable-5")
|
|
1575
|
+
|| modelId.includes("fable.5")) ? ["context-1m-2025-08-07"] : [],
|
|
1568
1576
|
...(thinkingConfig ?? {}),
|
|
1569
1577
|
...(effort ? { effort } : {}),
|
|
1570
1578
|
...sdkExtraOptions,
|
|
@@ -1629,8 +1637,9 @@ async function pumpSdkMessages(model, context, options, stream) {
|
|
|
1629
1637
|
}
|
|
1630
1638
|
: {}),
|
|
1631
1639
|
});
|
|
1640
|
+
const workflowMcpServerName = workflowMcpServerNameFromAllowedTools(sdkOpts.allowedTools);
|
|
1632
1641
|
const prompt = buildPromptFromContext(context, {
|
|
1633
|
-
workflowMcpServerName
|
|
1642
|
+
workflowMcpServerName,
|
|
1634
1643
|
browserMcpServerName: browserMcpServerNameFromAllowedTools(sdkOpts.allowedTools),
|
|
1635
1644
|
});
|
|
1636
1645
|
const queryPrompt = buildSdkQueryPrompt(context, prompt);
|
|
@@ -1668,7 +1677,30 @@ async function pumpSdkMessages(model, context, options, stream) {
|
|
|
1668
1677
|
switch (msg.type) {
|
|
1669
1678
|
// -- Init --
|
|
1670
1679
|
case "system": {
|
|
1671
|
-
//
|
|
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
|
+
}
|
|
1672
1704
|
break;
|
|
1673
1705
|
}
|
|
1674
1706
|
// -- Streaming partial messages --
|
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
// the real collaborators (state-reconciliation, doctor-proactive,
|
|
10
10
|
// auto-dispatch, recovery-classification, tool-contract, worktree-safety,
|
|
11
11
|
// uok/gate-runner, journal, session-lock, ctx.ui.notify) directly.
|
|
12
|
-
import { debugCount, debugTime } from "../debug-logger.js";
|
|
12
|
+
import { debugCount, debugLog, debugTime } from "../debug-logger.js";
|
|
13
13
|
import { reconcileBeforeDispatch } from "../state-reconciliation.js";
|
|
14
|
+
import { isLegalEdge, IllegalPhaseTransitionError } from "../state-transition-matrix.js";
|
|
14
15
|
import { resolveDispatch } from "../auto-dispatch.js";
|
|
15
16
|
import { classifyFailure } from "../recovery-classification.js";
|
|
16
17
|
import { verifyExpectedArtifact, refreshRecoveryDbForArtifact } from "../auto-recovery.js";
|
|
@@ -24,7 +25,7 @@ import { checkResourcesStale, autoWorktreeBranch, mergeMilestoneToMain } from ".
|
|
|
24
25
|
import { getSessionLockStatus } from "../session-lock.js";
|
|
25
26
|
import { resolveUokFlags } from "../uok/flags.js";
|
|
26
27
|
import { emitJournalEvent as _emitJournalEvent } from "../journal.js";
|
|
27
|
-
import { loadEffectiveGSDPreferences, getIsolationMode } from "../preferences.js";
|
|
28
|
+
import { loadEffectiveGSDPreferences, getIsolationMode, resolveEffectiveUnitIsolationMode } from "../preferences.js";
|
|
28
29
|
import { detectWorktreeName, getMainBranch, resolveProjectRoot, resolveWorktreeProjectRoot, } from "../worktree.js";
|
|
29
30
|
import { getPriorSliceCompletionBlocker } from "../dispatch-guard.js";
|
|
30
31
|
import { GitServiceImpl } from "../git-service.js";
|
|
@@ -244,6 +245,10 @@ export class AutoOrchestrator {
|
|
|
244
245
|
lastAdvanceKey = null;
|
|
245
246
|
lastFinalizedUnitKey = null;
|
|
246
247
|
dispatchKeyWindow = [];
|
|
248
|
+
// ADR-030 Phase Transition Invariant: the prior advance's reconciled Phase,
|
|
249
|
+
// the "from" endpoint of the edge check. In-memory; reset on start/resume/stop
|
|
250
|
+
// so the first advance of a session has no edge to assert.
|
|
251
|
+
lastDerivedPhase = null;
|
|
247
252
|
// #442: the unit key we last attempted graduated stuck-recovery for. Bounds
|
|
248
253
|
// recovery to one attempt per stuck episode per run (reset on start/resume/
|
|
249
254
|
// stop), mirroring the legacy Level-1-then-Level-2 escalation in phases.ts.
|
|
@@ -476,8 +481,7 @@ export class AutoOrchestrator {
|
|
|
476
481
|
}
|
|
477
482
|
// ── WorktreeAdapter (folded) ─────────────────────────────────────────────
|
|
478
483
|
getEffectiveUnitIsolationMode(basePath) {
|
|
479
|
-
|
|
480
|
-
return configuredMode === "worktree" && this.s.isolationDegraded ? "branch" : configuredMode;
|
|
484
|
+
return resolveEffectiveUnitIsolationMode(getIsolationMode(basePath), this.s.isolationDegraded, this.s.strandedRecoveryIsolationMode);
|
|
481
485
|
}
|
|
482
486
|
buildLifecycle() {
|
|
483
487
|
return new WorktreeLifecycle(this.s, {
|
|
@@ -576,6 +580,21 @@ export class AutoOrchestrator {
|
|
|
576
580
|
const recovery = classifyFailure(input);
|
|
577
581
|
return { action: recovery.action, reason: recovery.reason };
|
|
578
582
|
}
|
|
583
|
+
/**
|
|
584
|
+
* ADR-030 Phase Transition Invariant (advisory mode). The matrix is an
|
|
585
|
+
* assertion, not a decision-maker — deriveState already chose the phase; we
|
|
586
|
+
* only observe illegal *derived* edges that survived reconciliation. The
|
|
587
|
+
* matrix is still a sparse hardening spec, so this is telemetry-only (no
|
|
588
|
+
* block) until it is expanded into a validated legal-edge graph. To enforce:
|
|
589
|
+
* `throw violation;` instead of logging — recovery-classification maps
|
|
590
|
+
* IllegalPhaseTransitionError to kind "illegal-transition" (escalate).
|
|
591
|
+
*/
|
|
592
|
+
observePhaseTransition(from, to) {
|
|
593
|
+
if (isLegalEdge(from, to))
|
|
594
|
+
return;
|
|
595
|
+
const violation = new IllegalPhaseTransitionError(from, to);
|
|
596
|
+
debugLog("phase-transition-advisory", { from, to, message: violation.message });
|
|
597
|
+
}
|
|
579
598
|
// ── Lifecycle verbs ──────────────────────────────────────────────────────
|
|
580
599
|
/**
|
|
581
600
|
* #442: graduated stuck recovery, ported from the legacy
|
|
@@ -636,6 +655,7 @@ export class AutoOrchestrator {
|
|
|
636
655
|
this.lastFinalizedUnitKey = null;
|
|
637
656
|
this.dispatchKeyWindow = [];
|
|
638
657
|
this.lastStuckRecoveryKey = null;
|
|
658
|
+
this.lastDerivedPhase = null;
|
|
639
659
|
this.status.phase = "running";
|
|
640
660
|
this.bumpTransition();
|
|
641
661
|
this.journalTransition({ name: "start" });
|
|
@@ -721,6 +741,11 @@ export class AutoOrchestrator {
|
|
|
721
741
|
this.postAdvanceRecord(blocked);
|
|
722
742
|
return blocked;
|
|
723
743
|
}
|
|
744
|
+
const reconciledPhase = reconciliation.stateSnapshot.phase;
|
|
745
|
+
if (this.lastDerivedPhase !== null) {
|
|
746
|
+
this.observePhaseTransition(this.lastDerivedPhase, reconciledPhase);
|
|
747
|
+
}
|
|
748
|
+
this.lastDerivedPhase = reconciledPhase;
|
|
724
749
|
const decision = await this.decideNextUnit({ stateSnapshot: reconciliation.stateSnapshot });
|
|
725
750
|
if (!decision) {
|
|
726
751
|
const settlementBlock = this.evaluateNoRemainingUnitsSettlement(reconciliation.stateSnapshot);
|
|
@@ -833,16 +858,18 @@ export class AutoOrchestrator {
|
|
|
833
858
|
// checks coexist: idempotency for the common immediate-repeat case,
|
|
834
859
|
// stuck-loop for the saturated-window case.
|
|
835
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).
|
|
836
863
|
this.clearPendingDispatch();
|
|
837
|
-
const
|
|
864
|
+
const skipped = { kind: "skipped", reason: "idempotent advance: unit already active" };
|
|
838
865
|
this.journalTransition({
|
|
839
|
-
name: "advance-
|
|
840
|
-
reason:
|
|
866
|
+
name: "advance-skipped",
|
|
867
|
+
reason: skipped.reason,
|
|
841
868
|
unitType: decision.unitType,
|
|
842
869
|
unitId: decision.unitId,
|
|
843
870
|
});
|
|
844
|
-
this.postAdvanceRecord(
|
|
845
|
-
return
|
|
871
|
+
this.postAdvanceRecord(skipped);
|
|
872
|
+
return skipped;
|
|
846
873
|
}
|
|
847
874
|
// Stuck-loop detection: when the ring is saturated with copies of
|
|
848
875
|
// `nextKey` (count >= STUCK_WINDOW_SIZE), the orchestrator has been
|
|
@@ -981,6 +1008,9 @@ export class AutoOrchestrator {
|
|
|
981
1008
|
// Preserve dispatchKeyWindow across resume so stuck-loop detection
|
|
982
1009
|
// accumulates across pause/resume cycles rather than resetting each time.
|
|
983
1010
|
this.lastStuckRecoveryKey = null;
|
|
1011
|
+
// ADR-030: drop the prior "from" — the first advance after resume has no
|
|
1012
|
+
// edge to assert (avoids a false illegal-edge across the pause boundary).
|
|
1013
|
+
this.lastDerivedPhase = null;
|
|
984
1014
|
this.status.phase = "running";
|
|
985
1015
|
this.bumpTransition();
|
|
986
1016
|
this.journalTransition({ name: "resume" });
|
|
@@ -996,6 +1026,7 @@ export class AutoOrchestrator {
|
|
|
996
1026
|
this.status.activeUnit = undefined;
|
|
997
1027
|
this.lastAdvanceKey = null;
|
|
998
1028
|
this.lastFinalizedUnitKey = null;
|
|
1029
|
+
this.lastDerivedPhase = null;
|
|
999
1030
|
// Preserve dispatchKeyWindow on pause so stuck-loop detection accumulates
|
|
1000
1031
|
// across pause/resume cycles. Only clear on a hard stop.
|
|
1001
1032
|
if (reason !== "pause") {
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
import { importExtensionModule } from "@gsd/pi-coding-agent";
|
|
12
12
|
import { USER_DRIVEN_DEEP_UNITS, isAwaitingUserInput, } from "../auto-post-unit.js";
|
|
13
13
|
import { lastAssistantText } from "../user-input-boundary.js";
|
|
14
|
+
import { resolveEffectiveUnitIsolationMode } from "../preferences.js";
|
|
14
15
|
import { MAX_RECOVERY_CHARS, BUDGET_THRESHOLDS, MAX_FINALIZE_TIMEOUTS, } from "./types.js";
|
|
15
16
|
import { detectStuck } from "./detect-stuck.js";
|
|
16
17
|
import { runUnit } from "./run-unit.js";
|
|
@@ -265,7 +266,11 @@ async function validateSourceWriteWorktreeSafety(ic, unitType, unitId, milestone
|
|
|
265
266
|
if (!writesSource)
|
|
266
267
|
return null;
|
|
267
268
|
const projectRoot = s.canonicalProjectRoot ?? resolveWorktreeProjectRoot(s.basePath, s.originalBasePath);
|
|
268
|
-
|
|
269
|
+
// A degraded session already fell back to the milestone branch in the
|
|
270
|
+
// project root — validating against the canonical worktree root there
|
|
271
|
+
// would fail every dispatch with a false invalid-root. The same applies
|
|
272
|
+
// to a stranded-recovery session that adopted the milestone branch.
|
|
273
|
+
const isolationMode = resolveEffectiveUnitIsolationMode(deps.getIsolationMode(projectRoot), s.isolationDegraded, s.strandedRecoveryIsolationMode);
|
|
269
274
|
if (isolationMode !== "worktree")
|
|
270
275
|
return null;
|
|
271
276
|
const safety = createWorktreeSafetyModule();
|
|
@@ -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).
|
|
@@ -39,7 +39,7 @@ import { debugLog } from "./debug-logger.js";
|
|
|
39
39
|
import { runSafely } from "./auto-utils.js";
|
|
40
40
|
import { isMilestoneCloseoutSettled, runMilestoneCloseoutGitHub, } from "./milestone-closeout.js";
|
|
41
41
|
import { getEvidence, clearEvidenceFromDisk, isExecutionToolName } from "./safety/evidence-collector.js";
|
|
42
|
-
import { validateFileChanges } from "./safety/file-change-validator.js";
|
|
42
|
+
import { validateFileChanges, effectiveFileChangeAllowlist } from "./safety/file-change-validator.js";
|
|
43
43
|
import { crossReferenceEvidence } from "./safety/evidence-cross-ref.js";
|
|
44
44
|
import { validateContent } from "./safety/content-validator.js";
|
|
45
45
|
import { resolveSafetyHarnessConfig } from "./safety/safety-harness.js";
|
|
@@ -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";
|
|
@@ -507,9 +507,10 @@ export function _hasExecutionToolCallsInSessionForTest(entries) {
|
|
|
507
507
|
if (e?.type === "toolCall" && isExecutionToolName(e?.name ?? e?.toolName)) {
|
|
508
508
|
return true;
|
|
509
509
|
}
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
510
|
+
// Accept both session-manager entries ({type: "message", message}) and
|
|
511
|
+
// bare agent-end messages ({role, content}) — the auto loop passes the
|
|
512
|
+
// latter via opts.agentEndMessages.
|
|
513
|
+
const msg = e?.type === "message" ? e?.message : e;
|
|
513
514
|
if (!msg || msg.role !== "assistant" || !Array.isArray(msg.content))
|
|
514
515
|
continue;
|
|
515
516
|
for (const block of msg.content) {
|
|
@@ -1289,6 +1290,7 @@ export async function postUnitPreVerification(pctx, opts) {
|
|
|
1289
1290
|
const safetyConfig = resolveSafetyHarnessConfig(prefs?.safety_harness);
|
|
1290
1291
|
if (safetyConfig.enabled) {
|
|
1291
1292
|
const { milestone: sMid, slice: sSid, task: sTid } = parseUnitId(s.currentUnit.id);
|
|
1293
|
+
const fileChangeAllowlist = effectiveFileChangeAllowlist(safetyConfig.file_change_allowlist, prefs?.git?.manage_gitignore);
|
|
1292
1294
|
// File change validation (execute-task only, after unit execution)
|
|
1293
1295
|
if (safetyConfig.file_change_validation && s.currentUnit.type === "execute-task" && sMid && sSid && sTid) {
|
|
1294
1296
|
try {
|
|
@@ -1303,7 +1305,7 @@ export async function postUnitPreVerification(pctx, opts) {
|
|
|
1303
1305
|
const plannedFiles = getPlannedKeyFiles(sliceTaskRows.map((taskRow) => ({
|
|
1304
1306
|
files: taskRow.files,
|
|
1305
1307
|
})));
|
|
1306
|
-
const audit = validateFileChanges(s.basePath, expectedOutput, plannedFiles,
|
|
1308
|
+
const audit = validateFileChanges(s.basePath, expectedOutput, plannedFiles, fileChangeAllowlist);
|
|
1307
1309
|
if (audit && audit.violations.length > 0) {
|
|
1308
1310
|
const warnings = audit.violations.filter(v => v.severity === "warning");
|
|
1309
1311
|
for (const v of warnings) {
|
|
@@ -1319,7 +1321,7 @@ export async function postUnitPreVerification(pctx, opts) {
|
|
|
1319
1321
|
if (taskRow) {
|
|
1320
1322
|
const expectedOutput = taskRow.expected_output ?? [];
|
|
1321
1323
|
const plannedFiles = taskRow.files ?? [];
|
|
1322
|
-
const audit = validateFileChanges(s.basePath, expectedOutput, plannedFiles,
|
|
1324
|
+
const audit = validateFileChanges(s.basePath, expectedOutput, plannedFiles, fileChangeAllowlist);
|
|
1323
1325
|
if (audit && audit.violations.length > 0) {
|
|
1324
1326
|
const warnings = audit.violations.filter(v => v.severity === "warning");
|
|
1325
1327
|
for (const v of warnings) {
|
|
@@ -1699,7 +1701,16 @@ export async function postUnitPreVerification(pctx, opts) {
|
|
|
1699
1701
|
ctx.ui.notify(`Artifact missing for ${s.currentUnit.type} ${s.currentUnit.id} — DB unavailable, skipping retry.${dbSkipDiag ? ` Expected: ${dbSkipDiag}` : ""}`, "error");
|
|
1700
1702
|
}
|
|
1701
1703
|
else if (!triggerArtifactVerified) {
|
|
1702
|
-
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) {
|
|
1703
1714
|
const isUserSkip = /queued user message/i.test(s.lastToolInvocationError);
|
|
1704
1715
|
const errMsg = isUserSkip
|
|
1705
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;
|