@opengsd/gsd-pi 1.2.0-dev.955e4da0 → 1.2.0-dev.d6c5343c
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-style.d.ts +17 -0
- package/dist/cli-style.js +28 -0
- package/dist/cli.js +1 -1
- package/dist/headless-events.d.ts +4 -2
- package/dist/headless-events.js +14 -34
- package/dist/models-resolver.d.ts +3 -13
- package/dist/models-resolver.js +3 -22
- package/dist/resource-loader.js +2 -14
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +5 -4
- package/dist/resources/extensions/async-jobs/async-bash-tool.js +30 -64
- package/dist/resources/extensions/async-jobs/await-tool.js +80 -12
- package/dist/resources/extensions/async-jobs/index.js +65 -0
- package/dist/resources/extensions/async-jobs/job-manager.js +12 -1
- package/dist/resources/extensions/bg-shell/bg-shell-command.js +6 -6
- package/dist/resources/extensions/bg-shell/bg-shell-tool.js +10 -7
- package/dist/resources/extensions/bg-shell/overlay.js +9 -6
- package/dist/resources/extensions/bg-shell/process-manager.js +54 -25
- package/dist/resources/extensions/bg-shell/readiness-detector.js +11 -0
- package/dist/resources/extensions/bg-shell/utilities.js +3 -0
- package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +209 -88
- package/dist/resources/extensions/browser-tools/engine/selection.js +73 -5
- package/dist/resources/extensions/browser-tools/index.js +69 -12
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +30 -4
- package/dist/resources/extensions/gsd/auto/custom-verify-retry-store.js +17 -2
- package/dist/resources/extensions/gsd/auto/detect-stuck.js +33 -13
- package/dist/resources/extensions/gsd/auto/dispatch-history.js +105 -0
- package/dist/resources/extensions/gsd/auto/dispatch-key.js +37 -0
- package/dist/resources/extensions/gsd/auto/loop.js +4 -1
- package/dist/resources/extensions/gsd/auto/orchestrator.js +61 -44
- package/dist/resources/extensions/gsd/auto/phases.js +2 -2
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +8 -32
- package/dist/resources/extensions/gsd/auto-dispatch.js +40 -57
- package/dist/resources/extensions/gsd/auto-model-selection.js +25 -6
- package/dist/resources/extensions/gsd/auto-post-unit.js +23 -8
- package/dist/resources/extensions/gsd/auto-prompts.js +81 -19
- package/dist/resources/extensions/gsd/auto-start.js +18 -15
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +18 -0
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +12 -20
- package/dist/resources/extensions/gsd/auto-verification.js +9 -28
- package/dist/resources/extensions/gsd/auto-worktree.js +30 -90
- package/dist/resources/extensions/gsd/auto.js +4 -13
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +3 -2
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +23 -6
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +19 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +212 -48
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +303 -77
- package/dist/resources/extensions/gsd/branch-patterns.js +2 -0
- package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +83 -0
- package/dist/resources/extensions/gsd/browser-evidence.js +8 -2
- package/dist/resources/extensions/gsd/captures.js +4 -6
- package/dist/resources/extensions/gsd/consent-question.js +337 -0
- package/dist/resources/extensions/gsd/consent-verdict.js +63 -0
- package/dist/resources/extensions/gsd/constants.js +0 -2
- package/dist/resources/extensions/gsd/crash-recovery.js +4 -12
- package/dist/resources/extensions/gsd/db/queries.js +26 -0
- package/dist/resources/extensions/gsd/dispatch-guard.js +10 -35
- package/dist/resources/extensions/gsd/doctor-environment.js +2 -6
- package/dist/resources/extensions/gsd/doctor-format.js +9 -6
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +13 -15
- package/dist/resources/extensions/gsd/engine-hook-contract.js +70 -0
- package/dist/resources/extensions/gsd/error-classifier.js +9 -0
- package/dist/resources/extensions/gsd/exec-sandbox.js +30 -10
- package/dist/resources/extensions/gsd/files.js +33 -19
- package/dist/resources/extensions/gsd/guidance.js +158 -0
- package/dist/resources/extensions/gsd/guided-flow.js +17 -2
- package/dist/resources/extensions/gsd/markdown-renderer.js +10 -0
- package/dist/resources/extensions/gsd/mcp-filter.js +2 -19
- package/dist/resources/extensions/gsd/mcp-tool-name.js +5 -13
- package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +1 -1
- package/dist/resources/extensions/gsd/migrate/safety.js +4 -1
- package/dist/resources/extensions/gsd/milestone-closeout.js +13 -23
- package/dist/resources/extensions/gsd/notification-store.js +11 -4
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +6 -4
- package/dist/resources/extensions/gsd/parsers-legacy.js +16 -4
- package/dist/resources/extensions/gsd/paths.js +27 -0
- package/dist/resources/extensions/gsd/pre-execution-checks.js +91 -3
- package/dist/resources/extensions/gsd/preferences-models.js +14 -48
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/run-uat.md +6 -4
- package/dist/resources/extensions/gsd/prompts/system.md +5 -2
- package/dist/resources/extensions/gsd/provider-error-guidance.js +1 -5
- package/dist/resources/extensions/gsd/provider-switch-observer.js +1 -1
- package/dist/resources/extensions/gsd/publication.js +87 -0
- package/dist/resources/extensions/gsd/reactive-graph.js +8 -1
- package/dist/resources/extensions/gsd/recovery-classification.js +37 -94
- package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
- package/dist/resources/extensions/gsd/state.js +6 -20
- package/dist/resources/extensions/gsd/stop-notice.js +57 -0
- package/dist/resources/extensions/gsd/tool-presentation-plan.js +4 -4
- package/dist/resources/extensions/gsd/tool-surface-readiness.js +56 -0
- package/dist/resources/extensions/gsd/tools/complete-slice.js +20 -10
- package/dist/resources/extensions/gsd/tools/exec-tool.js +9 -7
- package/dist/resources/extensions/gsd/tools/plan-slice.js +12 -6
- package/dist/resources/extensions/gsd/uat-policy.js +42 -16
- package/dist/resources/extensions/gsd/unit-closeout.js +138 -0
- package/dist/resources/extensions/gsd/unit-context-composer.js +74 -1
- package/dist/resources/extensions/gsd/unit-context-manifest.js +4 -27
- package/dist/resources/extensions/gsd/unit-registry.js +337 -0
- package/dist/resources/extensions/gsd/unit-tool-contracts.js +9 -182
- package/dist/resources/extensions/gsd/verdict-parser.js +1 -1
- package/dist/resources/extensions/gsd/web-app-uat.js +45 -8
- package/dist/resources/extensions/gsd/workflow-tool-surface.js +1 -1
- package/dist/resources/extensions/gsd/worktree-git-recovery.js +15 -9
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +3 -2
- package/dist/resources/extensions/gsd/worktree-root.js +11 -0
- package/dist/resources/extensions/gsd/worktree-session-state.js +4 -5
- package/dist/resources/extensions/search-the-web/native-search.js +5 -3
- package/dist/resources/extensions/shared/browser-contract.js +59 -0
- package/dist/resources/extensions/shared/gsd-browser-cli.js +96 -5
- package/dist/resources/shared/package.json +3 -0
- package/dist/resources/skills/create-skill/references/executable-code.md +1 -1
- package/dist/resources/skills/create-skill/workflows/add-reference.md +8 -3
- package/dist/resources/skills/create-skill/workflows/add-script.md +4 -2
- package/dist/resources/skills/create-skill/workflows/add-template.md +3 -1
- package/dist/resources/skills/create-skill/workflows/add-workflow.md +8 -3
- package/dist/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
- package/dist/resources/skills/create-skill/workflows/verify-skill.md +9 -4
- package/dist/resources/skills/spike-wrap-up/SKILL.md +9 -9
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
- package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
- package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/{796.cf859a427a2cb2ac.js → 796.e0bdc932325d7e03.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{webpack-fbea77b5f9953368.js → webpack-f0285ce91d4ec9ef.js} +1 -1
- package/dist/web/standalone/package.json +1 -1
- package/dist/worktree-cli.js +3 -6
- package/dist/worktree-status-banner.js +7 -15
- package/package.json +1 -1
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/dist/rpc.d.ts +1 -0
- package/packages/contracts/dist/rpc.d.ts.map +1 -1
- package/packages/contracts/dist/rpc.js.map +1 -1
- package/packages/contracts/dist/workflow.d.ts +4 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +5 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +5 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +7 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +8 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +11 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +4 -4
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +3 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/cli.js +6 -3
- package/packages/mcp-server/dist/cli.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +8 -0
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +17 -1
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +3 -3
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts +1 -0
- package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/harness/env/nodejs.js +34 -3
- package/packages/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
- package/packages/pi-agent-core/dist/index.d.ts +1 -0
- package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/index.js +3 -0
- package/packages/pi-agent-core/dist/index.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/README.md +1 -0
- package/packages/pi-ai/dist/image-models.generated.d.ts +2 -2
- package/packages/pi-ai/dist/image-models.generated.js +6 -6
- package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +35 -125
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +46 -120
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/package.json +3 -2
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +2 -2
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +19 -13
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/provider-readiness.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/provider-readiness.js +13 -6
- package/packages/pi-coding-agent/dist/core/provider-readiness.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +11 -0
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.js +53 -11
- package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/utils/shell.d.ts +28 -2
- package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/utils/shell.js +56 -10
- package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +9 -0
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/package.json +2 -2
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/src/resources/GSD-WORKFLOW.md +5 -4
- package/src/resources/extensions/async-jobs/async-bash-cancel.test.ts +360 -0
- package/src/resources/extensions/async-jobs/async-bash-tool.ts +33 -56
- package/src/resources/extensions/async-jobs/await-tool.test.ts +139 -0
- package/src/resources/extensions/async-jobs/await-tool.ts +82 -12
- package/src/resources/extensions/async-jobs/index.ts +79 -0
- package/src/resources/extensions/async-jobs/job-manager.ts +21 -1
- package/src/resources/extensions/bg-shell/bg-shell-command.ts +6 -6
- package/src/resources/extensions/bg-shell/bg-shell-tool.ts +10 -6
- package/src/resources/extensions/bg-shell/overlay.ts +9 -5
- package/src/resources/extensions/bg-shell/process-manager.ts +50 -25
- package/src/resources/extensions/bg-shell/readiness-detector.ts +12 -0
- package/src/resources/extensions/bg-shell/tests/lifecycle-and-utilities.test.ts +48 -1
- package/src/resources/extensions/bg-shell/utilities.ts +3 -0
- package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +265 -98
- package/src/resources/extensions/browser-tools/engine/selection.ts +90 -4
- package/src/resources/extensions/browser-tools/index.ts +71 -13
- package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +83 -13
- package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +29 -1
- package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +136 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +34 -4
- package/src/resources/extensions/gsd/auto/custom-verify-retry-store.ts +21 -3
- package/src/resources/extensions/gsd/auto/detect-stuck.ts +32 -9
- package/src/resources/extensions/gsd/auto/dispatch-history.ts +152 -0
- package/src/resources/extensions/gsd/auto/dispatch-key.ts +39 -0
- package/src/resources/extensions/gsd/auto/loop.ts +4 -1
- package/src/resources/extensions/gsd/auto/orchestrator.ts +70 -46
- package/src/resources/extensions/gsd/auto/phases.ts +2 -2
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +8 -32
- package/src/resources/extensions/gsd/auto-dispatch.ts +38 -52
- package/src/resources/extensions/gsd/auto-model-selection.ts +25 -5
- package/src/resources/extensions/gsd/auto-post-unit.ts +25 -8
- package/src/resources/extensions/gsd/auto-prompts.ts +118 -35
- package/src/resources/extensions/gsd/auto-start.ts +18 -17
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +19 -0
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +14 -21
- package/src/resources/extensions/gsd/auto-verification.ts +8 -26
- package/src/resources/extensions/gsd/auto-worktree.ts +30 -93
- package/src/resources/extensions/gsd/auto.ts +8 -15
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +3 -5
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +23 -6
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +24 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +251 -47
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +352 -84
- package/src/resources/extensions/gsd/branch-patterns.ts +3 -0
- package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +108 -0
- package/src/resources/extensions/gsd/browser-evidence.ts +18 -2
- package/src/resources/extensions/gsd/captures.ts +4 -6
- package/src/resources/extensions/gsd/consent-question.ts +416 -0
- package/src/resources/extensions/gsd/consent-verdict.ts +86 -0
- package/src/resources/extensions/gsd/constants.ts +0 -3
- package/src/resources/extensions/gsd/crash-recovery.ts +3 -9
- package/src/resources/extensions/gsd/db/queries.ts +37 -0
- package/src/resources/extensions/gsd/dispatch-guard.ts +8 -31
- package/src/resources/extensions/gsd/doctor-environment.ts +2 -7
- package/src/resources/extensions/gsd/doctor-format.ts +12 -7
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +13 -15
- package/src/resources/extensions/gsd/engine-hook-contract.ts +79 -0
- package/src/resources/extensions/gsd/error-classifier.ts +11 -0
- package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
- package/src/resources/extensions/gsd/files.ts +33 -12
- package/src/resources/extensions/gsd/guidance.ts +217 -0
- package/src/resources/extensions/gsd/guided-flow.ts +16 -2
- package/src/resources/extensions/gsd/markdown-renderer.ts +11 -0
- package/src/resources/extensions/gsd/mcp-filter.ts +2 -23
- package/src/resources/extensions/gsd/mcp-tool-name.ts +6 -11
- package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +1 -1
- package/src/resources/extensions/gsd/migrate/safety.ts +4 -1
- package/src/resources/extensions/gsd/milestone-closeout.ts +13 -23
- package/src/resources/extensions/gsd/notification-store.ts +26 -3
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +6 -4
- package/src/resources/extensions/gsd/parsers-legacy.ts +16 -4
- package/src/resources/extensions/gsd/paths.ts +33 -0
- package/src/resources/extensions/gsd/pre-execution-checks.ts +109 -3
- package/src/resources/extensions/gsd/preferences-models.ts +12 -47
- package/src/resources/extensions/gsd/prompts/complete-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/replan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/run-uat.md +6 -4
- package/src/resources/extensions/gsd/prompts/system.md +5 -2
- package/src/resources/extensions/gsd/provider-error-guidance.ts +4 -9
- package/src/resources/extensions/gsd/provider-switch-observer.ts +1 -1
- package/src/resources/extensions/gsd/publication.ts +122 -0
- package/src/resources/extensions/gsd/reactive-graph.ts +11 -1
- package/src/resources/extensions/gsd/recovery-classification.ts +42 -96
- package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
- package/src/resources/extensions/gsd/state.ts +9 -21
- package/src/resources/extensions/gsd/stop-notice.ts +75 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +101 -26
- package/src/resources/extensions/gsd/tests/browser-automation-contract-fixture.ts +39 -0
- package/src/resources/extensions/gsd/tests/browser-contract.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +144 -0
- package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +66 -1
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +8 -7
- package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/consent-question.test.ts +336 -0
- package/src/resources/extensions/gsd/tests/custom-verify-retry-store.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +10 -10
- package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +303 -0
- package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +273 -0
- package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/dynamic-bash-no-cap.test.ts +132 -0
- package/src/resources/extensions/gsd/tests/engine-hook-contract.test.ts +148 -0
- package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +193 -0
- package/src/resources/extensions/gsd/tests/exec-tool.test.ts +29 -1
- package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +35 -1
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/guidance.test.ts +148 -0
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +53 -11
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +73 -58
- package/src/resources/extensions/gsd/tests/integration/gsd-integration-fixture.ts +80 -0
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +199 -0
- package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +32 -1
- package/src/resources/extensions/gsd/tests/notification-store.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +167 -0
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +139 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +193 -1
- package/src/resources/extensions/gsd/tests/prompt-db.test.ts +124 -6
- package/src/resources/extensions/gsd/tests/provider-error-guidance.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/publication.test.ts +120 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/stop-notice.test.ts +70 -0
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +76 -0
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +155 -0
- package/src/resources/extensions/gsd/tests/uat-policy.test.ts +112 -29
- package/src/resources/extensions/gsd/tests/unit-closeout.test.ts +209 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +67 -2
- package/src/resources/extensions/gsd/tests/unit-registry.test.ts +163 -0
- package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +44 -1
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +358 -0
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +67 -1
- package/src/resources/extensions/gsd/tool-presentation-plan.ts +4 -4
- package/src/resources/extensions/gsd/tool-surface-readiness.ts +76 -0
- package/src/resources/extensions/gsd/tools/complete-slice.ts +20 -10
- package/src/resources/extensions/gsd/tools/exec-tool.ts +8 -7
- package/src/resources/extensions/gsd/tools/plan-slice.ts +12 -6
- package/src/resources/extensions/gsd/uat-policy.ts +62 -16
- package/src/resources/extensions/gsd/unit-closeout.ts +201 -0
- package/src/resources/extensions/gsd/unit-context-composer.ts +111 -1
- package/src/resources/extensions/gsd/unit-context-manifest.ts +4 -28
- package/src/resources/extensions/gsd/unit-registry.ts +412 -0
- package/src/resources/extensions/gsd/unit-tool-contracts.ts +27 -192
- package/src/resources/extensions/gsd/verdict-parser.ts +1 -1
- package/src/resources/extensions/gsd/web-app-uat.ts +51 -8
- package/src/resources/extensions/gsd/workflow-tool-surface.ts +4 -1
- package/src/resources/extensions/gsd/worktree-git-recovery.ts +15 -9
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +3 -8
- package/src/resources/extensions/gsd/worktree-root.ts +12 -0
- package/src/resources/extensions/gsd/worktree-session-state.ts +3 -5
- package/src/resources/extensions/search-the-web/native-search.ts +5 -3
- package/src/resources/extensions/shared/browser-contract.ts +66 -0
- package/src/resources/extensions/shared/gsd-browser-cli.ts +119 -5
- package/src/resources/shared/package.json +3 -0
- package/src/resources/skills/create-skill/references/executable-code.md +1 -1
- package/src/resources/skills/create-skill/workflows/add-reference.md +8 -3
- package/src/resources/skills/create-skill/workflows/add-script.md +4 -2
- package/src/resources/skills/create-skill/workflows/add-template.md +3 -1
- package/src/resources/skills/create-skill/workflows/add-workflow.md +8 -3
- package/src/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
- package/src/resources/skills/create-skill/workflows/verify-skill.md +9 -4
- package/src/resources/skills/spike-wrap-up/SKILL.md +9 -9
- package/dist/resources/extensions/gsd/user-input-boundary.js +0 -218
- package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +0 -173
- package/src/resources/extensions/gsd/user-input-boundary.ts +0 -216
- /package/dist/web/standalone/.next/static/{C24pqUd-aru-l0Dp0gLZP → jmTLg6xZmAuq_LIqKOxrH}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{C24pqUd-aru-l0Dp0gLZP → jmTLg6xZmAuq_LIqKOxrH}/_ssgManifest.js +0 -0
|
@@ -28,6 +28,7 @@ import { ensureGsdSymlink, isInheritedRepo, validateProjectId } from "./repo-ide
|
|
|
28
28
|
import { migrateToExternalState, recoverFailedMigration } from "./migrate-external.js";
|
|
29
29
|
import { collectSecretsFromManifest } from "../get-secrets-from-user.js";
|
|
30
30
|
import { gsdRoot, resolveMilestoneFile } from "./paths.js";
|
|
31
|
+
import { milestoneEntryBlockedGuidance } from "./guidance.js";
|
|
31
32
|
import { invalidateAllCaches } from "./cache.js";
|
|
32
33
|
import { writeLock, clearLock, readCrashLock, isLockProcessAlive } from "./crash-recovery.js";
|
|
33
34
|
import {
|
|
@@ -57,7 +58,8 @@ import {
|
|
|
57
58
|
detectWorktreeName,
|
|
58
59
|
setActiveMilestoneId,
|
|
59
60
|
} from "./worktree.js";
|
|
60
|
-
import { getAutoWorktreePath, isInAutoWorktree
|
|
61
|
+
import { getAutoWorktreePath, isInAutoWorktree } from "./auto-worktree.js";
|
|
62
|
+
import { checkoutBranchWithStashGuard } from "./worktree-git-recovery.js";
|
|
61
63
|
import { readResourceVersion, cleanStaleRuntimeUnits } from "./auto-worktree.js";
|
|
62
64
|
import { worktreePath as getWorktreeDir, isInsideWorktreesDir } from "./worktree-manager.js";
|
|
63
65
|
import { emitWorktreeOrphaned } from "./worktree-telemetry.js";
|
|
@@ -993,12 +995,14 @@ export async function bootstrapAutoSession(
|
|
|
993
995
|
// phase-specific planning model for a discuss turn (#2829).
|
|
994
996
|
//
|
|
995
997
|
// Precedence:
|
|
996
|
-
// 1) Explicit session override via /gsd model (this session)
|
|
997
|
-
// 2)
|
|
998
|
-
// 3)
|
|
998
|
+
// 1) Explicit session override via /gsd model or /gsd auto --model (this session)
|
|
999
|
+
// 2) GSD model preferences from PREFERENCES.md (validated against live auth)
|
|
1000
|
+
// 3) Current session model from settings/session restore (if provider ready)
|
|
999
1001
|
//
|
|
1000
|
-
//
|
|
1001
|
-
//
|
|
1002
|
+
// PREFERENCES.md wins over the ambient session default (#3517) so /gsd auto
|
|
1003
|
+
// does not stick on claude-code/claude-sonnet-4-6 when the user configured
|
|
1004
|
+
// models via /gsd workflow-preferences or PREFERENCES.md. Custom providers
|
|
1005
|
+
// still skip PREFERENCES.md entirely (#4122).
|
|
1002
1006
|
//
|
|
1003
1007
|
// Exception (#4122): when the session provider is a custom provider declared
|
|
1004
1008
|
// in ~/.gsd/agent/models.json (Ollama, vLLM, OpenAI-compatible proxy, etc.),
|
|
@@ -1010,7 +1014,7 @@ export async function bootstrapAutoSession(
|
|
|
1010
1014
|
const sessionProviderIsCustom = isCustomProvider(ctx.model?.provider);
|
|
1011
1015
|
const preferredModel = sessionProviderIsCustom
|
|
1012
1016
|
? null
|
|
1013
|
-
: resolveDefaultSessionModel(ctx.model?.provider);
|
|
1017
|
+
: resolveDefaultSessionModel(ctx.model?.provider, base);
|
|
1014
1018
|
// Validate the preferred model against the live registry + provider auth so
|
|
1015
1019
|
// an unconfigured PREFERENCES.md entry (no API key / OAuth) can't become the
|
|
1016
1020
|
// start-model snapshot. Without this, every subsequent unit would try to
|
|
@@ -1040,8 +1044,8 @@ export async function bootstrapAutoSession(
|
|
|
1040
1044
|
: null;
|
|
1041
1045
|
const startThinkingSnapshot = pi.getThinkingLevel();
|
|
1042
1046
|
const startModelSnapshot = manualSessionOverride
|
|
1043
|
-
?? currentSessionModel
|
|
1044
1047
|
?? validatedPreferredModel
|
|
1048
|
+
?? currentSessionModel
|
|
1045
1049
|
?? null;
|
|
1046
1050
|
|
|
1047
1051
|
try {
|
|
@@ -1612,8 +1616,10 @@ export async function bootstrapAutoSession(
|
|
|
1612
1616
|
const isUnderGsdWorktrees = (p: string): boolean => {
|
|
1613
1617
|
const normalized = p.replaceAll("\\", "/");
|
|
1614
1618
|
if (findWorktreeSegment(normalized) !== null) return true;
|
|
1615
|
-
// The container directory itself (no trailing worktree name).
|
|
1616
|
-
return normalized.endsWith("/.gsd/worktrees")
|
|
1619
|
+
// The container directory itself (no trailing worktree name), in any layout.
|
|
1620
|
+
return normalized.endsWith("/.gsd/worktrees")
|
|
1621
|
+
|| normalized.endsWith("/.gsd-worktrees")
|
|
1622
|
+
|| /\/\.gsd\/projects\/[^/]+\/worktrees$/.test(normalized);
|
|
1617
1623
|
};
|
|
1618
1624
|
|
|
1619
1625
|
if (
|
|
@@ -1640,14 +1646,9 @@ export async function bootstrapAutoSession(
|
|
|
1640
1646
|
`Cannot enter milestone ${s.currentMilestoneId}: lease is held by another worker.`,
|
|
1641
1647
|
"error",
|
|
1642
1648
|
);
|
|
1643
|
-
} else if (enterResult.reason === "creation-failed") {
|
|
1644
|
-
ctx.ui.notify(
|
|
1645
|
-
`Cannot enter milestone ${s.currentMilestoneId}: worktree/branch creation failed. Isolation is degraded.`,
|
|
1646
|
-
"error",
|
|
1647
|
-
);
|
|
1648
|
-
} else if (enterResult.reason === "isolation-degraded") {
|
|
1649
|
+
} else if (enterResult.reason === "creation-failed" || enterResult.reason === "isolation-degraded") {
|
|
1649
1650
|
ctx.ui.notify(
|
|
1650
|
-
|
|
1651
|
+
milestoneEntryBlockedGuidance(s.currentMilestoneId, enterResult.reason),
|
|
1651
1652
|
"error",
|
|
1652
1653
|
);
|
|
1653
1654
|
} else if (enterResult.reason === "invalid-milestone-id") {
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { stripMcpToolPrefix } from "@gsd/pi-ai";
|
|
8
|
+
import { TOOL_SURFACE_NOT_READY } from "./tool-surface-readiness.js";
|
|
8
9
|
|
|
9
10
|
interface InFlightTool {
|
|
10
11
|
startedAt: number;
|
|
@@ -132,6 +133,15 @@ export function clearInFlightTools(): void {
|
|
|
132
133
|
const TOOL_INVOCATION_ERROR_RE = /Validation failed for tool|Input validation error|Invalid arguments for tool|MCP error -32602|No such tool available|Expected ',' or '\}'(?: after property value)?(?: in JSON)?|Unexpected end of JSON|Unexpected token.*in JSON|does not provide an export named|Named export .* not found|Cannot find module|ERR_MODULE_NOT_FOUND|ERR_MODULE_NOT_EXPORTED|ERR_PACKAGE_PATH_NOT_EXPORTED/i;
|
|
133
134
|
const DETERMINISTIC_POLICY_ERROR_RE = /(?:^|\b)(?:HARD BLOCK:|Blocked: \/gsd queue is a planning tool|Direct writes to \.gsd\/STATE\.md and \.gsd\/gsd\.db are blocked|This is a mechanical gate)/i;
|
|
134
135
|
|
|
136
|
+
/**
|
|
137
|
+
* Matches the runtime's "tool not registered" error. Unlike the deterministic
|
|
138
|
+
* invocation failures above, this one is usually transient: the workflow MCP
|
|
139
|
+
* server registers its tool surface asynchronously after session start, so a
|
|
140
|
+
* Unit's first tool call can race the registration. Callers should retry
|
|
141
|
+
* (bounded) instead of breaking the loop.
|
|
142
|
+
*/
|
|
143
|
+
const TOOL_UNAVAILABLE_ERROR_RE = new RegExp(`No such tool available|${TOOL_SURFACE_NOT_READY}`, "i");
|
|
144
|
+
|
|
135
145
|
/**
|
|
136
146
|
* Returns true if the error message indicates a deterministic invocation or
|
|
137
147
|
* policy failure (as opposed to a normal tool execution error).
|
|
@@ -141,6 +151,15 @@ export function isToolInvocationError(errorMsg: string): boolean {
|
|
|
141
151
|
return TOOL_INVOCATION_ERROR_RE.test(errorMsg) || isDeterministicPolicyError(errorMsg);
|
|
142
152
|
}
|
|
143
153
|
|
|
154
|
+
/**
|
|
155
|
+
* Returns true if the error message indicates the called tool was not on the
|
|
156
|
+
* session's tool surface (MCP startup race — see TOOL_UNAVAILABLE_ERROR_RE).
|
|
157
|
+
*/
|
|
158
|
+
export function isToolUnavailableError(errorMsg: string): boolean {
|
|
159
|
+
if (!errorMsg) return false;
|
|
160
|
+
return TOOL_UNAVAILABLE_ERROR_RE.test(errorMsg);
|
|
161
|
+
}
|
|
162
|
+
|
|
144
163
|
/**
|
|
145
164
|
* Returns true if the error message indicates the tool was skipped because
|
|
146
165
|
* a queued user message interrupted the turn (#3595). Retrying will produce
|
|
@@ -5,32 +5,25 @@ import {
|
|
|
5
5
|
} from "./unit-tool-contracts.js";
|
|
6
6
|
import {
|
|
7
7
|
WORKFLOW_TOOL_ALIAS_PAIRS,
|
|
8
|
-
canonicalWorkflowSurfaceToolName,
|
|
9
8
|
isWorkflowSurfaceAliasTool,
|
|
10
9
|
stripMcpToolPrefix,
|
|
11
10
|
} from "./workflow-tool-surface.js";
|
|
11
|
+
import { canonicalWorkflowToolName } from "./engine-hook-contract.js";
|
|
12
12
|
|
|
13
13
|
export {
|
|
14
14
|
AUTO_UNIT_SCOPED_TOOLS,
|
|
15
15
|
RUN_UAT_BROWSER_TOOL_NAMES,
|
|
16
16
|
} from "./unit-tool-contracts.js";
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const SECTION_CLOSE_GATE_UNIT_TYPES = new Set([
|
|
28
|
-
"execute-task",
|
|
29
|
-
"execute-task-simple",
|
|
30
|
-
"reactive-execute",
|
|
31
|
-
"complete-slice",
|
|
32
|
-
"validate-milestone",
|
|
33
|
-
]);
|
|
18
|
+
// Scope-class membership is declared per unit in the Unit Registry (ADR-033).
|
|
19
|
+
// EXECUTE_TASK_UNIT_TYPES = scopeClass "execute-task"; the section-close gate
|
|
20
|
+
// Set additionally includes scopeClass "section-close" — units whose completion
|
|
21
|
+
// handlers persist gate verdicts from artifact sections (gsd_save_gate_result
|
|
22
|
+
// belongs to gate-evaluate, so it is soft-blocked with a redirect below).
|
|
23
|
+
import {
|
|
24
|
+
EXECUTE_TASK_UNIT_TYPES,
|
|
25
|
+
SECTION_CLOSE_GATE_UNIT_TYPES,
|
|
26
|
+
} from "./unit-registry.js";
|
|
34
27
|
|
|
35
28
|
const EXTRA_SCOPED_GSD_LIFECYCLE_TOOLS = [
|
|
36
29
|
"gsd_skip_slice",
|
|
@@ -58,9 +51,9 @@ type AutoUnitToolScopeResult = {
|
|
|
58
51
|
displayReason?: string;
|
|
59
52
|
};
|
|
60
53
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
54
|
+
// Normalizer seam lives in engine-hook-contract.ts; re-exported here for
|
|
55
|
+
// existing scope importers.
|
|
56
|
+
export { canonicalWorkflowToolName };
|
|
64
57
|
|
|
65
58
|
export function isWorkflowAliasTool(toolName: string): boolean {
|
|
66
59
|
return isWorkflowSurfaceAliasTool(toolName);
|
|
@@ -110,7 +103,7 @@ function isNativeWorkflowTool(toolName: string): boolean {
|
|
|
110
103
|
return stripMcpToolPrefix(toolName) === "Workflow";
|
|
111
104
|
}
|
|
112
105
|
|
|
113
|
-
function readStringField(input: unknown, camel: string, snake: string): string | undefined {
|
|
106
|
+
export function readStringField(input: unknown, camel: string, snake: string): string | undefined {
|
|
114
107
|
if (!input || typeof input !== "object") return undefined;
|
|
115
108
|
const record = input as Record<string, unknown>;
|
|
116
109
|
const value = record[camel] ?? record[snake];
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
import type { ExtensionContext, ExtensionAPI } from "@gsd/pi-coding-agent";
|
|
17
17
|
import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
|
18
|
-
import { gsdProjectionRoot, resolveSliceFile, resolveSlicePath
|
|
18
|
+
import { gsdProjectionRoot, resolveSliceFile, resolveSlicePath } from "./paths.js";
|
|
19
19
|
import { resolveMilestoneValidationVerdict } from "./milestone-validation-verdict.js";
|
|
20
20
|
import { resolveCanonicalMilestoneRoot } from "./worktree-manager.js";
|
|
21
21
|
import { parseUnitId } from "./unit-id.js";
|
|
@@ -25,8 +25,6 @@ import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
|
25
25
|
import type { GSDPreferences } from "./preferences-types.js";
|
|
26
26
|
import { isClosedStatus } from "./status-guards.js";
|
|
27
27
|
import { loadFile } from "./files.js";
|
|
28
|
-
import { parseRoadmap } from "./parsers-legacy.js";
|
|
29
|
-
import { isMilestoneComplete } from "./state.js";
|
|
30
28
|
import {
|
|
31
29
|
runVerificationGate,
|
|
32
30
|
runVerificationGateForTargets,
|
|
@@ -373,29 +371,13 @@ async function runValidateMilestonePostCheck(
|
|
|
373
371
|
* DB-backed projects are authoritative (#4094 peer review); falls back to
|
|
374
372
|
* roadmap parsing only when the DB is unavailable.
|
|
375
373
|
*/
|
|
376
|
-
async function countIncompleteSlices(
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
return slices.filter((slice) => !isClosedStatus(slice.status)).length;
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
// Filesystem fallback: parse the roadmap markdown.
|
|
387
|
-
try {
|
|
388
|
-
const roadmapFile = resolveMilestoneFile(basePath, milestoneId, "ROADMAP");
|
|
389
|
-
if (!roadmapFile) return 1;
|
|
390
|
-
const roadmapContent = await loadFile(roadmapFile);
|
|
391
|
-
if (!roadmapContent) return 1;
|
|
392
|
-
const roadmap = parseRoadmap(roadmapContent);
|
|
393
|
-
if (roadmap.slices.length === 0) return 1;
|
|
394
|
-
return isMilestoneComplete(roadmap) ? 0 : 1;
|
|
395
|
-
} catch {
|
|
396
|
-
// Parsing failures should not cause false-positive pauses.
|
|
397
|
-
return 1;
|
|
398
|
-
}
|
|
374
|
+
async function countIncompleteSlices(_basePath: string, milestoneId: string): Promise<number> {
|
|
375
|
+
// DB-authoritative (ADR-017): no markdown fallback. DB unavailable or no
|
|
376
|
+
// rows means "unknown" — do not pause.
|
|
377
|
+
if (!isDbAvailable()) return 1;
|
|
378
|
+
const slices = getMilestoneSlices(milestoneId);
|
|
379
|
+
if (slices.length === 0) return 1;
|
|
380
|
+
return slices.filter((slice) => !isClosedStatus(slice.status)).length;
|
|
399
381
|
}
|
|
400
382
|
|
|
401
383
|
/**
|
|
@@ -44,23 +44,21 @@ import {
|
|
|
44
44
|
worktreePath,
|
|
45
45
|
isInsideWorktreesDir,
|
|
46
46
|
} from "./worktree-manager.js";
|
|
47
|
+
import { worktreePathFor } from "./worktree-placement.js";
|
|
47
48
|
import {
|
|
48
49
|
detectWorktreeName,
|
|
49
50
|
resolveGitHeadPath,
|
|
50
51
|
nudgeGitBranchCache,
|
|
51
52
|
} from "./worktree.js";
|
|
52
53
|
import {
|
|
53
|
-
findWorktreeSegment,
|
|
54
54
|
isGsdWorktreePath,
|
|
55
|
+
projectRootFromWorktreePath,
|
|
55
56
|
normalizeWorktreePathForCompare,
|
|
56
57
|
resolveWorktreeProjectRoot,
|
|
57
58
|
} from "./worktree-root.js";
|
|
58
59
|
import { autoResolveSafeConflictPaths } from "./git-conflict-resolve.js";
|
|
59
60
|
import { MergeConflictError, readIntegrationBranch, resolveMilestoneIntegrationBranch, RUNTIME_EXCLUSION_PATHS } from "./git-service.js";
|
|
60
|
-
import {
|
|
61
|
-
buildPullRequestEvidence,
|
|
62
|
-
createDraftPullRequestFromEvidence,
|
|
63
|
-
} from "./pull-request-process.js";
|
|
61
|
+
import { publishMilestone } from "./publication.js";
|
|
64
62
|
import { debugLog } from "./debug-logger.js";
|
|
65
63
|
import { logWarning, logError } from "./workflow-logger.js";
|
|
66
64
|
import {
|
|
@@ -73,9 +71,6 @@ import {
|
|
|
73
71
|
stashAlreadyExistsFilesFromError,
|
|
74
72
|
stashRefFromError,
|
|
75
73
|
} from "./worktree-git-recovery.js";
|
|
76
|
-
|
|
77
|
-
// Re-export for existing callers/tests (auto-start.ts, checkout-branch-stash-guard.test.ts).
|
|
78
|
-
export { checkoutBranchWithStashGuard } from "./worktree-git-recovery.js";
|
|
79
74
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
80
75
|
import { MILESTONE_ID_RE } from "./milestone-ids.js";
|
|
81
76
|
import { runWorktreePostCreateHook } from "./worktree-post-create-hook.js";
|
|
@@ -290,19 +285,6 @@ export function _gitPathspecForWorktreePath(basePath: string, targetPath: string
|
|
|
290
285
|
return gitPathspecForWorktreePath(basePath, targetPath);
|
|
291
286
|
}
|
|
292
287
|
|
|
293
|
-
function gitRemoteExists(basePath: string, remote: string): boolean {
|
|
294
|
-
try {
|
|
295
|
-
execFileSync("git", ["remote", "get-url", remote], {
|
|
296
|
-
cwd: basePath,
|
|
297
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
298
|
-
encoding: "utf-8",
|
|
299
|
-
});
|
|
300
|
-
return true;
|
|
301
|
-
} catch {
|
|
302
|
-
return false;
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
|
|
306
288
|
function findRegularMergeChangedPaths(basePath: string, milestoneBranch: string, mainBranch: string): Set<string> {
|
|
307
289
|
const changedPaths = new Set<string>();
|
|
308
290
|
let mergeLog = "";
|
|
@@ -520,12 +502,8 @@ export function checkResourcesStale(
|
|
|
520
502
|
* Returns the corrected base path.
|
|
521
503
|
*/
|
|
522
504
|
export function escapeStaleWorktree(base: string): string {
|
|
523
|
-
const
|
|
524
|
-
if (
|
|
525
|
-
|
|
526
|
-
// base is inside .gsd/worktrees/<something> — extract the project root.
|
|
527
|
-
// Normalization is 1:1 on characters, so the segment index is valid in `base`.
|
|
528
|
-
const projectRoot = base.slice(0, segment.gsdIdx);
|
|
505
|
+
const projectRoot = projectRootFromWorktreePath(base);
|
|
506
|
+
if (projectRoot === null) return base;
|
|
529
507
|
|
|
530
508
|
// Guard: If the candidate project root's .gsd IS the user-level ~/.gsd,
|
|
531
509
|
// the string-slice heuristic matched the wrong /.gsd/ boundary. This happens
|
|
@@ -1307,7 +1285,9 @@ export function getAutoWorktreePath(
|
|
|
1307
1285
|
): string | null {
|
|
1308
1286
|
basePath = resolveWorktreeProjectRoot(basePath);
|
|
1309
1287
|
|
|
1310
|
-
|
|
1288
|
+
// basePath is already the resolved project root — go straight to placement
|
|
1289
|
+
// instead of worktreePath(), which would re-resolve the root.
|
|
1290
|
+
const p = worktreePathFor(basePath, milestoneId);
|
|
1311
1291
|
if (!existsSync(p)) return null;
|
|
1312
1292
|
|
|
1313
1293
|
// Validate this is a real git worktree, not a stray directory.
|
|
@@ -2049,8 +2029,6 @@ export function mergeMilestoneToMain(
|
|
|
2049
2029
|
const isUntrackedRestoreFailure = stashPopMessage.includes("could not restore untracked files from stash");
|
|
2050
2030
|
const gsdContentConflicts: string[] = [];
|
|
2051
2031
|
const alreadyExists = stashAlreadyExistsFilesFromError(e);
|
|
2052
|
-
const gsdAlreadyExists = alreadyExists.filter((f) => f.startsWith(".gsd/"));
|
|
2053
|
-
const nonGsdAlreadyExists = alreadyExists.filter((f) => !f.startsWith(".gsd/"));
|
|
2054
2032
|
|
|
2055
2033
|
// Untracked-file restore failures can leave marker conflicts in tracked
|
|
2056
2034
|
// .gsd JSONL files without producing `U` status entries.
|
|
@@ -2114,11 +2092,12 @@ export function mergeMilestoneToMain(
|
|
|
2114
2092
|
} else if (
|
|
2115
2093
|
gsdUU.length === 0 &&
|
|
2116
2094
|
nonGsdUU.length === 0 &&
|
|
2117
|
-
|
|
2118
|
-
nonGsdAlreadyExists.length === 0
|
|
2095
|
+
alreadyExists.length > 0
|
|
2119
2096
|
) {
|
|
2120
|
-
// Untracked-file restore failure from stash pop where all collided
|
|
2121
|
-
//
|
|
2097
|
+
// Untracked-file restore failure from stash pop where all collided paths
|
|
2098
|
+
// already exist after merge (committed on target). Safe to drop the stash
|
|
2099
|
+
// for the full alreadyExists set — they were untracked on source by
|
|
2100
|
+
// definition of the "already exists, no checkout" failure.
|
|
2122
2101
|
if (stashRefForDrop) {
|
|
2123
2102
|
try {
|
|
2124
2103
|
execFileSync("git", ["stash", "drop", stashRefForDrop], {
|
|
@@ -2137,10 +2116,6 @@ export function mergeMilestoneToMain(
|
|
|
2137
2116
|
logWarning("reconcile", "Stash pop conflict on non-.gsd files after merge", {
|
|
2138
2117
|
files: nonGsdUU.join(", "),
|
|
2139
2118
|
});
|
|
2140
|
-
} else if (nonGsdAlreadyExists.length > 0) {
|
|
2141
|
-
logWarning("reconcile", "Stash pop restore collision on non-.gsd files after merge", {
|
|
2142
|
-
files: nonGsdAlreadyExists.join(", "),
|
|
2143
|
-
});
|
|
2144
2119
|
} else {
|
|
2145
2120
|
logWarning(
|
|
2146
2121
|
"worktree",
|
|
@@ -2258,62 +2233,24 @@ export function mergeMilestoneToMain(
|
|
|
2258
2233
|
};
|
|
2259
2234
|
|
|
2260
2235
|
let shouldCleanup = false;
|
|
2261
|
-
let pushed = false;
|
|
2262
|
-
let prCreated = false;
|
|
2263
2236
|
try {
|
|
2264
|
-
// 10.
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
}
|
|
2281
|
-
|
|
2282
|
-
// 9b. Auto-create PR if enabled (#2302: no longer gated on pushed/auto_push)
|
|
2283
|
-
if (prefs.auto_pr === true && !nothingToCommit) {
|
|
2284
|
-
const remote = prefs.remote ?? "origin";
|
|
2285
|
-
const prTarget = prefs.pr_target_branch ?? mainBranch;
|
|
2286
|
-
if (gitRemoteExists(originalBasePath_, remote)) {
|
|
2287
|
-
try {
|
|
2288
|
-
// Push the milestone branch to remote first
|
|
2289
|
-
execFileSync("git", ["push", remote, milestoneBranch], {
|
|
2290
|
-
cwd: originalBasePath_,
|
|
2291
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
2292
|
-
encoding: "utf-8",
|
|
2293
|
-
});
|
|
2294
|
-
const prEvidence = buildPullRequestEvidence({
|
|
2295
|
-
milestoneId,
|
|
2296
|
-
milestoneTitle,
|
|
2297
|
-
changeType: "feat",
|
|
2298
|
-
summaries: completedSlices.map((slice) => `### ${slice.id}\n${slice.title}`),
|
|
2299
|
-
testsRun: ["Auto-created after milestone merge. Run `npm run verify:merge` before marking this draft ready."],
|
|
2300
|
-
rollbackNotes: ["Close the draft PR or revert the merge commit if review finds a behavior regression."],
|
|
2301
|
-
how: "Generated by git.auto_pr after the milestone branch was pushed and merged locally.",
|
|
2302
|
-
});
|
|
2303
|
-
const prUrl = createDraftPullRequestFromEvidence(originalBasePath_, milestoneId, prEvidence, {
|
|
2304
|
-
head: milestoneBranch,
|
|
2305
|
-
base: prTarget,
|
|
2306
|
-
});
|
|
2307
|
-
if (!prUrl) {
|
|
2308
|
-
throw new Error("gh pr create returned no URL");
|
|
2309
|
-
}
|
|
2310
|
-
prCreated = true;
|
|
2311
|
-
} catch (err) {
|
|
2312
|
-
// PR creation failure is non-fatal — gh may not be installed or authenticated
|
|
2313
|
-
logWarning("worktree", `PR creation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
2314
|
-
}
|
|
2315
|
-
}
|
|
2316
|
-
}
|
|
2237
|
+
// 10/9b. Publication (auto-push / draft PR) — Publication module seam (ADR-034).
|
|
2238
|
+
const publication = publishMilestone({
|
|
2239
|
+
basePath: originalBasePath_,
|
|
2240
|
+
milestoneId,
|
|
2241
|
+
milestoneTitle,
|
|
2242
|
+
integrationBranch: mainBranch,
|
|
2243
|
+
milestoneBranch,
|
|
2244
|
+
sliceSummaries: completedSlices.map((slice) => `### ${slice.id}\n${slice.title}`),
|
|
2245
|
+
nothingToCommit,
|
|
2246
|
+
prefs: {
|
|
2247
|
+
autoPush: prefs.auto_push === true,
|
|
2248
|
+
autoPr: prefs.auto_pr === true,
|
|
2249
|
+
remote: prefs.remote,
|
|
2250
|
+
prTargetBranch: prefs.pr_target_branch,
|
|
2251
|
+
},
|
|
2252
|
+
});
|
|
2253
|
+
const { pushed, prCreated } = publication;
|
|
2317
2254
|
|
|
2318
2255
|
// 11. Guard removed — step 9b (#1792) now handles this with a smarter check:
|
|
2319
2256
|
// throws only when the milestone has unanchored code changes, passes
|
|
@@ -331,6 +331,11 @@ import {
|
|
|
331
331
|
} from "./db/auto-workers.js";
|
|
332
332
|
import { releaseMilestoneLease } from "./db/milestone-leases.js";
|
|
333
333
|
import { normalizeRealPath } from "./paths.js";
|
|
334
|
+
import {
|
|
335
|
+
formatStopNoticePrefix,
|
|
336
|
+
isBlockedStopReason,
|
|
337
|
+
stopNoticeDisplayReason,
|
|
338
|
+
} from "./stop-notice.js";
|
|
334
339
|
|
|
335
340
|
// ── ENCAPSULATION INVARIANT ─────────────────────────────────────────────────
|
|
336
341
|
// ALL mutable auto-mode state lives in the AutoSession class (auto/session.ts).
|
|
@@ -355,19 +360,7 @@ export function formatAutoStopNotification(prefix: string, totals: { cost: numbe
|
|
|
355
360
|
].join("\n");
|
|
356
361
|
}
|
|
357
362
|
|
|
358
|
-
|
|
359
|
-
return /^Blocked:\s*/i.test(reason ?? "");
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
function formatAutoStopDisplayReason(reason?: string | null): string {
|
|
363
|
-
return (reason ?? "").replace(/^Blocked:\s*/i, "").trim();
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
export function formatAutoStopNotificationPrefix(reason?: string | null): string {
|
|
367
|
-
const displayReason = formatAutoStopDisplayReason(reason);
|
|
368
|
-
const prefix = isBlockedStopReason(reason) ? "Auto-mode blocked" : "Auto-mode stopped";
|
|
369
|
-
return displayReason ? `${prefix} — ${displayReason}` : prefix;
|
|
370
|
-
}
|
|
363
|
+
export { formatStopNoticePrefix as formatAutoStopNotificationPrefix } from "./stop-notice.js";
|
|
371
364
|
|
|
372
365
|
function clearSessionModelOverrideForCommandSession(ctx?: ExtensionContext | null): void {
|
|
373
366
|
const sessionId =
|
|
@@ -1465,8 +1458,8 @@ export async function stopAuto(
|
|
|
1465
1458
|
): Promise<void> {
|
|
1466
1459
|
if (!s.active && !s.paused) return;
|
|
1467
1460
|
const loadedPreferences = loadEffectiveGSDPreferences(s.basePath || undefined)?.preferences;
|
|
1468
|
-
const stopNotificationPrefix =
|
|
1469
|
-
const displayReason =
|
|
1461
|
+
const stopNotificationPrefix = formatStopNoticePrefix(reason);
|
|
1462
|
+
const displayReason = stopNoticeDisplayReason(reason);
|
|
1470
1463
|
const isHeadlessStop = process.env.GSD_HEADLESS === "1";
|
|
1471
1464
|
const completionStopRequested = Boolean(options.completionWidget);
|
|
1472
1465
|
const preserveCloseoutTranscript = !isHeadlessStop && (
|
|
@@ -43,10 +43,8 @@ import {
|
|
|
43
43
|
} from "../error-classifier.js";
|
|
44
44
|
import { blockModel, isModelBlocked } from "../blocked-models.js";
|
|
45
45
|
import { getProjectGSDPreferencesPath } from "../preferences.js";
|
|
46
|
-
import {
|
|
47
|
-
|
|
48
|
-
resolveProviderErrorGuidance,
|
|
49
|
-
} from "../provider-error-guidance.js";
|
|
46
|
+
import { resolveProviderErrorGuidance } from "../provider-error-guidance.js";
|
|
47
|
+
import { formatGuidance } from "../guidance.js";
|
|
50
48
|
|
|
51
49
|
const retryState = createRetryState();
|
|
52
50
|
const MAX_NETWORK_RETRIES = 2;
|
|
@@ -627,7 +625,7 @@ export async function handleAgentEnd(
|
|
|
627
625
|
preferencesPath: dash.basePath ? getProjectGSDPreferencesPath(dash.basePath) : undefined,
|
|
628
626
|
hasConfiguredFallbacks: (modelConfig?.fallbacks.length ?? 0) > 0,
|
|
629
627
|
});
|
|
630
|
-
const guidanceText =
|
|
628
|
+
const guidanceText = formatGuidance(guidance);
|
|
631
629
|
|
|
632
630
|
await pauseForProviderModelRejection(ctx, pi, {
|
|
633
631
|
errorDetail,
|
|
@@ -7,7 +7,6 @@ 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";
|
|
@@ -87,8 +86,30 @@ export function registerDynamicTools(pi: ExtensionAPI): void {
|
|
|
87
86
|
const baseBash = createBashTool(fallbackRoot, {
|
|
88
87
|
spawnHook: (ctx) => ctx,
|
|
89
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
|
+
})();
|
|
90
109
|
const dynamicBash = {
|
|
91
110
|
...baseBash,
|
|
111
|
+
description: gsdBashDescription,
|
|
112
|
+
parameters: gsdBashParameters,
|
|
92
113
|
execute: async (
|
|
93
114
|
toolCallId: string,
|
|
94
115
|
params: { command: string; timeout?: number },
|
|
@@ -100,11 +121,7 @@ export function registerDynamicTools(pi: ExtensionAPI): void {
|
|
|
100
121
|
const fresh = createBashTool(basePath, {
|
|
101
122
|
spawnHook: (spawnCtx) => ({ ...spawnCtx, cwd: basePath }),
|
|
102
123
|
});
|
|
103
|
-
|
|
104
|
-
...params,
|
|
105
|
-
timeout: params.timeout ?? DEFAULT_BASH_TIMEOUT_SECS,
|
|
106
|
-
};
|
|
107
|
-
return (fresh as any).execute(toolCallId, paramsWithTimeout, signal, onUpdate, ctx);
|
|
124
|
+
return (fresh as any).execute(toolCallId, params, signal, onUpdate, ctx);
|
|
108
125
|
},
|
|
109
126
|
};
|
|
110
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
|
}
|