gsd-pi 2.78.0 → 2.78.1-dev.9d08d820b
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 +59 -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/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 +100 -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 +34 -8
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +121 -3
- 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-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/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 -3
- 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 +11 -11
- 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 +11 -11
- 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/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/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 +108 -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 +39 -8
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +141 -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-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/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/commands-extensions-version-compare.test.ts +58 -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/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/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 -3
- 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 → -Ukk6_YxRd4GY4iUOnRUE}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{C1zT2kEfoLhDdbWPWKrXd → -Ukk6_YxRd4GY4iUOnRUE}/_ssgManifest.js +0 -0
|
@@ -66,16 +66,22 @@ test("detectHealthWidgetProjectState: milestone without metrics returns active",
|
|
|
66
66
|
assert.equal(detectHealthWidgetProjectState(dir), "active");
|
|
67
67
|
});
|
|
68
68
|
|
|
69
|
-
test("buildHealthLines: none state shows onboarding
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
test("buildHealthLines: none state shows single onboarding line pointing at /gsd", (t) => {
|
|
70
|
+
const lines = buildHealthLines(activeData({ projectState: "none" }));
|
|
71
|
+
assert.equal(lines.length, 1, "renders exactly one line");
|
|
72
|
+
// Should not show System OK / Budget / Last commit chrome when there's no project.
|
|
73
|
+
assert.ok(!/System OK|Budget|Last commit/.test(lines[0]!), "no active-project chrome");
|
|
74
|
+
// Should direct user to bootstrap via /gsd.
|
|
75
|
+
assert.match(lines[0]!, /\/gsd/);
|
|
73
76
|
});
|
|
74
77
|
|
|
75
|
-
test("buildHealthLines: initialized state shows
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
]);
|
|
78
|
+
test("buildHealthLines: initialized state shows single setup line pointing at /gsd", (t) => {
|
|
79
|
+
const lines = buildHealthLines(activeData({ projectState: "initialized" }));
|
|
80
|
+
assert.equal(lines.length, 1, "renders exactly one line");
|
|
81
|
+
assert.ok(!/System OK|Budget|Last commit/.test(lines[0]!), "no active-project chrome");
|
|
82
|
+
// Distinct from "none" — must mention initialized/setup language and /gsd.
|
|
83
|
+
assert.match(lines[0]!, /\/gsd/);
|
|
84
|
+
assert.match(lines[0]!, /initiali[sz]ed|setup/i);
|
|
79
85
|
});
|
|
80
86
|
|
|
81
87
|
test("buildHealthLines: active state with ledger-driven spend shows spent summary", (t) => {
|
|
@@ -115,16 +121,20 @@ test("buildHealthLines: shows last commit with relative time and message", (t) =
|
|
|
115
121
|
assert.match(lines[0]!, /feat\(widget\): add health display/);
|
|
116
122
|
});
|
|
117
123
|
|
|
118
|
-
test("buildHealthLines: truncates long commit messages", (t) => {
|
|
124
|
+
test("buildHealthLines: truncates long commit messages with ellipsis", (t) => {
|
|
119
125
|
const epoch = Math.floor(Date.now() / 1000) - 60;
|
|
120
|
-
const longMsg = "a".repeat(
|
|
126
|
+
const longMsg = "a".repeat(200); // far longer than any reasonable widget cap
|
|
121
127
|
const lines = buildHealthLines(activeData({
|
|
122
128
|
lastCommitEpoch: epoch,
|
|
123
129
|
lastCommitMessage: longMsg,
|
|
124
130
|
}));
|
|
125
131
|
assert.equal(lines.length, 1);
|
|
126
|
-
|
|
127
|
-
|
|
132
|
+
// Behavioural contract: rendered output is shorter than the input message
|
|
133
|
+
// and ends the message portion with the ellipsis character.
|
|
134
|
+
const aRun = lines[0]!.match(/a+…/);
|
|
135
|
+
assert.ok(aRun, "rendered output contains a run of a-chars terminated by an ellipsis");
|
|
136
|
+
assert.ok(aRun![0].length - 1 < longMsg.length, "truncated message is shorter than input");
|
|
137
|
+
assert.ok(!lines[0]!.includes("a".repeat(longMsg.length)), "untruncated message must not appear in output");
|
|
128
138
|
});
|
|
129
139
|
|
|
130
140
|
test("buildHealthLines: no last commit section when epoch is null", (t) => {
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// GSD-2 — Verify /gsd help menu covers all registered commands
|
|
2
|
+
// Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
|
|
3
|
+
|
|
4
|
+
import { describe, test } from "node:test";
|
|
5
|
+
import assert from "node:assert/strict";
|
|
6
|
+
|
|
7
|
+
import { TOP_LEVEL_SUBCOMMANDS } from "../commands/catalog.ts";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Extracts command names from the showHelp("full") lines array.
|
|
11
|
+
* Each help line follows the pattern: " /gsd <cmd> ..."
|
|
12
|
+
*/
|
|
13
|
+
function extractHelpCommands(lines: string[]): Set<string> {
|
|
14
|
+
const cmds = new Set<string>();
|
|
15
|
+
for (const line of lines) {
|
|
16
|
+
const m = line.match(/^\s+\/gsd\s+(\S+)/);
|
|
17
|
+
if (m) cmds.add(m[1]);
|
|
18
|
+
}
|
|
19
|
+
return cmds;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
describe("help menu coverage", () => {
|
|
23
|
+
test("every TOP_LEVEL_SUBCOMMAND appears in showHelp(\"full\") output", async () => {
|
|
24
|
+
// Import showHelp and capture its output via a mock ctx
|
|
25
|
+
const lines: string[] = [];
|
|
26
|
+
const mockCtx = {
|
|
27
|
+
ui: {
|
|
28
|
+
notify(message: string) {
|
|
29
|
+
lines.push(...message.split("\n"));
|
|
30
|
+
},
|
|
31
|
+
custom: async () => {},
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const { showHelp } = await import("../commands/handlers/core.ts");
|
|
36
|
+
showHelp(mockCtx as any, "full");
|
|
37
|
+
|
|
38
|
+
const helpCmds = extractHelpCommands(lines);
|
|
39
|
+
|
|
40
|
+
// "help" is the command that shows the menu — it doesn't list itself
|
|
41
|
+
const SELF_REFERENTIAL = new Set(["help"]);
|
|
42
|
+
|
|
43
|
+
const missing: string[] = [];
|
|
44
|
+
for (const entry of TOP_LEVEL_SUBCOMMANDS) {
|
|
45
|
+
if (SELF_REFERENTIAL.has(entry.cmd)) continue;
|
|
46
|
+
if (!helpCmds.has(entry.cmd)) {
|
|
47
|
+
missing.push(entry.cmd);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
assert.deepStrictEqual(
|
|
52
|
+
missing,
|
|
53
|
+
[],
|
|
54
|
+
`Commands registered in TOP_LEVEL_SUBCOMMANDS but missing from /gsd help full:\n ${missing.join(", ")}`,
|
|
55
|
+
);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for getHomeDir() — cross-platform home directory resolution.
|
|
3
|
+
*
|
|
4
|
+
* @see https://github.com/gsd-build/gsd-2/issues/5015
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, beforeEach, afterEach } from "node:test";
|
|
7
|
+
import assert from "node:assert/strict";
|
|
8
|
+
import { homedir } from "node:os";
|
|
9
|
+
|
|
10
|
+
describe("getHomeDir", () => {
|
|
11
|
+
let savedHome: string | undefined;
|
|
12
|
+
let savedUserProfile: string | undefined;
|
|
13
|
+
let getHomeDir: () => string;
|
|
14
|
+
|
|
15
|
+
beforeEach(async () => {
|
|
16
|
+
savedHome = process.env.HOME;
|
|
17
|
+
savedUserProfile = process.env.USERPROFILE;
|
|
18
|
+
const mod = await import("../home-dir.ts");
|
|
19
|
+
getHomeDir = mod.getHomeDir;
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
afterEach(() => {
|
|
23
|
+
if (savedHome !== undefined) {
|
|
24
|
+
process.env.HOME = savedHome;
|
|
25
|
+
} else {
|
|
26
|
+
delete process.env.HOME;
|
|
27
|
+
}
|
|
28
|
+
if (savedUserProfile !== undefined) {
|
|
29
|
+
process.env.USERPROFILE = savedUserProfile;
|
|
30
|
+
} else {
|
|
31
|
+
delete process.env.USERPROFILE;
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("returns HOME when set", () => {
|
|
36
|
+
process.env.HOME = "/test/home";
|
|
37
|
+
delete process.env.USERPROFILE;
|
|
38
|
+
assert.equal(getHomeDir(), "/test/home");
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("falls back to USERPROFILE when HOME is unset", () => {
|
|
42
|
+
delete process.env.HOME;
|
|
43
|
+
process.env.USERPROFILE = String.raw`C:\Users\test`;
|
|
44
|
+
assert.equal(getHomeDir(), String.raw`C:\Users\test`);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("falls back to os.homedir() when both HOME and USERPROFILE are unset", () => {
|
|
48
|
+
delete process.env.HOME;
|
|
49
|
+
delete process.env.USERPROFILE;
|
|
50
|
+
assert.equal(getHomeDir(), homedir());
|
|
51
|
+
});
|
|
52
|
+
});
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime regression — milestones with all-done roadmap slices import as
|
|
3
|
+
* `complete` (#3699 / #3390 / #3379), follow-up #4902.
|
|
4
|
+
*
|
|
5
|
+
* The deleted `import-done-milestones.test.ts` was a source-grep check
|
|
6
|
+
* for the literal `roadmap.slices.every(s => s.done)`. This rewrite
|
|
7
|
+
* exercises `migrateHierarchyToDb()` against a fixture roadmap whose
|
|
8
|
+
* slices are all `[x]` and asserts the milestone row's `status` is
|
|
9
|
+
* `complete` — the actual behaviour the every() check exists to
|
|
10
|
+
* produce.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
|
|
14
|
+
import { join } from 'node:path';
|
|
15
|
+
import { tmpdir } from 'node:os';
|
|
16
|
+
|
|
17
|
+
import {
|
|
18
|
+
openDatabase,
|
|
19
|
+
closeDatabase,
|
|
20
|
+
getAllMilestones,
|
|
21
|
+
} from '../gsd-db.ts';
|
|
22
|
+
import { migrateHierarchyToDb } from '../md-importer.ts';
|
|
23
|
+
import { describe, test } from 'node:test';
|
|
24
|
+
import assert from 'node:assert/strict';
|
|
25
|
+
|
|
26
|
+
function createFixtureBase(): string {
|
|
27
|
+
const base = mkdtempSync(join(tmpdir(), 'gsd-import-done-'));
|
|
28
|
+
mkdirSync(join(base, '.gsd', 'milestones'), { recursive: true });
|
|
29
|
+
return base;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function writeFile(base: string, relativePath: string, content: string): void {
|
|
33
|
+
const full = join(base, '.gsd', relativePath);
|
|
34
|
+
mkdirSync(join(full, '..'), { recursive: true });
|
|
35
|
+
writeFileSync(full, content);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function cleanup(base: string): void {
|
|
39
|
+
rmSync(base, { recursive: true, force: true });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const ROADMAP_ALL_DONE = `# M001: Finished Milestone
|
|
43
|
+
|
|
44
|
+
**Vision:** Done work.
|
|
45
|
+
|
|
46
|
+
## Slices
|
|
47
|
+
|
|
48
|
+
- [x] **S01: First Slice** \`risk:low\` \`depends:[]\`
|
|
49
|
+
> After this: Done.
|
|
50
|
+
|
|
51
|
+
- [x] **S02: Second Slice** \`risk:medium\` \`depends:[S01]\`
|
|
52
|
+
> After this: Also done.
|
|
53
|
+
`;
|
|
54
|
+
|
|
55
|
+
const ROADMAP_PARTIAL = `# M002: In-Progress Milestone
|
|
56
|
+
|
|
57
|
+
**Vision:** Mid-flight.
|
|
58
|
+
|
|
59
|
+
## Slices
|
|
60
|
+
|
|
61
|
+
- [x] **S01: Done Slice** \`risk:low\` \`depends:[]\`
|
|
62
|
+
> After this: Done.
|
|
63
|
+
|
|
64
|
+
- [ ] **S02: Pending Slice** \`risk:medium\` \`depends:[S01]\`
|
|
65
|
+
> After this: TBD.
|
|
66
|
+
`;
|
|
67
|
+
|
|
68
|
+
const ROADMAP_EMPTY = `# M003: Empty Milestone
|
|
69
|
+
|
|
70
|
+
**Vision:** No slices yet.
|
|
71
|
+
|
|
72
|
+
## Slices
|
|
73
|
+
|
|
74
|
+
`;
|
|
75
|
+
|
|
76
|
+
describe('migrateHierarchyToDb: all-done milestones import as complete (#4902)', () => {
|
|
77
|
+
test('milestone with all [x] slices and no SUMMARY imports as complete', () => {
|
|
78
|
+
const base = createFixtureBase();
|
|
79
|
+
try {
|
|
80
|
+
writeFile(base, 'milestones/M001/M001-ROADMAP.md', ROADMAP_ALL_DONE);
|
|
81
|
+
// No SUMMARY.md — the all-done roadmap check is the authoritative signal.
|
|
82
|
+
|
|
83
|
+
openDatabase(':memory:');
|
|
84
|
+
migrateHierarchyToDb(base);
|
|
85
|
+
|
|
86
|
+
const milestones = getAllMilestones();
|
|
87
|
+
const m001 = milestones.find((m) => m.id === 'M001');
|
|
88
|
+
assert.ok(m001, 'M001 should be imported');
|
|
89
|
+
assert.equal(
|
|
90
|
+
m001!.status,
|
|
91
|
+
'complete',
|
|
92
|
+
'milestone with all-done slices must import as complete',
|
|
93
|
+
);
|
|
94
|
+
} finally {
|
|
95
|
+
closeDatabase();
|
|
96
|
+
cleanup(base);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test('milestone with one pending slice imports as active (negative case)', () => {
|
|
101
|
+
const base = createFixtureBase();
|
|
102
|
+
try {
|
|
103
|
+
writeFile(base, 'milestones/M002/M002-ROADMAP.md', ROADMAP_PARTIAL);
|
|
104
|
+
|
|
105
|
+
openDatabase(':memory:');
|
|
106
|
+
migrateHierarchyToDb(base);
|
|
107
|
+
|
|
108
|
+
const milestones = getAllMilestones();
|
|
109
|
+
const m002 = milestones.find((m) => m.id === 'M002');
|
|
110
|
+
assert.ok(m002, 'M002 should be imported');
|
|
111
|
+
assert.equal(
|
|
112
|
+
m002!.status,
|
|
113
|
+
'active',
|
|
114
|
+
'milestone with at least one pending slice must NOT be marked complete',
|
|
115
|
+
);
|
|
116
|
+
} finally {
|
|
117
|
+
closeDatabase();
|
|
118
|
+
cleanup(base);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
test('milestone with empty slice list does not import as complete', () => {
|
|
123
|
+
// Guards the `roadmap.slices.length > 0` precondition: an empty roadmap
|
|
124
|
+
// must not be misread as "everything is done" (vacuous truth bug).
|
|
125
|
+
const base = createFixtureBase();
|
|
126
|
+
try {
|
|
127
|
+
writeFile(base, 'milestones/M003/M003-ROADMAP.md', ROADMAP_EMPTY);
|
|
128
|
+
|
|
129
|
+
openDatabase(':memory:');
|
|
130
|
+
migrateHierarchyToDb(base);
|
|
131
|
+
|
|
132
|
+
const milestones = getAllMilestones();
|
|
133
|
+
const m003 = milestones.find((m) => m.id === 'M003');
|
|
134
|
+
assert.ok(m003, 'M003 should be imported');
|
|
135
|
+
assert.notEqual(
|
|
136
|
+
m003!.status,
|
|
137
|
+
'complete',
|
|
138
|
+
'empty roadmap (no slices) must not import as complete',
|
|
139
|
+
);
|
|
140
|
+
} finally {
|
|
141
|
+
closeDatabase();
|
|
142
|
+
cleanup(base);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
});
|
|
@@ -12,7 +12,7 @@ import { tmpdir } from "node:os";
|
|
|
12
12
|
import { join } from "node:path";
|
|
13
13
|
|
|
14
14
|
import { mapInitPrefsToWizardShape } from "../init-wizard.ts";
|
|
15
|
-
import { writePreferencesFile } from "../commands-prefs-wizard.ts";
|
|
15
|
+
import { handlePrefsWizard, writePreferencesFile } from "../commands-prefs-wizard.ts";
|
|
16
16
|
|
|
17
17
|
test("mapInitPrefsToWizardShape — full roundtrip with all fields", () => {
|
|
18
18
|
const out = mapInitPrefsToWizardShape({
|
|
@@ -123,6 +123,69 @@ test("writePreferencesFile — falls back to default body for new files", async
|
|
|
123
123
|
}
|
|
124
124
|
});
|
|
125
125
|
|
|
126
|
+
test("handlePrefsWizard — Advanced config writes min_request_interval_ms", async () => {
|
|
127
|
+
const tmp = mkdtempSync(join(tmpdir(), "gsd-init-prefs-routing-"));
|
|
128
|
+
const path = join(tmp, "PREFERENCES.md");
|
|
129
|
+
|
|
130
|
+
try {
|
|
131
|
+
const selectResponses = [
|
|
132
|
+
"Advanced",
|
|
133
|
+
"(keep current)",
|
|
134
|
+
"(keep current)",
|
|
135
|
+
"(keep current)",
|
|
136
|
+
"(keep current)",
|
|
137
|
+
"(keep current)",
|
|
138
|
+
"(keep current)",
|
|
139
|
+
"(keep current)",
|
|
140
|
+
"── Save & Exit ──",
|
|
141
|
+
];
|
|
142
|
+
const inputResponses = ["250"];
|
|
143
|
+
const ctx = {
|
|
144
|
+
ui: {
|
|
145
|
+
notify: () => {},
|
|
146
|
+
select: async (_label: string, options: string[]) => {
|
|
147
|
+
const response = selectResponses.shift();
|
|
148
|
+
if (response === undefined) {
|
|
149
|
+
throw new Error(
|
|
150
|
+
`Unexpected extra select prompt in handlePrefsWizard flow: selectResponses queue exhausted for "${_label}" ` +
|
|
151
|
+
"(expected no additional select prompts)",
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
if (response === "Advanced") {
|
|
155
|
+
const advancedOption = options.find((option) => option.startsWith("Advanced"));
|
|
156
|
+
if (!advancedOption) {
|
|
157
|
+
throw new Error(`Expected an "Advanced" option in "${_label}" menu`);
|
|
158
|
+
}
|
|
159
|
+
return advancedOption;
|
|
160
|
+
}
|
|
161
|
+
return response;
|
|
162
|
+
},
|
|
163
|
+
input: async () => {
|
|
164
|
+
const response = inputResponses.shift();
|
|
165
|
+
if (response === undefined) {
|
|
166
|
+
throw new Error(
|
|
167
|
+
"Unexpected extra input prompt in handlePrefsWizard flow: inputResponses queue exhausted " +
|
|
168
|
+
"(expected no additional input prompts)",
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
return response;
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
waitForIdle: async () => {},
|
|
175
|
+
reload: async () => {},
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
await handlePrefsWizard(ctx as any, "project", {}, { pathOverride: path });
|
|
179
|
+
|
|
180
|
+
assert.equal(selectResponses.length, 0, "Expected all queued selectResponses to be consumed");
|
|
181
|
+
assert.equal(inputResponses.length, 0, "Expected all queued inputResponses to be consumed");
|
|
182
|
+
const content = readFileSync(path, "utf-8");
|
|
183
|
+
assert.match(content, /^min_request_interval_ms:\s*250$/m);
|
|
184
|
+
} finally {
|
|
185
|
+
rmSync(tmp, { recursive: true, force: true });
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
|
|
126
189
|
// ─── Regression tests from #4457 codex adversarial review ──────────────────
|
|
127
190
|
|
|
128
191
|
test("init — Step 9b shape: 'not_yet' option is recognized as defer (#4457 review)", async () => {
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { describe, test, afterEach } from "node:test";
|
|
9
9
|
import assert from "node:assert/strict";
|
|
10
|
-
import { mkdtempSync, mkdirSync, writeFileSync, rmSync, existsSync, realpathSync } from "node:fs";
|
|
10
|
+
import { mkdtempSync, mkdirSync, writeFileSync, rmSync, existsSync, realpathSync, symlinkSync } from "node:fs";
|
|
11
11
|
import { join } from "node:path";
|
|
12
12
|
import { tmpdir } from "node:os";
|
|
13
13
|
import { execSync } from "node:child_process";
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
getAutoWorktreeOriginalBase,
|
|
22
22
|
getActiveAutoWorktreeContext,
|
|
23
23
|
syncGsdStateToWorktree,
|
|
24
|
+
_resetAutoWorktreeOriginalBaseForTests,
|
|
24
25
|
} from "../../auto-worktree.ts";
|
|
25
26
|
|
|
26
27
|
// Note: execSync is used intentionally in tests for git operations with
|
|
@@ -142,6 +143,54 @@ describe("auto-worktree lifecycle", () => {
|
|
|
142
143
|
teardownAutoWorktree(tempDir, "M003");
|
|
143
144
|
});
|
|
144
145
|
|
|
146
|
+
test("symlink-resolved auto worktree is detected after module state reset", () => {
|
|
147
|
+
tempDir = createTempRepo();
|
|
148
|
+
const savedGsdHome = process.env.GSD_HOME;
|
|
149
|
+
const fakeHome = realpathSync(mkdtempSync(join(tmpdir(), "auto-wt-home-")));
|
|
150
|
+
const storage = join(fakeHome, ".gsd", "projects", "abc123def456");
|
|
151
|
+
mkdirSync(join(storage, "milestones", "M001"), { recursive: true });
|
|
152
|
+
writeFileSync(join(storage, "milestones", "M001", "CONTEXT.md"), "# M001\n");
|
|
153
|
+
symlinkSync(storage, join(tempDir, ".gsd"));
|
|
154
|
+
process.env.GSD_HOME = join(fakeHome, ".gsd");
|
|
155
|
+
|
|
156
|
+
try {
|
|
157
|
+
const wtPath = createAutoWorktree(tempDir, "M001");
|
|
158
|
+
const realWtPath = realpathSync(wtPath);
|
|
159
|
+
assert.ok(realWtPath.startsWith(storage), "git registered the symlink-resolved worktree path");
|
|
160
|
+
|
|
161
|
+
_resetAutoWorktreeOriginalBaseForTests();
|
|
162
|
+
process.chdir(join(realWtPath, ".gsd", "milestones", "M001"));
|
|
163
|
+
|
|
164
|
+
assert.ok(isInAutoWorktree(tempDir), "structural detection works without module originalBase");
|
|
165
|
+
const resolved = getAutoWorktreePath(realWtPath, "M001");
|
|
166
|
+
assert.ok(resolved, "existing worktree is found when basePath is the worktree path");
|
|
167
|
+
assert.equal(realpathSync(resolved!), realWtPath);
|
|
168
|
+
assert.equal(existsSync(join(realWtPath, ".gsd", "worktrees", "M001")), false);
|
|
169
|
+
|
|
170
|
+
enterAutoWorktree(tempDir, "M001");
|
|
171
|
+
process.chdir(join(realWtPath, ".gsd", "milestones", "M001"));
|
|
172
|
+
assert.deepStrictEqual(
|
|
173
|
+
getActiveAutoWorktreeContext(),
|
|
174
|
+
{
|
|
175
|
+
originalBase: tempDir,
|
|
176
|
+
worktreeName: "M001",
|
|
177
|
+
branch: "milestone/M001",
|
|
178
|
+
},
|
|
179
|
+
"active context is detected from a symlink-resolved worktree cwd",
|
|
180
|
+
);
|
|
181
|
+
} finally {
|
|
182
|
+
process.chdir(tempDir);
|
|
183
|
+
try {
|
|
184
|
+
teardownAutoWorktree(tempDir, "M001");
|
|
185
|
+
} catch {
|
|
186
|
+
// Best-effort cleanup for partially-created temp worktrees.
|
|
187
|
+
}
|
|
188
|
+
if (savedGsdHome === undefined) delete process.env.GSD_HOME;
|
|
189
|
+
else process.env.GSD_HOME = savedGsdHome;
|
|
190
|
+
rmSync(fakeHome, { recursive: true, force: true });
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
|
|
145
194
|
test("coexistence with manual worktree", async () => {
|
|
146
195
|
tempDir = createTempRepo();
|
|
147
196
|
const msDir = join(tempDir, ".gsd", "milestones", "M003");
|
|
@@ -345,4 +394,26 @@ describe("auto-worktree lifecycle", () => {
|
|
|
345
394
|
teardownAutoWorktree(tempDir, "M003");
|
|
346
395
|
}
|
|
347
396
|
});
|
|
397
|
+
|
|
398
|
+
test("#2482: throws GSDError when repo has no commits", () => {
|
|
399
|
+
// Create a bare git init with no commits — HEAD is invalid
|
|
400
|
+
tempDir = realpathSync(mkdtempSync(join(tmpdir(), "auto-wt-empty-")));
|
|
401
|
+
run("git init", tempDir);
|
|
402
|
+
run("git config user.email test@test.com", tempDir);
|
|
403
|
+
run("git config user.name Test", tempDir);
|
|
404
|
+
|
|
405
|
+
assert.throws(
|
|
406
|
+
() => createAutoWorktree(tempDir, "M001"),
|
|
407
|
+
(err: unknown) => {
|
|
408
|
+
assert.ok(err instanceof Error, "should throw an Error");
|
|
409
|
+
assert.ok("code" in err, "should have a code property (GSDError)");
|
|
410
|
+
assert.strictEqual((err as { code: string }).code, "GSD_GIT_ERROR");
|
|
411
|
+
assert.ok(
|
|
412
|
+
err.message.includes("repository has no commits yet"),
|
|
413
|
+
`message should mention no commits, got: ${err.message}`,
|
|
414
|
+
);
|
|
415
|
+
return true;
|
|
416
|
+
},
|
|
417
|
+
);
|
|
418
|
+
});
|
|
348
419
|
});
|
|
@@ -338,27 +338,4 @@ console.log('\n=== token-savings: quality — correct scoping, no cross-contamin
|
|
|
338
338
|
rmSync(base, { recursive: true, force: true });
|
|
339
339
|
}
|
|
340
340
|
|
|
341
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
342
|
-
// Test: Fixture data realism — sufficient volume and distribution
|
|
343
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
344
|
-
|
|
345
|
-
console.log('\n=== token-savings: fixture data realism ===');
|
|
346
|
-
{
|
|
347
|
-
// Verify fixture generators produce sufficient volume
|
|
348
|
-
assert.ok(DECISIONS_COUNT >= 20, `decisions count ≥ 20 (actual: ${DECISIONS_COUNT})`);
|
|
349
|
-
assert.ok(REQUIREMENTS_COUNT >= 20, `requirements count ≥ 20 (actual: ${REQUIREMENTS_COUNT})`);
|
|
350
|
-
assert.ok(MILESTONES.length >= 3, `milestones ≥ 3 (actual: ${MILESTONES.length})`);
|
|
351
|
-
assert.ok(SLICE_ASSIGNMENTS.length >= 5, `slice assignments ≥ 5 (actual: ${SLICE_ASSIGNMENTS.length})`);
|
|
352
|
-
|
|
353
|
-
// Verify markdown content is substantial
|
|
354
|
-
assert.ok(decisionsMarkdown.length > 1000, `decisions markdown > 1000 chars (actual: ${decisionsMarkdown.length})`);
|
|
355
|
-
assert.ok(requirementsMarkdown.length > 1000, `requirements markdown > 1000 chars (actual: ${requirementsMarkdown.length})`);
|
|
356
|
-
|
|
357
|
-
// Verify content structure
|
|
358
|
-
assert.match(decisionsMarkdown, /\| D001 \|/, 'decisions markdown has D001');
|
|
359
|
-
assert.match(decisionsMarkdown, /\| D024 \|/, 'decisions markdown has D024');
|
|
360
|
-
assert.match(requirementsMarkdown, /### R001/, 'requirements markdown has R001');
|
|
361
|
-
assert.match(requirementsMarkdown, /### R021/, 'requirements markdown has R021');
|
|
362
|
-
}
|
|
363
|
-
|
|
364
341
|
// ─── Report ────────────────────────────────────────────────────────────────
|
|
@@ -4,6 +4,11 @@ import {
|
|
|
4
4
|
isDbAvailable,
|
|
5
5
|
_getAdapter,
|
|
6
6
|
} from '../gsd-db.ts';
|
|
7
|
+
import {
|
|
8
|
+
_resetLogs,
|
|
9
|
+
peekLogs,
|
|
10
|
+
setStderrLoggingEnabled,
|
|
11
|
+
} from '../workflow-logger.ts';
|
|
7
12
|
import {
|
|
8
13
|
getActiveMemories,
|
|
9
14
|
getActiveMemoriesRanked,
|
|
@@ -329,3 +334,126 @@ test('memory-store: schema includes memories table', () => {
|
|
|
329
334
|
|
|
330
335
|
closeDatabase();
|
|
331
336
|
});
|
|
337
|
+
|
|
338
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
339
|
+
// regression #4967 — createMemory must not silently swallow SQL errors
|
|
340
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
341
|
+
|
|
342
|
+
test('memory-store: createMemory throws on memory-table SQL errors (regression #4967)', () => {
|
|
343
|
+
openDatabase(':memory:');
|
|
344
|
+
|
|
345
|
+
const adapter = _getAdapter()!;
|
|
346
|
+
// Drop FTS + dependents first to satisfy SQLite's trigger ordering, then
|
|
347
|
+
// the base memories table. IF EXISTS makes setup robust against schema
|
|
348
|
+
// versions that may not have created every dependent (e.g. embeddings).
|
|
349
|
+
adapter.prepare('DROP TABLE IF EXISTS memory_embeddings').run();
|
|
350
|
+
adapter.prepare('DROP TABLE IF EXISTS memories_fts').run();
|
|
351
|
+
adapter.prepare('DROP TABLE IF EXISTS memories').run();
|
|
352
|
+
|
|
353
|
+
// Pre-fix behaviour: returns null and the caller has no idea why.
|
|
354
|
+
// Post-fix behaviour: throws so the caller can surface the real SQL message.
|
|
355
|
+
assert.throws(
|
|
356
|
+
() => createMemory({ category: 'gotcha', content: 'broken store' }),
|
|
357
|
+
/memories|no such table/i,
|
|
358
|
+
'createMemory must surface SQL errors instead of returning null',
|
|
359
|
+
);
|
|
360
|
+
|
|
361
|
+
closeDatabase();
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
test('memory-store: VACUUM retry rolls back partial memory and logs recovery', () => {
|
|
365
|
+
openDatabase(':memory:');
|
|
366
|
+
|
|
367
|
+
const adapter = _getAdapter()!;
|
|
368
|
+
const originalPrepareMethod = adapter.prepare;
|
|
369
|
+
const originalPrepare = adapter.prepare.bind(adapter);
|
|
370
|
+
const previousStderrLogging = setStderrLoggingEnabled(false);
|
|
371
|
+
const streamAny = process.stderr as unknown as {
|
|
372
|
+
write: (chunk: string | Uint8Array, ...rest: unknown[]) => boolean;
|
|
373
|
+
};
|
|
374
|
+
const originalStderrWrite = streamAny.write.bind(streamAny);
|
|
375
|
+
let selectFailures = 0;
|
|
376
|
+
let vacuumRuns = 0;
|
|
377
|
+
_resetLogs();
|
|
378
|
+
|
|
379
|
+
adapter.prepare = ((sql: string) => {
|
|
380
|
+
if (sql === 'SELECT seq FROM memories WHERE id = :id' && selectFailures === 0) {
|
|
381
|
+
const stmt = originalPrepare(sql);
|
|
382
|
+
return {
|
|
383
|
+
run: (...params: unknown[]) => stmt.run(...params),
|
|
384
|
+
get: (..._params: unknown[]) => {
|
|
385
|
+
selectFailures++;
|
|
386
|
+
throw new Error('database disk image is malformed');
|
|
387
|
+
},
|
|
388
|
+
all: (...params: unknown[]) => stmt.all(...params),
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
if (sql === 'VACUUM') {
|
|
393
|
+
const stmt = originalPrepare(sql);
|
|
394
|
+
return {
|
|
395
|
+
run: (...params: unknown[]) => {
|
|
396
|
+
vacuumRuns++;
|
|
397
|
+
return stmt.run(...params);
|
|
398
|
+
},
|
|
399
|
+
get: (...params: unknown[]) => stmt.get(...params),
|
|
400
|
+
all: (...params: unknown[]) => stmt.all(...params),
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
return originalPrepare(sql);
|
|
405
|
+
}) as typeof adapter.prepare;
|
|
406
|
+
streamAny.write = (): boolean => true;
|
|
407
|
+
|
|
408
|
+
try {
|
|
409
|
+
const id = createMemory({ category: 'gotcha', content: 'recover without duplicate' });
|
|
410
|
+
assert.equal(id, 'MEM001', 'retry should create a single first memory');
|
|
411
|
+
|
|
412
|
+
const rows = adapter.prepare('SELECT id FROM memories ORDER BY seq').all();
|
|
413
|
+
assert.deepStrictEqual(
|
|
414
|
+
rows.map((row) => row['id']),
|
|
415
|
+
['MEM001'],
|
|
416
|
+
'failed first attempt should not leave a live _TMP_ memory behind',
|
|
417
|
+
);
|
|
418
|
+
assert.equal(selectFailures, 1, 'test should simulate one malformed SELECT after INSERT');
|
|
419
|
+
assert.equal(vacuumRuns, 1, 'malformed recovery should run VACUUM once');
|
|
420
|
+
assert.ok(
|
|
421
|
+
peekLogs().some((entry) =>
|
|
422
|
+
entry.component === 'memory-store' &&
|
|
423
|
+
entry.message === 'recovered malformed memory store via VACUUM'
|
|
424
|
+
),
|
|
425
|
+
'successful VACUUM recovery should be emitted to the workflow logger',
|
|
426
|
+
);
|
|
427
|
+
} finally {
|
|
428
|
+
adapter.prepare = originalPrepareMethod;
|
|
429
|
+
streamAny.write = originalStderrWrite;
|
|
430
|
+
setStderrLoggingEnabled(previousStderrLogging);
|
|
431
|
+
_resetLogs();
|
|
432
|
+
closeDatabase();
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
test('memory-store: applyMemoryActions stays non-fatal when memory store is broken (regression #4967)', () => {
|
|
437
|
+
openDatabase(':memory:');
|
|
438
|
+
|
|
439
|
+
const adapter = _getAdapter()!;
|
|
440
|
+
// Drop FTS + dependents first to satisfy SQLite's trigger ordering, then
|
|
441
|
+
// the base memories table. IF EXISTS makes setup robust against schema
|
|
442
|
+
// versions that may not have created every dependent (e.g. embeddings).
|
|
443
|
+
adapter.prepare('DROP TABLE IF EXISTS memory_embeddings').run();
|
|
444
|
+
adapter.prepare('DROP TABLE IF EXISTS memories_fts').run();
|
|
445
|
+
adapter.prepare('DROP TABLE IF EXISTS memories').run();
|
|
446
|
+
|
|
447
|
+
// applyMemoryActions wraps createMemory in a transaction with an outer
|
|
448
|
+
// catch. Even with createMemory now throwing, applyMemoryActions must not
|
|
449
|
+
// crash the auto-mode flow that calls it (memory extraction is best-effort).
|
|
450
|
+
const actions: MemoryAction[] = [
|
|
451
|
+
{ action: 'CREATE', category: 'gotcha', content: 'inside-transaction call' },
|
|
452
|
+
];
|
|
453
|
+
assert.doesNotThrow(
|
|
454
|
+
() => applyMemoryActions(actions),
|
|
455
|
+
'applyMemoryActions must absorb thrown errors so callers continue',
|
|
456
|
+
);
|
|
457
|
+
|
|
458
|
+
closeDatabase();
|
|
459
|
+
});
|