gsd-pi 2.78.0-dev.aeeb2ca00 → 2.78.1-dev.0fdacd524
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 +8 -7
- package/dist/bundled-resource-path.d.ts +7 -0
- package/dist/bundled-resource-path.js +34 -2
- package/dist/claude-cli-check.js +77 -38
- package/dist/cli-policy.d.ts +13 -0
- package/dist/cli-policy.js +17 -0
- package/dist/cli.js +95 -55
- package/dist/headless-query.d.ts +22 -0
- package/dist/headless-query.js +43 -8
- package/dist/headless.d.ts +10 -0
- package/dist/headless.js +16 -1
- package/dist/loader.js +9 -13
- package/dist/onboarding.d.ts +10 -0
- package/dist/onboarding.js +2 -2
- package/dist/provider-migrations.d.ts +2 -2
- package/dist/provider-migrations.js +5 -2
- package/dist/resource-loader.d.ts +5 -2
- package/dist/resource-loader.js +30 -13
- package/dist/resources/.managed-resources-content-hash +1 -0
- package/dist/resources/extensions/claude-code-cli/readiness.js +90 -46
- package/dist/resources/extensions/google-search/index.js +2 -6
- package/dist/resources/extensions/gsd/auto/loop.js +23 -0
- package/dist/resources/extensions/gsd/auto/phases.js +5 -13
- package/dist/resources/extensions/gsd/auto/run-unit.js +26 -12
- package/dist/resources/extensions/gsd/auto/session.js +5 -6
- package/dist/resources/extensions/gsd/auto-dashboard.js +3 -2
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +55 -21
- package/dist/resources/extensions/gsd/auto-dispatch.js +18 -6
- package/dist/resources/extensions/gsd/auto-prompts.js +69 -2
- package/dist/resources/extensions/gsd/auto-recovery.js +43 -4
- package/dist/resources/extensions/gsd/auto-runtime-state.js +31 -0
- package/dist/resources/extensions/gsd/auto-start.js +1 -1
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +2 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +60 -13
- package/dist/resources/extensions/gsd/auto.js +39 -14
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +14 -2
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +7 -5
- package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +5 -4
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +112 -31
- package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +11 -6
- package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +22 -0
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +45 -8
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +121 -3
- package/dist/resources/extensions/gsd/commands/catalog.js +76 -5
- package/dist/resources/extensions/gsd/commands/handlers/core.js +23 -1
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +8 -0
- package/dist/resources/extensions/gsd/commands-config.js +3 -2
- package/dist/resources/extensions/gsd/commands-extensions.js +46 -3
- package/dist/resources/extensions/gsd/commands-handlers.js +3 -2
- package/dist/resources/extensions/gsd/commands-mcp-status.js +3 -1
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +10 -1
- package/dist/resources/extensions/gsd/commands-worktree.js +309 -0
- package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -1
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -0
- package/dist/resources/extensions/gsd/doctor-providers.js +2 -1
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +39 -1
- package/dist/resources/extensions/gsd/error-classifier.js +1 -1
- package/dist/resources/extensions/gsd/forensics.js +10 -8
- package/dist/resources/extensions/gsd/git-service.js +12 -5
- package/dist/resources/extensions/gsd/gsd-db.js +11 -2
- package/dist/resources/extensions/gsd/guided-flow.js +25 -24
- package/dist/resources/extensions/gsd/home-dir.js +16 -0
- package/dist/resources/extensions/gsd/key-manager.js +2 -1
- package/dist/resources/extensions/gsd/memory-store.js +66 -31
- package/dist/resources/extensions/gsd/migrate/command.js +3 -2
- package/dist/resources/extensions/gsd/milestone-id-reservation.js +36 -0
- package/dist/resources/extensions/gsd/model-router.js +114 -9
- package/dist/resources/extensions/gsd/native-git-bridge.js +7 -1
- package/dist/resources/extensions/gsd/preferences-models.js +91 -15
- package/dist/resources/extensions/gsd/preferences-types.js +2 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +32 -0
- package/dist/resources/extensions/gsd/preferences.js +5 -3
- package/dist/resources/extensions/gsd/prompt-loader.js +23 -12
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +10 -0
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +10 -0
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
- package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +2 -0
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +10 -0
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +10 -0
- package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +2 -0
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +9 -3
- package/dist/resources/extensions/gsd/state.js +42 -0
- package/dist/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
- package/dist/resources/extensions/gsd/tools/memory-tools.js +18 -1
- package/dist/resources/extensions/gsd/unit-context-manifest.js +29 -4
- package/dist/resources/extensions/gsd/visualizer-overlay.js +1 -1
- package/dist/resources/extensions/gsd/watch/header-renderer.js +3 -1
- package/dist/resources/extensions/gsd/worktree-command.js +26 -46
- package/dist/resources/extensions/gsd/worktree-manager.js +20 -1
- package/dist/resources/extensions/gsd/worktree-resolver.js +4 -13
- package/dist/resources/extensions/gsd/worktree-root.js +124 -0
- package/dist/resources/extensions/gsd/worktree-session-state.js +33 -0
- package/dist/resources/extensions/gsd/worktree.js +4 -115
- package/dist/resources/extensions/mcp-client/index.js +6 -9
- package/dist/resources/extensions/ollama/index.js +15 -2
- package/dist/resources/extensions/ollama/model-capabilities.js +31 -0
- package/dist/resources/extensions/ollama/ollama-client.js +40 -4
- package/dist/resources/extensions/slash-commands/create-extension.js +36 -22
- package/dist/resources/extensions/subagent/index.js +324 -178
- package/dist/resources/skills/create-gsd-extension/SKILL.md +9 -5
- package/dist/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
- package/dist/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
- package/dist/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
- package/dist/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
- package/dist/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
- package/dist/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
- package/dist/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
- package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +32 -12
- package/dist/resources/skills/lint/SKILL.md +4 -0
- package/dist/resources/skills/review/SKILL.md +4 -0
- package/dist/resources/skills/test/SKILL.md +3 -0
- package/dist/rtk-shared.d.ts +3 -0
- package/dist/rtk-shared.js +17 -0
- package/dist/rtk.d.ts +2 -5
- package/dist/rtk.js +3 -20
- package/dist/runtime-checks.d.ts +27 -0
- package/dist/runtime-checks.js +38 -0
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +13 -13
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +44 -4
- 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_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 +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/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +4 -2
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +2 -2
- 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 +2 -2
- 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/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +13 -13
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/server/webpack-runtime.js +1 -1
- package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +1 -0
- package/dist/web/standalone/.next/static/chunks/2824.08296bc2f9654698.js +1 -0
- package/dist/web/standalone/.next/static/chunks/3026.3af53b279375f082.js +1 -0
- package/dist/web/standalone/.next/static/chunks/315.6f68ae79b67d25cf.js +1 -0
- package/dist/web/standalone/.next/static/chunks/3497.4bfc60a3b3dea717.js +1 -0
- package/dist/web/standalone/.next/static/chunks/5516.4a07c872b5c3a663.js +1 -0
- package/dist/web/standalone/.next/static/chunks/8336.31b019697882acfb.js +10 -0
- package/dist/web/standalone/.next/static/chunks/8845.c9702695e8c5a9c5.js +2 -0
- package/dist/web/standalone/.next/static/chunks/9058.01ef3a463bda88f1.js +20 -0
- package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/{page-5b113fd32bc2a1c3.js → page-9bf2e0c50fb2ca05.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/webpack-f9f0dc45e4f3ac10.js +1 -0
- package/dist/web/standalone/package.json +2 -1
- package/dist/welcome-screen.js +27 -1
- package/dist/worktree-cli.d.ts +1 -0
- package/dist/worktree-cli.js +9 -3
- package/dist/worktree-status-banner.d.ts +1 -0
- package/dist/worktree-status-banner.js +132 -0
- package/package.json +1 -3
- package/packages/daemon/package.json +2 -2
- package/packages/mcp-server/dist/alias-telemetry.d.ts +8 -0
- package/packages/mcp-server/dist/alias-telemetry.d.ts.map +1 -0
- package/packages/mcp-server/dist/alias-telemetry.js +30 -0
- package/packages/mcp-server/dist/alias-telemetry.js.map +1 -0
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +74 -46
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +2 -2
- package/packages/mcp-server/src/alias-telemetry.test.ts +78 -0
- package/packages/mcp-server/src/alias-telemetry.ts +30 -0
- package/packages/mcp-server/src/workflow-tools.test.ts +78 -0
- package/packages/mcp-server/src/workflow-tools.ts +93 -58
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/package.json +1 -1
- package/packages/native/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js +231 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.js +48 -19
- package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
- package/packages/pi-ai/dist/types.d.ts +13 -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/repair-tool-json.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/repair-tool-json.js +24 -3
- package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -1
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +26 -0
- package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-ai/src/providers/anthropic-shared.cache-breakpoint.test.ts +289 -0
- package/packages/pi-ai/src/providers/anthropic-shared.ts +52 -20
- package/packages/pi-ai/src/types.ts +13 -0
- package/packages/pi-ai/src/utils/repair-tool-json.ts +24 -3
- package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +32 -0
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +6 -0
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/messages.js +4 -0
- package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +19 -2
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts +10 -0
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +18 -0
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +13 -0
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +20 -16
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts +37 -0
- package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/token-telemetry.js +49 -0
- package/packages/pi-coding-agent/dist/core/token-telemetry.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +133 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +14 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js +78 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js +181 -0
- package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js.map +1 -0
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +7 -0
- package/packages/pi-coding-agent/src/core/messages.ts +4 -0
- package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +32 -2
- package/packages/pi-coding-agent/src/core/model-registry.ts +21 -0
- package/packages/pi-coding-agent/src/core/system-prompt.ts +33 -15
- package/packages/pi-coding-agent/src/core/token-telemetry.ts +77 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +212 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +17 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +1 -1
- package/packages/pi-coding-agent/src/tests/system-prompt-cache-stability.test.ts +102 -0
- package/packages/pi-coding-agent/src/tests/token-telemetry.test.ts +200 -0
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js +17 -3
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
- package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts +2 -0
- package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js +161 -0
- package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js.map +1 -0
- package/packages/pi-tui/package.json +1 -1
- package/packages/pi-tui/src/__tests__/autocomplete.test.ts +20 -3
- package/packages/pi-tui/src/components/__tests__/leak-fixes-runtime.test.ts +219 -0
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/packages/rpc-client/package.json +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/extensions/claude-code-cli/readiness.ts +92 -47
- package/src/resources/extensions/google-search/index.ts +2 -9
- package/src/resources/extensions/gsd/auto/loop.ts +24 -2
- package/src/resources/extensions/gsd/auto/phases.ts +6 -14
- package/src/resources/extensions/gsd/auto/run-unit.ts +26 -12
- package/src/resources/extensions/gsd/auto/session.ts +5 -6
- package/src/resources/extensions/gsd/auto/types.ts +1 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +3 -2
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +60 -24
- package/src/resources/extensions/gsd/auto-dispatch.ts +18 -6
- package/src/resources/extensions/gsd/auto-prompts.ts +66 -2
- package/src/resources/extensions/gsd/auto-recovery.ts +46 -8
- package/src/resources/extensions/gsd/auto-runtime-state.ts +51 -0
- package/src/resources/extensions/gsd/auto-start.ts +1 -1
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +2 -4
- package/src/resources/extensions/gsd/auto-worktree.ts +82 -12
- package/src/resources/extensions/gsd/auto.ts +37 -10
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +15 -13
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +8 -7
- package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +10 -9
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +121 -31
- package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +12 -6
- package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +20 -0
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +50 -8
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +141 -11
- package/src/resources/extensions/gsd/commands/catalog.ts +82 -5
- package/src/resources/extensions/gsd/commands/handlers/core.ts +23 -1
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +10 -0
- package/src/resources/extensions/gsd/commands-config.ts +3 -2
- package/src/resources/extensions/gsd/commands-extensions.ts +43 -3
- package/src/resources/extensions/gsd/commands-handlers.ts +3 -2
- package/src/resources/extensions/gsd/commands-mcp-status.ts +3 -1
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +15 -1
- package/src/resources/extensions/gsd/commands-worktree.ts +383 -0
- package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -1
- package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -0
- package/src/resources/extensions/gsd/doctor-providers.ts +2 -1
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +39 -1
- package/src/resources/extensions/gsd/doctor-types.ts +3 -1
- package/src/resources/extensions/gsd/error-classifier.ts +1 -1
- package/src/resources/extensions/gsd/forensics.ts +12 -7
- package/src/resources/extensions/gsd/git-service.ts +13 -5
- package/src/resources/extensions/gsd/gsd-db.ts +12 -2
- package/src/resources/extensions/gsd/guided-flow.ts +27 -26
- package/src/resources/extensions/gsd/home-dir.ts +19 -0
- package/src/resources/extensions/gsd/journal.ts +4 -1
- package/src/resources/extensions/gsd/key-manager.ts +2 -1
- package/src/resources/extensions/gsd/memory-store.ts +81 -28
- package/src/resources/extensions/gsd/migrate/command.ts +3 -2
- package/src/resources/extensions/gsd/milestone-id-reservation.ts +47 -0
- package/src/resources/extensions/gsd/model-router.ts +172 -9
- package/src/resources/extensions/gsd/native-git-bridge.ts +7 -1
- package/src/resources/extensions/gsd/preferences-models.ts +101 -15
- package/src/resources/extensions/gsd/preferences-types.ts +6 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +35 -0
- package/src/resources/extensions/gsd/preferences.ts +16 -2
- package/src/resources/extensions/gsd/prompt-loader.ts +26 -12
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +10 -0
- package/src/resources/extensions/gsd/prompts/complete-slice.md +10 -0
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
- package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +2 -0
- package/src/resources/extensions/gsd/prompts/plan-slice.md +10 -0
- package/src/resources/extensions/gsd/prompts/refine-slice.md +10 -0
- package/src/resources/extensions/gsd/prompts/rewrite-docs.md +2 -0
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +9 -3
- package/src/resources/extensions/gsd/state.ts +42 -0
- package/src/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +179 -1
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +58 -0
- package/src/resources/extensions/gsd/tests/auto-session-encapsulation.test.ts +24 -5
- package/src/resources/extensions/gsd/tests/auto-supervisor.test.mjs +21 -4
- package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/budget-prediction.test.ts +138 -211
- package/src/resources/extensions/gsd/tests/bundled-skill-triggers.test.ts +50 -27
- package/src/resources/extensions/gsd/tests/commands-extensions-version-compare.test.ts +58 -0
- package/src/resources/extensions/gsd/tests/commands-worktree-clean.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +142 -59
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +7 -4
- package/src/resources/extensions/gsd/tests/completed-at-reconcile.test.ts +89 -32
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +41 -23
- package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +3 -43
- package/src/resources/extensions/gsd/tests/debug-logger.test.ts +5 -3
- package/src/resources/extensions/gsd/tests/deferred-milestone-dir-4996.test.ts +116 -0
- package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +22 -87
- package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +7 -118
- package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +18 -60
- package/src/resources/extensions/gsd/tests/doctor-orphan-milestone-4996.test.ts +100 -0
- package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +14 -76
- package/src/resources/extensions/gsd/tests/ensure-preconditions-guard-4996.test.ts +93 -0
- package/src/resources/extensions/gsd/tests/false-degraded-mode-warning.test.ts +22 -83
- package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +1 -63
- package/src/resources/extensions/gsd/tests/find-missing-summaries-closed-runtime.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/forensics-stuck-loops.test.ts +26 -1
- package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +63 -0
- package/src/resources/extensions/gsd/tests/google-search-stub.test.ts +25 -65
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/gsd-no-project-error-runtime.test.ts +81 -0
- package/src/resources/extensions/gsd/tests/headless-answers.test.ts +14 -4
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +22 -12
- package/src/resources/extensions/gsd/tests/help-menu-coverage.test.ts +57 -0
- package/src/resources/extensions/gsd/tests/home-dir.test.ts +52 -0
- package/src/resources/extensions/gsd/tests/import-done-milestones-runtime.test.ts +145 -0
- package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +64 -1
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +72 -1
- package/src/resources/extensions/gsd/tests/integration/token-savings.test.ts +0 -23
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +128 -0
- package/src/resources/extensions/gsd/tests/memory-tools.test.ts +33 -1
- package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +124 -0
- package/src/resources/extensions/gsd/tests/milestone-id-gap-reuse-4996.test.ts +152 -0
- package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +18 -1
- package/src/resources/extensions/gsd/tests/model-router.test.ts +169 -8
- package/src/resources/extensions/gsd/tests/native-git-infra-errors.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +32 -43
- package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +4 -10
- package/src/resources/extensions/gsd/tests/preferences.test.ts +127 -0
- package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +6 -6
- package/src/resources/extensions/gsd/tests/register-hooks-compaction-checkpoint.test.ts +93 -0
- package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +168 -19
- package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +23 -1
- package/src/resources/extensions/gsd/tests/steer-worktree-path.test.ts +17 -1
- package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +101 -0
- package/src/resources/extensions/gsd/tests/token-profile.test.ts +51 -4
- package/src/resources/extensions/gsd/tests/turn-epoch.test.ts +7 -16
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +38 -3
- package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -7
- package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +15 -1
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +6 -6
- package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +235 -0
- package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +34 -33
- package/src/resources/extensions/gsd/tests/worktree.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +131 -1
- package/src/resources/extensions/gsd/tools/memory-tools.ts +17 -1
- package/src/resources/extensions/gsd/unit-context-manifest.ts +44 -12
- package/src/resources/extensions/gsd/visualizer-overlay.ts +1 -1
- package/src/resources/extensions/gsd/watch/header-renderer.ts +3 -1
- package/src/resources/extensions/gsd/workflow-logger.ts +1 -0
- package/src/resources/extensions/gsd/worktree-command.ts +31 -44
- package/src/resources/extensions/gsd/worktree-manager.ts +40 -1
- package/src/resources/extensions/gsd/worktree-resolver.ts +4 -14
- package/src/resources/extensions/gsd/worktree-root.ts +144 -0
- package/src/resources/extensions/gsd/worktree-session-state.ts +35 -0
- package/src/resources/extensions/gsd/worktree.ts +8 -119
- package/src/resources/extensions/mcp-client/index.ts +6 -10
- package/src/resources/extensions/mcp-client/tests/global-config.test.ts +91 -0
- package/src/resources/extensions/ollama/index.ts +16 -2
- package/src/resources/extensions/ollama/model-capabilities.ts +34 -0
- package/src/resources/extensions/ollama/ollama-client.ts +41 -4
- package/src/resources/extensions/ollama/tests/model-capabilities.test.ts +96 -0
- package/src/resources/extensions/ollama/tests/ollama-client-timeout-env.test.ts +147 -0
- package/src/resources/extensions/slash-commands/create-extension.ts +38 -24
- package/src/resources/extensions/subagent/index.ts +165 -7
- package/src/resources/skills/create-gsd-extension/SKILL.md +9 -5
- package/src/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
- package/src/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
- package/src/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
- package/src/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
- package/src/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
- package/src/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
- package/src/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
- package/src/resources/skills/create-gsd-extension/templates/extension-skeleton.ts +2 -2
- package/src/resources/skills/create-gsd-extension/templates/stateful-tool-skeleton.ts +3 -3
- package/src/resources/skills/create-gsd-extension/templates/templates.test.ts +58 -0
- package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +32 -12
- package/src/resources/skills/lint/SKILL.md +4 -0
- package/src/resources/skills/review/SKILL.md +4 -0
- package/src/resources/skills/test/SKILL.md +3 -0
- package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +0 -601
- package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +0 -651
- package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +0 -91
- package/dist/resources/extensions/gsd/tests/auto-supervisor.test.mjs +0 -53
- package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +0 -112
- package/dist/resources/extensions/gsd/tests/resolve-ts-hooks.mjs +0 -23
- package/dist/resources/extensions/gsd/tests/resolve-ts.mjs +0 -5
- package/dist/resources/skills/github-workflows/references/gh/tests/__init__.py +0 -0
- package/dist/resources/skills/github-workflows/references/gh/tests/test_github_project_setup.py +0 -608
- package/dist/web/standalone/.next/static/chunks/2826.e9f5195e91f9cad2.js +0 -11
- package/dist/web/standalone/.next/static/chunks/3621.fc7480022c972438.js +0 -20
- package/dist/web/standalone/.next/static/chunks/webpack-2e68521d7c82f7c2.js +0 -1
- package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +0 -22
- package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +0 -47
- package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +0 -75
- /package/dist/web/standalone/.next/static/{cAJH99yNS1UPbeSEiNRrV → 4iu6IYeYfxOq8OidlDqp6}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{cAJH99yNS1UPbeSEiNRrV → 4iu6IYeYfxOq8OidlDqp6}/_ssgManifest.js +0 -0
package/README.md
CHANGED
|
@@ -471,6 +471,7 @@ On first run, GSD launches a branded setup wizard that walks you through LLM pro
|
|
|
471
471
|
| `/gsd logs` | Browse activity, debug, and metrics logs |
|
|
472
472
|
| `/gsd export --html` | Generate HTML report for current or completed milestone |
|
|
473
473
|
| `/worktree` (`/wt`) | Git worktree lifecycle — create, switch, merge, remove |
|
|
474
|
+
| `/gsd worktree` (`/gsd wt`) | TUI worktree management — list, merge, clean, remove with safety checks |
|
|
474
475
|
| `/voice` | Toggle real-time speech-to-text (macOS, Linux) |
|
|
475
476
|
| `/exit` | Graceful shutdown — saves session state before exiting |
|
|
476
477
|
| `/kill` | Kill GSD process immediately |
|
|
@@ -625,19 +626,19 @@ Start GSD with `gsd --debug` to enable structured JSONL diagnostic logging. Debu
|
|
|
625
626
|
|
|
626
627
|
### Token Optimization
|
|
627
628
|
|
|
628
|
-
GSD includes a coordinated token optimization system that reduces usage by 40-60% on cost-sensitive workloads. Set a single preference to coordinate model selection, phase skipping, and context compression:
|
|
629
|
+
GSD includes a coordinated token optimization system that reduces usage by 40-60% on cost-sensitive workloads. Set a single preference to coordinate model tier selection, phase skipping, and context compression:
|
|
629
630
|
|
|
630
631
|
```yaml
|
|
631
632
|
token_profile: budget # or balanced (default), quality
|
|
632
633
|
```
|
|
633
634
|
|
|
634
|
-
| Profile | Savings | What It Does
|
|
635
|
-
| ---------- | ------- |
|
|
636
|
-
| `budget` | 40-60% |
|
|
637
|
-
| `balanced` | 10-20% |
|
|
638
|
-
| `quality` | 0% |
|
|
635
|
+
| Profile | Savings | What It Does |
|
|
636
|
+
| ---------- | ------- | -------------------------------------------------------------------------------- |
|
|
637
|
+
| `budget` | 40-60% | Light/standard tier defaults, skip research/reassess, minimal context inlining |
|
|
638
|
+
| `balanced` | 10-20% | Standard tier for core work, light tier for simple work, standard context |
|
|
639
|
+
| `quality` | 0% | Heavy tier for planning, standard tier for core work, full context |
|
|
639
640
|
|
|
640
|
-
**Complexity-based routing** automatically classifies tasks as simple/standard/complex and routes to appropriate models.
|
|
641
|
+
**Complexity-based routing** automatically classifies tasks as simple/standard/complex and routes to appropriate available models. Token profiles define provider-agnostic tier intentions, so simple docs tasks use a light-tier configured model and complex architectural work can use a heavy-tier configured model. The classification is heuristic (sub-millisecond, no LLM calls) and learns from outcomes via a persistent routing history.
|
|
641
642
|
|
|
642
643
|
**Budget pressure** graduates model downgrading as you approach your budget ceiling — 50%, 75%, and 90% thresholds progressively shift work to cheaper tiers.
|
|
643
644
|
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
export type FileExists = (path: string) => boolean;
|
|
2
|
+
export declare function resolvePackageRoot(importUrl: string): string;
|
|
3
|
+
export declare function hasCompleteBundledResources(resourcesDir: string, fileExists?: FileExists): boolean;
|
|
4
|
+
export declare function resolveBundledResourcesDirFromPackageRoot(packageRoot: string, fileExists?: FileExists): string;
|
|
5
|
+
export declare function resolveBundledResourcesDir(importUrl: string, fileExists?: FileExists): string;
|
|
6
|
+
export declare function resolveBundledResource(importUrl: string, ...segments: string[]): string;
|
|
7
|
+
export declare function resolveBundledGsdExtensionModule(importUrl: string, moduleFile: string, fileExists?: FileExists): string;
|
|
1
8
|
/**
|
|
2
9
|
* Resolve bundled raw resource files from the package root.
|
|
3
10
|
*
|
|
@@ -1,5 +1,38 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
1
2
|
import { dirname, join, resolve } from "node:path";
|
|
2
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
+
export function resolvePackageRoot(importUrl) {
|
|
5
|
+
const moduleDir = dirname(fileURLToPath(importUrl));
|
|
6
|
+
return resolve(moduleDir, "..");
|
|
7
|
+
}
|
|
8
|
+
export function hasCompleteBundledResources(resourcesDir, fileExists = existsSync) {
|
|
9
|
+
return fileExists(join(resourcesDir, "agents")) &&
|
|
10
|
+
fileExists(join(resourcesDir, "extensions"));
|
|
11
|
+
}
|
|
12
|
+
export function resolveBundledResourcesDirFromPackageRoot(packageRoot, fileExists = existsSync) {
|
|
13
|
+
const distResources = join(packageRoot, "dist", "resources");
|
|
14
|
+
const srcResources = join(packageRoot, "src", "resources");
|
|
15
|
+
return hasCompleteBundledResources(distResources, fileExists)
|
|
16
|
+
? distResources
|
|
17
|
+
: srcResources;
|
|
18
|
+
}
|
|
19
|
+
export function resolveBundledResourcesDir(importUrl, fileExists = existsSync) {
|
|
20
|
+
return resolveBundledResourcesDirFromPackageRoot(resolvePackageRoot(importUrl), fileExists);
|
|
21
|
+
}
|
|
22
|
+
export function resolveBundledResource(importUrl, ...segments) {
|
|
23
|
+
return join(resolveBundledResourcesDir(importUrl), ...segments);
|
|
24
|
+
}
|
|
25
|
+
export function resolveBundledGsdExtensionModule(importUrl, moduleFile, fileExists = existsSync) {
|
|
26
|
+
const packageRoot = resolvePackageRoot(importUrl);
|
|
27
|
+
const distResources = join(packageRoot, "dist", "resources");
|
|
28
|
+
const jsFile = moduleFile.replace(/\.ts$/, ".js");
|
|
29
|
+
const distModule = join(distResources, "extensions", "gsd", jsFile);
|
|
30
|
+
if (hasCompleteBundledResources(distResources, fileExists) && fileExists(distModule)) {
|
|
31
|
+
return distModule;
|
|
32
|
+
}
|
|
33
|
+
const tsFile = moduleFile.replace(/\.js$/, ".ts");
|
|
34
|
+
return join(packageRoot, "src", "resources", "extensions", "gsd", tsFile);
|
|
35
|
+
}
|
|
3
36
|
/**
|
|
4
37
|
* Resolve bundled raw resource files from the package root.
|
|
5
38
|
*
|
|
@@ -8,7 +41,6 @@ import { fileURLToPath } from "node:url";
|
|
|
8
41
|
* `src/resources/**`, not next to the compiled entry point.
|
|
9
42
|
*/
|
|
10
43
|
export function resolveBundledSourceResource(importUrl, ...segments) {
|
|
11
|
-
const
|
|
12
|
-
const packageRoot = resolve(moduleDir, "..");
|
|
44
|
+
const packageRoot = resolvePackageRoot(importUrl);
|
|
13
45
|
return join(packageRoot, "src", "resources", ...segments);
|
|
14
46
|
}
|
package/dist/claude-cli-check.js
CHANGED
|
@@ -1,7 +1,25 @@
|
|
|
1
1
|
// GSD2 — Claude CLI binary detection for onboarding
|
|
2
2
|
// Lightweight check used at onboarding time (before extensions load).
|
|
3
3
|
// The full readiness check with caching lives in the claude-code-cli extension.
|
|
4
|
+
//
|
|
5
|
+
// Set GSD_CLAUDE_DEBUG=1 to log probe output to stderr. Useful when
|
|
6
|
+
// diagnosing platform-specific detection failures (Issue #4997).
|
|
4
7
|
import { execFileSync } from 'node:child_process';
|
|
8
|
+
/**
|
|
9
|
+
* Spawn the Claude CLI without triggering Node's DEP0190.
|
|
10
|
+
*
|
|
11
|
+
* Passing `args` together with `shell: true` is deprecated in Node 22+
|
|
12
|
+
* because the args are concatenated into the command string without
|
|
13
|
+
* escaping. On Windows we still need a shell to resolve `.cmd` shims, so
|
|
14
|
+
* we invoke `cmd /c <command> <args...>` explicitly. On POSIX we don't
|
|
15
|
+
* need a shell at all.
|
|
16
|
+
*/
|
|
17
|
+
function spawnClaude(command, args, opts) {
|
|
18
|
+
if (process.platform === 'win32') {
|
|
19
|
+
return execFileSync('cmd', ['/c', command, ...args], opts);
|
|
20
|
+
}
|
|
21
|
+
return execFileSync(command, args, opts);
|
|
22
|
+
}
|
|
5
23
|
/**
|
|
6
24
|
* Platform-correct binary name for the Claude Code CLI.
|
|
7
25
|
*
|
|
@@ -20,38 +38,40 @@ export const CLAUDE_COMMAND = process.platform === 'win32' ? 'claude.cmd' : 'cla
|
|
|
20
38
|
* expose a bare `claude` shim. Try all three so no valid install is missed.
|
|
21
39
|
*/
|
|
22
40
|
const CLAUDE_COMMAND_CANDIDATES = process.platform === 'win32' ? [CLAUDE_COMMAND, 'claude.exe', 'claude'] : [CLAUDE_COMMAND];
|
|
23
|
-
// Codes treated as "this candidate didn't run — try the next one" rather than
|
|
24
|
-
// fatal failures. ETIMEDOUT/EAGAIN cover slow-spawn cases on Windows where
|
|
25
|
-
// cmd.exe wrapping plus the Claude CLI startup path together exceed the
|
|
26
|
-
// per-attempt timeout (Issue #4997 regression on Windows + Node 25).
|
|
27
|
-
const SOFT_FAIL_CODES = new Set(['ENOENT', 'EINVAL', 'ETIMEDOUT', 'EAGAIN']);
|
|
28
41
|
const VERSION_TIMEOUT_MS = 5_000;
|
|
29
42
|
// Auth probe needs more headroom on Windows because the spawn goes through
|
|
30
43
|
// cmd.exe → claude.cmd → node → Claude CLI.
|
|
31
44
|
const AUTH_TIMEOUT_MS = 15_000;
|
|
45
|
+
function debugLog(...parts) {
|
|
46
|
+
if (process.env.GSD_CLAUDE_DEBUG) {
|
|
47
|
+
process.stderr.write(`[claude-cli-check] ${parts.map(p => (typeof p === 'string' ? p : JSON.stringify(p))).join(' ')}\n`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
32
50
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
51
|
+
* Find the first candidate that responds to `--version`. Returns the
|
|
52
|
+
* candidate name on success, null if none worked.
|
|
53
|
+
*
|
|
54
|
+
* On Windows with `shell: true`, a missing candidate surfaces as a
|
|
55
|
+
* non-zero exit from cmd.exe rather than ENOENT — so we cannot rely on
|
|
56
|
+
* the error code to decide "try next". Treat any failure as "try next"
|
|
57
|
+
* for the version probe.
|
|
35
58
|
*/
|
|
36
|
-
function
|
|
37
|
-
let lastError;
|
|
59
|
+
function findWorkingCommand() {
|
|
38
60
|
for (const command of CLAUDE_COMMAND_CANDIDATES) {
|
|
39
61
|
try {
|
|
40
|
-
|
|
41
|
-
timeout:
|
|
62
|
+
spawnClaude(command, ['--version'], {
|
|
63
|
+
timeout: VERSION_TIMEOUT_MS,
|
|
42
64
|
stdio: 'pipe',
|
|
43
|
-
shell: process.platform === 'win32',
|
|
44
65
|
});
|
|
66
|
+
debugLog('version probe ok via', command);
|
|
67
|
+
return command;
|
|
45
68
|
}
|
|
46
69
|
catch (error) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
if (code && SOFT_FAIL_CODES.has(code))
|
|
50
|
-
continue;
|
|
51
|
-
throw error;
|
|
70
|
+
debugLog('version probe failed for', command, 'code=', error?.code);
|
|
71
|
+
continue;
|
|
52
72
|
}
|
|
53
73
|
}
|
|
54
|
-
|
|
74
|
+
return null;
|
|
55
75
|
}
|
|
56
76
|
/**
|
|
57
77
|
* Decide auth state from `claude auth status` output.
|
|
@@ -62,6 +82,8 @@ function execClaudeCheck(args, timeoutMs) {
|
|
|
62
82
|
*/
|
|
63
83
|
function parseAuthStatus(output) {
|
|
64
84
|
const trimmed = output.trim();
|
|
85
|
+
if (!trimmed)
|
|
86
|
+
return null;
|
|
65
87
|
if (trimmed.startsWith('{')) {
|
|
66
88
|
try {
|
|
67
89
|
const parsed = JSON.parse(trimmed);
|
|
@@ -77,35 +99,52 @@ function parseAuthStatus(output) {
|
|
|
77
99
|
if (/not logged in|no credentials|unauthenticated|not authenticated/.test(lower)) {
|
|
78
100
|
return false;
|
|
79
101
|
}
|
|
80
|
-
|
|
102
|
+
if (/logged in|authenticated|signed in|email|subscription/.test(lower)) {
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
function probeAuth(command) {
|
|
108
|
+
// Try --json first (newer CLIs).
|
|
109
|
+
try {
|
|
110
|
+
const out = spawnClaude(command, ['auth', 'status', '--json'], {
|
|
111
|
+
timeout: AUTH_TIMEOUT_MS,
|
|
112
|
+
stdio: 'pipe',
|
|
113
|
+
}).toString();
|
|
114
|
+
debugLog('auth status --json output:', out.slice(0, 200));
|
|
115
|
+
const parsed = parseAuthStatus(out);
|
|
116
|
+
if (parsed !== null)
|
|
117
|
+
return parsed;
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
debugLog('auth status --json threw:', error.message?.slice(0, 200));
|
|
121
|
+
}
|
|
122
|
+
// Fallback: plain `auth status` (older CLIs that don't accept --json).
|
|
123
|
+
try {
|
|
124
|
+
const out = spawnClaude(command, ['auth', 'status'], {
|
|
125
|
+
timeout: AUTH_TIMEOUT_MS,
|
|
126
|
+
stdio: 'pipe',
|
|
127
|
+
}).toString();
|
|
128
|
+
debugLog('auth status output:', out.slice(0, 200));
|
|
129
|
+
return parseAuthStatus(out);
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
debugLog('auth status threw:', error.message?.slice(0, 200));
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
81
135
|
}
|
|
82
136
|
/**
|
|
83
137
|
* Check if the `claude` binary is installed (regardless of auth state).
|
|
84
138
|
*/
|
|
85
139
|
export function isClaudeBinaryInstalled() {
|
|
86
|
-
|
|
87
|
-
execClaudeCheck(['--version'], VERSION_TIMEOUT_MS);
|
|
88
|
-
return true;
|
|
89
|
-
}
|
|
90
|
-
catch {
|
|
91
|
-
return false;
|
|
92
|
-
}
|
|
140
|
+
return findWorkingCommand() !== null;
|
|
93
141
|
}
|
|
94
142
|
/**
|
|
95
143
|
* Check if the `claude` CLI is installed AND authenticated.
|
|
96
144
|
*/
|
|
97
145
|
export function isClaudeCliReady() {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
catch {
|
|
146
|
+
const command = findWorkingCommand();
|
|
147
|
+
if (!command)
|
|
102
148
|
return false;
|
|
103
|
-
|
|
104
|
-
try {
|
|
105
|
-
const output = execClaudeCheck(['auth', 'status', '--json'], AUTH_TIMEOUT_MS).toString();
|
|
106
|
-
return parseAuthStatus(output);
|
|
107
|
-
}
|
|
108
|
-
catch {
|
|
109
|
-
return false;
|
|
110
|
-
}
|
|
149
|
+
return probeAuth(command) === true;
|
|
111
150
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subcommands that must bypass the managed-resource-mismatch gate.
|
|
3
|
+
*
|
|
4
|
+
* When the synced resource manifest claims a newer gsd version than the
|
|
5
|
+
* running binary, exitIfManagedResourcesAreNewer() blocks every command
|
|
6
|
+
* with a "Version mismatch detected" diagnostic. The `update` subcommand
|
|
7
|
+
* MUST bypass that gate so the user can recover by upgrading the binary —
|
|
8
|
+
* otherwise they're stuck in a broken state with no escape hatch.
|
|
9
|
+
*
|
|
10
|
+
* Any new bypassed subcommand goes here. cli.ts dispatches on this
|
|
11
|
+
* predicate before calling exitIfManagedResourcesAreNewer().
|
|
12
|
+
*/
|
|
13
|
+
export declare function shouldBypassManagedResourceMismatchGate(firstMessage: string | undefined): boolean;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Policy helpers for cli.ts — extracted as pure functions so they can be
|
|
2
|
+
// unit-tested without executing cli.ts's top-level script body.
|
|
3
|
+
/**
|
|
4
|
+
* Subcommands that must bypass the managed-resource-mismatch gate.
|
|
5
|
+
*
|
|
6
|
+
* When the synced resource manifest claims a newer gsd version than the
|
|
7
|
+
* running binary, exitIfManagedResourcesAreNewer() blocks every command
|
|
8
|
+
* with a "Version mismatch detected" diagnostic. The `update` subcommand
|
|
9
|
+
* MUST bypass that gate so the user can recover by upgrading the binary —
|
|
10
|
+
* otherwise they're stuck in a broken state with no escape hatch.
|
|
11
|
+
*
|
|
12
|
+
* Any new bypassed subcommand goes here. cli.ts dispatches on this
|
|
13
|
+
* predicate before calling exitIfManagedResourcesAreNewer().
|
|
14
|
+
*/
|
|
15
|
+
export function shouldBypassManagedResourceMismatchGate(firstMessage) {
|
|
16
|
+
return firstMessage === 'update';
|
|
17
|
+
}
|
package/dist/cli.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { AuthStorage, DefaultResourceLoader, ModelRegistry, runPackageCommand, SettingsManager, SessionManager, createAgentSession, InteractiveMode, runPrintMode, runRpcMode, } from '@gsd/pi-coding-agent';
|
|
2
1
|
import { readFileSync } from 'node:fs';
|
|
3
2
|
import { join } from 'node:path';
|
|
4
3
|
import { agentDir, sessionsDir, authFilePath } from './app-paths.js';
|
|
@@ -9,6 +8,7 @@ import { migratePiCredentials } from './pi-migration.js';
|
|
|
9
8
|
import { shouldRunOnboarding, runOnboarding } from './onboarding.js';
|
|
10
9
|
import chalk from 'chalk';
|
|
11
10
|
import { checkForUpdates } from './update-check.js';
|
|
11
|
+
import { shouldBypassManagedResourceMismatchGate } from './cli-policy.js';
|
|
12
12
|
import { printHelp, printSubcommandHelp } from './help-text.js';
|
|
13
13
|
import { applySecurityOverrides } from './security-overrides.js';
|
|
14
14
|
import { validateConfiguredModel } from './startup-model-validation.js';
|
|
@@ -17,8 +17,11 @@ import { buildHeadlessAutoArgs, parseCliArgs, runWebCliBranch, migrateLegacyFlat
|
|
|
17
17
|
import { stopWebMode } from './web-mode.js';
|
|
18
18
|
import { getProjectSessionsDir } from './project-sessions.js';
|
|
19
19
|
import { markStartup, printStartupTimings } from './startup-timings.js';
|
|
20
|
-
import {
|
|
21
|
-
|
|
20
|
+
import { applyRtkProcessEnv, GSD_RTK_DISABLED_ENV, isTruthy } from './rtk-shared.js';
|
|
21
|
+
let piCodingAgentModulePromise;
|
|
22
|
+
function loadPiCodingAgentModule() {
|
|
23
|
+
return (piCodingAgentModulePromise ??= import('@gsd/pi-coding-agent'));
|
|
24
|
+
}
|
|
22
25
|
// ---------------------------------------------------------------------------
|
|
23
26
|
// V8 compile cache — Node 22+ can cache compiled bytecode across runs,
|
|
24
27
|
// eliminating repeated parse/compile overhead for unchanged modules.
|
|
@@ -129,27 +132,53 @@ if (process.argv.includes('--help') || process.argv.includes('-h')) {
|
|
|
129
132
|
// so concurrent callers await the same initialization.
|
|
130
133
|
let rtkBootstrapPromise;
|
|
131
134
|
async function doRtkBootstrap() {
|
|
135
|
+
let rtkStatus;
|
|
136
|
+
let rtkDisabled = isTruthy(process.env[GSD_RTK_DISABLED_ENV]);
|
|
132
137
|
// RTK is opt-in via experimental.rtk preference. Default: disabled.
|
|
133
138
|
// Honor GSD_RTK_DISABLED if already explicitly set in the environment
|
|
134
139
|
// (env var takes precedence over preferences for manual override).
|
|
135
|
-
if (!
|
|
140
|
+
if (!rtkDisabled) {
|
|
141
|
+
const { loadEffectiveGSDPreferences } = await import('./resources/extensions/gsd/preferences.js');
|
|
136
142
|
const prefs = loadEffectiveGSDPreferences();
|
|
137
143
|
const rtkEnabled = prefs?.preferences.experimental?.rtk === true;
|
|
138
144
|
if (!rtkEnabled) {
|
|
139
145
|
process.env[GSD_RTK_DISABLED_ENV] = '1';
|
|
146
|
+
rtkDisabled = true;
|
|
140
147
|
}
|
|
141
148
|
}
|
|
142
|
-
|
|
149
|
+
markStartup('rtkPreferenceCheck');
|
|
150
|
+
if (rtkDisabled) {
|
|
151
|
+
applyRtkProcessEnv(process.env);
|
|
152
|
+
rtkStatus = {
|
|
153
|
+
enabled: false,
|
|
154
|
+
supported: true,
|
|
155
|
+
available: false,
|
|
156
|
+
source: 'disabled',
|
|
157
|
+
reason: `${GSD_RTK_DISABLED_ENV} is set`,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
const { bootstrapRtk } = await import('./rtk.js');
|
|
162
|
+
rtkStatus = await bootstrapRtk();
|
|
163
|
+
}
|
|
143
164
|
markStartup('bootstrapRtk');
|
|
144
165
|
if (!rtkStatus.available && rtkStatus.supported && rtkStatus.enabled && rtkStatus.reason) {
|
|
145
166
|
process.stderr.write(`[gsd] Warning: RTK unavailable — continuing without shell-command compression (${rtkStatus.reason}).\n`);
|
|
146
167
|
}
|
|
147
168
|
}
|
|
148
169
|
function ensureRtkBootstrap() {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
170
|
+
if (!rtkBootstrapPromise) {
|
|
171
|
+
markStartup('preRtkBootstrap');
|
|
172
|
+
rtkBootstrapPromise = doRtkBootstrap();
|
|
173
|
+
}
|
|
174
|
+
return rtkBootstrapPromise;
|
|
175
|
+
}
|
|
176
|
+
// `gsd update` — update to the latest version via npm.
|
|
177
|
+
// MUST run before exitIfManagedResourcesAreNewer(): when the bundled resource
|
|
178
|
+
// manifest is from a newer version than the running binary, every other
|
|
179
|
+
// command is blocked — only `update` should bypass the gate so the user can
|
|
180
|
+
// actually upgrade out of the broken state. See shouldBypassManagedResourceMismatchGate.
|
|
181
|
+
if (shouldBypassManagedResourceMismatchGate(cliFlags.messages[0])) {
|
|
153
182
|
const { runUpdate } = await import('./update-cmd.js');
|
|
154
183
|
await runUpdate();
|
|
155
184
|
process.exit(0);
|
|
@@ -246,20 +275,25 @@ const hasSubcommand = cliFlags.messages.length > 0;
|
|
|
246
275
|
if (!process.stdin.isTTY && !isPrintMode && !hasSubcommand && !cliFlags.listModels && !cliFlags.web) {
|
|
247
276
|
printNonTtyErrorAndExit(undefined, false);
|
|
248
277
|
}
|
|
249
|
-
const
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
278
|
+
const packageCommandNames = new Set(['install', 'remove', 'list']);
|
|
279
|
+
if (packageCommandNames.has(cliFlags.messages[0])) {
|
|
280
|
+
const { runPackageCommand } = await loadPiCodingAgentModule();
|
|
281
|
+
const packageCommand = await runPackageCommand({
|
|
282
|
+
appName: 'gsd',
|
|
283
|
+
args: process.argv.slice(2),
|
|
284
|
+
cwd: process.cwd(),
|
|
285
|
+
agentDir,
|
|
286
|
+
stdout: process.stdout,
|
|
287
|
+
stderr: process.stderr,
|
|
288
|
+
allowedCommands: packageCommandNames,
|
|
289
|
+
});
|
|
290
|
+
if (packageCommand.handled) {
|
|
291
|
+
process.exit(packageCommand.exitCode);
|
|
292
|
+
}
|
|
260
293
|
}
|
|
261
294
|
// `gsd config` — replay the setup wizard and exit
|
|
262
295
|
if (cliFlags.messages[0] === 'config') {
|
|
296
|
+
const { AuthStorage } = await loadPiCodingAgentModule();
|
|
263
297
|
const authStorage = AuthStorage.create(authFilePath);
|
|
264
298
|
loadStoredEnvKeys(authStorage);
|
|
265
299
|
await runOnboarding(authStorage);
|
|
@@ -291,6 +325,7 @@ if (cliFlags.web || (cliFlags.messages[0] === 'web' && cliFlags.messages[1] !==
|
|
|
291
325
|
}
|
|
292
326
|
// `gsd sessions` — list past sessions and pick one to resume
|
|
293
327
|
if (cliFlags.messages[0] === 'sessions') {
|
|
328
|
+
const { SessionManager } = await loadPiCodingAgentModule();
|
|
294
329
|
const cwd = process.cwd();
|
|
295
330
|
const safePath = `--${cwd.replace(/^[/\\]/, '').replace(/[/\\:]/g, '-')}--`;
|
|
296
331
|
const projectSessionsDir = join(sessionsDir, safePath);
|
|
@@ -380,6 +415,35 @@ function flushPendingProviderRegistrations(resourceLoader, modelRegistry) {
|
|
|
380
415
|
if (cliFlags.messages[0] === 'auto') {
|
|
381
416
|
await runHeadlessFromAuto(buildHeadlessAutoArgs(cliFlags));
|
|
382
417
|
}
|
|
418
|
+
// ---------------------------------------------------------------------------
|
|
419
|
+
// Worktree subcommand — `gsd worktree <list|merge|clean|remove>`
|
|
420
|
+
// ---------------------------------------------------------------------------
|
|
421
|
+
if (!isPrintMode &&
|
|
422
|
+
cliFlags.listModels === undefined &&
|
|
423
|
+
(cliFlags.messages[0] === 'worktree' || cliFlags.messages[0] === 'wt')) {
|
|
424
|
+
const { handleList, handleMerge, handleClean, handleRemove } = await import('./worktree-cli.js');
|
|
425
|
+
const sub = cliFlags.messages[1];
|
|
426
|
+
const subArgs = cliFlags.messages.slice(2);
|
|
427
|
+
if (!sub || sub === 'list') {
|
|
428
|
+
await handleList(process.cwd());
|
|
429
|
+
}
|
|
430
|
+
else if (sub === 'merge') {
|
|
431
|
+
await handleMerge(process.cwd(), subArgs);
|
|
432
|
+
}
|
|
433
|
+
else if (sub === 'clean') {
|
|
434
|
+
await handleClean(process.cwd());
|
|
435
|
+
}
|
|
436
|
+
else if (sub === 'remove' || sub === 'rm') {
|
|
437
|
+
await handleRemove(process.cwd(), subArgs);
|
|
438
|
+
}
|
|
439
|
+
else {
|
|
440
|
+
process.stderr.write(`Unknown worktree command: ${sub}\n`);
|
|
441
|
+
process.stderr.write('Commands: list, merge [name], clean, remove <name>\n');
|
|
442
|
+
}
|
|
443
|
+
process.exit(0);
|
|
444
|
+
}
|
|
445
|
+
const { AuthStorage, DefaultResourceLoader, ModelRegistry, SettingsManager, SessionManager, createAgentSession, InteractiveMode, runPrintMode, runRpcMode, } = await loadPiCodingAgentModule();
|
|
446
|
+
markStartup('loadPiCodingAgent');
|
|
383
447
|
// Pi's tool bootstrap can mis-detect already-installed fd/rg on some systems
|
|
384
448
|
// because spawnSync(..., ["--version"]) returns EPERM despite a zero exit code.
|
|
385
449
|
// Provision local managed binaries first so Pi sees them without probing PATH.
|
|
@@ -431,11 +495,7 @@ if (cliFlags.listModels !== undefined) {
|
|
|
431
495
|
additionalExtensionPaths: cliFlags.extensions.length > 0 ? cliFlags.extensions : undefined,
|
|
432
496
|
});
|
|
433
497
|
await listModelsLoader.reload();
|
|
434
|
-
|
|
435
|
-
for (const { name, config } of listModelsExtensions.runtime.pendingProviderRegistrations) {
|
|
436
|
-
modelRegistry.registerProvider(name, config);
|
|
437
|
-
}
|
|
438
|
-
listModelsExtensions.runtime.pendingProviderRegistrations = [];
|
|
498
|
+
flushPendingProviderRegistrations(listModelsLoader, modelRegistry);
|
|
439
499
|
const models = modelRegistry.getAvailable();
|
|
440
500
|
if (models.length === 0) {
|
|
441
501
|
console.log('No models available. Set API keys in environment variables.');
|
|
@@ -483,6 +543,7 @@ if (!settingsManager.getQuietStartup()) {
|
|
|
483
543
|
if (!settingsManager.getCollapseChangelog()) {
|
|
484
544
|
settingsManager.setCollapseChangelog(true);
|
|
485
545
|
}
|
|
546
|
+
markStartup('startupSettings');
|
|
486
547
|
// ---------------------------------------------------------------------------
|
|
487
548
|
// Print / subagent mode — single-shot execution, no TTY required
|
|
488
549
|
// ---------------------------------------------------------------------------
|
|
@@ -515,7 +576,7 @@ if (isPrintMode) {
|
|
|
515
576
|
flushPendingProviderRegistrations(resourceLoader, modelRegistry);
|
|
516
577
|
migrateAnthropicDefaultToClaudeCode({
|
|
517
578
|
authStorage,
|
|
518
|
-
isClaudeCodeReady: modelRegistry.isProviderRequestReady('claude-code'),
|
|
579
|
+
isClaudeCodeReady: () => modelRegistry.isProviderRequestReady('claude-code'),
|
|
519
580
|
settingsManager,
|
|
520
581
|
modelRegistry,
|
|
521
582
|
});
|
|
@@ -577,31 +638,6 @@ if (isPrintMode) {
|
|
|
577
638
|
process.exit(0);
|
|
578
639
|
}
|
|
579
640
|
// ---------------------------------------------------------------------------
|
|
580
|
-
// Worktree subcommand — `gsd worktree <list|merge|clean|remove>`
|
|
581
|
-
// ---------------------------------------------------------------------------
|
|
582
|
-
if (cliFlags.messages[0] === 'worktree' || cliFlags.messages[0] === 'wt') {
|
|
583
|
-
const { handleList, handleMerge, handleClean, handleRemove } = await import('./worktree-cli.js');
|
|
584
|
-
const sub = cliFlags.messages[1];
|
|
585
|
-
const subArgs = cliFlags.messages.slice(2);
|
|
586
|
-
if (!sub || sub === 'list') {
|
|
587
|
-
await handleList(process.cwd());
|
|
588
|
-
}
|
|
589
|
-
else if (sub === 'merge') {
|
|
590
|
-
await handleMerge(process.cwd(), subArgs);
|
|
591
|
-
}
|
|
592
|
-
else if (sub === 'clean') {
|
|
593
|
-
await handleClean(process.cwd());
|
|
594
|
-
}
|
|
595
|
-
else if (sub === 'remove' || sub === 'rm') {
|
|
596
|
-
await handleRemove(process.cwd(), subArgs);
|
|
597
|
-
}
|
|
598
|
-
else {
|
|
599
|
-
process.stderr.write(`Unknown worktree command: ${sub}\n`);
|
|
600
|
-
process.stderr.write('Commands: list, merge [name], clean, remove <name>\n');
|
|
601
|
-
}
|
|
602
|
-
process.exit(0);
|
|
603
|
-
}
|
|
604
|
-
// ---------------------------------------------------------------------------
|
|
605
641
|
// Worktree flag (-w) — create/resume a worktree for the interactive session
|
|
606
642
|
// ---------------------------------------------------------------------------
|
|
607
643
|
if (cliFlags.worktree) {
|
|
@@ -613,11 +649,12 @@ if (cliFlags.worktree) {
|
|
|
613
649
|
// ---------------------------------------------------------------------------
|
|
614
650
|
if (!cliFlags.worktree && !isPrintMode) {
|
|
615
651
|
try {
|
|
616
|
-
const {
|
|
617
|
-
|
|
652
|
+
const { showWorktreeStatusBanner } = await import('./worktree-status-banner.js');
|
|
653
|
+
showWorktreeStatusBanner(process.cwd());
|
|
618
654
|
}
|
|
619
655
|
catch { /* non-fatal */ }
|
|
620
656
|
}
|
|
657
|
+
markStartup('worktreeStatusBanner');
|
|
621
658
|
// ---------------------------------------------------------------------------
|
|
622
659
|
// Auto-redirect: `gsd auto` with piped stdout → headless mode (#2732)
|
|
623
660
|
// When stdout is not a TTY (e.g. `gsd auto | cat`, `gsd auto > file`),
|
|
@@ -651,7 +688,9 @@ markStartup('initResources');
|
|
|
651
688
|
// Overlap resource loading with session manager setup — both are independent.
|
|
652
689
|
// resourceLoader.reload() is the most expensive step (jiti compilation), so
|
|
653
690
|
// starting it early shaves ~50-200ms off interactive startup.
|
|
654
|
-
const resourceLoader = buildResourceLoader(agentDir
|
|
691
|
+
const resourceLoader = await buildResourceLoader(agentDir, {
|
|
692
|
+
additionalExtensionPaths: cliFlags.extensions.length > 0 ? cliFlags.extensions : undefined,
|
|
693
|
+
});
|
|
655
694
|
const resourceLoadPromise = resourceLoader.reload();
|
|
656
695
|
// While resources load, let session manager finish any async I/O it needs.
|
|
657
696
|
// Then await the resource promise before creating the agent session.
|
|
@@ -660,10 +699,11 @@ markStartup('resourceLoader.reload');
|
|
|
660
699
|
flushPendingProviderRegistrations(resourceLoader, modelRegistry);
|
|
661
700
|
migrateAnthropicDefaultToClaudeCode({
|
|
662
701
|
authStorage,
|
|
663
|
-
isClaudeCodeReady: modelRegistry.isProviderRequestReady('claude-code'),
|
|
702
|
+
isClaudeCodeReady: () => modelRegistry.isProviderRequestReady('claude-code'),
|
|
664
703
|
settingsManager,
|
|
665
704
|
modelRegistry,
|
|
666
705
|
});
|
|
706
|
+
markStartup('providerMigrations');
|
|
667
707
|
const { session, extensionsResult, modelFallbackMessage: interactiveFallbackMsg } = await createAgentSession({
|
|
668
708
|
authStorage,
|
|
669
709
|
modelRegistry,
|
package/dist/headless-query.d.ts
CHANGED
|
@@ -14,6 +14,28 @@
|
|
|
14
14
|
* bypassing the extension loader's jiti setup (#1137).
|
|
15
15
|
*/
|
|
16
16
|
import type { GSDState } from './resources/extensions/gsd/types.js';
|
|
17
|
+
/**
|
|
18
|
+
* Resolve the GSD extensions root for headless-query. Prefers the synced
|
|
19
|
+
* agent directory (so headless-query loads the same extension copy as
|
|
20
|
+
* interactive/auto modes — #3471) and falls back to the bundled source
|
|
21
|
+
* resource for source-tree dev workflows.
|
|
22
|
+
*
|
|
23
|
+
* Pure on the given inputs (env + fs probe + bundled resolver) so the
|
|
24
|
+
* #3471 contract can be exercised in tests without spawning a subprocess.
|
|
25
|
+
*/
|
|
26
|
+
export declare function resolveGsdAgentExtensionsDir(env?: NodeJS.ProcessEnv): string;
|
|
27
|
+
/**
|
|
28
|
+
* Decide whether headless-query should load extensions from the agent
|
|
29
|
+
* sync directory (#3471) or fall back to bundled source. Returns the
|
|
30
|
+
* agent dir alongside the decision so a caller can use it directly.
|
|
31
|
+
*/
|
|
32
|
+
export declare function shouldUseAgentExtensionsDir(opts: {
|
|
33
|
+
env?: NodeJS.ProcessEnv;
|
|
34
|
+
fileExists?: (path: string) => boolean;
|
|
35
|
+
}): {
|
|
36
|
+
agentDir: string;
|
|
37
|
+
useAgentDir: boolean;
|
|
38
|
+
};
|
|
17
39
|
export interface QuerySnapshot {
|
|
18
40
|
state: GSDState;
|
|
19
41
|
next: {
|
package/dist/headless-query.js
CHANGED
|
@@ -17,17 +17,52 @@ import { createJiti } from '@mariozechner/jiti';
|
|
|
17
17
|
import { fileURLToPath } from 'node:url';
|
|
18
18
|
import { join } from 'node:path';
|
|
19
19
|
import { homedir } from 'node:os';
|
|
20
|
-
import {
|
|
20
|
+
import { resolveBundledGsdExtensionModule } from './bundled-resource-path.js';
|
|
21
21
|
const jiti = createJiti(fileURLToPath(import.meta.url), { interopDefault: true, debug: false });
|
|
22
|
-
// Resolve extensions from the synced agent directory so headless-query
|
|
23
|
-
// loads the same extension copy as interactive/auto modes (#3471).
|
|
24
|
-
// Falls back to bundled source for source-tree dev workflows.
|
|
25
|
-
const agentExtensionsDir = join(process.env.GSD_AGENT_DIR || join(homedir(), '.gsd', 'agent'), 'extensions', 'gsd');
|
|
26
22
|
const { existsSync } = await import('node:fs');
|
|
27
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Resolve the GSD extensions root for headless-query. Prefers the synced
|
|
25
|
+
* agent directory (so headless-query loads the same extension copy as
|
|
26
|
+
* interactive/auto modes — #3471) and falls back to the bundled source
|
|
27
|
+
* resource for source-tree dev workflows.
|
|
28
|
+
*
|
|
29
|
+
* Pure on the given inputs (env + fs probe + bundled resolver) so the
|
|
30
|
+
* #3471 contract can be exercised in tests without spawning a subprocess.
|
|
31
|
+
*/
|
|
32
|
+
export function resolveGsdAgentExtensionsDir(env = process.env) {
|
|
33
|
+
const agentRoot = env.GSD_AGENT_DIR || join(env.GSD_HOME || join(homedir(), '.gsd'), 'agent');
|
|
34
|
+
return join(agentRoot, 'extensions', 'gsd');
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Decide whether headless-query should load extensions from the agent
|
|
38
|
+
* sync directory (#3471) or fall back to bundled source. Returns the
|
|
39
|
+
* agent dir alongside the decision so a caller can use it directly.
|
|
40
|
+
*/
|
|
41
|
+
export function shouldUseAgentExtensionsDir(opts) {
|
|
42
|
+
const env = opts.env ?? process.env;
|
|
43
|
+
const fileExists = opts.fileExists ?? existsSync;
|
|
44
|
+
const agentDir = resolveGsdAgentExtensionsDir(env);
|
|
45
|
+
return {
|
|
46
|
+
agentDir,
|
|
47
|
+
useAgentDir: fileExists(join(agentDir, 'state.ts')) || fileExists(join(agentDir, 'state.js')),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
const agentExtensionsDir = resolveGsdAgentExtensionsDir();
|
|
51
|
+
const { useAgentDir } = shouldUseAgentExtensionsDir({ env: process.env });
|
|
28
52
|
const gsdExtensionPath = (...segments) => useAgentDir
|
|
29
|
-
?
|
|
30
|
-
:
|
|
53
|
+
? resolveAgentExtensionModule(agentExtensionsDir, segments)
|
|
54
|
+
: resolveBundledGsdExtensionModule(import.meta.url, segments.join('/'));
|
|
55
|
+
function resolveAgentExtensionModule(agentDir, segments) {
|
|
56
|
+
const requested = join(agentDir, ...segments);
|
|
57
|
+
if (existsSync(requested))
|
|
58
|
+
return requested;
|
|
59
|
+
if (segments.length === 1 && segments[0].endsWith('.ts')) {
|
|
60
|
+
const jsPath = join(agentDir, segments[0].replace(/\.ts$/, '.js'));
|
|
61
|
+
if (existsSync(jsPath))
|
|
62
|
+
return jsPath;
|
|
63
|
+
}
|
|
64
|
+
return requested;
|
|
65
|
+
}
|
|
31
66
|
async function loadExtensionModules() {
|
|
32
67
|
const stateModule = await jiti.import(gsdExtensionPath('state.ts'), {});
|
|
33
68
|
const dispatchModule = await jiti.import(gsdExtensionPath('auto-dispatch.ts'), {});
|