gsd-pi 2.71.0 → 2.72.0-dev.de4c4b3
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 +57 -17
- package/dist/cli.js +29 -3
- package/dist/headless-events.d.ts +2 -0
- package/dist/headless-events.js +7 -0
- package/dist/headless.js +16 -3
- package/dist/mcp-server.js +40 -17
- package/dist/provider-migrations.d.ts +10 -0
- package/dist/provider-migrations.js +12 -0
- package/dist/resource-loader.js +139 -13
- package/dist/resources/GSD-WORKFLOW.md +1 -1
- package/dist/resources/agents/debugger.md +58 -0
- package/dist/resources/agents/doc-writer.md +43 -0
- package/dist/resources/agents/git-ops.md +56 -0
- package/dist/resources/agents/javascript-pro.md +46 -271
- package/dist/resources/agents/planner.md +55 -0
- package/dist/resources/agents/refactorer.md +47 -0
- package/dist/resources/agents/reviewer.md +48 -0
- package/dist/resources/agents/security.md +59 -0
- package/dist/resources/agents/tester.md +50 -0
- package/dist/resources/agents/typescript-pro.md +41 -235
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +113 -10
- package/dist/resources/extensions/gsd/auto/infra-errors.js +34 -0
- package/dist/resources/extensions/gsd/auto/loop.js +32 -1
- package/dist/resources/extensions/gsd/auto/phases.js +5 -1
- package/dist/resources/extensions/gsd/auto/session.js +11 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +22 -16
- package/dist/resources/extensions/gsd/auto-model-selection.js +10 -2
- package/dist/resources/extensions/gsd/auto-prompts.js +88 -33
- package/dist/resources/extensions/gsd/auto-start.js +34 -7
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +1 -1
- package/dist/resources/extensions/gsd/auto-worktree.js +1 -1
- package/dist/resources/extensions/gsd/auto.js +56 -0
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +3 -3
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +2 -0
- package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +63 -51
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +6 -0
- package/dist/resources/extensions/gsd/commands/context.js +15 -6
- package/dist/resources/extensions/gsd/commands/dispatcher.js +12 -2
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +10 -33
- package/dist/resources/extensions/gsd/commands/handlers/core.js +56 -11
- package/dist/resources/extensions/gsd/commands/handlers/notifications-handler.js +15 -6
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +4 -10
- package/dist/resources/extensions/gsd/dashboard-overlay.js +8 -3
- package/dist/resources/extensions/gsd/dispatch-guard.js +18 -1
- package/dist/resources/extensions/gsd/doctor-providers.js +23 -0
- package/dist/resources/extensions/gsd/error-classifier.js +5 -2
- package/dist/resources/extensions/gsd/forensics.js +19 -6
- package/dist/resources/extensions/gsd/gate-registry.js +208 -0
- package/dist/resources/extensions/gsd/gsd-db.js +41 -0
- package/dist/resources/extensions/gsd/guided-flow.js +5 -10
- package/dist/resources/extensions/gsd/metrics.js +1 -0
- package/dist/resources/extensions/gsd/milestone-actions.js +10 -4
- package/dist/resources/extensions/gsd/milestone-validation-gates.js +11 -12
- package/dist/resources/extensions/gsd/notification-overlay.js +42 -13
- package/dist/resources/extensions/gsd/notification-store.js +56 -5
- package/dist/resources/extensions/gsd/notification-widget.js +5 -13
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +8 -3
- package/dist/resources/extensions/gsd/pre-execution-checks.js +35 -2
- package/dist/resources/extensions/gsd/prompt-validation.js +126 -0
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +5 -3
- package/dist/resources/extensions/gsd/prompts/discuss.md +2 -0
- package/dist/resources/extensions/gsd/prompts/execute-task.md +22 -19
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +2 -0
- package/dist/resources/extensions/gsd/prompts/guided-resume-task.md +1 -1
- package/dist/resources/extensions/gsd/prompts/queue.md +3 -2
- package/dist/resources/extensions/gsd/prompts/system.md +1 -0
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +4 -1
- package/dist/resources/extensions/gsd/session-model-override.js +25 -0
- package/dist/resources/extensions/gsd/shortcut-defs.js +40 -0
- package/dist/resources/extensions/gsd/state.js +9 -2
- package/dist/resources/extensions/gsd/tools/complete-slice.js +52 -1
- package/dist/resources/extensions/gsd/tools/complete-task.js +51 -1
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +4 -1
- package/dist/resources/extensions/ollama/index.js +13 -5
- package/dist/resources/extensions/shared/gsd-phase-state.js +35 -0
- package/dist/resources/extensions/subagent/agents.js +8 -0
- package/dist/resources/extensions/subagent/index.js +17 -0
- package/dist/resources/skills/create-skill/SKILL.md +2 -0
- package/dist/startup-model-validation.d.ts +0 -1
- package/dist/startup-model-validation.js +6 -2
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/required-server-files.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- 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 +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
- 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 +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
- package/dist/web/standalone/.next/server/chunks/63.js +3 -3
- package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +2 -2
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-f1e30ab6bb269149.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/package.json +1 -1
- package/packages/mcp-server/dist/server.d.ts +12 -1
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +90 -42
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +22 -12
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/src/server.ts +110 -38
- package/packages/mcp-server/src/workflow-tools.test.ts +110 -0
- package/packages/mcp-server/src/workflow-tools.ts +32 -12
- package/packages/pi-ai/dist/providers/amazon-bedrock.js +11 -2
- package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-auth.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/anthropic-auth.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js +20 -0
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts +4 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.js +8 -3
- package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.test.js +44 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.test.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts +2 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +7 -4
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.js +11 -0
- package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/packages/pi-ai/src/providers/amazon-bedrock.ts +13 -1
- package/packages/pi-ai/src/providers/anthropic-auth.test.ts +32 -0
- package/packages/pi-ai/src/providers/anthropic-shared.test.ts +55 -1
- package/packages/pi-ai/src/providers/anthropic-shared.ts +14 -3
- package/packages/pi-ai/src/providers/anthropic.ts +8 -4
- package/packages/pi-ai/src/providers/openai-completions.ts +14 -0
- package/packages/pi-coding-agent/dist/core/agent-session-renderable-tools.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/agent-session-renderable-tools.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session-renderable-tools.test.js +61 -0
- package/packages/pi-coding-agent/dist/core/agent-session-renderable-tools.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +2 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +10 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +27 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js +85 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver-initial-model-auth.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/model-resolver-initial-model-auth.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver-initial-model-auth.test.js +64 -0
- package/packages/pi-coding-agent/dist/core/model-resolver-initial-model-auth.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js +22 -18
- package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.test.d.ts +8 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.test.js +75 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +5 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js +55 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js +57 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.d.ts +11 -0
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +38 -5
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/sdk.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/sdk.test.js +71 -0
- package/packages/pi-coding-agent/dist/core/sdk.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/login-dialog.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/login-dialog.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/login-dialog.test.js +13 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/login-dialog.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +24 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js +9 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +43 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +7 -2
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/model-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/model-controller.js +6 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/model-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +4 -3
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +4 -2
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-renderable-tools.test.ts +70 -0
- package/packages/pi-coding-agent/src/core/agent-session.ts +2 -1
- package/packages/pi-coding-agent/src/core/auth-storage.test.ts +108 -0
- package/packages/pi-coding-agent/src/core/auth-storage.ts +30 -0
- package/packages/pi-coding-agent/src/core/model-resolver-initial-model-auth.test.ts +78 -0
- package/packages/pi-coding-agent/src/core/model-resolver.test.ts +85 -0
- package/packages/pi-coding-agent/src/core/model-resolver.ts +22 -18
- package/packages/pi-coding-agent/src/core/retry-handler.test.ts +83 -0
- package/packages/pi-coding-agent/src/core/retry-handler.ts +60 -1
- package/packages/pi-coding-agent/src/core/sdk.test.ts +89 -0
- package/packages/pi-coding-agent/src/core/sdk.ts +45 -9
- package/packages/pi-coding-agent/src/index.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/login-dialog.test.ts +24 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/login-dialog.ts +30 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/model-selector.ts +15 -6
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +47 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +7 -2
- package/packages/pi-coding-agent/src/modes/interactive/controllers/model-controller.ts +6 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +4 -3
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +4 -2
- package/pkg/package.json +1 -1
- package/src/resources/GSD-WORKFLOW.md +1 -1
- package/src/resources/agents/debugger.md +58 -0
- package/src/resources/agents/doc-writer.md +43 -0
- package/src/resources/agents/git-ops.md +56 -0
- package/src/resources/agents/javascript-pro.md +46 -271
- package/src/resources/agents/planner.md +55 -0
- package/src/resources/agents/refactorer.md +47 -0
- package/src/resources/agents/reviewer.md +48 -0
- package/src/resources/agents/security.md +59 -0
- package/src/resources/agents/tester.md +50 -0
- package/src/resources/agents/typescript-pro.md +41 -235
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +122 -8
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +189 -6
- package/src/resources/extensions/gsd/auto/infra-errors.ts +38 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +2 -0
- package/src/resources/extensions/gsd/auto/loop.ts +45 -1
- package/src/resources/extensions/gsd/auto/phases.ts +6 -0
- package/src/resources/extensions/gsd/auto/session.ts +11 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +29 -18
- package/src/resources/extensions/gsd/auto-model-selection.ts +9 -1
- package/src/resources/extensions/gsd/auto-prompts.ts +111 -33
- package/src/resources/extensions/gsd/auto-start.ts +41 -7
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +1 -1
- package/src/resources/extensions/gsd/auto-worktree.ts +1 -1
- package/src/resources/extensions/gsd/auto.ts +72 -0
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +3 -3
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +2 -0
- package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +79 -60
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +7 -0
- package/src/resources/extensions/gsd/commands/context.ts +16 -5
- package/src/resources/extensions/gsd/commands/dispatcher.ts +14 -2
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +10 -36
- package/src/resources/extensions/gsd/commands/handlers/core.ts +58 -11
- package/src/resources/extensions/gsd/commands/handlers/notifications-handler.ts +17 -7
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +4 -10
- package/src/resources/extensions/gsd/dashboard-overlay.ts +10 -3
- package/src/resources/extensions/gsd/dispatch-guard.ts +18 -1
- package/src/resources/extensions/gsd/doctor-providers.ts +24 -0
- package/src/resources/extensions/gsd/error-classifier.ts +5 -2
- package/src/resources/extensions/gsd/forensics.ts +23 -7
- package/src/resources/extensions/gsd/gate-registry.ts +251 -0
- package/src/resources/extensions/gsd/gsd-db.ts +51 -0
- package/src/resources/extensions/gsd/guided-flow.ts +5 -10
- package/src/resources/extensions/gsd/interrupted-session.ts +1 -0
- package/src/resources/extensions/gsd/metrics.ts +12 -1
- package/src/resources/extensions/gsd/milestone-actions.ts +10 -3
- package/src/resources/extensions/gsd/milestone-validation-gates.ts +11 -13
- package/src/resources/extensions/gsd/notification-overlay.ts +47 -14
- package/src/resources/extensions/gsd/notification-store.ts +54 -5
- package/src/resources/extensions/gsd/notification-widget.ts +5 -14
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +10 -3
- package/src/resources/extensions/gsd/pre-execution-checks.ts +39 -2
- package/src/resources/extensions/gsd/prompt-validation.ts +157 -0
- package/src/resources/extensions/gsd/prompts/complete-slice.md +5 -3
- package/src/resources/extensions/gsd/prompts/discuss.md +2 -0
- package/src/resources/extensions/gsd/prompts/execute-task.md +22 -19
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +2 -0
- package/src/resources/extensions/gsd/prompts/guided-resume-task.md +1 -1
- package/src/resources/extensions/gsd/prompts/queue.md +3 -2
- package/src/resources/extensions/gsd/prompts/system.md +1 -0
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +4 -1
- package/src/resources/extensions/gsd/session-model-override.ts +36 -0
- package/src/resources/extensions/gsd/shortcut-defs.ts +56 -0
- package/src/resources/extensions/gsd/state.ts +13 -2
- package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +25 -9
- package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/complete-slice-gate-closure.test.ts +167 -0
- package/src/resources/extensions/gsd/tests/complete-slice-prompt-task-summary-layout.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/execute-task-prompt-existing-artifact-guard.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/forensics-stuck-loops.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/format-shortcut.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/gate-dispatch.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/gate-registry.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/gsd-no-project-error.test.ts +73 -0
- package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +180 -0
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +66 -1
- package/src/resources/extensions/gsd/tests/model-isolation.test.ts +36 -51
- package/src/resources/extensions/gsd/tests/notification-store.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/notification-widget.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/notifications-handler.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/prompt-system-gate-coverage.test.ts +208 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/register-shortcuts.test.ts +63 -5
- package/src/resources/extensions/gsd/tests/session-model-override.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/validate-milestone-prompt-verification-classes.test.ts +18 -0
- package/src/resources/extensions/gsd/tools/complete-slice.ts +63 -0
- package/src/resources/extensions/gsd/tools/complete-task.ts +63 -0
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +4 -1
- package/src/resources/extensions/gsd/types.ts +26 -0
- package/src/resources/extensions/ollama/index.ts +13 -3
- package/src/resources/extensions/ollama/ollama-status-indicator.test.ts +28 -0
- package/src/resources/extensions/shared/gsd-phase-state.ts +42 -0
- package/src/resources/extensions/shared/tests/gsd-phase-state.test.ts +48 -0
- package/src/resources/extensions/subagent/agents.ts +10 -0
- package/src/resources/extensions/subagent/index.ts +18 -0
- package/src/resources/extensions/subagent/tests/agents-conflicts.test.ts +33 -0
- package/src/resources/skills/create-skill/SKILL.md +2 -0
- package/dist/web/standalone/.next/static/chunks/app/page-7115e62689b5fd84.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
- /package/dist/web/standalone/.next/static/{nPky_WQC28aBD77eZsRAB → f-Gremw0nLxxFUySaHRPw}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{nPky_WQC28aBD77eZsRAB → f-Gremw0nLxxFUySaHRPw}/_ssgManifest.js +0 -0
package/README.md
CHANGED
|
@@ -27,36 +27,68 @@ One command. Walk away. Come back to a built project with clean git history.
|
|
|
27
27
|
|
|
28
28
|
---
|
|
29
29
|
|
|
30
|
-
## What's New in v2.
|
|
30
|
+
## What's New in v2.71
|
|
31
31
|
|
|
32
|
-
### MCP
|
|
32
|
+
### MCP Secure Env Collect
|
|
33
33
|
|
|
34
|
-
- **
|
|
35
|
-
- **
|
|
36
|
-
- **Write gate enforcement** — workflow MCP respects write gates, preventing unauthorized state mutations from external clients.
|
|
34
|
+
- **Secure credential collection over MCP** — the new `secure_env_collect` tool uses MCP form elicitation to collect secrets (API keys, tokens) from external clients without exposing values in tool output. Masks input in interactive mode.
|
|
35
|
+
- **Hardened elicitation schema** — MCP elicitation schema handling is stricter, with proper validation and fallback for providers that don't support forms.
|
|
37
36
|
|
|
38
|
-
### Reliability
|
|
37
|
+
### MCP Reliability
|
|
39
38
|
|
|
40
|
-
- **
|
|
41
|
-
- **
|
|
42
|
-
- **
|
|
43
|
-
- **Auto-resume hardening** — `autoStartTime` restored on resume, managed resources resynced on auto resume.
|
|
39
|
+
- **Stream ordering preserved** — MCP tool output now renders in the correct order, fixing interleaved output in Claude Code and other MCP clients.
|
|
40
|
+
- **isError flag propagation** — workflow tool execution failures now correctly return `isError: true`, so MCP clients can distinguish success from failure.
|
|
41
|
+
- **Multi-round discuss questions** — new-project discuss phase supports multi-round questioning with structured question gates.
|
|
44
42
|
|
|
45
|
-
###
|
|
43
|
+
### Model Selection Hardening
|
|
46
44
|
|
|
47
|
-
- **
|
|
48
|
-
- **
|
|
45
|
+
- **Unconfigured models blocked** — models without a configured provider are filtered from selection surfaces, preventing dispatch failures.
|
|
46
|
+
- **Provider readiness required** — saved default model selection now verifies the provider is ready before accepting it.
|
|
47
|
+
- **Session override honored** — `/gsd model` selection persists as a session override across all dispatch phases.
|
|
48
|
+
- **Minimal context guard** — model override logic is skipped in minimal command contexts where it doesn't apply.
|
|
49
49
|
|
|
50
|
-
###
|
|
50
|
+
### Auto-Mode Resilience
|
|
51
51
|
|
|
52
|
-
- **
|
|
53
|
-
- **
|
|
52
|
+
- **Credential cooldown recovery** — auto-mode survives transient 429 rate-limit responses with structured cooldown errors and a bounded retry budget.
|
|
53
|
+
- **Fire-and-forget auto start** — auto start is detached from active turns to prevent blocking.
|
|
54
|
+
- **Scoped forensics** — stuck-loop forensics are now scoped to auto sessions only, preventing false positives in interactive use.
|
|
55
|
+
|
|
56
|
+
### TUI Improvements
|
|
57
|
+
|
|
58
|
+
- **Overlay subscription fix** — resolved overlay subscription lifecycle and `Ctrl+Shift+P` shortcut conflict.
|
|
59
|
+
- **Improved overlays and shortcuts** — GSD overlays, keyboard shortcuts, and notification flows redesigned for consistency.
|
|
60
|
+
- **Pinned output restored** — pinned output bar displays above the editor during tool execution again.
|
|
61
|
+
- **Turn completion cleanup** — pinned latest output is cleared on turn completion, preventing stale output from persisting.
|
|
62
|
+
- **Secure input masking** — extension input values are masked in interactive mode when collecting secrets.
|
|
63
|
+
|
|
64
|
+
### Provider Fixes
|
|
65
|
+
|
|
66
|
+
- **Full OAuth login URLs** — OAuth login URLs are now displayed in full instead of being truncated.
|
|
67
|
+
- **MiniMax bearer auth** — MiniMax Anthropic API requests use proper bearer authentication.
|
|
68
|
+
- **Case-insensitive tool rendering** — renderable tool matching is now case-insensitive, fixing missed tool output.
|
|
69
|
+
- **Headless idle timeout** — idle timeout is kept off during interactive tool execution in headless mode.
|
|
70
|
+
|
|
71
|
+
### Reliability & Internals
|
|
72
|
+
|
|
73
|
+
- **TOCTOU file locking** — race conditions in event log and custom workflow graph file locking are fixed with proper atomic lock acquisition.
|
|
74
|
+
- **State derive refactor** — `deriveStateFromDb` god function extracted into composable, testable helpers.
|
|
75
|
+
- **Windows portability** — hardened cross-platform portability across runtime, tooling, and CI.
|
|
76
|
+
- **Model routing transparency** — dynamic routing is skipped for interactive dispatches; model changes are always shown in the banner.
|
|
77
|
+
- **Capability-aware routing (ADR-004)** — full implementation of capability scoring, `before_model_select` hook, and task metadata extraction.
|
|
78
|
+
- **Multi-model provider strategy (ADR-005)** — infrastructure for multi-provider model selection wired into live paths.
|
|
79
|
+
- **Anti-fabrication guardrails** — discuss prompts enforce turn-taking to prevent fabricated user responses.
|
|
80
|
+
- **Milestone worktree cleanup** — merged worktree cleanup uses the milestone branch instead of generic lookups.
|
|
81
|
+
- **Tool cache control** — `cache_control` breakpoints added to tool definitions for improved prompt caching.
|
|
54
82
|
|
|
55
83
|
See the full [Changelog](./CHANGELOG.md) for details on every release.
|
|
56
84
|
|
|
57
85
|
<details>
|
|
58
|
-
<summary>Previous highlights (v2.
|
|
86
|
+
<summary>Previous highlights (v2.70 and earlier)</summary>
|
|
59
87
|
|
|
88
|
+
- **Full workflow over MCP (v2.68)** — slice replanning, milestone management, slice completion, task completion, and core planning tools exposed over MCP
|
|
89
|
+
- **Transport-gated MCP (v2.68)** — workflow tool availability adapts to provider transport capabilities automatically
|
|
90
|
+
- **Contextual tips system (v2.68)** — TUI and web terminal surface contextual tips based on workflow state
|
|
91
|
+
- **Ask user questions over MCP (v2.70)** — interactive questions exposed via elicitation for external integrations
|
|
60
92
|
- **Tiered Context Injection (M005)** — relevance-scoped context with 65%+ token reduction
|
|
61
93
|
- **Resilient transient error recovery** — defers to Core RetryHandler and fixes cmdCtx race conditions
|
|
62
94
|
- **Anthropic subscription routing** — auto-routed through Claude Code CLI provider with proper display names
|
|
@@ -725,6 +757,14 @@ Use expensive models where quality matters (planning, complex execution) and che
|
|
|
725
757
|
|
|
726
758
|
---
|
|
727
759
|
|
|
760
|
+
## Ecosystem
|
|
761
|
+
|
|
762
|
+
| Project | Description |
|
|
763
|
+
| ------- | ----------- |
|
|
764
|
+
| [GSD2 Config Utility](https://github.com/jeremymcs/gsd2-config) | Standalone configuration tool for managing GSD preferences, providers, and API keys |
|
|
765
|
+
|
|
766
|
+
---
|
|
767
|
+
|
|
728
768
|
## Star History
|
|
729
769
|
|
|
730
770
|
<a href="https://star-history.com/#gsd-build/gsd-2&Date">
|
package/dist/cli.js
CHANGED
|
@@ -7,6 +7,7 @@ import { ensureManagedTools } from './tool-bootstrap.js';
|
|
|
7
7
|
import { loadStoredEnvKeys } from './wizard.js';
|
|
8
8
|
import { migratePiCredentials } from './pi-migration.js';
|
|
9
9
|
import { validateConfiguredModel } from './startup-model-validation.js';
|
|
10
|
+
import { shouldMigrateAnthropicToClaudeCode } from './provider-migrations.js';
|
|
10
11
|
import { shouldRunOnboarding, runOnboarding } from './onboarding.js';
|
|
11
12
|
import chalk from 'chalk';
|
|
12
13
|
import { checkForUpdates } from './update-check.js';
|
|
@@ -233,6 +234,14 @@ if (cliFlags.messages[0] === 'sessions') {
|
|
|
233
234
|
rl.question(chalk.bold(' Enter session number to resume (or q to quit): '), resolve);
|
|
234
235
|
});
|
|
235
236
|
rl.close();
|
|
237
|
+
// Clean up stdin state left by readline.createInterface().
|
|
238
|
+
// Without this, downstream TUI initialization gets corrupted listeners and exhibits
|
|
239
|
+
// duplicate terminal I/O. Match the pattern used after onboarding cleanup.
|
|
240
|
+
process.stdin.removeAllListeners('data');
|
|
241
|
+
process.stdin.removeAllListeners('keypress');
|
|
242
|
+
if (process.stdin.setRawMode)
|
|
243
|
+
process.stdin.setRawMode(false);
|
|
244
|
+
process.stdin.pause();
|
|
236
245
|
const choice = parseInt(answer, 10);
|
|
237
246
|
if (isNaN(choice) || choice < 1 || choice > toShow.length) {
|
|
238
247
|
process.stderr.write(chalk.dim('Cancelled.\n'));
|
|
@@ -285,7 +294,7 @@ const { resolveModelsJsonPath } = await import('./models-resolver.js');
|
|
|
285
294
|
const modelsJsonPath = resolveModelsJsonPath();
|
|
286
295
|
const modelRegistry = new ModelRegistry(authStorage, modelsJsonPath);
|
|
287
296
|
markStartup('ModelRegistry');
|
|
288
|
-
const settingsManager = SettingsManager.create(agentDir);
|
|
297
|
+
const settingsManager = SettingsManager.create(process.cwd(), agentDir);
|
|
289
298
|
applySecurityOverrides(settingsManager);
|
|
290
299
|
markStartup('SettingsManager.create');
|
|
291
300
|
// Run onboarding wizard on first launch (no LLM provider configured)
|
|
@@ -401,7 +410,11 @@ if (isPrintMode) {
|
|
|
401
410
|
// Migrate anthropic OAuth users to claude-code provider when CLI is available (#3772).
|
|
402
411
|
// Anthropic blocks third-party apps from using subscription quotas — routing through
|
|
403
412
|
// the local claude CLI binary is TOS-compliant.
|
|
404
|
-
if (
|
|
413
|
+
if (shouldMigrateAnthropicToClaudeCode({
|
|
414
|
+
authStorage,
|
|
415
|
+
isClaudeCodeReady: modelRegistry.isProviderRequestReady('claude-code'),
|
|
416
|
+
defaultProvider: settingsManager.getDefaultProvider(),
|
|
417
|
+
})) {
|
|
405
418
|
const currentModelId = settingsManager.getDefaultModel();
|
|
406
419
|
if (currentModelId) {
|
|
407
420
|
const ccModel = modelRegistry.find('claude-code', currentModelId);
|
|
@@ -466,6 +479,15 @@ if (isPrintMode) {
|
|
|
466
479
|
if (mode === 'mcp') {
|
|
467
480
|
printStartupTimings();
|
|
468
481
|
const { startMcpServer } = await import('./mcp-server.js');
|
|
482
|
+
// Activate every registered tool before starting the MCP transport.
|
|
483
|
+
// `session.agent.state.tools` is the *active* subset, not the full
|
|
484
|
+
// registry — if we expose only the active set, extension-registered
|
|
485
|
+
// tools (gsd workflow, browser-tools, mac-tools, search-the-web, …)
|
|
486
|
+
// are invisible to MCP clients. Flipping the active set to every
|
|
487
|
+
// known tool name makes `state.tools` mirror the full registry for
|
|
488
|
+
// this MCP session, which is what an external client expects.
|
|
489
|
+
const allToolNames = session.getAllTools().map((t) => t.name);
|
|
490
|
+
session.setActiveToolsByName(allToolNames);
|
|
469
491
|
await startMcpServer({
|
|
470
492
|
tools: session.agent.state.tools ?? [],
|
|
471
493
|
version: process.env.GSD_VERSION || '0.0.0',
|
|
@@ -576,7 +598,11 @@ markStartup('createAgentSession');
|
|
|
576
598
|
// Migrate anthropic OAuth users to claude-code provider when CLI is available (#3772).
|
|
577
599
|
// Anthropic blocks third-party apps from using subscription quotas — routing through
|
|
578
600
|
// the local claude CLI binary is TOS-compliant.
|
|
579
|
-
if (
|
|
601
|
+
if (shouldMigrateAnthropicToClaudeCode({
|
|
602
|
+
authStorage,
|
|
603
|
+
isClaudeCodeReady: modelRegistry.isProviderRequestReady('claude-code'),
|
|
604
|
+
defaultProvider: settingsManager.getDefaultProvider(),
|
|
605
|
+
})) {
|
|
580
606
|
const currentModelId = settingsManager.getDefaultModel();
|
|
581
607
|
if (currentModelId) {
|
|
582
608
|
const ccModel = modelRegistry.find('claude-code', currentModelId);
|
|
@@ -43,6 +43,8 @@ export declare const NEW_MILESTONE_IDLE_TIMEOUT_MS = 120000;
|
|
|
43
43
|
export declare function isTerminalNotification(event: Record<string, unknown>): boolean;
|
|
44
44
|
export declare function isBlockedNotification(event: Record<string, unknown>): boolean;
|
|
45
45
|
export declare function isMilestoneReadyNotification(event: Record<string, unknown>): boolean;
|
|
46
|
+
export declare function isInteractiveHeadlessTool(toolName: string | undefined): boolean;
|
|
47
|
+
export declare function shouldArmHeadlessIdleTimeout(toolCallCount: number, interactiveToolCount: number): boolean;
|
|
46
48
|
export declare const FIRE_AND_FORGET_METHODS: Set<string>;
|
|
47
49
|
export declare const QUICK_COMMANDS: Set<string>;
|
|
48
50
|
export declare function isQuickCommand(command: string): boolean;
|
package/dist/headless-events.js
CHANGED
|
@@ -65,6 +65,7 @@ export const IDLE_TIMEOUT_MS = 15_000;
|
|
|
65
65
|
// between tool calls (e.g. after mkdir, before writing files). Use a
|
|
66
66
|
// longer idle timeout to avoid killing the session prematurely (#808).
|
|
67
67
|
export const NEW_MILESTONE_IDLE_TIMEOUT_MS = 120_000;
|
|
68
|
+
const INTERACTIVE_HEADLESS_TOOLS = new Set(['ask_user_questions', 'secure_env_collect']);
|
|
68
69
|
export function isTerminalNotification(event) {
|
|
69
70
|
if (event.type !== 'extension_ui_request' || event.method !== 'notify')
|
|
70
71
|
return false;
|
|
@@ -83,6 +84,12 @@ export function isMilestoneReadyNotification(event) {
|
|
|
83
84
|
return false;
|
|
84
85
|
return /milestone\s+m\d+.*ready/i.test(String(event.message ?? ''));
|
|
85
86
|
}
|
|
87
|
+
export function isInteractiveHeadlessTool(toolName) {
|
|
88
|
+
return INTERACTIVE_HEADLESS_TOOLS.has(String(toolName ?? ''));
|
|
89
|
+
}
|
|
90
|
+
export function shouldArmHeadlessIdleTimeout(toolCallCount, interactiveToolCount) {
|
|
91
|
+
return toolCallCount > 0 && interactiveToolCount === 0;
|
|
92
|
+
}
|
|
86
93
|
// ---------------------------------------------------------------------------
|
|
87
94
|
// Quick Command Detection
|
|
88
95
|
// ---------------------------------------------------------------------------
|
package/dist/headless.js
CHANGED
|
@@ -17,7 +17,7 @@ import { resolve } from 'node:path';
|
|
|
17
17
|
import { RpcClient, SessionManager } from '@gsd/pi-coding-agent';
|
|
18
18
|
import { getProjectSessionsDir } from './project-sessions.js';
|
|
19
19
|
import { loadAndValidateAnswerFile, AnswerInjector } from './headless-answers.js';
|
|
20
|
-
import { isTerminalNotification, isBlockedNotification, isMilestoneReadyNotification, isQuickCommand, FIRE_AND_FORGET_METHODS, IDLE_TIMEOUT_MS, NEW_MILESTONE_IDLE_TIMEOUT_MS, EXIT_SUCCESS, EXIT_ERROR, EXIT_BLOCKED, EXIT_CANCELLED, mapStatusToExitCode, } from './headless-events.js';
|
|
20
|
+
import { isTerminalNotification, isBlockedNotification, isMilestoneReadyNotification, isQuickCommand, FIRE_AND_FORGET_METHODS, IDLE_TIMEOUT_MS, NEW_MILESTONE_IDLE_TIMEOUT_MS, isInteractiveHeadlessTool, shouldArmHeadlessIdleTimeout, EXIT_SUCCESS, EXIT_ERROR, EXIT_BLOCKED, EXIT_CANCELLED, mapStatusToExitCode, } from './headless-events.js';
|
|
21
21
|
import { VALID_OUTPUT_FORMATS } from './headless-types.js';
|
|
22
22
|
import { handleExtensionUIRequest, formatProgress, formatThinkingLine, formatTextStart, formatTextEnd, formatThinkingStart, formatThinkingEnd, startSupervisedStdinReader, } from './headless-ui.js';
|
|
23
23
|
import { loadContext, bootstrapGsdProject, } from './headless-context.js';
|
|
@@ -282,6 +282,7 @@ async function runHeadlessOnce(options, restartCount) {
|
|
|
282
282
|
let exitCode = 0;
|
|
283
283
|
let milestoneReady = false; // tracks "Milestone X ready." for auto-chaining
|
|
284
284
|
const recentEvents = [];
|
|
285
|
+
const interactiveToolCallIds = new Set();
|
|
285
286
|
// JSON batch mode: cost aggregation (cumulative-max pattern per K004)
|
|
286
287
|
let cumulativeCostUsd = 0;
|
|
287
288
|
let cumulativeInputTokens = 0;
|
|
@@ -365,7 +366,7 @@ async function runHeadlessOnce(options, restartCount) {
|
|
|
365
366
|
function resetIdleTimer() {
|
|
366
367
|
if (idleTimer)
|
|
367
368
|
clearTimeout(idleTimer);
|
|
368
|
-
if (toolCallCount
|
|
369
|
+
if (shouldArmHeadlessIdleTimeout(toolCallCount, interactiveToolCallIds.size)) {
|
|
369
370
|
idleTimer = setTimeout(() => {
|
|
370
371
|
completed = true;
|
|
371
372
|
resolveCompletion();
|
|
@@ -386,13 +387,25 @@ async function runHeadlessOnce(options, restartCount) {
|
|
|
386
387
|
client.onEvent((event) => {
|
|
387
388
|
const eventObj = event;
|
|
388
389
|
trackEvent(eventObj);
|
|
390
|
+
const eventType = String(eventObj.type ?? '');
|
|
391
|
+
if (eventType === 'tool_execution_start') {
|
|
392
|
+
const toolCallId = String(eventObj.toolCallId ?? eventObj.id ?? '');
|
|
393
|
+
if (toolCallId && isInteractiveHeadlessTool(String(eventObj.toolName ?? ''))) {
|
|
394
|
+
interactiveToolCallIds.add(toolCallId);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
else if (eventType === 'tool_execution_end') {
|
|
398
|
+
const toolCallId = String(eventObj.toolCallId ?? eventObj.id ?? '');
|
|
399
|
+
if (toolCallId) {
|
|
400
|
+
interactiveToolCallIds.delete(toolCallId);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
389
403
|
resetIdleTimer();
|
|
390
404
|
// Answer injector: observe events for question metadata
|
|
391
405
|
injector?.observeEvent(eventObj);
|
|
392
406
|
// --json / --output-format stream-json: forward events as JSONL to stdout (filtered if --events)
|
|
393
407
|
// --output-format json (batch mode): suppress streaming, track cost for final result
|
|
394
408
|
if (options.json && options.outputFormat === 'stream-json') {
|
|
395
|
-
const eventType = String(eventObj.type ?? '');
|
|
396
409
|
if (!options.eventFilter || options.eventFilter.has(eventType)) {
|
|
397
410
|
process.stdout.write(JSON.stringify(eventObj) + '\n');
|
|
398
411
|
}
|
package/dist/mcp-server.js
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
// MCP SDK subpath imports use wildcard exports (./*)
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
// MCP SDK subpath imports use wildcard exports (./*) in @modelcontextprotocol/sdk's
|
|
2
|
+
// package.json export map. The wildcard maps "./foo" → "./dist/cjs/foo" (no .js
|
|
3
|
+
// suffix), so bare subpath specifiers like `${MCP_PKG}/server/stdio` resolve to
|
|
4
|
+
// a non-existent file. Historically the workaround (#3603) used createRequire so
|
|
5
|
+
// the CJS resolver could auto-append `.js`; that no longer works with current
|
|
6
|
+
// Node + SDK releases (#3914) — `_require.resolve` also fails with
|
|
7
|
+
// "Cannot find module .../dist/cjs/server/stdio".
|
|
8
|
+
//
|
|
9
|
+
// The reliable convention (matching packages/mcp-server/{server,cli}.ts) is to
|
|
10
|
+
// write the `.js` suffix explicitly on every wildcard subpath. Specifiers are
|
|
11
|
+
// built via a template string so TypeScript's NodeNext resolver treats them as
|
|
12
|
+
// `any` and skips static checking.
|
|
8
13
|
const MCP_PKG = '@modelcontextprotocol/sdk';
|
|
9
14
|
/**
|
|
10
15
|
* Starts a native MCP (Model Context Protocol) server over stdin/stdout.
|
|
@@ -22,9 +27,9 @@ const MCP_PKG = '@modelcontextprotocol/sdk';
|
|
|
22
27
|
*/
|
|
23
28
|
export async function startMcpServer(options) {
|
|
24
29
|
const { tools, version = '0.0.0' } = options;
|
|
25
|
-
const serverMod = await import(`${MCP_PKG}/server`);
|
|
26
|
-
const stdioMod = await import(
|
|
27
|
-
const typesMod = await import(
|
|
30
|
+
const serverMod = await import(`${MCP_PKG}/server/index.js`);
|
|
31
|
+
const stdioMod = await import(`${MCP_PKG}/server/stdio.js`);
|
|
32
|
+
const typesMod = await import(`${MCP_PKG}/types.js`);
|
|
28
33
|
const Server = serverMod.Server;
|
|
29
34
|
const StdioServerTransport = stdioMod.StdioServerTransport;
|
|
30
35
|
const { ListToolsRequestSchema, CallToolRequestSchema } = typesMod;
|
|
@@ -42,8 +47,14 @@ export async function startMcpServer(options) {
|
|
|
42
47
|
inputSchema: t.parameters,
|
|
43
48
|
})),
|
|
44
49
|
}));
|
|
45
|
-
// tools/call — execute the requested tool and return content blocks
|
|
46
|
-
|
|
50
|
+
// tools/call — execute the requested tool and return content blocks.
|
|
51
|
+
//
|
|
52
|
+
// The MCP SDK passes an `extra` argument to request handlers that includes
|
|
53
|
+
// an AbortSignal scoped to the RPC request (cancelled when the client
|
|
54
|
+
// cancels the tool call or the transport closes). Threading it into
|
|
55
|
+
// AgentTool.execute ensures long-running tools (Bash, WebFetch, grep on
|
|
56
|
+
// huge trees) actually stop when the client gives up on the result.
|
|
57
|
+
server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
|
|
47
58
|
const { name, arguments: args } = request.params;
|
|
48
59
|
const tool = toolMap.get(name);
|
|
49
60
|
if (!tool) {
|
|
@@ -52,20 +63,32 @@ export async function startMcpServer(options) {
|
|
|
52
63
|
content: [{ type: 'text', text: `Unknown tool: ${name}` }],
|
|
53
64
|
};
|
|
54
65
|
}
|
|
66
|
+
const signal = extra?.signal;
|
|
55
67
|
try {
|
|
56
|
-
const result = await tool.execute(`mcp-${Date.now()}`, args ?? {},
|
|
57
|
-
|
|
58
|
-
//
|
|
68
|
+
const result = await tool.execute(`mcp-${Date.now()}`, args ?? {}, signal, undefined);
|
|
69
|
+
// Convert AgentToolResult content blocks to MCP content format.
|
|
70
|
+
// text and image pass through; any other shape is serialized as text
|
|
71
|
+
// so the client sees the payload rather than an empty response.
|
|
59
72
|
const content = result.content.map((block) => {
|
|
60
73
|
if (block.type === 'text')
|
|
61
74
|
return { type: 'text', text: block.text ?? '' };
|
|
62
|
-
if (block.type === 'image')
|
|
63
|
-
return {
|
|
75
|
+
if (block.type === 'image') {
|
|
76
|
+
return {
|
|
77
|
+
type: 'image',
|
|
78
|
+
data: block.data ?? '',
|
|
79
|
+
mimeType: block.mimeType ?? 'image/png',
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
// Preserve unknown block types (resource, resource_link, audio, ...)
|
|
83
|
+
// by stringifying into a text block so clients see the payload.
|
|
64
84
|
return { type: 'text', text: JSON.stringify(block) };
|
|
65
85
|
});
|
|
66
86
|
return { content };
|
|
67
87
|
}
|
|
68
88
|
catch (err) {
|
|
89
|
+
// AbortError from a cancelled tool surfaces as a normal error — MCP
|
|
90
|
+
// clients interpret `isError: true` as a failed call, which is the
|
|
91
|
+
// correct behaviour for a cancelled request.
|
|
69
92
|
const message = err instanceof Error ? err.message : String(err);
|
|
70
93
|
return { isError: true, content: [{ type: 'text', text: message }] };
|
|
71
94
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AuthStorage } from "@gsd/pi-coding-agent";
|
|
2
|
+
type AnthropicMigrationDeps = {
|
|
3
|
+
authStorage: Pick<AuthStorage, "getCredentialsForProvider">;
|
|
4
|
+
isClaudeCodeReady: boolean;
|
|
5
|
+
defaultProvider: string | undefined;
|
|
6
|
+
env?: NodeJS.ProcessEnv;
|
|
7
|
+
};
|
|
8
|
+
export declare function hasDirectAnthropicApiKey(authStorage: Pick<AuthStorage, "getCredentialsForProvider">, env?: NodeJS.ProcessEnv): boolean;
|
|
9
|
+
export declare function shouldMigrateAnthropicToClaudeCode({ authStorage, isClaudeCodeReady, defaultProvider, env, }: AnthropicMigrationDeps): boolean;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function hasDirectAnthropicApiKey(authStorage, env = process.env) {
|
|
2
|
+
if ((env.ANTHROPIC_API_KEY ?? "").trim()) {
|
|
3
|
+
return true;
|
|
4
|
+
}
|
|
5
|
+
return authStorage.getCredentialsForProvider("anthropic").some((credential) => credential?.type === "api_key" && typeof credential?.key === "string" && credential.key.trim().length > 0);
|
|
6
|
+
}
|
|
7
|
+
export function shouldMigrateAnthropicToClaudeCode({ authStorage, isClaudeCodeReady, defaultProvider, env = process.env, }) {
|
|
8
|
+
if (!isClaudeCodeReady || defaultProvider !== "anthropic") {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
return !hasDirectAnthropicApiKey(authStorage, env);
|
|
12
|
+
}
|
package/dist/resource-loader.js
CHANGED
|
@@ -2,7 +2,7 @@ import { DefaultResourceLoader, sortExtensionPaths } from '@gsd/pi-coding-agent'
|
|
|
2
2
|
import { createHash } from 'node:crypto';
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
4
|
import { chmodSync, copyFileSync, cpSync, existsSync, lstatSync, mkdirSync, openSync, closeSync, readFileSync, readlinkSync, readdirSync, rmSync, statSync, symlinkSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
5
|
-
import { dirname, join, relative, resolve } from 'node:path';
|
|
5
|
+
import { basename, dirname, join, relative, resolve } from 'node:path';
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
7
7
|
import { compareSemver } from './update-check.js';
|
|
8
8
|
import { discoverExtensionEntryPaths } from './extension-discovery.js';
|
|
@@ -254,34 +254,160 @@ function copyDirRecursive(src, dest) {
|
|
|
254
254
|
* ~/.gsd/agent/extensions/ have no ancestor node_modules, so imports of
|
|
255
255
|
* @gsd/* packages fail. The symlink makes Node's standard resolution find
|
|
256
256
|
* them without requiring every call site to use jiti.
|
|
257
|
+
*
|
|
258
|
+
* Layout differences by install method:
|
|
259
|
+
* - Source/monorepo: packageRoot/node_modules has everything → simple symlink
|
|
260
|
+
* - npm/bun global: deps hoisted to dirname(packageRoot), including @gsd/* → simple symlink
|
|
261
|
+
* - pnpm global: external deps hoisted, but @gsd/* stays in packageRoot/node_modules
|
|
262
|
+
* → merged directory with symlinks from both roots (#3529, #3564)
|
|
257
263
|
*/
|
|
258
264
|
function ensureNodeModulesSymlink(agentDir) {
|
|
259
265
|
const agentNodeModules = join(agentDir, 'node_modules');
|
|
260
|
-
const
|
|
266
|
+
const internalNodeModules = join(packageRoot, 'node_modules');
|
|
267
|
+
const hoistedNodeModules = dirname(packageRoot);
|
|
268
|
+
const isGlobalInstall = basename(hoistedNodeModules) === 'node_modules';
|
|
269
|
+
if (!isGlobalInstall) {
|
|
270
|
+
// Source/monorepo: internal node_modules has everything
|
|
271
|
+
reconcileSymlink(agentNodeModules, internalNodeModules);
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
// Global install: check if workspace scopes (@gsd/*) are hoisted.
|
|
275
|
+
// npm/bun hoist everything; pnpm keeps workspace packages internal.
|
|
276
|
+
if (!hasMissingWorkspaceScopes(hoistedNodeModules, internalNodeModules)) {
|
|
277
|
+
// Everything is hoisted — simple symlink to parent node_modules
|
|
278
|
+
reconcileSymlink(agentNodeModules, hoistedNodeModules);
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
// pnpm-style layout: create a real directory merging both roots
|
|
282
|
+
reconcileMergedNodeModules(agentNodeModules, hoistedNodeModules, internalNodeModules);
|
|
283
|
+
}
|
|
284
|
+
/** Check if any @gsd* scopes exist in internal but not in hoisted node_modules */
|
|
285
|
+
function hasMissingWorkspaceScopes(hoisted, internal) {
|
|
286
|
+
if (!existsSync(internal))
|
|
287
|
+
return false;
|
|
261
288
|
try {
|
|
262
|
-
const
|
|
289
|
+
for (const entry of readdirSync(internal, { withFileTypes: true })) {
|
|
290
|
+
if (entry.isDirectory() && entry.name.startsWith('@gsd') &&
|
|
291
|
+
!existsSync(join(hoisted, entry.name))) {
|
|
292
|
+
return true;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
catch { /* non-fatal */ }
|
|
297
|
+
return false;
|
|
298
|
+
}
|
|
299
|
+
/** Ensure a symlink at `link` points to `target`, fixing stale/wrong entries */
|
|
300
|
+
function reconcileSymlink(link, target) {
|
|
301
|
+
try {
|
|
302
|
+
const stat = lstatSync(link);
|
|
263
303
|
if (stat.isSymbolicLink()) {
|
|
264
|
-
const existing = readlinkSync(
|
|
265
|
-
|
|
266
|
-
if (existing === gsdNodeModules && existsSync(agentNodeModules))
|
|
304
|
+
const existing = readlinkSync(link);
|
|
305
|
+
if (existing === target && existsSync(link))
|
|
267
306
|
return; // correct and target exists
|
|
268
|
-
|
|
307
|
+
unlinkSync(link);
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
// Real directory (or merged dir from previous pnpm fix) — remove it
|
|
311
|
+
rmSync(link, { recursive: true, force: true });
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
catch {
|
|
315
|
+
// lstatSync throws if path doesn't exist — fine, we'll create below
|
|
316
|
+
}
|
|
317
|
+
try {
|
|
318
|
+
symlinkSync(target, link, 'junction');
|
|
319
|
+
}
|
|
320
|
+
catch (err) {
|
|
321
|
+
console.error(`[gsd] WARN: Failed to symlink ${link} → ${target}: ${err instanceof Error ? err.message : err}`);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Create a real node_modules directory containing symlinks from both the
|
|
326
|
+
* hoisted root (external deps) and internal root (@gsd/* workspace packages).
|
|
327
|
+
* Used for pnpm global installs where @gsd/* isn't hoisted.
|
|
328
|
+
*/
|
|
329
|
+
function reconcileMergedNodeModules(agentNodeModules, hoisted, internal) {
|
|
330
|
+
// Fast path: if already merged for this packageRoot + same directory contents, skip.
|
|
331
|
+
// The fingerprint includes entry names from both roots so `pnpm add/remove` triggers rebuild.
|
|
332
|
+
const marker = join(agentNodeModules, '.gsd-merged');
|
|
333
|
+
const fingerprint = mergedFingerprint(hoisted, internal);
|
|
334
|
+
try {
|
|
335
|
+
if (existsSync(marker) && readFileSync(marker, 'utf-8').trim() === fingerprint)
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
catch { /* rebuild */ }
|
|
339
|
+
// Remove any existing symlink or stale merged directory
|
|
340
|
+
try {
|
|
341
|
+
const stat = lstatSync(agentNodeModules);
|
|
342
|
+
if (stat.isSymbolicLink()) {
|
|
269
343
|
unlinkSync(agentNodeModules);
|
|
270
344
|
}
|
|
271
345
|
else {
|
|
272
|
-
// Real directory (not a symlink) is blocking — remove it
|
|
273
346
|
rmSync(agentNodeModules, { recursive: true, force: true });
|
|
274
347
|
}
|
|
275
348
|
}
|
|
276
|
-
catch {
|
|
277
|
-
|
|
349
|
+
catch { /* doesn't exist */ }
|
|
350
|
+
mkdirSync(agentNodeModules, { recursive: true });
|
|
351
|
+
let linkedCount = 0;
|
|
352
|
+
// Symlink entries from the hoisted node_modules (external deps)
|
|
353
|
+
try {
|
|
354
|
+
for (const entry of readdirSync(hoisted, { withFileTypes: true })) {
|
|
355
|
+
// Skip the gsd-pi package itself and dotfiles
|
|
356
|
+
if (entry.name === basename(packageRoot))
|
|
357
|
+
continue;
|
|
358
|
+
if (entry.name.startsWith('.'))
|
|
359
|
+
continue;
|
|
360
|
+
try {
|
|
361
|
+
symlinkSync(join(hoisted, entry.name), join(agentNodeModules, entry.name));
|
|
362
|
+
linkedCount++;
|
|
363
|
+
}
|
|
364
|
+
catch { /* skip individual */ }
|
|
365
|
+
}
|
|
278
366
|
}
|
|
367
|
+
catch (err) {
|
|
368
|
+
console.error(`[gsd] WARN: Failed to read hoisted node_modules at ${hoisted}: ${err instanceof Error ? err.message : err}`);
|
|
369
|
+
}
|
|
370
|
+
// Overlay internal node_modules entries that weren't hoisted.
|
|
371
|
+
// This covers @gsd/* workspace packages AND optional deps like
|
|
372
|
+
// @anthropic-ai/claude-agent-sdk that npm keeps internal.
|
|
279
373
|
try {
|
|
280
|
-
|
|
374
|
+
for (const entry of readdirSync(internal, { withFileTypes: true })) {
|
|
375
|
+
if (entry.name.startsWith('.'))
|
|
376
|
+
continue;
|
|
377
|
+
const link = join(agentNodeModules, entry.name);
|
|
378
|
+
// Replace hoisted symlink with internal version (internal takes precedence)
|
|
379
|
+
try {
|
|
380
|
+
lstatSync(link);
|
|
381
|
+
unlinkSync(link);
|
|
382
|
+
}
|
|
383
|
+
catch { /* didn't exist — will create below */ }
|
|
384
|
+
try {
|
|
385
|
+
symlinkSync(join(internal, entry.name), link);
|
|
386
|
+
linkedCount++;
|
|
387
|
+
}
|
|
388
|
+
catch { /* skip individual */ }
|
|
389
|
+
}
|
|
281
390
|
}
|
|
282
391
|
catch (err) {
|
|
283
|
-
|
|
284
|
-
|
|
392
|
+
console.error(`[gsd] WARN: Failed to read internal node_modules at ${internal}: ${err instanceof Error ? err.message : err}`);
|
|
393
|
+
}
|
|
394
|
+
// Only stamp marker if we actually linked something — avoids caching a broken state
|
|
395
|
+
if (linkedCount > 0) {
|
|
396
|
+
try {
|
|
397
|
+
writeFileSync(marker, fingerprint);
|
|
398
|
+
}
|
|
399
|
+
catch { /* non-fatal */ }
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
/** Build a cache fingerprint from packageRoot + sorted entry names of both directories */
|
|
403
|
+
function mergedFingerprint(hoisted, internal) {
|
|
404
|
+
try {
|
|
405
|
+
const h = readdirSync(hoisted).sort().join(',');
|
|
406
|
+
const i = readdirSync(internal).sort().join(',');
|
|
407
|
+
return `${packageRoot}\n${h}\n${i}`;
|
|
408
|
+
}
|
|
409
|
+
catch {
|
|
410
|
+
return packageRoot; // fallback: at least invalidate on version change
|
|
285
411
|
}
|
|
286
412
|
}
|
|
287
413
|
/**
|
|
@@ -275,7 +275,7 @@ Work flows through these phases. Each phase produces a file.
|
|
|
275
275
|
**How to do it manually:**
|
|
276
276
|
1. Read the roadmap to understand the scope.
|
|
277
277
|
2. Identify 3-5 gray areas — implementation decisions the user cares about.
|
|
278
|
-
3. Use `ask_user_questions` to discuss each area.
|
|
278
|
+
3. Use `ask_user_questions` to discuss each area, one round at a time. Never fabricate user input; wait for the user's actual response before the next round.
|
|
279
279
|
4. Write decisions to the appropriate context file (`M###-CONTEXT.md` or `S##-CONTEXT.md`).
|
|
280
280
|
5. Do NOT discuss how to implement — only what the user wants.
|
|
281
281
|
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: debugger
|
|
3
|
+
description: Hypothesis-driven bug investigation with root cause analysis
|
|
4
|
+
model: sonnet
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are a debugger. Investigate bugs using a systematic, hypothesis-driven approach. Your goal is to find the root cause, not just suppress symptoms.
|
|
8
|
+
|
|
9
|
+
## Process
|
|
10
|
+
|
|
11
|
+
1. **Reproduce**: Understand the symptoms — what happens vs. what should happen
|
|
12
|
+
2. **Hypothesize**: List 2-3 most likely causes based on symptoms
|
|
13
|
+
3. **Investigate**: For each hypothesis, gather evidence (read code, check logs, trace execution)
|
|
14
|
+
4. **Narrow**: Eliminate hypotheses that don't match the evidence
|
|
15
|
+
5. **Root cause**: Identify the actual cause with file:line references
|
|
16
|
+
6. **Fix**: Propose the minimal change that addresses the root cause
|
|
17
|
+
|
|
18
|
+
## Investigation Tools
|
|
19
|
+
|
|
20
|
+
- Read source files at specific line ranges
|
|
21
|
+
- Grep for error messages, function names, variable usage
|
|
22
|
+
- Check git blame for recent changes to suspect areas
|
|
23
|
+
- Read test files to understand expected behavior
|
|
24
|
+
- Run tests to reproduce failures
|
|
25
|
+
|
|
26
|
+
## Output Format
|
|
27
|
+
|
|
28
|
+
## Symptoms
|
|
29
|
+
|
|
30
|
+
What's happening vs. what's expected.
|
|
31
|
+
|
|
32
|
+
## Hypotheses
|
|
33
|
+
|
|
34
|
+
1. **[hypothesis]** — why this could be the cause
|
|
35
|
+
2. **[hypothesis]** — why this could be the cause
|
|
36
|
+
|
|
37
|
+
## Investigation
|
|
38
|
+
|
|
39
|
+
### Hypothesis 1: [name]
|
|
40
|
+
|
|
41
|
+
Evidence gathered, files read, what was found.
|
|
42
|
+
**Verdict:** Confirmed / Eliminated — reason.
|
|
43
|
+
|
|
44
|
+
### Hypothesis 2: [name]
|
|
45
|
+
|
|
46
|
+
(same structure)
|
|
47
|
+
|
|
48
|
+
## Root Cause
|
|
49
|
+
|
|
50
|
+
**File:** `path/to/file.ts:42`
|
|
51
|
+
**Cause:** Clear explanation of the bug.
|
|
52
|
+
**Why it wasn't caught:** Missing test, edge case, etc.
|
|
53
|
+
|
|
54
|
+
## Recommended Fix
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
// minimal fix with explanation
|
|
58
|
+
```
|