gsd-pi 2.43.0-next.8 → 2.44.0-dev.0b97ffd
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 +30 -12
- package/dist/cli.js +13 -1
- package/dist/help-text.js +24 -0
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +21 -8
- package/dist/resources/extensions/gsd/auto-prompts.js +130 -51
- package/dist/resources/extensions/gsd/auto-start.js +10 -0
- package/dist/resources/extensions/gsd/auto-worktree.js +16 -2
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +5 -0
- package/dist/resources/extensions/gsd/dispatch-guard.js +34 -10
- package/dist/resources/extensions/gsd/markdown-renderer.js +7 -5
- package/dist/resources/extensions/gsd/reactive-graph.js +13 -2
- package/dist/resources/extensions/gsd/skill-health.js +3 -1
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +2 -11
- package/dist/resources/extensions/gsd/tools/plan-slice.js +2 -10
- package/dist/resources/extensions/gsd/visualizer-data.js +45 -13
- package/dist/resources/extensions/gsd/workspace-index.js +46 -15
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +18 -18
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/required-server-files.json +4 -4
- 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 +2 -2
- 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/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/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 +5 -5
- 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 +2 -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 +1 -1
- 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 +18 -18
- package/dist/web/standalone/.next/server/chunks/229.js +1 -1
- package/dist/web/standalone/.next/server/chunks/471.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-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 +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/app/_not-found/page-f2a7482d42a5614b.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/page-b9367c5ae13b99c6.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{main-app-2f2ee7b85712c2bd.js → main-app-fdab67f7802d7832.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.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/server.js +1 -1
- package/package.json +4 -4
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +3 -3
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +11 -34
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js +6 -8
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.d.ts +2 -2
- package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +2 -2
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +4 -4
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +18 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +24 -26
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +37 -0
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/fallback-resolver.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/fallback-resolver.js +2 -3
- package/packages/pi-coding-agent/dist/core/fallback-resolver.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/fallback-resolver.test.js +12 -2
- package/packages/pi-coding-agent/dist/core/fallback-resolver.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/fs-utils.test.js +29 -48
- package/packages/pi-coding-agent/dist/core/fs-utils.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.d.ts +38 -0
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.js +192 -0
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +255 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts +15 -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 +40 -3
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/package-commands.d.ts +25 -0
- package/packages/pi-coding-agent/dist/core/package-commands.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/package-commands.js +253 -0
- package/packages/pi-coding-agent/dist/core/package-commands.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/package-commands.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/package-commands.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/package-commands.test.js +225 -0
- package/packages/pi-coding-agent/dist/core/package-commands.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +34 -44
- package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +4 -0
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.test.js +30 -34
- package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +10 -12
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +3 -1
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -0
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/main.js +11 -199
- package/packages/pi-coding-agent/dist/main.js.map +1 -1
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js +43 -47
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +13 -37
- package/packages/pi-coding-agent/src/core/auth-storage.test.ts +7 -7
- package/packages/pi-coding-agent/src/core/compaction/branch-summarization.ts +2 -2
- package/packages/pi-coding-agent/src/core/compaction/compaction.ts +3 -3
- package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +4 -4
- package/packages/pi-coding-agent/src/core/extensions/index.ts +5 -0
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +23 -0
- package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +26 -26
- package/packages/pi-coding-agent/src/core/extensions/types.ts +44 -0
- package/packages/pi-coding-agent/src/core/fallback-resolver.test.ts +15 -2
- package/packages/pi-coding-agent/src/core/fallback-resolver.ts +2 -3
- package/packages/pi-coding-agent/src/core/fs-utils.test.ts +31 -43
- package/packages/pi-coding-agent/src/core/lifecycle-hooks.ts +274 -0
- package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +288 -0
- package/packages/pi-coding-agent/src/core/model-registry.ts +39 -3
- package/packages/pi-coding-agent/src/core/package-commands.test.ts +240 -0
- package/packages/pi-coding-agent/src/core/package-commands.ts +310 -0
- package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +40 -45
- package/packages/pi-coding-agent/src/core/sdk.ts +4 -0
- package/packages/pi-coding-agent/src/core/session-manager.test.ts +33 -33
- package/packages/pi-coding-agent/src/core/tools/edit-diff.test.ts +17 -17
- package/packages/pi-coding-agent/src/index.ts +7 -0
- package/packages/pi-coding-agent/src/main.ts +11 -232
- package/packages/pi-coding-agent/src/resources/extensions/memory/storage.test.ts +74 -74
- package/pkg/package.json +1 -1
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +22 -7
- package/src/resources/extensions/gsd/auto-prompts.ts +109 -42
- package/src/resources/extensions/gsd/auto-start.ts +14 -0
- package/src/resources/extensions/gsd/auto-worktree.ts +16 -3
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +8 -0
- package/src/resources/extensions/gsd/dispatch-guard.ts +28 -10
- package/src/resources/extensions/gsd/markdown-renderer.ts +7 -5
- package/src/resources/extensions/gsd/reactive-graph.ts +12 -2
- package/src/resources/extensions/gsd/skill-health.ts +2 -1
- package/src/resources/extensions/gsd/tests/all-milestones-complete-merge.test.ts +99 -99
- package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +14 -16
- package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +43 -57
- package/src/resources/extensions/gsd/tests/auto-preflight.test.ts +11 -13
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +465 -523
- package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +73 -75
- package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +34 -56
- package/src/resources/extensions/gsd/tests/auto-stash-merge.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +533 -656
- package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +165 -143
- package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +29 -52
- package/src/resources/extensions/gsd/tests/captures.test.ts +148 -176
- package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +32 -33
- package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +141 -143
- package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +25 -25
- package/src/resources/extensions/gsd/tests/commands-logs.test.ts +81 -81
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +38 -59
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +228 -263
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +250 -302
- package/src/resources/extensions/gsd/tests/context-store.test.ts +354 -367
- package/src/resources/extensions/gsd/tests/continue-here.test.ts +68 -72
- package/src/resources/extensions/gsd/tests/cost-projection.test.ts +92 -106
- package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +27 -35
- package/src/resources/extensions/gsd/tests/dashboard-budget.test.ts +220 -237
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +390 -420
- package/src/resources/extensions/gsd/tests/definition-loader.test.ts +76 -92
- package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +68 -83
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +152 -183
- package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +78 -101
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +192 -227
- package/src/resources/extensions/gsd/tests/detection.test.ts +232 -278
- package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +30 -34
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +164 -180
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +43 -49
- package/src/resources/extensions/gsd/tests/dispatch-uat-last-completed.test.ts +28 -32
- package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +27 -29
- package/src/resources/extensions/gsd/tests/doctor-delimiter-fix.test.ts +34 -38
- package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +54 -75
- package/src/resources/extensions/gsd/tests/doctor-environment-worktree.test.ts +21 -32
- package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +72 -97
- package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +38 -44
- package/src/resources/extensions/gsd/tests/doctor-git.test.ts +104 -145
- package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +84 -106
- package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +54 -60
- package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +72 -93
- package/src/resources/extensions/gsd/tests/doctor.test.ts +104 -134
- package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +123 -131
- package/src/resources/extensions/gsd/tests/exit-command.test.ts +20 -24
- package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +48 -57
- package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +5 -7
- package/src/resources/extensions/gsd/tests/flag-file-db.test.ts +30 -42
- package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +198 -206
- package/src/resources/extensions/gsd/tests/git-locale.test.ts +13 -27
- package/src/resources/extensions/gsd/tests/git-service.test.ts +285 -388
- package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +31 -39
- package/src/resources/extensions/gsd/tests/graph-operations.test.ts +63 -69
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +255 -264
- package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +108 -119
- package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +81 -103
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +229 -262
- package/src/resources/extensions/gsd/tests/headless-answers.test.ts +13 -13
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +29 -37
- package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +81 -102
- package/src/resources/extensions/gsd/tests/init-wizard.test.ts +16 -18
- package/src/resources/extensions/gsd/tests/integration-edge.test.ts +41 -46
- package/src/resources/extensions/gsd/tests/integration-lifecycle.test.ts +42 -53
- package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +75 -91
- package/src/resources/extensions/gsd/tests/integration-proof.test.ts +18 -18
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +150 -194
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +101 -125
- package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +45 -54
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +80 -93
- package/src/resources/extensions/gsd/tests/migrate-command.test.ts +57 -66
- package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +83 -93
- package/src/resources/extensions/gsd/tests/migrate-parser.test.ts +161 -170
- package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +125 -141
- package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +107 -131
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +87 -96
- package/src/resources/extensions/gsd/tests/migrate-writer.test.ts +125 -164
- package/src/resources/extensions/gsd/tests/must-have-parser.test.ts +81 -94
- package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +35 -36
- package/src/resources/extensions/gsd/tests/overrides.test.ts +99 -106
- package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +40 -47
- package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +25 -28
- package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +66 -83
- package/src/resources/extensions/gsd/tests/park-edge-cases.test.ts +54 -77
- package/src/resources/extensions/gsd/tests/park-milestone.test.ts +68 -115
- package/src/resources/extensions/gsd/tests/parsers.test.ts +546 -611
- package/src/resources/extensions/gsd/tests/paths.test.ts +72 -87
- package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +77 -117
- package/src/resources/extensions/gsd/tests/prompt-db.test.ts +56 -56
- package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +93 -119
- package/src/resources/extensions/gsd/tests/queue-order.test.ts +70 -82
- package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +42 -55
- package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +100 -0
- package/src/resources/extensions/gsd/tests/quick-branch-lifecycle.test.ts +45 -73
- package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +28 -38
- package/src/resources/extensions/gsd/tests/replan-slice.test.ts +73 -80
- package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +71 -74
- package/src/resources/extensions/gsd/tests/requirements.test.ts +70 -75
- package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +44 -66
- package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +114 -181
- package/src/resources/extensions/gsd/tests/rule-registry.test.ts +63 -65
- package/src/resources/extensions/gsd/tests/run-uat.test.ts +66 -128
- package/src/resources/extensions/gsd/tests/session-lock-multipath.test.ts +18 -25
- package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +37 -44
- package/src/resources/extensions/gsd/tests/shared-wal.test.ts +19 -26
- package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +63 -0
- package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +6 -8
- package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +22 -28
- package/src/resources/extensions/gsd/tests/token-savings.test.ts +54 -56
- package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +23 -25
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +9 -11
- package/src/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +66 -82
- package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +46 -47
- package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -22
- package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -86
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +41 -43
- package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +94 -96
- package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +11 -13
- package/src/resources/extensions/gsd/tests/worker-registry.test.ts +27 -29
- package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +50 -52
- package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +10 -13
- package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +14 -18
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +38 -39
- package/src/resources/extensions/gsd/tests/worktree-e2e.test.ts +17 -21
- package/src/resources/extensions/gsd/tests/worktree-health.test.ts +25 -30
- package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +30 -37
- package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +15 -22
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +59 -66
- package/src/resources/extensions/gsd/tests/worktree.test.ts +44 -50
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +1 -18
- package/src/resources/extensions/gsd/tools/plan-slice.ts +1 -15
- package/src/resources/extensions/gsd/visualizer-data.ts +46 -14
- package/src/resources/extensions/gsd/workspace-index.ts +49 -18
- package/dist/web/standalone/.next/static/chunks/app/_not-found/page-e07acdb7dd069836.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/layout-745c6ed5fea5fb06.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/page-801b53eff6e83579.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-e6255954dccfcf0a.js +0 -1
- /package/dist/web/standalone/.next/static/{drUWS0zys9uepCfCwecJv → alS4hoANx0TK4UVZY27da}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{drUWS0zys9uepCfCwecJv → alS4hoANx0TK4UVZY27da}/_ssgManifest.js +0 -0
|
@@ -19,9 +19,8 @@ import {
|
|
|
19
19
|
formatDecisionsForPrompt,
|
|
20
20
|
formatRequirementsForPrompt,
|
|
21
21
|
} from '../context-store.ts';
|
|
22
|
-
import {
|
|
23
|
-
|
|
24
|
-
const { assertEq, assertTrue, report } = createTestContext();
|
|
22
|
+
import { describe, test, beforeEach, afterEach } from 'node:test';
|
|
23
|
+
import assert from 'node:assert/strict';
|
|
25
24
|
|
|
26
25
|
// ─── Fixture Helper ────────────────────────────────────────────────────────
|
|
27
26
|
|
|
@@ -48,8 +47,7 @@ function generateDecisionsMarkdown(count: number): string {
|
|
|
48
47
|
// Edge Case 1: Empty Project
|
|
49
48
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
50
49
|
|
|
51
|
-
|
|
52
|
-
{
|
|
50
|
+
test('integration-edge: empty project', () => {
|
|
53
51
|
const base = mkdtempSync(join(tmpdir(), 'gsd-int-edge-empty-'));
|
|
54
52
|
const gsdDir = join(base, '.gsd');
|
|
55
53
|
mkdirSync(gsdDir, { recursive: true });
|
|
@@ -59,55 +57,54 @@ console.log('\n=== integration-edge: empty project ===');
|
|
|
59
57
|
try {
|
|
60
58
|
// Open DB first so migrateFromMarkdown doesn't auto-create at default path
|
|
61
59
|
openDatabase(dbPath);
|
|
62
|
-
|
|
60
|
+
assert.ok(isDbAvailable(), 'empty: DB available after open');
|
|
63
61
|
|
|
64
62
|
// Migrate with no markdown files on disk
|
|
65
63
|
const result = migrateFromMarkdown(base);
|
|
66
64
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
65
|
+
assert.deepStrictEqual(result.decisions, 0, 'empty: 0 decisions imported');
|
|
66
|
+
assert.deepStrictEqual(result.requirements, 0, 'empty: 0 requirements imported');
|
|
67
|
+
assert.deepStrictEqual(result.artifacts, 0, 'empty: 0 artifacts imported');
|
|
70
68
|
|
|
71
69
|
// Query decisions → empty array
|
|
72
70
|
const decisions = queryDecisions();
|
|
73
|
-
|
|
71
|
+
assert.deepStrictEqual(decisions.length, 0, 'empty: queryDecisions returns empty array');
|
|
74
72
|
|
|
75
73
|
// Query requirements → empty array
|
|
76
74
|
const requirements = queryRequirements();
|
|
77
|
-
|
|
75
|
+
assert.deepStrictEqual(requirements.length, 0, 'empty: queryRequirements returns empty array');
|
|
78
76
|
|
|
79
77
|
// Query with scope filters → still empty, no crash
|
|
80
78
|
const scopedDecisions = queryDecisions({ milestoneId: 'M001' });
|
|
81
|
-
|
|
79
|
+
assert.deepStrictEqual(scopedDecisions.length, 0, 'empty: scoped queryDecisions returns empty');
|
|
82
80
|
|
|
83
81
|
const scopedRequirements = queryRequirements({ sliceId: 'S01' });
|
|
84
|
-
|
|
82
|
+
assert.deepStrictEqual(scopedRequirements.length, 0, 'empty: scoped queryRequirements returns empty');
|
|
85
83
|
|
|
86
84
|
// Format empty results → empty strings
|
|
87
85
|
const formattedD = formatDecisionsForPrompt([]);
|
|
88
86
|
const formattedR = formatRequirementsForPrompt([]);
|
|
89
|
-
|
|
90
|
-
|
|
87
|
+
assert.deepStrictEqual(formattedD, '', 'empty: formatDecisionsForPrompt returns empty string');
|
|
88
|
+
assert.deepStrictEqual(formattedR, '', 'empty: formatRequirementsForPrompt returns empty string');
|
|
91
89
|
|
|
92
90
|
// Format with actual empty query results
|
|
93
91
|
const formattedD2 = formatDecisionsForPrompt(decisions);
|
|
94
92
|
const formattedR2 = formatRequirementsForPrompt(requirements);
|
|
95
|
-
|
|
96
|
-
|
|
93
|
+
assert.deepStrictEqual(formattedD2, '', 'empty: format of empty query decisions is empty string');
|
|
94
|
+
assert.deepStrictEqual(formattedR2, '', 'empty: format of empty query requirements is empty string');
|
|
97
95
|
|
|
98
96
|
closeDatabase();
|
|
99
97
|
} finally {
|
|
100
98
|
closeDatabase();
|
|
101
99
|
rmSync(base, { recursive: true, force: true });
|
|
102
100
|
}
|
|
103
|
-
}
|
|
101
|
+
});
|
|
104
102
|
|
|
105
103
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
106
104
|
// Edge Case 2: Partial Migration (decisions only, no requirements)
|
|
107
105
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
108
106
|
|
|
109
|
-
|
|
110
|
-
{
|
|
107
|
+
test('integration-edge: partial migration', () => {
|
|
111
108
|
const base = mkdtempSync(join(tmpdir(), 'gsd-int-edge-partial-'));
|
|
112
109
|
const gsdDir = join(base, '.gsd');
|
|
113
110
|
mkdirSync(gsdDir, { recursive: true });
|
|
@@ -120,49 +117,48 @@ console.log('\n=== integration-edge: partial migration ===');
|
|
|
120
117
|
|
|
121
118
|
try {
|
|
122
119
|
openDatabase(dbPath);
|
|
123
|
-
|
|
120
|
+
assert.ok(isDbAvailable(), 'partial: DB available after open');
|
|
124
121
|
|
|
125
122
|
const result = migrateFromMarkdown(base);
|
|
126
123
|
|
|
127
124
|
// Decisions imported, requirements skipped gracefully
|
|
128
|
-
|
|
129
|
-
|
|
125
|
+
assert.ok(result.decisions === 6, `partial: imported ${result.decisions} decisions, expected 6`);
|
|
126
|
+
assert.deepStrictEqual(result.requirements, 0, 'partial: 0 requirements imported (no file)');
|
|
130
127
|
|
|
131
128
|
// Decisions queryable
|
|
132
129
|
const decisions = queryDecisions();
|
|
133
|
-
|
|
130
|
+
assert.ok(decisions.length === 6, `partial: queryDecisions returns 6 (got ${decisions.length})`);
|
|
134
131
|
|
|
135
132
|
const m001Decisions = queryDecisions({ milestoneId: 'M001' });
|
|
136
|
-
|
|
137
|
-
|
|
133
|
+
assert.ok(m001Decisions.length > 0, 'partial: M001 decisions non-empty');
|
|
134
|
+
assert.ok(m001Decisions.length < decisions.length, 'partial: M001 scope filters correctly');
|
|
138
135
|
|
|
139
136
|
// Requirements return empty — no crash
|
|
140
137
|
const requirements = queryRequirements();
|
|
141
|
-
|
|
138
|
+
assert.deepStrictEqual(requirements.length, 0, 'partial: queryRequirements returns empty');
|
|
142
139
|
|
|
143
140
|
const scopedReqs = queryRequirements({ sliceId: 'S01' });
|
|
144
|
-
|
|
141
|
+
assert.deepStrictEqual(scopedReqs.length, 0, 'partial: scoped queryRequirements returns empty');
|
|
145
142
|
|
|
146
143
|
// Format works on partial data
|
|
147
144
|
const formattedD = formatDecisionsForPrompt(m001Decisions);
|
|
148
|
-
|
|
145
|
+
assert.ok(formattedD.length > 0, 'partial: formatted decisions non-empty');
|
|
149
146
|
|
|
150
147
|
const formattedR = formatRequirementsForPrompt(requirements);
|
|
151
|
-
|
|
148
|
+
assert.deepStrictEqual(formattedR, '', 'partial: formatted empty requirements is empty string');
|
|
152
149
|
|
|
153
150
|
closeDatabase();
|
|
154
151
|
} finally {
|
|
155
152
|
closeDatabase();
|
|
156
153
|
rmSync(base, { recursive: true, force: true });
|
|
157
154
|
}
|
|
158
|
-
}
|
|
155
|
+
});
|
|
159
156
|
|
|
160
157
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
161
158
|
// Edge Case 3: Fallback Mode (_resetProvider)
|
|
162
159
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
163
160
|
|
|
164
|
-
|
|
165
|
-
{
|
|
161
|
+
test('integration-edge: fallback mode', () => {
|
|
166
162
|
const base = mkdtempSync(join(tmpdir(), 'gsd-int-edge-fallback-'));
|
|
167
163
|
const gsdDir = join(base, '.gsd');
|
|
168
164
|
mkdirSync(gsdDir, { recursive: true });
|
|
@@ -175,54 +171,53 @@ console.log('\n=== integration-edge: fallback mode ===');
|
|
|
175
171
|
try {
|
|
176
172
|
// Step 1: Open DB normally and verify it works
|
|
177
173
|
openDatabase(dbPath);
|
|
178
|
-
|
|
174
|
+
assert.ok(isDbAvailable(), 'fallback: DB available after open');
|
|
179
175
|
|
|
180
176
|
migrateFromMarkdown(base);
|
|
181
177
|
const before = queryDecisions();
|
|
182
|
-
|
|
178
|
+
assert.ok(before.length === 4, `fallback: 4 decisions before reset (got ${before.length})`);
|
|
183
179
|
|
|
184
180
|
// Step 2: Close and reset provider → DB unavailable
|
|
185
181
|
closeDatabase();
|
|
186
182
|
_resetProvider();
|
|
187
|
-
|
|
183
|
+
assert.ok(!isDbAvailable(), 'fallback: DB unavailable after _resetProvider');
|
|
188
184
|
|
|
189
185
|
// Step 3: Queries degrade gracefully (return empty, don't throw)
|
|
190
186
|
const degradedDecisions = queryDecisions();
|
|
191
|
-
|
|
187
|
+
assert.deepStrictEqual(degradedDecisions.length, 0, 'fallback: queryDecisions returns empty when unavailable');
|
|
192
188
|
|
|
193
189
|
const degradedRequirements = queryRequirements();
|
|
194
|
-
|
|
190
|
+
assert.deepStrictEqual(degradedRequirements.length, 0, 'fallback: queryRequirements returns empty when unavailable');
|
|
195
191
|
|
|
196
192
|
const degradedScopedD = queryDecisions({ milestoneId: 'M001' });
|
|
197
|
-
|
|
193
|
+
assert.deepStrictEqual(degradedScopedD.length, 0, 'fallback: scoped queryDecisions returns empty when unavailable');
|
|
198
194
|
|
|
199
195
|
const degradedScopedR = queryRequirements({ sliceId: 'S01' });
|
|
200
|
-
|
|
196
|
+
assert.deepStrictEqual(degradedScopedR.length, 0, 'fallback: scoped queryRequirements returns empty when unavailable');
|
|
201
197
|
|
|
202
198
|
// Format functions work on empty arrays (no crash)
|
|
203
199
|
const formattedD = formatDecisionsForPrompt(degradedDecisions);
|
|
204
|
-
|
|
200
|
+
assert.deepStrictEqual(formattedD, '', 'fallback: format degraded decisions is empty');
|
|
205
201
|
|
|
206
202
|
const formattedR = formatRequirementsForPrompt(degradedRequirements);
|
|
207
|
-
|
|
203
|
+
assert.deepStrictEqual(formattedR, '', 'fallback: format degraded requirements is empty');
|
|
208
204
|
|
|
209
205
|
// Step 4: Re-open DB → restores availability
|
|
210
206
|
openDatabase(dbPath);
|
|
211
|
-
|
|
207
|
+
assert.ok(isDbAvailable(), 'fallback: DB available after re-open');
|
|
212
208
|
|
|
213
209
|
// Data should be there from the file-backed DB (persisted by first open)
|
|
214
210
|
// But rows may need re-import since the DB was freshly opened from the file
|
|
215
211
|
migrateFromMarkdown(base);
|
|
216
212
|
const restored = queryDecisions();
|
|
217
|
-
|
|
213
|
+
assert.ok(restored.length === 4, `fallback: 4 decisions after re-open (got ${restored.length})`);
|
|
218
214
|
|
|
219
215
|
closeDatabase();
|
|
220
216
|
} finally {
|
|
221
217
|
closeDatabase();
|
|
222
218
|
rmSync(base, { recursive: true, force: true });
|
|
223
219
|
}
|
|
224
|
-
}
|
|
220
|
+
});
|
|
225
221
|
|
|
226
222
|
// ─── Report ────────────────────────────────────────────────────────────────
|
|
227
223
|
|
|
228
|
-
report();
|
|
@@ -21,9 +21,8 @@ import {
|
|
|
21
21
|
formatRequirementsForPrompt,
|
|
22
22
|
} from '../context-store.ts';
|
|
23
23
|
import { saveDecisionToDb, generateDecisionsMd } from '../db-writer.ts';
|
|
24
|
-
import {
|
|
25
|
-
|
|
26
|
-
const { assertEq, assertTrue, assertMatch, report } = createTestContext();
|
|
24
|
+
import { describe, test, beforeEach, afterEach } from 'node:test';
|
|
25
|
+
import assert from 'node:assert/strict';
|
|
27
26
|
|
|
28
27
|
// ─── Fixture Generators (duplicated from token-savings.test.ts — file-scoped) ──
|
|
29
28
|
|
|
@@ -119,10 +118,7 @@ const ROADMAP_CONTENT = `# M001: Test Milestone\n\n**Vision:** Integration test
|
|
|
119
118
|
// Full Lifecycle Integration Test
|
|
120
119
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
121
120
|
|
|
122
|
-
async
|
|
123
|
-
|
|
124
|
-
console.log('\n=== integration-lifecycle: full pipeline ===');
|
|
125
|
-
{
|
|
121
|
+
test('integration-lifecycle: full pipeline', async () => {
|
|
126
122
|
// ── Step 1: Set up temp dir with realistic .gsd/ structure ──────────
|
|
127
123
|
const base = mkdtempSync(join(tmpdir(), 'gsd-int-lifecycle-'));
|
|
128
124
|
const gsdDir = join(base, '.gsd');
|
|
@@ -142,37 +138,37 @@ async function main(): Promise<void> {
|
|
|
142
138
|
try {
|
|
143
139
|
// ── Step 2: Open file-backed DB + migrateFromMarkdown ──────────────
|
|
144
140
|
openDatabase(dbPath);
|
|
145
|
-
|
|
141
|
+
assert.ok(isDbAvailable(), 'lifecycle: DB is available after open');
|
|
146
142
|
|
|
147
143
|
const result = migrateFromMarkdown(base);
|
|
148
144
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
145
|
+
assert.ok(result.decisions === DECISIONS_COUNT, `lifecycle: imported ${result.decisions} decisions, expected ${DECISIONS_COUNT}`);
|
|
146
|
+
assert.ok(result.requirements === REQUIREMENTS_COUNT, `lifecycle: imported ${result.requirements} requirements, expected ${REQUIREMENTS_COUNT}`);
|
|
147
|
+
assert.ok(result.artifacts >= 1, `lifecycle: imported at least 1 artifact (got ${result.artifacts})`);
|
|
152
148
|
|
|
153
149
|
// Verify file-backed DB uses WAL
|
|
154
150
|
const adapter = _getAdapter()!;
|
|
155
151
|
const mode = adapter.prepare('PRAGMA journal_mode').get();
|
|
156
|
-
|
|
152
|
+
assert.deepStrictEqual(mode?.['journal_mode'], 'wal', 'lifecycle: file-backed DB uses WAL mode');
|
|
157
153
|
|
|
158
154
|
// ── Step 3: Scoped queries — decisions by milestone ────────────────
|
|
159
155
|
const allDecisions = queryDecisions();
|
|
160
156
|
const m001Decisions = queryDecisions({ milestoneId: 'M001' });
|
|
161
157
|
const m002Decisions = queryDecisions({ milestoneId: 'M002' });
|
|
162
158
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
159
|
+
assert.ok(allDecisions.length === DECISIONS_COUNT, `lifecycle: all decisions count = ${DECISIONS_COUNT} (got ${allDecisions.length})`);
|
|
160
|
+
assert.ok(m001Decisions.length > 0, 'lifecycle: M001 decisions non-empty');
|
|
161
|
+
assert.ok(m002Decisions.length > 0, 'lifecycle: M002 decisions non-empty');
|
|
162
|
+
assert.ok(m001Decisions.length < allDecisions.length, 'lifecycle: M001 filtered count < total count');
|
|
163
|
+
assert.ok(m002Decisions.length < allDecisions.length, 'lifecycle: M002 filtered count < total count');
|
|
164
|
+
assert.deepStrictEqual(m001Decisions.length + m002Decisions.length, allDecisions.length, 'lifecycle: M001 + M002 = total decisions');
|
|
169
165
|
|
|
170
166
|
// Verify scoping correctness
|
|
171
167
|
for (const d of m001Decisions) {
|
|
172
|
-
|
|
168
|
+
assert.ok(d.when_context.includes('M001'), `lifecycle: M001 decision ${d.id} has M001 in when_context`);
|
|
173
169
|
}
|
|
174
170
|
for (const d of m002Decisions) {
|
|
175
|
-
|
|
171
|
+
assert.ok(d.when_context.includes('M002'), `lifecycle: M002 decision ${d.id} has M002 in when_context`);
|
|
176
172
|
}
|
|
177
173
|
|
|
178
174
|
// ── Step 4: Scoped queries — requirements by slice ─────────────────
|
|
@@ -180,19 +176,19 @@ async function main(): Promise<void> {
|
|
|
180
176
|
const s01Requirements = queryRequirements({ sliceId: 'S01' });
|
|
181
177
|
const s04Requirements = queryRequirements({ sliceId: 'S04' });
|
|
182
178
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
179
|
+
assert.ok(allRequirements.length === REQUIREMENTS_COUNT, `lifecycle: all requirements count = ${REQUIREMENTS_COUNT} (got ${allRequirements.length})`);
|
|
180
|
+
assert.ok(s01Requirements.length > 0, 'lifecycle: S01 requirements non-empty');
|
|
181
|
+
assert.ok(s04Requirements.length > 0, 'lifecycle: S04 requirements non-empty');
|
|
182
|
+
assert.ok(s01Requirements.length < allRequirements.length, 'lifecycle: S01 filtered count < total count');
|
|
187
183
|
|
|
188
184
|
// ── Step 5: Format + token savings validation ──────────────────────
|
|
189
185
|
const formattedDecisions = formatDecisionsForPrompt(m001Decisions);
|
|
190
186
|
const formattedRequirements = formatRequirementsForPrompt(s01Requirements);
|
|
191
187
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
188
|
+
assert.ok(formattedDecisions.length > 0, 'lifecycle: formatted M001 decisions non-empty');
|
|
189
|
+
assert.ok(formattedRequirements.length > 0, 'lifecycle: formatted S01 requirements non-empty');
|
|
190
|
+
assert.match(formattedDecisions, /\| D/, 'lifecycle: formatted decisions contains decision rows');
|
|
191
|
+
assert.match(formattedRequirements, /### R\d+/, 'lifecycle: formatted requirements has headings');
|
|
196
192
|
|
|
197
193
|
// Token savings: scoped output vs full file content
|
|
198
194
|
const fullDecisionsContent = readFileSync(join(gsdDir, 'DECISIONS.md'), 'utf-8');
|
|
@@ -203,24 +199,24 @@ async function main(): Promise<void> {
|
|
|
203
199
|
|
|
204
200
|
console.log(` Token savings: ${savingsPercent.toFixed(1)}% (scoped: ${dbScopedTotal}, full: ${fullTotal})`);
|
|
205
201
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
202
|
+
assert.ok(dbScopedTotal > 0, 'lifecycle: scoped content non-empty');
|
|
203
|
+
assert.ok(dbScopedTotal < fullTotal, 'lifecycle: scoped content smaller than full content');
|
|
204
|
+
assert.ok(savingsPercent >= 30, `lifecycle: savings ≥30% (actual: ${savingsPercent.toFixed(1)}%)`);
|
|
209
205
|
|
|
210
206
|
// ── Step 6: Simulate content change → re-import ────────────────────
|
|
211
207
|
const newDecisionRow = `| D${DECISIONS_COUNT + 1} | M001/S01 | testing | new decision added after initial import | choice X | rationale Y | yes |`;
|
|
212
208
|
appendFileSync(join(gsdDir, 'DECISIONS.md'), '\n' + newDecisionRow + '\n');
|
|
213
209
|
|
|
214
210
|
const result2 = migrateFromMarkdown(base);
|
|
215
|
-
|
|
211
|
+
assert.ok(result2.decisions === DECISIONS_COUNT + 1, `lifecycle: re-import got ${result2.decisions} decisions, expected ${DECISIONS_COUNT + 1}`);
|
|
216
212
|
|
|
217
213
|
const afterReimport = queryDecisions();
|
|
218
|
-
|
|
214
|
+
assert.ok(afterReimport.length === DECISIONS_COUNT + 1, `lifecycle: DB has ${DECISIONS_COUNT + 1} decisions after re-import (got ${afterReimport.length})`);
|
|
219
215
|
|
|
220
216
|
// Verify the new decision is queryable
|
|
221
217
|
const newM001 = queryDecisions({ milestoneId: 'M001' });
|
|
222
218
|
const foundNew = newM001.some(d => d.id === `D${DECISIONS_COUNT + 1}`);
|
|
223
|
-
|
|
219
|
+
assert.ok(foundNew, `lifecycle: newly imported D${DECISIONS_COUNT + 1} found in M001 scope`);
|
|
224
220
|
|
|
225
221
|
// ── Step 7: saveDecisionToDb write-back + round-trip ───────────────
|
|
226
222
|
const saved = await saveDecisionToDb(
|
|
@@ -234,44 +230,37 @@ async function main(): Promise<void> {
|
|
|
234
230
|
base,
|
|
235
231
|
);
|
|
236
232
|
|
|
237
|
-
|
|
238
|
-
|
|
233
|
+
assert.ok(typeof saved.id === 'string', 'lifecycle: saveDecisionToDb returned an id');
|
|
234
|
+
assert.match(saved.id, /^D\d+$/, 'lifecycle: saved ID matches D### pattern');
|
|
239
235
|
|
|
240
236
|
// Query back from DB
|
|
241
237
|
const allAfterSave = queryDecisions();
|
|
242
238
|
const savedDecision = allAfterSave.find(d => d.id === saved.id);
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
239
|
+
assert.ok(savedDecision !== null && savedDecision !== undefined, `lifecycle: saved decision ${saved.id} found in DB`);
|
|
240
|
+
assert.deepStrictEqual(savedDecision?.decision, 'integration test write-back decision', 'lifecycle: saved decision text matches');
|
|
241
|
+
assert.deepStrictEqual(savedDecision?.choice, 'option Z', 'lifecycle: saved choice matches');
|
|
246
242
|
|
|
247
243
|
// Verify DECISIONS.md was regenerated with the new decision
|
|
248
244
|
const regeneratedMd = readFileSync(join(gsdDir, 'DECISIONS.md'), 'utf-8');
|
|
249
|
-
|
|
250
|
-
|
|
245
|
+
assert.ok(regeneratedMd.includes(saved.id), `lifecycle: regenerated DECISIONS.md contains ${saved.id}`);
|
|
246
|
+
assert.ok(regeneratedMd.includes('integration test write-back decision'), 'lifecycle: regenerated md contains write-back text');
|
|
251
247
|
|
|
252
248
|
// Round-trip: parse regenerated markdown back → verify field fidelity
|
|
253
249
|
const reparsed = parseDecisionsTable(regeneratedMd);
|
|
254
250
|
const reparsedSaved = reparsed.find(d => d.id === saved.id);
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
251
|
+
assert.ok(reparsedSaved !== undefined, `lifecycle: reparsed markdown contains ${saved.id}`);
|
|
252
|
+
assert.deepStrictEqual(reparsedSaved?.choice, 'option Z', 'lifecycle: round-trip choice preserved');
|
|
253
|
+
assert.deepStrictEqual(reparsedSaved?.rationale, 'proves round-trip fidelity', 'lifecycle: round-trip rationale preserved');
|
|
258
254
|
|
|
259
255
|
// ── Step 8: DB consistency — total count sanity ─────────────────────
|
|
260
256
|
const finalCount = queryDecisions().length;
|
|
261
257
|
// Original 14 + 1 re-import + 1 saveDecisionToDb = 16
|
|
262
|
-
|
|
258
|
+
assert.ok(finalCount === DECISIONS_COUNT + 2, `lifecycle: final DB count = ${DECISIONS_COUNT + 2} (got ${finalCount})`);
|
|
263
259
|
|
|
264
260
|
closeDatabase();
|
|
265
261
|
} finally {
|
|
266
262
|
closeDatabase();
|
|
267
263
|
rmSync(base, { recursive: true, force: true });
|
|
268
264
|
}
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
report();
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
main().catch((error) => {
|
|
275
|
-
console.error(error);
|
|
276
|
-
process.exit(1);
|
|
277
265
|
});
|
|
266
|
+
|