gsd-pi 2.78.0-dev.aeeb2ca00 → 2.78.1-dev.84a383f51
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 +7 -7
- package/dist/claude-cli-check.js +64 -37
- 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 +24 -4
- package/dist/headless.d.ts +10 -0
- package/dist/headless.js +16 -1
- package/dist/loader.js +7 -10
- 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 +28 -5
- package/dist/resources/.managed-resources-content-hash +1 -0
- package/dist/resources/extensions/claude-code-cli/readiness.js +77 -45
- package/dist/resources/extensions/gsd/auto/loop.js +23 -0
- package/dist/resources/extensions/gsd/auto/phases.js +2 -2
- package/dist/resources/extensions/gsd/auto/run-unit.js +3 -1
- package/dist/resources/extensions/gsd/auto/session.js +3 -0
- 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 +30 -0
- 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 +94 -31
- package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +11 -6
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +34 -8
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +38 -2
- package/dist/resources/extensions/gsd/commands/catalog.js +69 -5
- package/dist/resources/extensions/gsd/commands/handlers/core.js +22 -1
- 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/dashboard-overlay.js +1 -1
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +4 -0
- 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 +2 -2
- 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 +23 -23
- package/dist/resources/extensions/gsd/memory-store.js +66 -31
- 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/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/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-session-state.js +33 -0
- package/dist/resources/extensions/mcp-client/index.js +6 -3
- package/dist/resources/extensions/slash-commands/create-extension.js +36 -22
- 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 +12 -12
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +44 -4
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +4 -2
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/server/webpack-runtime.js +1 -1
- package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +1 -0
- package/dist/web/standalone/.next/static/chunks/2824.08296bc2f9654698.js +1 -0
- package/dist/web/standalone/.next/static/chunks/3026.3af53b279375f082.js +1 -0
- package/dist/web/standalone/.next/static/chunks/315.6f68ae79b67d25cf.js +1 -0
- package/dist/web/standalone/.next/static/chunks/3497.4bfc60a3b3dea717.js +1 -0
- package/dist/web/standalone/.next/static/chunks/5516.4a07c872b5c3a663.js +1 -0
- package/dist/web/standalone/.next/static/chunks/8336.31b019697882acfb.js +10 -0
- package/dist/web/standalone/.next/static/chunks/8845.c9702695e8c5a9c5.js +2 -0
- package/dist/web/standalone/.next/static/chunks/9058.01ef3a463bda88f1.js +20 -0
- package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/{page-5b113fd32bc2a1c3.js → page-9bf2e0c50fb2ca05.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/webpack-f9f0dc45e4f3ac10.js +1 -0
- package/dist/web/standalone/package.json +2 -1
- package/dist/worktree-status-banner.d.ts +1 -0
- package/dist/worktree-status-banner.js +132 -0
- package/package.json +1 -1
- 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 +26 -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/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 +78 -46
- package/src/resources/extensions/gsd/auto/loop.ts +24 -2
- package/src/resources/extensions/gsd/auto/phases.ts +3 -3
- package/src/resources/extensions/gsd/auto/run-unit.ts +3 -1
- package/src/resources/extensions/gsd/auto/session.ts +3 -0
- package/src/resources/extensions/gsd/auto/types.ts +1 -0
- 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 +38 -0
- 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 +102 -31
- package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +12 -6
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +39 -8
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +39 -11
- package/src/resources/extensions/gsd/commands/catalog.ts +75 -5
- package/src/resources/extensions/gsd/commands/handlers/core.ts +22 -1
- 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/dashboard-overlay.ts +1 -1
- package/src/resources/extensions/gsd/docs/preferences-reference.md +4 -0
- 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 +2 -2
- 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 +25 -25
- package/src/resources/extensions/gsd/memory-store.ts +81 -28
- 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/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 +9 -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/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/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/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 +22 -0
- 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/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/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/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/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/write-gate-planning-unit.test.ts +15 -0
- package/src/resources/extensions/gsd/tools/memory-tools.ts +17 -1
- package/src/resources/extensions/gsd/unit-context-manifest.ts +8 -8
- 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-session-state.ts +35 -0
- package/src/resources/extensions/mcp-client/index.ts +6 -3
- package/src/resources/extensions/mcp-client/tests/global-config.test.ts +91 -0
- package/src/resources/extensions/slash-commands/create-extension.ts +38 -24
- 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/webpack-2e68521d7c82f7c2.js +0 -1
- package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +0 -22
- package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +0 -47
- package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +0 -75
- /package/dist/web/standalone/.next/static/{cAJH99yNS1UPbeSEiNRrV → UF5VF4F1tB0miEtJS7LyX}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{cAJH99yNS1UPbeSEiNRrV → UF5VF4F1tB0miEtJS7LyX}/_ssgManifest.js +0 -0
|
@@ -107,6 +107,50 @@ test("profile: resolveProfileDefaults exists and handles all 4 tiers", () => {
|
|
|
107
107
|
);
|
|
108
108
|
});
|
|
109
109
|
|
|
110
|
+
test("profile: PROFILE_TIER_MAP defines tier intentions for all profiles", async () => {
|
|
111
|
+
const { getProfileTierMap } = await import("../preferences-models.ts");
|
|
112
|
+
const profileMaps = {
|
|
113
|
+
budget: getProfileTierMap("budget"),
|
|
114
|
+
balanced: getProfileTierMap("balanced"),
|
|
115
|
+
quality: getProfileTierMap("quality"),
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
assert.deepEqual(
|
|
119
|
+
Object.keys(profileMaps).sort(),
|
|
120
|
+
["balanced", "budget", "quality"],
|
|
121
|
+
"PROFILE_TIER_MAP should include the profile default tiers",
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
const expectedPhaseKeys = ["completion", "execution", "execution_simple", "planning", "research", "subagent"];
|
|
125
|
+
const validTiers = new Set(["light", "standard", "heavy"]);
|
|
126
|
+
for (const [profile, tierMap] of Object.entries(profileMaps)) {
|
|
127
|
+
assert.deepEqual(
|
|
128
|
+
Object.keys(tierMap).sort(),
|
|
129
|
+
expectedPhaseKeys,
|
|
130
|
+
`${profile} should define all model-bearing phases`,
|
|
131
|
+
);
|
|
132
|
+
for (const [phase, tier] of Object.entries(tierMap)) {
|
|
133
|
+
assert.ok(validTiers.has(tier), `${profile}.${phase} should be a tier name`);
|
|
134
|
+
assert.ok(!tier.includes("claude-"), `${profile}.${phase} should not be a model ID`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test("profile: resolveProfileDefaults is provider-agnostic — picks OpenAI when only OpenAI is available", async () => {
|
|
140
|
+
// Behavioral check: with only OpenAI models in the available list, no slot
|
|
141
|
+
// should resolve to a claude-* model. Source-grep cannot prove this — only
|
|
142
|
+
// exercising the function with a controlled available-model list can.
|
|
143
|
+
const { resolveProfileDefaults } = await import("../preferences-models.ts");
|
|
144
|
+
const defaults = resolveProfileDefaults("balanced", ["gpt-4o", "gpt-4o-mini"]);
|
|
145
|
+
assert.ok(defaults.models, "balanced profile should populate models");
|
|
146
|
+
for (const [phase, modelId] of Object.entries(defaults.models!)) {
|
|
147
|
+
assert.ok(
|
|
148
|
+
typeof modelId === "string" && !String(modelId).startsWith("claude-"),
|
|
149
|
+
`${phase} resolved to ${modelId} but only OpenAI is available`,
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
|
|
110
154
|
test("profile: budget profile sets phase skips to true", () => {
|
|
111
155
|
// Extract the budget case block
|
|
112
156
|
const budgetIdx = preferencesSrc.indexOf('case "budget":');
|
|
@@ -222,11 +266,14 @@ test("merge: mergePreferences handles phases with spread", () => {
|
|
|
222
266
|
// Subagent Model Routing
|
|
223
267
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
224
268
|
|
|
225
|
-
test("subagent: budget profile
|
|
226
|
-
|
|
227
|
-
const
|
|
269
|
+
test("subagent: budget profile assigns light tier for subagent", () => {
|
|
270
|
+
// PROFILE_TIER_MAP.budget.subagent should be "light"
|
|
271
|
+
const tierMapIdx = preferencesSrc.indexOf("PROFILE_TIER_MAP");
|
|
272
|
+
const budgetIdx = preferencesSrc.indexOf("budget:", tierMapIdx);
|
|
273
|
+
const balancedIdx = preferencesSrc.indexOf("balanced:", tierMapIdx);
|
|
228
274
|
const budgetBlock = preferencesSrc.slice(budgetIdx, balancedIdx);
|
|
229
|
-
assert.ok(budgetBlock.includes("subagent:"), "budget profile should
|
|
275
|
+
assert.ok(budgetBlock.includes("subagent:"), "budget profile should define subagent tier");
|
|
276
|
+
assert.ok(budgetBlock.includes('"light"'), "budget subagent should use light tier");
|
|
230
277
|
});
|
|
231
278
|
|
|
232
279
|
test("subagent: resolveModelWithFallbacksForUnit handles subagent unit types", () => {
|
|
@@ -144,19 +144,10 @@ test("recoverTimedOutUnit: no top-level bumpTurnGeneration — steering branches
|
|
|
144
144
|
);
|
|
145
145
|
});
|
|
146
146
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
"utf-8",
|
|
155
|
-
);
|
|
156
|
-
const matches = src.match(/bumpAndResolveSynthetic\s*\(/g) ?? [];
|
|
157
|
-
assert.equal(
|
|
158
|
-
matches.length,
|
|
159
|
-
4,
|
|
160
|
-
`expected 4 advance-branch supersede sites (durableComplete, execute-task-exhausted, artifact-already-exists, non-execute-exhausted); found ${matches.length}`,
|
|
161
|
-
);
|
|
162
|
-
});
|
|
147
|
+
// Removed: source-grep count of `bumpAndResolveSynthetic\s*\(` occurrences.
|
|
148
|
+
// A literal 4 hardcodes the current branch shape, not behaviour. The
|
|
149
|
+
// behavioural invariant — "advance branches supersede atomically; non-advance
|
|
150
|
+
// branches do not bump" — is enforced by the previous test (no direct
|
|
151
|
+
// bumpTurnGeneration calls) plus the per-branch behavioural tests above
|
|
152
|
+
// (`recoverTimedOutUnit: …`). Refactors that split a branch into two would
|
|
153
|
+
// trip a count test without affecting correctness. Refs #4851.
|
|
@@ -76,13 +76,11 @@ describe("#3615 — structural: fallback exists with correct guards", () => {
|
|
|
76
76
|
);
|
|
77
77
|
});
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
);
|
|
85
|
-
});
|
|
79
|
+
// Removed: source-grep count of `return null;` occurrences. The behaviour
|
|
80
|
+
// we care about ("function returns null only when no auto-dispatch /
|
|
81
|
+
// guided-resume / fallback path matches") is exercised by the behavioural
|
|
82
|
+
// tests below — counting literal `return null;` tokens encodes statement
|
|
83
|
+
// shape, not contract. Refs #4851.
|
|
86
84
|
});
|
|
87
85
|
|
|
88
86
|
// ── Behavioral tests: RESUME_INTENT_PATTERNS ────────────────────────
|
|
@@ -4,7 +4,7 @@ import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
|
4
4
|
import { tmpdir } from "node:os";
|
|
5
5
|
import { join } from "node:path";
|
|
6
6
|
import { execSync } from "node:child_process";
|
|
7
|
-
import { runTurnGitAction } from "../git-service.ts";
|
|
7
|
+
import { handleTurnGitActionError, runTurnGitAction } from "../git-service.ts";
|
|
8
8
|
|
|
9
9
|
function run(cmd: string, cwd: string): string {
|
|
10
10
|
return execSync(cmd, { cwd, stdio: "pipe", encoding: "utf-8" }).trim();
|
|
@@ -83,3 +83,17 @@ test("uok gitops turn action commit creates commit with unit trailer", () => {
|
|
|
83
83
|
rmSync(repo, { recursive: true, force: true });
|
|
84
84
|
}
|
|
85
85
|
});
|
|
86
|
+
|
|
87
|
+
test("uok gitops turn action rethrows infrastructure failures", () => {
|
|
88
|
+
const err = Object.assign(new Error("ENFILE: file table overflow"), { code: "ENFILE" });
|
|
89
|
+
|
|
90
|
+
assert.throws(() => handleTurnGitActionError("commit", err), (thrown) => thrown === err);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
test("uok gitops turn action keeps non-infrastructure git failures recoverable", () => {
|
|
94
|
+
const result = handleTurnGitActionError("commit", new Error("nothing to commit"));
|
|
95
|
+
|
|
96
|
+
assert.equal(result.action, "commit");
|
|
97
|
+
assert.equal(result.status, "failed");
|
|
98
|
+
assert.equal(result.error, "nothing to commit");
|
|
99
|
+
});
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
import { test } from "node:test";
|
|
14
14
|
import assert from "node:assert/strict";
|
|
15
15
|
|
|
16
|
-
import { GSDVisualizerOverlay } from "../visualizer-overlay.ts";
|
|
16
|
+
import { GSDVisualizerOverlay, TAB_COUNT } from "../visualizer-overlay.ts";
|
|
17
17
|
|
|
18
18
|
function makeTui() {
|
|
19
19
|
const renders: number[] = [];
|
|
@@ -93,16 +93,16 @@ test("overlay switches tabs via 1–9,0 digit keys", (t) => {
|
|
|
93
93
|
|
|
94
94
|
test("overlay Tab key cycles forward and wraps around at TAB_COUNT", (t) => {
|
|
95
95
|
const { overlay } = makeOverlay(t);
|
|
96
|
-
overlay.activeTab =
|
|
96
|
+
overlay.activeTab = TAB_COUNT - 1;
|
|
97
97
|
overlay.handleInput("\t");
|
|
98
|
-
assert.equal(overlay.activeTab, 0,
|
|
98
|
+
assert.equal(overlay.activeTab, 0, `Tab wraps from ${TAB_COUNT - 1} back to 0`);
|
|
99
99
|
});
|
|
100
100
|
|
|
101
101
|
test("overlay Shift+Tab cycles backward and wraps", (t) => {
|
|
102
102
|
const { overlay } = makeOverlay(t);
|
|
103
103
|
overlay.activeTab = 0;
|
|
104
104
|
overlay.handleInput("\u001b[Z");
|
|
105
|
-
assert.equal(overlay.activeTab,
|
|
105
|
+
assert.equal(overlay.activeTab, TAB_COUNT - 1, `Shift+Tab wraps from 0 to ${TAB_COUNT - 1}`);
|
|
106
106
|
});
|
|
107
107
|
|
|
108
108
|
// ─── Filter mode ─────────────────────────────────────────────────────────
|
|
@@ -331,9 +331,9 @@ test("overlay footer hint mentions tab navigation, filter, scroll, and help", (t
|
|
|
331
331
|
|
|
332
332
|
// ─── Scroll offsets array is sized to TAB_COUNT ──────────────────────────
|
|
333
333
|
|
|
334
|
-
test("overlay scrollOffsets array has one slot per tab
|
|
334
|
+
test("overlay scrollOffsets array has one slot per tab", (t) => {
|
|
335
335
|
const { overlay } = makeOverlay(t);
|
|
336
|
-
assert.equal(overlay.scrollOffsets.length,
|
|
336
|
+
assert.equal(overlay.scrollOffsets.length, TAB_COUNT, "scrollOffsets sized to TAB_COUNT");
|
|
337
337
|
assert.ok(overlay.scrollOffsets.every((n: number) => n === 0), "initialized to zero");
|
|
338
338
|
});
|
|
339
339
|
|
|
@@ -10,6 +10,7 @@ import assert from 'node:assert/strict';
|
|
|
10
10
|
import { join, sep } from 'node:path';
|
|
11
11
|
|
|
12
12
|
import { shouldBlockPlanningUnit } from '../bootstrap/write-gate.ts';
|
|
13
|
+
import { isDeterministicPolicyError } from '../auto-tool-tracking.ts';
|
|
13
14
|
import type { ToolsPolicy } from '../unit-context-manifest.ts';
|
|
14
15
|
|
|
15
16
|
const BASE = join('/tmp', 'fake-project');
|
|
@@ -36,6 +37,20 @@ test('planning-unit: blocks edit to user source (the b23 forensic)', () => {
|
|
|
36
37
|
assert.match(r.reason!, /discuss-milestone/);
|
|
37
38
|
});
|
|
38
39
|
|
|
40
|
+
test('planning-unit: deterministic block reason is suitable for retry short-circuiting', () => {
|
|
41
|
+
const r = shouldBlockPlanningUnit(
|
|
42
|
+
'edit',
|
|
43
|
+
'src/main.ts',
|
|
44
|
+
BASE,
|
|
45
|
+
'discuss-milestone',
|
|
46
|
+
PLANNING,
|
|
47
|
+
);
|
|
48
|
+
assert.strictEqual(r.block, true);
|
|
49
|
+
assert.match(r.reason!, /HARD BLOCK/);
|
|
50
|
+
assert.match(r.reason!, /tools-policy/);
|
|
51
|
+
assert.strictEqual(isDeterministicPolicyError(r.reason!), true);
|
|
52
|
+
});
|
|
53
|
+
|
|
39
54
|
test('planning-unit: blocks write to user source via relative path', () => {
|
|
40
55
|
const r = shouldBlockPlanningUnit('write', 'src/main.ts', BASE, 'plan-milestone', PLANNING);
|
|
41
56
|
assert.strictEqual(r.block, true);
|
|
@@ -96,8 +96,24 @@ export function executeMemoryCapture(params: MemoryCaptureParams): ToolExecution
|
|
|
96
96
|
const tags = normalizeTags(params.tags);
|
|
97
97
|
|
|
98
98
|
const structuredFields = normalizeStructuredFields(params.structuredFields);
|
|
99
|
-
|
|
99
|
+
let id: string | null;
|
|
100
|
+
try {
|
|
101
|
+
id = createMemory({ category, content, confidence, scope, tags, structuredFields });
|
|
102
|
+
} catch (err) {
|
|
103
|
+
// Surface the underlying SQL message (e.g. "database disk image is
|
|
104
|
+
// malformed", "no such table: memories") so the operator gets the
|
|
105
|
+
// actionable signal instead of an opaque "create_failed". See #4967.
|
|
106
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
107
|
+
return {
|
|
108
|
+
content: [{ type: "text", text: `Error: failed to create memory: ${message}` }],
|
|
109
|
+
details: { operation: "memory_capture", error: message },
|
|
110
|
+
isError: true,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
100
113
|
if (!id) {
|
|
114
|
+
// DB unavailable or adapter missing — distinct from the SQL-error path
|
|
115
|
+
// above. Keep the legacy create_failed token here so any consumers that
|
|
116
|
+
// explicitly key on the unavailable case continue to work.
|
|
101
117
|
return {
|
|
102
118
|
content: [{ type: "text", text: "Error: failed to create memory." }],
|
|
103
119
|
details: { operation: "memory_capture", error: "create_failed" },
|
|
@@ -93,10 +93,10 @@ export type PreferencesPolicy = "none" | "active-only" | "full";
|
|
|
93
93
|
/**
|
|
94
94
|
* Tool-access policy per unit type (#4934).
|
|
95
95
|
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
96
|
+
* Runtime-enforced by the GSD write gate for active auto-mode units. The
|
|
97
|
+
* manifest declares the allowed tool surface; register-hooks.ts resolves the
|
|
98
|
+
* active unit's manifest before each tool call and write-gate.ts rejects
|
|
99
|
+
* violations before the tool executes.
|
|
100
100
|
*
|
|
101
101
|
* Modes:
|
|
102
102
|
* - "all" — Read + Edit/Write/MultiEdit/NotebookEdit + Bash + Task.
|
|
@@ -214,10 +214,10 @@ export interface UnitContextManifest {
|
|
|
214
214
|
/** Preferences block policy. */
|
|
215
215
|
readonly preferences: PreferencesPolicy;
|
|
216
216
|
/**
|
|
217
|
-
* Tool-access policy (#4934).
|
|
218
|
-
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
217
|
+
* Tool-access policy (#4934). Runtime enforcement covers path-scoped write
|
|
218
|
+
* blocking, subagent denial, and bash allowlisting for active auto-mode
|
|
219
|
+
* units. Required on every manifest so missing entries fail loud via the CI
|
|
220
|
+
* invariant test rather than defaulting to "all" silently.
|
|
221
221
|
*/
|
|
222
222
|
readonly tools: ToolsPolicy;
|
|
223
223
|
/** Artifact handling: inline (full body), excerpt (compact), or on-demand (path only). */
|
|
@@ -98,13 +98,15 @@ export function readGitBranch(projectRoot: string): string {
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
/**
|
|
101
|
-
* Read MCP server names from .mcp.json
|
|
101
|
+
* Read MCP server names from .mcp.json, .gsd/mcp.json, and the global
|
|
102
|
+
* ~/.gsd/mcp.json (or $GSD_HOME/mcp.json).
|
|
102
103
|
* Returns array of server name strings.
|
|
103
104
|
*/
|
|
104
105
|
export function readMcpServerNames(projectRoot: string): string[] {
|
|
105
106
|
const configPaths = [
|
|
106
107
|
join(projectRoot, ".mcp.json"),
|
|
107
108
|
join(projectRoot, ".gsd", "mcp.json"),
|
|
109
|
+
join(process.env.GSD_HOME || join(homedir(), ".gsd"), "mcp.json"),
|
|
108
110
|
];
|
|
109
111
|
const names: string[] = [];
|
|
110
112
|
const seen = new Set<string>();
|
|
@@ -66,6 +66,7 @@ export type LogComponent =
|
|
|
66
66
|
| "memory-embeddings" // Memory layer embedding generation
|
|
67
67
|
| "memory-ingest" // Memory layer ingestion pipeline
|
|
68
68
|
| "memory-backfill" // ADR-013: decisions->memories backfill
|
|
69
|
+
| "memory-store" // Memory CRUD layer — surfaces SQLite/store-level faults (#4967)
|
|
69
70
|
| "context-mode" // Context-mode exec sandbox and compaction snapshot
|
|
70
71
|
| "preflight" // Clean-root preflight gate at milestone completion
|
|
71
72
|
| "postUnit"; // Post-unit processing (abandon detection, overrides)
|
|
@@ -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[] = [];
|
|
@@ -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
|
+
}
|
|
@@ -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",
|