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
|
@@ -39,55 +39,61 @@ function activeData(overrides: Partial<HealthWidgetData> = {}): HealthWidgetData
|
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
test("detectHealthWidgetProjectState: no .gsd returns none", (
|
|
42
|
+
test("detectHealthWidgetProjectState: no .gsd returns none", () => {
|
|
43
43
|
const dir = makeTempDir("none");
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
try {
|
|
45
|
+
assert.equal(detectHealthWidgetProjectState(dir), "none");
|
|
46
|
+
} finally {
|
|
47
|
+
cleanup(dir);
|
|
48
|
+
}
|
|
47
49
|
});
|
|
48
50
|
|
|
49
|
-
test("detectHealthWidgetProjectState: bootstrapped .gsd without milestones returns initialized", (
|
|
51
|
+
test("detectHealthWidgetProjectState: bootstrapped .gsd without milestones returns initialized", () => {
|
|
50
52
|
const dir = makeTempDir("initialized");
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
try {
|
|
54
|
+
mkdirSync(join(dir, ".gsd"), { recursive: true });
|
|
55
|
+
assert.equal(detectHealthWidgetProjectState(dir), "initialized");
|
|
56
|
+
} finally {
|
|
57
|
+
cleanup(dir);
|
|
58
|
+
}
|
|
55
59
|
});
|
|
56
60
|
|
|
57
|
-
test("detectHealthWidgetProjectState: milestone without metrics returns active", (
|
|
61
|
+
test("detectHealthWidgetProjectState: milestone without metrics returns active", () => {
|
|
58
62
|
const dir = makeTempDir("active");
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
try {
|
|
64
|
+
mkdirSync(join(dir, ".gsd", "milestones", "M001"), { recursive: true });
|
|
65
|
+
assert.equal(detectHealthWidgetProjectState(dir), "active");
|
|
66
|
+
} finally {
|
|
67
|
+
cleanup(dir);
|
|
68
|
+
}
|
|
63
69
|
});
|
|
64
70
|
|
|
65
|
-
test("buildHealthLines: none state shows onboarding copy", (
|
|
71
|
+
test("buildHealthLines: none state shows onboarding copy", () => {
|
|
66
72
|
assert.deepEqual(buildHealthLines(activeData({ projectState: "none" })), [
|
|
67
73
|
" GSD No project loaded — run /gsd to start",
|
|
68
74
|
]);
|
|
69
75
|
});
|
|
70
76
|
|
|
71
|
-
test("buildHealthLines: initialized state shows continue setup copy", (
|
|
77
|
+
test("buildHealthLines: initialized state shows continue setup copy", () => {
|
|
72
78
|
assert.deepEqual(buildHealthLines(activeData({ projectState: "initialized" })), [
|
|
73
79
|
" GSD Project initialized — run /gsd to continue setup",
|
|
74
80
|
]);
|
|
75
81
|
});
|
|
76
82
|
|
|
77
|
-
test("buildHealthLines: active state with ledger-driven spend shows spent summary", (
|
|
83
|
+
test("buildHealthLines: active state with ledger-driven spend shows spent summary", () => {
|
|
78
84
|
const lines = buildHealthLines(activeData({ budgetSpent: 0.42 }));
|
|
79
85
|
assert.equal(lines.length, 1);
|
|
80
86
|
assert.match(lines[0]!, /● System OK/);
|
|
81
87
|
assert.match(lines[0]!, /Spent: 42\.0¢/);
|
|
82
88
|
});
|
|
83
89
|
|
|
84
|
-
test("buildHealthLines: active state with budget ceiling shows percent summary", (
|
|
90
|
+
test("buildHealthLines: active state with budget ceiling shows percent summary", () => {
|
|
85
91
|
const lines = buildHealthLines(activeData({ budgetSpent: 2.5, budgetCeiling: 10 }));
|
|
86
92
|
assert.equal(lines.length, 1);
|
|
87
93
|
assert.match(lines[0]!, /Budget: \$2\.50\/\$10\.00 \(25%\)/);
|
|
88
94
|
});
|
|
89
95
|
|
|
90
|
-
test("buildHealthLines: active state with issues reports issue summary", (
|
|
96
|
+
test("buildHealthLines: active state with issues reports issue summary", () => {
|
|
91
97
|
const lines = buildHealthLines(activeData({
|
|
92
98
|
providerIssue: "✗ OpenAI key missing",
|
|
93
99
|
environmentErrorCount: 1,
|
|
@@ -98,15 +104,17 @@ test("buildHealthLines: active state with issues reports issue summary", (t) =>
|
|
|
98
104
|
assert.match(lines[0]!, /Env: 1 error/);
|
|
99
105
|
});
|
|
100
106
|
|
|
101
|
-
test("detectHealthWidgetProjectState: metrics file alone does not imply project", (
|
|
107
|
+
test("detectHealthWidgetProjectState: metrics file alone does not imply project", () => {
|
|
102
108
|
const dir = makeTempDir("metrics-only");
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
109
|
+
try {
|
|
110
|
+
mkdirSync(join(dir, ".gsd"), { recursive: true });
|
|
111
|
+
writeFileSync(
|
|
112
|
+
join(dir, ".gsd", "metrics.json"),
|
|
113
|
+
JSON.stringify({ version: 1, projectStartedAt: Date.now(), units: [] }),
|
|
114
|
+
"utf-8",
|
|
115
|
+
);
|
|
116
|
+
assert.equal(detectHealthWidgetProjectState(dir), "initialized");
|
|
117
|
+
} finally {
|
|
118
|
+
cleanup(dir);
|
|
119
|
+
}
|
|
112
120
|
});
|
|
@@ -8,9 +8,9 @@ import {
|
|
|
8
8
|
verifyExpectedArtifact,
|
|
9
9
|
buildLoopRemediationSteps,
|
|
10
10
|
} from "../auto.ts";
|
|
11
|
-
import {
|
|
12
|
-
import assert from 'node:assert/strict';
|
|
11
|
+
import { createTestContext } from './test-helpers.ts';
|
|
13
12
|
|
|
13
|
+
const { assertEq, assertTrue, report } = createTestContext();
|
|
14
14
|
function createFixtureBase(): string {
|
|
15
15
|
const base = mkdtempSync(join(tmpdir(), "gsd-idle-recovery-test-"));
|
|
16
16
|
mkdirSync(join(base, ".gsd", "milestones", "M001", "slices", "S01", "tasks"), { recursive: true });
|
|
@@ -23,91 +23,99 @@ function cleanup(base: string): void {
|
|
|
23
23
|
|
|
24
24
|
// ═══ resolveExpectedArtifactPath ═════════════════════════════════════════════
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
{
|
|
27
|
+
console.log("\n=== resolveExpectedArtifactPath: research-milestone ===");
|
|
27
28
|
const base = createFixtureBase();
|
|
28
29
|
try {
|
|
29
30
|
const result = resolveExpectedArtifactPath("research-milestone", "M001", base);
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
assertTrue(result !== null, "should resolve a path");
|
|
32
|
+
assertTrue(result!.endsWith("M001-RESEARCH.md"), `path should end with M001-RESEARCH.md, got ${result}`);
|
|
32
33
|
} finally {
|
|
33
34
|
cleanup(base);
|
|
34
35
|
}
|
|
35
|
-
}
|
|
36
|
+
}
|
|
36
37
|
|
|
37
|
-
|
|
38
|
+
{
|
|
39
|
+
console.log("\n=== resolveExpectedArtifactPath: plan-milestone ===");
|
|
38
40
|
const base = createFixtureBase();
|
|
39
41
|
try {
|
|
40
42
|
const result = resolveExpectedArtifactPath("plan-milestone", "M001", base);
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
assertTrue(result !== null, "should resolve a path");
|
|
44
|
+
assertTrue(result!.endsWith("M001-ROADMAP.md"), `path should end with M001-ROADMAP.md, got ${result}`);
|
|
43
45
|
} finally {
|
|
44
46
|
cleanup(base);
|
|
45
47
|
}
|
|
46
|
-
}
|
|
48
|
+
}
|
|
47
49
|
|
|
48
|
-
|
|
50
|
+
{
|
|
51
|
+
console.log("\n=== resolveExpectedArtifactPath: research-slice ===");
|
|
49
52
|
const base = createFixtureBase();
|
|
50
53
|
try {
|
|
51
54
|
const result = resolveExpectedArtifactPath("research-slice", "M001/S01", base);
|
|
52
|
-
|
|
53
|
-
|
|
55
|
+
assertTrue(result !== null, "should resolve a path");
|
|
56
|
+
assertTrue(result!.endsWith("S01-RESEARCH.md"), `path should end with S01-RESEARCH.md, got ${result}`);
|
|
54
57
|
} finally {
|
|
55
58
|
cleanup(base);
|
|
56
59
|
}
|
|
57
|
-
}
|
|
60
|
+
}
|
|
58
61
|
|
|
59
|
-
|
|
62
|
+
{
|
|
63
|
+
console.log("\n=== resolveExpectedArtifactPath: plan-slice ===");
|
|
60
64
|
const base = createFixtureBase();
|
|
61
65
|
try {
|
|
62
66
|
const result = resolveExpectedArtifactPath("plan-slice", "M001/S01", base);
|
|
63
|
-
|
|
64
|
-
|
|
67
|
+
assertTrue(result !== null, "should resolve a path");
|
|
68
|
+
assertTrue(result!.endsWith("S01-PLAN.md"), `path should end with S01-PLAN.md, got ${result}`);
|
|
65
69
|
} finally {
|
|
66
70
|
cleanup(base);
|
|
67
71
|
}
|
|
68
|
-
}
|
|
72
|
+
}
|
|
69
73
|
|
|
70
|
-
|
|
74
|
+
{
|
|
75
|
+
console.log("\n=== resolveExpectedArtifactPath: complete-milestone ===");
|
|
71
76
|
const base = createFixtureBase();
|
|
72
77
|
try {
|
|
73
78
|
const result = resolveExpectedArtifactPath("complete-milestone", "M001", base);
|
|
74
|
-
|
|
75
|
-
|
|
79
|
+
assertTrue(result !== null, "should resolve a path");
|
|
80
|
+
assertTrue(result!.endsWith("M001-SUMMARY.md"), `path should end with M001-SUMMARY.md, got ${result}`);
|
|
76
81
|
} finally {
|
|
77
82
|
cleanup(base);
|
|
78
83
|
}
|
|
79
|
-
}
|
|
84
|
+
}
|
|
80
85
|
|
|
81
|
-
|
|
86
|
+
{
|
|
87
|
+
console.log("\n=== resolveExpectedArtifactPath: unknown unit type → null ===");
|
|
82
88
|
const base = createFixtureBase();
|
|
83
89
|
try {
|
|
84
90
|
const result = resolveExpectedArtifactPath("unknown-type", "M001/S01", base);
|
|
85
|
-
|
|
91
|
+
assertEq(result, null, "unknown type returns null");
|
|
86
92
|
} finally {
|
|
87
93
|
cleanup(base);
|
|
88
94
|
}
|
|
89
|
-
}
|
|
95
|
+
}
|
|
90
96
|
|
|
91
97
|
// ═══ writeBlockerPlaceholder ═════════════════════════════════════════════════
|
|
92
98
|
|
|
93
|
-
|
|
99
|
+
{
|
|
100
|
+
console.log("\n=== writeBlockerPlaceholder: writes file for research-slice ===");
|
|
94
101
|
const base = createFixtureBase();
|
|
95
102
|
try {
|
|
96
103
|
const result = writeBlockerPlaceholder("research-slice", "M001/S01", base, "idle recovery exhausted 2 attempts");
|
|
97
|
-
|
|
104
|
+
assertTrue(result !== null, "should return relative path");
|
|
98
105
|
const absPath = resolveExpectedArtifactPath("research-slice", "M001/S01", base)!;
|
|
99
|
-
|
|
106
|
+
assertTrue(existsSync(absPath), "file should exist on disk");
|
|
100
107
|
const content = readFileSync(absPath, "utf-8");
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
108
|
+
assertTrue(content.includes("BLOCKER"), "should contain BLOCKER heading");
|
|
109
|
+
assertTrue(content.includes("idle recovery exhausted 2 attempts"), "should contain the reason");
|
|
110
|
+
assertTrue(content.includes("research-slice"), "should mention the unit type");
|
|
111
|
+
assertTrue(content.includes("M001/S01"), "should mention the unit ID");
|
|
105
112
|
} finally {
|
|
106
113
|
cleanup(base);
|
|
107
114
|
}
|
|
108
|
-
}
|
|
115
|
+
}
|
|
109
116
|
|
|
110
|
-
|
|
117
|
+
{
|
|
118
|
+
console.log("\n=== writeBlockerPlaceholder: creates directory if missing ===");
|
|
111
119
|
const base = mkdtempSync(join(tmpdir(), "gsd-idle-recovery-test-"));
|
|
112
120
|
try {
|
|
113
121
|
// Only create milestone dir, not slice dir
|
|
@@ -115,36 +123,38 @@ test('writeBlockerPlaceholder: creates directory if missing', () => {
|
|
|
115
123
|
// resolveSlicePath needs the slice dir to exist to resolve, so this should return null
|
|
116
124
|
const result = writeBlockerPlaceholder("research-slice", "M001/S01", base, "test reason");
|
|
117
125
|
// Since the slice dir doesn't exist, resolveExpectedArtifactPath returns null
|
|
118
|
-
|
|
126
|
+
assertEq(result, null, "returns null when directory structure doesn't exist");
|
|
119
127
|
} finally {
|
|
120
128
|
cleanup(base);
|
|
121
129
|
}
|
|
122
|
-
}
|
|
130
|
+
}
|
|
123
131
|
|
|
124
|
-
|
|
132
|
+
{
|
|
133
|
+
console.log("\n=== writeBlockerPlaceholder: writes file for research-milestone ===");
|
|
125
134
|
const base = createFixtureBase();
|
|
126
135
|
try {
|
|
127
136
|
const result = writeBlockerPlaceholder("research-milestone", "M001", base, "hard timeout");
|
|
128
|
-
|
|
137
|
+
assertTrue(result !== null, "should return relative path");
|
|
129
138
|
const absPath = resolveExpectedArtifactPath("research-milestone", "M001", base)!;
|
|
130
|
-
|
|
139
|
+
assertTrue(existsSync(absPath), "file should exist on disk");
|
|
131
140
|
const content = readFileSync(absPath, "utf-8");
|
|
132
|
-
|
|
133
|
-
|
|
141
|
+
assertTrue(content.includes("BLOCKER"), "should contain BLOCKER heading");
|
|
142
|
+
assertTrue(content.includes("hard timeout"), "should contain the reason");
|
|
134
143
|
} finally {
|
|
135
144
|
cleanup(base);
|
|
136
145
|
}
|
|
137
|
-
}
|
|
146
|
+
}
|
|
138
147
|
|
|
139
|
-
|
|
148
|
+
{
|
|
149
|
+
console.log("\n=== writeBlockerPlaceholder: unknown type → null ===");
|
|
140
150
|
const base = createFixtureBase();
|
|
141
151
|
try {
|
|
142
152
|
const result = writeBlockerPlaceholder("unknown-type", "M001/S01", base, "test");
|
|
143
|
-
|
|
153
|
+
assertEq(result, null, "unknown type returns null");
|
|
144
154
|
} finally {
|
|
145
155
|
cleanup(base);
|
|
146
156
|
}
|
|
147
|
-
}
|
|
157
|
+
}
|
|
148
158
|
|
|
149
159
|
// ═══ verifyExpectedArtifact: complete-slice roadmap check ════════════════════
|
|
150
160
|
// Regression for #indefinite-hang: complete-slice must verify roadmap [x] or
|
|
@@ -167,7 +177,8 @@ const ROADMAP_COMPLETE = `# M001: Test Milestone
|
|
|
167
177
|
> After this: something works
|
|
168
178
|
`;
|
|
169
179
|
|
|
170
|
-
|
|
180
|
+
{
|
|
181
|
+
console.log("\n=== verifyExpectedArtifact: complete-slice — all artifacts present + roadmap marked [x] returns true ===");
|
|
171
182
|
const base = createFixtureBase();
|
|
172
183
|
try {
|
|
173
184
|
const sliceDir = join(base, ".gsd", "milestones", "M001", "slices", "S01");
|
|
@@ -175,13 +186,14 @@ test('verifyExpectedArtifact: complete-slice — all artifacts present + roadmap
|
|
|
175
186
|
writeFileSync(join(sliceDir, "S01-UAT.md"), "# UAT\n", "utf-8");
|
|
176
187
|
writeFileSync(join(base, ".gsd", "milestones", "M001", "M001-ROADMAP.md"), ROADMAP_COMPLETE, "utf-8");
|
|
177
188
|
const result = verifyExpectedArtifact("complete-slice", "M001/S01", base);
|
|
178
|
-
|
|
189
|
+
assertTrue(result === true, "SUMMARY + UAT + roadmap [x] should verify as true");
|
|
179
190
|
} finally {
|
|
180
191
|
cleanup(base);
|
|
181
192
|
}
|
|
182
|
-
}
|
|
193
|
+
}
|
|
183
194
|
|
|
184
|
-
|
|
195
|
+
{
|
|
196
|
+
console.log("\n=== verifyExpectedArtifact: complete-slice — SUMMARY + UAT present but roadmap NOT marked [x] returns false ===");
|
|
185
197
|
const base = createFixtureBase();
|
|
186
198
|
try {
|
|
187
199
|
const sliceDir = join(base, ".gsd", "milestones", "M001", "slices", "S01");
|
|
@@ -189,13 +201,14 @@ test('verifyExpectedArtifact: complete-slice — SUMMARY + UAT present but roadm
|
|
|
189
201
|
writeFileSync(join(sliceDir, "S01-UAT.md"), "# UAT\n", "utf-8");
|
|
190
202
|
writeFileSync(join(base, ".gsd", "milestones", "M001", "M001-ROADMAP.md"), ROADMAP_INCOMPLETE, "utf-8");
|
|
191
203
|
const result = verifyExpectedArtifact("complete-slice", "M001/S01", base);
|
|
192
|
-
|
|
204
|
+
assertTrue(result === false, "roadmap not marked [x] should return false (crash recovery scenario)");
|
|
193
205
|
} finally {
|
|
194
206
|
cleanup(base);
|
|
195
207
|
}
|
|
196
|
-
}
|
|
208
|
+
}
|
|
197
209
|
|
|
198
|
-
|
|
210
|
+
{
|
|
211
|
+
console.log("\n=== verifyExpectedArtifact: complete-slice — SUMMARY present but UAT missing returns false ===");
|
|
199
212
|
const base = createFixtureBase();
|
|
200
213
|
try {
|
|
201
214
|
const sliceDir = join(base, ".gsd", "milestones", "M001", "slices", "S01");
|
|
@@ -203,13 +216,14 @@ test('verifyExpectedArtifact: complete-slice — SUMMARY present but UAT missing
|
|
|
203
216
|
// no UAT file
|
|
204
217
|
writeFileSync(join(base, ".gsd", "milestones", "M001", "M001-ROADMAP.md"), ROADMAP_COMPLETE, "utf-8");
|
|
205
218
|
const result = verifyExpectedArtifact("complete-slice", "M001/S01", base);
|
|
206
|
-
|
|
219
|
+
assertTrue(result === false, "missing UAT should return false");
|
|
207
220
|
} finally {
|
|
208
221
|
cleanup(base);
|
|
209
222
|
}
|
|
210
|
-
}
|
|
223
|
+
}
|
|
211
224
|
|
|
212
|
-
|
|
225
|
+
{
|
|
226
|
+
console.log("\n=== verifyExpectedArtifact: complete-slice — no roadmap file present is lenient (returns true) ===");
|
|
213
227
|
const base = createFixtureBase();
|
|
214
228
|
try {
|
|
215
229
|
const sliceDir = join(base, ".gsd", "milestones", "M001", "slices", "S01");
|
|
@@ -217,80 +231,87 @@ test('verifyExpectedArtifact: complete-slice — no roadmap file present is leni
|
|
|
217
231
|
writeFileSync(join(sliceDir, "S01-UAT.md"), "# UAT\n", "utf-8");
|
|
218
232
|
// no roadmap file
|
|
219
233
|
const result = verifyExpectedArtifact("complete-slice", "M001/S01", base);
|
|
220
|
-
|
|
234
|
+
assertTrue(result === true, "missing roadmap file should be lenient and return true");
|
|
221
235
|
} finally {
|
|
222
236
|
cleanup(base);
|
|
223
237
|
}
|
|
224
|
-
}
|
|
238
|
+
}
|
|
225
239
|
|
|
226
240
|
// ═══ buildLoopRemediationSteps ═══════════════════════════════════════════════
|
|
227
241
|
|
|
228
|
-
|
|
242
|
+
{
|
|
243
|
+
console.log("\n=== buildLoopRemediationSteps: execute-task returns concrete steps ===");
|
|
229
244
|
const base = mkdtempSync(join(tmpdir(), "gsd-loop-remediation-test-"));
|
|
230
245
|
try {
|
|
231
246
|
mkdirSync(join(base, ".gsd", "milestones", "M002", "slices", "S03", "tasks"), { recursive: true });
|
|
232
247
|
const result = buildLoopRemediationSteps("execute-task", "M002/S03/T01", base);
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
248
|
+
assertTrue(result !== null, "should return remediation steps");
|
|
249
|
+
assertTrue(result!.includes("gsd undo-task"), "steps include undo-task command");
|
|
250
|
+
assertTrue(result!.includes("T01"), "steps mention the task ID");
|
|
251
|
+
assertTrue(result!.includes("gsd undo-task"), "steps include gsd undo-task command");
|
|
237
252
|
} finally {
|
|
238
253
|
rmSync(base, { recursive: true, force: true });
|
|
239
254
|
}
|
|
240
|
-
}
|
|
255
|
+
}
|
|
241
256
|
|
|
242
|
-
|
|
257
|
+
{
|
|
258
|
+
console.log("\n=== buildLoopRemediationSteps: plan-slice returns concrete steps ===");
|
|
243
259
|
const base = mkdtempSync(join(tmpdir(), "gsd-loop-remediation-test-"));
|
|
244
260
|
try {
|
|
245
261
|
mkdirSync(join(base, ".gsd", "milestones", "M001", "slices", "S01"), { recursive: true });
|
|
246
262
|
const result = buildLoopRemediationSteps("plan-slice", "M001/S01", base);
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
263
|
+
assertTrue(result !== null, "should return remediation steps for plan-slice");
|
|
264
|
+
assertTrue(result!.includes("S01-PLAN.md"), "steps mention the slice plan file");
|
|
265
|
+
assertTrue(result!.includes("gsd recover"), "steps include gsd recover command");
|
|
250
266
|
} finally {
|
|
251
267
|
rmSync(base, { recursive: true, force: true });
|
|
252
268
|
}
|
|
253
|
-
}
|
|
269
|
+
}
|
|
254
270
|
|
|
255
|
-
|
|
271
|
+
{
|
|
272
|
+
console.log("\n=== buildLoopRemediationSteps: research-slice returns concrete steps ===");
|
|
256
273
|
const base = mkdtempSync(join(tmpdir(), "gsd-loop-remediation-test-"));
|
|
257
274
|
try {
|
|
258
275
|
mkdirSync(join(base, ".gsd", "milestones", "M001", "slices", "S01"), { recursive: true });
|
|
259
276
|
const result = buildLoopRemediationSteps("research-slice", "M001/S01", base);
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
277
|
+
assertTrue(result !== null, "should return remediation steps for research-slice");
|
|
278
|
+
assertTrue(result!.includes("S01-RESEARCH.md"), "steps mention the slice research file");
|
|
279
|
+
assertTrue(result!.includes("gsd recover"), "steps include gsd recover command");
|
|
263
280
|
} finally {
|
|
264
281
|
rmSync(base, { recursive: true, force: true });
|
|
265
282
|
}
|
|
266
|
-
}
|
|
283
|
+
}
|
|
267
284
|
|
|
268
|
-
|
|
285
|
+
{
|
|
286
|
+
console.log("\n=== buildLoopRemediationSteps: unknown type returns null ===");
|
|
269
287
|
const base = mkdtempSync(join(tmpdir(), "gsd-loop-remediation-test-"));
|
|
270
288
|
try {
|
|
271
289
|
const result = buildLoopRemediationSteps("unknown-type", "M001/S01", base);
|
|
272
|
-
|
|
290
|
+
assertEq(result, null, "unknown type returns null");
|
|
273
291
|
} finally {
|
|
274
292
|
rmSync(base, { recursive: true, force: true });
|
|
275
293
|
}
|
|
276
|
-
}
|
|
294
|
+
}
|
|
277
295
|
|
|
278
296
|
// ═══ verifyExpectedArtifact: hook unit types ═════════════════════════════════
|
|
279
297
|
|
|
280
|
-
|
|
298
|
+
console.log("\n=== verifyExpectedArtifact: hook types always return true ===");
|
|
299
|
+
|
|
300
|
+
{
|
|
281
301
|
const base = createFixtureBase();
|
|
282
302
|
try {
|
|
283
303
|
// Hook units don't have standard artifacts — they should always pass
|
|
284
304
|
const result1 = verifyExpectedArtifact("hook/code-review", "M001/S01/T01", base);
|
|
285
|
-
|
|
305
|
+
assertTrue(result1, "hook/code-review should always return true");
|
|
286
306
|
|
|
287
307
|
const result2 = verifyExpectedArtifact("hook/simplify", "M001/S01/T02", base);
|
|
288
|
-
|
|
308
|
+
assertTrue(result2, "hook/simplify should always return true");
|
|
289
309
|
|
|
290
310
|
const result3 = verifyExpectedArtifact("hook/custom-hook", "M001/S01", base);
|
|
291
|
-
|
|
311
|
+
assertTrue(result3, "hook/custom-hook at slice level should return true");
|
|
292
312
|
} finally {
|
|
293
313
|
rmSync(base, { recursive: true, force: true });
|
|
294
314
|
}
|
|
295
|
-
}
|
|
315
|
+
}
|
|
296
316
|
|
|
317
|
+
report();
|
|
@@ -36,17 +36,19 @@ function cleanup(dir: string): void {
|
|
|
36
36
|
|
|
37
37
|
// ─── Detection Integration Tests ────────────────────────────────────────────────
|
|
38
38
|
|
|
39
|
-
test("init-wizard: clean folder detected as state=none", (
|
|
39
|
+
test("init-wizard: clean folder detected as state=none", () => {
|
|
40
40
|
const dir = makeTempDir("clean");
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
try {
|
|
42
|
+
const detection = detectProjectState(dir);
|
|
43
|
+
assert.equal(detection.state, "none");
|
|
44
|
+
assert.equal(detection.v1, undefined);
|
|
45
|
+
assert.equal(detection.v2, undefined);
|
|
46
|
+
} finally {
|
|
47
|
+
cleanup(dir);
|
|
48
|
+
}
|
|
47
49
|
});
|
|
48
50
|
|
|
49
|
-
test("init-wizard: v1 .planning/ triggers v1-planning state", (
|
|
51
|
+
test("init-wizard: v1 .planning/ triggers v1-planning state", () => {
|
|
50
52
|
const dir = makeTempDir("v1");
|
|
51
53
|
try {
|
|
52
54
|
mkdirSync(join(dir, ".planning", "phases", "01"), { recursive: true });
|
|
@@ -63,7 +65,7 @@ test("init-wizard: v1 .planning/ triggers v1-planning state", (t) => {
|
|
|
63
65
|
}
|
|
64
66
|
});
|
|
65
67
|
|
|
66
|
-
test("init-wizard: existing .gsd/ with milestones skips init", (
|
|
68
|
+
test("init-wizard: existing .gsd/ with milestones skips init", () => {
|
|
67
69
|
const dir = makeTempDir("existing");
|
|
68
70
|
try {
|
|
69
71
|
mkdirSync(join(dir, ".gsd", "milestones", "M001"), { recursive: true });
|
|
@@ -78,7 +80,7 @@ test("init-wizard: existing .gsd/ with milestones skips init", (t) => {
|
|
|
78
80
|
}
|
|
79
81
|
});
|
|
80
82
|
|
|
81
|
-
test("init-wizard: empty .gsd/ (no milestones) returns v2-gsd-empty", (
|
|
83
|
+
test("init-wizard: empty .gsd/ (no milestones) returns v2-gsd-empty", () => {
|
|
82
84
|
const dir = makeTempDir("empty-gsd");
|
|
83
85
|
try {
|
|
84
86
|
mkdirSync(join(dir, ".gsd", "milestones"), { recursive: true });
|
|
@@ -92,7 +94,7 @@ test("init-wizard: empty .gsd/ (no milestones) returns v2-gsd-empty", (t) => {
|
|
|
92
94
|
}
|
|
93
95
|
});
|
|
94
96
|
|
|
95
|
-
test("init-wizard: project signals populate from Node.js project", (
|
|
97
|
+
test("init-wizard: project signals populate from Node.js project", () => {
|
|
96
98
|
const dir = makeTempDir("node-project");
|
|
97
99
|
try {
|
|
98
100
|
writeFileSync(
|
|
@@ -119,7 +121,7 @@ test("init-wizard: project signals populate from Node.js project", (t) => {
|
|
|
119
121
|
}
|
|
120
122
|
});
|
|
121
123
|
|
|
122
|
-
test("init-wizard: v2 .gsd/ preferences detected", (
|
|
124
|
+
test("init-wizard: v2 .gsd/ preferences detected", () => {
|
|
123
125
|
const dir = makeTempDir("prefs-detect");
|
|
124
126
|
try {
|
|
125
127
|
mkdirSync(join(dir, ".gsd", "milestones"), { recursive: true });
|
|
@@ -133,7 +135,7 @@ test("init-wizard: v2 .gsd/ preferences detected", (t) => {
|
|
|
133
135
|
}
|
|
134
136
|
});
|
|
135
137
|
|
|
136
|
-
test("init-wizard: v2 uppercase PREFERENCES.md also detected", (
|
|
138
|
+
test("init-wizard: v2 uppercase PREFERENCES.md also detected", () => {
|
|
137
139
|
const dir = makeTempDir("prefs-upper");
|
|
138
140
|
try {
|
|
139
141
|
mkdirSync(join(dir, ".gsd", "milestones"), { recursive: true });
|
|
@@ -147,7 +149,7 @@ test("init-wizard: v2 uppercase PREFERENCES.md also detected", (t) => {
|
|
|
147
149
|
}
|
|
148
150
|
});
|
|
149
151
|
|
|
150
|
-
test("init-wizard: CONTEXT.md detected in v2", (
|
|
152
|
+
test("init-wizard: CONTEXT.md detected in v2", () => {
|
|
151
153
|
const dir = makeTempDir("context");
|
|
152
154
|
try {
|
|
153
155
|
mkdirSync(join(dir, ".gsd", "milestones"), { recursive: true });
|
|
@@ -161,7 +163,7 @@ test("init-wizard: CONTEXT.md detected in v2", (t) => {
|
|
|
161
163
|
}
|
|
162
164
|
});
|
|
163
165
|
|
|
164
|
-
test("init-wizard: multiple project files detected together", (
|
|
166
|
+
test("init-wizard: multiple project files detected together", () => {
|
|
165
167
|
const dir = makeTempDir("multi-files");
|
|
166
168
|
try {
|
|
167
169
|
writeFileSync(join(dir, "package.json"), JSON.stringify({ name: "test" }), "utf-8");
|
|
@@ -178,7 +180,7 @@ test("init-wizard: multiple project files detected together", (t) => {
|
|
|
178
180
|
}
|
|
179
181
|
});
|
|
180
182
|
|
|
181
|
-
test("init-wizard: v1 with both .planning/ and .gsd/ prioritizes v2", (
|
|
183
|
+
test("init-wizard: v1 with both .planning/ and .gsd/ prioritizes v2", () => {
|
|
182
184
|
const dir = makeTempDir("both-v1-v2");
|
|
183
185
|
try {
|
|
184
186
|
mkdirSync(join(dir, ".planning", "phases"), { recursive: true });
|