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
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import { describe, test } from "node:test";
|
|
11
11
|
import assert from "node:assert/strict";
|
|
12
12
|
|
|
13
|
-
import { _resolveReportBasePath } from "../auto/phases.ts";
|
|
13
|
+
import { _resolveDispatchGuardBasePath, _resolveReportBasePath } from "../auto/phases.ts";
|
|
14
14
|
|
|
15
15
|
describe("_resolveReportBasePath", () => {
|
|
16
16
|
test("uses originalBasePath when set (worktree scenario)", () => {
|
|
@@ -48,4 +48,21 @@ describe("_resolveReportBasePath", () => {
|
|
|
48
48
|
|
|
49
49
|
assert.equal(_resolveReportBasePath(session), "/home/user/repo");
|
|
50
50
|
});
|
|
51
|
+
|
|
52
|
+
test("uses GSD_PROJECT_ROOT for symlink-resolved worktree paths", () => {
|
|
53
|
+
const savedProjectRoot = process.env.GSD_PROJECT_ROOT;
|
|
54
|
+
process.env.GSD_PROJECT_ROOT = "/real/project";
|
|
55
|
+
try {
|
|
56
|
+
const session = {
|
|
57
|
+
originalBasePath: "",
|
|
58
|
+
basePath: "/Users/dev/.gsd/projects/abc123/worktrees/M001/slices/S01",
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
assert.equal(_resolveReportBasePath(session), "/real/project");
|
|
62
|
+
assert.equal(_resolveDispatchGuardBasePath(session), "/real/project");
|
|
63
|
+
} finally {
|
|
64
|
+
if (savedProjectRoot === undefined) delete process.env.GSD_PROJECT_ROOT;
|
|
65
|
+
else process.env.GSD_PROJECT_ROOT = savedProjectRoot;
|
|
66
|
+
}
|
|
67
|
+
});
|
|
51
68
|
});
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
resolveModelForComplexity,
|
|
6
6
|
escalateTier,
|
|
7
7
|
defaultRoutingConfig,
|
|
8
|
+
resolveModelForTier,
|
|
8
9
|
scoreModel,
|
|
9
10
|
computeTaskRequirements,
|
|
10
11
|
scoreEligibleModels,
|
|
@@ -248,6 +249,172 @@ test("#2192: known model is still downgraded normally", () => {
|
|
|
248
249
|
assert.notEqual(result.modelId, "claude-opus-4-6");
|
|
249
250
|
});
|
|
250
251
|
|
|
252
|
+
// ─── Cross-provider fallback ──────────────────────────────────────────────────
|
|
253
|
+
|
|
254
|
+
test("uses cross-provider equivalent when configured primary is unavailable", () => {
|
|
255
|
+
const config = { ...defaultRoutingConfig(), enabled: true };
|
|
256
|
+
// Profile default says claude-opus-4-6 for planning, but user is on GPT only
|
|
257
|
+
const result = resolveModelForComplexity(
|
|
258
|
+
makeClassification("heavy"),
|
|
259
|
+
{ primary: "claude-opus-4-6", fallbacks: [] },
|
|
260
|
+
config,
|
|
261
|
+
["gpt-4o", "gpt-4o-mini", "o1"],
|
|
262
|
+
);
|
|
263
|
+
// o1 is the heavy-tier GPT model — should be selected as cross-provider equivalent
|
|
264
|
+
assert.equal(result.modelId, "o1");
|
|
265
|
+
assert.equal(result.wasDowngraded, false);
|
|
266
|
+
assert.match(result.reason, /cross-provider/);
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
test("cross-provider: selects standard-tier equivalent when primary unavailable", () => {
|
|
270
|
+
const config = { ...defaultRoutingConfig(), enabled: true };
|
|
271
|
+
// Planning configured with Opus, but only GPT standard models available
|
|
272
|
+
const result = resolveModelForComplexity(
|
|
273
|
+
makeClassification("heavy"),
|
|
274
|
+
{ primary: "claude-opus-4-6", fallbacks: [] },
|
|
275
|
+
config,
|
|
276
|
+
["gpt-4o", "gpt-4o-mini"],
|
|
277
|
+
);
|
|
278
|
+
// gpt-4o is standard tier, not heavy — no heavy-tier model available
|
|
279
|
+
// Should fall back to gpt-4o (best available)
|
|
280
|
+
assert.ok(result.modelId === "gpt-4o" || result.modelId === "claude-opus-4-6");
|
|
281
|
+
assert.equal(result.wasDowngraded, false);
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
test("cross-provider: configured primary available by bare ID wins over equivalent", () => {
|
|
285
|
+
const config = { ...defaultRoutingConfig(), enabled: true };
|
|
286
|
+
// Provider-prefixed ID — bare match should find it
|
|
287
|
+
const result = resolveModelForComplexity(
|
|
288
|
+
makeClassification("heavy"),
|
|
289
|
+
{ primary: "claude-opus-4-6", fallbacks: [] },
|
|
290
|
+
config,
|
|
291
|
+
["anthropic/claude-opus-4-6", "o1"],
|
|
292
|
+
);
|
|
293
|
+
assert.equal(result.modelId, "claude-opus-4-6");
|
|
294
|
+
assert.equal(result.wasDowngraded, false);
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
// ─── resolveModelForTier (provider-agnostic tier resolution) ────────────────
|
|
298
|
+
|
|
299
|
+
test("resolveModelForTier: returns canonical Anthropic model when no available models", () => {
|
|
300
|
+
assert.equal(resolveModelForTier("heavy", []), "claude-opus-4-6");
|
|
301
|
+
assert.equal(resolveModelForTier("standard", []), "claude-sonnet-4-6");
|
|
302
|
+
assert.equal(resolveModelForTier("light", []), "claude-haiku-4-5");
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
test("resolveModelForTier: returns canonical model when it is available", () => {
|
|
306
|
+
assert.equal(
|
|
307
|
+
resolveModelForTier("heavy", ["claude-opus-4-6", "claude-sonnet-4-6"]),
|
|
308
|
+
"claude-opus-4-6",
|
|
309
|
+
);
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
test("resolveModelForTier: does not prefer canonical over cheaper same-tier model", () => {
|
|
313
|
+
const result = resolveModelForTier("light", ["claude-haiku-4-5", "gpt-4o-mini"]);
|
|
314
|
+
assert.equal(result, "gpt-4o-mini");
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
test("resolveModelForTier: honors configured tier_models pins", () => {
|
|
318
|
+
const config: DynamicRoutingConfig = {
|
|
319
|
+
...defaultRoutingConfig(),
|
|
320
|
+
tier_models: { light: "claude-haiku-4-5" },
|
|
321
|
+
};
|
|
322
|
+
const result = resolveModelForTier("light", ["claude-haiku-4-5", "gpt-4o-mini"], config);
|
|
323
|
+
assert.equal(result, "claude-haiku-4-5");
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
test("resolveModelForTier: picks cross-provider equivalent when Anthropic unavailable", () => {
|
|
327
|
+
// Only OpenAI models available
|
|
328
|
+
const result = resolveModelForTier("heavy", ["gpt-4o", "gpt-4o-mini", "o1"]);
|
|
329
|
+
// o1 is the heavy-tier model in the OpenAI lineup
|
|
330
|
+
assert.equal(result, "o1");
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
test("resolveModelForTier: picks standard-tier cross-provider model", () => {
|
|
334
|
+
const result = resolveModelForTier("standard", ["gpt-4o", "gpt-4o-mini"]);
|
|
335
|
+
assert.equal(result, "gpt-4o");
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
test("resolveModelForTier: picks light-tier cross-provider model", () => {
|
|
339
|
+
const result = resolveModelForTier("light", ["gpt-4o", "gpt-4o-mini"]);
|
|
340
|
+
assert.equal(result, "gpt-4o-mini");
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
test("resolveModelForTier: falls back to canonical when no tier match available", () => {
|
|
344
|
+
// Only unknown models available — getModelTier classifies unknowns as
|
|
345
|
+
// "standard", so a request for "heavy" finds no match and the canonical
|
|
346
|
+
// Anthropic ID is returned as a documented fallback.
|
|
347
|
+
const result = resolveModelForTier("heavy", ["some-custom-model"]);
|
|
348
|
+
assert.equal(result, "claude-opus-4-6");
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
test("resolveModelForTier: handles provider-prefixed available models", () => {
|
|
352
|
+
const result = resolveModelForTier("heavy", ["anthropic/claude-opus-4-6"]);
|
|
353
|
+
assert.equal(result, "claude-opus-4-6");
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
test("resolveModelForTier: picks Gemini models when only Google available", () => {
|
|
357
|
+
const result = resolveModelForTier("light", ["gemini-2.5-pro", "gemini-2.0-flash"]);
|
|
358
|
+
assert.equal(result, "gemini-2.0-flash");
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
// ─── Behavioral: profile defaults are provider-agnostic at runtime ──────────
|
|
362
|
+
|
|
363
|
+
test("resolveProfileDefaults: balanced with only OpenAI models returns OpenAI IDs", async () => {
|
|
364
|
+
const { resolveProfileDefaults } = await import("../preferences-models.js");
|
|
365
|
+
const defaults = resolveProfileDefaults("balanced", ["gpt-4o", "gpt-4o-mini"]);
|
|
366
|
+
assert.ok(defaults.models, "balanced should populate models");
|
|
367
|
+
// All slots must resolve to an available OpenAI ID — not a claude- canonical.
|
|
368
|
+
for (const [phase, modelId] of Object.entries(defaults.models!)) {
|
|
369
|
+
assert.ok(typeof modelId === "string" && modelId.length > 0, `${phase} should resolve to a model ID`);
|
|
370
|
+
assert.ok(
|
|
371
|
+
!String(modelId).startsWith("claude-"),
|
|
372
|
+
`${phase} resolved to ${modelId} but no claude-* model is available — should be OpenAI`,
|
|
373
|
+
);
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
test("resolveProfileDefaults: budget with only OpenAI models picks gpt-4o-mini for light slots", async () => {
|
|
378
|
+
const { resolveProfileDefaults } = await import("../preferences-models.js");
|
|
379
|
+
const defaults = resolveProfileDefaults("budget", ["gpt-4o", "gpt-4o-mini"]);
|
|
380
|
+
// light-tier slots in budget: research, execution_simple, completion, subagent
|
|
381
|
+
assert.equal(defaults.models?.research, "gpt-4o-mini");
|
|
382
|
+
assert.equal(defaults.models?.execution_simple, "gpt-4o-mini");
|
|
383
|
+
assert.equal(defaults.models?.completion, "gpt-4o-mini");
|
|
384
|
+
assert.equal(defaults.models?.subagent, "gpt-4o-mini");
|
|
385
|
+
// standard-tier slots: planning, execution
|
|
386
|
+
assert.equal(defaults.models?.planning, "gpt-4o");
|
|
387
|
+
assert.equal(defaults.models?.execution, "gpt-4o");
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
test("resolveProfileDefaults: honors dynamic routing tier_models pins", async () => {
|
|
391
|
+
const { resolveProfileDefaults } = await import("../preferences-models.js");
|
|
392
|
+
const defaults = resolveProfileDefaults(
|
|
393
|
+
"budget",
|
|
394
|
+
["claude-haiku-4-5", "gpt-4o-mini", "gpt-4o"],
|
|
395
|
+
{ ...defaultRoutingConfig(), tier_models: { light: "claude-haiku-4-5" } },
|
|
396
|
+
);
|
|
397
|
+
assert.equal(defaults.models?.research, "claude-haiku-4-5");
|
|
398
|
+
assert.equal(defaults.models?.execution_simple, "claude-haiku-4-5");
|
|
399
|
+
assert.equal(defaults.models?.completion, "claude-haiku-4-5");
|
|
400
|
+
assert.equal(defaults.models?.subagent, "claude-haiku-4-5");
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
test("resolveProfileDefaults: empty availableModelIds falls back to canonical Anthropic IDs", async () => {
|
|
404
|
+
const { resolveProfileDefaults } = await import("../preferences-models.js");
|
|
405
|
+
const defaults = resolveProfileDefaults("balanced", []);
|
|
406
|
+
// Documented fallback only — when registry is unavailable at bootstrap.
|
|
407
|
+
const planningModel = defaults.models?.planning;
|
|
408
|
+
assert.ok(typeof planningModel === "string" && planningModel.startsWith("claude-"));
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
test("resolveProfileDefaults: burn-max omits models so user choice is preserved", async () => {
|
|
412
|
+
const { resolveProfileDefaults } = await import("../preferences-models.js");
|
|
413
|
+
const defaults = resolveProfileDefaults("burn-max", ["gpt-4o"]);
|
|
414
|
+
assert.equal(defaults.models, undefined, "burn-max must not write model defaults");
|
|
415
|
+
assert.equal(defaults.dynamic_routing?.enabled, false);
|
|
416
|
+
});
|
|
417
|
+
|
|
251
418
|
// ─── Capability Scoring (ADR-004 Phase 2) ───────────────────────────────────
|
|
252
419
|
|
|
253
420
|
test("defaultRoutingConfig includes capability_routing: true", () => {
|
|
@@ -279,14 +446,8 @@ test("scoreModel computes weighted average of capability × requirement", () =>
|
|
|
279
446
|
assert.ok(Math.abs(score - 88.21) < 0.1, `score ${score} should be ~88.21`);
|
|
280
447
|
});
|
|
281
448
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
coding: 90, debugging: 80, research: 70,
|
|
285
|
-
reasoning: 85, speed: 50, longContext: 60, instruction: 75,
|
|
286
|
-
};
|
|
287
|
-
const score = scoreModel(caps, {});
|
|
288
|
-
assert.equal(score, 50);
|
|
289
|
-
});
|
|
449
|
+
// (Removed duplicate "scoreModel returns 50 for empty requirements" — the
|
|
450
|
+
// `describe("scoreModel")` block below has the same scenario.)
|
|
290
451
|
|
|
291
452
|
test("computeTaskRequirements returns base vector for known unit type", () => {
|
|
292
453
|
const reqs = computeTaskRequirements("execute-task");
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { chmodSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
|
|
7
|
+
import { git } from "./test-utils.ts";
|
|
8
|
+
import { GSD_GIT_ERROR } from "../errors.js";
|
|
9
|
+
|
|
10
|
+
test("nativeAddAllWithExclusions preserves infrastructure failures from git add", async () => {
|
|
11
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-native-git-infra-"));
|
|
12
|
+
const repo = join(base, "repo");
|
|
13
|
+
const bin = join(base, "bin");
|
|
14
|
+
mkdirSync(repo);
|
|
15
|
+
mkdirSync(bin);
|
|
16
|
+
|
|
17
|
+
const fakeGit = join(bin, "git");
|
|
18
|
+
writeFileSync(
|
|
19
|
+
fakeGit,
|
|
20
|
+
"#!/bin/sh\n" +
|
|
21
|
+
"echo 'fatal: ENFILE: file table overflow' >&2\n" +
|
|
22
|
+
"exit 1\n",
|
|
23
|
+
"utf-8",
|
|
24
|
+
);
|
|
25
|
+
chmodSync(fakeGit, 0o755);
|
|
26
|
+
|
|
27
|
+
const originalPath = process.env.PATH ?? "";
|
|
28
|
+
try {
|
|
29
|
+
git(repo, "init");
|
|
30
|
+
git(repo, "config", "user.email", "test@example.com");
|
|
31
|
+
git(repo, "config", "user.name", "Test User");
|
|
32
|
+
writeFileSync(join(repo, "README.md"), "# Test\n", "utf-8");
|
|
33
|
+
|
|
34
|
+
process.env.PATH = `${bin}:${originalPath}`;
|
|
35
|
+
const { nativeAddAllWithExclusions } = await import("../native-git-bridge.ts");
|
|
36
|
+
|
|
37
|
+
assert.throws(
|
|
38
|
+
() => nativeAddAllWithExclusions(repo, [".gsd/activity/"]),
|
|
39
|
+
(err) => {
|
|
40
|
+
const shaped = err as { code?: string; stderr?: string; message?: string };
|
|
41
|
+
assert.notEqual(shaped.code, GSD_GIT_ERROR);
|
|
42
|
+
assert.match(`${shaped.stderr ?? ""}${shaped.message ?? ""}`, /ENFILE/);
|
|
43
|
+
return true;
|
|
44
|
+
},
|
|
45
|
+
);
|
|
46
|
+
} finally {
|
|
47
|
+
process.env.PATH = originalPath;
|
|
48
|
+
rmSync(base, { recursive: true, force: true });
|
|
49
|
+
}
|
|
50
|
+
});
|
|
@@ -101,6 +101,14 @@ describe("auditOrphanedMilestoneBranches", () => {
|
|
|
101
101
|
result.warnings.some(w => w.includes("NOT merged")),
|
|
102
102
|
"should warn about unmerged branch",
|
|
103
103
|
);
|
|
104
|
+
assert.ok(
|
|
105
|
+
result.warnings.some(w => w.includes("/gsd doctor fix")),
|
|
106
|
+
`warning should suggest the real remediation command; got: ${JSON.stringify(result.warnings)}`,
|
|
107
|
+
);
|
|
108
|
+
assert.ok(
|
|
109
|
+
result.warnings.every(w => !w.includes("/gsd health --fix")),
|
|
110
|
+
`warning must not suggest the removed health --fix command; got: ${JSON.stringify(result.warnings)}`,
|
|
111
|
+
);
|
|
104
112
|
|
|
105
113
|
// Branch should still exist (data safety)
|
|
106
114
|
const branches = run("git branch --list milestone/M001", dir);
|
|
@@ -19,13 +19,15 @@ import { join } from "node:path";
|
|
|
19
19
|
import { tmpdir } from "node:os";
|
|
20
20
|
|
|
21
21
|
import {
|
|
22
|
-
persistState,
|
|
23
22
|
restoreState,
|
|
24
23
|
resetOrchestrator,
|
|
25
|
-
getOrchestratorState,
|
|
26
24
|
type PersistedState,
|
|
27
25
|
} from "../parallel-orchestrator.ts";
|
|
28
|
-
import {
|
|
26
|
+
import {
|
|
27
|
+
writeSessionStatus,
|
|
28
|
+
readAllSessionStatuses,
|
|
29
|
+
cleanupStaleSessions,
|
|
30
|
+
} from "../session-status-io.ts";
|
|
29
31
|
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
30
32
|
|
|
31
33
|
function makeTempDir(): string {
|
|
@@ -57,17 +59,20 @@ function makePersistedState(overrides: Partial<PersistedState> = {}): PersistedS
|
|
|
57
59
|
|
|
58
60
|
|
|
59
61
|
describe('parallel-crash-recovery', () => {
|
|
60
|
-
test('Test 1:
|
|
62
|
+
test('Test 1: orchestrator.json round-trips through restoreState (preserves worker fields)', () => {
|
|
61
63
|
const basePath = makeTempDir();
|
|
62
64
|
try {
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
+
// Write a full state file to disk and then exercise the real production
|
|
66
|
+
// restoreState() reader against it. This verifies the persisted file
|
|
67
|
+
// schema (the contract between persistState's writer and the reader)
|
|
68
|
+
// — earlier this test inlined a test-only writer and re-parsed JSON,
|
|
69
|
+
// bypassing production code entirely.
|
|
65
70
|
const state = makePersistedState({
|
|
66
71
|
workers: [
|
|
67
72
|
{
|
|
68
73
|
milestoneId: "M001",
|
|
69
74
|
title: "M001",
|
|
70
|
-
pid: process.pid,
|
|
75
|
+
pid: process.pid, // alive — survives restoreState's PID filter
|
|
71
76
|
worktreePath: "/tmp/wt-M001",
|
|
72
77
|
startedAt: Date.now(),
|
|
73
78
|
state: "running",
|
|
@@ -78,13 +83,13 @@ test('Test 1: persistState writes valid JSON', () => {
|
|
|
78
83
|
});
|
|
79
84
|
writeStateFile(basePath, state);
|
|
80
85
|
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
assert.deepStrictEqual(
|
|
84
|
-
assert.deepStrictEqual(
|
|
85
|
-
assert.deepStrictEqual(
|
|
86
|
-
assert.deepStrictEqual(
|
|
87
|
-
assert.deepStrictEqual(
|
|
86
|
+
const restored = restoreState(basePath);
|
|
87
|
+
assert.ok(restored !== null, "restoreState: returns state for live worker");
|
|
88
|
+
assert.deepStrictEqual(restored!.active, true, "active field preserved through round-trip");
|
|
89
|
+
assert.deepStrictEqual(restored!.workers.length, 1, "worker count preserved");
|
|
90
|
+
assert.deepStrictEqual(restored!.workers[0].milestoneId, "M001", "milestoneId preserved");
|
|
91
|
+
assert.deepStrictEqual(restored!.workers[0].cost, 0.15, "cost preserved");
|
|
92
|
+
assert.deepStrictEqual(restored!.totalCost, 0.15, "totalCost preserved");
|
|
88
93
|
} finally {
|
|
89
94
|
rmSync(basePath, { recursive: true, force: true });
|
|
90
95
|
}
|
|
@@ -201,11 +206,12 @@ test('Test 5: restoreState skips stopped/error workers even with alive PIDs', ()
|
|
|
201
206
|
}
|
|
202
207
|
});
|
|
203
208
|
|
|
204
|
-
test('Test 6:
|
|
209
|
+
test('Test 6: cleanupStaleSessions removes dead-PID sessions and keeps live ones', () => {
|
|
205
210
|
const basePath = makeTempDir();
|
|
206
211
|
try {
|
|
207
|
-
// Write a session status with a dead PID
|
|
208
212
|
mkdirSync(join(basePath, ".gsd", "parallel"), { recursive: true });
|
|
213
|
+
|
|
214
|
+
// Dead PID
|
|
209
215
|
writeSessionStatus(basePath, {
|
|
210
216
|
milestoneId: "M001",
|
|
211
217
|
pid: 99999999,
|
|
@@ -218,7 +224,7 @@ test('Test 6: orphan detection finds stale sessions', () => {
|
|
|
218
224
|
worktreePath: "/tmp/wt-M001",
|
|
219
225
|
});
|
|
220
226
|
|
|
221
|
-
//
|
|
227
|
+
// Live PID (this process)
|
|
222
228
|
writeSessionStatus(basePath, {
|
|
223
229
|
milestoneId: "M002",
|
|
224
230
|
pid: process.pid,
|
|
@@ -231,37 +237,20 @@ test('Test 6: orphan detection finds stale sessions', () => {
|
|
|
231
237
|
worktreePath: "/tmp/wt-M002",
|
|
232
238
|
});
|
|
233
239
|
|
|
234
|
-
// Read all sessions — both should exist initially
|
|
235
240
|
const before = readAllSessionStatuses(basePath);
|
|
236
|
-
assert.deepStrictEqual(before.length, 2, "
|
|
241
|
+
assert.deepStrictEqual(before.length, 2, "both sessions exist before cleanup");
|
|
237
242
|
|
|
238
|
-
//
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
try {
|
|
244
|
-
process.kill(session.pid, 0);
|
|
245
|
-
alive = true;
|
|
246
|
-
} catch {
|
|
247
|
-
alive = false;
|
|
248
|
-
}
|
|
249
|
-
orphans.push({ milestoneId: session.milestoneId, pid: session.pid, alive });
|
|
250
|
-
if (!alive) {
|
|
251
|
-
removeSessionStatus(basePath, session.milestoneId);
|
|
252
|
-
}
|
|
253
|
-
}
|
|
243
|
+
// Drive the real production cleanup function. Earlier this test
|
|
244
|
+
// re-implemented the cleanup loop inline (process.kill + remove*) and
|
|
245
|
+
// never exercised cleanupStaleSessions itself — so changes to the
|
|
246
|
+
// production sweep would not have been caught.
|
|
247
|
+
const removed = cleanupStaleSessions(basePath);
|
|
254
248
|
|
|
255
|
-
assert.
|
|
256
|
-
const deadOrphan = orphans.find(o => o.milestoneId === "M001");
|
|
257
|
-
assert.ok(deadOrphan !== undefined && !deadOrphan.alive, "orphan: M001 detected as dead");
|
|
258
|
-
const aliveOrphan = orphans.find(o => o.milestoneId === "M002");
|
|
259
|
-
assert.ok(aliveOrphan !== undefined && aliveOrphan.alive, "orphan: M002 detected as alive");
|
|
249
|
+
assert.deepStrictEqual(removed, ["M001"], "dead-PID session id is reported as removed");
|
|
260
250
|
|
|
261
|
-
// Dead session should be cleaned up
|
|
262
251
|
const after = readAllSessionStatuses(basePath);
|
|
263
|
-
assert.deepStrictEqual(after.length, 1, "
|
|
264
|
-
assert.deepStrictEqual(after[0].milestoneId, "M002", "
|
|
252
|
+
assert.deepStrictEqual(after.length, 1, "dead session cleaned up");
|
|
253
|
+
assert.deepStrictEqual(after[0].milestoneId, "M002", "alive session remains");
|
|
265
254
|
} finally {
|
|
266
255
|
rmSync(basePath, { recursive: true, force: true });
|
|
267
256
|
}
|
|
@@ -18,20 +18,14 @@ const phasesSrc = readFileSync(phasesPath, "utf-8");
|
|
|
18
18
|
|
|
19
19
|
console.log("\n=== #2766: Non-MergeConflictError stops auto mode ===");
|
|
20
20
|
|
|
21
|
-
// ── Test 1:
|
|
22
|
-
|
|
23
|
-
assertTrue(
|
|
24
|
-
phasesPath.length > 0 && phasesPath.endsWith("phases.ts"),
|
|
25
|
-
"phases.ts file exists and is readable",
|
|
26
|
-
);
|
|
21
|
+
// ── Test 1: every mergeAndExit call site has a catch (mergeErr) block ──
|
|
27
22
|
|
|
28
23
|
// Count all mergeAndExit catch blocks by finding "} catch (mergeErr)" patterns
|
|
29
|
-
const
|
|
30
|
-
// Use the source itself for matching
|
|
24
|
+
const mergeAndExitCallCount = [...phasesSrc.matchAll(/\.mergeAndExit\(/g)].length;
|
|
31
25
|
const mergeErrCatchCount = [...phasesSrc.matchAll(/\} catch \(mergeErr\)/g)].length;
|
|
32
26
|
assertTrue(
|
|
33
|
-
mergeErrCatchCount
|
|
34
|
-
`
|
|
27
|
+
mergeErrCatchCount === mergeAndExitCallCount && mergeAndExitCallCount > 0,
|
|
28
|
+
`every mergeAndExit call site has a catch (mergeErr) block (calls=${mergeAndExitCallCount}, catches=${mergeErrCatchCount})`,
|
|
35
29
|
);
|
|
36
30
|
|
|
37
31
|
// ── Test 2: Every mergeErr catch block handles non-MergeConflictError ───
|
|
@@ -236,6 +236,20 @@ test("valid values pass through correctly", () => {
|
|
|
236
236
|
assert.equal(p3.auto_supervisor?.model, "claude-opus-4-6");
|
|
237
237
|
});
|
|
238
238
|
|
|
239
|
+
test("min_request_interval_ms floors decimals and rejects timer overflow values", () => {
|
|
240
|
+
const valid = validatePreferences({ min_request_interval_ms: 1000.9 });
|
|
241
|
+
assert.equal(valid.errors.length, 0);
|
|
242
|
+
assert.equal(valid.preferences.min_request_interval_ms, 1000);
|
|
243
|
+
|
|
244
|
+
const max = validatePreferences({ min_request_interval_ms: 2_147_483_647 });
|
|
245
|
+
assert.equal(max.errors.length, 0);
|
|
246
|
+
assert.equal(max.preferences.min_request_interval_ms, 2_147_483_647);
|
|
247
|
+
|
|
248
|
+
const tooHigh = validatePreferences({ min_request_interval_ms: 2_147_483_648 });
|
|
249
|
+
assert.ok(tooHigh.errors.some(e => e.includes("min_request_interval_ms must be a non-negative number <= 2147483647")));
|
|
250
|
+
assert.equal(tooHigh.preferences.min_request_interval_ms, undefined);
|
|
251
|
+
});
|
|
252
|
+
|
|
239
253
|
test("mixed valid/invalid/unknown keys handled correctly", () => {
|
|
240
254
|
const { preferences, errors, warnings } = validatePreferences({
|
|
241
255
|
uat_dispatch: true, totally_made_up: "value", budget_ceiling: "garbage",
|
|
@@ -246,6 +260,71 @@ test("mixed valid/invalid/unknown keys handled correctly", () => {
|
|
|
246
260
|
assert.equal(preferences.budget_ceiling, undefined);
|
|
247
261
|
});
|
|
248
262
|
|
|
263
|
+
test("disabled_model_providers validates and normalizes string arrays", () => {
|
|
264
|
+
const { preferences, errors } = validatePreferences({
|
|
265
|
+
disabled_model_providers: ["google-gemini-cli", " google-gemini-cli ", "openai-codex", " "],
|
|
266
|
+
});
|
|
267
|
+
assert.equal(errors.length, 0);
|
|
268
|
+
assert.deepEqual(preferences.disabled_model_providers, ["google-gemini-cli", "openai-codex"]);
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
test("disabled_model_providers rejects non-array values", () => {
|
|
272
|
+
const { errors } = validatePreferences({ disabled_model_providers: "google-gemini-cli" as any });
|
|
273
|
+
assert.ok(errors.some((e) => e.includes("disabled_model_providers must be an array of strings")));
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
test("loadEffectiveGSDPreferences preserves disabled_model_providers across merge layers", () => {
|
|
277
|
+
const originalCwd = process.cwd();
|
|
278
|
+
const originalGsdHome = process.env.GSD_HOME;
|
|
279
|
+
const tempProject = mkdtempSync(join(tmpdir(), "gsd-disabled-provider-project-"));
|
|
280
|
+
const tempGsdHome = mkdtempSync(join(tmpdir(), "gsd-disabled-provider-home-"));
|
|
281
|
+
|
|
282
|
+
try {
|
|
283
|
+
mkdirSync(join(tempProject, ".gsd"), { recursive: true });
|
|
284
|
+
|
|
285
|
+
writeFileSync(
|
|
286
|
+
join(tempGsdHome, "PREFERENCES.md"),
|
|
287
|
+
[
|
|
288
|
+
"---",
|
|
289
|
+
"version: 1",
|
|
290
|
+
"disabled_model_providers:",
|
|
291
|
+
" - google-gemini-cli",
|
|
292
|
+
"---",
|
|
293
|
+
].join("\n"),
|
|
294
|
+
"utf-8",
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
writeFileSync(
|
|
298
|
+
join(tempProject, ".gsd", "PREFERENCES.md"),
|
|
299
|
+
[
|
|
300
|
+
"---",
|
|
301
|
+
"version: 1",
|
|
302
|
+
"disabled_model_providers:",
|
|
303
|
+
" - openai-codex",
|
|
304
|
+
" - google-gemini-cli",
|
|
305
|
+
"---",
|
|
306
|
+
].join("\n"),
|
|
307
|
+
"utf-8",
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
process.env.GSD_HOME = tempGsdHome;
|
|
311
|
+
process.chdir(tempProject);
|
|
312
|
+
|
|
313
|
+
const loaded = loadEffectiveGSDPreferences();
|
|
314
|
+
assert.notEqual(loaded, null);
|
|
315
|
+
assert.deepEqual(
|
|
316
|
+
loaded!.preferences.disabled_model_providers,
|
|
317
|
+
["google-gemini-cli", "openai-codex"],
|
|
318
|
+
);
|
|
319
|
+
} finally {
|
|
320
|
+
process.chdir(originalCwd);
|
|
321
|
+
if (originalGsdHome === undefined) delete process.env.GSD_HOME;
|
|
322
|
+
else process.env.GSD_HOME = originalGsdHome;
|
|
323
|
+
rmSync(tempProject, { recursive: true, force: true });
|
|
324
|
+
rmSync(tempGsdHome, { recursive: true, force: true });
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
|
|
249
328
|
// ── Wizard fields ────────────────────────────────────────────────────────────
|
|
250
329
|
|
|
251
330
|
test("budget fields validate correctly", () => {
|
|
@@ -683,6 +762,54 @@ test("loadEffectiveGSDPreferences exposes slice_parallel prefs to runtime caller
|
|
|
683
762
|
}
|
|
684
763
|
});
|
|
685
764
|
|
|
765
|
+
test("loadEffectiveGSDPreferences merges min_request_interval_ms with project overriding global (#2996)", () => {
|
|
766
|
+
const originalCwd = process.cwd();
|
|
767
|
+
const originalGsdHome = process.env.GSD_HOME;
|
|
768
|
+
const tempProject = mkdtempSync(join(tmpdir(), "gsd-rate-limit-project-"));
|
|
769
|
+
const tempGsdHome = mkdtempSync(join(tmpdir(), "gsd-rate-limit-home-"));
|
|
770
|
+
|
|
771
|
+
try {
|
|
772
|
+
mkdirSync(join(tempProject, ".gsd"), { recursive: true });
|
|
773
|
+
|
|
774
|
+
writeFileSync(
|
|
775
|
+
join(tempGsdHome, "PREFERENCES.md"),
|
|
776
|
+
[
|
|
777
|
+
"---",
|
|
778
|
+
"version: 1",
|
|
779
|
+
"min_request_interval_ms: 250",
|
|
780
|
+
"budget_ceiling: 45",
|
|
781
|
+
"---",
|
|
782
|
+
].join("\n"),
|
|
783
|
+
"utf-8",
|
|
784
|
+
);
|
|
785
|
+
|
|
786
|
+
writeFileSync(
|
|
787
|
+
join(tempProject, ".gsd", "PREFERENCES.md"),
|
|
788
|
+
[
|
|
789
|
+
"---",
|
|
790
|
+
"version: 1",
|
|
791
|
+
"min_request_interval_ms: 100",
|
|
792
|
+
"---",
|
|
793
|
+
].join("\n"),
|
|
794
|
+
"utf-8",
|
|
795
|
+
);
|
|
796
|
+
|
|
797
|
+
process.env.GSD_HOME = tempGsdHome;
|
|
798
|
+
process.chdir(tempProject);
|
|
799
|
+
|
|
800
|
+
const loaded = loadEffectiveGSDPreferences();
|
|
801
|
+
assert.notEqual(loaded, null);
|
|
802
|
+
assert.equal(loaded!.preferences.min_request_interval_ms, 100);
|
|
803
|
+
assert.equal(loaded!.preferences.budget_ceiling, 45);
|
|
804
|
+
} finally {
|
|
805
|
+
process.chdir(originalCwd);
|
|
806
|
+
if (originalGsdHome === undefined) delete process.env.GSD_HOME;
|
|
807
|
+
else process.env.GSD_HOME = originalGsdHome;
|
|
808
|
+
rmSync(tempProject, { recursive: true, force: true });
|
|
809
|
+
rmSync(tempGsdHome, { recursive: true, force: true });
|
|
810
|
+
}
|
|
811
|
+
});
|
|
812
|
+
|
|
686
813
|
test("preferences paths use canonical uppercase filenames", () => {
|
|
687
814
|
const originalCwd = process.cwd();
|
|
688
815
|
const originalGsdHome = process.env.GSD_HOME;
|
|
@@ -93,4 +93,20 @@ describe('register-hooks session_before_compact (#3696)', () => {
|
|
|
93
93
|
'session_before_compact should not check isAutoPaused',
|
|
94
94
|
);
|
|
95
95
|
});
|
|
96
|
+
|
|
97
|
+
test('session_before_compact does not gate checkpointing to executing phase (#4258)', () => {
|
|
98
|
+
const compactIdx = registerHooksSrc.indexOf('session_before_compact');
|
|
99
|
+
assert.ok(compactIdx > -1, 'session_before_compact hook should exist');
|
|
100
|
+
|
|
101
|
+
const preCheckpointSection = registerHooksSrc.slice(
|
|
102
|
+
compactIdx,
|
|
103
|
+
registerHooksSrc.indexOf('const sliceDir', compactIdx),
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
const normalized = preCheckpointSection.replace(/\/\/.*$/gm, '');
|
|
107
|
+
assert.ok(
|
|
108
|
+
!/if\s*\(\s*state\.phase\s*!==\s*['"]executing['"]\s*\)\s*\{?\s*return\b/.test(normalized),
|
|
109
|
+
'session_before_compact should not early-return on non-executing phases',
|
|
110
|
+
);
|
|
111
|
+
});
|
|
96
112
|
});
|
|
@@ -103,6 +103,13 @@ test("classifyError detects Codex server_error from extracted message", () => {
|
|
|
103
103
|
assert.ok("retryAfterMs" in result && result.retryAfterMs === 30_000);
|
|
104
104
|
});
|
|
105
105
|
|
|
106
|
+
test("classifyError detects stream INTERNAL_ERROR received from peer as transient server", () => {
|
|
107
|
+
const result = classifyError("stream error: stream ID 75; INTERNAL_ERROR; received from peer");
|
|
108
|
+
assert.ok(isTransient(result));
|
|
109
|
+
assert.equal(result.kind, "server");
|
|
110
|
+
assert.ok("retryAfterMs" in result && result.retryAfterMs === 30_000);
|
|
111
|
+
});
|
|
112
|
+
|
|
106
113
|
test("classifyError detects overloaded error", () => {
|
|
107
114
|
const result = classifyError("overloaded_error: Overloaded");
|
|
108
115
|
assert.ok(isTransient(result));
|