@opengsd/gsd-pi 1.0.2-dev.e9a1b49 → 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 +36 -55
- 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-post-create-hook.js +117 -0
- 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/dist/worktree-cli.d.ts +0 -2
- package/dist/worktree-cli.js +21 -9
- package/package.json +5 -2
- package/packages/cloud-mcp-gateway/bin/gsd-cloud-mcp-gateway.js +14 -0
- package/packages/cloud-mcp-gateway/package.json +4 -3
- 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/bin/gsd-mcp-server.js +14 -0
- 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 +5 -4
- 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/bin/pi-ai.js +14 -0
- 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 +73 -226
- 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 +3 -2
- 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/deps.js +10 -0
- 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 +47 -57
- 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-post-create-hook.test.ts +141 -1
- 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-post-create-hook.ts +127 -0
- 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/tsconfig.extensions.tsbuildinfo +0 -1
- /package/dist/web/standalone/.next/static/{BEjZM0MLHLibeMFbjtMol → tH1tnDYt1E0hK9Ien73Z0}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{BEjZM0MLHLibeMFbjtMol → tH1tnDYt1E0hK9Ien73Z0}/_ssgManifest.js +0 -0
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
unlinkSync,
|
|
21
21
|
lstatSync as lstatSyncFn,
|
|
22
22
|
} from "node:fs";
|
|
23
|
-
import { isAbsolute, join, relative, resolve, sep as pathSep } from "node:path";
|
|
23
|
+
import { dirname, isAbsolute, join, relative, resolve, sep as pathSep } from "node:path";
|
|
24
24
|
import { GSDError, GSD_IO_ERROR, GSD_GIT_ERROR } from "./errors.js";
|
|
25
25
|
import {
|
|
26
26
|
reconcileWorktreeDb,
|
|
@@ -59,6 +59,8 @@ import { debugLog } from "./debug-logger.js";
|
|
|
59
59
|
import { logWarning, logError } from "./workflow-logger.js";
|
|
60
60
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
61
61
|
import { MILESTONE_ID_RE } from "./milestone-ids.js";
|
|
62
|
+
import { runWorktreePostCreateHook } from "./worktree-post-create-hook.js";
|
|
63
|
+
import { classifyProject } from "./detection.js";
|
|
62
64
|
import {
|
|
63
65
|
nativeGetCurrentBranch,
|
|
64
66
|
nativeDetectMainBranch,
|
|
@@ -258,6 +260,47 @@ export function _resolveAutoWorktreeStartPoint(
|
|
|
258
260
|
: undefined;
|
|
259
261
|
}
|
|
260
262
|
|
|
263
|
+
function importUntrackedProjectRootContentIntoEmptyWorktree(
|
|
264
|
+
projectRoot: string,
|
|
265
|
+
worktreeRoot: string,
|
|
266
|
+
milestoneId: string,
|
|
267
|
+
): number {
|
|
268
|
+
const worktreeClassification = classifyProject(worktreeRoot);
|
|
269
|
+
if (worktreeClassification.kind !== "greenfield") return 0;
|
|
270
|
+
|
|
271
|
+
const projectRootClassification = classifyProject(projectRoot);
|
|
272
|
+
if (
|
|
273
|
+
projectRootClassification.kind === "greenfield" ||
|
|
274
|
+
projectRootClassification.kind === "invalid-repo" ||
|
|
275
|
+
projectRootClassification.untrackedFiles.length === 0
|
|
276
|
+
) {
|
|
277
|
+
return 0;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
let copied = 0;
|
|
281
|
+
for (const relPath of projectRootClassification.untrackedFiles) {
|
|
282
|
+
const src = join(projectRoot, relPath);
|
|
283
|
+
if (!existsSync(src)) continue;
|
|
284
|
+
|
|
285
|
+
const dst = join(worktreeRoot, relPath);
|
|
286
|
+
if (existsSync(dst)) continue;
|
|
287
|
+
|
|
288
|
+
mkdirSync(dirname(dst), { recursive: true });
|
|
289
|
+
cpSync(src, dst, { recursive: true, force: false });
|
|
290
|
+
copied++;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (copied > 0) {
|
|
294
|
+
debugLog("createAutoWorktree", {
|
|
295
|
+
phase: "import-untracked-project-content",
|
|
296
|
+
milestoneId,
|
|
297
|
+
copied,
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return copied;
|
|
302
|
+
}
|
|
303
|
+
|
|
261
304
|
export function _shouldReconcileWorktreeDb(
|
|
262
305
|
worktreeDbPath: string,
|
|
263
306
|
mainDbPath: string,
|
|
@@ -912,62 +955,7 @@ export function syncWorktreeStateBack(
|
|
|
912
955
|
): { synced: string[] } {
|
|
913
956
|
return _finalizeProjectionForMergeImpl(mainBasePath, worktreePath, milestoneId);
|
|
914
957
|
}
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
/**
|
|
918
|
-
* Run the user-configured post-create hook script after worktree creation.
|
|
919
|
-
* The script receives SOURCE_DIR and WORKTREE_DIR as environment variables.
|
|
920
|
-
* Failure is non-fatal — returns the error message or null on success.
|
|
921
|
-
*
|
|
922
|
-
* Reads the hook path from git.worktree_post_create in preferences.
|
|
923
|
-
* Pass hookPath directly to bypass preference loading (useful for testing).
|
|
924
|
-
*/
|
|
925
|
-
export function runWorktreePostCreateHook(
|
|
926
|
-
sourceDir: string,
|
|
927
|
-
worktreeDir: string,
|
|
928
|
-
hookPath?: string,
|
|
929
|
-
): string | null {
|
|
930
|
-
if (hookPath === undefined) {
|
|
931
|
-
const prefs = loadEffectiveGSDPreferences()?.preferences?.git;
|
|
932
|
-
hookPath = prefs?.worktree_post_create;
|
|
933
|
-
}
|
|
934
|
-
if (!hookPath) return null;
|
|
935
|
-
|
|
936
|
-
// Resolve relative paths against the source project root.
|
|
937
|
-
// On Windows, convert 8.3 short paths (e.g. RUNNER~1) to long paths
|
|
938
|
-
// so execFileSync can locate the file correctly.
|
|
939
|
-
let resolved = isAbsolute(hookPath) ? hookPath : join(sourceDir, hookPath);
|
|
940
|
-
if (!existsSync(resolved)) {
|
|
941
|
-
return `Worktree post-create hook not found: ${resolved}`;
|
|
942
|
-
}
|
|
943
|
-
if (process.platform === "win32") {
|
|
944
|
-
try { resolved = realpathSync.native(resolved); } catch (err) { /* keep original */
|
|
945
|
-
logWarning("worktree", `realpath failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
946
|
-
}
|
|
947
|
-
}
|
|
948
|
-
|
|
949
|
-
try {
|
|
950
|
-
// .bat/.cmd files on Windows require shell mode — execFileSync cannot
|
|
951
|
-
// spawn them directly (EINVAL).
|
|
952
|
-
const needsShell = process.platform === "win32" && /\.(bat|cmd)$/i.test(resolved);
|
|
953
|
-
execFileSync(resolved, [], {
|
|
954
|
-
cwd: worktreeDir,
|
|
955
|
-
env: {
|
|
956
|
-
...process.env,
|
|
957
|
-
SOURCE_DIR: sourceDir,
|
|
958
|
-
WORKTREE_DIR: worktreeDir,
|
|
959
|
-
},
|
|
960
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
961
|
-
encoding: "utf-8",
|
|
962
|
-
timeout: 30_000, // 30 second timeout
|
|
963
|
-
shell: needsShell,
|
|
964
|
-
});
|
|
965
|
-
return null;
|
|
966
|
-
} catch (err) {
|
|
967
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
968
|
-
return `Worktree post-create hook failed: ${msg}`;
|
|
969
|
-
}
|
|
970
|
-
}
|
|
958
|
+
export { runWorktreePostCreateHook } from "./worktree-post-create-hook.js";
|
|
971
959
|
|
|
972
960
|
// ─── Auto-Worktree Branch Naming ───────────────────────────────────────────
|
|
973
961
|
|
|
@@ -1387,6 +1375,8 @@ export function createAutoWorktree(
|
|
|
1387
1375
|
// The original concerns (#759, #778) no longer apply because there is
|
|
1388
1376
|
// no second copy to drift.
|
|
1389
1377
|
|
|
1378
|
+
importUntrackedProjectRootContentIntoEmptyWorktree(basePath, info.path, milestoneId);
|
|
1379
|
+
|
|
1390
1380
|
// Run user-configured post-create hook (#597) — e.g. copy .env, symlink assets
|
|
1391
1381
|
const hookError = runWorktreePostCreateHook(basePath, info.path);
|
|
1392
1382
|
if (hookError) {
|
|
@@ -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
|
}
|