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
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
getSlice,
|
|
14
14
|
updateSliceStatus,
|
|
15
15
|
getSliceTasks,
|
|
16
|
+
SCHEMA_VERSION,
|
|
16
17
|
} from '../gsd-db.ts';
|
|
17
18
|
import { handleCompleteSlice } from '../tools/complete-slice.ts';
|
|
18
19
|
import type { CompleteSliceParams } from '../types.ts';
|
|
@@ -115,19 +116,21 @@ Run the test suite and verify all assertions pass.
|
|
|
115
116
|
}
|
|
116
117
|
|
|
117
118
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
118
|
-
// complete-slice:
|
|
119
|
+
// complete-slice: fresh DB migrates to current schema version
|
|
119
120
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
120
121
|
|
|
121
|
-
console.log('\n=== complete-slice: schema
|
|
122
|
+
console.log('\n=== complete-slice: fresh DB migrates to current schema version ===');
|
|
122
123
|
{
|
|
123
124
|
const dbPath = tempDbPath();
|
|
124
125
|
openDatabase(dbPath);
|
|
125
126
|
|
|
126
127
|
const adapter = _getAdapter()!;
|
|
127
128
|
|
|
128
|
-
//
|
|
129
|
+
// Pin schema version against the source-of-truth constant so this test
|
|
130
|
+
// survives migration bumps but still catches a "fresh DB was not migrated"
|
|
131
|
+
// regression.
|
|
129
132
|
const versionRow = adapter.prepare('SELECT MAX(version) as v FROM schema_version').get();
|
|
130
|
-
assertEq(versionRow?.['v'],
|
|
133
|
+
assertEq(versionRow?.['v'], SCHEMA_VERSION, 'fresh DB should be migrated to current SCHEMA_VERSION');
|
|
131
134
|
|
|
132
135
|
// Verify slices table has full_summary_md and full_uat_md columns
|
|
133
136
|
const cols = adapter.prepare("PRAGMA table_info(slices)").all();
|
|
@@ -1,42 +1,99 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* reconciled to 'complete' via the file-existence path in state.ts.
|
|
2
|
+
* Behavioural regression test for #4129.
|
|
4
3
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* When deriveStateFromDb's reconcileSliceTasks finds a SUMMARY.md on disk
|
|
5
|
+
* for a task whose DB row is still pending, it flips the row to "complete".
|
|
6
|
+
* Before #4129, the call to updateTaskStatus omitted the completedAt
|
|
7
|
+
* timestamp, leaving completed_at NULL forever.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
9
|
+
* The fix passes new Date().toISOString() as the 5th argument; this test
|
|
10
|
+
* exercises that path end-to-end and asserts the column is populated.
|
|
11
|
+
*
|
|
12
|
+
* Refs #4829 (rewrite from positional source-grep).
|
|
10
13
|
*/
|
|
11
14
|
|
|
12
|
-
import { describe, test } from
|
|
13
|
-
import assert from
|
|
14
|
-
import {
|
|
15
|
-
import { join
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
15
|
+
import { describe, test, beforeEach, afterEach } from 'node:test';
|
|
16
|
+
import assert from 'node:assert/strict';
|
|
17
|
+
import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
|
|
18
|
+
import { join } from 'node:path';
|
|
19
|
+
import { tmpdir } from 'node:os';
|
|
20
|
+
|
|
21
|
+
import { deriveStateFromDb, invalidateStateCache } from '../state.ts';
|
|
22
|
+
import {
|
|
23
|
+
openDatabase,
|
|
24
|
+
closeDatabase,
|
|
25
|
+
insertMilestone,
|
|
26
|
+
insertSlice,
|
|
27
|
+
insertTask,
|
|
28
|
+
getTask,
|
|
29
|
+
} from '../gsd-db.ts';
|
|
30
|
+
|
|
31
|
+
let basePath: string;
|
|
32
|
+
|
|
33
|
+
function setupProject(): void {
|
|
34
|
+
basePath = mkdtempSync(join(tmpdir(), 'gsd-completed-at-'));
|
|
35
|
+
// Project structure with active milestone, one slice, one task whose
|
|
36
|
+
// SUMMARY.md is already on disk — but the DB row is still "pending".
|
|
37
|
+
mkdirSync(join(basePath, '.gsd', 'milestones', 'M001', 'slices', 'S01', 'tasks'), { recursive: true });
|
|
38
|
+
|
|
39
|
+
// CONTEXT + ROADMAP so deriveState identifies M001 as active and S01 as the active slice.
|
|
40
|
+
writeFileSync(
|
|
41
|
+
join(basePath, '.gsd', 'milestones', 'M001', 'M001-CONTEXT.md'),
|
|
42
|
+
'# M001\nActive milestone.\n',
|
|
43
|
+
);
|
|
44
|
+
writeFileSync(
|
|
45
|
+
join(basePath, '.gsd', 'milestones', 'M001', 'M001-ROADMAP.md'),
|
|
46
|
+
`# M001\n\n## Slices\n\n- [ ] **S01: Slice** \`risk:low\` \`depends:[]\`\n - After this: works\n`,
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
// Plan file for the slice so reconcile can populate task list if DB is empty.
|
|
50
|
+
writeFileSync(
|
|
51
|
+
join(basePath, '.gsd', 'milestones', 'M001', 'slices', 'S01', 'S01-PLAN.md'),
|
|
52
|
+
`# S01: Slice\n\n## Tasks\n\n- [ ] **T01: Test task** \`est:30m\`\n - Do: x\n - Verify: y\n`,
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
// The summary file: this is the on-disk evidence that flips the task
|
|
56
|
+
// status to "complete" inside reconcileSliceTasks.
|
|
57
|
+
writeFileSync(
|
|
58
|
+
join(basePath, '.gsd', 'milestones', 'M001', 'slices', 'S01', 'tasks', 'T01-SUMMARY.md'),
|
|
59
|
+
'---\nid: T01\nparent: S01\nmilestone: M001\nblocker_discovered: false\n---\n# T01\n',
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
describe('completed_at reconcile (#4129)', () => {
|
|
64
|
+
beforeEach(() => {
|
|
65
|
+
setupProject();
|
|
66
|
+
openDatabase(join(basePath, '.gsd', 'gsd.db'));
|
|
67
|
+
insertMilestone({ id: 'M001', title: 'M001', status: 'active' });
|
|
68
|
+
insertSlice({ id: 'S01', milestoneId: 'M001', title: 'Slice', status: 'active' });
|
|
69
|
+
// Task is "pending" in DB, but SUMMARY.md exists on disk → reconcile flips it.
|
|
70
|
+
insertTask({ id: 'T01', sliceId: 'S01', milestoneId: 'M001', title: 'Test task', status: 'pending' });
|
|
71
|
+
invalidateStateCache();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
afterEach(() => {
|
|
75
|
+
closeDatabase();
|
|
76
|
+
try { rmSync(basePath, { recursive: true, force: true }); } catch { /* */ }
|
|
32
77
|
});
|
|
33
78
|
|
|
34
|
-
test(
|
|
35
|
-
|
|
36
|
-
assert.
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
79
|
+
test('reconcileSliceTasks sets completed_at when flipping a pending task to complete via SUMMARY.md', async () => {
|
|
80
|
+
const before = getTask('M001', 'S01', 'T01');
|
|
81
|
+
assert.strictEqual(before?.status, 'pending', 'task starts pending');
|
|
82
|
+
assert.strictEqual(before?.completed_at, null, 'task starts with completed_at NULL');
|
|
83
|
+
|
|
84
|
+
// Trigger the reconcile path (state.ts → reconcileSliceTasks).
|
|
85
|
+
await deriveStateFromDb(basePath);
|
|
86
|
+
|
|
87
|
+
const after = getTask('M001', 'S01', 'T01');
|
|
88
|
+
assert.strictEqual(after?.status, 'complete', 'task should be flipped to complete');
|
|
89
|
+
assert.ok(
|
|
90
|
+
typeof after?.completed_at === 'string' && after.completed_at.length > 0,
|
|
91
|
+
`completed_at must be populated by reconcileSliceTasks (#4129); got ${JSON.stringify(after?.completed_at)}`,
|
|
92
|
+
);
|
|
93
|
+
// Sanity: timestamp parses as a valid ISO date.
|
|
94
|
+
assert.ok(
|
|
95
|
+
!Number.isNaN(Date.parse(after!.completed_at!)),
|
|
96
|
+
`completed_at should be a valid ISO timestamp, got ${after!.completed_at}`,
|
|
40
97
|
);
|
|
41
98
|
});
|
|
42
99
|
});
|
|
@@ -12,7 +12,7 @@ import { mkdtempSync, rmSync, existsSync } from "node:fs";
|
|
|
12
12
|
import { join } from "node:path";
|
|
13
13
|
import { tmpdir } from "node:os";
|
|
14
14
|
|
|
15
|
-
import { autoLoop, resolveAgentEnd, _resetPendingResolve } from "../auto-loop.js";
|
|
15
|
+
import { autoLoop, resolveAgentEnd, _hasPendingResolveForTest, _resetPendingResolve } from "../auto-loop.js";
|
|
16
16
|
import type { LoopDeps } from "../auto/loop-deps.js";
|
|
17
17
|
import type { SessionLockStatus } from "../session-lock.js";
|
|
18
18
|
import { writeGraph, readGraph, type WorkflowGraph, type GraphStep } from "../graph.ts";
|
|
@@ -29,6 +29,17 @@ function makeTmpDir(): string {
|
|
|
29
29
|
return dir;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
async function resolveNextAgentEnd(timeoutMs = 3_000): Promise<void> {
|
|
33
|
+
const deadline = Date.now() + timeoutMs;
|
|
34
|
+
while (!_hasPendingResolveForTest()) {
|
|
35
|
+
if (Date.now() > deadline) {
|
|
36
|
+
throw new Error("Timed out waiting for pending agent_end resolver");
|
|
37
|
+
}
|
|
38
|
+
await new Promise((r) => setTimeout(r, 5));
|
|
39
|
+
}
|
|
40
|
+
resolveAgentEnd({ messages: [{ role: "assistant" }] });
|
|
41
|
+
}
|
|
42
|
+
|
|
32
43
|
afterEach(() => {
|
|
33
44
|
_resetPendingResolve();
|
|
34
45
|
for (const d of tmpDirs) {
|
|
@@ -276,19 +287,16 @@ describe("Custom engine loop integration", () => {
|
|
|
276
287
|
// We need to resolve resolveAgentEnd for each step.
|
|
277
288
|
|
|
278
289
|
// Step 1: step-a
|
|
279
|
-
await new Promise((r) => setTimeout(r, 80));
|
|
280
290
|
unitCount++;
|
|
281
|
-
|
|
291
|
+
await resolveNextAgentEnd();
|
|
282
292
|
|
|
283
293
|
// Step 2: step-b
|
|
284
|
-
await new Promise((r) => setTimeout(r, 80));
|
|
285
294
|
unitCount++;
|
|
286
|
-
|
|
295
|
+
await resolveNextAgentEnd();
|
|
287
296
|
|
|
288
297
|
// Step 3: step-c
|
|
289
|
-
await new Promise((r) => setTimeout(r, 80));
|
|
290
298
|
unitCount++;
|
|
291
|
-
|
|
299
|
+
await resolveNextAgentEnd();
|
|
292
300
|
|
|
293
301
|
// After step-c completes, engine.reconcile marks it complete, then
|
|
294
302
|
// next deriveState sees isComplete=true → stopAuto → loop exits
|
|
@@ -398,8 +406,7 @@ describe("Custom engine loop integration", () => {
|
|
|
398
406
|
|
|
399
407
|
const loopPromise = autoLoop(ctx, pi, s, deps);
|
|
400
408
|
|
|
401
|
-
await
|
|
402
|
-
resolveAgentEnd({ messages: [{ role: "assistant" }] });
|
|
409
|
+
await resolveNextAgentEnd();
|
|
403
410
|
|
|
404
411
|
await loopPromise;
|
|
405
412
|
|
|
@@ -460,12 +467,10 @@ describe("Custom engine loop integration", () => {
|
|
|
460
467
|
const loopPromise = autoLoop(ctx, pi, s, deps);
|
|
461
468
|
|
|
462
469
|
// Resolve step-a
|
|
463
|
-
await
|
|
464
|
-
resolveAgentEnd({ messages: [{ role: "assistant" }] });
|
|
470
|
+
await resolveNextAgentEnd();
|
|
465
471
|
|
|
466
472
|
// Resolve step-b
|
|
467
|
-
await
|
|
468
|
-
resolveAgentEnd({ messages: [{ role: "assistant" }] });
|
|
473
|
+
await resolveNextAgentEnd();
|
|
469
474
|
|
|
470
475
|
await loopPromise;
|
|
471
476
|
|
|
@@ -514,7 +519,9 @@ describe("Custom engine loop integration", () => {
|
|
|
514
519
|
});
|
|
515
520
|
|
|
516
521
|
const resolver = setInterval(() => {
|
|
517
|
-
|
|
522
|
+
if (_hasPendingResolveForTest()) {
|
|
523
|
+
resolveAgentEnd({ messages: [{ role: "assistant" }] });
|
|
524
|
+
}
|
|
518
525
|
}, 25);
|
|
519
526
|
let timeout: NodeJS.Timeout | undefined;
|
|
520
527
|
try {
|
|
@@ -569,7 +576,9 @@ describe("Custom engine loop integration", () => {
|
|
|
569
576
|
});
|
|
570
577
|
const deps1 = makeMockDeps();
|
|
571
578
|
const resolver1 = setInterval(() => {
|
|
572
|
-
|
|
579
|
+
if (_hasPendingResolveForTest()) {
|
|
580
|
+
resolveAgentEnd({ messages: [{ role: "assistant" }] });
|
|
581
|
+
}
|
|
573
582
|
if (pi1.calls.length >= 2) {
|
|
574
583
|
s1.active = false;
|
|
575
584
|
}
|
|
@@ -614,7 +623,9 @@ describe("Custom engine loop integration", () => {
|
|
|
614
623
|
},
|
|
615
624
|
});
|
|
616
625
|
const resolver2 = setInterval(() => {
|
|
617
|
-
|
|
626
|
+
if (_hasPendingResolveForTest()) {
|
|
627
|
+
resolveAgentEnd({ messages: [{ role: "assistant" }] });
|
|
628
|
+
}
|
|
618
629
|
}, 25);
|
|
619
630
|
let timeout2: NodeJS.Timeout | undefined;
|
|
620
631
|
try {
|
|
@@ -640,7 +651,12 @@ describe("Custom engine loop integration", () => {
|
|
|
640
651
|
assert.match(stopEntry ?? "", /requested retry 4 times without passing/);
|
|
641
652
|
});
|
|
642
653
|
|
|
643
|
-
it("
|
|
654
|
+
it("two-step workflow drives both steps to complete and stops when isComplete fires", async () => {
|
|
655
|
+
// Note (#4831): renamed from "GRAPH.yaml step stays pending when session
|
|
656
|
+
// deactivates before reconcile" — the assertion body never proved the
|
|
657
|
+
// pending-on-deactivate claim and even comments that "the reconcile
|
|
658
|
+
// will still run for step-b". The behaviour this test actually pins is:
|
|
659
|
+
// both steps reconcile complete and stopAuto fires once isComplete.
|
|
644
660
|
_resetPendingResolve();
|
|
645
661
|
|
|
646
662
|
// Two-step workflow: a → b. We will complete step-a, then force a break
|
|
@@ -672,28 +688,30 @@ describe("Custom engine loop integration", () => {
|
|
|
672
688
|
const loopPromise = autoLoop(ctx, pi, s, deps);
|
|
673
689
|
|
|
674
690
|
// Resolve step-a successfully
|
|
675
|
-
await
|
|
676
|
-
resolveAgentEnd({ messages: [{ role: "assistant" }] });
|
|
691
|
+
await resolveNextAgentEnd();
|
|
677
692
|
|
|
678
693
|
// Step-b enters runUnit — deactivate the session before resolving.
|
|
679
694
|
// runUnit checks s.active after newSession and returns cancelled if false.
|
|
680
695
|
// But since newSession resolves synchronously in our mock (before the
|
|
681
696
|
// active check), the unit still runs. Instead, let's just cancel it.
|
|
682
|
-
await new Promise((r) => setTimeout(r, 80));
|
|
683
697
|
// Resolve as cancelled to simulate a failed session
|
|
684
|
-
|
|
698
|
+
await resolveNextAgentEnd();
|
|
685
699
|
|
|
686
700
|
// The reconcile will still run for step-b in this flow since
|
|
687
701
|
// runUnitPhase returns "next" (not "break") for completed units.
|
|
688
702
|
// After both steps complete, the engine detects isComplete and stops.
|
|
689
703
|
await loopPromise;
|
|
690
704
|
|
|
691
|
-
//
|
|
705
|
+
// Both steps reconcile complete; the renamed expectation pins that the
|
|
706
|
+
// engine drives the workflow through isComplete rather than leaving any
|
|
707
|
+
// step pending.
|
|
692
708
|
const finalGraph = readGraph(runDir);
|
|
693
709
|
const stepA = finalGraph.steps.find(s => s.id === "step-a");
|
|
710
|
+
const stepB = finalGraph.steps.find(s => s.id === "step-b");
|
|
694
711
|
assert.equal(stepA?.status, "complete", "Step-a should be complete");
|
|
712
|
+
assert.equal(stepB?.status, "complete", "Step-b should be complete");
|
|
695
713
|
|
|
696
|
-
//
|
|
714
|
+
// The loop must stop once isComplete fires.
|
|
697
715
|
assert.ok(
|
|
698
716
|
deps.callLog.some((e: string) => e.startsWith("stopAuto:")),
|
|
699
717
|
"stopAuto should have been called",
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
* retrying can never succeed and causes cost spikes.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import { readFileSync } from "node:fs";
|
|
20
19
|
import { join, sep } from "node:path";
|
|
21
20
|
import { createTestContext } from "./test-helpers.ts";
|
|
22
21
|
|
|
@@ -89,47 +88,8 @@ assertEq(
|
|
|
89
88
|
"Non-worktree path is unchanged",
|
|
90
89
|
);
|
|
91
90
|
|
|
92
|
-
//
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const dynamicToolsSrc = readFileSync(
|
|
97
|
-
join(import.meta.dirname, "..", "bootstrap", "dynamic-tools.ts"),
|
|
98
|
-
"utf-8",
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
// ensureDbOpen should surface diagnostic context, not just boolean false
|
|
102
|
-
// Check that the catch block logs error details via workflow-logger
|
|
103
|
-
assertTrue(
|
|
104
|
-
dynamicToolsSrc.includes("ensureDbOpen failed") && dynamicToolsSrc.includes("logWarning"),
|
|
105
|
-
"ensureDbOpen catch block surfaces diagnostic information via logWarning instead of bare false (#2517)",
|
|
106
|
-
);
|
|
107
|
-
|
|
108
|
-
// ── Part 3: post-unit does NOT artifact-retry on db_unavailable ──────────
|
|
109
|
-
|
|
110
|
-
console.log("\n=== #2517 Part 3: post-unit db_unavailable is infra-fatal ===");
|
|
111
|
-
|
|
112
|
-
const postUnitSrc = readFileSync(
|
|
113
|
-
join(import.meta.dirname, "..", "auto-post-unit.ts"),
|
|
114
|
-
"utf-8",
|
|
115
|
-
);
|
|
116
|
-
|
|
117
|
-
// The artifact retry block should check DB availability and skip retry
|
|
118
|
-
// when the DB is unavailable (infra failure, not a missing artifact).
|
|
119
|
-
assertTrue(
|
|
120
|
-
postUnitSrc.includes("db_unavailable") || postUnitSrc.includes("isDbAvailable"),
|
|
121
|
-
"post-unit artifact retry path checks DB availability to avoid retry loop (#2517)",
|
|
122
|
-
);
|
|
123
|
-
|
|
124
|
-
// Verify the retry block is guarded: when !isDbAvailable(), the code must
|
|
125
|
-
// NOT return "retry". The pattern should be: if (!verified && !isDbAvailable()) { skip }
|
|
126
|
-
// followed by else if (!verified) { ... return "retry" }
|
|
127
|
-
const dbUnavailableGuard = postUnitSrc.match(
|
|
128
|
-
/!triggerArtifactVerified\s*&&\s*!isDbAvailable\(\)/,
|
|
129
|
-
);
|
|
130
|
-
assertTrue(
|
|
131
|
-
!!dbUnavailableGuard,
|
|
132
|
-
"The retry block explicitly guards against !isDbAvailable() before returning 'retry' (#2517)",
|
|
133
|
-
);
|
|
91
|
+
// Source-grep checks for ensureDbOpen diagnostics + post-unit retry guard
|
|
92
|
+
// were removed (#4826) — the behavioural retry-loop tests live in
|
|
93
|
+
// auto-post-unit.test.ts and exercise isDbAvailable() directly.
|
|
134
94
|
|
|
135
95
|
report();
|
|
@@ -167,9 +167,11 @@ test('auto-prunes old debug logs', () => {
|
|
|
167
167
|
enableDebug(tmp);
|
|
168
168
|
|
|
169
169
|
const files = readdirSync(debugDir).filter(f => f.startsWith('debug-') && f.endsWith('.log'));
|
|
170
|
-
//
|
|
171
|
-
//
|
|
172
|
-
|
|
170
|
+
// MAX_DEBUG_LOGS is 5 — enableDebug prunes to < 5 old and then creates 1 new,
|
|
171
|
+
// so the directory must hold at most 5 files in total. The previous
|
|
172
|
+
// assertion (<= 6) would have passed even with one stale log left behind
|
|
173
|
+
// (Refs #4831).
|
|
174
|
+
assert.ok(files.length <= 5, `should have pruned old logs to <= 5, got ${files.length}`);
|
|
173
175
|
|
|
174
176
|
disableDebug();
|
|
175
177
|
});
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// GSD Extension — Regression test for #4996: deferred milestone dir creation
|
|
2
|
+
// Verifies that showHeadlessMilestoneCreation does not pre-create the milestone
|
|
3
|
+
// directory before the discuss flow runs. The dir should only appear after a
|
|
4
|
+
// writer (saveArtifactToDb / atomicWriteAsync) emits the first artifact.
|
|
5
|
+
|
|
6
|
+
import { describe, it, beforeEach, afterEach } from "node:test";
|
|
7
|
+
import assert from "node:assert/strict";
|
|
8
|
+
import { mkdtempSync, mkdirSync, existsSync, rmSync, readFileSync } from "node:fs";
|
|
9
|
+
import { dirname, join } from "node:path";
|
|
10
|
+
import { tmpdir } from "node:os";
|
|
11
|
+
import { fileURLToPath } from "node:url";
|
|
12
|
+
|
|
13
|
+
import { isReusableGhostMilestone } from "../state.ts";
|
|
14
|
+
import { nextMilestoneIdReserved } from "../milestone-id-reservation.ts";
|
|
15
|
+
import { clearReservedMilestoneIds, findMilestoneIds } from "../milestone-ids.ts";
|
|
16
|
+
import { invalidateAllCaches } from "../cache.ts";
|
|
17
|
+
import { closeDatabase, openDatabase } from "../gsd-db.ts";
|
|
18
|
+
|
|
19
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
20
|
+
const GUIDED_FLOW_PATH = join(__dirname, "..", "guided-flow.ts");
|
|
21
|
+
|
|
22
|
+
function getShowHeadlessBody(): string {
|
|
23
|
+
const source = readFileSync(GUIDED_FLOW_PATH, "utf-8");
|
|
24
|
+
const fnStart = source.indexOf("export async function showHeadlessMilestoneCreation");
|
|
25
|
+
assert.ok(fnStart > -1, "showHeadlessMilestoneCreation must exist in guided-flow.ts");
|
|
26
|
+
const nextExport = source.indexOf("\nexport ", fnStart + 1);
|
|
27
|
+
return source.slice(fnStart, nextExport === -1 ? source.length : nextExport);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function makeBase(prefix = "gsd-deferred-dir-"): string {
|
|
31
|
+
const base = mkdtempSync(join(tmpdir(), prefix));
|
|
32
|
+
mkdirSync(join(base, ".gsd", "milestones"), { recursive: true });
|
|
33
|
+
return base;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
describe("showHeadlessMilestoneCreation source guard (#4996)", () => {
|
|
37
|
+
it("does not call mkdirSync in the headless milestone creation path", () => {
|
|
38
|
+
const body = getShowHeadlessBody();
|
|
39
|
+
assert.doesNotMatch(
|
|
40
|
+
body,
|
|
41
|
+
/\bmkdirSync\s*\(/,
|
|
42
|
+
"showHeadlessMilestoneCreation must not pre-create milestone directories",
|
|
43
|
+
);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("does not call mkdir or mkdirp before dispatchWorkflow", () => {
|
|
47
|
+
const body = getShowHeadlessBody();
|
|
48
|
+
const dispatchIdx = body.indexOf("dispatchWorkflow");
|
|
49
|
+
assert.ok(dispatchIdx > -1, "dispatchWorkflow must be present");
|
|
50
|
+
|
|
51
|
+
const beforeDispatch = body.slice(0, dispatchIdx);
|
|
52
|
+
assert.doesNotMatch(
|
|
53
|
+
beforeDispatch,
|
|
54
|
+
/\b(?:mkdir|mkdirp)\s*\(/,
|
|
55
|
+
"showHeadlessMilestoneCreation must defer directory creation until artifact write",
|
|
56
|
+
);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
describe("deferred milestone dir creation (#4996)", () => {
|
|
61
|
+
let base: string;
|
|
62
|
+
|
|
63
|
+
beforeEach(() => {
|
|
64
|
+
clearReservedMilestoneIds();
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
afterEach(() => {
|
|
68
|
+
try { closeDatabase(); } catch { /* ignore */ }
|
|
69
|
+
try { invalidateAllCaches(); } catch { /* ignore */ }
|
|
70
|
+
try { clearReservedMilestoneIds(); } catch { /* ignore */ }
|
|
71
|
+
try { rmSync(base, { recursive: true, force: true }); } catch { /* ignore */ }
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("(a) fresh project: milestones dir has no M001 entry before any discuss flow", () => {
|
|
75
|
+
base = makeBase();
|
|
76
|
+
const nextId = nextMilestoneIdReserved(findMilestoneIds(base), false, base);
|
|
77
|
+
assert.equal(nextId, "M001", "reservation should choose M001 for a fresh project");
|
|
78
|
+
|
|
79
|
+
const ids = findMilestoneIds(base);
|
|
80
|
+
assert.equal(ids.length, 0, "no milestone dirs should exist before any discuss flow");
|
|
81
|
+
|
|
82
|
+
// And specifically M001 should not exist
|
|
83
|
+
const m001Dir = join(base, ".gsd", "milestones", "M001");
|
|
84
|
+
assert.ok(!existsSync(m001Dir), "M001 dir must not exist before the discuss flow runs");
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("(b) abandoned discuss flow leaves no orphan: isReusableGhostMilestone returns false for non-existent dir", () => {
|
|
88
|
+
base = makeBase();
|
|
89
|
+
const nextId = nextMilestoneIdReserved(findMilestoneIds(base), false, base);
|
|
90
|
+
assert.equal(nextId, "M001", "reservation should not require a pre-created directory");
|
|
91
|
+
|
|
92
|
+
const m001Dir = join(base, ".gsd", "milestones", "M001");
|
|
93
|
+
assert.ok(!existsSync(m001Dir), "no M001 dir should exist");
|
|
94
|
+
assert.equal(isReusableGhostMilestone(base, "M001"), false, "non-existent milestone should not be reusable");
|
|
95
|
+
// findMilestoneIds only returns dirs that exist
|
|
96
|
+
const ids = findMilestoneIds(base);
|
|
97
|
+
assert.ok(!ids.includes("M001"), "M001 should not appear in findMilestoneIds when no dir exists");
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it("(c) a stub dir left from a previous bug IS reusable but a newly-generated ID with no dir is not in the ghost list", () => {
|
|
101
|
+
base = makeBase();
|
|
102
|
+
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
103
|
+
// Create a stub to represent a pre-existing phantom
|
|
104
|
+
mkdirSync(join(base, ".gsd", "milestones", "M001", "slices"), { recursive: true });
|
|
105
|
+
|
|
106
|
+
// isReusableGhostMilestone identifies the orphaned stub
|
|
107
|
+
assert.ok(isReusableGhostMilestone(base, "M001"), "pre-existing stub should be identified as reusable ghost");
|
|
108
|
+
const nextId = nextMilestoneIdReserved(findMilestoneIds(base), false, base);
|
|
109
|
+
assert.equal(nextId, "M001", "reservation should reuse the pre-existing ghost");
|
|
110
|
+
|
|
111
|
+
// The new ID (M002, which would be max+1 in this scenario but ghost reuse returns M001)
|
|
112
|
+
// should not have a dir
|
|
113
|
+
const m002Dir = join(base, ".gsd", "milestones", "M002");
|
|
114
|
+
assert.ok(!existsSync(m002Dir), "a freshly-requested ID should have no dir until first artifact write");
|
|
115
|
+
});
|
|
116
|
+
});
|