gsd-pi 2.44.0-dev.848dd4c → 2.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -30
- package/dist/resources/extensions/gsd/auto-start.js +0 -10
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +0 -5
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +14 -14
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/required-server-files.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +5 -5
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +14 -14
- package/dist/web/standalone/.next/server/chunks/229.js +1 -1
- package/dist/web/standalone/.next/server/chunks/471.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +2 -2
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-f2a7482d42a5614b.js → page-2f24283c162b6ab3.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-a16c7a7ecdf0c2cf.js → layout-9ecfd95f343793f0.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-7e9530a7122506c5.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +1 -0
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js +8 -6
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +26 -24
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/fs-utils.test.js +48 -29
- package/packages/pi-coding-agent/dist/core/fs-utils.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +44 -34
- package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.test.js +34 -30
- package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +12 -10
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js +47 -43
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js.map +1 -1
- package/packages/pi-coding-agent/src/core/auth-storage.test.ts +7 -7
- package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +26 -26
- package/packages/pi-coding-agent/src/core/fs-utils.test.ts +43 -31
- package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +45 -40
- package/packages/pi-coding-agent/src/core/session-manager.test.ts +33 -33
- package/packages/pi-coding-agent/src/core/tools/edit-diff.test.ts +17 -17
- package/packages/pi-coding-agent/src/resources/extensions/memory/storage.test.ts +74 -74
- package/src/resources/extensions/gsd/auto-start.ts +0 -14
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +0 -8
- package/src/resources/extensions/gsd/tests/all-milestones-complete-merge.test.ts +99 -99
- package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +16 -14
- package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +57 -43
- package/src/resources/extensions/gsd/tests/auto-preflight.test.ts +13 -11
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +523 -465
- package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +75 -73
- package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +56 -34
- package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +656 -533
- package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +143 -165
- package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +52 -29
- package/src/resources/extensions/gsd/tests/captures.test.ts +176 -148
- package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +33 -32
- package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +143 -141
- package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +25 -25
- package/src/resources/extensions/gsd/tests/commands-logs.test.ts +81 -81
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +59 -38
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +263 -228
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +302 -250
- package/src/resources/extensions/gsd/tests/context-store.test.ts +367 -354
- package/src/resources/extensions/gsd/tests/continue-here.test.ts +72 -68
- package/src/resources/extensions/gsd/tests/cost-projection.test.ts +106 -92
- package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +35 -27
- package/src/resources/extensions/gsd/tests/dashboard-budget.test.ts +237 -220
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +420 -390
- package/src/resources/extensions/gsd/tests/definition-loader.test.ts +92 -76
- package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +83 -68
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +183 -152
- package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +101 -78
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +227 -192
- package/src/resources/extensions/gsd/tests/detection.test.ts +278 -232
- package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +34 -30
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +180 -164
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +49 -43
- package/src/resources/extensions/gsd/tests/dispatch-uat-last-completed.test.ts +32 -28
- package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +29 -27
- package/src/resources/extensions/gsd/tests/doctor-delimiter-fix.test.ts +38 -34
- package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +75 -54
- package/src/resources/extensions/gsd/tests/doctor-environment-worktree.test.ts +32 -21
- package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +97 -72
- package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +44 -38
- package/src/resources/extensions/gsd/tests/doctor-git.test.ts +145 -104
- package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +106 -84
- package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +60 -54
- package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +93 -72
- package/src/resources/extensions/gsd/tests/doctor.test.ts +134 -104
- package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +131 -123
- package/src/resources/extensions/gsd/tests/exit-command.test.ts +24 -20
- package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +57 -48
- package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +7 -5
- package/src/resources/extensions/gsd/tests/flag-file-db.test.ts +42 -30
- package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +206 -198
- package/src/resources/extensions/gsd/tests/git-locale.test.ts +27 -13
- package/src/resources/extensions/gsd/tests/git-service.test.ts +388 -285
- package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +39 -31
- package/src/resources/extensions/gsd/tests/graph-operations.test.ts +69 -63
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +264 -255
- package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +119 -108
- package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +103 -81
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +262 -229
- package/src/resources/extensions/gsd/tests/headless-answers.test.ts +13 -13
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +37 -29
- package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +102 -81
- package/src/resources/extensions/gsd/tests/init-wizard.test.ts +18 -16
- package/src/resources/extensions/gsd/tests/integration-edge.test.ts +46 -41
- package/src/resources/extensions/gsd/tests/integration-lifecycle.test.ts +53 -42
- package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +91 -75
- package/src/resources/extensions/gsd/tests/integration-proof.test.ts +18 -18
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +194 -150
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +125 -101
- package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +54 -45
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +93 -80
- package/src/resources/extensions/gsd/tests/migrate-command.test.ts +66 -57
- package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +93 -83
- package/src/resources/extensions/gsd/tests/migrate-parser.test.ts +170 -161
- package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +141 -125
- package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +131 -107
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +96 -87
- package/src/resources/extensions/gsd/tests/migrate-writer.test.ts +164 -125
- package/src/resources/extensions/gsd/tests/must-have-parser.test.ts +94 -81
- package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +36 -35
- package/src/resources/extensions/gsd/tests/overrides.test.ts +106 -99
- package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +47 -40
- package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +28 -25
- package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +83 -66
- package/src/resources/extensions/gsd/tests/park-edge-cases.test.ts +77 -54
- package/src/resources/extensions/gsd/tests/park-milestone.test.ts +115 -68
- package/src/resources/extensions/gsd/tests/parsers.test.ts +611 -546
- package/src/resources/extensions/gsd/tests/paths.test.ts +87 -72
- package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +117 -77
- package/src/resources/extensions/gsd/tests/prompt-db.test.ts +56 -56
- package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +119 -93
- package/src/resources/extensions/gsd/tests/queue-order.test.ts +82 -70
- package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +55 -42
- package/src/resources/extensions/gsd/tests/quick-branch-lifecycle.test.ts +73 -45
- package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +38 -28
- package/src/resources/extensions/gsd/tests/replan-slice.test.ts +80 -73
- package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +74 -71
- package/src/resources/extensions/gsd/tests/requirements.test.ts +75 -70
- package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +66 -44
- package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +181 -114
- package/src/resources/extensions/gsd/tests/rule-registry.test.ts +65 -63
- package/src/resources/extensions/gsd/tests/run-uat.test.ts +128 -66
- package/src/resources/extensions/gsd/tests/session-lock-multipath.test.ts +25 -18
- package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +44 -37
- package/src/resources/extensions/gsd/tests/shared-wal.test.ts +26 -19
- package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +8 -6
- package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +28 -22
- package/src/resources/extensions/gsd/tests/token-savings.test.ts +56 -54
- package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +25 -23
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +11 -9
- package/src/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +82 -66
- package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +47 -46
- package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +22 -20
- package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +86 -84
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +43 -41
- package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +96 -94
- package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +13 -11
- package/src/resources/extensions/gsd/tests/worker-registry.test.ts +29 -27
- package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +52 -50
- package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +13 -10
- package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +18 -14
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +39 -38
- package/src/resources/extensions/gsd/tests/worktree-e2e.test.ts +21 -17
- package/src/resources/extensions/gsd/tests/worktree-health.test.ts +30 -25
- package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +37 -30
- package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +22 -15
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +66 -59
- package/src/resources/extensions/gsd/tests/worktree.test.ts +50 -44
- package/dist/web/standalone/.next/static/chunks/app/page-b9367c5ae13b99c6.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +0 -1
- package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +0 -100
- package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +0 -63
- /package/dist/web/standalone/.next/static/{-zps1Q9mQmioAKLcQiCr8 → mgkxN0mGP6gSUmGPEzbk_}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{-zps1Q9mQmioAKLcQiCr8 → mgkxN0mGP6gSUmGPEzbk_}/_ssgManifest.js +0 -0
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { after, describe, test } from 'node:test';
|
|
2
|
-
import assert from 'node:assert/strict';
|
|
3
1
|
import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync, existsSync } from "node:fs";
|
|
4
2
|
import { join } from "node:path";
|
|
5
3
|
import { tmpdir } from "node:os";
|
|
6
4
|
|
|
7
5
|
import { formatDoctorReport, runGSDDoctor, summarizeDoctorIssues, filterDoctorIssues, selectDoctorScope, validateTitle } from "../doctor.js";
|
|
6
|
+
import { createTestContext } from './test-helpers.ts';
|
|
7
|
+
|
|
8
|
+
const { assertEq, assertTrue, report } = createTestContext();
|
|
8
9
|
const tmpBase = mkdtempSync(join(tmpdir(), "gsd-doctor-test-"));
|
|
9
10
|
const gsd = join(tmpBase, ".gsd");
|
|
10
11
|
const mDir = join(gsd, "milestones", "M001");
|
|
@@ -60,41 +61,46 @@ Implemented.
|
|
|
60
61
|
- log
|
|
61
62
|
`);
|
|
62
63
|
|
|
63
|
-
|
|
64
|
-
|
|
64
|
+
async function main(): Promise<void> {
|
|
65
|
+
console.log("\n=== doctor diagnose ===");
|
|
66
|
+
{
|
|
65
67
|
const report = await runGSDDoctor(tmpBase, { fix: false });
|
|
66
68
|
// Reconciliation issue codes have been removed — doctor should NOT report them
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
69
|
+
assertTrue(!report.issues.some(issue => issue.code === "all_tasks_done_missing_slice_summary" as any), "does not report removed code all_tasks_done_missing_slice_summary");
|
|
70
|
+
assertTrue(!report.issues.some(issue => issue.code === "all_tasks_done_missing_slice_uat" as any), "does not report removed code all_tasks_done_missing_slice_uat");
|
|
71
|
+
assertTrue(!report.issues.some(issue => issue.code === "all_tasks_done_roadmap_not_checked" as any), "does not report removed code all_tasks_done_roadmap_not_checked");
|
|
72
|
+
}
|
|
71
73
|
|
|
72
|
-
|
|
74
|
+
console.log("\n=== doctor formatting ===");
|
|
75
|
+
{
|
|
73
76
|
const report = await runGSDDoctor(tmpBase, { fix: false });
|
|
74
77
|
const summary = summarizeDoctorIssues(report.issues);
|
|
75
78
|
const scoped = filterDoctorIssues(report.issues, { scope: "M001/S01", includeWarnings: true });
|
|
76
79
|
const text = formatDoctorReport(report, { scope: "M001/S01", includeWarnings: true, maxIssues: 5 });
|
|
77
|
-
|
|
78
|
-
}
|
|
80
|
+
assertTrue(text.includes("Scope: M001/S01"), "formatted report shows scope");
|
|
81
|
+
}
|
|
79
82
|
|
|
80
|
-
|
|
83
|
+
console.log("\n=== doctor default scope ===");
|
|
84
|
+
{
|
|
81
85
|
const scope = await selectDoctorScope(tmpBase);
|
|
82
|
-
|
|
83
|
-
}
|
|
86
|
+
assertEq(scope, "M001/S01", "default doctor scope targets the active slice");
|
|
87
|
+
}
|
|
84
88
|
|
|
85
|
-
|
|
89
|
+
console.log("\n=== doctor fix ===");
|
|
90
|
+
{
|
|
86
91
|
const report = await runGSDDoctor(tmpBase, { fix: true });
|
|
87
92
|
// With reconciliation removed, doctor no longer creates placeholder summaries,
|
|
88
93
|
// UAT files, or marks checkboxes. It only applies infrastructure fixes.
|
|
89
94
|
// The task checkbox marking (task_summary_without_done_checkbox) is also removed.
|
|
90
95
|
// Just verify it doesn't crash and produces a report.
|
|
91
|
-
|
|
92
|
-
}
|
|
96
|
+
assertTrue(report.issues !== undefined, "doctor produces a report with issues array");
|
|
97
|
+
}
|
|
93
98
|
|
|
94
|
-
|
|
99
|
+
rmSync(tmpBase, { recursive: true, force: true });
|
|
95
100
|
|
|
96
101
|
// ─── Milestone summary detection: missing summary ──────────────────────
|
|
97
|
-
|
|
102
|
+
console.log("\n=== doctor detects missing milestone summary ===");
|
|
103
|
+
{
|
|
98
104
|
const msBase = mkdtempSync(join(tmpdir(), "gsd-doctor-ms-test-"));
|
|
99
105
|
const msGsd = join(msBase, ".gsd");
|
|
100
106
|
const msMDir = join(msGsd, "milestones", "M001");
|
|
@@ -147,21 +153,22 @@ parent: M001
|
|
|
147
153
|
// NO milestone summary — this is the condition we're detecting
|
|
148
154
|
|
|
149
155
|
const report = await runGSDDoctor(msBase, { fix: false });
|
|
150
|
-
|
|
156
|
+
assertTrue(
|
|
151
157
|
report.issues.some(issue => issue.code === "all_slices_done_missing_milestone_summary"),
|
|
152
158
|
"detects missing milestone summary when all slices are done"
|
|
153
159
|
);
|
|
154
160
|
const msIssue = report.issues.find(issue => issue.code === "all_slices_done_missing_milestone_summary");
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
161
|
+
assertEq(msIssue?.scope, "milestone", "milestone summary issue has scope 'milestone'");
|
|
162
|
+
assertEq(msIssue?.severity, "warning", "milestone summary issue has severity 'warning'");
|
|
163
|
+
assertEq(msIssue?.unitId, "M001", "milestone summary issue unitId is 'M001'");
|
|
164
|
+
assertTrue(msIssue?.message?.includes("SUMMARY") ?? false, "milestone summary issue message mentions SUMMARY");
|
|
159
165
|
|
|
160
166
|
rmSync(msBase, { recursive: true, force: true });
|
|
161
|
-
}
|
|
167
|
+
}
|
|
162
168
|
|
|
163
169
|
// ─── Milestone summary detection: summary present (no false positive) ──
|
|
164
|
-
|
|
170
|
+
console.log("\n=== doctor does NOT flag milestone with summary ===");
|
|
171
|
+
{
|
|
165
172
|
const msBase = mkdtempSync(join(tmpdir(), "gsd-doctor-ms-ok-test-"));
|
|
166
173
|
const msGsd = join(msBase, ".gsd");
|
|
167
174
|
const msMDir = join(msGsd, "milestones", "M001");
|
|
@@ -211,16 +218,17 @@ parent: M001
|
|
|
211
218
|
writeFileSync(join(msMDir, "M001-SUMMARY.md"), `# M001 Summary\n\nMilestone complete.`);
|
|
212
219
|
|
|
213
220
|
const report = await runGSDDoctor(msBase, { fix: false });
|
|
214
|
-
|
|
221
|
+
assertTrue(
|
|
215
222
|
!report.issues.some(issue => issue.code === "all_slices_done_missing_milestone_summary"),
|
|
216
223
|
"does NOT report missing milestone summary when summary exists"
|
|
217
224
|
);
|
|
218
225
|
|
|
219
226
|
rmSync(msBase, { recursive: true, force: true });
|
|
220
|
-
}
|
|
227
|
+
}
|
|
221
228
|
|
|
222
229
|
// ─── blocker_discovered_no_replan detection ────────────────────────────
|
|
223
|
-
|
|
230
|
+
console.log("\n=== doctor detects blocker_discovered_no_replan ===");
|
|
231
|
+
{
|
|
224
232
|
const bBase = mkdtempSync(join(tmpdir(), "gsd-doctor-blocker-test-"));
|
|
225
233
|
const bGsd = join(bBase, ".gsd");
|
|
226
234
|
const bMDir = join(bGsd, "milestones", "M001");
|
|
@@ -276,17 +284,18 @@ Discovered an issue.
|
|
|
276
284
|
// No REPLAN.md — should trigger the issue
|
|
277
285
|
const report = await runGSDDoctor(bBase, { fix: false });
|
|
278
286
|
const blockerIssues = report.issues.filter(i => i.code === "blocker_discovered_no_replan");
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
287
|
+
assertTrue(blockerIssues.length > 0, "detects blocker_discovered_no_replan");
|
|
288
|
+
assertEq(blockerIssues[0]?.severity, "warning", "blocker issue has warning severity");
|
|
289
|
+
assertEq(blockerIssues[0]?.scope, "slice", "blocker issue has slice scope");
|
|
290
|
+
assertTrue(blockerIssues[0]?.message?.includes("T01") ?? false, "blocker issue message mentions T01");
|
|
291
|
+
assertTrue(blockerIssues[0]?.message?.includes("S01") ?? false, "blocker issue message mentions S01");
|
|
284
292
|
|
|
285
293
|
rmSync(bBase, { recursive: true, force: true });
|
|
286
|
-
}
|
|
294
|
+
}
|
|
287
295
|
|
|
288
296
|
// ─── blocker_discovered with REPLAN.md (no false positive) ─────────────
|
|
289
|
-
|
|
297
|
+
console.log("\n=== doctor does NOT flag blocker when REPLAN.md exists ===");
|
|
298
|
+
{
|
|
290
299
|
const bBase = mkdtempSync(join(tmpdir(), "gsd-doctor-blocker-ok-test-"));
|
|
291
300
|
const bGsd = join(bBase, ".gsd");
|
|
292
301
|
const bMDir = join(bGsd, "milestones", "M001");
|
|
@@ -336,13 +345,14 @@ Discovered an issue.
|
|
|
336
345
|
|
|
337
346
|
const report = await runGSDDoctor(bBase, { fix: false });
|
|
338
347
|
const blockerIssues = report.issues.filter(i => i.code === "blocker_discovered_no_replan");
|
|
339
|
-
|
|
348
|
+
assertEq(blockerIssues.length, 0, "no blocker_discovered_no_replan when REPLAN.md exists");
|
|
340
349
|
|
|
341
350
|
rmSync(bBase, { recursive: true, force: true });
|
|
342
|
-
}
|
|
351
|
+
}
|
|
343
352
|
|
|
344
353
|
// ─── Must-have verification: all addressed → no issue ─────────────────
|
|
345
|
-
|
|
354
|
+
console.log("\n=== doctor: done task with must-haves all addressed → no issue ===");
|
|
355
|
+
{
|
|
346
356
|
const mhBase = mkdtempSync(join(tmpdir(), "gsd-doctor-mh-ok-"));
|
|
347
357
|
const mhGsd = join(mhBase, ".gsd");
|
|
348
358
|
const mhMDir = join(mhGsd, "milestones", "M001");
|
|
@@ -360,16 +370,17 @@ Discovered an issue.
|
|
|
360
370
|
writeFileSync(join(mhTDir, "T01-SUMMARY.md"), `---\nid: T01\nparent: S01\nmilestone: M001\n---\n# T01: Implement\n\n## What Happened\nAdded parseWidgets function. Unit tests pass with zero failures.\n`);
|
|
361
371
|
|
|
362
372
|
const report = await runGSDDoctor(mhBase, { fix: false });
|
|
363
|
-
|
|
373
|
+
assertTrue(
|
|
364
374
|
!report.issues.some(i => i.code === "task_done_must_haves_not_verified"),
|
|
365
375
|
"no must-have issue when all must-haves are addressed"
|
|
366
376
|
);
|
|
367
377
|
|
|
368
378
|
rmSync(mhBase, { recursive: true, force: true });
|
|
369
|
-
}
|
|
379
|
+
}
|
|
370
380
|
|
|
371
381
|
// ─── Must-have verification: not addressed → warning fired ───────────
|
|
372
|
-
|
|
382
|
+
console.log("\n=== doctor: done task with must-haves NOT addressed → warning ===");
|
|
383
|
+
{
|
|
373
384
|
const mhBase = mkdtempSync(join(tmpdir(), "gsd-doctor-mh-fail-"));
|
|
374
385
|
const mhGsd = join(mhBase, ".gsd");
|
|
375
386
|
const mhMDir = join(mhGsd, "milestones", "M001");
|
|
@@ -388,18 +399,19 @@ Discovered an issue.
|
|
|
388
399
|
|
|
389
400
|
const report = await runGSDDoctor(mhBase, { fix: false });
|
|
390
401
|
const mhIssue = report.issues.find(i => i.code === "task_done_must_haves_not_verified");
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
402
|
+
assertTrue(!!mhIssue, "must-have issue is fired when summary doesn't address all must-haves");
|
|
403
|
+
assertEq(mhIssue?.severity, "warning", "must-have issue is warning severity");
|
|
404
|
+
assertEq(mhIssue?.scope, "task", "must-have issue scope is task");
|
|
405
|
+
assertTrue(mhIssue?.message?.includes("3 must-haves") ?? false, "message mentions total must-have count");
|
|
406
|
+
assertTrue(mhIssue?.message?.includes("only 1") ?? false, "message mentions addressed count");
|
|
407
|
+
assertEq(mhIssue?.fixable, false, "must-have issue is not fixable");
|
|
397
408
|
|
|
398
409
|
rmSync(mhBase, { recursive: true, force: true });
|
|
399
|
-
}
|
|
410
|
+
}
|
|
400
411
|
|
|
401
412
|
// ─── Must-have verification: no task plan → no issue ─────────────────
|
|
402
|
-
|
|
413
|
+
console.log("\n=== doctor: done task with no task plan file → no issue ===");
|
|
414
|
+
{
|
|
403
415
|
const mhBase = mkdtempSync(join(tmpdir(), "gsd-doctor-mh-noplan-"));
|
|
404
416
|
const mhGsd = join(mhBase, ".gsd");
|
|
405
417
|
const mhMDir = join(mhGsd, "milestones", "M001");
|
|
@@ -414,16 +426,17 @@ Discovered an issue.
|
|
|
414
426
|
writeFileSync(join(mhTDir, "T01-SUMMARY.md"), `---\nid: T01\nparent: S01\nmilestone: M001\n---\n# T01: Implement\n\n## What Happened\nDone.\n`);
|
|
415
427
|
|
|
416
428
|
const report = await runGSDDoctor(mhBase, { fix: false });
|
|
417
|
-
|
|
429
|
+
assertTrue(
|
|
418
430
|
!report.issues.some(i => i.code === "task_done_must_haves_not_verified"),
|
|
419
431
|
"no must-have issue when task plan file doesn't exist"
|
|
420
432
|
);
|
|
421
433
|
|
|
422
434
|
rmSync(mhBase, { recursive: true, force: true });
|
|
423
|
-
}
|
|
435
|
+
}
|
|
424
436
|
|
|
425
437
|
// ─── Must-have verification: plan exists but no Must-Haves section → no issue
|
|
426
|
-
|
|
438
|
+
console.log("\n=== doctor: done task with plan but no Must-Haves section → no issue ===");
|
|
439
|
+
{
|
|
427
440
|
const mhBase = mkdtempSync(join(tmpdir(), "gsd-doctor-mh-nosect-"));
|
|
428
441
|
const mhGsd = join(mhBase, ".gsd");
|
|
429
442
|
const mhMDir = join(mhGsd, "milestones", "M001");
|
|
@@ -440,49 +453,55 @@ Discovered an issue.
|
|
|
440
453
|
writeFileSync(join(mhTDir, "T01-SUMMARY.md"), `---\nid: T01\nparent: S01\nmilestone: M001\n---\n# T01: Implement\n\n## What Happened\nDone.\n`);
|
|
441
454
|
|
|
442
455
|
const report = await runGSDDoctor(mhBase, { fix: false });
|
|
443
|
-
|
|
456
|
+
assertTrue(
|
|
444
457
|
!report.issues.some(i => i.code === "task_done_must_haves_not_verified"),
|
|
445
458
|
"no must-have issue when task plan has no Must-Haves section"
|
|
446
459
|
);
|
|
447
460
|
|
|
448
461
|
rmSync(mhBase, { recursive: true, force: true });
|
|
449
|
-
}
|
|
462
|
+
}
|
|
450
463
|
|
|
451
464
|
// ─── validateTitle: em dash and slash detection ────────────────────────
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
465
|
+
console.log("\n=== validateTitle: returns null for clean titles ===");
|
|
466
|
+
{
|
|
467
|
+
assertEq(validateTitle("Foundation"), null, "clean title passes");
|
|
468
|
+
assertEq(validateTitle("Build Core Systems"), null, "clean title with spaces passes");
|
|
469
|
+
assertEq(validateTitle("API v2 Integration"), null, "clean title with version passes");
|
|
470
|
+
assertEq(validateTitle(""), null, "empty title passes");
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
console.log("\n=== validateTitle: detects em dash ===");
|
|
474
|
+
{
|
|
460
475
|
const result = validateTitle("Foundation — Build Core");
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
}
|
|
476
|
+
assertTrue(result !== null, "detects em dash in title");
|
|
477
|
+
assertTrue(result!.includes("em/en dash"), "message mentions em/en dash");
|
|
478
|
+
}
|
|
464
479
|
|
|
465
|
-
|
|
480
|
+
console.log("\n=== validateTitle: detects en dash ===");
|
|
481
|
+
{
|
|
466
482
|
const result = validateTitle("Phase 1 – Phase 2");
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
}
|
|
483
|
+
assertTrue(result !== null, "detects en dash in title");
|
|
484
|
+
assertTrue(result!.includes("em/en dash"), "message mentions em/en dash for en dash");
|
|
485
|
+
}
|
|
470
486
|
|
|
471
|
-
|
|
487
|
+
console.log("\n=== validateTitle: detects forward slash ===");
|
|
488
|
+
{
|
|
472
489
|
const result = validateTitle("Client/Server");
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
}
|
|
490
|
+
assertTrue(result !== null, "detects forward slash in title");
|
|
491
|
+
assertTrue(result!.includes("forward slash"), "message mentions forward slash");
|
|
492
|
+
}
|
|
476
493
|
|
|
477
|
-
|
|
494
|
+
console.log("\n=== validateTitle: detects both em dash and slash ===");
|
|
495
|
+
{
|
|
478
496
|
const result = validateTitle("Client — Server/API");
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
}
|
|
497
|
+
assertTrue(result !== null, "detects both delimiters");
|
|
498
|
+
assertTrue(result!.includes("em/en dash"), "message mentions em/en dash");
|
|
499
|
+
assertTrue(result!.includes("forward slash"), "message mentions forward slash");
|
|
500
|
+
}
|
|
483
501
|
|
|
484
502
|
// ─── doctor detects delimiter_in_title for milestone ───────────────────
|
|
485
|
-
|
|
503
|
+
console.log("\n=== doctor detects em dash in milestone title ===");
|
|
504
|
+
{
|
|
486
505
|
const dtBase = mkdtempSync(join(tmpdir(), "gsd-doctor-dt-test-"));
|
|
487
506
|
const dtGsd = join(dtBase, ".gsd");
|
|
488
507
|
const dtMDir = join(dtGsd, "milestones", "M001");
|
|
@@ -497,19 +516,20 @@ Discovered an issue.
|
|
|
497
516
|
|
|
498
517
|
const report = await runGSDDoctor(dtBase, { fix: false });
|
|
499
518
|
const dtIssues = report.issues.filter(i => i.code === "delimiter_in_title");
|
|
500
|
-
|
|
519
|
+
assertTrue(dtIssues.length >= 1, "detects delimiter_in_title for milestone with em dash");
|
|
501
520
|
const milestoneIssue = dtIssues.find(i => i.scope === "milestone");
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
521
|
+
assertTrue(milestoneIssue !== undefined, "delimiter issue has milestone scope");
|
|
522
|
+
assertEq(milestoneIssue?.severity, "warning", "delimiter issue has warning severity");
|
|
523
|
+
assertEq(milestoneIssue?.unitId, "M001", "delimiter issue unitId is M001");
|
|
524
|
+
assertTrue(milestoneIssue?.message?.includes("em/en dash") ?? false, "issue message mentions em/en dash");
|
|
525
|
+
assertEq(milestoneIssue?.fixable, true, "delimiter issue is auto-fixable");
|
|
507
526
|
|
|
508
527
|
rmSync(dtBase, { recursive: true, force: true });
|
|
509
|
-
}
|
|
528
|
+
}
|
|
510
529
|
|
|
511
530
|
// ─── doctor detects delimiter_in_title for slice ────────────────────────
|
|
512
|
-
|
|
531
|
+
console.log("\n=== doctor detects em dash in slice title ===");
|
|
532
|
+
{
|
|
513
533
|
const dtBase = mkdtempSync(join(tmpdir(), "gsd-doctor-dt-slice-"));
|
|
514
534
|
const dtGsd = join(dtBase, ".gsd");
|
|
515
535
|
const dtMDir = join(dtGsd, "milestones", "M001");
|
|
@@ -524,17 +544,18 @@ Discovered an issue.
|
|
|
524
544
|
|
|
525
545
|
const report = await runGSDDoctor(dtBase, { fix: false });
|
|
526
546
|
const dtIssues = report.issues.filter(i => i.code === "delimiter_in_title");
|
|
527
|
-
|
|
547
|
+
assertTrue(dtIssues.length >= 1, "detects delimiter_in_title for slice with em dash");
|
|
528
548
|
const sliceIssue = dtIssues.find(i => i.scope === "slice");
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
549
|
+
assertTrue(sliceIssue !== undefined, "delimiter issue has slice scope");
|
|
550
|
+
assertEq(sliceIssue?.severity, "warning", "slice delimiter issue has warning severity");
|
|
551
|
+
assertEq(sliceIssue?.unitId, "M001/S01", "slice delimiter issue unitId is M001/S01");
|
|
532
552
|
|
|
533
553
|
rmSync(dtBase, { recursive: true, force: true });
|
|
534
|
-
}
|
|
554
|
+
}
|
|
535
555
|
|
|
536
556
|
// ─── doctor does NOT flag clean titles ──────────────────────────────────
|
|
537
|
-
|
|
557
|
+
console.log("\n=== doctor does NOT flag milestone with clean title ===");
|
|
558
|
+
{
|
|
538
559
|
const dtBase = mkdtempSync(join(tmpdir(), "gsd-doctor-dt-clean-"));
|
|
539
560
|
const dtGsd = join(dtBase, ".gsd");
|
|
540
561
|
const dtMDir = join(dtGsd, "milestones", "M001");
|
|
@@ -549,13 +570,14 @@ Discovered an issue.
|
|
|
549
570
|
|
|
550
571
|
const report = await runGSDDoctor(dtBase, { fix: false });
|
|
551
572
|
const dtIssues = report.issues.filter(i => i.code === "delimiter_in_title");
|
|
552
|
-
|
|
573
|
+
assertEq(dtIssues.length, 0, "no delimiter_in_title issues for clean titles");
|
|
553
574
|
|
|
554
575
|
rmSync(dtBase, { recursive: true, force: true });
|
|
555
|
-
}
|
|
576
|
+
}
|
|
556
577
|
|
|
557
578
|
// ─── unresolvable_dependency: range syntax dep warns ─────────────────
|
|
558
|
-
|
|
579
|
+
console.log("\n=== doctor: unresolvable_dependency warns for leftover range ID ===");
|
|
580
|
+
{
|
|
559
581
|
// Simulate a roadmap where expandDependencies did NOT expand (pre-fix stored artifact)
|
|
560
582
|
// by writing a dep that looks like a range but doesn't match any real slice.
|
|
561
583
|
const base = mkdtempSync(join(tmpdir(), "gsd-doctor-udep-"));
|
|
@@ -577,15 +599,16 @@ Discovered an issue.
|
|
|
577
599
|
|
|
578
600
|
const r = await runGSDDoctor(base, { fix: false });
|
|
579
601
|
const udepIssues = r.issues.filter(i => i.code === "unresolvable_dependency");
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
602
|
+
assertTrue(udepIssues.length > 0, "unresolvable_dependency fires for unknown dep S99");
|
|
603
|
+
assertEq(udepIssues[0]?.severity, "warning", "severity is warning");
|
|
604
|
+
assertTrue(udepIssues[0]?.message.includes("S99"), "message names the bad dep");
|
|
583
605
|
|
|
584
606
|
rmSync(base, { recursive: true, force: true });
|
|
585
|
-
}
|
|
607
|
+
}
|
|
586
608
|
|
|
587
609
|
// ─── unresolvable_dependency: valid deps do not warn ─────────────────
|
|
588
|
-
|
|
610
|
+
console.log("\n=== doctor: no unresolvable_dependency for valid deps ===");
|
|
611
|
+
{
|
|
589
612
|
const base = mkdtempSync(join(tmpdir(), "gsd-doctor-udep-ok-"));
|
|
590
613
|
const mDir2 = join(base, ".gsd", "milestones", "M001");
|
|
591
614
|
const sDir2 = join(mDir2, "slices", "S01");
|
|
@@ -605,8 +628,15 @@ Discovered an issue.
|
|
|
605
628
|
|
|
606
629
|
const r = await runGSDDoctor(base, { fix: false });
|
|
607
630
|
const udepIssues = r.issues.filter(i => i.code === "unresolvable_dependency");
|
|
608
|
-
|
|
631
|
+
assertEq(udepIssues.length, 0, "no unresolvable_dependency for valid S01 dep");
|
|
609
632
|
|
|
610
633
|
rmSync(base, { recursive: true, force: true });
|
|
611
|
-
}
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
report();
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
main().catch((error) => {
|
|
640
|
+
console.error(error);
|
|
641
|
+
process.exit(1);
|
|
612
642
|
});
|