gsd-pi 2.44.0-dev.848dd4c → 2.44.0
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 +12 -30
- package/dist/resources/extensions/gsd/auto-start.js +0 -10
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +0 -5
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +14 -14
- 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 +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 +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 +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 +14 -14
- 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 → page-2f24283c162b6ab3.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-a16c7a7ecdf0c2cf.js → layout-9ecfd95f343793f0.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-7e9530a7122506c5.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.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 +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js +8 -6
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +26 -24
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/fs-utils.test.js +48 -29
- package/packages/pi-coding-agent/dist/core/fs-utils.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +44 -34
- package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.test.js +34 -30
- 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 +12 -10
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js +47 -43
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js.map +1 -1
- package/packages/pi-coding-agent/src/core/auth-storage.test.ts +7 -7
- package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +26 -26
- package/packages/pi-coding-agent/src/core/fs-utils.test.ts +43 -31
- package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +45 -40
- 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/resources/extensions/memory/storage.test.ts +74 -74
- package/src/resources/extensions/gsd/auto-start.ts +0 -14
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +0 -8
- 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 +16 -14
- package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +57 -43
- package/src/resources/extensions/gsd/tests/auto-preflight.test.ts +13 -11
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +523 -465
- package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +75 -73
- package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +56 -34
- package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +656 -533
- package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +143 -165
- package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +52 -29
- package/src/resources/extensions/gsd/tests/captures.test.ts +176 -148
- package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +33 -32
- package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +143 -141
- 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 +59 -38
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +263 -228
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +302 -250
- package/src/resources/extensions/gsd/tests/context-store.test.ts +367 -354
- package/src/resources/extensions/gsd/tests/continue-here.test.ts +72 -68
- package/src/resources/extensions/gsd/tests/cost-projection.test.ts +106 -92
- package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +35 -27
- package/src/resources/extensions/gsd/tests/dashboard-budget.test.ts +237 -220
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +420 -390
- package/src/resources/extensions/gsd/tests/definition-loader.test.ts +92 -76
- package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +83 -68
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +183 -152
- package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +101 -78
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +227 -192
- package/src/resources/extensions/gsd/tests/detection.test.ts +278 -232
- package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +34 -30
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +180 -164
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +49 -43
- package/src/resources/extensions/gsd/tests/dispatch-uat-last-completed.test.ts +32 -28
- package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +29 -27
- package/src/resources/extensions/gsd/tests/doctor-delimiter-fix.test.ts +38 -34
- package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +75 -54
- package/src/resources/extensions/gsd/tests/doctor-environment-worktree.test.ts +32 -21
- package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +97 -72
- package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +44 -38
- package/src/resources/extensions/gsd/tests/doctor-git.test.ts +145 -104
- package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +106 -84
- package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +60 -54
- package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +93 -72
- package/src/resources/extensions/gsd/tests/doctor.test.ts +134 -104
- package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +131 -123
- package/src/resources/extensions/gsd/tests/exit-command.test.ts +24 -20
- package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +57 -48
- package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +7 -5
- package/src/resources/extensions/gsd/tests/flag-file-db.test.ts +42 -30
- package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +206 -198
- package/src/resources/extensions/gsd/tests/git-locale.test.ts +27 -13
- package/src/resources/extensions/gsd/tests/git-service.test.ts +388 -285
- package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +39 -31
- package/src/resources/extensions/gsd/tests/graph-operations.test.ts +69 -63
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +264 -255
- package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +119 -108
- package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +103 -81
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +262 -229
- package/src/resources/extensions/gsd/tests/headless-answers.test.ts +13 -13
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +37 -29
- package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +102 -81
- package/src/resources/extensions/gsd/tests/init-wizard.test.ts +18 -16
- package/src/resources/extensions/gsd/tests/integration-edge.test.ts +46 -41
- package/src/resources/extensions/gsd/tests/integration-lifecycle.test.ts +53 -42
- package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +91 -75
- package/src/resources/extensions/gsd/tests/integration-proof.test.ts +18 -18
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +194 -150
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +125 -101
- package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +54 -45
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +93 -80
- package/src/resources/extensions/gsd/tests/migrate-command.test.ts +66 -57
- package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +93 -83
- package/src/resources/extensions/gsd/tests/migrate-parser.test.ts +170 -161
- package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +141 -125
- package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +131 -107
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +96 -87
- package/src/resources/extensions/gsd/tests/migrate-writer.test.ts +164 -125
- package/src/resources/extensions/gsd/tests/must-have-parser.test.ts +94 -81
- package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +36 -35
- package/src/resources/extensions/gsd/tests/overrides.test.ts +106 -99
- package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +47 -40
- package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +28 -25
- package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +83 -66
- package/src/resources/extensions/gsd/tests/park-edge-cases.test.ts +77 -54
- package/src/resources/extensions/gsd/tests/park-milestone.test.ts +115 -68
- package/src/resources/extensions/gsd/tests/parsers.test.ts +611 -546
- package/src/resources/extensions/gsd/tests/paths.test.ts +87 -72
- package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +117 -77
- package/src/resources/extensions/gsd/tests/prompt-db.test.ts +56 -56
- package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +119 -93
- package/src/resources/extensions/gsd/tests/queue-order.test.ts +82 -70
- package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +55 -42
- package/src/resources/extensions/gsd/tests/quick-branch-lifecycle.test.ts +73 -45
- package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +38 -28
- package/src/resources/extensions/gsd/tests/replan-slice.test.ts +80 -73
- package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +74 -71
- package/src/resources/extensions/gsd/tests/requirements.test.ts +75 -70
- package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +66 -44
- package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +181 -114
- package/src/resources/extensions/gsd/tests/rule-registry.test.ts +65 -63
- package/src/resources/extensions/gsd/tests/run-uat.test.ts +128 -66
- package/src/resources/extensions/gsd/tests/session-lock-multipath.test.ts +25 -18
- package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +44 -37
- package/src/resources/extensions/gsd/tests/shared-wal.test.ts +26 -19
- package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +8 -6
- package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +28 -22
- package/src/resources/extensions/gsd/tests/token-savings.test.ts +56 -54
- package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +25 -23
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +11 -9
- package/src/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +82 -66
- package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +47 -46
- package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +22 -20
- package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +86 -84
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +43 -41
- package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +96 -94
- package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +13 -11
- package/src/resources/extensions/gsd/tests/worker-registry.test.ts +29 -27
- package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +52 -50
- package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +13 -10
- package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +18 -14
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +39 -38
- package/src/resources/extensions/gsd/tests/worktree-e2e.test.ts +21 -17
- package/src/resources/extensions/gsd/tests/worktree-health.test.ts +30 -25
- package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +37 -30
- package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +22 -15
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +66 -59
- package/src/resources/extensions/gsd/tests/worktree.test.ts +50 -44
- package/dist/web/standalone/.next/static/chunks/app/page-b9367c5ae13b99c6.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +0 -1
- package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +0 -100
- package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +0 -63
- /package/dist/web/standalone/.next/static/{-zps1Q9mQmioAKLcQiCr8 → mgkxN0mGP6gSUmGPEzbk_}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{-zps1Q9mQmioAKLcQiCr8 → mgkxN0mGP6gSUmGPEzbk_}/_ssgManifest.js +0 -0
|
@@ -5,8 +5,7 @@
|
|
|
5
5
|
// (b) Helpers fall back to non-null output when DB unavailable
|
|
6
6
|
// (c) Scoped filtering actually reduces content
|
|
7
7
|
|
|
8
|
-
import {
|
|
9
|
-
import assert from 'node:assert/strict';
|
|
8
|
+
import { createTestContext } from './test-helpers.ts';
|
|
10
9
|
import {
|
|
11
10
|
openDatabase,
|
|
12
11
|
closeDatabase,
|
|
@@ -23,6 +22,8 @@ import {
|
|
|
23
22
|
formatRequirementsForPrompt,
|
|
24
23
|
} from '../context-store.ts';
|
|
25
24
|
|
|
25
|
+
const { assertEq, assertTrue, assertMatch, assertNoMatch, report } = createTestContext();
|
|
26
|
+
|
|
26
27
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
27
28
|
// prompt-db: DB-aware decisions helper returns scoped content
|
|
28
29
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -49,23 +50,23 @@ console.log('\n=== prompt-db: scoped decisions from DB ===');
|
|
|
49
50
|
|
|
50
51
|
// Query scoped to M001
|
|
51
52
|
const m001Decisions = queryDecisions({ milestoneId: 'M001' });
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
assertTrue(m001Decisions.length > 0, 'M001 decisions should exist');
|
|
54
|
+
assertTrue(m001Decisions.length < 10, `scoped query should return fewer than 10 (got ${m001Decisions.length})`);
|
|
54
55
|
|
|
55
56
|
// Verify all returned decisions are for M001
|
|
56
57
|
for (const d of m001Decisions) {
|
|
57
|
-
|
|
58
|
+
assertMatch(d.when_context, /M001/, `decision ${d.id} should be for M001`);
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
// Format and verify wrapping
|
|
61
62
|
const formatted = formatDecisionsForPrompt(m001Decisions);
|
|
62
|
-
|
|
63
|
-
|
|
63
|
+
assertTrue(formatted.length > 0, 'formatted decisions should be non-empty');
|
|
64
|
+
assertMatch(formatted, /\| # \| When \| Scope/, 'formatted decisions have table header');
|
|
64
65
|
|
|
65
66
|
// Verify the expected wrapper format that inlineDecisionsFromDb would produce
|
|
66
67
|
const wrapped = `### Decisions\nSource: \`.gsd/DECISIONS.md\`\n\n${formatted}`;
|
|
67
|
-
|
|
68
|
-
|
|
68
|
+
assertMatch(wrapped, /^### Decisions/, 'wrapped decisions start with ### Decisions');
|
|
69
|
+
assertMatch(wrapped, /Source:.*DECISIONS\.md/, 'wrapped decisions have source path');
|
|
69
70
|
|
|
70
71
|
closeDatabase();
|
|
71
72
|
}
|
|
@@ -100,25 +101,25 @@ console.log('\n=== prompt-db: scoped requirements from DB ===');
|
|
|
100
101
|
|
|
101
102
|
// Query scoped to S01 — should get R001 (primary) and R002 (supporting)
|
|
102
103
|
const s01Reqs = queryRequirements({ sliceId: 'S01' });
|
|
103
|
-
|
|
104
|
+
assertEq(s01Reqs.length, 2, 'S01 requirements should be 2 (primary + supporting)');
|
|
104
105
|
const ids = s01Reqs.map(r => r.id).sort();
|
|
105
|
-
|
|
106
|
+
assertEq(ids, ['R001', 'R002'], 'S01 owns R001 and supports R002');
|
|
106
107
|
|
|
107
108
|
// Unscoped query returns all 3
|
|
108
109
|
const allReqs = queryRequirements();
|
|
109
|
-
|
|
110
|
+
assertEq(allReqs.length, 3, 'unscoped requirements should return all 3');
|
|
110
111
|
|
|
111
112
|
// Format and verify wrapping
|
|
112
113
|
const formatted = formatRequirementsForPrompt(s01Reqs);
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
assertTrue(formatted.length > 0, 'formatted requirements should be non-empty');
|
|
115
|
+
assertMatch(formatted, /### R001/, 'formatted requirements include R001');
|
|
116
|
+
assertMatch(formatted, /### R002/, 'formatted requirements include R002');
|
|
117
|
+
assertNoMatch(formatted, /### R003/, 'formatted requirements exclude R003');
|
|
117
118
|
|
|
118
119
|
// Verify the expected wrapper format that inlineRequirementsFromDb would produce
|
|
119
120
|
const wrapped = `### Requirements\nSource: \`.gsd/REQUIREMENTS.md\`\n\n${formatted}`;
|
|
120
|
-
|
|
121
|
-
|
|
121
|
+
assertMatch(wrapped, /^### Requirements/, 'wrapped requirements start with ### Requirements');
|
|
122
|
+
assertMatch(wrapped, /Source:.*REQUIREMENTS\.md/, 'wrapped requirements have source path');
|
|
122
123
|
|
|
123
124
|
closeDatabase();
|
|
124
125
|
}
|
|
@@ -141,13 +142,13 @@ console.log('\n=== prompt-db: project content from DB ===');
|
|
|
141
142
|
});
|
|
142
143
|
|
|
143
144
|
const content = queryProject();
|
|
144
|
-
|
|
145
|
+
assertEq(content, '# Test Project\n\nThis is the project description.', 'queryProject returns content');
|
|
145
146
|
|
|
146
147
|
// Verify the expected wrapper format that inlineProjectFromDb would produce
|
|
147
148
|
const wrapped = `### Project\nSource: \`.gsd/PROJECT.md\`\n\n${content}`;
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
149
|
+
assertMatch(wrapped, /^### Project/, 'wrapped project starts with ### Project');
|
|
150
|
+
assertMatch(wrapped, /Source:.*PROJECT\.md/, 'wrapped project has source path');
|
|
151
|
+
assertMatch(wrapped, /# Test Project/, 'wrapped project includes content');
|
|
151
152
|
|
|
152
153
|
closeDatabase();
|
|
153
154
|
}
|
|
@@ -159,27 +160,27 @@ console.log('\n=== prompt-db: project content from DB ===');
|
|
|
159
160
|
console.log('\n=== prompt-db: fallback when DB unavailable ===');
|
|
160
161
|
{
|
|
161
162
|
closeDatabase();
|
|
162
|
-
|
|
163
|
+
assertTrue(!isDbAvailable(), 'DB should not be available');
|
|
163
164
|
|
|
164
165
|
// queryDecisions returns [] when DB closed — helper would fall back
|
|
165
166
|
const decisions = queryDecisions({ milestoneId: 'M001' });
|
|
166
|
-
|
|
167
|
+
assertEq(decisions, [], 'queryDecisions returns [] when DB closed');
|
|
167
168
|
|
|
168
169
|
// queryRequirements returns [] when DB closed — helper would fall back
|
|
169
170
|
const requirements = queryRequirements({ sliceId: 'S01' });
|
|
170
|
-
|
|
171
|
+
assertEq(requirements, [], 'queryRequirements returns [] when DB closed');
|
|
171
172
|
|
|
172
173
|
// queryProject returns null when DB closed — helper would fall back
|
|
173
174
|
const project = queryProject();
|
|
174
|
-
|
|
175
|
+
assertEq(project, null, 'queryProject returns null when DB closed');
|
|
175
176
|
|
|
176
177
|
// formatDecisionsForPrompt returns '' for empty input
|
|
177
178
|
const formatted = formatDecisionsForPrompt([]);
|
|
178
|
-
|
|
179
|
+
assertEq(formatted, '', 'formatDecisionsForPrompt returns empty for empty input');
|
|
179
180
|
|
|
180
181
|
// formatRequirementsForPrompt returns '' for empty input
|
|
181
182
|
const formattedReqs = formatRequirementsForPrompt([]);
|
|
182
|
-
|
|
183
|
+
assertEq(formattedReqs, '', 'formatRequirementsForPrompt returns empty for empty input');
|
|
183
184
|
}
|
|
184
185
|
|
|
185
186
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -209,15 +210,15 @@ console.log('\n=== prompt-db: scoped filtering reduces content ===');
|
|
|
209
210
|
const allDecisions = queryDecisions();
|
|
210
211
|
const m001Decisions = queryDecisions({ milestoneId: 'M001' });
|
|
211
212
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
213
|
+
assertEq(allDecisions.length, 10, 'unscoped returns all 10 decisions');
|
|
214
|
+
assertTrue(m001Decisions.length < 10, `M001-scoped returns fewer than 10 (got ${m001Decisions.length})`);
|
|
215
|
+
assertTrue(m001Decisions.length > 0, 'M001-scoped returns at least 1');
|
|
215
216
|
|
|
216
217
|
// Format both and compare sizes — scoped should be shorter
|
|
217
218
|
const allFormatted = formatDecisionsForPrompt(allDecisions);
|
|
218
219
|
const scopedFormatted = formatDecisionsForPrompt(m001Decisions);
|
|
219
220
|
|
|
220
|
-
|
|
221
|
+
assertTrue(
|
|
221
222
|
scopedFormatted.length < allFormatted.length,
|
|
222
223
|
`scoped content (${scopedFormatted.length} chars) should be shorter than unscoped (${allFormatted.length} chars)`,
|
|
223
224
|
);
|
|
@@ -244,14 +245,14 @@ console.log('\n=== prompt-db: scoped filtering reduces content ===');
|
|
|
244
245
|
const allReqs = queryRequirements();
|
|
245
246
|
const s01Reqs = queryRequirements({ sliceId: 'S01' });
|
|
246
247
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
248
|
+
assertEq(allReqs.length, 8, 'unscoped returns all 8 requirements');
|
|
249
|
+
assertTrue(s01Reqs.length < 8, `S01-scoped returns fewer than 8 (got ${s01Reqs.length})`);
|
|
250
|
+
assertTrue(s01Reqs.length > 0, 'S01-scoped returns at least 1');
|
|
250
251
|
|
|
251
252
|
const allReqsFormatted = formatRequirementsForPrompt(allReqs);
|
|
252
253
|
const scopedReqsFormatted = formatRequirementsForPrompt(s01Reqs);
|
|
253
254
|
|
|
254
|
-
|
|
255
|
+
assertTrue(
|
|
255
256
|
scopedReqsFormatted.length < allReqsFormatted.length,
|
|
256
257
|
`scoped requirements (${scopedReqsFormatted.length} chars) should be shorter than unscoped (${allReqsFormatted.length} chars)`,
|
|
257
258
|
);
|
|
@@ -291,23 +292,23 @@ console.log('\n=== prompt-db: DB helpers wrapper format matches expected pattern
|
|
|
291
292
|
|
|
292
293
|
// Simulate what inlineDecisionsFromDb does
|
|
293
294
|
const decisions = queryDecisions({ milestoneId: 'M001' });
|
|
294
|
-
|
|
295
|
+
assertTrue(decisions.length === 1, 'got 1 decision for M001');
|
|
295
296
|
const dFormatted = formatDecisionsForPrompt(decisions);
|
|
296
297
|
const dWrapped = `### Decisions\nSource: \`.gsd/DECISIONS.md\`\n\n${dFormatted}`;
|
|
297
|
-
|
|
298
|
+
assertMatch(dWrapped, /^### Decisions\nSource: `.gsd\/DECISIONS\.md`\n\n\| #/, 'decisions wrapper format correct');
|
|
298
299
|
|
|
299
300
|
// Simulate what inlineRequirementsFromDb does
|
|
300
301
|
const reqs = queryRequirements({ sliceId: 'S01' });
|
|
301
|
-
|
|
302
|
+
assertTrue(reqs.length === 1, 'got 1 requirement for S01');
|
|
302
303
|
const rFormatted = formatRequirementsForPrompt(reqs);
|
|
303
304
|
const rWrapped = `### Requirements\nSource: \`.gsd/REQUIREMENTS.md\`\n\n${rFormatted}`;
|
|
304
|
-
|
|
305
|
+
assertMatch(rWrapped, /^### Requirements\nSource: `.gsd\/REQUIREMENTS\.md`\n\n### R001/, 'requirements wrapper format correct');
|
|
305
306
|
|
|
306
307
|
// Simulate what inlineProjectFromDb does
|
|
307
308
|
const project = queryProject();
|
|
308
|
-
|
|
309
|
+
assertTrue(project !== null, 'project content exists');
|
|
309
310
|
const pWrapped = `### Project\nSource: \`.gsd/PROJECT.md\`\n\n${project}`;
|
|
310
|
-
|
|
311
|
+
assertMatch(pWrapped, /^### Project\nSource: `.gsd\/PROJECT\.md`\n\n# Project Name/, 'project wrapper format correct');
|
|
311
312
|
|
|
312
313
|
closeDatabase();
|
|
313
314
|
}
|
|
@@ -321,9 +322,8 @@ import { join } from 'node:path';
|
|
|
321
322
|
import { tmpdir } from 'node:os';
|
|
322
323
|
import { migrateFromMarkdown } from '../md-importer.ts';
|
|
323
324
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
test('prompt-db: re-import updates DB when source markdown changes', () => {
|
|
325
|
+
console.log('\n=== prompt-db: re-import updates DB when source markdown changes ===');
|
|
326
|
+
{
|
|
327
327
|
// Create a temp dir simulating a project with .gsd/DECISIONS.md
|
|
328
328
|
const tmpDir = mkdtempSync(join(tmpdir(), 'prompt-db-reimport-'));
|
|
329
329
|
const gsdDir = join(tmpDir, '.gsd');
|
|
@@ -345,9 +345,9 @@ test('prompt-db: re-import updates DB when source markdown changes', () => {
|
|
|
345
345
|
|
|
346
346
|
// Verify initial state: 2 decisions
|
|
347
347
|
const initial = queryDecisions();
|
|
348
|
-
|
|
348
|
+
assertEq(initial.length, 2, 're-import: initial import has 2 decisions');
|
|
349
349
|
const initialIds = initial.map(d => d.id).sort();
|
|
350
|
-
|
|
350
|
+
assertEq(initialIds, ['D001', 'D002'], 're-import: initial decisions are D001, D002');
|
|
351
351
|
|
|
352
352
|
// Now "the LLM modifies DECISIONS.md" — add a third decision
|
|
353
353
|
const updatedDecisions = `# Decisions Register
|
|
@@ -365,23 +365,23 @@ test('prompt-db: re-import updates DB when source markdown changes', () => {
|
|
|
365
365
|
|
|
366
366
|
// Verify DB now has 3 decisions
|
|
367
367
|
const afterReimport = queryDecisions();
|
|
368
|
-
|
|
368
|
+
assertEq(afterReimport.length, 3, 're-import: after re-import has 3 decisions');
|
|
369
369
|
const afterIds = afterReimport.map(d => d.id).sort();
|
|
370
|
-
|
|
370
|
+
assertEq(afterIds, ['D001', 'D002', 'D003'], 're-import: decisions are D001, D002, D003');
|
|
371
371
|
|
|
372
372
|
// Verify the new decision has correct data
|
|
373
373
|
const d003 = afterReimport.find(d => d.id === 'D003');
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
374
|
+
assertTrue(d003 !== undefined, 're-import: D003 exists');
|
|
375
|
+
assertEq(d003!.when_context, 'M001/S02', 're-import: D003 when_context is M001/S02');
|
|
376
|
+
assertEq(d003!.scope, 'runtime', 're-import: D003 scope is runtime');
|
|
377
|
+
assertEq(d003!.choice, 'D014 pattern', 're-import: D003 choice is D014 pattern');
|
|
378
378
|
|
|
379
379
|
// Verify scoped query picks up the new decision
|
|
380
380
|
const m001Scoped = queryDecisions({ milestoneId: 'M001' });
|
|
381
|
-
|
|
381
|
+
assertTrue(m001Scoped.length === 3, 're-import: all 3 decisions are for M001');
|
|
382
382
|
|
|
383
383
|
closeDatabase();
|
|
384
|
-
}
|
|
384
|
+
}
|
|
385
385
|
|
|
386
386
|
// ─── Final Report ──────────────────────────────────────────────────────────
|
|
387
|
-
|
|
387
|
+
report();
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { describe, test } from 'node:test';
|
|
2
|
-
import assert from 'node:assert/strict';
|
|
3
1
|
import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
4
2
|
import { join } from "node:path";
|
|
5
3
|
import { tmpdir } from "node:os";
|
|
@@ -7,94 +5,122 @@ import { tmpdir } from "node:os";
|
|
|
7
5
|
import { deriveState } from "../state.js";
|
|
8
6
|
import { buildExistingMilestonesContext } from "../guided-flow.js";
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
8
|
+
let passed = 0;
|
|
9
|
+
let failed = 0;
|
|
10
|
+
|
|
11
|
+
function assert(condition: boolean, message: string): void {
|
|
12
|
+
if (condition) {
|
|
13
|
+
passed++;
|
|
14
|
+
} else {
|
|
15
|
+
failed++;
|
|
16
|
+
console.error(` FAIL: ${message}`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// ─── Fixture setup ──────────────────────────────────────────────────────
|
|
21
|
+
|
|
22
|
+
const tmpBase = mkdtempSync(join(tmpdir(), "gsd-queue-draft-test-"));
|
|
23
|
+
const gsd = join(tmpBase, ".gsd");
|
|
24
|
+
|
|
25
|
+
// M001: has only CONTEXT-DRAFT.md (draft milestone)
|
|
26
|
+
mkdirSync(join(gsd, "milestones", "M001"), { recursive: true });
|
|
27
|
+
writeFileSync(
|
|
28
|
+
join(gsd, "milestones", "M001", "M001-CONTEXT-DRAFT.md"),
|
|
29
|
+
"# M001: Draft Milestone\n\nSeed material from prior discussion.\n",
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
// M002: has full CONTEXT.md (ready milestone)
|
|
33
|
+
mkdirSync(join(gsd, "milestones", "M002"), { recursive: true });
|
|
34
|
+
writeFileSync(
|
|
35
|
+
join(gsd, "milestones", "M002", "M002-CONTEXT.md"),
|
|
36
|
+
"# M002: Ready Milestone\n\nFull context from deep discussion.\n",
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
// M003: has both CONTEXT.md and CONTEXT-DRAFT.md (CONTEXT wins)
|
|
40
|
+
mkdirSync(join(gsd, "milestones", "M003"), { recursive: true });
|
|
41
|
+
writeFileSync(
|
|
42
|
+
join(gsd, "milestones", "M003", "M003-CONTEXT.md"),
|
|
43
|
+
"# M003: Full Context\n\nThis is the real context.\n",
|
|
44
|
+
);
|
|
45
|
+
writeFileSync(
|
|
46
|
+
join(gsd, "milestones", "M003", "M003-CONTEXT-DRAFT.md"),
|
|
47
|
+
"# M003: Draft\n\nThis should be ignored.\n",
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
// M004: has neither (empty milestone dir)
|
|
51
|
+
mkdirSync(join(gsd, "milestones", "M004"), { recursive: true });
|
|
52
|
+
|
|
53
|
+
// ─── Build context ──────────────────────────────────────────────────────
|
|
54
|
+
|
|
55
|
+
const state = await deriveState(tmpBase);
|
|
56
|
+
const milestoneIds = ["M001", "M002", "M003", "M004"];
|
|
57
|
+
const context = await buildExistingMilestonesContext(tmpBase, milestoneIds, state);
|
|
58
|
+
|
|
59
|
+
// ─── Test: draft-only milestone includes "Draft context available" ──────
|
|
60
|
+
|
|
61
|
+
assert(
|
|
62
|
+
context.includes("Draft context available"),
|
|
63
|
+
"M001 (draft-only) should include 'Draft context available' label",
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
assert(
|
|
67
|
+
context.includes("Seed material from prior discussion"),
|
|
68
|
+
"M001 draft content should be included in context output",
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
// ─── Test: full-context milestone uses "Context:" label ────────────────
|
|
72
|
+
|
|
73
|
+
assert(
|
|
74
|
+
context.includes("**Context:**"),
|
|
75
|
+
"M002 (full context) should use 'Context:' label",
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
assert(
|
|
79
|
+
context.includes("Full context from deep discussion"),
|
|
80
|
+
"M002 context content should be included",
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
// ─── Test: both files → CONTEXT.md wins, no draft label ────────────────
|
|
84
|
+
|
|
85
|
+
// Find M003's section and check it has Context: but not Draft
|
|
86
|
+
const m003Idx = context.indexOf("M003:");
|
|
87
|
+
const m003Section = context.slice(m003Idx, m003Idx + 500);
|
|
88
|
+
|
|
89
|
+
assert(
|
|
90
|
+
m003Section.includes("**Context:**"),
|
|
91
|
+
"M003 (both files) should use 'Context:' label (CONTEXT.md wins)",
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
assert(
|
|
95
|
+
!m003Section.includes("Draft context available"),
|
|
96
|
+
"M003 (both files) should NOT show draft label — CONTEXT.md takes precedence",
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
assert(
|
|
100
|
+
m003Section.includes("This is the real context"),
|
|
101
|
+
"M003 should show CONTEXT.md content, not draft content",
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
// ─── Test: neither file → no context section ───────────────────────────
|
|
105
|
+
|
|
106
|
+
const m004Idx = context.indexOf("M004:");
|
|
107
|
+
const m004Section = context.slice(m004Idx, m004Idx + 500);
|
|
108
|
+
|
|
109
|
+
assert(
|
|
110
|
+
!m004Section.includes("**Context:**"),
|
|
111
|
+
"M004 (neither file) should not have Context: label",
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
assert(
|
|
115
|
+
!m004Section.includes("Draft context available"),
|
|
116
|
+
"M004 (neither file) should not have Draft label",
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
// ─── Cleanup ──────────────────────────────────────────────────────────
|
|
120
|
+
|
|
121
|
+
rmSync(tmpBase, { recursive: true, force: true });
|
|
122
|
+
|
|
123
|
+
// ─── Results ──────────────────────────────────────────────────────────
|
|
124
|
+
|
|
125
|
+
console.log(`\nqueue-draft-detection: ${passed} passed, ${failed} failed`);
|
|
126
|
+
if (failed > 0) process.exit(1);
|