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
|
@@ -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, existsSync, readFileSync } from 'node:fs';
|
|
4
2
|
import { join } from 'node:path';
|
|
5
3
|
import { tmpdir } from 'node:os';
|
|
@@ -11,6 +9,10 @@ import {
|
|
|
11
9
|
pruneQueueOrder,
|
|
12
10
|
validateQueueOrder,
|
|
13
11
|
} from '../queue-order.ts';
|
|
12
|
+
import { createTestContext } from './test-helpers.ts';
|
|
13
|
+
|
|
14
|
+
const { assertEq, assertTrue, report } = createTestContext();
|
|
15
|
+
|
|
14
16
|
// ─── Fixture Helpers ───────────────────────────────────────────────────────
|
|
15
17
|
|
|
16
18
|
function createFixtureBase(): string {
|
|
@@ -27,166 +29,176 @@ function cleanup(base: string): void {
|
|
|
27
29
|
// sortByQueueOrder
|
|
28
30
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
29
31
|
|
|
32
|
+
console.log('\n=== sortByQueueOrder ===');
|
|
30
33
|
|
|
31
|
-
describe('queue-order', () => {
|
|
32
|
-
test('sortByQueueOrder', () => {
|
|
33
34
|
// Null order → default milestoneIdSort
|
|
35
|
+
{
|
|
34
36
|
const result = sortByQueueOrder(['M003', 'M001', 'M002'], null);
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
+
assertEq(result, ['M001', 'M002', 'M003'], 'null order falls back to numeric sort');
|
|
38
|
+
}
|
|
37
39
|
|
|
38
40
|
// Custom order → exact sequence
|
|
39
|
-
|
|
41
|
+
{
|
|
40
42
|
const result = sortByQueueOrder(['M001', 'M002', 'M003'], ['M003', 'M001', 'M002']);
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
+
assertEq(result, ['M003', 'M001', 'M002'], 'custom order produces exact sequence');
|
|
44
|
+
}
|
|
43
45
|
|
|
44
46
|
// Custom order with new IDs → appended at end in numeric order
|
|
45
|
-
|
|
47
|
+
{
|
|
46
48
|
const result = sortByQueueOrder(['M001', 'M002', 'M003', 'M004'], ['M003', 'M001']);
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
+
assertEq(result, ['M003', 'M001', 'M002', 'M004'], 'new IDs appended in numeric order');
|
|
50
|
+
}
|
|
49
51
|
|
|
50
52
|
// Custom order with deleted IDs → silently skipped
|
|
51
|
-
|
|
53
|
+
{
|
|
52
54
|
const result = sortByQueueOrder(['M001', 'M003'], ['M003', 'M002', 'M001']);
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
+
assertEq(result, ['M003', 'M001'], 'deleted IDs in order are skipped');
|
|
56
|
+
}
|
|
55
57
|
|
|
56
58
|
// Empty custom order → all IDs in numeric order
|
|
57
|
-
|
|
59
|
+
{
|
|
58
60
|
const result = sortByQueueOrder(['M002', 'M001'], []);
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
+
assertEq(result, ['M001', 'M002'], 'empty custom order falls back to numeric sort');
|
|
62
|
+
}
|
|
61
63
|
|
|
62
64
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
63
65
|
// loadQueueOrder / saveQueueOrder
|
|
64
66
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
65
|
-
|
|
67
|
+
|
|
68
|
+
console.log('\n=== loadQueueOrder / saveQueueOrder ===');
|
|
69
|
+
|
|
66
70
|
// Load returns null when file doesn't exist
|
|
71
|
+
{
|
|
67
72
|
const base = createFixtureBase();
|
|
68
|
-
|
|
73
|
+
assertEq(loadQueueOrder(base), null, 'returns null when file missing');
|
|
69
74
|
cleanup(base);
|
|
70
|
-
}
|
|
75
|
+
}
|
|
71
76
|
|
|
72
77
|
// Save then load round-trip
|
|
73
|
-
|
|
78
|
+
{
|
|
74
79
|
const base = createFixtureBase();
|
|
75
80
|
saveQueueOrder(base, ['M003', 'M001', 'M002']);
|
|
76
81
|
const loaded = loadQueueOrder(base);
|
|
77
|
-
|
|
82
|
+
assertEq(loaded, ['M003', 'M001', 'M002'], 'round-trip preserves order');
|
|
78
83
|
|
|
79
84
|
// Verify file contains updatedAt
|
|
80
85
|
const raw = JSON.parse(readFileSync(join(base, '.gsd', 'QUEUE-ORDER.json'), 'utf-8'));
|
|
81
|
-
|
|
86
|
+
assertTrue(typeof raw.updatedAt === 'string' && raw.updatedAt.length > 0, 'file contains updatedAt');
|
|
82
87
|
|
|
83
88
|
cleanup(base);
|
|
84
|
-
}
|
|
89
|
+
}
|
|
85
90
|
|
|
86
91
|
// Load returns null on corrupt JSON
|
|
87
|
-
|
|
92
|
+
{
|
|
88
93
|
const base = createFixtureBase();
|
|
89
94
|
writeFileSync(join(base, '.gsd', 'QUEUE-ORDER.json'), 'not json');
|
|
90
|
-
|
|
95
|
+
assertEq(loadQueueOrder(base), null, 'returns null on corrupt JSON');
|
|
91
96
|
cleanup(base);
|
|
92
|
-
}
|
|
97
|
+
}
|
|
93
98
|
|
|
94
99
|
// Load returns null when order field is not an array
|
|
95
|
-
|
|
100
|
+
{
|
|
96
101
|
const base = createFixtureBase();
|
|
97
102
|
writeFileSync(join(base, '.gsd', 'QUEUE-ORDER.json'), '{"order": "invalid"}');
|
|
98
|
-
|
|
103
|
+
assertEq(loadQueueOrder(base), null, 'returns null when order is not array');
|
|
99
104
|
cleanup(base);
|
|
100
|
-
}
|
|
105
|
+
}
|
|
101
106
|
|
|
102
107
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
103
108
|
// pruneQueueOrder
|
|
104
109
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
105
|
-
|
|
110
|
+
|
|
111
|
+
console.log('\n=== pruneQueueOrder ===');
|
|
112
|
+
|
|
106
113
|
// Prune removes invalid IDs
|
|
114
|
+
{
|
|
107
115
|
const base = createFixtureBase();
|
|
108
116
|
saveQueueOrder(base, ['M001', 'M002', 'M003']);
|
|
109
117
|
pruneQueueOrder(base, ['M001', 'M003']);
|
|
110
|
-
|
|
118
|
+
assertEq(loadQueueOrder(base), ['M001', 'M003'], 'prune removes invalid IDs');
|
|
111
119
|
cleanup(base);
|
|
112
|
-
}
|
|
120
|
+
}
|
|
113
121
|
|
|
114
122
|
// Prune no-ops when file doesn't exist
|
|
115
|
-
|
|
123
|
+
{
|
|
116
124
|
const base = createFixtureBase();
|
|
117
125
|
pruneQueueOrder(base, ['M001']); // should not throw
|
|
118
|
-
|
|
126
|
+
assertTrue(!existsSync(join(base, '.gsd', 'QUEUE-ORDER.json')), 'prune does not create file');
|
|
119
127
|
cleanup(base);
|
|
120
|
-
}
|
|
128
|
+
}
|
|
121
129
|
|
|
122
130
|
// Prune no-ops when all IDs are valid
|
|
123
|
-
|
|
131
|
+
{
|
|
124
132
|
const base = createFixtureBase();
|
|
125
133
|
saveQueueOrder(base, ['M001', 'M002']);
|
|
126
134
|
pruneQueueOrder(base, ['M001', 'M002', 'M003']);
|
|
127
|
-
|
|
135
|
+
assertEq(loadQueueOrder(base), ['M001', 'M002'], 'prune is no-op when all valid');
|
|
128
136
|
cleanup(base);
|
|
129
|
-
}
|
|
137
|
+
}
|
|
130
138
|
|
|
131
139
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
132
140
|
// validateQueueOrder
|
|
133
141
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
134
|
-
|
|
142
|
+
|
|
143
|
+
console.log('\n=== validateQueueOrder ===');
|
|
144
|
+
|
|
135
145
|
// Valid order with no dependencies
|
|
146
|
+
{
|
|
136
147
|
const depsMap = new Map<string, string[]>();
|
|
137
148
|
const result = validateQueueOrder(['M001', 'M002'], depsMap, new Set());
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
149
|
+
assertTrue(result.valid, 'valid when no dependencies');
|
|
150
|
+
assertEq(result.violations.length, 0, 'no violations');
|
|
151
|
+
assertEq(result.redundant.length, 0, 'no redundancies');
|
|
152
|
+
}
|
|
142
153
|
|
|
143
154
|
// Dependency violation: M002 before M001, but M002 depends on M001
|
|
144
|
-
|
|
155
|
+
{
|
|
145
156
|
const depsMap = new Map<string, string[]>([['M002', ['M001']]]);
|
|
146
157
|
const result = validateQueueOrder(['M002', 'M001'], depsMap, new Set());
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
158
|
+
assertTrue(!result.valid, 'invalid when dep violated');
|
|
159
|
+
assertEq(result.violations.length, 1, 'one violation');
|
|
160
|
+
assertEq(result.violations[0].type, 'would_block', 'violation type is would_block');
|
|
161
|
+
assertEq(result.violations[0].milestone, 'M002', 'violation milestone is M002');
|
|
162
|
+
assertEq(result.violations[0].dependsOn, 'M001', 'violation dep is M001');
|
|
163
|
+
}
|
|
153
164
|
|
|
154
165
|
// Redundant dependency: M002 depends on M001, M001 comes first in order
|
|
155
|
-
|
|
166
|
+
{
|
|
156
167
|
const depsMap = new Map<string, string[]>([['M002', ['M001']]]);
|
|
157
168
|
const result = validateQueueOrder(['M001', 'M002'], depsMap, new Set());
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
169
|
+
assertTrue(result.valid, 'valid when dep satisfied by position');
|
|
170
|
+
assertEq(result.redundant.length, 1, 'one redundancy');
|
|
171
|
+
assertEq(result.redundant[0].milestone, 'M002', 'redundant milestone is M002');
|
|
172
|
+
}
|
|
162
173
|
|
|
163
174
|
// Completed dep is always satisfied
|
|
164
|
-
|
|
175
|
+
{
|
|
165
176
|
const depsMap = new Map<string, string[]>([['M002', ['M001']]]);
|
|
166
177
|
const result = validateQueueOrder(['M002'], depsMap, new Set(['M001']));
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}
|
|
178
|
+
assertTrue(result.valid, 'valid when dep is already completed');
|
|
179
|
+
assertEq(result.violations.length, 0, 'no violations for completed dep');
|
|
180
|
+
}
|
|
170
181
|
|
|
171
182
|
// Missing dependency
|
|
172
|
-
|
|
183
|
+
{
|
|
173
184
|
const depsMap = new Map<string, string[]>([['M002', ['M099']]]);
|
|
174
185
|
const result = validateQueueOrder(['M001', 'M002'], depsMap, new Set());
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
}
|
|
186
|
+
assertTrue(!result.valid, 'invalid when dep does not exist');
|
|
187
|
+
assertEq(result.violations[0].type, 'missing_dep', 'violation type is missing_dep');
|
|
188
|
+
}
|
|
178
189
|
|
|
179
190
|
// Circular dependency
|
|
180
|
-
|
|
191
|
+
{
|
|
181
192
|
const depsMap = new Map<string, string[]>([
|
|
182
193
|
['M001', ['M002']],
|
|
183
194
|
['M002', ['M001']],
|
|
184
195
|
]);
|
|
185
196
|
const result = validateQueueOrder(['M001', 'M002'], depsMap, new Set());
|
|
186
|
-
|
|
197
|
+
assertTrue(!result.valid, 'invalid on circular dependency');
|
|
187
198
|
const circularViolation = result.violations.find(v => v.type === 'circular');
|
|
188
|
-
|
|
189
|
-
}
|
|
199
|
+
assertTrue(!!circularViolation, 'circular violation detected');
|
|
200
|
+
}
|
|
190
201
|
|
|
191
202
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
192
|
-
|
|
203
|
+
|
|
204
|
+
report();
|
|
@@ -11,8 +11,6 @@
|
|
|
11
11
|
* 4. A fresh deriveState() call (simulating new session) also works
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import { describe, test } from 'node:test';
|
|
15
|
-
import assert from 'node:assert/strict';
|
|
16
14
|
import { mkdtempSync, mkdirSync, rmSync, writeFileSync, readFileSync, existsSync } from 'node:fs';
|
|
17
15
|
import { join } from 'node:path';
|
|
18
16
|
import { tmpdir } from 'node:os';
|
|
@@ -21,6 +19,10 @@ import { deriveState, invalidateStateCache } from '../state.ts';
|
|
|
21
19
|
import { findMilestoneIds } from '../guided-flow.ts';
|
|
22
20
|
import { saveQueueOrder, loadQueueOrder } from '../queue-order.ts';
|
|
23
21
|
import { parseContextDependsOn } from '../files.ts';
|
|
22
|
+
import { createTestContext } from './test-helpers.ts';
|
|
23
|
+
|
|
24
|
+
const { assertEq, assertTrue, report } = createTestContext();
|
|
25
|
+
|
|
24
26
|
// ─── Fixture Helpers ───────────────────────────────────────────────────────
|
|
25
27
|
|
|
26
28
|
function createFixtureBase(): string {
|
|
@@ -68,9 +70,8 @@ function readContextFile(base: string, mid: string): string {
|
|
|
68
70
|
// Test: Queue order changes milestone activation
|
|
69
71
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
70
72
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
test('E2E: queue-order changes active milestone', async () => {
|
|
73
|
+
console.log('\n=== E2E: queue-order changes active milestone ===');
|
|
74
|
+
{
|
|
74
75
|
const base = createFixtureBase();
|
|
75
76
|
try {
|
|
76
77
|
// Setup: M007 complete, M008 and M009 pending (no context, no roadmap)
|
|
@@ -83,7 +84,7 @@ test('E2E: queue-order changes active milestone', async () => {
|
|
|
83
84
|
// Without custom order: M008 comes first (numeric sort)
|
|
84
85
|
invalidateStateCache();
|
|
85
86
|
const stateBefore = await deriveState(base);
|
|
86
|
-
|
|
87
|
+
assertEq(stateBefore.activeMilestone?.id, 'M008', 'before reorder: M008 is active');
|
|
87
88
|
|
|
88
89
|
// Save custom order: M009 before M008
|
|
89
90
|
saveQueueOrder(base, ['M009', 'M008']);
|
|
@@ -91,23 +92,25 @@ test('E2E: queue-order changes active milestone', async () => {
|
|
|
91
92
|
// With custom order: M009 should be active
|
|
92
93
|
invalidateStateCache();
|
|
93
94
|
const stateAfter = await deriveState(base);
|
|
94
|
-
|
|
95
|
+
assertEq(stateAfter.activeMilestone?.id, 'M009', 'after reorder: M009 is active');
|
|
95
96
|
|
|
96
97
|
// findMilestoneIds respects the order
|
|
97
98
|
const ids = findMilestoneIds(base);
|
|
98
99
|
const m008Idx = ids.indexOf('M008');
|
|
99
100
|
const m009Idx = ids.indexOf('M009');
|
|
100
|
-
|
|
101
|
+
assertTrue(m009Idx < m008Idx, 'findMilestoneIds: M009 comes before M008');
|
|
101
102
|
|
|
102
103
|
} finally {
|
|
103
104
|
cleanup(base);
|
|
104
105
|
}
|
|
105
|
-
}
|
|
106
|
+
}
|
|
106
107
|
|
|
107
108
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
108
109
|
// Test: Reorder + depends_on removal = correct state
|
|
109
110
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
110
|
-
|
|
111
|
+
|
|
112
|
+
console.log('\n=== E2E: reorder with depends_on removal ===');
|
|
113
|
+
{
|
|
111
114
|
const base = createFixtureBase();
|
|
112
115
|
try {
|
|
113
116
|
// Setup: M007 complete, M008 depends_on M009, M009 no deps
|
|
@@ -118,7 +121,7 @@ test('E2E: reorder with depends_on removal', async () => {
|
|
|
118
121
|
// Before: M008 depends on M009, so deriveState skips M008, M009 is active
|
|
119
122
|
invalidateStateCache();
|
|
120
123
|
const stateBefore = await deriveState(base);
|
|
121
|
-
|
|
124
|
+
assertEq(stateBefore.activeMilestone?.id, 'M009', 'before: M009 active (M008 dep-blocked)');
|
|
122
125
|
|
|
123
126
|
// Simulate reorder confirm: save order M009→M008, remove depends_on from M008
|
|
124
127
|
saveQueueOrder(base, ['M009', 'M008']);
|
|
@@ -131,27 +134,29 @@ test('E2E: reorder with depends_on removal', async () => {
|
|
|
131
134
|
// Verify: depends_on is gone
|
|
132
135
|
const updatedContent = readContextFile(base, 'M008');
|
|
133
136
|
const deps = parseContextDependsOn(updatedContent);
|
|
134
|
-
|
|
137
|
+
assertEq(deps.length, 0, 'depends_on removed from M008-CONTEXT.md');
|
|
135
138
|
|
|
136
139
|
// Verify: deriveState still picks M009 (it's first in queue order)
|
|
137
140
|
invalidateStateCache();
|
|
138
141
|
const stateAfter = await deriveState(base);
|
|
139
|
-
|
|
142
|
+
assertEq(stateAfter.activeMilestone?.id, 'M009', 'after: M009 still active (first in queue)');
|
|
140
143
|
|
|
141
144
|
// Verify: M008 is now pending (not dep-blocked)
|
|
142
145
|
const m008Entry = stateAfter.registry.find(m => m.id === 'M008');
|
|
143
|
-
|
|
144
|
-
|
|
146
|
+
assertEq(m008Entry?.status, 'pending', 'M008 is pending (not dep-blocked)');
|
|
147
|
+
assertTrue(!m008Entry?.dependsOn || m008Entry.dependsOn.length === 0, 'M008 has no dependsOn');
|
|
145
148
|
|
|
146
149
|
} finally {
|
|
147
150
|
cleanup(base);
|
|
148
151
|
}
|
|
149
|
-
}
|
|
152
|
+
}
|
|
150
153
|
|
|
151
154
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
152
155
|
// Test: Fresh deriveState (simulating new session) respects queue order
|
|
153
156
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
154
|
-
|
|
157
|
+
|
|
158
|
+
console.log('\n=== E2E: fresh session respects queue order ===');
|
|
159
|
+
{
|
|
155
160
|
const base = createFixtureBase();
|
|
156
161
|
try {
|
|
157
162
|
writeCompleteMilestone(base, 'M007');
|
|
@@ -166,21 +171,23 @@ test('E2E: fresh session respects queue order', async () => {
|
|
|
166
171
|
|
|
167
172
|
// Derive state — should read QUEUE-ORDER.json from disk
|
|
168
173
|
const state = await deriveState(base);
|
|
169
|
-
|
|
174
|
+
assertEq(state.activeMilestone?.id, 'M009', 'fresh session: M009 is active');
|
|
170
175
|
|
|
171
176
|
// Verify queue order persisted
|
|
172
177
|
const order = loadQueueOrder(base);
|
|
173
|
-
|
|
178
|
+
assertEq(order, ['M009', 'M008'], 'QUEUE-ORDER.json persisted correctly');
|
|
174
179
|
|
|
175
180
|
} finally {
|
|
176
181
|
cleanup(base);
|
|
177
182
|
}
|
|
178
|
-
}
|
|
183
|
+
}
|
|
179
184
|
|
|
180
185
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
181
186
|
// Test: Queue order with newly added milestones
|
|
182
187
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
183
|
-
|
|
188
|
+
|
|
189
|
+
console.log('\n=== E2E: new milestones appended to queue ===');
|
|
190
|
+
{
|
|
184
191
|
const base = createFixtureBase();
|
|
185
192
|
try {
|
|
186
193
|
writeCompleteMilestone(base, 'M007');
|
|
@@ -200,22 +207,24 @@ test('E2E: new milestones appended to queue', async () => {
|
|
|
200
207
|
const m009Idx = ids.indexOf('M009');
|
|
201
208
|
const m008Idx = ids.indexOf('M008');
|
|
202
209
|
const m010Idx = ids.indexOf('M010');
|
|
203
|
-
|
|
204
|
-
|
|
210
|
+
assertTrue(m009Idx < m008Idx, 'M009 before M008');
|
|
211
|
+
assertTrue(m008Idx < m010Idx, 'M008 before M010 (new milestone appended)');
|
|
205
212
|
|
|
206
213
|
// M009 is still active (first non-complete in queue order)
|
|
207
214
|
const state = await deriveState(base);
|
|
208
|
-
|
|
215
|
+
assertEq(state.activeMilestone?.id, 'M009', 'M009 still active after M010 added');
|
|
209
216
|
|
|
210
217
|
} finally {
|
|
211
218
|
cleanup(base);
|
|
212
219
|
}
|
|
213
|
-
}
|
|
220
|
+
}
|
|
214
221
|
|
|
215
222
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
216
223
|
// Test: No queue order file = default numeric sort (backward compat)
|
|
217
224
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
218
|
-
|
|
225
|
+
|
|
226
|
+
console.log('\n=== E2E: backward compat without QUEUE-ORDER.json ===');
|
|
227
|
+
{
|
|
219
228
|
const base = createFixtureBase();
|
|
220
229
|
try {
|
|
221
230
|
writeCompleteMilestone(base, 'M007');
|
|
@@ -225,20 +234,22 @@ test('E2E: backward compat without QUEUE-ORDER.json', async () => {
|
|
|
225
234
|
// No QUEUE-ORDER.json — default numeric sort
|
|
226
235
|
invalidateStateCache();
|
|
227
236
|
const state = await deriveState(base);
|
|
228
|
-
|
|
237
|
+
assertEq(state.activeMilestone?.id, 'M008', 'no queue order: M008 active (numeric)');
|
|
229
238
|
|
|
230
239
|
const ids = findMilestoneIds(base);
|
|
231
|
-
|
|
240
|
+
assertTrue(ids.indexOf('M008') < ids.indexOf('M009'), 'default sort: M008 before M009');
|
|
232
241
|
|
|
233
242
|
} finally {
|
|
234
243
|
cleanup(base);
|
|
235
244
|
}
|
|
236
|
-
}
|
|
245
|
+
}
|
|
237
246
|
|
|
238
247
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
239
248
|
// Test: non-milestone directories are filtered out (#1494)
|
|
240
249
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
241
|
-
|
|
250
|
+
|
|
251
|
+
console.log('\n=== E2E: non-milestone directories filtered from findMilestoneIds (#1494) ===');
|
|
252
|
+
{
|
|
242
253
|
const base = createFixtureBase();
|
|
243
254
|
try {
|
|
244
255
|
writeContext(base, 'M001', '', 'First');
|
|
@@ -249,20 +260,22 @@ test('E2E: non-milestone directories filtered from findMilestoneIds (#1494)', ()
|
|
|
249
260
|
|
|
250
261
|
invalidateStateCache();
|
|
251
262
|
const ids = findMilestoneIds(base);
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
263
|
+
assertEq(ids.length, 2, 'only M001 and M002 returned');
|
|
264
|
+
assertTrue(!ids.includes('slices'), 'slices directory excluded');
|
|
265
|
+
assertTrue(!ids.includes('temp-backup'), 'temp-backup directory excluded');
|
|
266
|
+
assertTrue(ids.includes('M001'), 'M001 included');
|
|
267
|
+
assertTrue(ids.includes('M002'), 'M002 included');
|
|
257
268
|
} finally {
|
|
258
269
|
cleanup(base);
|
|
259
270
|
}
|
|
260
|
-
}
|
|
271
|
+
}
|
|
261
272
|
|
|
262
273
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
263
274
|
// Test: depends_on inline array format removal
|
|
264
275
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
265
|
-
|
|
276
|
+
|
|
277
|
+
console.log('\n=== E2E: depends_on inline format preserved after partial removal ===');
|
|
278
|
+
{
|
|
266
279
|
const base = createFixtureBase();
|
|
267
280
|
try {
|
|
268
281
|
writeCompleteMilestone(base, 'M007');
|
|
@@ -274,7 +287,7 @@ test('E2E: depends_on inline format preserved after partial removal', () => {
|
|
|
274
287
|
// Verify both deps are parsed
|
|
275
288
|
const contentBefore = readContextFile(base, 'M008');
|
|
276
289
|
const depsBefore = parseContextDependsOn(contentBefore);
|
|
277
|
-
|
|
290
|
+
assertEq(depsBefore.length, 2, 'M008 has 2 deps before');
|
|
278
291
|
|
|
279
292
|
// Simulate removing only M009 dep (keep M010)
|
|
280
293
|
const content = readContextFile(base, 'M008');
|
|
@@ -284,12 +297,12 @@ test('E2E: depends_on inline format preserved after partial removal', () => {
|
|
|
284
297
|
// Verify only M010 remains
|
|
285
298
|
const contentAfter = readContextFile(base, 'M008');
|
|
286
299
|
const depsAfter = parseContextDependsOn(contentAfter);
|
|
287
|
-
|
|
288
|
-
|
|
300
|
+
assertEq(depsAfter.length, 1, 'M008 has 1 dep after removal');
|
|
301
|
+
assertEq(depsAfter[0], 'M010', 'remaining dep is M010');
|
|
289
302
|
|
|
290
303
|
} finally {
|
|
291
304
|
cleanup(base);
|
|
292
305
|
}
|
|
293
|
-
}
|
|
306
|
+
}
|
|
294
307
|
|
|
295
|
-
|
|
308
|
+
report();
|