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
|
@@ -10,9 +10,9 @@ import { parsePlanningDirectory } from '../migrate/parser.ts';
|
|
|
10
10
|
import { validatePlanningDirectory } from '../migrate/validator.ts';
|
|
11
11
|
|
|
12
12
|
import type { PlanningProject, ValidationResult } from '../migrate/types.ts';
|
|
13
|
-
import {
|
|
14
|
-
import assert from 'node:assert/strict';
|
|
13
|
+
import { createTestContext } from './test-helpers.ts';
|
|
15
14
|
|
|
15
|
+
const { assertEq, assertTrue, report } = createTestContext();
|
|
16
16
|
// ─── Fixture Helpers ───────────────────────────────────────────────────────
|
|
17
17
|
|
|
18
18
|
function createFixtureBase(): string {
|
|
@@ -241,9 +241,11 @@ Fixed the login button by correcting the touch event handler.
|
|
|
241
241
|
// Test Groups
|
|
242
242
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
243
243
|
|
|
244
|
-
|
|
244
|
+
async function main(): Promise<void> {
|
|
245
245
|
|
|
246
|
-
|
|
246
|
+
// ─── Test 1: Complete .planning directory ──────────────────────────────
|
|
247
|
+
console.log('\n=== Complete .planning directory with all file types ===');
|
|
248
|
+
{
|
|
247
249
|
const base = createFixtureBase();
|
|
248
250
|
try {
|
|
249
251
|
const planning = createPlanningDir(base);
|
|
@@ -311,86 +313,86 @@ Dashboard needs auth to be complete first.
|
|
|
311
313
|
const project = await parsePlanningDirectory(planning);
|
|
312
314
|
|
|
313
315
|
// Top-level structure
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
316
|
+
assertEq(project.path, planning, 'project.path matches');
|
|
317
|
+
assertTrue(project.project !== null, 'PROJECT.md parsed');
|
|
318
|
+
assertTrue(project.roadmap !== null, 'ROADMAP.md parsed');
|
|
319
|
+
assertTrue(project.requirements.length > 0, 'requirements parsed');
|
|
320
|
+
assertTrue(project.state !== null, 'STATE.md parsed');
|
|
321
|
+
assertTrue(project.config !== null, 'config.json parsed');
|
|
320
322
|
|
|
321
323
|
// Phases
|
|
322
|
-
|
|
323
|
-
|
|
324
|
+
assertTrue('29-auth-system' in project.phases, 'phase 29 present');
|
|
325
|
+
assertTrue('30-dashboard' in project.phases, 'phase 30 present');
|
|
324
326
|
|
|
325
327
|
const phase29 = project.phases['29-auth-system'];
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
328
|
+
assertEq(phase29?.number, 29, 'phase 29 number');
|
|
329
|
+
assertEq(phase29?.slug, 'auth-system', 'phase 29 slug');
|
|
330
|
+
assertTrue('01' in (phase29?.plans ?? {}), 'phase 29 has plan 01');
|
|
331
|
+
assertTrue('01' in (phase29?.summaries ?? {}), 'phase 29 has summary 01');
|
|
332
|
+
assertTrue((phase29?.research?.length ?? 0) > 0, 'phase 29 has research');
|
|
331
333
|
|
|
332
334
|
// Plan content (XML-in-markdown)
|
|
333
335
|
const plan29 = phase29?.plans?.['01'];
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
336
|
+
assertTrue(plan29 !== undefined, 'plan 29-01 exists');
|
|
337
|
+
assertTrue(plan29?.objective?.includes('authentication') ?? false, 'plan objective extracted');
|
|
338
|
+
assertTrue((plan29?.tasks?.length ?? 0) >= 3, 'plan tasks extracted');
|
|
339
|
+
assertTrue(plan29?.context?.includes('JWT') ?? false, 'plan context extracted');
|
|
340
|
+
assertTrue(plan29?.verification !== '', 'plan verification extracted');
|
|
341
|
+
assertTrue(plan29?.successCriteria !== '', 'plan success criteria extracted');
|
|
340
342
|
|
|
341
343
|
// Plan frontmatter
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
344
|
+
assertEq(plan29?.frontmatter?.phase, '29-auth-system', 'plan frontmatter phase');
|
|
345
|
+
assertEq(plan29?.frontmatter?.plan, '01', 'plan frontmatter plan');
|
|
346
|
+
assertEq(plan29?.frontmatter?.type, 'implementation', 'plan frontmatter type');
|
|
347
|
+
assertEq(plan29?.frontmatter?.wave, 1, 'plan frontmatter wave');
|
|
348
|
+
assertEq(plan29?.frontmatter?.autonomous, true, 'plan frontmatter autonomous');
|
|
347
349
|
|
|
348
350
|
// Summary content
|
|
349
351
|
const summary29 = phase29?.summaries?.['01'];
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
352
|
+
assertTrue(summary29 !== undefined, 'summary 29-01 exists');
|
|
353
|
+
assertEq(summary29?.frontmatter?.phase, '29-auth-system', 'summary frontmatter phase');
|
|
354
|
+
assertEq(summary29?.frontmatter?.plan, '01', 'summary frontmatter plan');
|
|
355
|
+
assertEq(summary29?.frontmatter?.subsystem, 'auth', 'summary frontmatter subsystem');
|
|
356
|
+
assertTrue((summary29?.frontmatter?.tags?.length ?? 0) >= 2, 'summary frontmatter tags');
|
|
357
|
+
assertTrue((summary29?.frontmatter?.provides?.length ?? 0) >= 2, 'summary frontmatter provides');
|
|
358
|
+
assertTrue((summary29?.frontmatter?.affects?.length ?? 0) >= 1, 'summary frontmatter affects');
|
|
359
|
+
assertTrue((summary29?.frontmatter?.['tech-stack']?.length ?? 0) >= 2, 'summary frontmatter tech-stack');
|
|
360
|
+
assertTrue((summary29?.frontmatter?.['key-files']?.length ?? 0) >= 2, 'summary frontmatter key-files');
|
|
361
|
+
assertTrue((summary29?.frontmatter?.['key-decisions']?.length ?? 0) >= 2, 'summary frontmatter key-decisions');
|
|
362
|
+
assertTrue((summary29?.frontmatter?.['patterns-established']?.length ?? 0) >= 1, 'summary frontmatter patterns-established');
|
|
363
|
+
assertEq(summary29?.frontmatter?.duration, '2h', 'summary frontmatter duration');
|
|
364
|
+
assertEq(summary29?.frontmatter?.completed, '2026-01-15', 'summary frontmatter completed');
|
|
363
365
|
|
|
364
366
|
// Quick tasks
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
367
|
+
assertTrue(project.quickTasks.length >= 1, 'quick tasks parsed');
|
|
368
|
+
assertEq(project.quickTasks[0]?.number, 1, 'quick task number');
|
|
369
|
+
assertTrue(project.quickTasks[0]?.plan !== null, 'quick task has plan');
|
|
370
|
+
assertTrue(project.quickTasks[0]?.summary !== null, 'quick task has summary');
|
|
369
371
|
|
|
370
372
|
// Milestones
|
|
371
|
-
|
|
373
|
+
assertTrue(project.milestones.length >= 1, 'milestones parsed');
|
|
372
374
|
|
|
373
375
|
// Root research
|
|
374
|
-
|
|
376
|
+
assertTrue(project.research.length >= 1, 'root research parsed');
|
|
375
377
|
|
|
376
378
|
// Config
|
|
377
|
-
|
|
379
|
+
assertEq(project.config?.projectName, 'test-project', 'config projectName');
|
|
378
380
|
|
|
379
381
|
// State
|
|
380
|
-
|
|
381
|
-
|
|
382
|
+
assertTrue(project.state?.currentPhase?.includes('30') ?? false, 'state current phase');
|
|
383
|
+
assertEq(project.state?.status, 'in-progress', 'state status');
|
|
382
384
|
|
|
383
385
|
// Validation
|
|
384
|
-
|
|
385
|
-
|
|
386
|
+
assertEq(project.validation.valid, true, 'validation passes for complete dir');
|
|
387
|
+
assertEq(project.validation.issues.length, 0, 'no validation issues');
|
|
386
388
|
} finally {
|
|
387
389
|
cleanup(base);
|
|
388
390
|
}
|
|
389
|
-
}
|
|
391
|
+
}
|
|
390
392
|
|
|
391
393
|
// ─── Test 2: Minimal .planning directory (only ROADMAP.md) ─────────────
|
|
392
|
-
|
|
393
|
-
|
|
394
|
+
console.log('\n=== Minimal .planning directory (only ROADMAP.md) ===');
|
|
395
|
+
{
|
|
394
396
|
const base = createFixtureBase();
|
|
395
397
|
try {
|
|
396
398
|
const planning = createPlanningDir(base);
|
|
@@ -398,42 +400,42 @@ test('Minimal .planning directory (only ROADMAP.md)', async () => {
|
|
|
398
400
|
|
|
399
401
|
const project = await parsePlanningDirectory(planning);
|
|
400
402
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
403
|
+
assertEq(project.project, null, 'minimal: PROJECT.md is null');
|
|
404
|
+
assertTrue(project.roadmap !== null, 'minimal: ROADMAP.md parsed');
|
|
405
|
+
assertEq(project.requirements.length, 0, 'minimal: no requirements');
|
|
406
|
+
assertEq(project.state, null, 'minimal: no state');
|
|
407
|
+
assertEq(project.config, null, 'minimal: no config');
|
|
408
|
+
assertEq(Object.keys(project.phases).length, 0, 'minimal: no phases');
|
|
409
|
+
assertEq(project.quickTasks.length, 0, 'minimal: no quick tasks');
|
|
410
|
+
assertEq(project.milestones.length, 0, 'minimal: no milestones');
|
|
411
|
+
assertEq(project.research.length, 0, 'minimal: no research');
|
|
412
|
+
assertEq(project.validation.valid, true, 'minimal: validation passes');
|
|
411
413
|
} finally {
|
|
412
414
|
cleanup(base);
|
|
413
415
|
}
|
|
414
|
-
}
|
|
416
|
+
}
|
|
415
417
|
|
|
416
418
|
// ─── Test 3: Missing directory → validation fatal error ────────────────
|
|
417
|
-
|
|
418
|
-
|
|
419
|
+
console.log('\n=== Missing directory → validation returns fatal error ===');
|
|
420
|
+
{
|
|
419
421
|
const base = createFixtureBase();
|
|
420
422
|
try {
|
|
421
423
|
const result = await validatePlanningDirectory(join(base, 'nonexistent'));
|
|
422
424
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
425
|
+
assertEq(result.valid, false, 'missing dir: validation fails');
|
|
426
|
+
assertTrue(result.issues.length > 0, 'missing dir: has issues');
|
|
427
|
+
assertTrue(
|
|
426
428
|
result.issues.some(i => i.severity === 'fatal'),
|
|
427
429
|
'missing dir: has fatal issue'
|
|
428
430
|
);
|
|
429
431
|
} finally {
|
|
430
432
|
cleanup(base);
|
|
431
433
|
}
|
|
432
|
-
}
|
|
434
|
+
}
|
|
433
435
|
|
|
434
436
|
// ─── Test 4: Duplicate phase numbers ───────────────────────────────────
|
|
435
|
-
|
|
436
|
-
|
|
437
|
+
console.log('\n=== Phase directory with duplicate numbers ===');
|
|
438
|
+
{
|
|
437
439
|
const base = createFixtureBase();
|
|
438
440
|
try {
|
|
439
441
|
const planning = createPlanningDir(base);
|
|
@@ -454,18 +456,18 @@ test('Phase directory with duplicate numbers', async () => {
|
|
|
454
456
|
|
|
455
457
|
const project = await parsePlanningDirectory(planning);
|
|
456
458
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
459
|
+
assertTrue('45-core-infrastructure' in project.phases, 'dup nums: core-infrastructure phase present');
|
|
460
|
+
assertTrue('45-logging-config' in project.phases, 'dup nums: logging-config phase present');
|
|
461
|
+
assertEq(project.phases['45-core-infrastructure']?.number, 45, 'dup nums: both have number 45 (a)');
|
|
462
|
+
assertEq(project.phases['45-logging-config']?.number, 45, 'dup nums: both have number 45 (b)');
|
|
461
463
|
} finally {
|
|
462
464
|
cleanup(base);
|
|
463
465
|
}
|
|
464
|
-
}
|
|
466
|
+
}
|
|
465
467
|
|
|
466
468
|
// ─── Test 5: XML-in-markdown plan parsing ──────────────────────────────
|
|
467
|
-
|
|
468
|
-
|
|
469
|
+
console.log('\n=== Plan file with XML-in-markdown ===');
|
|
470
|
+
{
|
|
469
471
|
const base = createFixtureBase();
|
|
470
472
|
try {
|
|
471
473
|
const planning = createPlanningDir(base);
|
|
@@ -478,21 +480,21 @@ test('Plan file with XML-in-markdown', async () => {
|
|
|
478
480
|
const project = await parsePlanningDirectory(planning);
|
|
479
481
|
const plan = project.phases['29-auth-system']?.plans?.['01'];
|
|
480
482
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
483
|
+
assertTrue(plan !== undefined, 'xml plan: plan exists');
|
|
484
|
+
assertTrue(plan?.objective?.includes('authentication') ?? false, 'xml plan: objective extracted');
|
|
485
|
+
assertTrue((plan?.tasks?.length ?? 0) === 3, 'xml plan: 3 tasks extracted');
|
|
486
|
+
assertTrue(plan?.tasks?.[0]?.includes('auth middleware') ?? false, 'xml plan: first task content');
|
|
487
|
+
assertTrue(plan?.context?.includes('JWT') ?? false, 'xml plan: context extracted');
|
|
488
|
+
assertTrue(plan?.verification?.includes('Login returns') ?? false, 'xml plan: verification extracted');
|
|
489
|
+
assertTrue(plan?.successCriteria?.includes('endpoints respond') ?? false, 'xml plan: success criteria extracted');
|
|
488
490
|
} finally {
|
|
489
491
|
cleanup(base);
|
|
490
492
|
}
|
|
491
|
-
}
|
|
493
|
+
}
|
|
492
494
|
|
|
493
495
|
// ─── Test 6: Summary file with YAML frontmatter ───────────────────────
|
|
494
|
-
|
|
495
|
-
|
|
496
|
+
console.log('\n=== Summary file with YAML frontmatter ===');
|
|
497
|
+
{
|
|
496
498
|
const base = createFixtureBase();
|
|
497
499
|
try {
|
|
498
500
|
const planning = createPlanningDir(base);
|
|
@@ -505,27 +507,27 @@ test('Summary file with YAML frontmatter', async () => {
|
|
|
505
507
|
const project = await parsePlanningDirectory(planning);
|
|
506
508
|
const summary = project.phases['29-auth-system']?.summaries?.['01'];
|
|
507
509
|
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
510
|
+
assertTrue(summary !== undefined, 'summary fm: summary exists');
|
|
511
|
+
assertEq(summary?.frontmatter?.phase, '29-auth-system', 'summary fm: phase');
|
|
512
|
+
assertEq(summary?.frontmatter?.plan, '01', 'summary fm: plan');
|
|
513
|
+
assertEq(summary?.frontmatter?.subsystem, 'auth', 'summary fm: subsystem');
|
|
514
|
+
assertEq(summary?.frontmatter?.tags, ['authentication', 'security'], 'summary fm: tags');
|
|
515
|
+
assertEq(summary?.frontmatter?.provides, ['auth-middleware', 'jwt-validation'], 'summary fm: provides');
|
|
516
|
+
assertEq(summary?.frontmatter?.affects, ['api-routes'], 'summary fm: affects');
|
|
517
|
+
assertEq(summary?.frontmatter?.['tech-stack'], ['jsonwebtoken', 'express'], 'summary fm: tech-stack');
|
|
518
|
+
assertEq(summary?.frontmatter?.['key-files'], ['src/auth.ts', 'src/middleware/auth.ts'], 'summary fm: key-files');
|
|
519
|
+
assertEq(summary?.frontmatter?.['key-decisions'], ['Use RS256 for JWT signing', 'Store refresh tokens in DB'], 'summary fm: key-decisions');
|
|
520
|
+
assertEq(summary?.frontmatter?.['patterns-established'], ['Middleware-based auth'], 'summary fm: patterns-established');
|
|
521
|
+
assertEq(summary?.frontmatter?.duration, '2h', 'summary fm: duration');
|
|
522
|
+
assertEq(summary?.frontmatter?.completed, '2026-01-15', 'summary fm: completed');
|
|
521
523
|
} finally {
|
|
522
524
|
cleanup(base);
|
|
523
525
|
}
|
|
524
|
-
}
|
|
526
|
+
}
|
|
525
527
|
|
|
526
528
|
// ─── Test 7: Orphan summaries (no matching plan) ──────────────────────
|
|
527
|
-
|
|
528
|
-
|
|
529
|
+
console.log('\n=== Orphan summaries (no matching plan) ===');
|
|
530
|
+
{
|
|
529
531
|
const base = createFixtureBase();
|
|
530
532
|
try {
|
|
531
533
|
const planning = createPlanningDir(base);
|
|
@@ -559,19 +561,19 @@ Another orphan.
|
|
|
559
561
|
const project = await parsePlanningDirectory(planning);
|
|
560
562
|
const phase = project.phases['45-logging-config'];
|
|
561
563
|
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
564
|
+
assertTrue(phase !== undefined, 'orphan: phase exists');
|
|
565
|
+
assertEq(Object.keys(phase?.plans ?? {}).length, 0, 'orphan: no plans');
|
|
566
|
+
assertTrue(Object.keys(phase?.summaries ?? {}).length >= 2, 'orphan: summaries preserved');
|
|
567
|
+
assertTrue('04' in (phase?.summaries ?? {}), 'orphan: summary 04 present');
|
|
568
|
+
assertTrue('05' in (phase?.summaries ?? {}), 'orphan: summary 05 present');
|
|
567
569
|
} finally {
|
|
568
570
|
cleanup(base);
|
|
569
571
|
}
|
|
570
|
-
}
|
|
572
|
+
}
|
|
571
573
|
|
|
572
574
|
// ─── Test 8: .archive/ directory skipped ──────────────────────────────
|
|
573
|
-
|
|
574
|
-
|
|
575
|
+
console.log('\n=== .archive/ directory → skipped by default ===');
|
|
576
|
+
{
|
|
575
577
|
const base = createFixtureBase();
|
|
576
578
|
try {
|
|
577
579
|
const planning = createPlanningDir(base);
|
|
@@ -589,17 +591,17 @@ test('.archive/ directory → skipped by default', async () => {
|
|
|
589
591
|
|
|
590
592
|
const project = await parsePlanningDirectory(planning);
|
|
591
593
|
|
|
592
|
-
|
|
594
|
+
assertTrue('29-auth-system' in project.phases, 'archive: normal phase present');
|
|
593
595
|
// Archive phases should not appear in the phases map
|
|
594
|
-
|
|
596
|
+
assertTrue(!Object.keys(project.phases).some(k => k.includes('old-auth')), 'archive: archived phase not present');
|
|
595
597
|
} finally {
|
|
596
598
|
cleanup(base);
|
|
597
599
|
}
|
|
598
|
-
}
|
|
600
|
+
}
|
|
599
601
|
|
|
600
602
|
// ─── Test 9: Quick tasks ──────────────────────────────────────────────
|
|
601
|
-
|
|
602
|
-
|
|
603
|
+
console.log('\n=== Quick tasks parsed ===');
|
|
604
|
+
{
|
|
603
605
|
const base = createFixtureBase();
|
|
604
606
|
try {
|
|
605
607
|
const planning = createPlanningDir(base);
|
|
@@ -618,22 +620,22 @@ test('Quick tasks parsed', async () => {
|
|
|
618
620
|
|
|
619
621
|
const project = await parsePlanningDirectory(planning);
|
|
620
622
|
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
623
|
+
assertEq(project.quickTasks.length, 2, 'quick: 2 quick tasks');
|
|
624
|
+
assertEq(project.quickTasks[0]?.number, 1, 'quick: first task number');
|
|
625
|
+
assertEq(project.quickTasks[0]?.slug, 'fix-login', 'quick: first task slug');
|
|
626
|
+
assertTrue(project.quickTasks[0]?.plan !== null, 'quick: first task has plan');
|
|
627
|
+
assertTrue(project.quickTasks[0]?.summary !== null, 'quick: first task has summary');
|
|
628
|
+
assertEq(project.quickTasks[1]?.number, 2, 'quick: second task number');
|
|
629
|
+
assertTrue(project.quickTasks[1]?.plan !== null, 'quick: second task has plan');
|
|
630
|
+
assertEq(project.quickTasks[1]?.summary, null, 'quick: second task has no summary');
|
|
629
631
|
} finally {
|
|
630
632
|
cleanup(base);
|
|
631
633
|
}
|
|
632
|
-
}
|
|
634
|
+
}
|
|
633
635
|
|
|
634
636
|
// ─── Test 10: Roadmap with milestone sections and <details> ────────────
|
|
635
|
-
|
|
636
|
-
|
|
637
|
+
console.log('\n=== Roadmap with milestone sections and <details> blocks ===');
|
|
638
|
+
{
|
|
637
639
|
const base = createFixtureBase();
|
|
638
640
|
try {
|
|
639
641
|
const planning = createPlanningDir(base);
|
|
@@ -641,35 +643,35 @@ test('Roadmap with milestone sections and <details> blocks', async () => {
|
|
|
641
643
|
|
|
642
644
|
const project = await parsePlanningDirectory(planning);
|
|
643
645
|
|
|
644
|
-
|
|
645
|
-
|
|
646
|
+
assertTrue(project.roadmap !== null, 'ms roadmap: roadmap parsed');
|
|
647
|
+
assertTrue((project.roadmap?.milestones?.length ?? 0) >= 2, 'ms roadmap: has milestone sections');
|
|
646
648
|
|
|
647
649
|
// Check collapsed milestone
|
|
648
650
|
const v20 = project.roadmap?.milestones?.find(m => m.id.includes('2.0'));
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
651
|
+
assertTrue(v20 !== undefined, 'ms roadmap: v2.0 milestone found');
|
|
652
|
+
assertEq(v20?.collapsed, true, 'ms roadmap: v2.0 is collapsed');
|
|
653
|
+
assertTrue((v20?.phases?.length ?? 0) >= 2, 'ms roadmap: v2.0 has phases');
|
|
654
|
+
assertTrue(v20?.phases?.every(p => p.done) ?? false, 'ms roadmap: v2.0 phases all done');
|
|
653
655
|
|
|
654
656
|
// Check active milestone
|
|
655
657
|
const v25 = project.roadmap?.milestones?.find(m => m.id.includes('2.5'));
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
658
|
+
assertTrue(v25 !== undefined, 'ms roadmap: v2.5 milestone found');
|
|
659
|
+
assertEq(v25?.collapsed, false, 'ms roadmap: v2.5 is not collapsed');
|
|
660
|
+
assertTrue((v25?.phases?.length ?? 0) >= 3, 'ms roadmap: v2.5 has phases');
|
|
659
661
|
|
|
660
662
|
// Check completion state
|
|
661
663
|
const phase29 = v25?.phases?.find(p => p.number === 29);
|
|
662
|
-
|
|
664
|
+
assertTrue(phase29?.done === true, 'ms roadmap: phase 29 is done');
|
|
663
665
|
const phase30 = v25?.phases?.find(p => p.number === 30);
|
|
664
|
-
|
|
666
|
+
assertTrue(phase30?.done === false, 'ms roadmap: phase 30 is not done');
|
|
665
667
|
} finally {
|
|
666
668
|
cleanup(base);
|
|
667
669
|
}
|
|
668
|
-
}
|
|
670
|
+
}
|
|
669
671
|
|
|
670
672
|
// ─── Test 11: Non-standard phase files → extra files ──────────────────
|
|
671
|
-
|
|
672
|
-
|
|
673
|
+
console.log('\n=== Non-standard phase files → collected as extra files ===');
|
|
674
|
+
{
|
|
673
675
|
const base = createFixtureBase();
|
|
674
676
|
try {
|
|
675
677
|
const planning = createPlanningDir(base);
|
|
@@ -685,28 +687,28 @@ test('Non-standard phase files → collected as extra files', async () => {
|
|
|
685
687
|
const project = await parsePlanningDirectory(planning);
|
|
686
688
|
const phase = project.phases['36-attachment-system'];
|
|
687
689
|
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
690
|
+
assertTrue(phase !== undefined, 'extra: phase exists');
|
|
691
|
+
assertTrue((phase?.extraFiles?.length ?? 0) >= 3, 'extra: non-standard files collected');
|
|
692
|
+
assertTrue(
|
|
691
693
|
phase?.extraFiles?.some(f => f.fileName === 'BASELINE.md') ?? false,
|
|
692
694
|
'extra: BASELINE.md collected'
|
|
693
695
|
);
|
|
694
|
-
|
|
696
|
+
assertTrue(
|
|
695
697
|
phase?.extraFiles?.some(f => f.fileName === 'BUNDLE-ANALYSIS.md') ?? false,
|
|
696
698
|
'extra: BUNDLE-ANALYSIS.md collected'
|
|
697
699
|
);
|
|
698
|
-
|
|
700
|
+
assertTrue(
|
|
699
701
|
phase?.extraFiles?.some(f => f.fileName === 'depcheck-results.txt') ?? false,
|
|
700
702
|
'extra: depcheck-results.txt collected'
|
|
701
703
|
);
|
|
702
704
|
} finally {
|
|
703
705
|
cleanup(base);
|
|
704
706
|
}
|
|
705
|
-
}
|
|
707
|
+
}
|
|
706
708
|
|
|
707
709
|
// ─── Test 12: Validation — missing ROADMAP.md → warning (not fatal) ───
|
|
708
|
-
|
|
709
|
-
|
|
710
|
+
console.log('\n=== Validation: missing ROADMAP.md → warning (not fatal) ===');
|
|
711
|
+
{
|
|
710
712
|
const base = createFixtureBase();
|
|
711
713
|
try {
|
|
712
714
|
const planning = createPlanningDir(base);
|
|
@@ -715,19 +717,19 @@ test('Validation: missing ROADMAP.md → warning (not fatal)', async () => {
|
|
|
715
717
|
|
|
716
718
|
const result = await validatePlanningDirectory(planning);
|
|
717
719
|
|
|
718
|
-
|
|
719
|
-
|
|
720
|
+
assertEq(result.valid, true, 'no roadmap: validation still passes');
|
|
721
|
+
assertTrue(
|
|
720
722
|
result.issues.some(i => i.severity === 'warning' && i.file.includes('ROADMAP')),
|
|
721
723
|
'no roadmap: warning issue mentions ROADMAP'
|
|
722
724
|
);
|
|
723
725
|
} finally {
|
|
724
726
|
cleanup(base);
|
|
725
727
|
}
|
|
726
|
-
}
|
|
728
|
+
}
|
|
727
729
|
|
|
728
730
|
// ─── Test 13: Validation — missing PROJECT.md → warning ───────────────
|
|
729
|
-
|
|
730
|
-
|
|
731
|
+
console.log('\n=== Validation: missing PROJECT.md → warning ===');
|
|
732
|
+
{
|
|
731
733
|
const base = createFixtureBase();
|
|
732
734
|
try {
|
|
733
735
|
const planning = createPlanningDir(base);
|
|
@@ -736,13 +738,20 @@ test('Validation: missing PROJECT.md → warning', async () => {
|
|
|
736
738
|
|
|
737
739
|
const result = await validatePlanningDirectory(planning);
|
|
738
740
|
|
|
739
|
-
|
|
740
|
-
|
|
741
|
+
assertEq(result.valid, true, 'no project: validation passes (warning only)');
|
|
742
|
+
assertTrue(
|
|
741
743
|
result.issues.some(i => i.severity === 'warning' && i.file.includes('PROJECT')),
|
|
742
744
|
'no project: warning issue mentions PROJECT'
|
|
743
745
|
);
|
|
744
746
|
} finally {
|
|
745
747
|
cleanup(base);
|
|
746
748
|
}
|
|
747
|
-
}
|
|
749
|
+
}
|
|
748
750
|
|
|
751
|
+
report();
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
main().catch((error) => {
|
|
755
|
+
console.error(error);
|
|
756
|
+
process.exit(1);
|
|
757
|
+
});
|