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