gsd-pi 2.78.0 → 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 +60 -23
- package/dist/bundled-resource-path.d.ts +7 -0
- package/dist/bundled-resource-path.js +34 -2
- package/dist/claude-cli-check.js +104 -33
- 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 +128 -32
- 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 +14 -14
- package/dist/web/standalone/.next/build-manifest.json +4 -4
- 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/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 +4 -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 +2 -2
- 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 +2 -2
- 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 +4 -4
- 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 +14 -14
- 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-manifest.json +5 -5
- package/dist/web/standalone/.next/server/middleware-react-loadable-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/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/_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-9bf2e0c50fb2ca05.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/.next/static/chunks/webpack-f9f0dc45e4f3ac10.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/package.json +2 -1
- package/dist/web/standalone/server.js +1 -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 +130 -30
- 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/app/page-151349214571e2b6.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/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/{C1zT2kEfoLhDdbWPWKrXd → 4iu6IYeYfxOq8OidlDqp6}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{C1zT2kEfoLhDdbWPWKrXd → 4iu6IYeYfxOq8OidlDqp6}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { existsSync, readFileSync, realpathSync, statSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join, resolve } from "node:path";
|
|
4
|
+
|
|
5
|
+
export interface WorktreeSegment {
|
|
6
|
+
gsdIdx: number;
|
|
7
|
+
afterWorktrees: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function normalizeWorktreePathForCompare(path: string): string {
|
|
11
|
+
let normalized: string;
|
|
12
|
+
try {
|
|
13
|
+
normalized = realpathSync(path);
|
|
14
|
+
} catch {
|
|
15
|
+
normalized = resolve(path);
|
|
16
|
+
}
|
|
17
|
+
const slashed = normalized.replaceAll("\\", "/");
|
|
18
|
+
const trimmed = slashed.replace(/\/+$/, "");
|
|
19
|
+
return process.platform === "win32" ? (trimmed || "/").toLowerCase() : (trimmed || "/");
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Find the GSD worktree segment in both direct project layout and the
|
|
24
|
+
* symlink-resolved external-state layout used by ~/.gsd/projects/<hash>.
|
|
25
|
+
*/
|
|
26
|
+
export function findWorktreeSegment(normalizedPath: string): WorktreeSegment | null {
|
|
27
|
+
const directMarker = "/.gsd/worktrees/";
|
|
28
|
+
const directIdx = normalizedPath.indexOf(directMarker);
|
|
29
|
+
if (directIdx !== -1) {
|
|
30
|
+
return { gsdIdx: directIdx, afterWorktrees: directIdx + directMarker.length };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const externalRe = /\/\.gsd\/projects\/[^/]+\/worktrees\//;
|
|
34
|
+
const externalMatch = normalizedPath.match(externalRe);
|
|
35
|
+
if (externalMatch && externalMatch.index !== undefined) {
|
|
36
|
+
return {
|
|
37
|
+
gsdIdx: externalMatch.index,
|
|
38
|
+
afterWorktrees: externalMatch.index + externalMatch[0].length,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function isGsdWorktreePath(path: string): boolean {
|
|
46
|
+
return findWorktreeSegment(path.replaceAll("\\", "/")) !== null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Resolve the canonical project root for worktree operations.
|
|
51
|
+
*
|
|
52
|
+
* `originalBasePath` wins when available because session state already knows the
|
|
53
|
+
* root. `GSD_PROJECT_ROOT` is the next strongest signal for worker processes.
|
|
54
|
+
* Otherwise, derive the root from direct `.gsd/worktrees` paths, or recover it
|
|
55
|
+
* from the worktree `.git` file for symlink-resolved ~/.gsd/project paths.
|
|
56
|
+
*/
|
|
57
|
+
export function resolveWorktreeProjectRoot(
|
|
58
|
+
basePath: string,
|
|
59
|
+
originalBasePath?: string | null,
|
|
60
|
+
): string {
|
|
61
|
+
const preferred =
|
|
62
|
+
originalBasePath?.trim() ||
|
|
63
|
+
process.env.GSD_PROJECT_ROOT?.trim() ||
|
|
64
|
+
basePath;
|
|
65
|
+
|
|
66
|
+
return resolveProjectRootFromPath(preferred);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function resolveProjectRootFromPath(path: string): string {
|
|
70
|
+
const normalizedPath = path.replaceAll("\\", "/");
|
|
71
|
+
const segment = findWorktreeSegment(normalizedPath);
|
|
72
|
+
if (!segment) return resolveGitWorkingTreeRoot(path) ?? path;
|
|
73
|
+
|
|
74
|
+
const sepChar = path.includes("\\") ? "\\" : "/";
|
|
75
|
+
const gsdMarker = `${sepChar}.gsd${sepChar}`;
|
|
76
|
+
const markerIdx = path.indexOf(gsdMarker);
|
|
77
|
+
const candidate = markerIdx !== -1
|
|
78
|
+
? path.slice(0, markerIdx)
|
|
79
|
+
: path.slice(0, segment.gsdIdx);
|
|
80
|
+
|
|
81
|
+
const gsdHome = normalizeWorktreePathForCompare(process.env.GSD_HOME || join(homedir(), ".gsd"));
|
|
82
|
+
const candidateGsdPath = normalizeWorktreePathForCompare(join(candidate, ".gsd"));
|
|
83
|
+
|
|
84
|
+
if (candidateGsdPath === gsdHome || candidateGsdPath.startsWith(`${gsdHome}/`)) {
|
|
85
|
+
const realRoot = resolveProjectRootFromGitFile(path);
|
|
86
|
+
return realRoot ?? path;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return candidate;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function resolveGitWorkingTreeRoot(path: string): string | null {
|
|
93
|
+
try {
|
|
94
|
+
let dir = existsSync(path) && !statSync(path).isDirectory()
|
|
95
|
+
? resolve(path, "..")
|
|
96
|
+
: path;
|
|
97
|
+
|
|
98
|
+
for (let i = 0; i < 30; i++) {
|
|
99
|
+
const gitPath = join(dir, ".git");
|
|
100
|
+
if (existsSync(gitPath)) return dir;
|
|
101
|
+
|
|
102
|
+
const parent = resolve(dir, "..");
|
|
103
|
+
if (parent === dir) break;
|
|
104
|
+
dir = parent;
|
|
105
|
+
}
|
|
106
|
+
} catch {
|
|
107
|
+
// Non-fatal: callers either keep the original path or fail closed.
|
|
108
|
+
}
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function resolveProjectRootFromGitFile(worktreePath: string): string | null {
|
|
113
|
+
try {
|
|
114
|
+
let dir = worktreePath;
|
|
115
|
+
for (let i = 0; i < 30; i++) {
|
|
116
|
+
const gitPath = join(dir, ".git");
|
|
117
|
+
if (existsSync(gitPath)) {
|
|
118
|
+
const content = readFileSync(gitPath, "utf8").trim();
|
|
119
|
+
if (content.startsWith("gitdir: ")) {
|
|
120
|
+
const gitDir = resolve(dir, content.slice(8));
|
|
121
|
+
const dotGitDir = resolve(gitDir, "..", "..");
|
|
122
|
+
if (dotGitDir.endsWith(".git") || dotGitDir.endsWith(".git/") || dotGitDir.endsWith(".git\\")) {
|
|
123
|
+
return resolve(dotGitDir, "..");
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const commonDirPath = join(gitDir, "commondir");
|
|
127
|
+
if (existsSync(commonDirPath)) {
|
|
128
|
+
const commonDir = readFileSync(commonDirPath, "utf8").trim();
|
|
129
|
+
const resolvedCommonDir = resolve(gitDir, commonDir);
|
|
130
|
+
return resolve(resolvedCommonDir, "..");
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const parent = resolve(dir, "..");
|
|
137
|
+
if (parent === dir) break;
|
|
138
|
+
dir = parent;
|
|
139
|
+
}
|
|
140
|
+
} catch {
|
|
141
|
+
// Non-fatal: callers either keep the original path or fail closed.
|
|
142
|
+
}
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// GSD worktree session state
|
|
2
|
+
let originalCwd: string | null = null;
|
|
3
|
+
|
|
4
|
+
export function getWorktreeOriginalCwd(): string | null {
|
|
5
|
+
return originalCwd;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function setWorktreeOriginalCwd(cwd: string): void {
|
|
9
|
+
originalCwd = cwd;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function clearWorktreeOriginalCwd(): void {
|
|
13
|
+
originalCwd = null;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function ensureWorktreeOriginalCwdFromPath(cwd: string = process.cwd()): string | null {
|
|
17
|
+
if (originalCwd) return originalCwd;
|
|
18
|
+
const marker = `${/\\/.test(cwd) ? "\\" : "/"}.gsd${/\\/.test(cwd) ? "\\" : "/"}worktrees${/\\/.test(cwd) ? "\\" : "/"}`;
|
|
19
|
+
const markerIdx = cwd.indexOf(marker);
|
|
20
|
+
if (markerIdx !== -1) {
|
|
21
|
+
originalCwd = cwd.slice(0, markerIdx);
|
|
22
|
+
}
|
|
23
|
+
return originalCwd;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function getActiveWorktreeName(): string | null {
|
|
27
|
+
if (!originalCwd) return null;
|
|
28
|
+
const cwd = process.cwd();
|
|
29
|
+
const wtDir = `${originalCwd.replace(/[\\/]+$/, "")}/.gsd/worktrees`.replaceAll("\\", "/");
|
|
30
|
+
const normalizedCwd = cwd.replaceAll("\\", "/");
|
|
31
|
+
if (!normalizedCwd.startsWith(`${wtDir}/`)) return null;
|
|
32
|
+
const rel = normalizedCwd.slice(wtDir.length + 1);
|
|
33
|
+
const name = rel.split("/")[0];
|
|
34
|
+
return name || null;
|
|
35
|
+
}
|
|
@@ -12,12 +12,16 @@
|
|
|
12
12
|
* SLICE_BRANCH_RE) remain for backwards compatibility with legacy branches.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import { existsSync, readFileSync,
|
|
16
|
-
import { join, resolve
|
|
17
|
-
import { homedir } from "node:os";
|
|
15
|
+
import { existsSync, readFileSync, utimesSync } from "node:fs";
|
|
16
|
+
import { join, resolve } from "node:path";
|
|
18
17
|
|
|
19
18
|
import { GitServiceImpl, writeIntegrationBranch, type TaskCommitContext } from "./git-service.js";
|
|
20
19
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
20
|
+
import {
|
|
21
|
+
findWorktreeSegment,
|
|
22
|
+
resolveWorktreeProjectRoot,
|
|
23
|
+
} from "./worktree-root.js";
|
|
24
|
+
export { resolveWorktreeProjectRoot } from "./worktree-root.js";
|
|
21
25
|
|
|
22
26
|
export { MergeConflictError } from "./git-service.js";
|
|
23
27
|
export type { TaskCommitContext } from "./git-service.js";
|
|
@@ -78,29 +82,6 @@ export function captureIntegrationBranch(basePath: string, milestoneId: string):
|
|
|
78
82
|
|
|
79
83
|
// ─── Pure Utility Functions (unchanged) ────────────────────────────────────
|
|
80
84
|
|
|
81
|
-
/**
|
|
82
|
-
* Find the worktrees segment in a path, supporting both direct
|
|
83
|
-
* (`/.gsd/worktrees/`) and symlink-resolved (`/.gsd/projects/<hash>/worktrees/`)
|
|
84
|
-
* layouts. When `.gsd` is a symlink to `~/.gsd/projects/<hash>`, resolved
|
|
85
|
-
* paths contain the intermediate `projects/<hash>/` segment that the old
|
|
86
|
-
* single-marker check missed.
|
|
87
|
-
*/
|
|
88
|
-
function findWorktreeSegment(normalizedPath: string): { gsdIdx: number; afterWorktrees: number } | null {
|
|
89
|
-
// Direct layout: /.gsd/worktrees/<name>
|
|
90
|
-
const directMarker = "/.gsd/worktrees/";
|
|
91
|
-
const idx = normalizedPath.indexOf(directMarker);
|
|
92
|
-
if (idx !== -1) {
|
|
93
|
-
return { gsdIdx: idx, afterWorktrees: idx + directMarker.length };
|
|
94
|
-
}
|
|
95
|
-
// Symlink-resolved layout: /.gsd/projects/<hash>/worktrees/<name>
|
|
96
|
-
const symlinkRe = /\/\.gsd\/projects\/[a-f0-9]+\/worktrees\//;
|
|
97
|
-
const match = normalizedPath.match(symlinkRe);
|
|
98
|
-
if (match && match.index !== undefined) {
|
|
99
|
-
return { gsdIdx: match.index, afterWorktrees: match.index + match[0].length };
|
|
100
|
-
}
|
|
101
|
-
return null;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
85
|
/**
|
|
105
86
|
* Detect the active worktree name from the current working directory.
|
|
106
87
|
* Returns null if not inside a GSD worktree (.gsd/worktrees/<name>/).
|
|
@@ -133,99 +114,7 @@ export function detectWorktreeName(basePath: string): string | null {
|
|
|
133
114
|
* operate against the real project root, not a worktree subdirectory.
|
|
134
115
|
*/
|
|
135
116
|
export function resolveProjectRoot(basePath: string): string {
|
|
136
|
-
|
|
137
|
-
if (process.env.GSD_PROJECT_ROOT) {
|
|
138
|
-
return process.env.GSD_PROJECT_ROOT;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
const normalizedPath = basePath.replaceAll("\\", "/");
|
|
142
|
-
const seg = findWorktreeSegment(normalizedPath);
|
|
143
|
-
if (!seg) return basePath;
|
|
144
|
-
|
|
145
|
-
// Candidate root via the string-slice heuristic
|
|
146
|
-
const sepChar = basePath.includes("\\") ? "\\" : "/";
|
|
147
|
-
const gsdMarker = `${sepChar}.gsd${sepChar}`;
|
|
148
|
-
const gsdIdx = basePath.indexOf(gsdMarker);
|
|
149
|
-
const candidate = gsdIdx !== -1
|
|
150
|
-
? basePath.slice(0, gsdIdx)
|
|
151
|
-
: basePath.slice(0, seg.gsdIdx);
|
|
152
|
-
|
|
153
|
-
// Layer 2: Guard against resolving to the user's home directory.
|
|
154
|
-
// When .gsd is a symlink into ~/.gsd/projects/<hash>, the resolved path
|
|
155
|
-
// contains /.gsd/ at the user-level boundary. Slicing there yields ~ — wrong.
|
|
156
|
-
const gsdHome = normalizePathForCompare(process.env.GSD_HOME || join(homedir(), ".gsd"));
|
|
157
|
-
const candidateGsdPath = normalizePathForCompare(join(candidate, ".gsd"));
|
|
158
|
-
|
|
159
|
-
if (candidateGsdPath === gsdHome || candidateGsdPath.startsWith(gsdHome + "/")) {
|
|
160
|
-
// The candidate is the home directory (or within it in a way that .gsd
|
|
161
|
-
// maps to the user-level GSD dir). Try to recover the real project root
|
|
162
|
-
// from the worktree's .git file.
|
|
163
|
-
const realRoot = resolveProjectRootFromGitFile(basePath);
|
|
164
|
-
if (realRoot) return realRoot;
|
|
165
|
-
// If git file resolution failed, return basePath unchanged rather than ~
|
|
166
|
-
return basePath;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
return candidate;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Recover the real project root from a worktree's .git file.
|
|
174
|
-
*
|
|
175
|
-
* Each git worktree has a `.git` file (not directory) containing:
|
|
176
|
-
* gitdir: /real/project/.git/worktrees/<name>
|
|
177
|
-
*
|
|
178
|
-
* Walking up from that gitdir gives us `/real/project/.git`, and its
|
|
179
|
-
* parent is the real project root.
|
|
180
|
-
*/
|
|
181
|
-
function resolveProjectRootFromGitFile(worktreePath: string): string | null {
|
|
182
|
-
try {
|
|
183
|
-
// Walk up from the worktree path to find the .git file
|
|
184
|
-
let dir = worktreePath;
|
|
185
|
-
for (let i = 0; i < 30; i++) {
|
|
186
|
-
const gitPath = join(dir, ".git");
|
|
187
|
-
if (existsSync(gitPath)) {
|
|
188
|
-
const content = readFileSync(gitPath, "utf8").trim();
|
|
189
|
-
if (content.startsWith("gitdir: ")) {
|
|
190
|
-
// gitdir points to: <real-project>/.git/worktrees/<name>
|
|
191
|
-
const gitDir = resolve(dir, content.slice(8));
|
|
192
|
-
// Walk up: .git/worktrees/<name> → .git/worktrees → .git → project root
|
|
193
|
-
const dotGitDir = resolve(gitDir, "..", "..");
|
|
194
|
-
// Verify this looks like a .git directory
|
|
195
|
-
if (dotGitDir.endsWith(".git") || dotGitDir.endsWith(".git/") || dotGitDir.endsWith(".git\\")) {
|
|
196
|
-
return resolve(dotGitDir, "..");
|
|
197
|
-
}
|
|
198
|
-
// Alternative: the commondir file inside the worktree gitdir
|
|
199
|
-
// points to the main .git directory
|
|
200
|
-
const commonDirPath = join(gitDir, "commondir");
|
|
201
|
-
if (existsSync(commonDirPath)) {
|
|
202
|
-
const commonDir = readFileSync(commonDirPath, "utf8").trim();
|
|
203
|
-
const resolvedCommonDir = resolve(gitDir, commonDir);
|
|
204
|
-
return resolve(resolvedCommonDir, "..");
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
break;
|
|
208
|
-
}
|
|
209
|
-
const parent = resolve(dir, "..");
|
|
210
|
-
if (parent === dir) break;
|
|
211
|
-
dir = parent;
|
|
212
|
-
}
|
|
213
|
-
} catch {
|
|
214
|
-
// Non-fatal — caller will use fallback
|
|
215
|
-
}
|
|
216
|
-
return null;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
function normalizePathForCompare(path: string): string {
|
|
220
|
-
let normalized: string;
|
|
221
|
-
try {
|
|
222
|
-
normalized = realpathSync(path);
|
|
223
|
-
} catch {
|
|
224
|
-
normalized = resolve(path);
|
|
225
|
-
}
|
|
226
|
-
const slashed = normalized.replaceAll("\\", "/");
|
|
227
|
-
const trimmed = slashed.replace(/\/+$/, "");
|
|
228
|
-
return trimmed || "/";
|
|
117
|
+
return resolveWorktreeProjectRoot(basePath);
|
|
229
118
|
}
|
|
230
119
|
|
|
231
120
|
/**
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* MCP Client Extension — Native MCP server integration for pi
|
|
3
3
|
*
|
|
4
4
|
* Provides on-demand access to MCP servers configured in project files
|
|
5
|
-
* (.mcp.json, .gsd/mcp.json)
|
|
5
|
+
* (.mcp.json, .gsd/mcp.json) and the global ~/.gsd/mcp.json (or
|
|
6
|
+
* $GSD_HOME/mcp.json) using the @modelcontextprotocol/sdk Client
|
|
6
7
|
* directly — no external CLI dependency required.
|
|
7
8
|
*
|
|
8
9
|
* Three tools:
|
|
@@ -24,6 +25,7 @@ import { Client } from "@modelcontextprotocol/sdk/client";
|
|
|
24
25
|
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
25
26
|
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
26
27
|
import { readFileSync, existsSync } from "node:fs";
|
|
28
|
+
import { homedir } from "node:os";
|
|
27
29
|
import { join } from "node:path";
|
|
28
30
|
import { buildHttpTransportOpts } from "./auth.js";
|
|
29
31
|
import type { McpHttpAuthConfig } from "./auth.js";
|
|
@@ -102,6 +104,7 @@ function readConfigs(): McpServerConfig[] {
|
|
|
102
104
|
const configPaths = [
|
|
103
105
|
join(process.cwd(), ".mcp.json"),
|
|
104
106
|
join(process.cwd(), ".gsd", "mcp.json"),
|
|
107
|
+
join(process.env.GSD_HOME || join(homedir(), ".gsd"), "mcp.json"),
|
|
105
108
|
];
|
|
106
109
|
|
|
107
110
|
for (const configPath of configPaths) {
|
|
@@ -321,7 +324,7 @@ async function closeAll(): Promise<void> {
|
|
|
321
324
|
// ─── Formatters ───────────────────────────────────────────────────────────────
|
|
322
325
|
|
|
323
326
|
function formatServerList(servers: McpServerConfig[]): string {
|
|
324
|
-
if (servers.length === 0) return "No MCP servers configured. Add servers to .mcp.json or .gsd/mcp.json.";
|
|
327
|
+
if (servers.length === 0) return "No MCP servers configured. Add servers to .mcp.json, .gsd/mcp.json, or $GSD_HOME/mcp.json (default: ~/.gsd/mcp.json).";
|
|
325
328
|
|
|
326
329
|
const lines: string[] = [`${servers.length} MCP servers configured:\n`];
|
|
327
330
|
|
|
@@ -384,7 +387,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
384
387
|
name: "mcp_servers",
|
|
385
388
|
label: "MCP Servers",
|
|
386
389
|
description:
|
|
387
|
-
"List all available MCP servers configured in project files (.mcp.json, .gsd/mcp.json). " +
|
|
390
|
+
"List all available MCP servers configured in project files (.mcp.json, .gsd/mcp.json) or globally ($GSD_HOME/mcp.json, default: ~/.gsd/mcp.json). " +
|
|
388
391
|
"Shows server names, transport type, and connection status. Use mcp_discover to get full tool schemas for a server.",
|
|
389
392
|
promptSnippet:
|
|
390
393
|
"List available MCP servers from project configuration",
|
|
@@ -624,13 +627,6 @@ export default function (pi: ExtensionAPI) {
|
|
|
624
627
|
|
|
625
628
|
// ── Lifecycle ─────────────────────────────────────────────────────────────
|
|
626
629
|
|
|
627
|
-
pi.on("session_start", async (_event, ctx) => {
|
|
628
|
-
const servers = readConfigs();
|
|
629
|
-
if (servers.length > 0) {
|
|
630
|
-
ctx.ui.notify(`MCP client ready — ${servers.length} server(s) configured`, "info");
|
|
631
|
-
}
|
|
632
|
-
});
|
|
633
|
-
|
|
634
630
|
pi.on("session_shutdown", async () => {
|
|
635
631
|
await closeAll();
|
|
636
632
|
});
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regression test for #4757 — readConfigs() must also read the global
|
|
3
|
+
* ~/.gsd/mcp.json (resolved as $GSD_HOME/mcp.json when GSD_HOME is set).
|
|
4
|
+
*
|
|
5
|
+
* Behaviour test against the exported getServerConfig — no source grep.
|
|
6
|
+
* The fixture is anchored via $GSD_HOME so the test never touches the
|
|
7
|
+
* developer's real ~/.gsd directory.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import test, { before, after } from "node:test";
|
|
11
|
+
import assert from "node:assert/strict";
|
|
12
|
+
import { writeFileSync, mkdtempSync, realpathSync, rmSync } from "node:fs";
|
|
13
|
+
import { tmpdir } from "node:os";
|
|
14
|
+
import { join } from "node:path";
|
|
15
|
+
|
|
16
|
+
import { getServerConfig } from "../index.js";
|
|
17
|
+
|
|
18
|
+
let cwdDir: string;
|
|
19
|
+
let gsdHomeDir: string;
|
|
20
|
+
let originalCwd: string;
|
|
21
|
+
let originalGsdHome: string | undefined;
|
|
22
|
+
|
|
23
|
+
before(() => {
|
|
24
|
+
originalCwd = process.cwd();
|
|
25
|
+
originalGsdHome = process.env.GSD_HOME;
|
|
26
|
+
|
|
27
|
+
// realpathSync resolves any symlink in tmpdir() — on macOS /var → /private/var
|
|
28
|
+
// so process.cwd() after chdir matches what mkdtempSync returned.
|
|
29
|
+
cwdDir = realpathSync(mkdtempSync(join(tmpdir(), "mcp-cwd-")));
|
|
30
|
+
gsdHomeDir = realpathSync(mkdtempSync(join(tmpdir(), "mcp-gsdhome-")));
|
|
31
|
+
|
|
32
|
+
// Project-local fixture (also defines `shared-server` for the precedence test)
|
|
33
|
+
writeFileSync(
|
|
34
|
+
join(cwdDir, ".mcp.json"),
|
|
35
|
+
JSON.stringify({
|
|
36
|
+
mcpServers: {
|
|
37
|
+
"project-server": { command: "echo", args: ["proj"] },
|
|
38
|
+
"shared-server": { command: "echo", args: ["from-project"] },
|
|
39
|
+
},
|
|
40
|
+
}),
|
|
41
|
+
"utf-8",
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
// Global fixture rooted at $GSD_HOME (also defines `shared-server` to test
|
|
45
|
+
// that project-local takes precedence on name collision)
|
|
46
|
+
writeFileSync(
|
|
47
|
+
join(gsdHomeDir, "mcp.json"),
|
|
48
|
+
JSON.stringify({
|
|
49
|
+
mcpServers: {
|
|
50
|
+
"global-server": { command: "echo", args: ["glob"] },
|
|
51
|
+
"shared-server": { command: "echo", args: ["from-global"] },
|
|
52
|
+
},
|
|
53
|
+
}),
|
|
54
|
+
"utf-8",
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
process.chdir(cwdDir);
|
|
58
|
+
process.env.GSD_HOME = gsdHomeDir;
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
after(() => {
|
|
62
|
+
process.chdir(originalCwd);
|
|
63
|
+
if (originalGsdHome === undefined) delete process.env.GSD_HOME;
|
|
64
|
+
else process.env.GSD_HOME = originalGsdHome;
|
|
65
|
+
try { rmSync(cwdDir, { recursive: true, force: true }); } catch { /* best-effort */ }
|
|
66
|
+
try { rmSync(gsdHomeDir, { recursive: true, force: true }); } catch { /* best-effort */ }
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test("#4757: getServerConfig resolves servers declared in $GSD_HOME/mcp.json", () => {
|
|
70
|
+
const cfg = getServerConfig("global-server");
|
|
71
|
+
assert.ok(cfg, "server defined in $GSD_HOME/mcp.json must resolve");
|
|
72
|
+
assert.equal(cfg?.name, "global-server");
|
|
73
|
+
assert.equal(cfg?.sourcePath, join(gsdHomeDir, "mcp.json"));
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test("#4757: project-local servers still resolve when global config exists", () => {
|
|
77
|
+
const cfg = getServerConfig("project-server");
|
|
78
|
+
assert.ok(cfg, "project-local server must continue to resolve");
|
|
79
|
+
assert.equal(cfg?.sourcePath, join(cwdDir, ".mcp.json"));
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test("#4757: project-local config wins on server-name collision", () => {
|
|
83
|
+
const cfg = getServerConfig("shared-server");
|
|
84
|
+
assert.ok(cfg, "shared server must resolve");
|
|
85
|
+
assert.equal(
|
|
86
|
+
cfg?.sourcePath,
|
|
87
|
+
join(cwdDir, ".mcp.json"),
|
|
88
|
+
"project-local config must take precedence over $GSD_HOME on name collision",
|
|
89
|
+
);
|
|
90
|
+
assert.deepEqual(cfg?.args, ["from-project"]);
|
|
91
|
+
});
|
|
@@ -119,17 +119,31 @@ export default function ollama(pi: ExtensionAPI) {
|
|
|
119
119
|
// In headless/auto mode, await the probe so the fallback resolver can
|
|
120
120
|
// see Ollama before the first LLM call (#3531 race condition).
|
|
121
121
|
// In interactive mode, keep it async for fast startup.
|
|
122
|
+
// Surface probe failures under GSD_DEBUG so users can diagnose silent
|
|
123
|
+
// "Ollama is missing from /model" reports without patching dist/. The
|
|
124
|
+
// probe still soft-fails (registration is best-effort) — we just stop
|
|
125
|
+
// dropping the error on the floor. See #4982.
|
|
126
|
+
const debugOllama = (where: string, error: unknown): void => {
|
|
127
|
+
if (process.env.GSD_DEBUG) {
|
|
128
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
129
|
+
process.stderr.write(`[ollama] ${where} probe failed: ${msg}\n`);
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
|
|
122
133
|
if (!ctx.hasUI) {
|
|
123
134
|
try {
|
|
124
135
|
await probeAndRegister(pi);
|
|
125
|
-
} catch {
|
|
136
|
+
} catch (error) {
|
|
137
|
+
debugOllama("headless", error);
|
|
138
|
+
}
|
|
126
139
|
} else {
|
|
127
140
|
probeAndRegister(pi)
|
|
128
141
|
.then((found) => {
|
|
129
142
|
ctx.ui.setStatus("ollama", found ? "Ollama" : undefined);
|
|
130
143
|
})
|
|
131
|
-
.catch(() => {
|
|
144
|
+
.catch((error) => {
|
|
132
145
|
ctx.ui.setStatus("ollama", undefined);
|
|
146
|
+
debugOllama("interactive", error);
|
|
133
147
|
});
|
|
134
148
|
}
|
|
135
149
|
});
|
|
@@ -56,10 +56,44 @@ const KNOWN_MODELS: Array<[pattern: string, caps: ModelCapability]> = [
|
|
|
56
56
|
["llama2", { contextWindow: 4096, maxTokens: 4096, ollamaOptions: { num_ctx: 4096 } }],
|
|
57
57
|
|
|
58
58
|
// ─── Qwen family ────────────────────────────────────────────────────
|
|
59
|
+
// Long-variant entries MUST appear before the bare `qwen3` base —
|
|
60
|
+
// `baseName.startsWith(pattern)` returns true for `qwen3.5`/`qwen3-coder`/
|
|
61
|
+
// `qwen3-next` against `qwen3`, and the first match wins (#4991).
|
|
62
|
+
// ref: qwen3-next 1M ctx — https://qwen.ai/blog?id=qwen3-next
|
|
63
|
+
["qwen3-next", { contextWindow: 1048576, maxTokens: 32768, ollamaOptions: { num_ctx: 1048576 } }],
|
|
64
|
+
// ref: qwen3-coder 256K ctx — https://qwenlm.github.io/blog/qwen3-coder/
|
|
65
|
+
["qwen3-coder", { contextWindow: 262144, maxTokens: 32768, ollamaOptions: { num_ctx: 262144 } }],
|
|
66
|
+
// ref: qwen3.5 / qwen3.6 1M ctx — Ollama Cloud release notes
|
|
67
|
+
["qwen3.6", { contextWindow: 1048576, maxTokens: 32768, ollamaOptions: { num_ctx: 1048576 } }],
|
|
68
|
+
["qwen3.5", { contextWindow: 1048576, maxTokens: 32768, ollamaOptions: { num_ctx: 1048576 } }],
|
|
59
69
|
["qwen3", { contextWindow: 131072, maxTokens: 32768, ollamaOptions: { num_ctx: 131072 } }],
|
|
60
70
|
["qwen2.5", { contextWindow: 131072, maxTokens: 32768, ollamaOptions: { num_ctx: 131072 } }],
|
|
61
71
|
["qwen2", { contextWindow: 131072, maxTokens: 32768, ollamaOptions: { num_ctx: 131072 } }],
|
|
62
72
|
|
|
73
|
+
// ─── GLM family (Z.ai, Ollama Cloud) ────────────────────────────────
|
|
74
|
+
// ref: glm 4.6 / 5.x 200K ctx — https://docs.z.ai/devpack/using5.1
|
|
75
|
+
// Long-variant entries before bare `glm-5` / `glm-4` would-be bases to
|
|
76
|
+
// avoid prefix shadowing (#4991).
|
|
77
|
+
["glm-5.1", { contextWindow: 204800, maxTokens: 16384, ollamaOptions: { num_ctx: 204800 } }],
|
|
78
|
+
["glm-5", { contextWindow: 204800, maxTokens: 16384, ollamaOptions: { num_ctx: 204800 } }],
|
|
79
|
+
["glm-4.6", { contextWindow: 204800, maxTokens: 16384, ollamaOptions: { num_ctx: 204800 } }],
|
|
80
|
+
["glm-4", { contextWindow: 131072, maxTokens: 16384, ollamaOptions: { num_ctx: 131072 } }],
|
|
81
|
+
|
|
82
|
+
// ─── Kimi K2 (Moonshot, Ollama Cloud) ──────────────────────────────
|
|
83
|
+
// ref: kimi-k2 256K ctx — https://platform.moonshot.ai/docs
|
|
84
|
+
// Same shadowing concern: kimi-k2-thinking and kimi-k2.{5,6} must
|
|
85
|
+
// match before any future bare `kimi-k2` entry (#4991).
|
|
86
|
+
["kimi-k2-thinking", { contextWindow: 262144, maxTokens: 16384, ollamaOptions: { num_ctx: 262144 } }],
|
|
87
|
+
["kimi-k2.6", { contextWindow: 262144, maxTokens: 16384, ollamaOptions: { num_ctx: 262144 } }],
|
|
88
|
+
["kimi-k2.5", { contextWindow: 262144, maxTokens: 16384, ollamaOptions: { num_ctx: 262144 } }],
|
|
89
|
+
["kimi-k2", { contextWindow: 262144, maxTokens: 16384, ollamaOptions: { num_ctx: 262144 } }],
|
|
90
|
+
|
|
91
|
+
// ─── MiniMax M2 (Ollama Cloud) ─────────────────────────────────────
|
|
92
|
+
// ref: minimax-m2 1M ctx — https://www.minimax.io/news/minimax-m2
|
|
93
|
+
["minimax-m2.7", { contextWindow: 1048576, maxTokens: 16384, ollamaOptions: { num_ctx: 1048576 } }],
|
|
94
|
+
["minimax-m2.5", { contextWindow: 1048576, maxTokens: 16384, ollamaOptions: { num_ctx: 1048576 } }],
|
|
95
|
+
["minimax-m2", { contextWindow: 1048576, maxTokens: 16384, ollamaOptions: { num_ctx: 1048576 } }],
|
|
96
|
+
|
|
63
97
|
// ─── Gemma family ───────────────────────────────────────────────────
|
|
64
98
|
["gemma3", { contextWindow: 131072, maxTokens: 16384, ollamaOptions: { num_ctx: 131072 } }],
|
|
65
99
|
["gemma2", { contextWindow: 8192, maxTokens: 8192, ollamaOptions: { num_ctx: 8192 } }],
|
|
@@ -19,8 +19,45 @@ import type {
|
|
|
19
19
|
import { parseNDJsonStream } from "./ndjson-stream.js";
|
|
20
20
|
|
|
21
21
|
const DEFAULT_HOST = "http://localhost:11434";
|
|
22
|
-
const
|
|
23
|
-
const
|
|
22
|
+
const DEFAULT_PROBE_TIMEOUT_MS = 1500;
|
|
23
|
+
const DEFAULT_REQUEST_TIMEOUT_MS = 10000;
|
|
24
|
+
export const MAX_TIMER_DELAY_MS = 2_147_483_647;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Parse a positive integer from an environment variable, falling back to
|
|
28
|
+
* `fallback` when the var is unset, empty, non-numeric, zero, or negative.
|
|
29
|
+
*
|
|
30
|
+
* Defensive parsing: a typo like `OLLAMA_PROBE_TIMEOUT_MS=abc` or
|
|
31
|
+
* `OLLAMA_PROBE_TIMEOUT_MS=0` should not silently disable the timeout —
|
|
32
|
+
* fall back to the documented default instead.
|
|
33
|
+
*/
|
|
34
|
+
export function envPositiveInt(name: string, fallback: number): number {
|
|
35
|
+
const raw = process.env[name];
|
|
36
|
+
if (!raw) return fallback;
|
|
37
|
+
const parsed = Number.parseInt(raw, 10);
|
|
38
|
+
if (!Number.isFinite(parsed) || parsed <= 0) return fallback;
|
|
39
|
+
return Math.min(parsed, MAX_TIMER_DELAY_MS);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Effective probe timeout for the startup `isRunning()` health check.
|
|
44
|
+
* Override with `OLLAMA_PROBE_TIMEOUT_MS=<ms>` for slower networks (LAN
|
|
45
|
+
* Ollama hosts, cloud endpoints, contended cold starts).
|
|
46
|
+
*
|
|
47
|
+
* Resolved at call time — tests and downstream callers can mutate
|
|
48
|
+
* `process.env` between invocations and pick up the new value.
|
|
49
|
+
*/
|
|
50
|
+
export function getProbeTimeoutMs(): number {
|
|
51
|
+
return envPositiveInt("OLLAMA_PROBE_TIMEOUT_MS", DEFAULT_PROBE_TIMEOUT_MS);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Effective per-request timeout for REST calls. Override with
|
|
56
|
+
* `OLLAMA_REQUEST_TIMEOUT_MS=<ms>`.
|
|
57
|
+
*/
|
|
58
|
+
export function getRequestTimeoutMs(): number {
|
|
59
|
+
return envPositiveInt("OLLAMA_REQUEST_TIMEOUT_MS", DEFAULT_REQUEST_TIMEOUT_MS);
|
|
60
|
+
}
|
|
24
61
|
|
|
25
62
|
/**
|
|
26
63
|
* Get the Ollama host URL from OLLAMA_HOST or default.
|
|
@@ -57,7 +94,7 @@ function withAuth(options: RequestInit = {}): RequestInit {
|
|
|
57
94
|
};
|
|
58
95
|
}
|
|
59
96
|
|
|
60
|
-
async function fetchWithTimeout(url: string, options: RequestInit = {}, timeoutMs =
|
|
97
|
+
async function fetchWithTimeout(url: string, options: RequestInit = {}, timeoutMs = getRequestTimeoutMs()): Promise<Response> {
|
|
61
98
|
const controller = new AbortController();
|
|
62
99
|
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
63
100
|
try {
|
|
@@ -77,7 +114,7 @@ export async function isRunning(): Promise<boolean> {
|
|
|
77
114
|
const host = getOllamaHost();
|
|
78
115
|
const isCloud = host.includes("ollama.com") || host.includes("cloud");
|
|
79
116
|
const probeUrl = isCloud ? `${host}/api/tags` : `${host}/`;
|
|
80
|
-
const timeout = isCloud ?
|
|
117
|
+
const timeout = isCloud ? getRequestTimeoutMs() : getProbeTimeoutMs();
|
|
81
118
|
const response = await fetchWithTimeout(probeUrl, isCloud ? { method: "GET" } : {}, timeout);
|
|
82
119
|
return response.ok;
|
|
83
120
|
} catch {
|