@opengsd/gsd-pi 1.0.2-dev.e70300c → 1.0.2-dev.fb7ddf1
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/README.md +63 -12
- package/dist/headless-answers.js +2 -1
- package/dist/headless-events.d.ts +1 -0
- package/dist/headless-events.js +8 -1
- package/dist/onboarding.js +22 -3
- package/dist/resource-loader.d.ts +7 -0
- package/dist/resource-loader.js +44 -9
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +34 -11
- package/dist/resources/extensions/context7/index.js +12 -2
- package/dist/resources/extensions/get-secrets-from-user.js +16 -16
- package/dist/resources/extensions/google-cli/index.js +30 -0
- package/dist/resources/extensions/google-cli/models.js +55 -0
- package/dist/resources/extensions/google-cli/package.json +11 -0
- package/dist/resources/extensions/google-cli/readiness.js +12 -0
- package/dist/resources/extensions/google-cli/stream-adapter.js +191 -0
- package/dist/resources/extensions/gsd/auto/loop.js +81 -1
- package/dist/resources/extensions/gsd/auto/orchestrator.js +4 -2
- package/dist/resources/extensions/gsd/auto/phases.js +38 -1
- package/dist/resources/extensions/gsd/auto/run-unit.js +8 -0
- package/dist/resources/extensions/gsd/auto/session.js +3 -0
- package/dist/resources/extensions/gsd/auto-dispatch.js +17 -7
- package/dist/resources/extensions/gsd/auto-post-unit.js +65 -16
- package/dist/resources/extensions/gsd/auto-prompts.js +5 -236
- package/dist/resources/extensions/gsd/auto-recovery.js +10 -5
- package/dist/resources/extensions/gsd/auto-start.js +232 -49
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +2 -1
- package/dist/resources/extensions/gsd/auto-verification.js +14 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +34 -1
- package/dist/resources/extensions/gsd/auto.js +40 -2
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +4 -3
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +7 -2
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +39 -5
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +107 -27
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +3 -27
- package/dist/resources/extensions/gsd/bootstrap/tool-search-shim.js +4 -4
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +1 -1
- package/dist/resources/extensions/gsd/closeout-recovery.js +7 -1
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +9 -1
- package/dist/resources/extensions/gsd/commands-handlers.js +3 -0
- package/dist/resources/extensions/gsd/commands-usage.js +105 -1
- package/dist/resources/extensions/gsd/config-overlay.js +20 -14
- package/dist/resources/extensions/gsd/context-overlay.js +22 -16
- package/dist/resources/extensions/gsd/dashboard-overlay.js +10 -23
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +87 -0
- package/dist/resources/extensions/gsd/doctor-git-checks.js +70 -5
- package/dist/resources/extensions/gsd/doctor-providers.js +54 -24
- package/dist/resources/extensions/gsd/doctor.js +7 -2
- package/dist/resources/extensions/gsd/git-conflict-state.js +26 -1
- package/dist/resources/extensions/gsd/guided-flow.js +5 -6
- package/dist/resources/extensions/gsd/key-manager.js +45 -13
- package/dist/resources/extensions/gsd/mcp-filter.js +57 -18
- package/dist/resources/extensions/gsd/mcp-project-config.js +15 -9
- package/dist/resources/extensions/gsd/migration-auto-check.js +5 -1
- package/dist/resources/extensions/gsd/milestone-actions.js +3 -0
- package/dist/resources/extensions/gsd/milestone-reopen-events.js +28 -0
- package/dist/resources/extensions/gsd/notification-overlay.js +8 -9
- package/dist/resources/extensions/gsd/parallel-merge.js +6 -4
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +15 -13
- package/dist/resources/extensions/gsd/post-execution-checks.js +5 -4
- package/dist/resources/extensions/gsd/preferences-skills.js +11 -4
- package/dist/resources/extensions/gsd/preferences.js +14 -2
- package/dist/resources/extensions/gsd/prompt-loader.js +2 -0
- package/dist/resources/extensions/gsd/prompts/discuss.md +4 -2
- package/dist/resources/extensions/gsd/prompts/gate-evaluate.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
- package/dist/resources/extensions/gsd/prompts/system.md +3 -20
- package/dist/resources/extensions/gsd/queue-reorder-ui.js +28 -18
- package/dist/resources/extensions/gsd/repo-identity.js +36 -6
- package/dist/resources/extensions/gsd/repository-registry.js +3 -1
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +13 -6
- package/dist/resources/extensions/gsd/skill-activation.js +233 -0
- package/dist/resources/extensions/gsd/skill-catalog.data.js +820 -0
- package/dist/resources/extensions/gsd/skill-catalog.install.js +179 -0
- package/dist/resources/extensions/gsd/skill-catalog.js +5 -1028
- package/dist/resources/extensions/gsd/skill-discovery.js +121 -79
- package/dist/resources/extensions/gsd/skill-scope.js +52 -0
- package/dist/resources/extensions/gsd/skill-telemetry.js +6 -39
- package/dist/resources/extensions/gsd/skills/gsd-headless/SKILL.md +1 -1
- package/dist/resources/extensions/gsd/skills.js +60 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +351 -0
- package/dist/resources/extensions/gsd/state-reconciliation/index.js +41 -0
- package/dist/resources/extensions/gsd/state-reconciliation/registry.js +4 -0
- package/dist/resources/extensions/gsd/tools/complete-task.js +9 -0
- package/dist/resources/extensions/gsd/tools/exec-tool.js +42 -8
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +63 -2
- package/dist/resources/extensions/gsd/tui/render-kit.js +51 -0
- package/dist/resources/extensions/gsd/unit-context-manifest.js +35 -26
- package/dist/resources/extensions/gsd/user-input-boundary.js +1 -1
- package/dist/resources/extensions/gsd/vision-ask.js +22 -0
- package/dist/resources/extensions/gsd/visualizer-overlay.js +8 -36
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +24 -3
- package/dist/resources/extensions/gsd/worktree-state-projection.js +29 -0
- package/dist/resources/extensions/search-the-web/native-search.js +57 -8
- package/dist/resources/extensions/shared/confirm-ui.js +9 -6
- package/dist/resources/extensions/shared/dialog-frame.js +42 -0
- package/dist/resources/extensions/shared/interview-ui.js +42 -30
- package/dist/resources/extensions/shared/next-action-ui.js +6 -6
- package/dist/resources/extensions/subagent/index.js +8 -15
- package/dist/resources/shared/package-manager-detection.js +36 -0
- package/dist/resources/skills/agent-browser/SKILL.md +1 -1
- package/dist/resources/skills/api-design/SKILL.md +1 -1
- package/dist/resources/skills/code-optimizer/SKILL.md +6 -11
- package/dist/resources/skills/create-gsd-extension/SKILL.md +1 -1
- package/dist/resources/skills/create-mcp-server/SKILL.md +1 -1
- package/dist/resources/skills/create-skill/references/gsd-skill-ecosystem.md +1 -1
- package/dist/resources/skills/create-skill/workflows/verify-skill.md +2 -10
- package/dist/resources/skills/debug-like-expert/references/when-to-research.md +1 -5
- package/dist/resources/skills/decompose-into-slices/SKILL.md +3 -3
- package/dist/resources/skills/dependency-upgrade/SKILL.md +1 -1
- package/dist/resources/skills/forensics/SKILL.md +2 -2
- package/dist/resources/skills/grill-me/SKILL.md +1 -1
- package/dist/resources/skills/handoff/SKILL.md +1 -1
- package/dist/resources/skills/make-interfaces-feel-better/SKILL.md +1 -1
- package/dist/resources/skills/observability/SKILL.md +1 -1
- package/dist/resources/skills/security-review/SKILL.md +1 -1
- package/dist/resources/skills/spike-wrap-up/SKILL.md +1 -1
- package/dist/resources/skills/tdd/SKILL.md +1 -1
- package/dist/resources/skills/write-docs/SKILL.md +1 -1
- package/dist/resources/skills/write-milestone-brief/SKILL.md +1 -1
- package/dist/update-check.d.ts +6 -2
- package/dist/update-check.js +7 -3
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +8 -8
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- 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/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 +8 -8
- package/dist/web/standalone/.next/server/chunks/1834.js +2 -2
- package/dist/web/standalone/.next/server/middleware-build-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/node_modules/node-pty/build/Makefile +1 -1
- package/package.json +5 -2
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/dist/rpc.test.js +5 -0
- package/packages/contracts/dist/rpc.test.js.map +1 -1
- package/packages/contracts/dist/workflow.d.ts +15 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js +16 -0
- package/packages/contracts/dist/workflow.js.map +1 -1
- package/packages/contracts/dist/workflow.test.js +1 -0
- package/packages/contracts/dist/workflow.test.js.map +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts +1 -0
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.js +22 -8
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.js.map +1 -1
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.d.ts +12 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.js +45 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.d.ts +3 -2
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.js +11 -11
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.d.ts +3 -3
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.js +13 -11
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.d.ts +3 -3
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.js +12 -10
- package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/index.d.ts +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/index.js +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/index.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.d.ts +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.js +2 -2
- package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.d.ts +6 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.js +9 -6
- package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- 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 +3 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +0 -2
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +2 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts +3 -0
- 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 +144 -2
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-session.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-session.js +2 -14
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-session.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +7 -1
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +13 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +47 -8
- 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/agent-loop.js +16 -14
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/harness/skills.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/harness/skills.js +6 -0
- package/packages/pi-agent-core/dist/harness/skills.js.map +1 -1
- package/packages/pi-agent-core/dist/harness/system-prompt.d.ts +7 -0
- package/packages/pi-agent-core/dist/harness/system-prompt.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/harness/system-prompt.js +7 -0
- package/packages/pi-agent-core/dist/harness/system-prompt.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +48 -206
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +67 -220
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +50 -0
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-responses-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-responses-shared.js +28 -4
- package/packages/pi-ai/dist/providers/openai-responses-shared.js.map +1 -1
- package/packages/pi-ai/dist/types.d.ts +2 -0
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/dist/utils/tests/tool-search-shim.test.js +29 -1
- package/packages/pi-ai/dist/utils/tests/tool-search-shim.test.js.map +1 -1
- package/packages/pi-ai/dist/utils/tool-search-shim.d.ts +4 -1
- package/packages/pi-ai/dist/utils/tool-search-shim.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/tool-search-shim.js +58 -10
- package/packages/pi-ai/dist/utils/tool-search-shim.js.map +1 -1
- package/packages/pi-ai/dist/utils/tool-shims.d.ts +1 -1
- package/packages/pi-ai/dist/utils/tool-shims.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/tool-shims.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/README.md +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts +2 -2
- package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js +8 -2
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.js +3 -0
- package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.js +5 -7
- package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.d.ts +2 -2
- package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.js +5 -4
- package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/write.js +0 -1
- package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
- package/packages/pi-coding-agent/package.json +8 -8
- package/packages/pi-tui/package.json +1 -1
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/scripts/install/detect-existing.js +17 -3
- package/scripts/install/npm-global.js +103 -33
- package/scripts/install.js +1 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +36 -11
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +86 -19
- package/src/resources/extensions/context7/index.ts +15 -2
- package/src/resources/extensions/get-secrets-from-user.ts +17 -16
- package/src/resources/extensions/google-cli/index.ts +34 -0
- package/src/resources/extensions/google-cli/models.ts +57 -0
- package/src/resources/extensions/google-cli/package.json +11 -0
- package/src/resources/extensions/google-cli/readiness.ts +15 -0
- package/src/resources/extensions/google-cli/stream-adapter.ts +245 -0
- package/src/resources/extensions/gsd/auto/loop.ts +96 -1
- package/src/resources/extensions/gsd/auto/orchestrator.ts +4 -2
- package/src/resources/extensions/gsd/auto/phases.ts +47 -1
- package/src/resources/extensions/gsd/auto/run-unit.ts +10 -0
- package/src/resources/extensions/gsd/auto/session.ts +3 -0
- package/src/resources/extensions/gsd/auto-dispatch.ts +31 -11
- package/src/resources/extensions/gsd/auto-post-unit.ts +101 -18
- package/src/resources/extensions/gsd/auto-prompts.ts +4 -284
- package/src/resources/extensions/gsd/auto-recovery.ts +10 -7
- package/src/resources/extensions/gsd/auto-start.ts +307 -56
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +3 -1
- package/src/resources/extensions/gsd/auto-verification.ts +18 -2
- package/src/resources/extensions/gsd/auto-worktree.ts +45 -1
- package/src/resources/extensions/gsd/auto.ts +50 -2
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +4 -3
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +9 -4
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +42 -5
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +124 -25
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +3 -28
- package/src/resources/extensions/gsd/bootstrap/tool-search-shim.ts +4 -4
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +1 -1
- package/src/resources/extensions/gsd/closeout-recovery.ts +6 -1
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +9 -1
- package/src/resources/extensions/gsd/commands-handlers.ts +2 -0
- package/src/resources/extensions/gsd/commands-usage.ts +110 -5
- package/src/resources/extensions/gsd/config-overlay.ts +19 -16
- package/src/resources/extensions/gsd/context-overlay.ts +24 -19
- package/src/resources/extensions/gsd/dashboard-overlay.ts +14 -27
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +99 -0
- package/src/resources/extensions/gsd/doctor-git-checks.ts +72 -5
- package/src/resources/extensions/gsd/doctor-providers.ts +55 -27
- package/src/resources/extensions/gsd/doctor-types.ts +2 -0
- package/src/resources/extensions/gsd/doctor.ts +7 -2
- package/src/resources/extensions/gsd/git-conflict-state.ts +25 -1
- package/src/resources/extensions/gsd/guided-flow.ts +5 -6
- package/src/resources/extensions/gsd/key-manager.ts +57 -14
- package/src/resources/extensions/gsd/mcp-filter.ts +64 -17
- package/src/resources/extensions/gsd/mcp-project-config.ts +24 -9
- package/src/resources/extensions/gsd/migration-auto-check.ts +6 -0
- package/src/resources/extensions/gsd/milestone-actions.ts +2 -0
- package/src/resources/extensions/gsd/milestone-reopen-events.ts +28 -0
- package/src/resources/extensions/gsd/notification-overlay.ts +12 -11
- package/src/resources/extensions/gsd/parallel-merge.ts +6 -4
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +16 -12
- package/src/resources/extensions/gsd/post-execution-checks.ts +7 -4
- package/src/resources/extensions/gsd/preferences-skills.ts +11 -4
- package/src/resources/extensions/gsd/preferences.ts +17 -2
- package/src/resources/extensions/gsd/prompt-loader.ts +2 -0
- package/src/resources/extensions/gsd/prompts/discuss.md +4 -2
- package/src/resources/extensions/gsd/prompts/gate-evaluate.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
- package/src/resources/extensions/gsd/prompts/system.md +3 -20
- package/src/resources/extensions/gsd/queue-reorder-ui.ts +29 -20
- package/src/resources/extensions/gsd/repo-identity.ts +35 -7
- package/src/resources/extensions/gsd/repository-registry.ts +3 -1
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +13 -6
- package/src/resources/extensions/gsd/skill-activation.ts +292 -0
- package/src/resources/extensions/gsd/skill-catalog.data.ts +858 -0
- package/src/resources/extensions/gsd/skill-catalog.install.ts +205 -0
- package/src/resources/extensions/gsd/skill-catalog.ts +16 -1087
- package/src/resources/extensions/gsd/skill-discovery.ts +134 -78
- package/src/resources/extensions/gsd/skill-scope.ts +63 -0
- package/src/resources/extensions/gsd/skill-telemetry.ts +6 -40
- package/src/resources/extensions/gsd/skills/gsd-headless/SKILL.md +1 -1
- package/src/resources/extensions/gsd/skills.ts +75 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +499 -0
- package/src/resources/extensions/gsd/state-reconciliation/index.ts +40 -0
- package/src/resources/extensions/gsd/state-reconciliation/registry.ts +8 -0
- package/src/resources/extensions/gsd/state-reconciliation/types.ts +30 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +328 -2
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/auto-post-unit-artifact-diagnostic.test.ts +28 -2
- package/src/resources/extensions/gsd/tests/auto-post-unit-evidence-crossref-4909.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +41 -0
- package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +24 -0
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +436 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-untracked-content.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/closeout-recovery.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/commands-context.test.ts +5 -3
- package/src/resources/extensions/gsd/tests/commands-dispatcher-workspace-git.test.ts +15 -2
- package/src/resources/extensions/gsd/tests/commands-usage.test.ts +97 -0
- package/src/resources/extensions/gsd/tests/complete-slice-reopen-handoff.test.ts +40 -3
- package/src/resources/extensions/gsd/tests/context-chart.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +64 -0
- package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/discord-invite-links.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/discuss-prompt.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/discuss-tool-scoping.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +71 -1
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +105 -0
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +101 -1
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/headless-answers.test.ts +22 -3
- package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +43 -0
- package/src/resources/extensions/gsd/tests/interactive-tool-idle-exemption.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/key-manager.test.ts +23 -4
- package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +19 -1
- package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +24 -0
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +56 -1
- package/src/resources/extensions/gsd/tests/notification-overlay.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +70 -10
- package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/park-milestone.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +127 -10
- package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +93 -0
- package/src/resources/extensions/gsd/tests/project-relocation-recovery.test.ts +101 -0
- package/src/resources/extensions/gsd/tests/queue-reorder-ui.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/register-extension-guard.test.ts +116 -11
- package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/repository-registry.test.ts +30 -1
- package/src/resources/extensions/gsd/tests/show-config-command.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/skill-discovery.test.ts +111 -0
- package/src/resources/extensions/gsd/tests/skill-scope-auto.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/skills.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +13 -2
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +303 -0
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +67 -1
- package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +24 -1
- package/src/resources/extensions/gsd/tests/tui-border-assertions.ts +28 -0
- package/src/resources/extensions/gsd/tests/tui-render-kit.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/vision-ask.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +6 -1
- package/src/resources/extensions/gsd/tests/workflow-mcp-auto-prep.test.ts +133 -0
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +82 -0
- package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +16 -1
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +38 -1
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +45 -1
- package/src/resources/extensions/gsd/tools/complete-task.ts +9 -0
- package/src/resources/extensions/gsd/tools/exec-tool.ts +42 -10
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +82 -5
- package/src/resources/extensions/gsd/tui/render-kit.ts +82 -0
- package/src/resources/extensions/gsd/unit-context-manifest.ts +37 -26
- package/src/resources/extensions/gsd/user-input-boundary.ts +1 -1
- package/src/resources/extensions/gsd/vision-ask.ts +28 -0
- package/src/resources/extensions/gsd/visualizer-overlay.ts +12 -40
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +37 -2
- package/src/resources/extensions/gsd/worktree-state-projection.ts +33 -0
- package/src/resources/extensions/search-the-web/native-search.ts +60 -8
- package/src/resources/extensions/shared/confirm-ui.ts +8 -12
- package/src/resources/extensions/shared/dialog-frame.ts +71 -0
- package/src/resources/extensions/shared/interview-ui.ts +43 -42
- package/src/resources/extensions/shared/next-action-ui.ts +6 -6
- package/src/resources/extensions/shared/tests/confirm-ui.test.ts +57 -0
- package/src/resources/extensions/shared/tests/interview-ui-border.test.ts +163 -0
- package/src/resources/extensions/shared/tests/next-action-ui-hasui.test.ts +55 -0
- package/src/resources/extensions/subagent/index.ts +8 -15
- package/src/resources/shared/package-manager-detection.ts +39 -0
- package/src/resources/skills/agent-browser/SKILL.md +1 -1
- package/src/resources/skills/api-design/SKILL.md +1 -1
- package/src/resources/skills/code-optimizer/SKILL.md +6 -11
- package/src/resources/skills/create-gsd-extension/SKILL.md +1 -1
- package/src/resources/skills/create-mcp-server/SKILL.md +1 -1
- package/src/resources/skills/create-skill/references/gsd-skill-ecosystem.md +1 -1
- package/src/resources/skills/create-skill/workflows/verify-skill.md +2 -10
- package/src/resources/skills/debug-like-expert/references/when-to-research.md +1 -5
- package/src/resources/skills/decompose-into-slices/SKILL.md +3 -3
- package/src/resources/skills/dependency-upgrade/SKILL.md +1 -1
- package/src/resources/skills/forensics/SKILL.md +2 -2
- package/src/resources/skills/grill-me/SKILL.md +1 -1
- package/src/resources/skills/handoff/SKILL.md +1 -1
- package/src/resources/skills/make-interfaces-feel-better/SKILL.md +1 -1
- package/src/resources/skills/observability/SKILL.md +1 -1
- package/src/resources/skills/security-review/SKILL.md +1 -1
- package/src/resources/skills/spike-wrap-up/SKILL.md +1 -1
- package/src/resources/skills/tdd/SKILL.md +1 -1
- package/src/resources/skills/write-docs/SKILL.md +1 -1
- package/src/resources/skills/write-milestone-brief/SKILL.md +1 -1
- /package/dist/web/standalone/.next/static/{szb-HAt0IoSx3docUZO-E → tH1tnDYt1E0hK9Ien73Z0}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{szb-HAt0IoSx3docUZO-E → tH1tnDYt1E0hK9Ien73Z0}/_ssgManifest.js +0 -0
|
@@ -135,6 +135,8 @@ import {
|
|
|
135
135
|
captureAvailableSkills,
|
|
136
136
|
resetSkillTelemetry,
|
|
137
137
|
} from "./skill-telemetry.js";
|
|
138
|
+
import { getInstalledSkillNames } from "./skills.js";
|
|
139
|
+
import { effectiveSkillNamesForUnit } from "./skill-scope.js";
|
|
138
140
|
import { getRtkSessionSavings } from "../shared/rtk-session-stats.js";
|
|
139
141
|
import { deactivateGSD } from "../shared/gsd-phase-state.js";
|
|
140
142
|
import {
|
|
@@ -216,7 +218,14 @@ import {
|
|
|
216
218
|
deregisterSigtermHandler as _deregisterSigtermHandler,
|
|
217
219
|
detectWorkingTreeActivity,
|
|
218
220
|
} from "./auto-supervisor.js";
|
|
219
|
-
import {
|
|
221
|
+
import {
|
|
222
|
+
isDbAvailable,
|
|
223
|
+
getMilestone,
|
|
224
|
+
getMilestoneSlices,
|
|
225
|
+
getSlice,
|
|
226
|
+
getTask,
|
|
227
|
+
refreshOpenDatabaseFromDisk,
|
|
228
|
+
} from "./gsd-db.js";
|
|
220
229
|
import { markLatestActiveForWorkerCanceled } from "./db/unit-dispatches.js";
|
|
221
230
|
import { writeUnitRuntimeRecord } from "./unit-runtime.js";
|
|
222
231
|
import { countPendingCaptures } from "./captures.js";
|
|
@@ -2068,6 +2077,25 @@ export function createWiredDispatchAdapter(
|
|
|
2068
2077
|
dispatchBasePath: string,
|
|
2069
2078
|
session?: AutoSession,
|
|
2070
2079
|
): DispatchAdapter {
|
|
2080
|
+
function getAlreadyClosedDispatchReason(unitType: string, unitId: string): string | null {
|
|
2081
|
+
if (!isDbAvailable()) return null;
|
|
2082
|
+
refreshOpenDatabaseFromDisk();
|
|
2083
|
+
const { milestone, slice, task } = parseUnitId(unitId);
|
|
2084
|
+
if (unitType === "execute-task" && milestone && slice && task) {
|
|
2085
|
+
const row = getTask(milestone, slice, task);
|
|
2086
|
+
return row && isClosedStatus(row.status)
|
|
2087
|
+
? `execute-task ${unitId} is already ${row.status}`
|
|
2088
|
+
: null;
|
|
2089
|
+
}
|
|
2090
|
+
if (unitType === "complete-slice" && milestone && slice) {
|
|
2091
|
+
const row = getSlice(milestone, slice);
|
|
2092
|
+
return row && isClosedStatus(row.status)
|
|
2093
|
+
? `complete-slice ${unitId} is already ${row.status}`
|
|
2094
|
+
: null;
|
|
2095
|
+
}
|
|
2096
|
+
return null;
|
|
2097
|
+
}
|
|
2098
|
+
|
|
2071
2099
|
return {
|
|
2072
2100
|
async decideNextUnit(input) {
|
|
2073
2101
|
const state = input.stateSnapshot;
|
|
@@ -2107,6 +2135,15 @@ export function createWiredDispatchAdapter(
|
|
|
2107
2135
|
const pendingRetry = session?.pendingVerificationRetryDispatch;
|
|
2108
2136
|
if (session && pendingRetry) {
|
|
2109
2137
|
session.pendingVerificationRetryDispatch = null;
|
|
2138
|
+
const alreadyClosedReason = getAlreadyClosedDispatchReason(
|
|
2139
|
+
pendingRetry.unitType,
|
|
2140
|
+
pendingRetry.unitId,
|
|
2141
|
+
);
|
|
2142
|
+
if (alreadyClosedReason) {
|
|
2143
|
+
session.pendingOrchestrationDispatch = null;
|
|
2144
|
+
session.pendingVerificationRetry = null;
|
|
2145
|
+
return { kind: "skipped", reason: alreadyClosedReason };
|
|
2146
|
+
}
|
|
2110
2147
|
session.pendingOrchestrationDispatch = pendingRetry;
|
|
2111
2148
|
return {
|
|
2112
2149
|
unitType: pendingRetry.unitType,
|
|
@@ -2144,6 +2181,14 @@ export function createWiredDispatchAdapter(
|
|
|
2144
2181
|
reason: action.matchedRule ?? "dispatch-skip",
|
|
2145
2182
|
};
|
|
2146
2183
|
}
|
|
2184
|
+
const alreadyClosedReason = getAlreadyClosedDispatchReason(action.unitType, action.unitId);
|
|
2185
|
+
if (alreadyClosedReason) {
|
|
2186
|
+
if (session) {
|
|
2187
|
+
session.pendingOrchestrationDispatch = null;
|
|
2188
|
+
session.pendingVerificationRetry = null;
|
|
2189
|
+
}
|
|
2190
|
+
return { kind: "skipped", reason: alreadyClosedReason };
|
|
2191
|
+
}
|
|
2147
2192
|
if (session) {
|
|
2148
2193
|
const pending: PendingOrchestrationDispatch = {
|
|
2149
2194
|
unitType: action.unitType,
|
|
@@ -2562,7 +2607,10 @@ function buildLoopDeps(pi: ExtensionAPI): LoopDeps {
|
|
|
2562
2607
|
autoCommitUnit,
|
|
2563
2608
|
recordOutcome,
|
|
2564
2609
|
writeLock,
|
|
2565
|
-
captureAvailableSkills
|
|
2610
|
+
captureAvailableSkills: () => {
|
|
2611
|
+
const unitType = s.currentUnit?.type;
|
|
2612
|
+
captureAvailableSkills(effectiveSkillNamesForUnit(unitType, getInstalledSkillNames()));
|
|
2613
|
+
},
|
|
2566
2614
|
ensurePreconditions,
|
|
2567
2615
|
updateSliceProgressCache,
|
|
2568
2616
|
|
|
@@ -715,8 +715,9 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
715
715
|
promptSnippet: "Complete a GSD task (DB write + summary render + checkbox toggle)",
|
|
716
716
|
promptGuidelines: [
|
|
717
717
|
"Use gsd_task_complete (or gsd_complete_task) when a task is finished and needs to be recorded.",
|
|
718
|
-
"
|
|
719
|
-
"
|
|
718
|
+
"Include verification whenever possible. If verification is omitted, the executor derives it from verificationEvidence when possible.",
|
|
719
|
+
"verificationEvidence is an array of objects with command, exitCode, verdict, durationMs.",
|
|
720
|
+
"The tool validates required fields and returns an error message if verification cannot be derived.",
|
|
720
721
|
"On success, returns the summaryPath where the SUMMARY.md was written.",
|
|
721
722
|
"Idempotent — calling with the same params twice will upsert (INSERT OR REPLACE) without error.",
|
|
722
723
|
],
|
|
@@ -727,7 +728,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
727
728
|
milestoneId: Type.String({ description: "Milestone ID (e.g. M001)" }),
|
|
728
729
|
oneLiner: Type.String({ description: "One-line summary of what was accomplished" }),
|
|
729
730
|
narrative: Type.String({ description: "Detailed narrative of what happened during the task" }),
|
|
730
|
-
verification: Type.String({ description: "What was verified and how — commands run, tests passed, behavior confirmed" }),
|
|
731
|
+
verification: Type.Optional(Type.String({ description: "What was verified and how — commands run, tests passed, behavior confirmed. If omitted, derived from verificationEvidence when possible." })),
|
|
731
732
|
// ── Enrichment metadata (optional — defaults to empty) ────────────
|
|
732
733
|
deviations: Type.Optional(Type.String({ description: "Deviations from the task plan, or 'None.'" })),
|
|
733
734
|
knownIssues: Type.Optional(Type.String({ description: "Known issues discovered but not fixed, or 'None.'" })),
|
|
@@ -43,11 +43,16 @@ export function registerExecTools(pi: ExtensionAPI): void {
|
|
|
43
43
|
"Need persisted output? Read the stdout_path returned in details (file on local disk).",
|
|
44
44
|
],
|
|
45
45
|
parameters: Type.Object({
|
|
46
|
-
runtime: Type.
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
runtime: Type.Optional(
|
|
47
|
+
Type.String({
|
|
48
|
+
description:
|
|
49
|
+
"Optional interpreter. Defaults to bash. Supported: bash, node, python; sh/shell, js/nodejs, and py/python3 aliases are accepted.",
|
|
50
|
+
}),
|
|
49
51
|
),
|
|
50
|
-
script: Type.String({ description: "Script body. Keep output small (log the finding, not the data)." }),
|
|
52
|
+
script: Type.Optional(Type.String({ description: "Script body. Keep output small (log the finding, not the data)." })),
|
|
53
|
+
command: Type.Optional(Type.String({ description: "Alias for script; defaults to bash when runtime is omitted." })),
|
|
54
|
+
cmd: Type.Optional(Type.String({ description: "Short alias for script." })),
|
|
55
|
+
code: Type.Optional(Type.String({ description: "Alias for script, useful for node/python snippets." })),
|
|
51
56
|
purpose: Type.Optional(Type.String({ description: "Short label recorded in meta.json for later review." })),
|
|
52
57
|
timeout_ms: Type.Optional(
|
|
53
58
|
Type.Number({
|
|
@@ -27,6 +27,32 @@ import { initCmuxEventListeners } from "../../cmux/index.js";
|
|
|
27
27
|
|
|
28
28
|
export { writeCrashLog } from "./crash-log.js";
|
|
29
29
|
|
|
30
|
+
// Pipe-closed storm guard. #99/#101 stopped EPIPE from flooding ~/.gsd/crash,
|
|
31
|
+
// but a persistently-broken output pipe whose `destroyed`/`writableEnded` flags
|
|
32
|
+
// never flip is still swallowed on every write — a tight, progress-free CPU
|
|
33
|
+
// spin. If the pipe-closed error fires in a tight loop the pipe is gone for
|
|
34
|
+
// good; exit cleanly instead.
|
|
35
|
+
const EPIPE_STORM_THRESHOLD = 100;
|
|
36
|
+
const EPIPE_STORM_WINDOW_MS = 10_000;
|
|
37
|
+
let epipeCount = 0;
|
|
38
|
+
let epipeWindowStart = 0;
|
|
39
|
+
|
|
40
|
+
/** Write to stderr without ever re-throwing — stderr can EPIPE too, which would
|
|
41
|
+
* re-enter this handler and re-loop. */
|
|
42
|
+
function safeStderr(msg: string): void {
|
|
43
|
+
try {
|
|
44
|
+
process.stderr.write(msg);
|
|
45
|
+
} catch { /* stderr is also broken; nothing we can do */ }
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** A peer closing the read end of a pipe mid-write surfaces differently per
|
|
49
|
+
* platform: POSIX throws `EPIPE`; Windows throws `Error: write EOF` (or
|
|
50
|
+
* `read EOF`) with no `code` set, from node:internal/stream_base_commons.
|
|
51
|
+
* Both are the same logical condition and must be treated as recoverable —
|
|
52
|
+
* otherwise the Windows EOF variant escapes to the uncaught-exception path
|
|
53
|
+
* and crashes auto-mode workers mid-iteration (#181). ECONNRESET is NOT
|
|
54
|
+
* included here: it commonly comes from network sockets (#182 follow-up) and
|
|
55
|
+
* is a real error that should surface rather than be silently swallowed. */
|
|
30
56
|
function isPipeClosedError(err: Error): boolean {
|
|
31
57
|
const errno = (err as NodeJS.ErrnoException).code;
|
|
32
58
|
if (errno === "EPIPE") return true;
|
|
@@ -36,7 +62,7 @@ function isPipeClosedError(err: Error): boolean {
|
|
|
36
62
|
|
|
37
63
|
export function handleRecoverableExtensionProcessError(err: Error): boolean {
|
|
38
64
|
if (err.message.includes("ProcessTransport is not ready for writing")) {
|
|
39
|
-
|
|
65
|
+
safeStderr(`[gsd] swallowed dead transport control write: ${err.message}\n`);
|
|
40
66
|
return true;
|
|
41
67
|
}
|
|
42
68
|
if (isPipeClosedError(err)) {
|
|
@@ -46,7 +72,18 @@ export function handleRecoverableExtensionProcessError(err: Error): boolean {
|
|
|
46
72
|
if (stdoutGone) {
|
|
47
73
|
process.exit(0);
|
|
48
74
|
}
|
|
49
|
-
|
|
75
|
+
const now = Date.now();
|
|
76
|
+
if (now - epipeWindowStart > EPIPE_STORM_WINDOW_MS) {
|
|
77
|
+
epipeWindowStart = now;
|
|
78
|
+
epipeCount = 0;
|
|
79
|
+
}
|
|
80
|
+
if (++epipeCount > EPIPE_STORM_THRESHOLD) {
|
|
81
|
+
safeStderr(
|
|
82
|
+
`[gsd] ${tag} storm (${epipeCount} within ${EPIPE_STORM_WINDOW_MS}ms) — output pipe is gone; exiting.\n`,
|
|
83
|
+
);
|
|
84
|
+
process.exit(0);
|
|
85
|
+
}
|
|
86
|
+
safeStderr(
|
|
50
87
|
`[gsd] swallowed ${tag} (syscall=${(err as NodeJS.ErrnoException).syscall ?? "?"})\n`,
|
|
51
88
|
);
|
|
52
89
|
return true;
|
|
@@ -54,18 +91,18 @@ export function handleRecoverableExtensionProcessError(err: Error): boolean {
|
|
|
54
91
|
if ((err as NodeJS.ErrnoException).code === "EIO") {
|
|
55
92
|
const syscall = (err as NodeJS.ErrnoException).syscall;
|
|
56
93
|
if (syscall === "read") {
|
|
57
|
-
|
|
94
|
+
safeStderr(`[gsd] EIO: ${err.message}\n`);
|
|
58
95
|
return true;
|
|
59
96
|
}
|
|
60
97
|
}
|
|
61
98
|
if ((err as NodeJS.ErrnoException).code === "ENOENT") {
|
|
62
99
|
const syscall = (err as NodeJS.ErrnoException).syscall;
|
|
63
100
|
if (syscall?.startsWith("spawn")) {
|
|
64
|
-
|
|
101
|
+
safeStderr(`[gsd] spawn ENOENT: ${(err as any).path ?? "unknown"} — command not found\n`);
|
|
65
102
|
return true;
|
|
66
103
|
}
|
|
67
104
|
if (syscall === "uv_cwd") {
|
|
68
|
-
|
|
105
|
+
safeStderr(`[gsd] ENOENT (${syscall}): ${err.message}\n`);
|
|
69
106
|
return true;
|
|
70
107
|
}
|
|
71
108
|
}
|
|
@@ -33,6 +33,7 @@ import { resolveWorktreeProjectRoot } from "../worktree-root.js";
|
|
|
33
33
|
import { extractSubagentAgentClasses } from "./subagent-input.js";
|
|
34
34
|
import { approvalGateIdForUnit, isExplicitApprovalResponse, shouldPauseForUserApprovalQuestion } from "../user-input-boundary.js";
|
|
35
35
|
import { resolveSkillManifest } from "../skill-manifest.js";
|
|
36
|
+
import { applyUnitSkillVisibility, unitHasSkillManifest } from "../skill-scope.js";
|
|
36
37
|
import { getGuidedUnitContext } from "../guided-unit-context.js";
|
|
37
38
|
import { registerPlanMilestoneSchemaRecovery } from "./plan-milestone-schema-recovery.js";
|
|
38
39
|
|
|
@@ -146,6 +147,53 @@ function withPreservedShimTools(toolNames: readonly string[]): string[] {
|
|
|
146
147
|
return [...new Set([...toolNames, ...ALWAYS_PRESERVED_SHIM_TOOL_NAMES])];
|
|
147
148
|
}
|
|
148
149
|
|
|
150
|
+
/**
|
|
151
|
+
* Backwards-compatibility workflow tool aliases (each forwards to a canonical
|
|
152
|
+
* twin). Mirrors WORKFLOW_TOOL_CONTRACTS[].aliases in @opengsd/contracts. These
|
|
153
|
+
* stay registered/callable but are dropped from the model-advertised tool set
|
|
154
|
+
* (~5.6K tokens/turn of duplicate schemas) — the canonical name is always
|
|
155
|
+
* advertised, and prompts/scoped tool sets already use canonical names.
|
|
156
|
+
*/
|
|
157
|
+
const WORKFLOW_ALIAS_TOOL_NAMES = new Set<string>([
|
|
158
|
+
"gsd_save_decision",
|
|
159
|
+
"gsd_update_requirement",
|
|
160
|
+
"gsd_save_requirement",
|
|
161
|
+
"gsd_generate_milestone_id",
|
|
162
|
+
"gsd_task_plan",
|
|
163
|
+
"gsd_slice_replan",
|
|
164
|
+
"gsd_complete_slice",
|
|
165
|
+
"gsd_milestone_complete",
|
|
166
|
+
"gsd_milestone_validate",
|
|
167
|
+
"gsd_roadmap_reassess",
|
|
168
|
+
"gsd_complete_task",
|
|
169
|
+
"gsd_reopen_task",
|
|
170
|
+
"gsd_reopen_slice",
|
|
171
|
+
"gsd_reopen_milestone",
|
|
172
|
+
]);
|
|
173
|
+
|
|
174
|
+
/** True when a (possibly mcp-scoped) tool name is a workflow alias. */
|
|
175
|
+
function isWorkflowAliasTool(toolName: string): boolean {
|
|
176
|
+
return WORKFLOW_ALIAS_TOOL_NAMES.has(canonicalToolName(toolName));
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** True for the ~58 Playwright browser tools (browser_navigate, browser_click, …). */
|
|
180
|
+
function isBrowserTool(toolName: string): boolean {
|
|
181
|
+
return canonicalToolName(toolName).startsWith("browser_");
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* True when any message in the request is driven by a GSD workflow command
|
|
186
|
+
* (customType starting "gsd-"). Plain interactive chat has none, and is scoped
|
|
187
|
+
* to the minimal GSD tool surface by default.
|
|
188
|
+
*/
|
|
189
|
+
export function requestHasGsdCustomType(
|
|
190
|
+
requestCustomMessages: readonly { customType?: string }[] | undefined,
|
|
191
|
+
): boolean {
|
|
192
|
+
return (requestCustomMessages ?? []).some(
|
|
193
|
+
(message) => typeof message.customType === "string" && message.customType.startsWith("gsd-"),
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
|
|
149
197
|
const RUN_UAT_BROWSER_TOOL_NAMES = [
|
|
150
198
|
"browser_navigate",
|
|
151
199
|
"browser_click",
|
|
@@ -178,6 +226,7 @@ const AUTO_UNIT_SCOPED_TOOLS: Record<string, readonly string[]> = {
|
|
|
178
226
|
"gsd_plan_milestone",
|
|
179
227
|
"gsd_milestone_generate_id",
|
|
180
228
|
],
|
|
229
|
+
"discuss-slice": ["gsd_summary_save", "gsd_decision_save"],
|
|
181
230
|
"validate-milestone": ["gsd_validate_milestone", "gsd_reassess_roadmap", "subagent"],
|
|
182
231
|
"complete-milestone": ["gsd_complete_milestone", "subagent"],
|
|
183
232
|
"research-slice": ["gsd_summary_save", "gsd_decision_save"],
|
|
@@ -213,7 +262,7 @@ function isGsdManagedTool(name: string): boolean {
|
|
|
213
262
|
*
|
|
214
263
|
* MCP-scoped names follow `mcp__<namespace>__<toolname>`.
|
|
215
264
|
* Example: if `requestedToolNames` contains `gsd_exec` and `activeToolNames` contains
|
|
216
|
-
* `
|
|
265
|
+
* `mcp__custom-workflow__gsd_exec`, the MCP-scoped active name is included in the result.
|
|
217
266
|
*
|
|
218
267
|
* Returns deduplicated active tool names that satisfy the requested base names.
|
|
219
268
|
*/
|
|
@@ -313,6 +362,16 @@ function isGeneralGsdToolScopingRequested(): boolean {
|
|
|
313
362
|
return process.env.PI_GSD_MINIMAL_TOOLS === "1";
|
|
314
363
|
}
|
|
315
364
|
|
|
365
|
+
/**
|
|
366
|
+
* Whether the ~58-tool Playwright browser surface (~7K tokens) should be
|
|
367
|
+
* advertised in interactive sessions. Off by default — browser tools stay
|
|
368
|
+
* registered/callable (so auto run-uat, which scopes them in explicitly, is
|
|
369
|
+
* unaffected) but are dropped from the model-facing surface until opted in.
|
|
370
|
+
*/
|
|
371
|
+
function isBrowserToolSurfaceRequested(): boolean {
|
|
372
|
+
return process.env.PI_GSD_BROWSER_TOOLS === "1";
|
|
373
|
+
}
|
|
374
|
+
|
|
316
375
|
export interface ScopedGsdWorkflowState {
|
|
317
376
|
tools: string[] | null;
|
|
318
377
|
visibleSkills: string[] | undefined;
|
|
@@ -357,8 +416,7 @@ export function scopeGsdWorkflowToolsForDispatch(
|
|
|
357
416
|
? buildMinimalAutoGsdToolSet(current, unitType, registeredToolNames)
|
|
358
417
|
: buildMinimalGsdWorkflowToolSet(current, registeredToolNames);
|
|
359
418
|
const toolsChanged = !(scoped.length === current.length && scoped.every((name, index) => name === current[index]));
|
|
360
|
-
const
|
|
361
|
-
const canScopeSkills = skillManifest !== null && pi.getVisibleSkills && pi.setVisibleSkills;
|
|
419
|
+
const canScopeSkills = unitHasSkillManifest(unitType) && pi.getVisibleSkills && pi.setVisibleSkills;
|
|
362
420
|
if (!toolsChanged && !canScopeSkills) {
|
|
363
421
|
return null;
|
|
364
422
|
}
|
|
@@ -366,8 +424,8 @@ export function scopeGsdWorkflowToolsForDispatch(
|
|
|
366
424
|
pi.setActiveTools(scoped);
|
|
367
425
|
}
|
|
368
426
|
const visibleSkills = canScopeSkills ? pi.getVisibleSkills!() : undefined;
|
|
369
|
-
if (canScopeSkills) {
|
|
370
|
-
pi.setVisibleSkills
|
|
427
|
+
if (canScopeSkills && pi.setVisibleSkills) {
|
|
428
|
+
applyUnitSkillVisibility({ setVisibleSkills: pi.setVisibleSkills }, unitType);
|
|
371
429
|
}
|
|
372
430
|
return {
|
|
373
431
|
tools: toolsChanged ? current : null,
|
|
@@ -507,6 +565,21 @@ function initSessionNotifications(ctx: ExtensionContext): void {
|
|
|
507
565
|
initNotificationWidget(ctx);
|
|
508
566
|
}
|
|
509
567
|
|
|
568
|
+
async function prepareWorkflowMcpForHookContext(
|
|
569
|
+
ctx: ExtensionContext,
|
|
570
|
+
basePath: string,
|
|
571
|
+
): Promise<void> {
|
|
572
|
+
// Skip MCP auto-prep when running inside an auto-worktree. The worktree
|
|
573
|
+
// already has .mcp.json from createAutoWorktree, and re-running the writer
|
|
574
|
+
// post-chdir rewrites the file mid-run (non-idempotent due to cwd-relative
|
|
575
|
+
// CLI path resolution), dirtying the tree and breaking the milestone merge.
|
|
576
|
+
const { isInAutoWorktree } = await import("../auto-worktree.js");
|
|
577
|
+
if (isInAutoWorktree(basePath)) return;
|
|
578
|
+
|
|
579
|
+
const { prepareWorkflowMcpForProject } = await import("../workflow-mcp-auto-prep.js");
|
|
580
|
+
prepareWorkflowMcpForProject(ctx, basePath);
|
|
581
|
+
}
|
|
582
|
+
|
|
510
583
|
export function registerHooks(
|
|
511
584
|
pi: ExtensionAPI,
|
|
512
585
|
ecosystemHandlers: GSDEcosystemBeforeAgentStartHandler[],
|
|
@@ -532,12 +605,7 @@ export function registerHooks(
|
|
|
532
605
|
await syncServiceTierStatus(ctx);
|
|
533
606
|
await applyDisabledModelProviderPolicy(ctx);
|
|
534
607
|
await applyCompactionThresholdOverride(ctx);
|
|
535
|
-
|
|
536
|
-
const { isInAutoWorktree } = await import("../auto-worktree.js");
|
|
537
|
-
if (!isInAutoWorktree(basePath)) {
|
|
538
|
-
const { prepareWorkflowMcpForProject } = await import("../workflow-mcp-auto-prep.js");
|
|
539
|
-
prepareWorkflowMcpForProject(ctx, basePath);
|
|
540
|
-
}
|
|
608
|
+
await prepareWorkflowMcpForHookContext(ctx, basePath);
|
|
541
609
|
|
|
542
610
|
// Apply show_token_cost preference (#1515)
|
|
543
611
|
try {
|
|
@@ -563,15 +631,7 @@ export function registerHooks(
|
|
|
563
631
|
await syncServiceTierStatus(ctx);
|
|
564
632
|
await applyDisabledModelProviderPolicy(ctx);
|
|
565
633
|
await applyCompactionThresholdOverride(ctx);
|
|
566
|
-
|
|
567
|
-
// already has .mcp.json from createAutoWorktree, and re-running the writer
|
|
568
|
-
// post-chdir rewrites the file mid-run (non-idempotent due to cwd-relative
|
|
569
|
-
// CLI path resolution), dirtying the tree and breaking the milestone merge.
|
|
570
|
-
const { isInAutoWorktree } = await import("../auto-worktree.js");
|
|
571
|
-
if (!isInAutoWorktree(basePath)) {
|
|
572
|
-
const { prepareWorkflowMcpForProject } = await import("../workflow-mcp-auto-prep.js");
|
|
573
|
-
prepareWorkflowMcpForProject(ctx, basePath);
|
|
574
|
-
}
|
|
634
|
+
await prepareWorkflowMcpForHookContext(ctx, basePath);
|
|
575
635
|
await loadToolApiKeysForSession();
|
|
576
636
|
if (!isAutoActive()) {
|
|
577
637
|
ctx.ui.setWidget("gsd-progress", undefined);
|
|
@@ -608,9 +668,26 @@ export function registerHooks(
|
|
|
608
668
|
}
|
|
609
669
|
clearDeferredApprovalGate(beforeAgentBasePath);
|
|
610
670
|
|
|
671
|
+
// session_start can fire before the active provider has settled. By
|
|
672
|
+
// before_agent_start, Claude Code CLI sessions should get the same
|
|
673
|
+
// project MCP config that /gsd mcp init would write.
|
|
674
|
+
await prepareWorkflowMcpForHookContext(ctx, beforeAgentBasePath);
|
|
675
|
+
|
|
676
|
+
let systemPrompt = event.systemPrompt;
|
|
677
|
+
const { appendDiscoveredSkillsFallback, hasSkillSnapshot, refreshCatalogForNewSkills } = await import("../skill-discovery.js");
|
|
678
|
+
if (hasSkillSnapshot()) {
|
|
679
|
+
const loadedSkills = await refreshCatalogForNewSkills({
|
|
680
|
+
reload: () => (ctx as ExtensionContext & { reload: () => Promise<void> }).reload(),
|
|
681
|
+
notify: (message, level) => ctx.ui.notify(message, level),
|
|
682
|
+
});
|
|
683
|
+
if (loadedSkills.length > 0) {
|
|
684
|
+
systemPrompt = appendDiscoveredSkillsFallback(ctx.getSystemPrompt(), loadedSkills);
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
|
|
611
688
|
// GSD's own context injection (existing behavior — unchanged).
|
|
612
689
|
const { buildBeforeAgentStartResult } = await import("./system-context.js");
|
|
613
|
-
const gsdResult = await buildBeforeAgentStartResult(event, ctx);
|
|
690
|
+
const gsdResult = await buildBeforeAgentStartResult({ ...event, systemPrompt }, ctx);
|
|
614
691
|
|
|
615
692
|
// Refresh the snapshot used by ecosystem getPhase()/getActiveUnit().
|
|
616
693
|
// deriveState has its own ~100ms cache so this is cheap on repeat calls.
|
|
@@ -623,7 +700,7 @@ export function registerHooks(
|
|
|
623
700
|
|
|
624
701
|
// Chain ecosystem handlers using pi's runner.ts chaining protocol:
|
|
625
702
|
// each handler sees the systemPrompt mutated by prior handlers.
|
|
626
|
-
let currentSystemPrompt = gsdResult?.systemPrompt ??
|
|
703
|
+
let currentSystemPrompt = gsdResult?.systemPrompt ?? systemPrompt;
|
|
627
704
|
// `any` because pi's BeforeAgentStartEventResult.message uses an internal
|
|
628
705
|
// CustomMessage type that's not re-exported (see ecosystem/gsd-extension-api.ts).
|
|
629
706
|
let lastMessage: any = gsdResult?.message;
|
|
@@ -1307,9 +1384,23 @@ export function registerHooks(
|
|
|
1307
1384
|
// Extensions can override tool set after model selection by returning { toolNames: [...] }
|
|
1308
1385
|
// Return undefined to let the built-in provider compatibility filtering proceed.
|
|
1309
1386
|
pi.on("adjust_tool_set", async (event) => {
|
|
1310
|
-
if (isFullGsdToolSurfaceRequested()) return undefined;
|
|
1311
1387
|
const removed = new Set(event.filteredTools);
|
|
1312
|
-
const
|
|
1388
|
+
const compatible = event.activeToolNames.filter((name) => !removed.has(name));
|
|
1389
|
+
// Always drop backwards-compatibility workflow aliases from the advertised
|
|
1390
|
+
// surface; they remain registered/callable but never cost schema tokens.
|
|
1391
|
+
// Drop the heavy browser surface too unless explicitly opted in — it stays
|
|
1392
|
+
// registered, so auto run-uat (which scopes browser tools in from the full
|
|
1393
|
+
// registry) still works. Both filters are skipped under full-tools mode.
|
|
1394
|
+
const fullToolsRequested = isFullGsdToolSurfaceRequested();
|
|
1395
|
+
const dropAliases = !fullToolsRequested;
|
|
1396
|
+
const dropBrowser = !fullToolsRequested && !isBrowserToolSurfaceRequested();
|
|
1397
|
+
const providerCompatible = compatible.filter(
|
|
1398
|
+
(name) => !(dropAliases && isWorkflowAliasTool(name)) && !(dropBrowser && isBrowserTool(name)),
|
|
1399
|
+
);
|
|
1400
|
+
const surfaceReduced = providerCompatible.length !== compatible.length;
|
|
1401
|
+
if (fullToolsRequested) {
|
|
1402
|
+
return surfaceReduced ? { toolNames: providerCompatible } : undefined;
|
|
1403
|
+
}
|
|
1313
1404
|
const registeredToolNames = resolveRegisteredToolNames(pi, event.activeToolNames);
|
|
1314
1405
|
const guidedUnit = getGuidedUnitContext();
|
|
1315
1406
|
const requestScoped = buildRequestScopedGsdToolSet(
|
|
@@ -1334,6 +1425,14 @@ export function registerHooks(
|
|
|
1334
1425
|
if (isGeneralGsdToolScopingRequested()) {
|
|
1335
1426
|
return { toolNames: buildMinimalGsdToolSet(providerCompatible) };
|
|
1336
1427
|
}
|
|
1337
|
-
|
|
1428
|
+
// Plain interactive chat (no GSD workflow command driving this request)
|
|
1429
|
+
// never needs the full ~50-tool workflow surface — scope it to the minimal
|
|
1430
|
+
// GSD set by default (all non-GSD tools are preserved). Requests carrying a
|
|
1431
|
+
// gsd-* customType keep their existing surface, so no command is stranded.
|
|
1432
|
+
// Set PI_GSD_FULL_TOOLS=1 (handled above) to restore the full surface.
|
|
1433
|
+
if (!requestHasGsdCustomType(event.requestCustomMessages)) {
|
|
1434
|
+
return { toolNames: buildMinimalGsdToolSet(providerCompatible) };
|
|
1435
|
+
}
|
|
1436
|
+
return surfaceReduced ? { toolNames: providerCompatible } : undefined;
|
|
1338
1437
|
});
|
|
1339
1438
|
}
|
|
@@ -11,11 +11,9 @@ import { loadPrompt, getTemplatesDir } from "../prompt-loader.js";
|
|
|
11
11
|
import { readForensicsMarker } from "../forensics.js";
|
|
12
12
|
import { resolveAllSkillReferences, renderPreferencesForSystemPrompt, loadEffectiveGSDPreferences } from "../preferences.js";
|
|
13
13
|
import { resolveModelWithFallbacksForUnit } from "../preferences-models.js";
|
|
14
|
-
import { resolveSkillReference } from "../preferences-skills.js";
|
|
15
14
|
import { resolveGsdRootFile, resolveSliceFile, resolveSlicePath, resolveTaskFile, resolveTaskFiles, resolveTasksDir, relSliceFile, relSlicePath, relTaskFile } from "../paths.js";
|
|
16
15
|
import { extractIntroAndRules } from "../knowledge-parser.js";
|
|
17
16
|
import { ensureCodebaseMapFresh, readCodebaseMap } from "../codebase-generator.js";
|
|
18
|
-
import { hasSkillSnapshot, detectNewSkills, formatSkillsXml } from "../skill-discovery.js";
|
|
19
17
|
import { getActiveAutoWorktreeContext } from "../auto-worktree.js";
|
|
20
18
|
import { getActiveWorktreeName, getWorktreeOriginalCwd } from "../worktree-session-state.js";
|
|
21
19
|
import { deriveState } from "../state.js";
|
|
@@ -72,20 +70,6 @@ export const BUNDLED_SKILL_TRIGGERS: Array<{ trigger: string; skill: string }> =
|
|
|
72
70
|
{ trigger: "Deep code optimization audit — perf anti-patterns, memory leaks, algorithmic complexity, bundle size, I/O, caching, dead code (parallel pattern-based hunt)", skill: "code-optimizer" },
|
|
73
71
|
];
|
|
74
72
|
|
|
75
|
-
function buildBundledSkillsTable(): string {
|
|
76
|
-
const cwd = process.cwd();
|
|
77
|
-
const rows: string[] = [];
|
|
78
|
-
for (const { trigger, skill } of BUNDLED_SKILL_TRIGGERS) {
|
|
79
|
-
const resolution = resolveSkillReference(skill, cwd);
|
|
80
|
-
if (resolution.method === "unresolved") continue; // skill not installed — omit from prompt
|
|
81
|
-
rows.push(`| ${trigger} | \`${resolution.resolvedPath}\` |`);
|
|
82
|
-
}
|
|
83
|
-
if (rows.length === 0) {
|
|
84
|
-
return "*No bundled skills found. Install or sync skills to `~/.gsd/agent/skills/`, `~/.agents/skills/`, or `~/.claude/skills/`.*";
|
|
85
|
-
}
|
|
86
|
-
return `| Trigger | Skill to load |\n|---|---|\n${rows.join("\n")}`;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
73
|
function warnDeprecatedAgentInstructions(): void {
|
|
90
74
|
const paths = [
|
|
91
75
|
join(gsdHome(), "agent-instructions.md"),
|
|
@@ -110,7 +94,6 @@ export async function buildBeforeAgentStartResult(
|
|
|
110
94
|
|
|
111
95
|
const stopContextTimer = debugTime("context-inject");
|
|
112
96
|
const systemContent = loadPrompt("system", {
|
|
113
|
-
bundledSkillsTable: buildBundledSkillsTable(),
|
|
114
97
|
templatesDir: getTemplatesDir(),
|
|
115
98
|
shortcutDashboard: formatShortcut("Ctrl+Alt+G"),
|
|
116
99
|
shortcutShell: formatShortcut("Ctrl+Alt+B"),
|
|
@@ -141,7 +124,7 @@ export async function buildBeforeAgentStartResult(
|
|
|
141
124
|
if (loadedPreferences) {
|
|
142
125
|
const cwd = basePath;
|
|
143
126
|
const report = resolveAllSkillReferences(loadedPreferences.preferences, cwd);
|
|
144
|
-
preferenceBlock = `\n\n${renderPreferencesForSystemPrompt(loadedPreferences.preferences, report.resolutions)}`;
|
|
127
|
+
preferenceBlock = `\n\n${renderPreferencesForSystemPrompt(loadedPreferences.preferences, report.resolutions, { includeResolvedPaths: false })}`;
|
|
145
128
|
if (report.warnings.length > 0) {
|
|
146
129
|
ctx.ui.notify(
|
|
147
130
|
`GSD skill preferences: ${report.warnings.length} unresolved skill${report.warnings.length === 1 ? "" : "s"}: ${report.warnings.join(", ")}`,
|
|
@@ -201,14 +184,6 @@ export async function buildBeforeAgentStartResult(
|
|
|
201
184
|
);
|
|
202
185
|
}
|
|
203
186
|
|
|
204
|
-
let newSkillsBlock = "";
|
|
205
|
-
if (hasSkillSnapshot()) {
|
|
206
|
-
const newSkills = detectNewSkills();
|
|
207
|
-
if (newSkills.length > 0) {
|
|
208
|
-
newSkillsBlock = formatSkillsXml(newSkills);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
187
|
let codebaseBlock = "";
|
|
213
188
|
try {
|
|
214
189
|
const codebaseOptions = loadedPreferences?.preferences?.codebase
|
|
@@ -264,13 +239,13 @@ export async function buildBeforeAgentStartResult(
|
|
|
264
239
|
// Keeping it out of `fullSystem` preserves provider prompt-cache stability
|
|
265
240
|
// for the static system/tool prefix. The dynamic memory block rides the
|
|
266
241
|
// volatile context message instead. (#5019)
|
|
267
|
-
const fullSystem = `${event.systemPrompt}\n\n[SYSTEM CONTEXT — GSD]\n\n${systemContent}${preferenceBlock}${knowledgeBlock}${codebaseBlock}${
|
|
242
|
+
const fullSystem = `${event.systemPrompt}\n\n[SYSTEM CONTEXT — GSD]\n\n${systemContent}${preferenceBlock}${knowledgeBlock}${codebaseBlock}${worktreeBlock}${subagentModelBlock}`;
|
|
268
243
|
|
|
269
244
|
stopContextTimer({
|
|
270
245
|
systemPromptSize: fullSystem.length,
|
|
271
246
|
injectionSize: injection?.length ?? forensicsInjection?.length ?? 0,
|
|
272
247
|
hasPreferences: preferenceBlock.length > 0,
|
|
273
|
-
hasNewSkills:
|
|
248
|
+
hasNewSkills: false,
|
|
274
249
|
});
|
|
275
250
|
|
|
276
251
|
const contextMessage = buildContextMessage({ memoryBlock, injection, forensicsInjection });
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// GSD does not implement Anthropic deferred-tool ToolSearch. Models trained on
|
|
2
|
-
// that API sometimes try `select:
|
|
2
|
+
// that API sometimes try `select:mcp__<server>__<tool>` and get a hard
|
|
3
3
|
// "Tool ToolSearch not found" failure. This shim returns explicit call guidance.
|
|
4
4
|
|
|
5
5
|
import { createToolSearchShimResult, Type } from "@gsd/pi-ai";
|
|
@@ -12,14 +12,14 @@ export function registerToolSearchShim(pi: ExtensionAPI): void {
|
|
|
12
12
|
name: "ToolSearch",
|
|
13
13
|
label: "Tool Search (guidance)",
|
|
14
14
|
description:
|
|
15
|
-
"Not supported in GSD.
|
|
16
|
-
"(e.g. gsd_save_gate_result or
|
|
15
|
+
"Not supported in GSD. If the needed workflow tool is active, invoke the exact listed tool name " +
|
|
16
|
+
"(e.g. gsd_save_gate_result, or the active MCP-scoped workflow name in Claude Code). Do not use ToolSearch.",
|
|
17
17
|
parameters: Type.Object({
|
|
18
18
|
query: Type.String({ description: "Ignored — use a direct tool call instead" }),
|
|
19
19
|
max_results: Type.Optional(Type.Number()),
|
|
20
20
|
}),
|
|
21
21
|
async execute(_toolCallId, params) {
|
|
22
|
-
return createToolSearchShimResult(params);
|
|
22
|
+
return createToolSearchShimResult(params, { activeToolNames: pi.getActiveTools() });
|
|
23
23
|
},
|
|
24
24
|
renderCall(args: any, theme: any) {
|
|
25
25
|
const q = args.query ?? "";
|
|
@@ -802,7 +802,7 @@ export function shouldBlockPlanningUnit(
|
|
|
802
802
|
if (!policy) return { block: false };
|
|
803
803
|
if (policy.mode === "all") return { block: false };
|
|
804
804
|
|
|
805
|
-
const tool = toolName;
|
|
805
|
+
const tool = canonicalToolName(toolName);
|
|
806
806
|
|
|
807
807
|
// Read-only mode: only Read-class tools are permitted.
|
|
808
808
|
if (policy.mode === "read-only") {
|
|
@@ -205,7 +205,12 @@ export function getCloseoutManualResolveBlocker(basePath: string): string | null
|
|
|
205
205
|
return `Unmerged paths remain in ${basePath}: ${conflictProbe.unmerged.slice(0, 5).join(", ")}`;
|
|
206
206
|
}
|
|
207
207
|
|
|
208
|
-
|
|
208
|
+
let status: string;
|
|
209
|
+
try {
|
|
210
|
+
status = runGit(basePath, ["status", "--porcelain"]);
|
|
211
|
+
} catch {
|
|
212
|
+
return `Could not inspect git status in ${basePath}.`;
|
|
213
|
+
}
|
|
209
214
|
if (status) {
|
|
210
215
|
return `Working tree still has uncommitted changes in ${basePath}. Commit, stash, or run /gsd closeout retry first.`;
|
|
211
216
|
}
|
|
@@ -208,7 +208,15 @@ export async function handleAutoCommand(trimmed: string, ctx: ExtensionCommandCo
|
|
|
208
208
|
|
|
209
209
|
if (trimmed === "") {
|
|
210
210
|
if (!(await guardRemoteSession(ctx, pi))) return true;
|
|
211
|
-
|
|
211
|
+
const basePath = projectRoot();
|
|
212
|
+
const { hasGsdBootstrapArtifacts } = await import("../../detection.js");
|
|
213
|
+
const { gsdRoot } = await import("../../paths.js");
|
|
214
|
+
if (!hasGsdBootstrapArtifacts(gsdRoot(basePath))) {
|
|
215
|
+
const { showSmartEntry } = await import("../../guided-flow.js");
|
|
216
|
+
await showSmartEntry(ctx, pi, basePath, { step: true });
|
|
217
|
+
return true;
|
|
218
|
+
}
|
|
219
|
+
if (await hasUnresolvedCloseoutBlocker(ctx, basePath)) return true;
|
|
212
220
|
const { showGsdHome } = await import("../../gsd-command-home.js");
|
|
213
221
|
await showGsdHome(ctx, pi, projectRoot());
|
|
214
222
|
return true;
|
|
@@ -26,6 +26,7 @@ import { isAutoActive, checkRemoteAutoSession } from "./auto.js";
|
|
|
26
26
|
import { getAutoWorktreePath } from "./auto-worktree.js";
|
|
27
27
|
import { currentDirectoryRoot, projectRoot } from "./commands/context.js";
|
|
28
28
|
import { loadPrompt } from "./prompt-loader.js";
|
|
29
|
+
import { isPnpmInstall } from "../../shared/package-manager-detection.js";
|
|
29
30
|
import {
|
|
30
31
|
buildDoctorHealIssuePayload,
|
|
31
32
|
buildDoctorHealSummary,
|
|
@@ -57,6 +58,7 @@ function isBunInstall(argv1: string | undefined = process.argv[1]): boolean {
|
|
|
57
58
|
|
|
58
59
|
function resolveInstallCommand(pkg: string): string {
|
|
59
60
|
if (isBunInstall()) return `bun add -g ${pkg}`;
|
|
61
|
+
if (isPnpmInstall()) return `pnpm add -g ${pkg}`;
|
|
60
62
|
return `npm install -g ${pkg}`;
|
|
61
63
|
}
|
|
62
64
|
|