@opengsd/gsd-pi 1.2.0-dev.955e4da0 → 1.2.0-dev.fb12b103
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-style.d.ts +17 -0
- package/dist/cli-style.js +28 -0
- package/dist/cli.js +1 -1
- package/dist/headless-events.d.ts +4 -2
- package/dist/headless-events.js +7 -29
- package/dist/models-resolver.d.ts +3 -13
- package/dist/models-resolver.js +3 -22
- package/dist/resource-loader.js +2 -14
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/async-jobs/async-bash-tool.js +30 -64
- package/dist/resources/extensions/async-jobs/await-tool.js +80 -12
- package/dist/resources/extensions/async-jobs/index.js +65 -0
- package/dist/resources/extensions/async-jobs/job-manager.js +12 -1
- package/dist/resources/extensions/bg-shell/bg-shell-command.js +6 -6
- package/dist/resources/extensions/bg-shell/bg-shell-tool.js +10 -7
- package/dist/resources/extensions/bg-shell/overlay.js +9 -6
- package/dist/resources/extensions/bg-shell/process-manager.js +54 -25
- package/dist/resources/extensions/bg-shell/readiness-detector.js +11 -0
- package/dist/resources/extensions/bg-shell/utilities.js +3 -0
- package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +209 -88
- package/dist/resources/extensions/browser-tools/engine/selection.js +73 -5
- package/dist/resources/extensions/browser-tools/index.js +69 -12
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +30 -4
- package/dist/resources/extensions/gsd/auto/orchestrator.js +7 -5
- package/dist/resources/extensions/gsd/auto-dispatch.js +12 -1
- package/dist/resources/extensions/gsd/auto-model-selection.js +25 -6
- package/dist/resources/extensions/gsd/auto-post-unit.js +11 -2
- package/dist/resources/extensions/gsd/auto-prompts.js +15 -10
- package/dist/resources/extensions/gsd/auto-start.js +15 -10
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +18 -0
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +7 -16
- package/dist/resources/extensions/gsd/auto-worktree.js +30 -90
- package/dist/resources/extensions/gsd/auto.js +4 -13
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +3 -2
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +23 -6
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +19 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +122 -20
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +6 -2
- package/dist/resources/extensions/gsd/branch-patterns.js +2 -0
- package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +83 -0
- package/dist/resources/extensions/gsd/browser-evidence.js +8 -2
- package/dist/resources/extensions/gsd/captures.js +4 -6
- package/dist/resources/extensions/gsd/constants.js +0 -2
- package/dist/resources/extensions/gsd/crash-recovery.js +4 -12
- package/dist/resources/extensions/gsd/doctor-environment.js +2 -6
- package/dist/resources/extensions/gsd/doctor-format.js +9 -6
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +13 -15
- package/dist/resources/extensions/gsd/error-classifier.js +9 -0
- package/dist/resources/extensions/gsd/exec-sandbox.js +30 -10
- package/dist/resources/extensions/gsd/guidance.js +98 -0
- package/dist/resources/extensions/gsd/guided-flow.js +17 -2
- package/dist/resources/extensions/gsd/mcp-filter.js +2 -19
- package/dist/resources/extensions/gsd/mcp-tool-name.js +5 -13
- package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +1 -1
- package/dist/resources/extensions/gsd/migrate/safety.js +4 -1
- package/dist/resources/extensions/gsd/notification-store.js +11 -4
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +6 -4
- package/dist/resources/extensions/gsd/paths.js +27 -0
- package/dist/resources/extensions/gsd/pre-execution-checks.js +91 -3
- package/dist/resources/extensions/gsd/preferences-models.js +14 -48
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/run-uat.md +1 -1
- package/dist/resources/extensions/gsd/prompts/system.md +5 -2
- package/dist/resources/extensions/gsd/provider-error-guidance.js +1 -5
- package/dist/resources/extensions/gsd/provider-switch-observer.js +1 -1
- package/dist/resources/extensions/gsd/publication.js +87 -0
- package/dist/resources/extensions/gsd/recovery-classification.js +37 -94
- package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
- package/dist/resources/extensions/gsd/state.js +1 -20
- package/dist/resources/extensions/gsd/stop-notice.js +57 -0
- package/dist/resources/extensions/gsd/tool-surface-readiness.js +56 -0
- package/dist/resources/extensions/gsd/tools/exec-tool.js +9 -7
- package/dist/resources/extensions/gsd/tools/plan-slice.js +12 -6
- package/dist/resources/extensions/gsd/uat-policy.js +2 -1
- package/dist/resources/extensions/gsd/unit-closeout.js +138 -0
- package/dist/resources/extensions/gsd/unit-context-composer.js +74 -1
- package/dist/resources/extensions/gsd/unit-context-manifest.js +4 -27
- package/dist/resources/extensions/gsd/unit-registry.js +337 -0
- package/dist/resources/extensions/gsd/unit-tool-contracts.js +9 -182
- package/dist/resources/extensions/gsd/web-app-uat.js +45 -8
- package/dist/resources/extensions/gsd/workflow-tool-surface.js +1 -1
- package/dist/resources/extensions/gsd/worktree-git-recovery.js +15 -9
- package/dist/resources/extensions/gsd/worktree-root.js +11 -0
- package/dist/resources/extensions/gsd/worktree-session-state.js +4 -5
- package/dist/resources/extensions/search-the-web/native-search.js +5 -3
- package/dist/resources/extensions/shared/browser-contract.js +59 -0
- package/dist/resources/extensions/shared/gsd-browser-cli.js +96 -5
- package/dist/resources/shared/package.json +3 -0
- package/dist/resources/skills/create-skill/references/executable-code.md +1 -1
- package/dist/resources/skills/create-skill/workflows/add-reference.md +8 -3
- package/dist/resources/skills/create-skill/workflows/add-script.md +4 -2
- package/dist/resources/skills/create-skill/workflows/add-template.md +3 -1
- package/dist/resources/skills/create-skill/workflows/add-workflow.md +8 -3
- package/dist/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
- package/dist/resources/skills/create-skill/workflows/verify-skill.md +9 -4
- package/dist/resources/skills/spike-wrap-up/SKILL.md +9 -9
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +13 -13
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +13 -13
- package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
- package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/{796.cf859a427a2cb2ac.js → 796.e0bdc932325d7e03.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{webpack-fbea77b5f9953368.js → webpack-f0285ce91d4ec9ef.js} +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
- package/dist/web/standalone/node_modules/postcss/lib/container.js +18 -26
- package/dist/web/standalone/node_modules/postcss/lib/css-syntax-error.js +14 -47
- package/dist/web/standalone/node_modules/postcss/lib/declaration.js +4 -4
- package/dist/web/standalone/node_modules/postcss/lib/fromJSON.js +3 -3
- package/dist/web/standalone/node_modules/postcss/lib/input.js +29 -54
- package/dist/web/standalone/node_modules/postcss/lib/lazy-result.js +37 -47
- package/dist/web/standalone/node_modules/postcss/lib/map-generator.js +9 -26
- package/dist/web/standalone/node_modules/postcss/lib/no-work-result.js +55 -57
- package/dist/web/standalone/node_modules/postcss/lib/node.js +31 -99
- package/dist/web/standalone/node_modules/postcss/lib/parse.js +1 -1
- package/dist/web/standalone/node_modules/postcss/lib/parser.js +9 -10
- package/dist/web/standalone/node_modules/postcss/lib/postcss.js +12 -12
- package/dist/web/standalone/node_modules/postcss/lib/previous-map.js +11 -30
- package/dist/web/standalone/node_modules/postcss/lib/processor.js +7 -7
- package/dist/web/standalone/node_modules/postcss/lib/result.js +5 -5
- package/dist/web/standalone/node_modules/postcss/lib/rule.js +6 -6
- package/dist/web/standalone/node_modules/postcss/lib/stringifier.js +28 -69
- package/dist/web/standalone/node_modules/postcss/lib/tokenize.js +2 -6
- package/dist/web/standalone/node_modules/postcss/package.json +48 -48
- package/dist/web/standalone/package.json +1 -1
- package/dist/worktree-cli.js +3 -6
- package/dist/worktree-status-banner.js +7 -15
- package/package.json +1 -1
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/dist/rpc.d.ts +1 -0
- package/packages/contracts/dist/rpc.d.ts.map +1 -1
- package/packages/contracts/dist/rpc.js.map +1 -1
- package/packages/contracts/dist/workflow.d.ts +4 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +5 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +5 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +7 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +8 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +11 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +4 -4
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +3 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/cli.js +6 -3
- package/packages/mcp-server/dist/cli.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +8 -0
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +17 -1
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +3 -3
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts +1 -0
- package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/harness/env/nodejs.js +34 -3
- package/packages/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
- package/packages/pi-agent-core/dist/index.d.ts +1 -0
- package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/index.js +3 -0
- package/packages/pi-agent-core/dist/index.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +94 -382
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +149 -422
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +2 -2
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +19 -13
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/provider-readiness.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/provider-readiness.js +13 -6
- package/packages/pi-coding-agent/dist/core/provider-readiness.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +11 -0
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.js +53 -11
- package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/utils/shell.d.ts +28 -2
- package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/utils/shell.js +56 -10
- package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +9 -0
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/package.json +2 -2
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/src/resources/extensions/async-jobs/async-bash-cancel.test.ts +360 -0
- package/src/resources/extensions/async-jobs/async-bash-tool.ts +33 -56
- package/src/resources/extensions/async-jobs/await-tool.test.ts +139 -0
- package/src/resources/extensions/async-jobs/await-tool.ts +82 -12
- package/src/resources/extensions/async-jobs/index.ts +79 -0
- package/src/resources/extensions/async-jobs/job-manager.ts +21 -1
- package/src/resources/extensions/bg-shell/bg-shell-command.ts +6 -6
- package/src/resources/extensions/bg-shell/bg-shell-tool.ts +10 -6
- package/src/resources/extensions/bg-shell/overlay.ts +9 -5
- package/src/resources/extensions/bg-shell/process-manager.ts +50 -25
- package/src/resources/extensions/bg-shell/readiness-detector.ts +12 -0
- package/src/resources/extensions/bg-shell/tests/lifecycle-and-utilities.test.ts +48 -1
- package/src/resources/extensions/bg-shell/utilities.ts +3 -0
- package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +265 -98
- package/src/resources/extensions/browser-tools/engine/selection.ts +90 -4
- package/src/resources/extensions/browser-tools/index.ts +71 -13
- package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +83 -13
- package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +29 -1
- package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +136 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +34 -4
- package/src/resources/extensions/gsd/auto/orchestrator.ts +7 -5
- package/src/resources/extensions/gsd/auto-dispatch.ts +12 -0
- package/src/resources/extensions/gsd/auto-model-selection.ts +25 -5
- package/src/resources/extensions/gsd/auto-post-unit.ts +13 -2
- package/src/resources/extensions/gsd/auto-prompts.ts +40 -26
- package/src/resources/extensions/gsd/auto-start.ts +15 -10
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +19 -0
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +10 -17
- package/src/resources/extensions/gsd/auto-worktree.ts +30 -93
- package/src/resources/extensions/gsd/auto.ts +8 -15
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +3 -5
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +23 -6
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +24 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +151 -15
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +6 -2
- package/src/resources/extensions/gsd/branch-patterns.ts +3 -0
- package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +108 -0
- package/src/resources/extensions/gsd/browser-evidence.ts +18 -2
- package/src/resources/extensions/gsd/captures.ts +4 -6
- package/src/resources/extensions/gsd/constants.ts +0 -3
- package/src/resources/extensions/gsd/crash-recovery.ts +3 -9
- package/src/resources/extensions/gsd/doctor-environment.ts +2 -7
- package/src/resources/extensions/gsd/doctor-format.ts +12 -7
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +13 -15
- package/src/resources/extensions/gsd/error-classifier.ts +11 -0
- package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
- package/src/resources/extensions/gsd/guidance.ts +139 -0
- package/src/resources/extensions/gsd/guided-flow.ts +16 -2
- package/src/resources/extensions/gsd/mcp-filter.ts +2 -23
- package/src/resources/extensions/gsd/mcp-tool-name.ts +6 -11
- package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +1 -1
- package/src/resources/extensions/gsd/migrate/safety.ts +4 -1
- package/src/resources/extensions/gsd/notification-store.ts +26 -3
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +6 -4
- package/src/resources/extensions/gsd/paths.ts +33 -0
- package/src/resources/extensions/gsd/pre-execution-checks.ts +109 -3
- package/src/resources/extensions/gsd/preferences-models.ts +12 -47
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/replan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/run-uat.md +1 -1
- package/src/resources/extensions/gsd/prompts/system.md +5 -2
- package/src/resources/extensions/gsd/provider-error-guidance.ts +4 -9
- package/src/resources/extensions/gsd/provider-switch-observer.ts +1 -1
- package/src/resources/extensions/gsd/publication.ts +122 -0
- package/src/resources/extensions/gsd/recovery-classification.ts +42 -96
- package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
- package/src/resources/extensions/gsd/state.ts +4 -21
- package/src/resources/extensions/gsd/stop-notice.ts +75 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +16 -19
- package/src/resources/extensions/gsd/tests/browser-automation-contract-fixture.ts +39 -0
- package/src/resources/extensions/gsd/tests/browser-contract.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +144 -0
- package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +66 -1
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +8 -7
- package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +303 -0
- package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/dynamic-bash-no-cap.test.ts +132 -0
- package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +193 -0
- package/src/resources/extensions/gsd/tests/exec-tool.test.ts +29 -1
- package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +35 -1
- package/src/resources/extensions/gsd/tests/guidance.test.ts +125 -0
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +53 -11
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +73 -58
- package/src/resources/extensions/gsd/tests/integration/gsd-integration-fixture.ts +80 -0
- package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +32 -1
- package/src/resources/extensions/gsd/tests/notification-store.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +167 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +193 -1
- package/src/resources/extensions/gsd/tests/provider-error-guidance.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/publication.test.ts +120 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/stop-notice.test.ts +70 -0
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +76 -0
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +155 -0
- package/src/resources/extensions/gsd/tests/uat-policy.test.ts +24 -29
- package/src/resources/extensions/gsd/tests/unit-closeout.test.ts +209 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +67 -2
- package/src/resources/extensions/gsd/tests/unit-registry.test.ts +163 -0
- package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +44 -1
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +2 -2
- package/src/resources/extensions/gsd/tool-surface-readiness.ts +76 -0
- package/src/resources/extensions/gsd/tools/exec-tool.ts +8 -7
- package/src/resources/extensions/gsd/tools/plan-slice.ts +12 -6
- package/src/resources/extensions/gsd/uat-policy.ts +2 -1
- package/src/resources/extensions/gsd/unit-closeout.ts +201 -0
- package/src/resources/extensions/gsd/unit-context-composer.ts +111 -1
- package/src/resources/extensions/gsd/unit-context-manifest.ts +4 -28
- package/src/resources/extensions/gsd/unit-registry.ts +412 -0
- package/src/resources/extensions/gsd/unit-tool-contracts.ts +27 -192
- package/src/resources/extensions/gsd/web-app-uat.ts +51 -8
- package/src/resources/extensions/gsd/workflow-tool-surface.ts +4 -1
- package/src/resources/extensions/gsd/worktree-git-recovery.ts +15 -9
- package/src/resources/extensions/gsd/worktree-root.ts +12 -0
- package/src/resources/extensions/gsd/worktree-session-state.ts +3 -5
- package/src/resources/extensions/search-the-web/native-search.ts +5 -3
- package/src/resources/extensions/shared/browser-contract.ts +66 -0
- package/src/resources/extensions/shared/gsd-browser-cli.ts +119 -5
- package/src/resources/shared/package.json +3 -0
- package/src/resources/skills/create-skill/references/executable-code.md +1 -1
- package/src/resources/skills/create-skill/workflows/add-reference.md +8 -3
- package/src/resources/skills/create-skill/workflows/add-script.md +4 -2
- package/src/resources/skills/create-skill/workflows/add-template.md +3 -1
- package/src/resources/skills/create-skill/workflows/add-workflow.md +8 -3
- package/src/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
- package/src/resources/skills/create-skill/workflows/verify-skill.md +9 -4
- package/src/resources/skills/spike-wrap-up/SKILL.md +9 -9
- /package/dist/web/standalone/.next/static/{C24pqUd-aru-l0Dp0gLZP → mU4QIDlpVHDdjDpeEKh5W}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{C24pqUd-aru-l0Dp0gLZP → mU4QIDlpVHDdjDpeEKh5W}/_ssgManifest.js +0 -0
|
@@ -221,16 +221,20 @@ export function loadWriteGateSnapshot(basePath) {
|
|
|
221
221
|
* verification there; without this refresh the extension host keeps stale
|
|
222
222
|
* pending-gate memory and `activateDeferredApprovalGate` can re-arm a gate
|
|
223
223
|
* that the subprocess already cleared on disk.
|
|
224
|
+
*
|
|
225
|
+
* Returns the snapshot used for the refresh so callers that need to inspect
|
|
226
|
+
* it (e.g. re-arm guards) avoid a second disk read.
|
|
224
227
|
*/
|
|
225
228
|
export function refreshWriteGateStateFromDisk(basePath) {
|
|
226
|
-
if (!shouldPersistWriteGateSnapshot())
|
|
227
|
-
return;
|
|
228
229
|
const snapshot = loadWriteGateSnapshot(basePath);
|
|
230
|
+
if (!shouldPersistWriteGateSnapshot())
|
|
231
|
+
return snapshot;
|
|
229
232
|
const state = getWriteGateState(basePath);
|
|
230
233
|
state.pendingGateId = snapshot.pendingGateId;
|
|
231
234
|
state.activeQueuePhase = snapshot.activeQueuePhase;
|
|
232
235
|
state.verifiedDepthMilestones = new Set(snapshot.verifiedDepthMilestones);
|
|
233
236
|
state.verifiedApprovalGates = new Set(snapshot.verifiedApprovalGates ?? []);
|
|
237
|
+
return snapshot;
|
|
234
238
|
}
|
|
235
239
|
export function isDepthVerified(basePath = process.cwd()) {
|
|
236
240
|
return getWriteGateState(basePath).verifiedDepthMilestones.size > 0;
|
|
@@ -11,3 +11,5 @@ export const SLICE_BRANCH_RE = /^gsd\/(?:([a-zA-Z0-9_-]+)\/)?(M\d+(?:-[a-z0-9]{6
|
|
|
11
11
|
export const QUICK_BRANCH_RE = /^gsd\/quick\//;
|
|
12
12
|
/** Matches GSD-generated workflow template branches, not arbitrary user gsd/* branches. */
|
|
13
13
|
export const WORKFLOW_BRANCH_RE = /^gsd\/(?:hotfix|bugfix|small-feature|refactor|spike|security-audit|dep-upgrade|full-project)\//;
|
|
14
|
+
/** Auto-mode milestone branch prefix: milestone/<MID>. */
|
|
15
|
+
export const MILESTONE_BRANCH_PREFIX = "milestone/";
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { resolveAmbientBrowserEngineResolution, resolveBrowserEngineResolution, } from "../browser-tools/engine/selection.js";
|
|
4
|
+
import { resolveGsdBrowserCliAvailability, resolveGsdBrowserDaemonStartInvocation, } from "../shared/gsd-browser-cli.js";
|
|
5
|
+
import { uatTypeIncludesBrowser } from "./uat-policy.js";
|
|
6
|
+
const DEFAULT_DAEMON_START_TIMEOUT_MS = 30_000;
|
|
7
|
+
function isEnvDisabled(value) {
|
|
8
|
+
if (!value)
|
|
9
|
+
return false;
|
|
10
|
+
const normalized = value.trim().toLowerCase();
|
|
11
|
+
return normalized === "0" || normalized === "false" || normalized === "off";
|
|
12
|
+
}
|
|
13
|
+
function isWarmUpDisabled(env = process.env) {
|
|
14
|
+
const value = env.GSD_BROWSER_WARMUP?.trim().toLowerCase();
|
|
15
|
+
return value === "0" || value === "false" || value === "off";
|
|
16
|
+
}
|
|
17
|
+
/** Active engine for warm-up: explicit env override, else session-committed ambient resolution. */
|
|
18
|
+
function resolveActiveBrowserEngine(projectRoot, env) {
|
|
19
|
+
if (env.GSD_BROWSER_ENGINE?.trim()) {
|
|
20
|
+
return resolveBrowserEngineResolution(env, projectRoot).engine;
|
|
21
|
+
}
|
|
22
|
+
return resolveAmbientBrowserEngineResolution(projectRoot).engine;
|
|
23
|
+
}
|
|
24
|
+
export function shouldWarmBrowserDaemonForUat(ctx) {
|
|
25
|
+
if (!uatTypeIncludesBrowser(ctx.uatType))
|
|
26
|
+
return false;
|
|
27
|
+
const env = ctx.env ?? process.env;
|
|
28
|
+
if (isWarmUpDisabled(env))
|
|
29
|
+
return false;
|
|
30
|
+
if (isEnvDisabled(env.GSD_BROWSER_MCP_ENABLED))
|
|
31
|
+
return false;
|
|
32
|
+
const availability = resolveGsdBrowserCliAvailability(env);
|
|
33
|
+
if (!availability.available)
|
|
34
|
+
return false;
|
|
35
|
+
const projectRoot = resolve(ctx.projectRoot);
|
|
36
|
+
return resolveActiveBrowserEngine(projectRoot, env) === "gsd-browser";
|
|
37
|
+
}
|
|
38
|
+
export function ensureBrowserDaemonStarted(projectRoot, options = {}) {
|
|
39
|
+
const env = options.env ?? process.env;
|
|
40
|
+
const availability = resolveGsdBrowserCliAvailability(env);
|
|
41
|
+
if (!availability.available) {
|
|
42
|
+
return { ok: false, error: availability.detail };
|
|
43
|
+
}
|
|
44
|
+
let invocation;
|
|
45
|
+
try {
|
|
46
|
+
invocation = resolveGsdBrowserDaemonStartInvocation(projectRoot, env);
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
return {
|
|
50
|
+
ok: false,
|
|
51
|
+
error: error instanceof Error ? error.message : String(error),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
execFileSync(invocation.command, invocation.args, {
|
|
56
|
+
cwd: invocation.cwd,
|
|
57
|
+
env: { ...process.env, ...env, ...(invocation.env ?? {}) },
|
|
58
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
59
|
+
timeout: options.timeoutMs ?? DEFAULT_DAEMON_START_TIMEOUT_MS,
|
|
60
|
+
encoding: "utf-8",
|
|
61
|
+
});
|
|
62
|
+
return { ok: true };
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
return {
|
|
66
|
+
ok: false,
|
|
67
|
+
error: error instanceof Error ? error.message : String(error),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Best-effort pre-warm of the gsd-browser session daemon before browser-backed
|
|
73
|
+
* run-uat dispatch. Returns an actionable stop reason when warm-up is required
|
|
74
|
+
* but fails; returns null when warm-up is skipped or succeeds.
|
|
75
|
+
*/
|
|
76
|
+
export function prepareBrowserDaemonForUat(ctx) {
|
|
77
|
+
if (!shouldWarmBrowserDaemonForUat(ctx))
|
|
78
|
+
return null;
|
|
79
|
+
const result = ensureBrowserDaemonStarted(ctx.projectRoot, { env: ctx.env });
|
|
80
|
+
if (result.ok)
|
|
81
|
+
return null;
|
|
82
|
+
return `Cannot dispatch browser-backed run-uat: gsd-browser daemon failed to start (${result.error}). Ensure Chrome/Chromium is installed, run \`gsd-browser daemon health\` with the project session flags from .mcp.json, or set GSD_BROWSER_PATH to a Chromium binary.`;
|
|
83
|
+
}
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
// Project/App: gsd-pi
|
|
2
2
|
// File Purpose: Shared browser-observable UAT requirement and evidence detection.
|
|
3
|
-
|
|
3
|
+
import { BROWSER_EVIDENCE_SIGNAL_TOOL_NAMES } from "../shared/browser-contract.js";
|
|
4
|
+
// Alternation fragment over the contract's evidence-signal names, e.g.
|
|
5
|
+
// `browser_(?:assert|batch|...)`. The names are `browser_`-prefixed
|
|
6
|
+
// identifiers (pinned by tests/browser-contract.test.ts), so no escaping is
|
|
7
|
+
// needed.
|
|
8
|
+
const BROWSER_TOOL_SIGNAL = `browser_(?:${BROWSER_EVIDENCE_SIGNAL_TOOL_NAMES.map((name) => name.slice("browser_".length)).join("|")})`;
|
|
9
|
+
export const BROWSER_REQUIREMENT_RE = new RegExp(String.raw `\b(?:file://|localhost|playwright|chrome|screenshot|snapshot|${BROWSER_TOOL_SIGNAL})\b|\b(?:open|launch|navigate|load|visit|serve|start)\b.{0,80}\b(?:browser|page|localhost|file://)\b|\bbrowser\s+(?:check|session|test|uat|tool|automation|interaction|flow)\b`, "i");
|
|
4
10
|
export const NO_BROWSER_EVIDENCE_RE = /\b(?:no|without|not|wasn'?t|isn'?t)\s+(?:automated\s+)?(?:live\s+)?browser(?:\s+(?:session|test|uat))?|\bno\s+automated\s+browser\b|\bnot\s+conducted\b/i;
|
|
5
|
-
export const BROWSER_RUNTIME_RE =
|
|
11
|
+
export const BROWSER_RUNTIME_RE = new RegExp(String.raw `\b(?:browser|playwright|chrome|camoufox|${BROWSER_TOOL_SIGNAL}|screenshot|snapshot|file://|localhost)\b`, "i");
|
|
6
12
|
export const BROWSER_ACTION_RE = /\b(?:open(?:ed)?|navigate(?:d)?|click(?:ed)?|type(?:d)?|reload(?:ed)?|capture(?:d)?|screenshot|snapshot)\b/i;
|
|
7
13
|
export const BROWSER_ASSERTION_RE = /\b(?:assert(?:ed|ion)?|observed|confirmed|verified|expected|visible|text|count|label|strikethrough|localstorage|screenshot|snapshot|passed)\b/i;
|
|
8
14
|
const NON_REQUIREMENT_BROWSER_HEADING_RE = /^(?:not\s+proven|not\s+covered|out\s+of\s+scope|deferred|follow-?ups?|known\s+limitations|notes\s+for\s+tester)\b/i;
|
|
@@ -11,7 +11,7 @@ import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
|
11
11
|
import { join, resolve } from "node:path";
|
|
12
12
|
import { randomUUID } from "node:crypto";
|
|
13
13
|
import { gsdRoot } from "./paths.js";
|
|
14
|
-
import {
|
|
14
|
+
import { projectRootFromWorktreePath } from "./worktree-root.js";
|
|
15
15
|
// ─── Constants ────────────────────────────────────────────────────────────────
|
|
16
16
|
const CAPTURES_FILENAME = "CAPTURES.md";
|
|
17
17
|
const VALID_CLASSIFICATIONS = [
|
|
@@ -30,11 +30,9 @@ const VALID_CLASSIFICATIONS = [
|
|
|
30
30
|
* directory that contains `.gsd/worktrees/` — that's the project root.
|
|
31
31
|
*/
|
|
32
32
|
export function resolveCapturesPath(basePath) {
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
if (
|
|
36
|
-
// basePath is inside a worktree — resolve to project root
|
|
37
|
-
const projectRoot = resolved.slice(0, segment.gsdIdx);
|
|
33
|
+
// If basePath is inside a worktree, resolve to the project root.
|
|
34
|
+
const projectRoot = projectRootFromWorktreePath(resolve(basePath));
|
|
35
|
+
if (projectRoot) {
|
|
38
36
|
return join(projectRoot, ".gsd", CAPTURES_FILENAME);
|
|
39
37
|
}
|
|
40
38
|
return join(gsdRoot(basePath), CAPTURES_FILENAME);
|
|
@@ -6,8 +6,6 @@
|
|
|
6
6
|
// ─── Timeouts ─────────────────────────────────────────────────────────────────
|
|
7
7
|
/** Default timeout for verification-gate commands (ms). */
|
|
8
8
|
export const DEFAULT_COMMAND_TIMEOUT_MS = 120_000;
|
|
9
|
-
/** Default timeout for the dynamic bash tool (seconds). */
|
|
10
|
-
export const DEFAULT_BASH_TIMEOUT_SECS = 120;
|
|
11
9
|
// ─── Cache Sizes ──────────────────────────────────────────────────────────────
|
|
12
10
|
/** Max directory-listing cache entries before eviction (#611). */
|
|
13
11
|
export const DIR_CACHE_MAX = 200;
|
|
@@ -29,6 +29,7 @@ import { markLatestActiveForWorkerCanceled } from "./db/unit-dispatches.js";
|
|
|
29
29
|
import { getRuntimeKv, setRuntimeKv, deleteRuntimeKv } from "./db/runtime-kv.js";
|
|
30
30
|
import { _getAdapter, isDbAvailable } from "./gsd-db.js";
|
|
31
31
|
import { gsdRoot, normalizeRealPath } from "./paths.js";
|
|
32
|
+
import { crashResumeHint } from "./guidance.js";
|
|
32
33
|
import { atomicWriteSync } from "./atomic-write.js";
|
|
33
34
|
import { effectiveLockFile } from "./session-lock.js";
|
|
34
35
|
import { isInFlightRuntimePhase, listUnitRuntimeRecords } from "./unit-runtime.js";
|
|
@@ -289,18 +290,9 @@ export function formatCrashInfo(lock) {
|
|
|
289
290
|
` Started at: ${lock.unitStartedAt}`,
|
|
290
291
|
` PID: ${lock.pid}`,
|
|
291
292
|
];
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
else if (lock.unitType.includes("research") || lock.unitType.includes("plan")) {
|
|
296
|
-
lines.push(`The ${lock.unitType} unit may be incomplete. Run /gsd auto to re-run it.`);
|
|
297
|
-
}
|
|
298
|
-
else if (lock.unitType.includes("execute")) {
|
|
299
|
-
lines.push(`Task execution was interrupted. Run /gsd auto to resume — completed work is preserved.`);
|
|
300
|
-
}
|
|
301
|
-
else if (lock.unitType.includes("complete")) {
|
|
302
|
-
lines.push(`Slice/milestone completion was interrupted. Run /gsd auto to finish.`);
|
|
303
|
-
}
|
|
293
|
+
const hint = crashResumeHint(lock.unitType, lock.unitId);
|
|
294
|
+
if (hint)
|
|
295
|
+
lines.push(hint);
|
|
304
296
|
return lines.join("\n");
|
|
305
297
|
}
|
|
306
298
|
/**
|
|
@@ -12,7 +12,7 @@ import { existsSync, readFileSync, statSync } from "node:fs";
|
|
|
12
12
|
import { execSync } from "node:child_process";
|
|
13
13
|
import { join } from "node:path";
|
|
14
14
|
import { detectPythonExecutable } from "./python-resolver.js";
|
|
15
|
-
import {
|
|
15
|
+
import { projectRootFromWorktreePath } from "./worktree-root.js";
|
|
16
16
|
// ── Constants ──────────────────────────────────────────────────────────────
|
|
17
17
|
/** Default dev server ports to scan for conflicts. */
|
|
18
18
|
const DEFAULT_DEV_PORTS = [3000, 3001, 4000, 5000, 5173, 8000, 8080, 8888];
|
|
@@ -33,11 +33,7 @@ function resolveWorktreeProjectRoot(basePath) {
|
|
|
33
33
|
const envRoot = process.env.GSD_WORKTREE;
|
|
34
34
|
if (envRoot)
|
|
35
35
|
return envRoot;
|
|
36
|
-
|
|
37
|
-
if (!segment)
|
|
38
|
-
return null;
|
|
39
|
-
// Everything before the worktree segment is the project root
|
|
40
|
-
return basePath.slice(0, segment.gsdIdx);
|
|
36
|
+
return projectRootFromWorktreePath(basePath);
|
|
41
37
|
}
|
|
42
38
|
function tryExec(cmd, cwd) {
|
|
43
39
|
try {
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { doctorFixHint } from "./guidance.js";
|
|
2
|
+
function severityTag(severity) {
|
|
3
|
+
return severity === "error" ? "ERROR" : severity === "warning" ? "WARN" : "INFO";
|
|
4
|
+
}
|
|
1
5
|
function matchesScope(unitId, scope) {
|
|
2
6
|
if (!scope)
|
|
3
7
|
return true;
|
|
@@ -47,8 +51,10 @@ export function formatDoctorReport(report, options) {
|
|
|
47
51
|
if (scopedIssues.length > 0) {
|
|
48
52
|
lines.push("Priority issues:");
|
|
49
53
|
for (const issue of scopedIssues.slice(0, maxIssues)) {
|
|
50
|
-
|
|
51
|
-
|
|
54
|
+
lines.push(`- [${severityTag(issue.severity)}] ${issue.unitId}: ${issue.message}${issue.file ? ` (${issue.file})` : ""}`);
|
|
55
|
+
const hint = doctorFixHint(issue.code);
|
|
56
|
+
if (hint && issue.severity !== "info")
|
|
57
|
+
lines.push(` Fix: ${hint}`);
|
|
52
58
|
}
|
|
53
59
|
if (scopedIssues.length > maxIssues) {
|
|
54
60
|
lines.push(`- ...and ${scopedIssues.length - maxIssues} more in scope`);
|
|
@@ -66,10 +72,7 @@ export function formatDoctorReport(report, options) {
|
|
|
66
72
|
export function formatDoctorIssuesForPrompt(issues) {
|
|
67
73
|
if (issues.length === 0)
|
|
68
74
|
return "- No remaining issues in scope.";
|
|
69
|
-
return issues.map(issue => {
|
|
70
|
-
const prefix = issue.severity === "error" ? "ERROR" : issue.severity === "warning" ? "WARN" : "INFO";
|
|
71
|
-
return `- [${prefix}] ${issue.unitId} | ${issue.code} | ${issue.message}${issue.file ? ` | file: ${issue.file}` : ""} | fixable: ${issue.fixable ? "yes" : "no"}`;
|
|
72
|
-
}).join("\n");
|
|
75
|
+
return issues.map(issue => `- [${severityTag(issue.severity)}] ${issue.unitId} | ${issue.code} | ${issue.message}${issue.file ? ` | file: ${issue.file}` : ""} | fixable: ${issue.fixable ? "yes" : "no"}`).join("\n");
|
|
73
76
|
}
|
|
74
77
|
/**
|
|
75
78
|
* Serialize a doctor report to JSON — suitable for CI/tooling integration.
|
|
@@ -401,21 +401,19 @@ export async function checkRuntimeHealth(basePath, issues, fixesApplied, shouldF
|
|
|
401
401
|
if (!hasBlanketIgnore) {
|
|
402
402
|
missing.push(...criticalPatterns.filter(p => !existingLines.has(p)));
|
|
403
403
|
}
|
|
404
|
-
{
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
fixesApplied.push("added missing GSD runtime patterns to .gitignore");
|
|
418
|
-
}
|
|
404
|
+
if (missing.length > 0) {
|
|
405
|
+
issues.push({
|
|
406
|
+
severity: "warning",
|
|
407
|
+
code: "gitignore_missing_patterns",
|
|
408
|
+
scope: "project",
|
|
409
|
+
unitId: "project",
|
|
410
|
+
message: `${missing.length} critical GSD runtime pattern(s) missing from .gitignore: ${missing.join(", ")}`,
|
|
411
|
+
file: ".gitignore",
|
|
412
|
+
fixable: true,
|
|
413
|
+
});
|
|
414
|
+
if (shouldFix("gitignore_missing_patterns")) {
|
|
415
|
+
ensureGitignore(basePath, { manageGitignore });
|
|
416
|
+
fixesApplied.push("added missing GSD runtime patterns to .gitignore");
|
|
419
417
|
}
|
|
420
418
|
}
|
|
421
419
|
}
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* @see https://github.com/open-gsd/gsd-pi/issues/2577
|
|
11
11
|
*/
|
|
12
|
+
import { TOOL_SURFACE_NOT_READY } from "./tool-surface-readiness.js";
|
|
12
13
|
export function createRetryState() {
|
|
13
14
|
return { networkRetryCount: 0, consecutiveTransientCount: 0, currentRetryModelId: undefined };
|
|
14
15
|
}
|
|
@@ -44,6 +45,10 @@ const CONNECTION_RE = /terminated|connection.?(?:refused|error)|other side close
|
|
|
44
45
|
const STREAM_RE = /in JSON at position \d+|Unexpected end of JSON|SyntaxError.*JSON/i;
|
|
45
46
|
const RESET_DELAY_RE = /reset in (\d+)s/i;
|
|
46
47
|
const TOOL_SCHEMA_RE = /schema overload|consecutive tool validation failures/i;
|
|
48
|
+
// GSD tool-surface readiness abort (claude-code stream adapter): the workflow
|
|
49
|
+
// MCP server had not registered the Unit's required tools at SDK init. The
|
|
50
|
+
// server typically finishes connecting within seconds — same-model retry.
|
|
51
|
+
const TOOL_SURFACE_NOT_READY_RE = new RegExp(TOOL_SURFACE_NOT_READY, "i");
|
|
47
52
|
// Provider rejected the request shape for the selected model (400 bad request,
|
|
48
53
|
// grammar limits, etc.). Not transient — try a different model/fallback.
|
|
49
54
|
// Context-window 400s stay in SERVER_RE (checked earlier).
|
|
@@ -77,6 +82,10 @@ export function classifyError(errorMsg, retryAfterMs) {
|
|
|
77
82
|
if (TOOL_SCHEMA_RE.test(errorMsg)) {
|
|
78
83
|
return { kind: "tool-schema", retryAfterMs: 0 };
|
|
79
84
|
}
|
|
85
|
+
// Tool-surface readiness abort — transient; retry the same model shortly.
|
|
86
|
+
if (TOOL_SURFACE_NOT_READY_RE.test(errorMsg)) {
|
|
87
|
+
return { kind: "network", retryAfterMs: retryAfterMs ?? 3_000 };
|
|
88
|
+
}
|
|
80
89
|
const isPermanent = PERMANENT_RE.test(errorMsg);
|
|
81
90
|
const isRateLimit = RATE_LIMIT_RE.test(errorMsg) || AFFORDABILITY_RE.test(errorMsg);
|
|
82
91
|
const isUnsupportedModel = UNSUPPORTED_MODEL_MODEL_RE.test(errorMsg) &&
|
|
@@ -11,7 +11,11 @@ import { spawn } from "node:child_process";
|
|
|
11
11
|
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
12
12
|
import { randomUUID } from "node:crypto";
|
|
13
13
|
import { resolve } from "node:path";
|
|
14
|
+
import { killProcessTree, SIGKILL_GRACE_MS, HARD_DEADLINE_MS } from "@gsd/pi-coding-agent";
|
|
14
15
|
const ALWAYS_FORWARD_ENV = ["PATH", "HOME"];
|
|
16
|
+
// SIGKILL_GRACE_MS / HARD_DEADLINE_MS are imported from @gsd/pi-coding-agent
|
|
17
|
+
// (shell.ts) — the single source of truth for the graceful-kill timing ladder —
|
|
18
|
+
// so this sandbox can never drift from the canonical kill path it delegates to.
|
|
15
19
|
export const EXEC_DEFAULTS = {
|
|
16
20
|
clampTimeoutMs: 600_000,
|
|
17
21
|
defaultTimeoutMs: 30_000,
|
|
@@ -120,6 +124,7 @@ export function runExecSandbox(request, opts) {
|
|
|
120
124
|
exit_code: null,
|
|
121
125
|
signal: null,
|
|
122
126
|
timed_out: false,
|
|
127
|
+
force_resolved: false,
|
|
123
128
|
duration_ms: duration,
|
|
124
129
|
stdout_bytes: 0,
|
|
125
130
|
stderr_bytes: Buffer.byteLength(`spawn error: ${message}\n`),
|
|
@@ -172,24 +177,38 @@ export function runExecSandbox(request, opts) {
|
|
|
172
177
|
stderrTruncated = true;
|
|
173
178
|
}
|
|
174
179
|
});
|
|
180
|
+
const effectiveGraceMs = opts.kill_grace_ms ?? SIGKILL_GRACE_MS;
|
|
181
|
+
const effectiveForceResolveDelay = opts.force_resolve_delay_ms ?? (effectiveGraceMs + HARD_DEADLINE_MS);
|
|
175
182
|
let timedOut = false;
|
|
183
|
+
let settled = false;
|
|
184
|
+
let forceResolveTimer;
|
|
176
185
|
const timer = setTimeout(() => {
|
|
177
186
|
timedOut = true;
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
}
|
|
187
|
+
// killProcessTree handles both platforms and kills the whole tree: on Unix
|
|
188
|
+
// it signals the process group (SIGTERM -> grace -> SIGKILL); on Windows it
|
|
189
|
+
// force-kills the tree via taskkill /F /T. Using child.kill("SIGTERM") here
|
|
190
|
+
// would only terminate the direct child on Windows, orphaning grandchildren.
|
|
191
|
+
if (child.pid != null) {
|
|
192
|
+
killProcessTree(child.pid, { graceMs: effectiveGraceMs });
|
|
185
193
|
}
|
|
186
194
|
else {
|
|
187
|
-
child.kill("
|
|
195
|
+
child.kill("SIGTERM");
|
|
188
196
|
}
|
|
197
|
+
// Arm hard-deadline force-resolve in case child never closes (D-state).
|
|
198
|
+
// The "SIGKILL" here is a synthetic marker (the process may not have actually
|
|
199
|
+
// received it); force_resolved=true records that this was a deadline, not an exit.
|
|
200
|
+
forceResolveTimer = setTimeout(() => {
|
|
201
|
+
finalize(null, "SIGKILL", true);
|
|
202
|
+
}, effectiveForceResolveDelay);
|
|
203
|
+
forceResolveTimer.unref?.();
|
|
189
204
|
}, timeoutMs);
|
|
190
205
|
timer.unref?.();
|
|
191
|
-
const finalize = (exitCode, signal) => {
|
|
206
|
+
const finalize = (exitCode, signal, forceResolved = false) => {
|
|
207
|
+
if (settled)
|
|
208
|
+
return;
|
|
209
|
+
settled = true;
|
|
192
210
|
clearTimeout(timer);
|
|
211
|
+
clearTimeout(forceResolveTimer);
|
|
193
212
|
const duration = Date.now() - started;
|
|
194
213
|
const stdoutBuf = Buffer.concat(stdoutChunks);
|
|
195
214
|
const stderrBuf = Buffer.concat(stderrChunks);
|
|
@@ -211,6 +230,7 @@ export function runExecSandbox(request, opts) {
|
|
|
211
230
|
exit_code: exitCode,
|
|
212
231
|
signal,
|
|
213
232
|
timed_out: timedOut,
|
|
233
|
+
force_resolved: forceResolved,
|
|
214
234
|
duration_ms: duration,
|
|
215
235
|
stdout_bytes: stdoutBytes,
|
|
216
236
|
stderr_bytes: stderrBytes,
|
|
@@ -254,6 +274,7 @@ function writeMeta(path, result, request, now) {
|
|
|
254
274
|
exit_code: result.exit_code,
|
|
255
275
|
signal: result.signal,
|
|
256
276
|
timed_out: result.timed_out,
|
|
277
|
+
force_resolved: result.force_resolved,
|
|
257
278
|
duration_ms: result.duration_ms,
|
|
258
279
|
stdout_bytes: result.stdout_bytes,
|
|
259
280
|
stderr_bytes: result.stderr_bytes,
|
|
@@ -261,7 +282,6 @@ function writeMeta(path, result, request, now) {
|
|
|
261
282
|
stderr_truncated: result.stderr_truncated,
|
|
262
283
|
stdout_path: result.stdout_path,
|
|
263
284
|
stderr_path: result.stderr_path,
|
|
264
|
-
...(request.metadata ? { metadata: request.metadata } : {}),
|
|
265
285
|
};
|
|
266
286
|
writeFileSync(path, `${JSON.stringify(meta, null, 2)}\n`);
|
|
267
287
|
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
// Project/App: gsd-pi
|
|
2
|
+
// File Purpose: Guidance module — the single catalog mapping typed findings
|
|
3
|
+
// (Recovery kinds, milestone blocker kinds, doctor issue codes, crash unit
|
|
4
|
+
// classes) to user-facing remediation: what happened and what to do next.
|
|
5
|
+
//
|
|
6
|
+
// Emit sites pass the typed finding; phrasing, command names, and step
|
|
7
|
+
// ordering live here. A missing catalog row is a visible gap, not a silent
|
|
8
|
+
// omission scattered across call sites.
|
|
9
|
+
/** Flatten guidance into a notification / pause-banner string. */
|
|
10
|
+
export function formatGuidance(guidance) {
|
|
11
|
+
if (guidance.steps.length === 0)
|
|
12
|
+
return guidance.summary;
|
|
13
|
+
const numbered = guidance.steps.map((step, index) => `${index + 1}. ${step}`).join("\n");
|
|
14
|
+
return `${guidance.summary}\n\n${numbered}`;
|
|
15
|
+
}
|
|
16
|
+
const RECOVERY_REMEDIATION = {
|
|
17
|
+
"tool-schema": "Fix the Unit Tool Contract or tool schema before retrying.",
|
|
18
|
+
"tool-contract": "Fix the Unit Tool Contract or prompt so the Unit is only asked to use tools owned by its phase.",
|
|
19
|
+
"tool-unavailable": "The tool surface had not finished registering when the Unit called it (workflow MCP startup race). Retry after the surface is ready; escalate if the tool never appears.",
|
|
20
|
+
"deterministic-policy": "Resolve the policy blocker; retrying the same Unit will repeat the failure.",
|
|
21
|
+
"lifecycle-progression": "Route to the required owning Unit or restore the missing artifact before advancing lifecycle state.",
|
|
22
|
+
"stale-worker": "Run `/gsd doctor` to detect and clear the stale worker or lock, then run `/gsd auto` to resume.",
|
|
23
|
+
"worktree-invalid": "Run `/gsd doctor` to diagnose the milestone worktree (`gsd worktree list` shows its state). Repair it, or merge salvageable work with `gsd worktree merge <name>` before recreating — recreating discards uncommitted work.",
|
|
24
|
+
"verification-drift": "Run `/gsd status` to see the verification finding, fix or re-run the verification, then run `/gsd auto` to resume. `/gsd doctor` can repair stale state files.",
|
|
25
|
+
"reconciliation-drift": "Run `/gsd doctor` to surface the persistent or repair-failed drift kinds, apply its fixes, then run `/gsd auto` to resume.",
|
|
26
|
+
"illegal-transition": "A derived Phase edge rejected by the Phase Transition Invariant survived reconciliation; inspect deriveState and the State Reconciliation Module before resuming.",
|
|
27
|
+
"runtime-unknown": "Inspect the runtime error and add a dedicated classification if it is repeatable.",
|
|
28
|
+
"provider-transient": "Retry after the provider/network condition clears.",
|
|
29
|
+
"provider-permanent": "Inspect provider credentials, model entitlement, or request shape.",
|
|
30
|
+
};
|
|
31
|
+
export function recoveryRemediation(key) {
|
|
32
|
+
return RECOVERY_REMEDIATION[key];
|
|
33
|
+
}
|
|
34
|
+
// ─── Milestone validation blockers ──────────────────────────────────────
|
|
35
|
+
// NOTE: the first line of each blocker is load-bearing — validation-block-guard
|
|
36
|
+
// matches /milestone validation returned needs-(?:attention|remediation)/i.
|
|
37
|
+
// Keep that phrase intact when editing.
|
|
38
|
+
export function needsAttentionBlockerGuidance(milestoneId) {
|
|
39
|
+
return [
|
|
40
|
+
`Milestone ${milestoneId} is blocked because milestone validation returned needs-attention.`,
|
|
41
|
+
`Fix options:`,
|
|
42
|
+
`1. Review the validation details: \`/gsd status\``,
|
|
43
|
+
`2. If you fixed the missing evidence or issue, re-run milestone validation: \`/gsd validate-milestone\``,
|
|
44
|
+
`3. If the finding is acceptable, override it: \`/gsd verdict pass --rationale "why this is okay"\``,
|
|
45
|
+
`4. If this should wait, defer it explicitly: \`/gsd park ${milestoneId}\``,
|
|
46
|
+
`After validation or override passes, run \`/gsd auto\` to complete and merge the milestone.`,
|
|
47
|
+
].join("\n");
|
|
48
|
+
}
|
|
49
|
+
export function needsRemediationBlockerGuidance(milestoneId) {
|
|
50
|
+
return [
|
|
51
|
+
`Milestone ${milestoneId} is blocked because milestone validation returned needs-remediation, but all slices are complete.`,
|
|
52
|
+
`Fix options:`,
|
|
53
|
+
`1. Run \`/gsd dispatch reassess\` to add remediation slices, then run \`/gsd auto\``,
|
|
54
|
+
`2. If the finding is acceptable, override it: \`/gsd verdict pass --rationale "why this is okay"\``,
|
|
55
|
+
`3. If this should wait, defer it explicitly: \`/gsd park ${milestoneId}\``,
|
|
56
|
+
].join("\n");
|
|
57
|
+
}
|
|
58
|
+
// ─── Crash recovery resume hints ────────────────────────────────────────
|
|
59
|
+
/** Resume hint for an interrupted auto-mode unit, by unit class. */
|
|
60
|
+
export function crashResumeHint(unitType, unitId) {
|
|
61
|
+
if (unitType === "starting" && unitId === "bootstrap") {
|
|
62
|
+
return `No work was lost. Run /gsd auto to restart.`;
|
|
63
|
+
}
|
|
64
|
+
if (unitType.includes("research") || unitType.includes("plan")) {
|
|
65
|
+
return `The ${unitType} unit may be incomplete. Run /gsd auto to re-run it.`;
|
|
66
|
+
}
|
|
67
|
+
if (unitType.includes("execute")) {
|
|
68
|
+
return `Task execution was interrupted. Run /gsd auto to resume — completed work is preserved.`;
|
|
69
|
+
}
|
|
70
|
+
if (unitType.includes("complete")) {
|
|
71
|
+
return `Slice/milestone completion was interrupted. Run /gsd auto to finish.`;
|
|
72
|
+
}
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
// ─── Doctor issue fix hints ─────────────────────────────────────────────
|
|
76
|
+
// Partial by design: codes without a row render no hint. Add rows here as
|
|
77
|
+
// guidance is authored — the gap is visible in one place.
|
|
78
|
+
const DOCTOR_FIX_HINTS = {
|
|
79
|
+
db_unavailable: "The workflow database could not be opened — state derivation is degraded. Restart the session; if it persists, run `/gsd doctor` from the project root.",
|
|
80
|
+
stale_crash_lock: "Run `/gsd doctor` to clear the stale lock, then `/gsd auto` to resume.",
|
|
81
|
+
stale_parallel_session: "Run `/gsd doctor` to clear the stale session registration.",
|
|
82
|
+
unresolved_git_conflicts: "Resolve the conflict markers, commit, then re-run `/gsd auto`.",
|
|
83
|
+
conflict_markers_in_tracked_files: "Search the listed files for `<<<<<<<` markers, resolve, and commit.",
|
|
84
|
+
worktree_dirty: "Commit or merge the worktree's changes (`gsd worktree merge <name>`) before removing it.",
|
|
85
|
+
worktree_branch_merged: "The branch is merged — remove the worktree to reclaim space.",
|
|
86
|
+
orphaned_auto_worktree: "Run `/gsd doctor` to fix, or merge salvageable work with `gsd worktree merge <name>`.",
|
|
87
|
+
gitignore_missing_patterns: "Run `/gsd doctor` to append the missing .gitignore patterns.",
|
|
88
|
+
invalid_preferences: "Edit .gsd/PREFERENCES.md to fix the invalid field, then re-run the command.",
|
|
89
|
+
provider_key_missing: "Add the provider API key to your environment or provider config, then retry.",
|
|
90
|
+
provider_key_backedoff: "The key is cooling down after repeated failures — wait, or switch the phase model in .gsd/PREFERENCES.md.",
|
|
91
|
+
state_file_stale: "Run `/gsd doctor` to rebuild the projection from the database.",
|
|
92
|
+
state_file_missing: "Run `/gsd doctor` to rebuild the projection from the database.",
|
|
93
|
+
projection_drift: "Run `/gsd doctor` to rebuild markdown projections from the database (DB is the source of truth).",
|
|
94
|
+
uat_retry_exhausted: "Review the failing UAT criteria via `/gsd status`, fix the issue, then re-run `/gsd auto`.",
|
|
95
|
+
};
|
|
96
|
+
export function doctorFixHint(code) {
|
|
97
|
+
return DOCTOR_FIX_HINTS[code];
|
|
98
|
+
}
|
|
@@ -47,10 +47,10 @@ import { DISCUSS_TOOLS_ALLOWLIST } from "./constants.js";
|
|
|
47
47
|
import { getWorkflowTransportSupportError, getRequiredWorkflowToolsForGuidedUnit, supportsStructuredQuestions, } from "./workflow-mcp.js";
|
|
48
48
|
import { runPreparation, formatCodebaseBrief, formatPriorContextBrief, } from "./preparation.js";
|
|
49
49
|
import { verifyExpectedArtifact } from "./auto-recovery.js";
|
|
50
|
-
import { getPendingGate } from "./bootstrap/write-gate.js";
|
|
50
|
+
import { clearPendingGate, extractDepthVerificationMilestoneId, getPendingGate } from "./bootstrap/write-gate.js";
|
|
51
51
|
import { _getPendingAutoStart, deletePendingAutoStart, hasPendingAutoStart, setPendingAutoStart, } from "./pending-auto-start.js";
|
|
52
52
|
import { clearGuidedUnitContext, setGuidedUnitContext } from "./guided-unit-context.js";
|
|
53
|
-
import { scheduleAutoStartAfterIdle } from "./discussion-handoff.js";
|
|
53
|
+
import { checkAutoStartAfterDiscuss, scheduleAutoStartAfterIdle } from "./discussion-handoff.js";
|
|
54
54
|
export { maybeHandleEmptyIntentTurn, maybeHandleReadyPhraseWithoutFiles, resetEmptyTurnCounter, } from "./guided-unit-completion.js";
|
|
55
55
|
export { _getPendingAutoStart, clearPendingAutoStart, getDiscussionMilestoneId, setPendingAutoStart, } from "./pending-auto-start.js";
|
|
56
56
|
export { checkAutoStartAfterDiscuss } from "./discussion-handoff.js";
|
|
@@ -1529,6 +1529,21 @@ export async function showSmartEntry(ctx, pi, basePath, options) {
|
|
|
1529
1529
|
deletePendingAutoStart(basePath);
|
|
1530
1530
|
}
|
|
1531
1531
|
else {
|
|
1532
|
+
if (milestoneHasContext && !isAgentTurnInFlight(ctx)) {
|
|
1533
|
+
// The discussion already produced CONTEXT but the agent_end handoff
|
|
1534
|
+
// never consumed the entry — e.g. an external-engine post-hoc gate
|
|
1535
|
+
// re-arm wiped the depth verification after the save (write-gate
|
|
1536
|
+
// two-process sync). CONTEXT can only be written through a verified
|
|
1537
|
+
// depth gate, so a gate still pending for this milestone is stale:
|
|
1538
|
+
// clear it and re-run the handoff instead of dead-ending.
|
|
1539
|
+
const gateBasePath = entry.scope.workspace.projectRoot;
|
|
1540
|
+
const pendingGateId = getPendingGate(gateBasePath);
|
|
1541
|
+
if (pendingGateId && extractDepthVerificationMilestoneId(pendingGateId) === entry.milestoneId) {
|
|
1542
|
+
clearPendingGate(gateBasePath);
|
|
1543
|
+
}
|
|
1544
|
+
if (checkAutoStartAfterDiscuss(basePath))
|
|
1545
|
+
return;
|
|
1546
|
+
}
|
|
1532
1547
|
ctx.ui.notify("Discussion already in progress — answer the question above to continue.", "info");
|
|
1533
1548
|
return;
|
|
1534
1549
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { homedir } from "node:os";
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
|
+
import { isGsdBrowserMcpServerConfig } from "../shared/gsd-browser-cli.js";
|
|
4
5
|
import { toMcpWildcardToolName } from "./mcp-tool-name.js";
|
|
5
6
|
import { resolveModelMcpConfig } from "./preferences-mcp.js";
|
|
6
7
|
function isRecord(value) {
|
|
@@ -63,29 +64,11 @@ function isWorkflowMcpServerConfig(config) {
|
|
|
63
64
|
const args = Array.isArray(config.args) ? config.args.filter((arg) => typeof arg === "string") : [];
|
|
64
65
|
return args.some((arg) => arg.includes("gsd-mcp-server") || arg.includes("packages/mcp-server"));
|
|
65
66
|
}
|
|
66
|
-
function isBrowserMcpServerConfig(config) {
|
|
67
|
-
if (!isRecord(config))
|
|
68
|
-
return false;
|
|
69
|
-
const command = typeof config.command === "string" ? config.command : "";
|
|
70
|
-
if (command.includes("gsd-browser") || command.includes("@opengsd/gsd-browser")) {
|
|
71
|
-
return true;
|
|
72
|
-
}
|
|
73
|
-
const env = config.env;
|
|
74
|
-
if (isRecord(env)) {
|
|
75
|
-
if (typeof env.GSD_BROWSER_CLI_PATH === "string"
|
|
76
|
-
|| typeof env.GSD_BROWSER_BIN_PATH === "string"
|
|
77
|
-
|| typeof env.GSD_BROWSER_MCP_COMMAND === "string") {
|
|
78
|
-
return true;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
const args = Array.isArray(config.args) ? config.args.filter((arg) => typeof arg === "string") : [];
|
|
82
|
-
return args.some((arg) => arg.includes("gsd-browser") || arg.includes("@opengsd/gsd-browser"));
|
|
83
|
-
}
|
|
84
67
|
export function discoverWorkflowMcpServerName(projectDir) {
|
|
85
68
|
return discoverMcpServers(projectDir).find((server) => isWorkflowMcpServerConfig(server.config))?.name;
|
|
86
69
|
}
|
|
87
70
|
export function discoverBrowserMcpServerName(projectDir) {
|
|
88
|
-
return discoverMcpServers(projectDir).find((server) =>
|
|
71
|
+
return discoverMcpServers(projectDir).find((server) => isGsdBrowserMcpServerConfig(server.config))?.name;
|
|
89
72
|
}
|
|
90
73
|
export function discoverMcpServerNames(projectDir) {
|
|
91
74
|
return discoverMcpServers(projectDir).map((server) => server.name);
|
|
@@ -1,20 +1,12 @@
|
|
|
1
1
|
// Project/App: gsd-pi
|
|
2
|
-
// File Purpose:
|
|
2
|
+
// File Purpose: GSD-facing face over the shared @gsd/pi-ai MCP tool-name helpers.
|
|
3
|
+
import { parseMcpToolName as parsePiAiMcpToolName, stripMcpToolPrefix } from "@gsd/pi-ai";
|
|
3
4
|
const MCP_TOOL_PREFIX = "mcp__";
|
|
4
5
|
export function parseMcpToolName(toolName) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const toolSeparator = toolName.indexOf("__", MCP_TOOL_PREFIX.length);
|
|
8
|
-
if (toolSeparator < 0)
|
|
9
|
-
return null;
|
|
10
|
-
return {
|
|
11
|
-
serverName: toolName.slice(MCP_TOOL_PREFIX.length, toolSeparator),
|
|
12
|
-
toolName: toolName.slice(toolSeparator + 2),
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
export function stripMcpToolPrefix(toolName) {
|
|
16
|
-
return parseMcpToolName(toolName)?.toolName ?? toolName;
|
|
6
|
+
const parsed = parsePiAiMcpToolName(toolName);
|
|
7
|
+
return parsed ? { serverName: parsed.server, toolName: parsed.tool } : null;
|
|
17
8
|
}
|
|
9
|
+
export { stripMcpToolPrefix };
|
|
18
10
|
export function toMcpToolName(serverName, toolName) {
|
|
19
11
|
return `${MCP_TOOL_PREFIX}${serverName}__${toolName}`;
|
|
20
12
|
}
|
|
@@ -211,7 +211,7 @@ export function reportConsolidationGaps(basePath) {
|
|
|
211
211
|
const report = scanConsolidationGaps(basePath);
|
|
212
212
|
if (report.totalGaps === 0)
|
|
213
213
|
return report;
|
|
214
|
-
appendNotification(report.summary, "warning", "workflow-logger");
|
|
214
|
+
appendNotification(report.summary, "warning", "workflow-logger", { kind: "memory-consolidation" });
|
|
215
215
|
logWarning("memory-consolidation", report.summary);
|
|
216
216
|
return report;
|
|
217
217
|
}
|