@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
|
@@ -7,11 +7,11 @@ import { join } from "node:path";
|
|
|
7
7
|
import type { ExtensionAPI } from "@gsd/pi-coding-agent";
|
|
8
8
|
import { createBashTool, createEditTool, createReadTool, createWriteTool } from "@gsd/pi-coding-agent";
|
|
9
9
|
|
|
10
|
-
import { DEFAULT_BASH_TIMEOUT_SECS } from "../constants.js";
|
|
11
10
|
import { logWarning } from "../workflow-logger.js";
|
|
12
11
|
import { openWorkflowDatabase } from "../db-workspace.js";
|
|
13
12
|
import { getAutoWorktreePath } from "../auto-worktree.js";
|
|
14
13
|
import { resolveWorktreeProjectRoot } from "../worktree-root.js";
|
|
14
|
+
import { worktreesDirs } from "../worktree-placement.js";
|
|
15
15
|
|
|
16
16
|
export function safeWorkspaceCwd(): string {
|
|
17
17
|
try {
|
|
@@ -46,13 +46,15 @@ export function resolveWorkflowToolBasePath(
|
|
|
46
46
|
const worktree = getAutoWorktreePath(projectRoot, milestoneId);
|
|
47
47
|
if (worktree) return worktree;
|
|
48
48
|
} else {
|
|
49
|
-
const
|
|
50
|
-
|
|
49
|
+
const live: string[] = [];
|
|
50
|
+
for (const worktreesDir of worktreesDirs(projectRoot)) {
|
|
51
|
+
if (!existsSync(worktreesDir)) continue;
|
|
51
52
|
try {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
live.push(
|
|
54
|
+
...readdirSync(worktreesDir)
|
|
55
|
+
.map((name) => join(worktreesDir, name))
|
|
56
|
+
.filter((p) => existsSync(join(p, ".git"))),
|
|
57
|
+
);
|
|
56
58
|
} catch (err) {
|
|
57
59
|
logWarning(
|
|
58
60
|
"bootstrap",
|
|
@@ -60,6 +62,7 @@ export function resolveWorkflowToolBasePath(
|
|
|
60
62
|
);
|
|
61
63
|
}
|
|
62
64
|
}
|
|
65
|
+
if (live.length === 1) return live[0]!;
|
|
63
66
|
}
|
|
64
67
|
return cwd;
|
|
65
68
|
}
|
|
@@ -83,8 +86,30 @@ export function registerDynamicTools(pi: ExtensionAPI): void {
|
|
|
83
86
|
const baseBash = createBashTool(fallbackRoot, {
|
|
84
87
|
spawnHook: (ctx) => ctx,
|
|
85
88
|
});
|
|
89
|
+
// The auto-mode stalled-tool watchdog only exists in GSD/auto-mode, so the
|
|
90
|
+
// watchdog verbiage is injected here (the GSD-registered tool) rather than in
|
|
91
|
+
// core bash.ts, which is reused by non-GSD embeddings that have no watchdog.
|
|
92
|
+
const WATCHDOG_DETAIL =
|
|
93
|
+
"Genuine hangs are caught by the auto-mode stalled-tool watchdog (stalled: 5m / idle: 10m / soft: 20m / hard: 30m).";
|
|
94
|
+
const gsdBashDescription = `${(baseBash as any).description} ${WATCHDOG_DETAIL}`;
|
|
95
|
+
const gsdBashParameters = (() => {
|
|
96
|
+
const params: any = (baseBash as any).parameters;
|
|
97
|
+
if (!params?.properties?.timeout) return params;
|
|
98
|
+
return {
|
|
99
|
+
...params,
|
|
100
|
+
properties: {
|
|
101
|
+
...params.properties,
|
|
102
|
+
timeout: {
|
|
103
|
+
...params.properties.timeout,
|
|
104
|
+
description: `${params.properties.timeout.description} ${WATCHDOG_DETAIL}`,
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
})();
|
|
86
109
|
const dynamicBash = {
|
|
87
110
|
...baseBash,
|
|
111
|
+
description: gsdBashDescription,
|
|
112
|
+
parameters: gsdBashParameters,
|
|
88
113
|
execute: async (
|
|
89
114
|
toolCallId: string,
|
|
90
115
|
params: { command: string; timeout?: number },
|
|
@@ -96,11 +121,7 @@ export function registerDynamicTools(pi: ExtensionAPI): void {
|
|
|
96
121
|
const fresh = createBashTool(basePath, {
|
|
97
122
|
spawnHook: (spawnCtx) => ({ ...spawnCtx, cwd: basePath }),
|
|
98
123
|
});
|
|
99
|
-
|
|
100
|
-
...params,
|
|
101
|
-
timeout: params.timeout ?? DEFAULT_BASH_TIMEOUT_SECS,
|
|
102
|
-
};
|
|
103
|
-
return (fresh as any).execute(toolCallId, paramsWithTimeout, signal, onUpdate, ctx);
|
|
124
|
+
return (fresh as any).execute(toolCallId, params, signal, onUpdate, ctx);
|
|
104
125
|
},
|
|
105
126
|
};
|
|
106
127
|
pi.registerTool(dynamicBash as any);
|
|
@@ -17,6 +17,7 @@ import { registerHooks } from "./register-hooks.js";
|
|
|
17
17
|
import { registerShortcuts } from "./register-shortcuts.js";
|
|
18
18
|
import { writeCrashLog } from "./crash-log.js";
|
|
19
19
|
import { logWarning } from "../workflow-logger.js";
|
|
20
|
+
import { UNIT_TOOL_CONTRACTS } from "../unit-tool-contracts.js";
|
|
20
21
|
// Static import so cmux event listeners are registered synchronously during
|
|
21
22
|
// extension bootstrap. Prior implementation used `void import().then()` which
|
|
22
23
|
// queued listener registration as a microtask — any CMUX_CHANNELS emit fired
|
|
@@ -37,6 +38,12 @@ const EPIPE_STORM_WINDOW_MS = 10_000;
|
|
|
37
38
|
let epipeCount = 0;
|
|
38
39
|
let epipeWindowStart = 0;
|
|
39
40
|
|
|
41
|
+
export const CRITICAL_GSD_WORKFLOW_TOOL_NAMES = [...new Set(
|
|
42
|
+
Object.values(UNIT_TOOL_CONTRACTS)
|
|
43
|
+
.flatMap((contract) => contract.requiredWorkflowTools)
|
|
44
|
+
.filter((toolName) => toolName.startsWith("gsd_")),
|
|
45
|
+
)].sort();
|
|
46
|
+
|
|
40
47
|
/** Write to stderr without ever re-throwing — stderr can EPIPE too, which would
|
|
41
48
|
* re-enter this handler and re-loop. */
|
|
42
49
|
function safeStderr(msg: string): void {
|
|
@@ -133,6 +140,21 @@ export function installEpipeGuard(): void {
|
|
|
133
140
|
}
|
|
134
141
|
}
|
|
135
142
|
|
|
143
|
+
function assertCriticalGsdWorkflowToolsRegistered(pi: ExtensionAPI): void {
|
|
144
|
+
if (typeof pi.getAllTools !== "function") return;
|
|
145
|
+
|
|
146
|
+
const registered = new Set(pi.getAllTools().map((tool) => tool.name));
|
|
147
|
+
const missing = CRITICAL_GSD_WORKFLOW_TOOL_NAMES.filter((toolName) => !registered.has(toolName));
|
|
148
|
+
if (missing.length === 0) return;
|
|
149
|
+
|
|
150
|
+
const message = [
|
|
151
|
+
`Critical GSD workflow tool registration failed; missing required tool(s): ${missing.join(", ")}.`,
|
|
152
|
+
"Check earlier bootstrap warnings for the registration slot that failed.",
|
|
153
|
+
].join(" ");
|
|
154
|
+
logWarning("bootstrap", message);
|
|
155
|
+
throw new Error(message);
|
|
156
|
+
}
|
|
157
|
+
|
|
136
158
|
export function registerGsdExtension(pi: ExtensionAPI): void {
|
|
137
159
|
// Note: registerGSDCommand is called by index.ts before this function,
|
|
138
160
|
// so we intentionally skip it here to avoid double-registration.
|
|
@@ -214,4 +236,6 @@ export function registerGsdExtension(pi: ExtensionAPI): void {
|
|
|
214
236
|
);
|
|
215
237
|
}
|
|
216
238
|
}
|
|
239
|
+
|
|
240
|
+
assertCriticalGsdWorkflowToolsRegistered(pi);
|
|
217
241
|
}
|
|
@@ -13,7 +13,7 @@ import type { GSDEcosystemBeforeAgentStartHandler } from "../ecosystem/gsd-exten
|
|
|
13
13
|
import { updateSnapshot } from "../ecosystem/gsd-extension-api.js";
|
|
14
14
|
|
|
15
15
|
import { buildMilestoneFileName, clearPathCache, milestonesDir, resolveMilestonePath, resolveSliceFile, resolveSlicePath } from "../paths.js";
|
|
16
|
-
import { applyAskUserQuestionsGateResult, canonicalToolName, clearDiscussionFlowState, formatPendingAskUserQuestionsGateMessage, isMilestoneDepthVerified, isQueuePhaseActive, markApprovalGateVerified, markDepthVerified, resetWriteGateState, shouldBlockContextWrite, shouldBlockPlanningUnit, shouldBlockQueueExecution, shouldBlockWorktreeWrite, isGateQuestionId, setPendingGate, clearPendingGate, getPendingGate, shouldBlockPendingGate, shouldBlockPendingGateBash, extractDepthVerificationMilestoneId } from "./write-gate.js";
|
|
16
|
+
import { applyAskUserQuestionsGateResult, canonicalToolName, clearDiscussionFlowState, formatPendingAskUserQuestionsGateMessage, isApprovalGateVerifiedInSnapshot, isDepthConfirmationAnswer, isMilestoneDepthVerified, isMilestoneDepthVerifiedInSnapshot, isQueuePhaseActive, loadWriteGateSnapshot, markApprovalGateVerified, markDepthVerified, refreshWriteGateStateFromDisk, resetWriteGateState, shouldBlockContextWrite, shouldBlockPlanningUnit, shouldBlockQueueExecution, shouldBlockWorktreeWrite, isGateQuestionId, setPendingGate, clearPendingGate, getPendingGate, shouldBlockPendingGate, shouldBlockPendingGateBash, extractDepthVerificationMilestoneId } from "./write-gate.js";
|
|
17
17
|
import { resolveManifest } from "../unit-context-manifest.js";
|
|
18
18
|
import { isBlockedStateFile, isBashWriteToStateFile, BLOCKED_WRITE_ERROR } from "../write-intercept.js";
|
|
19
19
|
import { loadFile, saveFile, formatContinue } from "../files.js";
|
|
@@ -39,7 +39,14 @@ import { saveActivityLog } from "../activity-log.js";
|
|
|
39
39
|
import { recordToolCall as safetyRecordToolCall, recordToolResult as safetyRecordToolResult, saveEvidenceToDisk } from "../safety/evidence-collector.js";
|
|
40
40
|
import { parseUnitId } from "../unit-id.js";
|
|
41
41
|
import { classifyCommand } from "../safety/destructive-guard.js";
|
|
42
|
+
import {
|
|
43
|
+
confirmDestructiveCommand,
|
|
44
|
+
consumeDestructiveConfirmation,
|
|
45
|
+
isDestructiveConfirmGateId,
|
|
46
|
+
requestDestructiveConfirmation,
|
|
47
|
+
} from "../safety/destructive-confirmation.js";
|
|
42
48
|
import { logWarning as safetyLogWarning } from "../workflow-logger.js";
|
|
49
|
+
import { isUnitCloseoutTool, runInteractiveUnitCloseout } from "../unit-closeout.js";
|
|
43
50
|
import { installNotifyInterceptor } from "./notify-interceptor.js";
|
|
44
51
|
import { initNotificationStore } from "../notification-store.js";
|
|
45
52
|
import { initNotificationWidget } from "../notification-widget.js";
|
|
@@ -57,10 +64,14 @@ import { applyUnitSkillVisibility, unitHasSkillManifest } from "../skill-scope.j
|
|
|
57
64
|
import { getGuidedUnitContext } from "../guided-unit-context.js";
|
|
58
65
|
import { registerPlanMilestoneSchemaRecovery } from "./plan-milestone-schema-recovery.js";
|
|
59
66
|
import { AUTO_UNIT_SCOPED_TOOLS, RUN_UAT_BROWSER_TOOL_NAMES, canonicalWorkflowToolName, isWorkflowAliasTool } from "../auto-unit-tool-scope.js";
|
|
67
|
+
import { hasBrowserContractPrefix } from "../../shared/browser-contract.js";
|
|
60
68
|
import { filterToolsForProvider } from "../model-router.js";
|
|
61
69
|
import { mcpToolMatchesBaseName } from "../mcp-tool-name.js";
|
|
62
70
|
import { RUN_UAT_READ_ONLY_TOOL_NAMES, RUN_UAT_WORKFLOW_TOOL_NAMES } from "../tool-presentation-plan.js";
|
|
63
71
|
import { supportsSourceObservationsForUnit } from "../source-observations.js";
|
|
72
|
+
import { clearPendingAutoStart } from "../pending-auto-start.js";
|
|
73
|
+
import { resolveWorkflowToolBasePath } from "./dynamic-tools.js";
|
|
74
|
+
import { getRequiredWorkflowToolsForUnit } from "../unit-tool-contracts.js";
|
|
64
75
|
|
|
65
76
|
let approvalQuestionAbortInFlight = false;
|
|
66
77
|
|
|
@@ -177,7 +188,7 @@ function withPreservedShimTools(toolNames: readonly string[]): string[] {
|
|
|
177
188
|
|
|
178
189
|
/** True for the browser automation tools (browser_navigate, browser_click, ...). */
|
|
179
190
|
function isBrowserTool(toolName: string): boolean {
|
|
180
|
-
return canonicalToolName(toolName)
|
|
191
|
+
return hasBrowserContractPrefix(canonicalToolName(toolName));
|
|
181
192
|
}
|
|
182
193
|
|
|
183
194
|
/**
|
|
@@ -258,6 +269,7 @@ export function buildMinimalAutoGsdToolSet(
|
|
|
258
269
|
activeToolNames: readonly string[],
|
|
259
270
|
unitType: string | undefined,
|
|
260
271
|
registeredToolNames: readonly string[] = activeToolNames,
|
|
272
|
+
warnOnUnresolvedRequiredTools = registeredToolNames !== activeToolNames,
|
|
261
273
|
): string[] {
|
|
262
274
|
if (unitType === "run-uat") {
|
|
263
275
|
return buildRunUatGsdToolSet(activeToolNames, registeredToolNames);
|
|
@@ -273,7 +285,36 @@ export function buildMinimalAutoGsdToolSet(
|
|
|
273
285
|
[...activeToolNames, ...registeredToolNames],
|
|
274
286
|
[...MINIMAL_GSD_TOOL_NAMES, ...unitTools],
|
|
275
287
|
);
|
|
276
|
-
|
|
288
|
+
const result = withPreservedShimTools([...new Set([...preserved, ...scoped])]);
|
|
289
|
+
warnIfRequiredWorkflowToolsUnresolved(unitType, result, warnOnUnresolvedRequiredTools);
|
|
290
|
+
return result;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
function hasResolvedWorkflowTool(
|
|
294
|
+
resolvedToolNames: readonly string[],
|
|
295
|
+
requiredToolName: string,
|
|
296
|
+
): boolean {
|
|
297
|
+
return resolvedToolNames.some(
|
|
298
|
+
(name) => name === requiredToolName || mcpToolMatchesBaseName(name, requiredToolName),
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
function warnIfRequiredWorkflowToolsUnresolved(
|
|
303
|
+
unitType: string | undefined,
|
|
304
|
+
scopedToolNames: readonly string[],
|
|
305
|
+
shouldWarn: boolean,
|
|
306
|
+
): void {
|
|
307
|
+
if (!unitType || !shouldWarn) return;
|
|
308
|
+
|
|
309
|
+
const unresolved = getRequiredWorkflowToolsForUnit(unitType).filter(
|
|
310
|
+
(toolName) => !hasResolvedWorkflowTool(scopedToolNames, toolName),
|
|
311
|
+
);
|
|
312
|
+
if (unresolved.length === 0) return;
|
|
313
|
+
|
|
314
|
+
safetyLogWarning(
|
|
315
|
+
"bootstrap",
|
|
316
|
+
`buildMinimalAutoGsdToolSet(${unitType}): required workflow tool(s) not in active/registered surface after scoping: ${unresolved.join(", ")}. Tool registration may have partially failed, provider filtering may have removed a required tool, or workflow MCP may be disconnected.`,
|
|
317
|
+
);
|
|
277
318
|
}
|
|
278
319
|
|
|
279
320
|
export function buildRunUatGsdToolSet(
|
|
@@ -326,6 +367,7 @@ export function buildRequestScopedGsdToolSet(
|
|
|
326
367
|
requestCustomMessages: readonly { customType?: string }[] | undefined,
|
|
327
368
|
registeredToolNames: readonly string[] = activeToolNames,
|
|
328
369
|
guidedUnitType?: string,
|
|
370
|
+
warnOnUnresolvedRequiredTools = registeredToolNames !== activeToolNames,
|
|
329
371
|
): string[] | undefined {
|
|
330
372
|
for (let index = (requestCustomMessages?.length ?? 0) - 1; index >= 0; index--) {
|
|
331
373
|
const currentCustomType = requestCustomMessages?.[index]?.customType;
|
|
@@ -336,7 +378,12 @@ export function buildRequestScopedGsdToolSet(
|
|
|
336
378
|
currentCustomType === "gsd-triage"
|
|
337
379
|
) {
|
|
338
380
|
if (guidedUnitType) {
|
|
339
|
-
return buildMinimalAutoGsdToolSet(
|
|
381
|
+
return buildMinimalAutoGsdToolSet(
|
|
382
|
+
activeToolNames,
|
|
383
|
+
guidedUnitType,
|
|
384
|
+
registeredToolNames,
|
|
385
|
+
warnOnUnresolvedRequiredTools,
|
|
386
|
+
);
|
|
340
387
|
}
|
|
341
388
|
return buildMinimalGsdWorkflowToolSet(activeToolNames, registeredToolNames);
|
|
342
389
|
}
|
|
@@ -385,11 +432,13 @@ function applyMinimalGsdToolSurface(pi: ExtensionAPI): void {
|
|
|
385
432
|
const dash = getAutoRuntimeSnapshot();
|
|
386
433
|
if (dash.active && dash.currentUnit) {
|
|
387
434
|
const currentToolNames = pi.getActiveTools();
|
|
435
|
+
const hasRegisteredSurface = typeof pi.getAllTools === "function";
|
|
388
436
|
const registeredToolNames = resolveRegisteredToolNames(pi, currentToolNames);
|
|
389
437
|
const scopedToolNames = buildMinimalAutoGsdToolSet(
|
|
390
438
|
currentToolNames,
|
|
391
439
|
dash.currentUnit.type,
|
|
392
440
|
registeredToolNames,
|
|
441
|
+
hasRegisteredSurface,
|
|
393
442
|
);
|
|
394
443
|
recordAutoToolSurfaceSnapshot({
|
|
395
444
|
source: "runtime-scope",
|
|
@@ -411,9 +460,10 @@ export function scopeGsdWorkflowToolsForDispatch(
|
|
|
411
460
|
): ScopedGsdWorkflowState | null {
|
|
412
461
|
if (isFullGsdToolSurfaceRequested()) return null;
|
|
413
462
|
const current = pi.getActiveTools();
|
|
463
|
+
const hasRegisteredSurface = typeof pi.getAllTools === "function";
|
|
414
464
|
const registeredToolNames = resolveRegisteredToolNames(pi, current);
|
|
415
465
|
const scoped = unitType
|
|
416
|
-
? buildMinimalAutoGsdToolSet(current, unitType, registeredToolNames)
|
|
466
|
+
? buildMinimalAutoGsdToolSet(current, unitType, registeredToolNames, hasRegisteredSurface)
|
|
417
467
|
: buildMinimalGsdWorkflowToolSet(current, registeredToolNames);
|
|
418
468
|
recordAutoToolSurfaceSnapshot({
|
|
419
469
|
source: "dispatch-scope",
|
|
@@ -572,8 +622,13 @@ function isShellExecutionTool(canonicalName: string): boolean {
|
|
|
572
622
|
|
|
573
623
|
function activateDeferredApprovalGate(basePath: string): void {
|
|
574
624
|
if (deferredApprovalGate?.basePath !== basePath) return;
|
|
575
|
-
|
|
625
|
+
const gateId = deferredApprovalGate.gateId;
|
|
576
626
|
deferredApprovalGate = null;
|
|
627
|
+
const snapshot = refreshWriteGateStateFromDisk(basePath);
|
|
628
|
+
const milestoneId = extractDepthVerificationMilestoneId(gateId);
|
|
629
|
+
if (isApprovalGateVerifiedInSnapshot(snapshot, gateId)) return;
|
|
630
|
+
if (milestoneId && isMilestoneDepthVerifiedInSnapshot(snapshot, milestoneId)) return;
|
|
631
|
+
setPendingGate(gateId, basePath);
|
|
577
632
|
}
|
|
578
633
|
|
|
579
634
|
function extractGateQuestionId(input: unknown): string | undefined {
|
|
@@ -593,6 +648,26 @@ function isContextDraftSummarySave(toolName: string, input: unknown): boolean {
|
|
|
593
648
|
return (input as { artifact_type?: unknown }).artifact_type === "CONTEXT-DRAFT";
|
|
594
649
|
}
|
|
595
650
|
|
|
651
|
+
/**
|
|
652
|
+
* External engines (claude-code-cli) deliver ask_user_questions results as
|
|
653
|
+
* relayed MCP tool results: the structured round payload arrives in
|
|
654
|
+
* `result.structuredContent`, not in pi-native `event.details`. Without this
|
|
655
|
+
* fallback, applyAskUserQuestionsGateResult sees no response for an answered
|
|
656
|
+
* gate question and lands in the "waiting" branch — leaving a re-armed gate
|
|
657
|
+
* permanently pending and the discuss→auto handoff blocked.
|
|
658
|
+
*/
|
|
659
|
+
function resolveAskUserQuestionsGateDetails(event: { details?: unknown; result?: unknown }): any {
|
|
660
|
+
const hasRoundShape = (value: any): boolean =>
|
|
661
|
+
!!value && typeof value === "object" &&
|
|
662
|
+
(value.cancelled !== undefined || value.response !== undefined);
|
|
663
|
+
|
|
664
|
+
const details = event.details as any;
|
|
665
|
+
if (hasRoundShape(details)) return details;
|
|
666
|
+
const structured = (event.result as { structuredContent?: unknown } | undefined)?.structuredContent;
|
|
667
|
+
if (hasRoundShape(structured)) return structured;
|
|
668
|
+
return details ?? {};
|
|
669
|
+
}
|
|
670
|
+
|
|
596
671
|
type StructuredQuestion = {
|
|
597
672
|
id?: string;
|
|
598
673
|
header?: string;
|
|
@@ -802,7 +877,7 @@ export function registerHooks(
|
|
|
802
877
|
}
|
|
803
878
|
});
|
|
804
879
|
|
|
805
|
-
pi.on("session_switch", async (
|
|
880
|
+
pi.on("session_switch", async (event, ctx) => {
|
|
806
881
|
const basePath = contextBasePath(ctx);
|
|
807
882
|
const preserveCloseoutSurface = isAutoCompletionStopInProgress();
|
|
808
883
|
initSessionNotifications(ctx);
|
|
@@ -811,6 +886,13 @@ export function registerHooks(
|
|
|
811
886
|
clearDeferredApprovalGate();
|
|
812
887
|
await resetAskUserQuestionsTurnCache();
|
|
813
888
|
clearDiscussionFlowState(basePath);
|
|
889
|
+
// /clear or /new destroys the conversation holding a discuss interview, so
|
|
890
|
+
// its pending discuss→auto handoff can never be answered — clear it. Resume
|
|
891
|
+
// restores the interview transcript, so the entry survives. Auto-mode's own
|
|
892
|
+
// newSession() calls are safe: the handoff consumes the entry on agent_end.
|
|
893
|
+
if (event.reason === "new") {
|
|
894
|
+
clearPendingAutoStart(basePath);
|
|
895
|
+
}
|
|
814
896
|
await syncServiceTierStatus(ctx);
|
|
815
897
|
await applyDisabledModelProviderPolicy(ctx);
|
|
816
898
|
await applyCompactionThresholdOverride(ctx);
|
|
@@ -1314,23 +1396,39 @@ export function registerHooks(
|
|
|
1314
1396
|
|
|
1315
1397
|
// Destructive command classification + hard gate in all modes.
|
|
1316
1398
|
if (isToolCallEventType("bash", event)) {
|
|
1317
|
-
const
|
|
1399
|
+
const command = event.input.command;
|
|
1400
|
+
const classification = classifyCommand(command);
|
|
1318
1401
|
if (classification.destructive) {
|
|
1402
|
+
const guardBasePath = contextBasePath(ctx);
|
|
1403
|
+
// Escape hatch: if the user already confirmed this exact command via a
|
|
1404
|
+
// destructive_confirm gate, consume the one-shot token and let it run.
|
|
1405
|
+
// Without this, the block below loops forever — the model cannot satisfy
|
|
1406
|
+
// "confirm in the current turn" because nothing ever clears the gate.
|
|
1407
|
+
if (consumeDestructiveConfirmation(command, guardBasePath)) {
|
|
1408
|
+
safetyLogWarning("safety", `destructive command confirmed: ${classification.labels.join(", ")}`, {
|
|
1409
|
+
command: String(command).slice(0, 200),
|
|
1410
|
+
});
|
|
1411
|
+
return;
|
|
1412
|
+
}
|
|
1413
|
+
// Record the command as pending so an affirmative answer to a
|
|
1414
|
+
// destructive_confirm gate (handled in tool_result) can confirm it.
|
|
1415
|
+
requestDestructiveConfirmation(command, guardBasePath);
|
|
1319
1416
|
const reason = [
|
|
1320
1417
|
"HARD BLOCK: destructive Bash command requires explicit human confirmation.",
|
|
1321
1418
|
`Detected: ${classification.labels.join(", ")}`,
|
|
1322
|
-
"
|
|
1323
|
-
"
|
|
1419
|
+
"Call ask_user_questions with a question id containing \"destructive_confirm\"",
|
|
1420
|
+
"and a first option that affirms the action; wait for the user's response,",
|
|
1421
|
+
"then re-issue this exact command in the same turn to run it once.",
|
|
1324
1422
|
].join(" ");
|
|
1325
1423
|
safetyLogWarning("safety", `destructive command: ${classification.labels.join(", ")}`, {
|
|
1326
|
-
command: String(
|
|
1424
|
+
command: String(command).slice(0, 200),
|
|
1327
1425
|
});
|
|
1328
1426
|
if (ctx) {
|
|
1329
1427
|
await maybePauseAutoForApprovalGate(
|
|
1330
1428
|
ctx,
|
|
1331
1429
|
pi,
|
|
1332
1430
|
isAutoActive(),
|
|
1333
|
-
"
|
|
1431
|
+
"Destructive-command confirmation is waiting for your answer — pausing auto-mode.",
|
|
1334
1432
|
);
|
|
1335
1433
|
}
|
|
1336
1434
|
return { block: true, reason };
|
|
@@ -1368,13 +1466,27 @@ export function registerHooks(
|
|
|
1368
1466
|
} else if (isAutoActive()) {
|
|
1369
1467
|
clearToolInvocationError();
|
|
1370
1468
|
}
|
|
1469
|
+
// Interactive Closeout adapter (ADR-032): auto-mode owns closeout for its
|
|
1470
|
+
// own units; interactive completions get the durable git subset (commit +
|
|
1471
|
+
// Closeout Git Verdict) instead of silently bypassing git.isolation.
|
|
1472
|
+
if (!event.isError && !isAutoActive() && isUnitCloseoutTool(toolName)) {
|
|
1473
|
+
try {
|
|
1474
|
+
runInteractiveUnitCloseout({
|
|
1475
|
+
basePath: resolveWorkflowToolBasePath(ctx, event.input as { milestone_id?: string }),
|
|
1476
|
+
canonicalToolName: toolName,
|
|
1477
|
+
input: event.input,
|
|
1478
|
+
});
|
|
1479
|
+
} catch (err) {
|
|
1480
|
+
safetyLogWarning("engine", `interactive unit closeout failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1371
1483
|
if (toolName !== "ask_user_questions") return;
|
|
1372
1484
|
const basePath = contextBasePath(ctx);
|
|
1373
1485
|
const milestoneId = await getDiscussionMilestoneIdFor(basePath);
|
|
1374
1486
|
|
|
1375
|
-
const details = event
|
|
1487
|
+
const details = resolveAskUserQuestionsGateDetails(event);
|
|
1376
1488
|
|
|
1377
|
-
const questions: any[] = (event.input as any)?.questions ?? [];
|
|
1489
|
+
const questions: any[] = (event.input as any)?.questions ?? details?.questions ?? [];
|
|
1378
1490
|
const gateResult = applyAskUserQuestionsGateResult({
|
|
1379
1491
|
basePath,
|
|
1380
1492
|
questions,
|
|
@@ -1405,6 +1517,24 @@ export function registerHooks(
|
|
|
1405
1517
|
}
|
|
1406
1518
|
|
|
1407
1519
|
if (details?.cancelled || !details?.response) return;
|
|
1520
|
+
|
|
1521
|
+
// Destructive-command confirmation: an affirmative answer to a
|
|
1522
|
+
// destructive_confirm gate promotes the pending blocked command to a
|
|
1523
|
+
// one-shot confirmed token, which the bash tool_call guard consumes on the
|
|
1524
|
+
// next attempt. Rejecting/declining leaves the command blocked.
|
|
1525
|
+
// (Depth-verification gate handling now lives in
|
|
1526
|
+
// applyAskUserQuestionsGateResult above; only the destructive-confirm gate
|
|
1527
|
+
// is handled inline here.)
|
|
1528
|
+
for (const question of questions) {
|
|
1529
|
+
if (isDestructiveConfirmGateId(question?.id)) {
|
|
1530
|
+
const answer = details.response?.answers?.[question.id];
|
|
1531
|
+
if (isDepthConfirmationAnswer(answer?.selected, question.options)) {
|
|
1532
|
+
confirmDestructiveCommand(basePath);
|
|
1533
|
+
}
|
|
1534
|
+
break;
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1408
1538
|
if (!milestoneId) return;
|
|
1409
1539
|
await saveDiscussionQuestionRound(basePath, milestoneId, questions, details);
|
|
1410
1540
|
});
|
|
@@ -1415,10 +1545,42 @@ export function registerHooks(
|
|
|
1415
1545
|
if (toolName === "ask_user_questions") {
|
|
1416
1546
|
const questionId = extractGateQuestionId(event.args);
|
|
1417
1547
|
if (typeof questionId === "string") {
|
|
1418
|
-
|
|
1548
|
+
// External engines (claude-code-cli) ingest the SDK turn's tool blocks
|
|
1549
|
+
// post-hoc, so this event can fire AFTER the workflow MCP child already
|
|
1550
|
+
// verified this gate and allowed the CONTEXT save. setPendingGate also
|
|
1551
|
+
// revokes verifiedDepthMilestones/verifiedApprovalGates, so an
|
|
1552
|
+
// unconditional re-arm here wipes the child's verification and leaves
|
|
1553
|
+
// the discuss→auto handoff permanently blocked. Skip the re-arm when
|
|
1554
|
+
// the snapshot already records this exact gate as verified — mirrors
|
|
1555
|
+
// activateDeferredApprovalGate's guard. Stale verified state cannot
|
|
1556
|
+
// leak into a later re-discussion: a successful handoff deletes the
|
|
1557
|
+
// snapshot via clearDiscussionFlowState.
|
|
1558
|
+
const snapshot = refreshWriteGateStateFromDisk(basePath);
|
|
1559
|
+
const gateMilestoneId = extractDepthVerificationMilestoneId(questionId);
|
|
1560
|
+
const alreadyVerified =
|
|
1561
|
+
isApprovalGateVerifiedInSnapshot(snapshot, questionId) ||
|
|
1562
|
+
isMilestoneDepthVerifiedInSnapshot(snapshot, gateMilestoneId);
|
|
1563
|
+
if (!alreadyVerified) {
|
|
1564
|
+
setPendingGate(questionId, basePath);
|
|
1565
|
+
}
|
|
1419
1566
|
clearDeferredApprovalGate(basePath);
|
|
1420
1567
|
}
|
|
1421
1568
|
}
|
|
1569
|
+
|
|
1570
|
+
// Safety harness: record evidence here, not only in tool_call. External
|
|
1571
|
+
// engines (claude-code-cli) pre-execute tools, so the agent loop skips
|
|
1572
|
+
// beforeToolCall/tool_call for them — tool_execution_start is the only
|
|
1573
|
+
// event that fires for every tool call. recordToolCall dedupes by
|
|
1574
|
+
// toolCallId, so native tools (which hit both events) record once.
|
|
1575
|
+
safetyRecordToolCall(event.toolCallId, event.toolName, (event.args ?? {}) as Record<string, unknown>);
|
|
1576
|
+
const execDash = getAutoRuntimeSnapshot();
|
|
1577
|
+
if (execDash.basePath && execDash.currentUnit?.type === "execute-task") {
|
|
1578
|
+
const { milestone: xMid, slice: xSid, task: xTid } = parseUnitId(execDash.currentUnit.id);
|
|
1579
|
+
if (xMid && xSid && xTid) {
|
|
1580
|
+
saveEvidenceToDisk(execDash.basePath, xMid, xSid, xTid);
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1422
1584
|
if (!isAutoActive()) return;
|
|
1423
1585
|
markToolStart(event.toolCallId, event.toolName);
|
|
1424
1586
|
});
|
|
@@ -1499,6 +1661,7 @@ export function registerHooks(
|
|
|
1499
1661
|
return surfaceReduced ? { toolNames: providerCompatible } : undefined;
|
|
1500
1662
|
}
|
|
1501
1663
|
const registeredToolNames = resolveRegisteredToolNames(pi, event.activeToolNames);
|
|
1664
|
+
const hasRegisteredSurface = typeof pi.getAllTools === "function";
|
|
1502
1665
|
const compatibleRegisteredToolNames = filterToolsForProvider(
|
|
1503
1666
|
registeredToolNames,
|
|
1504
1667
|
event.selectedModelApi,
|
|
@@ -1513,6 +1676,7 @@ export function registerHooks(
|
|
|
1513
1676
|
event.requestCustomMessages,
|
|
1514
1677
|
requestRegisteredToolNames,
|
|
1515
1678
|
guidedUnit?.unitType,
|
|
1679
|
+
hasRegisteredSurface,
|
|
1516
1680
|
);
|
|
1517
1681
|
if (requestScoped) {
|
|
1518
1682
|
recordAutoToolSurfaceSnapshot({
|
|
@@ -1533,6 +1697,7 @@ export function registerHooks(
|
|
|
1533
1697
|
dash.currentUnit.type === "run-uat" ? aliasFilteredCompatible : providerCompatible,
|
|
1534
1698
|
dash.currentUnit.type,
|
|
1535
1699
|
registeredForUnit,
|
|
1700
|
+
hasRegisteredSurface,
|
|
1536
1701
|
);
|
|
1537
1702
|
recordAutoToolSurfaceSnapshot({
|
|
1538
1703
|
source: "provider-adjustment",
|
|
@@ -10,6 +10,7 @@ import { getIsolationMode } from "../preferences.js";
|
|
|
10
10
|
import { compileSubagentPermissionContract, type ToolsPolicy } from "../unit-context-manifest.js";
|
|
11
11
|
import { logWarning } from "../workflow-logger.js";
|
|
12
12
|
import { isGsdWorktreePath, resolveWorktreeProjectRoot } from "../worktree-root.js";
|
|
13
|
+
import { worktreesDirs } from "../worktree-placement.js";
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Regex matching milestone CONTEXT.md file names in both legacy M001
|
|
@@ -244,6 +245,27 @@ export function loadWriteGateSnapshot(basePath: string): WriteGateSnapshot {
|
|
|
244
245
|
}
|
|
245
246
|
}
|
|
246
247
|
|
|
248
|
+
/**
|
|
249
|
+
* Merge the persisted write-gate snapshot into the in-process Map entry.
|
|
250
|
+
* The workflow MCP server runs in a child process and records depth
|
|
251
|
+
* verification there; without this refresh the extension host keeps stale
|
|
252
|
+
* pending-gate memory and `activateDeferredApprovalGate` can re-arm a gate
|
|
253
|
+
* that the subprocess already cleared on disk.
|
|
254
|
+
*
|
|
255
|
+
* Returns the snapshot used for the refresh so callers that need to inspect
|
|
256
|
+
* it (e.g. re-arm guards) avoid a second disk read.
|
|
257
|
+
*/
|
|
258
|
+
export function refreshWriteGateStateFromDisk(basePath: string): WriteGateSnapshot {
|
|
259
|
+
const snapshot = loadWriteGateSnapshot(basePath);
|
|
260
|
+
if (!shouldPersistWriteGateSnapshot()) return snapshot;
|
|
261
|
+
const state = getWriteGateState(basePath);
|
|
262
|
+
state.pendingGateId = snapshot.pendingGateId;
|
|
263
|
+
state.activeQueuePhase = snapshot.activeQueuePhase;
|
|
264
|
+
state.verifiedDepthMilestones = new Set(snapshot.verifiedDepthMilestones);
|
|
265
|
+
state.verifiedApprovalGates = new Set(snapshot.verifiedApprovalGates ?? []);
|
|
266
|
+
return snapshot;
|
|
267
|
+
}
|
|
268
|
+
|
|
247
269
|
export function isDepthVerified(basePath: string = process.cwd()): boolean {
|
|
248
270
|
return getWriteGateState(basePath).verifiedDepthMilestones.size > 0;
|
|
249
271
|
}
|
|
@@ -256,6 +278,7 @@ export function isMilestoneDepthVerified(
|
|
|
256
278
|
basePath: string = process.cwd(),
|
|
257
279
|
): boolean {
|
|
258
280
|
if (!milestoneId) return false;
|
|
281
|
+
refreshWriteGateStateFromDisk(basePath);
|
|
259
282
|
return getWriteGateState(basePath).verifiedDepthMilestones.has(milestoneId);
|
|
260
283
|
}
|
|
261
284
|
|
|
@@ -357,6 +380,7 @@ export function clearPendingGate(basePath: string): void {
|
|
|
357
380
|
* Get the currently pending gate, if any.
|
|
358
381
|
*/
|
|
359
382
|
export function getPendingGate(basePath: string = process.cwd()): string | null {
|
|
383
|
+
refreshWriteGateStateFromDisk(basePath);
|
|
360
384
|
return getWriteGateState(basePath).pendingGateId;
|
|
361
385
|
}
|
|
362
386
|
|
|
@@ -1138,10 +1162,12 @@ export function shouldBlockWorktreeWrite(
|
|
|
1138
1162
|
const realTarget = realpathOrResolve(absTarget);
|
|
1139
1163
|
const realRoot = realpathOrResolve(projectRoot);
|
|
1140
1164
|
const realGsd = realpathOrResolve(join(projectRoot, ".gsd"));
|
|
1141
|
-
const realWorktreesDir = realpathOrResolve(join(projectRoot, ".gsd", "worktrees"));
|
|
1142
1165
|
|
|
1143
|
-
// Allow writes inside
|
|
1144
|
-
|
|
1166
|
+
// Allow writes inside a legitimate worktrees subtree (canonical
|
|
1167
|
+
// .gsd-worktrees/ or legacy .gsd/worktrees/).
|
|
1168
|
+
for (const container of worktreesDirs(projectRoot)) {
|
|
1169
|
+
if (isPathContained(realTarget, realpathOrResolve(container))) return { block: false };
|
|
1170
|
+
}
|
|
1145
1171
|
|
|
1146
1172
|
// Allow writes to .gsd/ planning artifacts, but reject siblings whose name
|
|
1147
1173
|
// starts with "worktrees" (the worktrees-extra prefix trick — case 4).
|
|
@@ -14,3 +14,6 @@ export const QUICK_BRANCH_RE = /^gsd\/quick\//;
|
|
|
14
14
|
|
|
15
15
|
/** Matches GSD-generated workflow template branches, not arbitrary user gsd/* branches. */
|
|
16
16
|
export const WORKFLOW_BRANCH_RE = /^gsd\/(?:hotfix|bugfix|small-feature|refactor|spike|security-audit|dep-upgrade|full-project)\//;
|
|
17
|
+
|
|
18
|
+
/** Auto-mode milestone branch prefix: milestone/<MID>. */
|
|
19
|
+
export const MILESTONE_BRANCH_PREFIX = "milestone/";
|