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
|
@@ -19,9 +19,9 @@ import type {
|
|
|
19
19
|
GSDSlice,
|
|
20
20
|
GSDTask,
|
|
21
21
|
} from '../migrate/types.ts';
|
|
22
|
-
import {
|
|
23
|
-
import assert from 'node:assert/strict';
|
|
22
|
+
import { createTestContext } from './test-helpers.ts';
|
|
24
23
|
|
|
24
|
+
const { assertEq, assertTrue, report } = createTestContext();
|
|
25
25
|
// ─── Fixture Helpers ───────────────────────────────────────────────────────
|
|
26
26
|
|
|
27
27
|
function emptyProject(overrides: Partial<PlanningProject> = {}): PlanningProject {
|
|
@@ -134,7 +134,8 @@ function makeResearch(fileName: string, content: string): PlanningResearch {
|
|
|
134
134
|
|
|
135
135
|
// ─── Scenario 1: Flat Single-Milestone (3 phases → M001 with S01/S02/S03) ──
|
|
136
136
|
|
|
137
|
-
|
|
137
|
+
{
|
|
138
|
+
console.log('Scenario 1: Flat single-milestone');
|
|
138
139
|
|
|
139
140
|
const project = emptyProject({
|
|
140
141
|
project: '# My Project\nA cool project.',
|
|
@@ -158,25 +159,26 @@ test('Scenario 1: Flat single-milestone', () => {
|
|
|
158
159
|
|
|
159
160
|
const result = transformToGSD(project);
|
|
160
161
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}
|
|
162
|
+
assertEq(result.milestones.length, 1, 'flat: produces 1 milestone');
|
|
163
|
+
assertTrue(result.milestones[0]?.id === 'M001', 'flat: milestone ID is M001');
|
|
164
|
+
assertEq(result.milestones[0]?.slices.length, 3, 'flat: 3 slices');
|
|
165
|
+
assertEq(result.milestones[0]?.slices[0]?.id, 'S01', 'flat: first slice is S01');
|
|
166
|
+
assertEq(result.milestones[0]?.slices[1]?.id, 'S02', 'flat: second slice is S02');
|
|
167
|
+
assertEq(result.milestones[0]?.slices[2]?.id, 'S03', 'flat: third slice is S03');
|
|
168
|
+
assertTrue(result.milestones[0]?.slices[0]?.title.length > 0, 'flat: slice title not empty');
|
|
169
|
+
assertEq(result.milestones[0]?.slices[0]?.tasks.length, 1, 'flat: S01 has 1 task');
|
|
170
|
+
assertEq(result.milestones[0]?.slices[1]?.tasks.length, 2, 'flat: S02 has 2 tasks');
|
|
171
|
+
assertEq(result.milestones[0]?.slices[2]?.tasks.length, 1, 'flat: S03 has 1 task');
|
|
172
|
+
assertEq(result.milestones[0]?.slices[0]?.tasks[0]?.id, 'T01', 'flat: first task is T01');
|
|
173
|
+
assertEq(result.milestones[0]?.slices[1]?.tasks[1]?.id, 'T02', 'flat: second task in S02 is T02');
|
|
174
|
+
assertTrue(result.projectContent.includes('My Project'), 'flat: projectContent preserved');
|
|
175
|
+
assertEq(result.milestones[0]?.boundaryMap, [], 'flat: boundaryMap defaults to empty');
|
|
176
|
+
}
|
|
176
177
|
|
|
177
178
|
// ─── Scenario 2: Multi-Milestone (2 milestones with independent numbering) ──
|
|
178
179
|
|
|
179
|
-
|
|
180
|
+
{
|
|
181
|
+
console.log('Scenario 2: Multi-milestone');
|
|
180
182
|
|
|
181
183
|
const project = emptyProject({
|
|
182
184
|
roadmap: milestoneRoadmap([
|
|
@@ -204,22 +206,23 @@ test('Scenario 2: Multi-milestone', () => {
|
|
|
204
206
|
|
|
205
207
|
const result = transformToGSD(project);
|
|
206
208
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
209
|
+
assertEq(result.milestones.length, 2, 'multi: 2 milestones');
|
|
210
|
+
assertEq(result.milestones[0]?.id, 'M001', 'multi: first milestone M001');
|
|
211
|
+
assertEq(result.milestones[1]?.id, 'M002', 'multi: second milestone M002');
|
|
212
|
+
assertEq(result.milestones[0]?.slices.length, 2, 'multi: M001 has 2 slices');
|
|
213
|
+
assertEq(result.milestones[1]?.slices.length, 3, 'multi: M002 has 3 slices');
|
|
212
214
|
// Independent numbering: both start at S01
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
}
|
|
215
|
+
assertEq(result.milestones[0]?.slices[0]?.id, 'S01', 'multi: M001 starts at S01');
|
|
216
|
+
assertEq(result.milestones[1]?.slices[0]?.id, 'S01', 'multi: M002 starts at S01');
|
|
217
|
+
assertEq(result.milestones[1]?.slices[2]?.id, 'S03', 'multi: M002 third slice is S03');
|
|
218
|
+
assertTrue(result.milestones[0]?.title.length > 0, 'multi: M001 has title');
|
|
219
|
+
assertTrue(result.milestones[1]?.title.length > 0, 'multi: M002 has title');
|
|
220
|
+
}
|
|
219
221
|
|
|
220
222
|
// ─── Scenario 3: Decimal Phase Ordering (1, 2, 2.1, 2.2, 3 → S01–S05) ──
|
|
221
223
|
|
|
222
|
-
|
|
224
|
+
{
|
|
225
|
+
console.log('Scenario 3: Decimal phase ordering');
|
|
223
226
|
|
|
224
227
|
const project = emptyProject({
|
|
225
228
|
roadmap: flatRoadmap([
|
|
@@ -240,26 +243,27 @@ test('Scenario 3: Decimal phase ordering', () => {
|
|
|
240
243
|
|
|
241
244
|
const result = transformToGSD(project);
|
|
242
245
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
246
|
+
assertEq(result.milestones[0]?.slices.length, 5, 'decimal: 5 slices total');
|
|
247
|
+
assertEq(result.milestones[0]?.slices[0]?.id, 'S01', 'decimal: first is S01');
|
|
248
|
+
assertEq(result.milestones[0]?.slices[1]?.id, 'S02', 'decimal: second is S02');
|
|
249
|
+
assertEq(result.milestones[0]?.slices[2]?.id, 'S03', 'decimal: third is S03');
|
|
250
|
+
assertEq(result.milestones[0]?.slices[3]?.id, 'S04', 'decimal: fourth is S04');
|
|
251
|
+
assertEq(result.milestones[0]?.slices[4]?.id, 'S05', 'decimal: fifth is S05');
|
|
249
252
|
// Order must be by float value: 1, 2, 2.1, 2.2, 3
|
|
250
|
-
|
|
253
|
+
assertTrue(
|
|
251
254
|
result.milestones[0]?.slices[0]?.title.toLowerCase().includes('foundation'),
|
|
252
255
|
'decimal: S01 is foundation (phase 1)',
|
|
253
256
|
);
|
|
254
|
-
|
|
257
|
+
assertTrue(
|
|
255
258
|
result.milestones[0]?.slices[4]?.title.toLowerCase().includes('finalize'),
|
|
256
259
|
'decimal: S05 is finalize (phase 3)',
|
|
257
260
|
);
|
|
258
|
-
}
|
|
261
|
+
}
|
|
259
262
|
|
|
260
263
|
// ─── Scenario 4: Completion State ──────────────────────────────────────────
|
|
261
264
|
|
|
262
|
-
|
|
265
|
+
{
|
|
266
|
+
console.log('Scenario 4: Completion state mapping');
|
|
263
267
|
|
|
264
268
|
const project = emptyProject({
|
|
265
269
|
roadmap: flatRoadmap([
|
|
@@ -284,25 +288,26 @@ test('Scenario 4: Completion state mapping', () => {
|
|
|
284
288
|
const doneSlice = result.milestones[0]?.slices[0];
|
|
285
289
|
const activeSlice = result.milestones[0]?.slices[1];
|
|
286
290
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
}
|
|
291
|
+
assertTrue(doneSlice?.done === true, 'completion: done phase → done slice');
|
|
292
|
+
assertTrue(activeSlice?.done === false, 'completion: active phase → not-done slice');
|
|
293
|
+
assertTrue(doneSlice?.tasks[0]?.done === true, 'completion: plan with summary → done task');
|
|
294
|
+
assertTrue(doneSlice?.tasks[1]?.done === false, 'completion: plan without summary → not-done task');
|
|
295
|
+
assertTrue(doneSlice?.tasks[0]?.summary !== null, 'completion: done task has summary data');
|
|
296
|
+
assertTrue(doneSlice?.tasks[1]?.summary === null, 'completion: not-done task has null summary');
|
|
297
|
+
assertEq(doneSlice?.tasks[0]?.summary?.completedAt, '2026-01-15', 'completion: summary completedAt from frontmatter');
|
|
298
|
+
assertEq(doneSlice?.tasks[0]?.summary?.duration, '2h', 'completion: summary duration from frontmatter');
|
|
299
|
+
assertEq(doneSlice?.tasks[0]?.summary?.provides, ['feature-01'], 'completion: summary provides from frontmatter');
|
|
300
|
+
assertEq(doneSlice?.tasks[0]?.summary?.keyFiles, ['file-01.ts'], 'completion: summary keyFiles from frontmatter');
|
|
301
|
+
assertTrue(doneSlice?.tasks[0]?.summary?.whatHappened?.includes('Summary body') ?? false, 'completion: summary whatHappened from body');
|
|
302
|
+
assertTrue(doneSlice?.summary !== null, 'completion: done slice has slice summary');
|
|
303
|
+
assertTrue(activeSlice?.summary === null, 'completion: active slice has null summary');
|
|
304
|
+
assertEq(doneSlice?.tasks[0]?.estimate, '2h', 'completion: task estimate from summary duration');
|
|
305
|
+
}
|
|
302
306
|
|
|
303
307
|
// ─── Scenario 5: Research Consolidation ────────────────────────────────────
|
|
304
308
|
|
|
305
|
-
|
|
309
|
+
{
|
|
310
|
+
console.log('Scenario 5: Research consolidation');
|
|
306
311
|
|
|
307
312
|
const project = emptyProject({
|
|
308
313
|
roadmap: flatRoadmap([roadmapEntry(1, 'researched-phase')]),
|
|
@@ -323,27 +328,28 @@ test('Scenario 5: Research consolidation', () => {
|
|
|
323
328
|
const result = transformToGSD(project);
|
|
324
329
|
|
|
325
330
|
// Project-level research → milestone research
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
331
|
+
assertTrue(result.milestones[0]?.research !== null, 'research: milestone has consolidated research');
|
|
332
|
+
assertTrue(result.milestones[0]?.research!.includes('Project Summary'), 'research: includes SUMMARY content');
|
|
333
|
+
assertTrue(result.milestones[0]?.research!.includes('Architecture'), 'research: includes ARCHITECTURE content');
|
|
334
|
+
assertTrue(result.milestones[0]?.research!.includes('Pitfalls'), 'research: includes PITFALLS content');
|
|
330
335
|
|
|
331
336
|
// Fixed ordering: SUMMARY before ARCHITECTURE before PITFALLS
|
|
332
337
|
const summaryIdx = result.milestones[0]?.research!.indexOf('Project Summary') ?? -1;
|
|
333
338
|
const archIdx = result.milestones[0]?.research!.indexOf('Architecture') ?? -1;
|
|
334
339
|
const pitfallIdx = result.milestones[0]?.research!.indexOf('Pitfalls') ?? -1;
|
|
335
|
-
|
|
336
|
-
|
|
340
|
+
assertTrue(summaryIdx < archIdx, 'research: SUMMARY before ARCHITECTURE in consolidated');
|
|
341
|
+
assertTrue(archIdx < pitfallIdx, 'research: ARCHITECTURE before PITFALLS in consolidated');
|
|
337
342
|
|
|
338
343
|
// Phase-level research → slice research
|
|
339
344
|
const slice = result.milestones[0]?.slices[0];
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
}
|
|
345
|
+
assertTrue(slice?.research !== null, 'research: slice has phase research');
|
|
346
|
+
assertTrue(slice?.research!.includes('Phase Features'), 'research: slice research includes phase content');
|
|
347
|
+
}
|
|
343
348
|
|
|
344
349
|
// ─── Scenario 6: Requirements Classification ──────────────────────────────
|
|
345
350
|
|
|
346
|
-
|
|
351
|
+
{
|
|
352
|
+
console.log('Scenario 6: Requirements classification');
|
|
347
353
|
|
|
348
354
|
const project = emptyProject({
|
|
349
355
|
roadmap: flatRoadmap([roadmapEntry(1, 'req-phase')]),
|
|
@@ -359,21 +365,22 @@ test('Scenario 6: Requirements classification', () => {
|
|
|
359
365
|
|
|
360
366
|
const result = transformToGSD(project);
|
|
361
367
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
}
|
|
368
|
+
assertEq(result.requirements.length, 3, 'requirements: 3 requirements');
|
|
369
|
+
assertEq(result.requirements[0]?.id, 'R001', 'requirements: first is R001');
|
|
370
|
+
assertEq(result.requirements[0]?.status, 'active', 'requirements: R001 status active');
|
|
371
|
+
assertEq(result.requirements[1]?.status, 'validated', 'requirements: R002 status validated');
|
|
372
|
+
assertEq(result.requirements[2]?.status, 'deferred', 'requirements: R003 status deferred');
|
|
373
|
+
assertTrue(result.requirements[0]?.title === 'Core Feature', 'requirements: R001 title preserved');
|
|
374
|
+
assertTrue(result.requirements[0]?.description.includes('Description for R001'), 'requirements: R001 description preserved');
|
|
375
|
+
assertEq(result.requirements[0]?.class, 'core-capability', 'requirements: default class');
|
|
376
|
+
assertEq(result.requirements[0]?.source, 'inferred', 'requirements: default source');
|
|
377
|
+
assertEq(result.requirements[0]?.primarySlice, 'none yet', 'requirements: default primarySlice');
|
|
378
|
+
}
|
|
373
379
|
|
|
374
380
|
// ─── Scenario 7: Empty Phase (no plans → slice with 0 tasks) ───────────────
|
|
375
381
|
|
|
376
|
-
|
|
382
|
+
{
|
|
383
|
+
console.log('Scenario 7: Empty phase');
|
|
377
384
|
|
|
378
385
|
const project = emptyProject({
|
|
379
386
|
roadmap: flatRoadmap([
|
|
@@ -390,14 +397,15 @@ test('Scenario 7: Empty phase', () => {
|
|
|
390
397
|
|
|
391
398
|
const result = transformToGSD(project);
|
|
392
399
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
}
|
|
400
|
+
assertEq(result.milestones[0]?.slices[0]?.tasks.length, 0, 'empty: empty phase → 0 tasks');
|
|
401
|
+
assertEq(result.milestones[0]?.slices[1]?.tasks.length, 1, 'empty: non-empty phase → 1 task');
|
|
402
|
+
assertTrue(result.milestones[0]?.slices[0]?.id === 'S01', 'empty: empty slice still gets ID');
|
|
403
|
+
}
|
|
397
404
|
|
|
398
405
|
// ─── Scenario 8: Demo Derivation from Plan Objective ───────────────────────
|
|
399
406
|
|
|
400
|
-
|
|
407
|
+
{
|
|
408
|
+
console.log('Scenario 8: Demo derivation');
|
|
401
409
|
|
|
402
410
|
const project = emptyProject({
|
|
403
411
|
roadmap: flatRoadmap([roadmapEntry(1, 'demo-phase')]),
|
|
@@ -412,18 +420,19 @@ test('Scenario 8: Demo derivation', () => {
|
|
|
412
420
|
|
|
413
421
|
const result = transformToGSD(project);
|
|
414
422
|
|
|
415
|
-
|
|
416
|
-
|
|
423
|
+
assertTrue(result.milestones[0]?.slices[0]?.demo.length > 0, 'demo: slice demo is not empty');
|
|
424
|
+
assertTrue(
|
|
417
425
|
result.milestones[0]?.slices[0]?.demo.includes('authentication') ||
|
|
418
426
|
result.milestones[0]?.slices[0]?.demo.includes('Build'),
|
|
419
427
|
'demo: slice demo derived from first plan objective',
|
|
420
428
|
);
|
|
421
|
-
|
|
422
|
-
}
|
|
429
|
+
assertTrue(result.milestones[0]?.slices[0]?.goal.length > 0, 'demo: slice goal is not empty');
|
|
430
|
+
}
|
|
423
431
|
|
|
424
432
|
// ─── Scenario 9: Field Defaults and Type Safety ────────────────────────────
|
|
425
433
|
|
|
426
|
-
|
|
434
|
+
{
|
|
435
|
+
console.log('Scenario 9: Field defaults');
|
|
427
436
|
|
|
428
437
|
const project = emptyProject({
|
|
429
438
|
roadmap: flatRoadmap([roadmapEntry(1, 'defaults-phase')]),
|
|
@@ -451,19 +460,20 @@ test('Scenario 9: Field defaults', () => {
|
|
|
451
460
|
const slice = result.milestones[0]?.slices[0];
|
|
452
461
|
const task = slice?.tasks[0];
|
|
453
462
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
}
|
|
463
|
+
assertEq(slice?.risk, 'medium', 'defaults: slice risk defaults to medium');
|
|
464
|
+
assertEq(slice?.depends, [], 'defaults: S01 has no depends');
|
|
465
|
+
assertTrue(task?.description.length > 0, 'defaults: task description not empty');
|
|
466
|
+
assertEq(task?.files, ['src/auth.ts', 'src/db.ts'], 'defaults: task files from frontmatter');
|
|
467
|
+
assertEq(task?.mustHaves, ['Auth works', 'DB connected'], 'defaults: task mustHaves from frontmatter');
|
|
468
|
+
assertEq(task?.done, false, 'defaults: task without summary is not done');
|
|
469
|
+
assertEq(task?.estimate, '', 'defaults: task without summary has empty estimate');
|
|
470
|
+
assertTrue(task?.summary === null, 'defaults: task without summary has null summary');
|
|
471
|
+
}
|
|
463
472
|
|
|
464
473
|
// ─── Scenario 10: Sequential Depends ──────────────────────────────────────
|
|
465
474
|
|
|
466
|
-
|
|
475
|
+
{
|
|
476
|
+
console.log('Scenario 10: Sequential depends');
|
|
467
477
|
|
|
468
478
|
const project = emptyProject({
|
|
469
479
|
roadmap: flatRoadmap([
|
|
@@ -481,14 +491,15 @@ test('Scenario 10: Sequential depends', () => {
|
|
|
481
491
|
const result = transformToGSD(project);
|
|
482
492
|
const slices = result.milestones[0]?.slices;
|
|
483
493
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
}
|
|
494
|
+
assertEq(slices?.[0]?.depends, [], 'depends: S01 has empty depends');
|
|
495
|
+
assertEq(slices?.[1]?.depends, ['S01'], 'depends: S02 depends on S01');
|
|
496
|
+
assertEq(slices?.[2]?.depends, ['S02'], 'depends: S03 depends on S02');
|
|
497
|
+
}
|
|
488
498
|
|
|
489
499
|
// ─── Scenario 11: Requirements with unknown status and missing IDs ─────────
|
|
490
500
|
|
|
491
|
-
|
|
501
|
+
{
|
|
502
|
+
console.log('Scenario 11: Requirements edge cases');
|
|
492
503
|
|
|
493
504
|
const project = emptyProject({
|
|
494
505
|
roadmap: flatRoadmap([roadmapEntry(1, 'req-edge')]),
|
|
@@ -505,16 +516,17 @@ test('Scenario 11: Requirements edge cases', () => {
|
|
|
505
516
|
|
|
506
517
|
const result = transformToGSD(project);
|
|
507
518
|
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
}
|
|
519
|
+
assertEq(result.requirements[0]?.id, 'R001', 'req-edge: empty id gets R001');
|
|
520
|
+
assertEq(result.requirements[1]?.id, 'R002', 'req-edge: second empty id gets R002');
|
|
521
|
+
assertEq(result.requirements[2]?.id, 'R005', 'req-edge: existing id preserved');
|
|
522
|
+
assertEq(result.requirements[2]?.status, 'active', 'req-edge: unknown status normalized to active');
|
|
523
|
+
assertEq(result.requirements[3]?.status, 'deferred', 'req-edge: uppercase DEFERRED normalized');
|
|
524
|
+
}
|
|
514
525
|
|
|
515
526
|
// ─── Scenario 12: Vision derivation ────────────────────────────────────────
|
|
516
527
|
|
|
517
|
-
|
|
528
|
+
{
|
|
529
|
+
console.log('Scenario 12: Vision derivation');
|
|
518
530
|
|
|
519
531
|
// Vision from project description
|
|
520
532
|
const project1 = emptyProject({
|
|
@@ -524,7 +536,7 @@ test('Scenario 12: Vision derivation', () => {
|
|
|
524
536
|
});
|
|
525
537
|
|
|
526
538
|
const result1 = transformToGSD(project1);
|
|
527
|
-
|
|
539
|
+
assertTrue(result1.milestones[0]?.vision.includes('revolutionary'), 'vision: derived from project first line');
|
|
528
540
|
|
|
529
541
|
// Vision fallback when no project
|
|
530
542
|
const project2 = emptyProject({
|
|
@@ -533,12 +545,13 @@ test('Scenario 12: Vision derivation', () => {
|
|
|
533
545
|
});
|
|
534
546
|
|
|
535
547
|
const result2 = transformToGSD(project2);
|
|
536
|
-
|
|
537
|
-
}
|
|
548
|
+
assertTrue(result2.milestones[0]?.vision.length > 0, 'vision: fallback is non-empty');
|
|
549
|
+
}
|
|
538
550
|
|
|
539
551
|
// ─── Scenario 13: Decisions content from summaries ─────────────────────────
|
|
540
552
|
|
|
541
|
-
|
|
553
|
+
{
|
|
554
|
+
console.log('Scenario 13: Decisions content');
|
|
542
555
|
|
|
543
556
|
const project = emptyProject({
|
|
544
557
|
roadmap: flatRoadmap([roadmapEntry(1, 'decision-phase', true)]),
|
|
@@ -552,12 +565,13 @@ test('Scenario 13: Decisions content', () => {
|
|
|
552
565
|
|
|
553
566
|
const result = transformToGSD(project);
|
|
554
567
|
|
|
555
|
-
|
|
556
|
-
}
|
|
568
|
+
assertTrue(result.decisionsContent.includes('decision-01'), 'decisions: extracts key-decisions from summaries');
|
|
569
|
+
}
|
|
557
570
|
|
|
558
571
|
// ─── Scenario 14: No undefined values in output ───────────────────────────
|
|
559
572
|
|
|
560
|
-
|
|
573
|
+
{
|
|
574
|
+
console.log('Scenario 14: No undefined values');
|
|
561
575
|
|
|
562
576
|
const project = emptyProject({
|
|
563
577
|
project: '# Test\nDescription.',
|
|
@@ -582,7 +596,7 @@ test('Scenario 14: No undefined values', () => {
|
|
|
582
596
|
// Deep check for undefined values
|
|
583
597
|
function checkNoUndefined(obj: unknown, path: string): void {
|
|
584
598
|
if (obj === undefined) {
|
|
585
|
-
|
|
599
|
+
assertTrue(false, `no-undefined: ${path} is undefined`);
|
|
586
600
|
return;
|
|
587
601
|
}
|
|
588
602
|
if (obj === null) return; // null is allowed (e.g. research, summary)
|
|
@@ -598,12 +612,13 @@ test('Scenario 14: No undefined values', () => {
|
|
|
598
612
|
}
|
|
599
613
|
|
|
600
614
|
checkNoUndefined(result, 'result');
|
|
601
|
-
|
|
602
|
-
}
|
|
615
|
+
assertTrue(true, 'no-undefined: deep check completed without finding undefined values');
|
|
616
|
+
}
|
|
603
617
|
|
|
604
618
|
// ─── Scenario 15: Research with no files ───────────────────────────────────
|
|
605
619
|
|
|
606
|
-
|
|
620
|
+
{
|
|
621
|
+
console.log('Scenario 15: Empty research');
|
|
607
622
|
|
|
608
623
|
const project = emptyProject({
|
|
609
624
|
roadmap: flatRoadmap([roadmapEntry(1, 'no-research')]),
|
|
@@ -611,9 +626,10 @@ test('Scenario 15: Empty research', () => {
|
|
|
611
626
|
});
|
|
612
627
|
|
|
613
628
|
const result = transformToGSD(project);
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
}
|
|
629
|
+
assertTrue(result.milestones[0]?.research === null, 'empty-research: milestone research is null');
|
|
630
|
+
assertTrue(result.milestones[0]?.slices[0]?.research === null, 'empty-research: slice research is null');
|
|
631
|
+
}
|
|
617
632
|
|
|
618
633
|
// ─── Results ───────────────────────────────────────────────────────────────
|
|
619
634
|
|
|
635
|
+
report();
|