gsd-pi 2.78.0 → 2.78.1-dev.8a893322c
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 +3 -1
- 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-dispatch.js +18 -6
- package/dist/resources/extensions/gsd/auto-prompts.js +63 -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 +14 -5
- 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/plan-slice.md +10 -0
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +10 -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/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 +15 -15
- 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 +15 -15
- 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 +3 -1
- 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-dispatch.ts +18 -6
- package/src/resources/extensions/gsd/auto-prompts.ts +60 -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 +14 -4
- 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/plan-slice.md +10 -0
- package/src/resources/extensions/gsd/prompts/refine-slice.md +10 -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 +178 -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-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/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 → QK8fABiGPmonfTgboN0Y9}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{C1zT2kEfoLhDdbWPWKrXd → QK8fABiGPmonfTgboN0Y9}/_ssgManifest.js +0 -0
|
@@ -33,29 +33,21 @@ import { inferCommitType } from "./git-service.js";
|
|
|
33
33
|
import type { FileLineStat } from "./worktree-manager.js";
|
|
34
34
|
import { existsSync, realpathSync, readdirSync, rmSync, unlinkSync } from "node:fs";
|
|
35
35
|
import { nativeMergeAbort } from "./native-git-bridge.js";
|
|
36
|
-
import { join
|
|
36
|
+
import { join } from "node:path";
|
|
37
|
+
import {
|
|
38
|
+
clearWorktreeOriginalCwd,
|
|
39
|
+
ensureWorktreeOriginalCwdFromPath,
|
|
40
|
+
getActiveWorktreeName,
|
|
41
|
+
getWorktreeOriginalCwd,
|
|
42
|
+
setWorktreeOriginalCwd,
|
|
43
|
+
} from "./worktree-session-state.js";
|
|
44
|
+
|
|
45
|
+
export { getActiveWorktreeName, getWorktreeOriginalCwd } from "./worktree-session-state.js";
|
|
37
46
|
|
|
38
47
|
/**
|
|
39
48
|
* Tracks the original project root so we can switch back.
|
|
40
49
|
* Set when we first chdir into a worktree, cleared on return.
|
|
41
50
|
*/
|
|
42
|
-
let originalCwd: string | null = null;
|
|
43
|
-
|
|
44
|
-
/** Get the original project root if currently in a worktree, or null. */
|
|
45
|
-
export function getWorktreeOriginalCwd(): string | null {
|
|
46
|
-
return originalCwd;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/** Get the name of the active worktree, or null if not in one. */
|
|
50
|
-
export function getActiveWorktreeName(): string | null {
|
|
51
|
-
if (!originalCwd) return null;
|
|
52
|
-
const cwd = process.cwd();
|
|
53
|
-
const wtDir = join(originalCwd, ".gsd", "worktrees");
|
|
54
|
-
if (!cwd.startsWith(wtDir)) return null;
|
|
55
|
-
const rel = cwd.slice(wtDir.length + 1);
|
|
56
|
-
const name = rel.split("/")[0] ?? rel.split("\\")[0];
|
|
57
|
-
return name || null;
|
|
58
|
-
}
|
|
59
51
|
|
|
60
52
|
// ─── Shared completions and handler (used by both /worktree and /wt) ────────
|
|
61
53
|
|
|
@@ -145,7 +137,7 @@ async function worktreeHandler(
|
|
|
145
137
|
return;
|
|
146
138
|
}
|
|
147
139
|
// create and switch both do the same thing: switch if exists, create if not
|
|
148
|
-
const mainBase =
|
|
140
|
+
const mainBase = getWorktreeOriginalCwd() ?? basePath;
|
|
149
141
|
const existing = listWorktrees(mainBase);
|
|
150
142
|
if (existing.some(wt => wt.name === name)) {
|
|
151
143
|
await handleSwitch(basePath, name, ctx);
|
|
@@ -157,7 +149,7 @@ async function worktreeHandler(
|
|
|
157
149
|
|
|
158
150
|
if (trimmed === "merge" || trimmed.startsWith("merge ")) {
|
|
159
151
|
const mergeArgs = trimmed.replace(/^merge\s*/, "").trim().split(/\s+/).filter(Boolean);
|
|
160
|
-
const mainBase =
|
|
152
|
+
const mainBase = getWorktreeOriginalCwd() ?? basePath;
|
|
161
153
|
const activeWt = getActiveWorktreeName();
|
|
162
154
|
|
|
163
155
|
if (mergeArgs.length === 0) {
|
|
@@ -191,7 +183,7 @@ async function worktreeHandler(
|
|
|
191
183
|
|
|
192
184
|
if (trimmed === "remove" || trimmed.startsWith("remove ")) {
|
|
193
185
|
const name = trimmed.replace(/^remove\s*/, "").trim();
|
|
194
|
-
const mainBase =
|
|
186
|
+
const mainBase = getWorktreeOriginalCwd() ?? basePath;
|
|
195
187
|
|
|
196
188
|
if (name === "all") {
|
|
197
189
|
await handleRemoveAll(mainBase, ctx);
|
|
@@ -213,7 +205,7 @@ async function worktreeHandler(
|
|
|
213
205
|
return;
|
|
214
206
|
}
|
|
215
207
|
|
|
216
|
-
const mainBase =
|
|
208
|
+
const mainBase = getWorktreeOriginalCwd() ?? basePath;
|
|
217
209
|
const nameOnly = trimmed.split(/\s+/)[0]!;
|
|
218
210
|
if (trimmed !== nameOnly) {
|
|
219
211
|
ctx.ui.notify(`Unknown command. Did you mean /${alias} switch ${nameOnly}?`, "warning");
|
|
@@ -241,14 +233,7 @@ export function registerWorktreeCommand(pi: ExtensionAPI): void {
|
|
|
241
233
|
// Restore worktree state after /reload.
|
|
242
234
|
// The module-level originalCwd resets to null when extensions are re-loaded,
|
|
243
235
|
// but process.cwd() is still inside the worktree. Detect this and recover.
|
|
244
|
-
|
|
245
|
-
const cwd = process.cwd();
|
|
246
|
-
const marker = `${sep}.gsd${sep}worktrees${sep}`;
|
|
247
|
-
const markerIdx = cwd.indexOf(marker);
|
|
248
|
-
if (markerIdx !== -1) {
|
|
249
|
-
originalCwd = cwd.slice(0, markerIdx);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
236
|
+
ensureWorktreeOriginalCwdFromPath();
|
|
252
237
|
|
|
253
238
|
pi.registerCommand("worktree", {
|
|
254
239
|
description: "Git worktrees (also /wt): /worktree <name> | list | merge | remove",
|
|
@@ -320,7 +305,7 @@ async function handleCreate(
|
|
|
320
305
|
const commitMsg = autoCommitCurrentBranch(basePath, "worktree-switch", name);
|
|
321
306
|
|
|
322
307
|
// Create from the main tree, not from inside another worktree
|
|
323
|
-
const mainBase =
|
|
308
|
+
const mainBase = getWorktreeOriginalCwd() ?? basePath;
|
|
324
309
|
const info = createWorktree(mainBase, name);
|
|
325
310
|
|
|
326
311
|
// Run user-configured post-create hook (#597) — e.g. copy .env, symlink assets
|
|
@@ -330,7 +315,7 @@ async function handleCreate(
|
|
|
330
315
|
}
|
|
331
316
|
|
|
332
317
|
// Track original cwd before switching
|
|
333
|
-
if (!
|
|
318
|
+
if (!getWorktreeOriginalCwd()) setWorktreeOriginalCwd(basePath);
|
|
334
319
|
|
|
335
320
|
const prevCwd = process.cwd();
|
|
336
321
|
process.chdir(info.path);
|
|
@@ -390,7 +375,7 @@ async function handleSwitch(
|
|
|
390
375
|
ctx: ExtensionCommandContext,
|
|
391
376
|
): Promise<void> {
|
|
392
377
|
try {
|
|
393
|
-
const mainBase =
|
|
378
|
+
const mainBase = getWorktreeOriginalCwd() ?? basePath;
|
|
394
379
|
const wtPath = worktreePath(mainBase, name);
|
|
395
380
|
|
|
396
381
|
if (!existsSync(wtPath)) {
|
|
@@ -405,7 +390,7 @@ async function handleSwitch(
|
|
|
405
390
|
const commitMsg = autoCommitCurrentBranch(basePath, "worktree-switch", name);
|
|
406
391
|
|
|
407
392
|
// Track original cwd before switching
|
|
408
|
-
if (!
|
|
393
|
+
if (!getWorktreeOriginalCwd()) setWorktreeOriginalCwd(basePath);
|
|
409
394
|
|
|
410
395
|
const prevCwd = process.cwd();
|
|
411
396
|
process.chdir(wtPath);
|
|
@@ -433,6 +418,7 @@ async function handleSwitch(
|
|
|
433
418
|
}
|
|
434
419
|
|
|
435
420
|
async function handleReturn(ctx: ExtensionCommandContext): Promise<void> {
|
|
421
|
+
const originalCwd = getWorktreeOriginalCwd();
|
|
436
422
|
if (!originalCwd) {
|
|
437
423
|
ctx.ui.notify("Already in the main project tree.", "info");
|
|
438
424
|
return;
|
|
@@ -442,7 +428,7 @@ async function handleReturn(ctx: ExtensionCommandContext): Promise<void> {
|
|
|
442
428
|
const commitMsg = autoCommitCurrentBranch(process.cwd(), "worktree-return", "worktree");
|
|
443
429
|
|
|
444
430
|
const returnTo = originalCwd;
|
|
445
|
-
|
|
431
|
+
clearWorktreeOriginalCwd();
|
|
446
432
|
|
|
447
433
|
const prevCwd = process.cwd();
|
|
448
434
|
process.chdir(returnTo);
|
|
@@ -504,7 +490,7 @@ async function handleList(
|
|
|
504
490
|
ctx: ExtensionCommandContext,
|
|
505
491
|
): Promise<void> {
|
|
506
492
|
try {
|
|
507
|
-
const mainBase =
|
|
493
|
+
const mainBase = getWorktreeOriginalCwd() ?? basePath;
|
|
508
494
|
const worktrees = listWorktrees(mainBase);
|
|
509
495
|
|
|
510
496
|
if (worktrees.length === 0) {
|
|
@@ -552,6 +538,7 @@ async function handleList(
|
|
|
552
538
|
lines.push("");
|
|
553
539
|
}
|
|
554
540
|
|
|
541
|
+
const originalCwd = getWorktreeOriginalCwd();
|
|
555
542
|
if (originalCwd) {
|
|
556
543
|
lines.push(` ${CLR.label("main tree")} ${CLR.path(originalCwd)}`);
|
|
557
544
|
}
|
|
@@ -651,11 +638,11 @@ async function handleMerge(
|
|
|
651
638
|
|
|
652
639
|
// Switch to the main tree before merging.
|
|
653
640
|
// Must be on the main branch to run git merge --squash.
|
|
654
|
-
if (
|
|
641
|
+
if (getWorktreeOriginalCwd()) {
|
|
655
642
|
const prevCwd = process.cwd();
|
|
656
643
|
process.chdir(basePath);
|
|
657
644
|
nudgeGitBranchCache(prevCwd);
|
|
658
|
-
|
|
645
|
+
clearWorktreeOriginalCwd();
|
|
659
646
|
}
|
|
660
647
|
|
|
661
648
|
// --- Deterministic merge path (preferred) ---
|
|
@@ -754,7 +741,7 @@ async function handleRemove(
|
|
|
754
741
|
ctx: ExtensionCommandContext,
|
|
755
742
|
): Promise<void> {
|
|
756
743
|
try {
|
|
757
|
-
const mainBase =
|
|
744
|
+
const mainBase = getWorktreeOriginalCwd() ?? basePath;
|
|
758
745
|
|
|
759
746
|
// Validate the worktree exists before attempting removal
|
|
760
747
|
const worktrees = listWorktrees(mainBase);
|
|
@@ -779,9 +766,9 @@ async function handleRemove(
|
|
|
779
766
|
removeWorktree(mainBase, name, { deleteBranch: true });
|
|
780
767
|
|
|
781
768
|
// If we were in that worktree, removeWorktree chdir'd us out — clear tracking
|
|
782
|
-
if (
|
|
769
|
+
if (getWorktreeOriginalCwd() && process.cwd() !== prevCwd) {
|
|
783
770
|
nudgeGitBranchCache(prevCwd);
|
|
784
|
-
|
|
771
|
+
clearWorktreeOriginalCwd();
|
|
785
772
|
}
|
|
786
773
|
|
|
787
774
|
ctx.ui.notify(`${CLR.ok("✓")} Worktree ${CLR.name(name)} removed ${CLR.muted("(branch deleted)")}.`, "info");
|
|
@@ -796,7 +783,7 @@ async function handleRemoveAll(
|
|
|
796
783
|
ctx: ExtensionCommandContext,
|
|
797
784
|
): Promise<void> {
|
|
798
785
|
try {
|
|
799
|
-
const mainBase =
|
|
786
|
+
const mainBase = getWorktreeOriginalCwd() ?? basePath;
|
|
800
787
|
const worktrees = listWorktrees(mainBase);
|
|
801
788
|
|
|
802
789
|
if (worktrees.length === 0) {
|
|
@@ -830,9 +817,9 @@ async function handleRemoveAll(
|
|
|
830
817
|
}
|
|
831
818
|
|
|
832
819
|
// If we were in a worktree that got removed, clear tracking
|
|
833
|
-
if (
|
|
820
|
+
if (getWorktreeOriginalCwd() && process.cwd() !== prevCwd) {
|
|
834
821
|
nudgeGitBranchCache(prevCwd);
|
|
835
|
-
|
|
822
|
+
clearWorktreeOriginalCwd();
|
|
836
823
|
}
|
|
837
824
|
|
|
838
825
|
const lines: string[] = [];
|
|
@@ -39,6 +39,11 @@ import {
|
|
|
39
39
|
nativeWorktreeRemove,
|
|
40
40
|
} from "./native-git-bridge.js";
|
|
41
41
|
import { emitCanonicalRootRedirect } from "./worktree-telemetry.js";
|
|
42
|
+
import {
|
|
43
|
+
isGsdWorktreePath,
|
|
44
|
+
normalizeWorktreePathForCompare,
|
|
45
|
+
resolveWorktreeProjectRoot,
|
|
46
|
+
} from "./worktree-root.js";
|
|
42
47
|
|
|
43
48
|
// ─── Types ─────────────────────────────────────────────────────────────────
|
|
44
49
|
|
|
@@ -75,6 +80,20 @@ function normalizePathForComparison(path: string): string {
|
|
|
75
80
|
return process.platform === "win32" ? normalized.toLowerCase() : normalized;
|
|
76
81
|
}
|
|
77
82
|
|
|
83
|
+
function normalizeBasePathForWorktreeOps(basePath: string): string {
|
|
84
|
+
const resolved = resolveWorktreeProjectRoot(basePath);
|
|
85
|
+
if (
|
|
86
|
+
isGsdWorktreePath(basePath) &&
|
|
87
|
+
normalizeWorktreePathForCompare(resolved) === normalizeWorktreePathForCompare(basePath)
|
|
88
|
+
) {
|
|
89
|
+
throw new GSDError(
|
|
90
|
+
GSD_GIT_ERROR,
|
|
91
|
+
`Cannot resolve project root from worktree path: ${basePath}. Run the command from the project root or set GSD_PROJECT_ROOT.`,
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
return resolved;
|
|
95
|
+
}
|
|
96
|
+
|
|
78
97
|
// ─── resolveGitDir ─────────────────────────────────────────────────────────
|
|
79
98
|
|
|
80
99
|
/**
|
|
@@ -106,7 +125,7 @@ export function resolveGitDir(basePath: string): string {
|
|
|
106
125
|
}
|
|
107
126
|
|
|
108
127
|
export function worktreesDir(basePath: string): string {
|
|
109
|
-
return join(basePath, ".gsd", "worktrees");
|
|
128
|
+
return join(resolveWorktreeProjectRoot(basePath), ".gsd", "worktrees");
|
|
110
129
|
}
|
|
111
130
|
|
|
112
131
|
export function worktreePath(basePath: string, name: string): string {
|
|
@@ -195,6 +214,8 @@ export function resolveCanonicalMilestoneRoot(
|
|
|
195
214
|
* @param opts.branch — override the default `worktree/<name>` branch name
|
|
196
215
|
*/
|
|
197
216
|
export function createWorktree(basePath: string, name: string, opts: { branch?: string; startPoint?: string; reuseExistingBranch?: boolean } = {}): WorktreeInfo {
|
|
217
|
+
basePath = normalizeBasePathForWorktreeOps(basePath);
|
|
218
|
+
|
|
198
219
|
// Validate name: alphanumeric, hyphens, underscores only
|
|
199
220
|
if (!/^[a-zA-Z0-9_-]+$/.test(name)) {
|
|
200
221
|
throw new GSDError(GSD_PARSE_ERROR, `Invalid worktree name "${name}". Use only letters, numbers, hyphens, and underscores.`);
|
|
@@ -297,6 +318,8 @@ export function createWorktree(basePath: string, name: string, opts: { branch?:
|
|
|
297
318
|
* Uses native worktree list and filters to those under .gsd/worktrees/.
|
|
298
319
|
*/
|
|
299
320
|
export function listWorktrees(basePath: string): WorktreeInfo[] {
|
|
321
|
+
basePath = normalizeBasePathForWorktreeOps(basePath);
|
|
322
|
+
|
|
300
323
|
const baseVariants = [resolve(basePath)];
|
|
301
324
|
if (existsSync(basePath)) {
|
|
302
325
|
baseVariants.push(realpathSync(basePath));
|
|
@@ -459,6 +482,8 @@ export function removeWorktree(
|
|
|
459
482
|
name: string,
|
|
460
483
|
opts: { deleteBranch?: boolean; force?: boolean; branch?: string } = {},
|
|
461
484
|
): void {
|
|
485
|
+
basePath = normalizeBasePathForWorktreeOps(basePath);
|
|
486
|
+
|
|
462
487
|
let wtPath = worktreePath(basePath, name);
|
|
463
488
|
const branch = opts.branch ?? worktreeBranchName(name);
|
|
464
489
|
const { deleteBranch = true, force = true } = opts;
|
|
@@ -714,6 +739,8 @@ function parseDiffNameStatus(entries: { status: string; path: string }[]): Workt
|
|
|
714
739
|
* Returns a summary of added, modified, and removed GSD artifacts.
|
|
715
740
|
*/
|
|
716
741
|
export function diffWorktreeGSD(basePath: string, name: string): WorktreeDiffSummary {
|
|
742
|
+
basePath = normalizeBasePathForWorktreeOps(basePath);
|
|
743
|
+
|
|
717
744
|
const branch = worktreeBranchName(name);
|
|
718
745
|
const mainBranch = nativeDetectMainBranch(basePath);
|
|
719
746
|
|
|
@@ -729,6 +756,8 @@ export function diffWorktreeGSD(basePath: string, name: string): WorktreeDiffSum
|
|
|
729
756
|
* content, this correctly returns an empty diff.
|
|
730
757
|
*/
|
|
731
758
|
export function diffWorktreeAll(basePath: string, name: string): WorktreeDiffSummary {
|
|
759
|
+
basePath = normalizeBasePathForWorktreeOps(basePath);
|
|
760
|
+
|
|
732
761
|
const branch = worktreeBranchName(name);
|
|
733
762
|
const mainBranch = nativeDetectMainBranch(basePath);
|
|
734
763
|
|
|
@@ -742,6 +771,8 @@ export function diffWorktreeAll(basePath: string, name: string): WorktreeDiffSum
|
|
|
742
771
|
* Uses direct diff (not merge-base) so the preview matches the actual merge outcome.
|
|
743
772
|
*/
|
|
744
773
|
export function diffWorktreeNumstat(basePath: string, name: string): FileLineStat[] {
|
|
774
|
+
basePath = normalizeBasePathForWorktreeOps(basePath);
|
|
775
|
+
|
|
745
776
|
const branch = worktreeBranchName(name);
|
|
746
777
|
const mainBranch = nativeDetectMainBranch(basePath);
|
|
747
778
|
|
|
@@ -760,6 +791,8 @@ export function diffWorktreeNumstat(basePath: string, name: string): FileLineSta
|
|
|
760
791
|
* Returns the raw unified diff for LLM consumption.
|
|
761
792
|
*/
|
|
762
793
|
export function getWorktreeGSDDiff(basePath: string, name: string): string {
|
|
794
|
+
basePath = normalizeBasePathForWorktreeOps(basePath);
|
|
795
|
+
|
|
763
796
|
const branch = worktreeBranchName(name);
|
|
764
797
|
const mainBranch = nativeDetectMainBranch(basePath);
|
|
765
798
|
|
|
@@ -771,6 +804,8 @@ export function getWorktreeGSDDiff(basePath: string, name: string): string {
|
|
|
771
804
|
* Returns the raw unified diff for LLM consumption.
|
|
772
805
|
*/
|
|
773
806
|
export function getWorktreeCodeDiff(basePath: string, name: string): string {
|
|
807
|
+
basePath = normalizeBasePathForWorktreeOps(basePath);
|
|
808
|
+
|
|
774
809
|
const branch = worktreeBranchName(name);
|
|
775
810
|
const mainBranch = nativeDetectMainBranch(basePath);
|
|
776
811
|
|
|
@@ -781,6 +816,8 @@ export function getWorktreeCodeDiff(basePath: string, name: string): string {
|
|
|
781
816
|
* Get commit log for the worktree branch since it diverged from main.
|
|
782
817
|
*/
|
|
783
818
|
export function getWorktreeLog(basePath: string, name: string): string {
|
|
819
|
+
basePath = normalizeBasePathForWorktreeOps(basePath);
|
|
820
|
+
|
|
784
821
|
const branch = worktreeBranchName(name);
|
|
785
822
|
const mainBranch = nativeDetectMainBranch(basePath);
|
|
786
823
|
|
|
@@ -795,6 +832,8 @@ export function getWorktreeLog(basePath: string, name: string): string {
|
|
|
795
832
|
* Returns the merge commit message.
|
|
796
833
|
*/
|
|
797
834
|
export function mergeWorktreeToMain(basePath: string, name: string, commitMessage: string): string {
|
|
835
|
+
basePath = normalizeBasePathForWorktreeOps(basePath);
|
|
836
|
+
|
|
798
837
|
const branch = worktreeBranchName(name);
|
|
799
838
|
const mainBranch = nativeDetectMainBranch(basePath);
|
|
800
839
|
const current = nativeGetCurrentBranch(basePath);
|
|
@@ -23,6 +23,7 @@ import { emitJournalEvent } from "./journal.js";
|
|
|
23
23
|
import { emitWorktreeCreated, emitWorktreeMerged } from "./worktree-telemetry.js";
|
|
24
24
|
import { getCollapseCadence, getMilestoneResquash, resquashMilestoneOnMain } from "./slice-cadence.js";
|
|
25
25
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
26
|
+
import { resolveWorktreeProjectRoot } from "./worktree-root.js";
|
|
26
27
|
|
|
27
28
|
// ─── Dependency Interface ──────────────────────────────────────────────────
|
|
28
29
|
|
|
@@ -84,31 +85,20 @@ export interface NotifyCtx {
|
|
|
84
85
|
|
|
85
86
|
// ─── Path Helpers ──────────────────────────────────────────────────────────
|
|
86
87
|
|
|
87
|
-
/**
|
|
88
|
-
* Worktree marker segment — present in any path produced by worktreePath().
|
|
89
|
-
* Used to strip the worktree suffix and recover the project root (#3729).
|
|
90
|
-
*/
|
|
91
|
-
const WORKTREE_MARKER = "/.gsd/worktrees/";
|
|
92
|
-
|
|
93
88
|
/**
|
|
94
89
|
* Resolve the project root from session path state.
|
|
95
90
|
*
|
|
96
91
|
* Prefers `originalBasePath` (always the project root when set), but falls
|
|
97
92
|
* back to `basePath` when `originalBasePath` is falsy (e.g. fresh AutoSession
|
|
98
93
|
* with default empty string). If `basePath` itself is inside a worktree
|
|
99
|
-
* directory (
|
|
100
|
-
* actual project root
|
|
94
|
+
* directory (including symlink-resolved ~/.gsd/projects/<hash>/worktrees
|
|
95
|
+
* paths), recover the actual project root to prevent double nesting (#3729).
|
|
101
96
|
*/
|
|
102
97
|
export function resolveProjectRoot(
|
|
103
98
|
originalBasePath: string,
|
|
104
99
|
basePath: string,
|
|
105
100
|
): string {
|
|
106
|
-
|
|
107
|
-
const markerIdx = resolved.indexOf(WORKTREE_MARKER);
|
|
108
|
-
if (markerIdx !== -1) {
|
|
109
|
-
resolved = resolved.slice(0, markerIdx);
|
|
110
|
-
}
|
|
111
|
-
return resolved;
|
|
101
|
+
return resolveWorktreeProjectRoot(basePath, originalBasePath);
|
|
112
102
|
}
|
|
113
103
|
|
|
114
104
|
// ─── WorktreeResolver ──────────────────────────────────────────────────────
|
|
@@ -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
|
+
}
|