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
|
@@ -1,28 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Behavioural regression tests for #2892.
|
|
3
3
|
*
|
|
4
|
-
* When the DB is open but empty (e.g
|
|
5
|
-
* getMilestoneSlices() returns []
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
4
|
+
* When the DB is open but empty (e.g. after crash/truncation),
|
|
5
|
+
* getMilestoneSlices() returns []. The fix in showDiscuss() falls back to
|
|
6
|
+
* parsing slices from the on-disk ROADMAP file instead of declaring "all
|
|
7
|
+
* slices are complete." These tests pin the parser contract that the
|
|
8
|
+
* fallback depends on: incomplete checkboxes (`[ ]`) yield `done=false`
|
|
9
|
+
* slices and completed checkboxes (`[x]`) yield `done=true`.
|
|
10
|
+
*
|
|
11
|
+
* The earlier source-grep / regex-on-showDiscuss-body tests (audit verdicts
|
|
12
|
+
* SOURCE_GREP / POSITIONAL — see #4826/#4829) were dropped; they pinned a
|
|
13
|
+
* specific surface form rather than behaviour.
|
|
9
14
|
*/
|
|
10
15
|
|
|
11
16
|
import { describe, test } from "node:test";
|
|
12
17
|
import assert from "node:assert/strict";
|
|
13
|
-
import { readFileSync } from "node:fs";
|
|
14
|
-
import { fileURLToPath } from "node:url";
|
|
15
|
-
import { dirname, join } from "node:path";
|
|
16
18
|
import { parseRoadmapSlices } from "../roadmap-slices.ts";
|
|
17
19
|
|
|
18
|
-
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
19
|
-
|
|
20
|
-
function readGuidedFlowSource(): string {
|
|
21
|
-
const thisFile = fileURLToPath(import.meta.url);
|
|
22
|
-
const thisDir = dirname(thisFile);
|
|
23
|
-
return readFileSync(join(thisDir, "..", "guided-flow.ts"), "utf-8");
|
|
24
|
-
}
|
|
25
|
-
|
|
26
20
|
const SAMPLE_ROADMAP = `# M012 Roadmap
|
|
27
21
|
|
|
28
22
|
## Slices
|
|
@@ -34,80 +28,23 @@ const SAMPLE_ROADMAP = `# M012 Roadmap
|
|
|
34
28
|
> After this: dashboard renders
|
|
35
29
|
`;
|
|
36
30
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
describe("discuss-empty-db-fallback (#2892)", () => {
|
|
40
|
-
|
|
41
|
-
test("1. parseRoadmapSlices extracts slices from a valid ROADMAP", () => {
|
|
31
|
+
describe("discuss-empty-db-fallback parser contract (#2892)", () => {
|
|
32
|
+
test("parseRoadmapSlices extracts slices from a valid ROADMAP", () => {
|
|
42
33
|
const slices = parseRoadmapSlices(SAMPLE_ROADMAP);
|
|
43
34
|
assert.strictEqual(slices.length, 3, "should parse 3 slices from sample roadmap");
|
|
44
|
-
|
|
45
|
-
assert.
|
|
46
|
-
assert.strictEqual(slices[2]!.id, "S03");
|
|
47
|
-
// All slices are incomplete ([ ] not [x])
|
|
48
|
-
assert.ok(slices.every(s => !s.done), "all slices should be incomplete");
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
test("2. guided-flow imports parseRoadmapSlices for roadmap fallback", () => {
|
|
52
|
-
const source = readGuidedFlowSource();
|
|
53
|
-
assert.ok(
|
|
54
|
-
source.includes("parseRoadmapSlices"),
|
|
55
|
-
"guided-flow must import parseRoadmapSlices to support roadmap fallback when DB is empty",
|
|
56
|
-
);
|
|
35
|
+
const ids = slices.map(s => s.id).sort();
|
|
36
|
+
assert.deepStrictEqual(ids, ["S01", "S02", "S03"]);
|
|
57
37
|
});
|
|
58
38
|
|
|
59
|
-
test("
|
|
60
|
-
const
|
|
61
|
-
// The fix must add a fallback that checks normSlices.length === 0 && roadmapContent
|
|
62
|
-
// and repopulates normSlices from the roadmap before the pendingSlices guard.
|
|
63
|
-
//
|
|
64
|
-
// Pattern: after DB query produces normSlices, if empty + roadmap exists,
|
|
65
|
-
// fall back to parseRoadmapSlices(roadmapContent).
|
|
66
|
-
const fallbackPattern = /normSlices\.length\s*===\s*0\s*&&\s*roadmapContent/;
|
|
39
|
+
test("incomplete checkboxes yield done=false (so fallback shows them as pending)", () => {
|
|
40
|
+
const slices = parseRoadmapSlices(SAMPLE_ROADMAP);
|
|
67
41
|
assert.ok(
|
|
68
|
-
|
|
69
|
-
"
|
|
42
|
+
slices.every(s => s.done === false),
|
|
43
|
+
"all 3 incomplete roadmap slices must be done=false — otherwise the empty-DB fallback would falsely report them complete (#2892)",
|
|
70
44
|
);
|
|
71
45
|
});
|
|
72
46
|
|
|
73
|
-
test("
|
|
74
|
-
const source = readGuidedFlowSource();
|
|
75
|
-
// Extract the showDiscuss function body
|
|
76
|
-
const fnMatch = source.match(
|
|
77
|
-
/async function showDiscuss\s*\([^)]*\)[^{]*\{([\s\S]*?)\nfunction\s/,
|
|
78
|
-
);
|
|
79
|
-
assert.ok(!!fnMatch, "showDiscuss function body must be found");
|
|
80
|
-
|
|
81
|
-
if (fnMatch) {
|
|
82
|
-
const body = fnMatch[1]!;
|
|
83
|
-
// After the DB query block (isDbAvailable/getMilestoneSlices), there should
|
|
84
|
-
// be a roadmap fallback BEFORE the pendingSlices.length === 0 check.
|
|
85
|
-
// Find the getMilestoneSlices call and the pendingSlices === 0 check
|
|
86
|
-
const dbQueryIdx = body.indexOf("getMilestoneSlices");
|
|
87
|
-
const fallbackIdx = body.indexOf("parseRoadmapSlices");
|
|
88
|
-
const pendingGuardIdx = body.indexOf('pendingSlices.length === 0');
|
|
89
|
-
|
|
90
|
-
assert.ok(dbQueryIdx > 0, "getMilestoneSlices call must exist");
|
|
91
|
-
assert.ok(fallbackIdx > 0, "parseRoadmapSlices fallback must exist");
|
|
92
|
-
assert.ok(pendingGuardIdx > 0, "pendingSlices.length === 0 guard must exist");
|
|
93
|
-
assert.ok(
|
|
94
|
-
fallbackIdx > dbQueryIdx && fallbackIdx < pendingGuardIdx,
|
|
95
|
-
"parseRoadmapSlices fallback must appear BETWEEN DB query and pendingSlices === 0 guard",
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
test("5. roadmap-parsed slices map to NormSlice format with done=false by default", () => {
|
|
101
|
-
// When falling back to roadmap, incomplete slices ([ ]) should map to done:false,
|
|
102
|
-
// ensuring they appear as pending and are NOT falsely reported as complete.
|
|
103
|
-
const slices = parseRoadmapSlices(SAMPLE_ROADMAP);
|
|
104
|
-
const normSlices = slices.map(s => ({ id: s.id, done: s.done, title: s.title }));
|
|
105
|
-
const pendingSlices = normSlices.filter(s => !s.done);
|
|
106
|
-
assert.strictEqual(pendingSlices.length, 3,
|
|
107
|
-
"all 3 incomplete roadmap slices should be pending — not falsely treated as complete");
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
test("6. roadmap with completed slices correctly reports them as done", () => {
|
|
47
|
+
test("completed checkboxes yield done=true; mixed roadmap surfaces only the open slices as pending", () => {
|
|
111
48
|
const completedRoadmap = `# M012 Roadmap
|
|
112
49
|
|
|
113
50
|
## Slices
|
|
@@ -119,9 +56,7 @@ describe("discuss-empty-db-fallback (#2892)", () => {
|
|
|
119
56
|
> After this: dashboard renders
|
|
120
57
|
`;
|
|
121
58
|
const slices = parseRoadmapSlices(completedRoadmap);
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
assert.strictEqual(pendingSlices.length, 1, "only S02 should be pending");
|
|
125
|
-
assert.strictEqual(pendingSlices[0]!.id, "S02");
|
|
59
|
+
const pendingIds = slices.filter(s => !s.done).map(s => s.id);
|
|
60
|
+
assert.deepStrictEqual(pendingIds, ["S02"], "only S02 should be reported as pending");
|
|
126
61
|
});
|
|
127
62
|
});
|
|
@@ -16,11 +16,9 @@
|
|
|
16
16
|
|
|
17
17
|
import { describe, test, afterEach } from "node:test";
|
|
18
18
|
import assert from "node:assert/strict";
|
|
19
|
-
import { mkdtempSync, mkdirSync, rmSync, writeFileSync
|
|
19
|
+
import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
20
20
|
import { join } from "node:path";
|
|
21
21
|
import { tmpdir } from "node:os";
|
|
22
|
-
import { fileURLToPath } from "node:url";
|
|
23
|
-
import { dirname } from "node:path";
|
|
24
22
|
|
|
25
23
|
import { deriveState } from "../state.ts";
|
|
26
24
|
import { invalidateAllCaches } from "../cache.ts";
|
|
@@ -57,12 +55,6 @@ function writeRoadmap(base: string, mid: string, content: string): void {
|
|
|
57
55
|
writeFileSync(join(base, ".gsd", "milestones", mid, `${mid}-ROADMAP.md`), content);
|
|
58
56
|
}
|
|
59
57
|
|
|
60
|
-
function readGuidedFlowSource(): string {
|
|
61
|
-
const thisFile = fileURLToPath(import.meta.url);
|
|
62
|
-
const thisDir = dirname(thisFile);
|
|
63
|
-
return readFileSync(join(thisDir, "..", "guided-flow.ts"), "utf-8");
|
|
64
|
-
}
|
|
65
|
-
|
|
66
58
|
// ─── Tests ────────────────────────────────────────────────────────────────────
|
|
67
59
|
|
|
68
60
|
describe("discuss-queued-milestones (#2307)", () => {
|
|
@@ -169,113 +161,10 @@ describe("discuss-queued-milestones (#2307)", () => {
|
|
|
169
161
|
}
|
|
170
162
|
});
|
|
171
163
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
// return;
|
|
179
|
-
// }
|
|
180
|
-
//
|
|
181
|
-
// The new guard should check for pending milestones and route instead.
|
|
182
|
-
const oldGuardPattern = /if\s*\(!state\.activeMilestone\)\s*\{\s*ctx\.ui\.notify\("No active milestone/;
|
|
183
|
-
assert.ok(
|
|
184
|
-
!oldGuardPattern.test(source),
|
|
185
|
-
"guided-flow must not unconditionally exit when activeMilestone is null",
|
|
186
|
-
);
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
test("7. showDiscussQueuedMilestone helper exists in guided-flow", () => {
|
|
190
|
-
const source = readGuidedFlowSource();
|
|
191
|
-
assert.ok(
|
|
192
|
-
source.includes("showDiscussQueuedMilestone"),
|
|
193
|
-
"guided-flow must export showDiscussQueuedMilestone helper",
|
|
194
|
-
);
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
test("8. dispatchDiscussForMilestone helper exists in guided-flow", () => {
|
|
198
|
-
const source = readGuidedFlowSource();
|
|
199
|
-
assert.ok(
|
|
200
|
-
source.includes("dispatchDiscussForMilestone"),
|
|
201
|
-
"guided-flow must export dispatchDiscussForMilestone helper",
|
|
202
|
-
);
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
test("9. dispatchDiscussForMilestone does not set pendingAutoStart", () => {
|
|
206
|
-
const source = readGuidedFlowSource();
|
|
207
|
-
|
|
208
|
-
// Extract the dispatchDiscussForMilestone function body
|
|
209
|
-
const fnMatch = source.match(
|
|
210
|
-
/async function dispatchDiscussForMilestone\s*\([^)]*\)[^{]*\{([\s\S]*?)\n\}/,
|
|
211
|
-
);
|
|
212
|
-
assert.ok(!!fnMatch, "dispatchDiscussForMilestone function body must be present");
|
|
213
|
-
|
|
214
|
-
if (fnMatch) {
|
|
215
|
-
assert.ok(
|
|
216
|
-
!fnMatch[1].includes("pendingAutoStart"),
|
|
217
|
-
"dispatchDiscussForMilestone must NOT set pendingAutoStart — discussing a queued milestone must not activate it",
|
|
218
|
-
);
|
|
219
|
-
}
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
test("10. slice picker includes queued milestone option when pending milestones exist", () => {
|
|
223
|
-
const source = readGuidedFlowSource();
|
|
224
|
-
assert.ok(
|
|
225
|
-
source.includes("discuss_queued_milestone"),
|
|
226
|
-
"slice picker must include a 'discuss_queued_milestone' action id for queued milestones",
|
|
227
|
-
);
|
|
228
|
-
assert.ok(
|
|
229
|
-
source.includes("Discuss a queued milestone"),
|
|
230
|
-
"slice picker must label the queued milestone action clearly",
|
|
231
|
-
);
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
test("11. queued milestone picker labels entries with [queued]", () => {
|
|
235
|
-
const source = readGuidedFlowSource();
|
|
236
|
-
assert.ok(
|
|
237
|
-
source.includes("[queued]"),
|
|
238
|
-
"queued milestone picker must label entries with [queued] to distinguish from active",
|
|
239
|
-
);
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
// ─── #3150: allDiscussed early-return must not block queued milestone discussion ──
|
|
243
|
-
|
|
244
|
-
test("12. allDiscussed path checks for pending milestones before returning (#3150)", () => {
|
|
245
|
-
const source = readGuidedFlowSource();
|
|
246
|
-
|
|
247
|
-
// Extract the allDiscussed block — the if (allDiscussed) { ... } body
|
|
248
|
-
const allDiscussedMatch = source.match(
|
|
249
|
-
/const allDiscussed = pendingSlices\.every\([\s\S]*?\n if \(allDiscussed\) \{([\s\S]*?)\n \}/,
|
|
250
|
-
);
|
|
251
|
-
assert.ok(!!allDiscussedMatch, "allDiscussed guard block must exist in showDiscuss()");
|
|
252
|
-
|
|
253
|
-
if (allDiscussedMatch) {
|
|
254
|
-
const body = allDiscussedMatch[1];
|
|
255
|
-
// The fix must check for pending milestones and route to showDiscussQueuedMilestone
|
|
256
|
-
assert.ok(
|
|
257
|
-
body.includes("pending") && body.includes("showDiscussQueuedMilestone"),
|
|
258
|
-
"allDiscussed block must check for pending milestones and call showDiscussQueuedMilestone before returning (#3150)",
|
|
259
|
-
);
|
|
260
|
-
}
|
|
261
|
-
});
|
|
262
|
-
|
|
263
|
-
test("13. pendingSlices.length===0 path checks for pending milestones before returning (#3150)", () => {
|
|
264
|
-
const source = readGuidedFlowSource();
|
|
265
|
-
|
|
266
|
-
// Find the pendingSlices.length === 0 guard block
|
|
267
|
-
const zeroSlicesMatch = source.match(
|
|
268
|
-
/if \(pendingSlices\.length === 0\) \{([\s\S]*?)\n \}/,
|
|
269
|
-
);
|
|
270
|
-
assert.ok(!!zeroSlicesMatch, "pendingSlices.length === 0 guard block must exist in showDiscuss()");
|
|
271
|
-
|
|
272
|
-
if (zeroSlicesMatch) {
|
|
273
|
-
const body = zeroSlicesMatch[1];
|
|
274
|
-
// The fix must check for pending milestones and route to showDiscussQueuedMilestone
|
|
275
|
-
assert.ok(
|
|
276
|
-
body.includes("pending") && body.includes("showDiscussQueuedMilestone"),
|
|
277
|
-
"pendingSlices.length===0 block must check for pending milestones and call showDiscussQueuedMilestone before returning (#3150)",
|
|
278
|
-
);
|
|
279
|
-
}
|
|
280
|
-
});
|
|
164
|
+
// The earlier tests 6-13 source-grepped guided-flow.ts for identifier
|
|
165
|
+
// names (showDiscussQueuedMilestone, dispatchDiscussForMilestone),
|
|
166
|
+
// UI-copy strings ("[queued]", "Discuss a queued milestone"), and
|
|
167
|
+
// regex-on-function-body assertions for the #3150 routing — all
|
|
168
|
+
// structural rather than behavioural (Refs #4826). They were dropped
|
|
169
|
+
// when this file was tightened against handler-level assertions.
|
|
281
170
|
});
|
|
@@ -1,77 +1,35 @@
|
|
|
1
|
-
// GSD-2 —
|
|
2
|
-
//
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
* all extension tools even when cwd hasn't changed
|
|
16
|
-
*/
|
|
1
|
+
// GSD-2 — Behavioural regression test for #3616.
|
|
2
|
+
//
|
|
3
|
+
// Bug: After a discuss session narrows the active tool set via setActiveTools,
|
|
4
|
+
// the narrowed list persisted into the next auto-mode session because newSession()
|
|
5
|
+
// did not restore extension tools when cwd was unchanged. This caused
|
|
6
|
+
// gsd_plan_slice and other DB tools to be missing from plan-slice subagent
|
|
7
|
+
// sessions.
|
|
8
|
+
//
|
|
9
|
+
// The behavioural invariant we can pin without grepping source: gsd_plan_slice
|
|
10
|
+
// (a heavy planning tool) is NOT inside the discuss allowlist. The remaining
|
|
11
|
+
// guarantees (newSession including all extension tools in both branches) are
|
|
12
|
+
// covered by agent-session.test.ts inside packages/pi-coding-agent.
|
|
13
|
+
//
|
|
14
|
+
// Refs #4826 (rewrite from source-grep on guided-flow.ts / agent-session.ts).
|
|
17
15
|
|
|
18
16
|
import { describe, test } from "node:test";
|
|
19
17
|
import assert from "node:assert/strict";
|
|
20
|
-
import { readFileSync } from "node:fs";
|
|
21
|
-
import { join, dirname } from "node:path";
|
|
22
|
-
import { fileURLToPath } from "node:url";
|
|
23
18
|
|
|
24
19
|
import { DISCUSS_TOOLS_ALLOWLIST } from "../constants.ts";
|
|
25
|
-
import { extractSourceRegion } from "./test-helpers.ts";
|
|
26
|
-
|
|
27
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
28
|
-
const guidedFlowSource = readFileSync(join(__dirname, "..", "guided-flow.ts"), "utf-8");
|
|
29
20
|
|
|
30
21
|
describe("#3616 — discuss tool scoping must not leak across sessions", () => {
|
|
31
22
|
test("gsd_plan_slice is NOT in DISCUSS_TOOLS_ALLOWLIST", () => {
|
|
32
23
|
assert.ok(
|
|
33
24
|
!DISCUSS_TOOLS_ALLOWLIST.includes("gsd_plan_slice"),
|
|
34
|
-
|
|
35
|
-
);
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
test("tool scoping only activates for discuss-* unit types", () => {
|
|
39
|
-
// The guard must be: if (unitType?.startsWith("discuss-"))
|
|
40
|
-
assert.ok(
|
|
41
|
-
guidedFlowSource.includes('unitType?.startsWith("discuss-")'),
|
|
42
|
-
"tool scoping should only trigger for discuss-* unit types",
|
|
25
|
+
`gsd_plan_slice (a heavy planning tool) must be excluded from the discuss scope; allowlist=${JSON.stringify(DISCUSS_TOOLS_ALLOWLIST)}`,
|
|
43
26
|
);
|
|
44
27
|
});
|
|
45
28
|
|
|
46
|
-
test("
|
|
47
|
-
// setActiveTools changes the active subset but doesn't remove tools from
|
|
48
|
-
// the registry. newSession()'s _refreshToolRegistry can restore them.
|
|
49
|
-
assert.ok(
|
|
50
|
-
guidedFlowSource.includes("pi.setActiveTools(scopedTools)"),
|
|
51
|
-
"should use pi.setActiveTools to narrow tools (preserving registry)",
|
|
52
|
-
);
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
test("newSession() in agent-session.ts has defense against tool narrowing persistence", () => {
|
|
56
|
-
const agentSessionSource = readFileSync(
|
|
57
|
-
join(process.cwd(), "packages/pi-coding-agent/src/core/agent-session.ts"),
|
|
58
|
-
"utf-8",
|
|
59
|
-
);
|
|
60
|
-
const newSessionStart = agentSessionSource.indexOf("async newSession(options?:");
|
|
61
|
-
assert.ok(newSessionStart >= 0, "should find newSession");
|
|
62
|
-
const body = extractSourceRegion(agentSessionSource, "async newSession(options?:");
|
|
63
|
-
|
|
64
|
-
// Both branches (cwd-changed and cwd-unchanged) must include extension tools
|
|
65
|
-
assert.ok(
|
|
66
|
-
body.includes("includeAllExtensionTools: true"),
|
|
67
|
-
"newSession() must include all extension tools in both branches",
|
|
68
|
-
);
|
|
69
|
-
|
|
70
|
-
// Count occurrences — should be at least 2 (one per branch)
|
|
71
|
-
const matches = body.match(/includeAllExtensionTools:\s*true/g);
|
|
29
|
+
test("DISCUSS_TOOLS_ALLOWLIST is non-empty (sanity)", () => {
|
|
72
30
|
assert.ok(
|
|
73
|
-
|
|
74
|
-
|
|
31
|
+
DISCUSS_TOOLS_ALLOWLIST.length > 0,
|
|
32
|
+
"discuss scope should include at least one tool — empty allowlist would break /gsd discuss",
|
|
75
33
|
);
|
|
76
34
|
});
|
|
77
35
|
});
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// GSD Extension — Regression test for #4996: doctor orphan milestone dir check
|
|
2
|
+
// Verifies that checkRuntimeHealth reports orphan_milestone_dir for empty stub
|
|
3
|
+
// dirs with no DB row, does not report populated dirs, and does not report
|
|
4
|
+
// legitimate in-flight worktree-only milestone dirs.
|
|
5
|
+
|
|
6
|
+
import { describe, it, afterEach } from "node:test";
|
|
7
|
+
import assert from "node:assert/strict";
|
|
8
|
+
import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { tmpdir } from "node:os";
|
|
11
|
+
|
|
12
|
+
import { checkRuntimeHealth } from "../doctor-runtime-checks.ts";
|
|
13
|
+
import {
|
|
14
|
+
openDatabase,
|
|
15
|
+
closeDatabase,
|
|
16
|
+
insertMilestone,
|
|
17
|
+
} from "../gsd-db.ts";
|
|
18
|
+
import { invalidateAllCaches } from "../cache.ts";
|
|
19
|
+
import type { DoctorIssue, DoctorIssueCode } from "../doctor-types.ts";
|
|
20
|
+
|
|
21
|
+
function makeBase(prefix = "gsd-doctor-orphan-"): string {
|
|
22
|
+
const base = mkdtempSync(join(tmpdir(), prefix));
|
|
23
|
+
mkdirSync(join(base, ".gsd", "milestones"), { recursive: true });
|
|
24
|
+
return base;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function stubDir(base: string, mid: string): void {
|
|
28
|
+
mkdirSync(join(base, ".gsd", "milestones", mid, "slices"), { recursive: true });
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function populateDir(base: string, mid: string): void {
|
|
32
|
+
mkdirSync(join(base, ".gsd", "milestones", mid), { recursive: true });
|
|
33
|
+
writeFileSync(join(base, ".gsd", "milestones", mid, `${mid}-CONTEXT.md`), `# ${mid}\n`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
describe("gsd_doctor orphan milestone directory check (#4996)", () => {
|
|
37
|
+
let base: string;
|
|
38
|
+
|
|
39
|
+
afterEach(() => {
|
|
40
|
+
try { closeDatabase(); } catch { /* ignore */ }
|
|
41
|
+
try { invalidateAllCaches(); } catch { /* ignore */ }
|
|
42
|
+
try { rmSync(base, { recursive: true, force: true }); } catch { /* ignore */ }
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("(a) empty stub dir with no DB row is reported as orphan_milestone_dir", async () => {
|
|
46
|
+
base = makeBase();
|
|
47
|
+
stubDir(base, "M003");
|
|
48
|
+
|
|
49
|
+
const issues: DoctorIssue[] = [];
|
|
50
|
+
const fixes: string[] = [];
|
|
51
|
+
await checkRuntimeHealth(base, issues, fixes, () => false);
|
|
52
|
+
|
|
53
|
+
const orphan = issues.find(i => i.code === "orphan_milestone_dir" && i.unitId === "M003");
|
|
54
|
+
assert.ok(orphan, "should report orphan_milestone_dir for empty stub");
|
|
55
|
+
assert.equal(orphan?.severity, "warning");
|
|
56
|
+
assert.equal(orphan?.fixable, true);
|
|
57
|
+
assert.ok(orphan?.message.includes("M003"), "message should name the milestone");
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("(b) populated milestone dir is NOT reported", async () => {
|
|
61
|
+
base = makeBase();
|
|
62
|
+
populateDir(base, "M001");
|
|
63
|
+
|
|
64
|
+
const issues: DoctorIssue[] = [];
|
|
65
|
+
const fixes: string[] = [];
|
|
66
|
+
await checkRuntimeHealth(base, issues, fixes, () => false);
|
|
67
|
+
|
|
68
|
+
const orphan = issues.find(i => i.code === "orphan_milestone_dir" && i.unitId === "M001");
|
|
69
|
+
assert.ok(!orphan, "populated milestone dir must not be reported as orphan");
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it("(c) worktree-only milestone (no content files, no DB row, but worktree exists) is NOT reported", async () => {
|
|
73
|
+
base = makeBase();
|
|
74
|
+
stubDir(base, "M003");
|
|
75
|
+
// Simulate a legitimate in-flight worktree
|
|
76
|
+
mkdirSync(join(base, ".gsd", "worktrees", "M003"), { recursive: true });
|
|
77
|
+
|
|
78
|
+
const issues: DoctorIssue[] = [];
|
|
79
|
+
const fixes: string[] = [];
|
|
80
|
+
await checkRuntimeHealth(base, issues, fixes, () => false);
|
|
81
|
+
|
|
82
|
+
const orphan = issues.find(i => i.code === "orphan_milestone_dir" && i.unitId === "M003");
|
|
83
|
+
assert.ok(!orphan, "milestone with a worktree must not be reported as orphan");
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it("(d) queued DB row (in-flight ID) is NOT reported as orphan", async () => {
|
|
87
|
+
base = makeBase();
|
|
88
|
+
stubDir(base, "M003");
|
|
89
|
+
const dbPath = join(base, ".gsd", "gsd.db");
|
|
90
|
+
openDatabase(dbPath);
|
|
91
|
+
insertMilestone({ id: "M003", status: "queued" });
|
|
92
|
+
|
|
93
|
+
const issues: DoctorIssue[] = [];
|
|
94
|
+
const fixes: string[] = [];
|
|
95
|
+
await checkRuntimeHealth(base, issues, fixes, () => false);
|
|
96
|
+
|
|
97
|
+
const orphan = issues.find(i => i.code === "orphan_milestone_dir" && i.unitId === "M003");
|
|
98
|
+
assert.ok(!orphan, "queued DB row must block orphan report (in-flight race protection)");
|
|
99
|
+
});
|
|
100
|
+
});
|
|
@@ -1,82 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Behavioural regression test for #2645 — double mergeAndExit guard.
|
|
3
|
+
*
|
|
4
|
+
* AutoSession.milestoneMergedInPhases is the producer-side flag set by the
|
|
5
|
+
* "complete" / "all-milestones-complete" branches in phases.ts after they
|
|
6
|
+
* call mergeAndExit. stopAuto reads it to skip the redundant Step-4 merge
|
|
7
|
+
* (which previously failed because the branch was already deleted).
|
|
8
|
+
*
|
|
9
|
+
* Refs #4829 (rewrite from positional source-grep on phases.ts/auto.ts).
|
|
10
|
+
*/
|
|
11
|
+
|
|
1
12
|
import { describe, test } from "node:test";
|
|
2
13
|
import assert from "node:assert/strict";
|
|
3
|
-
import { readFileSync } from "node:fs";
|
|
4
|
-
import { join, dirname } from "node:path";
|
|
5
|
-
import { fileURLToPath } from "node:url";
|
|
6
14
|
import { AutoSession } from "../auto/session.ts";
|
|
7
|
-
import { extractSourceRegion } from "./test-helpers.ts";
|
|
8
|
-
|
|
9
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
10
|
-
|
|
11
|
-
describe("double mergeAndExit guard (#2645)", () => {
|
|
12
|
-
test("phases.ts sets milestoneMergedInPhases after mergeAndExit in milestone-complete path", () => {
|
|
13
|
-
// Source audit: the "complete" phase path must set the guard flag
|
|
14
|
-
// after calling mergeAndExit so that stopAuto skips the second merge.
|
|
15
|
-
const phasesSrc = readFileSync(
|
|
16
|
-
join(__dirname, "..", "auto", "phases.ts"),
|
|
17
|
-
"utf-8",
|
|
18
|
-
);
|
|
19
|
-
|
|
20
|
-
// Find the "complete" phase block
|
|
21
|
-
const completeIdx = phasesSrc.indexOf('state.phase === "complete"');
|
|
22
|
-
assert.ok(completeIdx > 0, "phases.ts should have a 'complete' phase check");
|
|
23
|
-
|
|
24
|
-
const afterComplete = extractSourceRegion(phasesSrc, 'state.phase === "complete"');
|
|
25
|
-
const mergeIdx = afterComplete.indexOf("deps.resolver.mergeAndExit");
|
|
26
|
-
const flagIdx = afterComplete.indexOf("s.milestoneMergedInPhases = true");
|
|
27
|
-
|
|
28
|
-
assert.ok(mergeIdx > 0, "complete path should call mergeAndExit");
|
|
29
|
-
assert.ok(flagIdx > 0, "complete path should set milestoneMergedInPhases");
|
|
30
|
-
assert.ok(
|
|
31
|
-
flagIdx > mergeIdx,
|
|
32
|
-
"milestoneMergedInPhases must be set AFTER mergeAndExit (not before)",
|
|
33
|
-
);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
test("phases.ts sets milestoneMergedInPhases after mergeAndExit in all-milestones-complete path", () => {
|
|
37
|
-
const phasesSrc = readFileSync(
|
|
38
|
-
join(__dirname, "..", "auto", "phases.ts"),
|
|
39
|
-
"utf-8",
|
|
40
|
-
);
|
|
41
|
-
|
|
42
|
-
// The "all milestones complete" block checks incomplete.length === 0
|
|
43
|
-
const allCompleteIdx = phasesSrc.indexOf("incomplete.length === 0");
|
|
44
|
-
assert.ok(allCompleteIdx > 0, "phases.ts should have an all-milestones-complete check");
|
|
45
|
-
|
|
46
|
-
const afterAllComplete = extractSourceRegion(phasesSrc, "incomplete.length === 0");
|
|
47
|
-
const mergeIdx = afterAllComplete.indexOf("deps.resolver.mergeAndExit");
|
|
48
|
-
const flagIdx = afterAllComplete.indexOf("s.milestoneMergedInPhases = true");
|
|
49
|
-
|
|
50
|
-
assert.ok(mergeIdx > 0, "all-complete path should call mergeAndExit");
|
|
51
|
-
assert.ok(flagIdx > 0, "all-complete path should set milestoneMergedInPhases");
|
|
52
|
-
assert.ok(
|
|
53
|
-
flagIdx > mergeIdx,
|
|
54
|
-
"milestoneMergedInPhases must be set AFTER mergeAndExit (not before)",
|
|
55
|
-
);
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
test("stopAuto checks milestoneMergedInPhases before calling mergeAndExit", () => {
|
|
59
|
-
const autoSrc = readFileSync(
|
|
60
|
-
join(__dirname, "..", "auto.ts"),
|
|
61
|
-
"utf-8",
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
// The Step 4 worktree exit block must check the guard flag
|
|
65
|
-
const step4Idx = autoSrc.indexOf("Step 4: Auto-worktree exit");
|
|
66
|
-
assert.ok(step4Idx > 0, "auto.ts should have Step 4 worktree exit");
|
|
67
|
-
|
|
68
|
-
const step4Block = extractSourceRegion(autoSrc, "Step 4: Auto-worktree exit");
|
|
69
|
-
assert.ok(
|
|
70
|
-
step4Block.includes("milestoneMergedInPhases"),
|
|
71
|
-
"stopAuto Step 4 must check milestoneMergedInPhases before merging",
|
|
72
|
-
);
|
|
73
|
-
assert.ok(
|
|
74
|
-
step4Block.includes("!s.milestoneMergedInPhases"),
|
|
75
|
-
"stopAuto should skip merge when milestoneMergedInPhases is true",
|
|
76
|
-
);
|
|
77
|
-
});
|
|
78
15
|
|
|
79
|
-
|
|
16
|
+
describe("AutoSession.milestoneMergedInPhases (#2645)", () => {
|
|
17
|
+
test("defaults to false on a fresh session", () => {
|
|
80
18
|
const session = new AutoSession();
|
|
81
19
|
assert.equal(
|
|
82
20
|
session.milestoneMergedInPhases,
|
|
@@ -85,7 +23,7 @@ describe("double mergeAndExit guard (#2645)", () => {
|
|
|
85
23
|
);
|
|
86
24
|
});
|
|
87
25
|
|
|
88
|
-
test("
|
|
26
|
+
test("reset() clears the flag back to false", () => {
|
|
89
27
|
const session = new AutoSession();
|
|
90
28
|
session.milestoneMergedInPhases = true;
|
|
91
29
|
session.reset();
|