gsd-pi 2.43.0 → 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/bg-shell/overlay.js +3 -0
- package/dist/resources/extensions/github-sync/sync.js +2 -1
- package/dist/resources/extensions/gsd/auto/loop.js +0 -2
- package/dist/resources/extensions/gsd/auto/phases.js +7 -12
- package/dist/resources/extensions/gsd/auto-dashboard.js +19 -18
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +34 -19
- package/dist/resources/extensions/gsd/auto-dispatch.js +36 -21
- package/dist/resources/extensions/gsd/auto-post-unit.js +128 -14
- package/dist/resources/extensions/gsd/auto-prompts.js +202 -92
- package/dist/resources/extensions/gsd/auto-recovery.js +83 -135
- package/dist/resources/extensions/gsd/auto-start.js +10 -0
- package/dist/resources/extensions/gsd/auto-supervisor.js +14 -0
- package/dist/resources/extensions/gsd/auto-timeout-recovery.js +4 -7
- package/dist/resources/extensions/gsd/auto-verification.js +5 -10
- package/dist/resources/extensions/gsd/auto-worktree.js +123 -30
- package/dist/resources/extensions/gsd/auto.js +1 -4
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +611 -0
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +28 -3
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +7 -0
- package/dist/resources/extensions/gsd/commands/catalog.js +3 -1
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +15 -1
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +5 -0
- package/dist/resources/extensions/gsd/commands-handlers.js +1 -1
- package/dist/resources/extensions/gsd/commands-maintenance.js +78 -3
- package/dist/resources/extensions/gsd/dashboard-overlay.js +32 -31
- package/dist/resources/extensions/gsd/db-writer.js +95 -4
- package/dist/resources/extensions/gsd/dispatch-guard.js +35 -30
- package/dist/resources/extensions/gsd/doctor-checks.js +28 -11
- package/dist/resources/extensions/gsd/doctor-environment.js +28 -0
- package/dist/resources/extensions/gsd/doctor-types.js +0 -15
- package/dist/resources/extensions/gsd/doctor.js +46 -282
- package/dist/resources/extensions/gsd/file-watcher.js +5 -1
- package/dist/resources/extensions/gsd/files.js +14 -198
- package/dist/resources/extensions/gsd/git-service.js +4 -0
- package/dist/resources/extensions/gsd/gitignore.js +4 -0
- package/dist/resources/extensions/gsd/gsd-db.js +819 -197
- package/dist/resources/extensions/gsd/guided-flow.js +18 -8
- package/dist/resources/extensions/gsd/markdown-renderer.js +862 -0
- package/dist/resources/extensions/gsd/md-importer.js +182 -4
- package/dist/resources/extensions/gsd/native-git-bridge.js +10 -1
- package/dist/resources/extensions/gsd/parallel-eligibility.js +14 -19
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +38 -0
- package/dist/resources/extensions/gsd/parsers-legacy.js +239 -0
- package/dist/resources/extensions/gsd/preferences-types.js +1 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +9 -0
- package/dist/resources/extensions/gsd/preferences.js +1 -0
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +22 -9
- package/dist/resources/extensions/gsd/prompts/discuss.md +2 -2
- package/dist/resources/extensions/gsd/prompts/execute-task.md +15 -5
- package/dist/resources/extensions/gsd/prompts/guided-complete-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-execute-task.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-plan-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +6 -10
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -7
- package/dist/resources/extensions/gsd/prompts/reactive-execute.md +3 -3
- package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -7
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +6 -6
- package/dist/resources/extensions/gsd/reactive-graph.js +33 -3
- package/dist/resources/extensions/gsd/skill-health.js +3 -1
- package/dist/resources/extensions/gsd/state.js +484 -30
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +128 -0
- package/dist/resources/extensions/gsd/tools/complete-slice.js +244 -0
- package/dist/resources/extensions/gsd/tools/complete-task.js +204 -0
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +205 -0
- package/dist/resources/extensions/gsd/tools/plan-slice.js +155 -0
- package/dist/resources/extensions/gsd/tools/plan-task.js +94 -0
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +152 -0
- package/dist/resources/extensions/gsd/tools/replan-slice.js +146 -0
- package/dist/resources/extensions/gsd/triage-resolution.js +17 -1
- package/dist/resources/extensions/gsd/undo.js +197 -3
- package/dist/resources/extensions/gsd/visualizer-data.js +53 -16
- package/dist/resources/extensions/gsd/workspace-index.js +63 -39
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +18 -17
- package/dist/web/standalone/.next/build-manifest.json +4 -4
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
- package/dist/web/standalone/.next/required-server-files.json +4 -4
- package/dist/web/standalone/.next/routes-manifest.json +6 -0
- 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 +4 -4
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
- 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 +4 -4
- 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 +2 -2
- 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 -0
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -0
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -0
- 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 +5 -5
- 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 +5 -5
- 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 +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- 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 -17
- package/dist/web/standalone/.next/server/chunks/229.js +3 -3
- package/dist/web/standalone/.next/server/chunks/471.js +3 -3
- package/dist/web/standalone/.next/server/functions-config-manifest.json +1 -0
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-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/alS4hoANx0TK4UVZY27da/_buildManifest.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{4024.c195dc1fdd2adbea.js → 4024.0de81b543b28b9fe.js} +2 -2
- package/dist/web/standalone/.next/static/chunks/app/_global-error/{page-d07a2c023f1aef1e.js → page-d83ba70a25a85472.js} +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/api/boot/{route-d07a2c023f1aef1e.js → route-d83ba70a25a85472.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/{route-d07a2c023f1aef1e.js → route-d83ba70a25a85472.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/{route-d07a2c023f1aef1e.js → route-d83ba70a25a85472.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/captures/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/files/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/git/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/history/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/projects/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/steer/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/undo/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/update/route-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-d83ba70a25a85472.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/app-error-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-d83ba70a25a85472.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-fa307370fcf9fb2c.js → webpack-9014b5adb127a98a.js} +1 -1
- package/dist/web/standalone/.next/static/css/8a727f372cf53002.css +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-ai/dist/models.custom.d.ts +173 -0
- package/packages/pi-ai/dist/models.custom.d.ts.map +1 -0
- package/packages/pi-ai/dist/models.custom.js +170 -0
- package/packages/pi-ai/dist/models.custom.js.map +1 -0
- package/packages/pi-ai/dist/models.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.js +16 -1
- package/packages/pi-ai/dist/models.js.map +1 -1
- package/packages/pi-ai/dist/models.test.d.ts +2 -0
- package/packages/pi-ai/dist/models.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/models.test.js +67 -0
- package/packages/pi-ai/dist/models.test.js.map +1 -0
- package/packages/pi-ai/src/models.custom.ts +172 -0
- package/packages/pi-ai/src/models.test.ts +85 -0
- package/packages/pi-ai/src/models.ts +17 -1
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +10 -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 +21 -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 +6 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +80 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.test.js +63 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.test.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/lsp/client.d.ts +5 -0
- package/packages/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/client.js +69 -21
- package/packages/pi-coding-agent/dist/core/lsp/client.js.map +1 -1
- 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/modes/interactive/components/footer.d.ts +6 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +21 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +8 -15
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/print-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/print-mode.js +45 -34
- package/packages/pi-coding-agent/dist/modes/print-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js +7 -2
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +2 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.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 +26 -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.test.ts +96 -0
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +89 -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/lsp/client.ts +83 -21
- 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/modes/interactive/components/footer.ts +20 -0
- package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +9 -16
- package/packages/pi-coding-agent/src/modes/print-mode.ts +42 -32
- package/packages/pi-coding-agent/src/modes/rpc/rpc-client.ts +8 -2
- package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +2 -1
- package/packages/pi-coding-agent/src/resources/extensions/memory/storage.test.ts +74 -74
- package/pkg/dist/modes/interactive/theme/theme.d.ts +1 -1
- package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/theme.js +8 -15
- package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/extensions/bg-shell/overlay.ts +4 -0
- package/src/resources/extensions/github-sync/sync.ts +2 -1
- package/src/resources/extensions/gsd/auto/loop-deps.ts +0 -8
- package/src/resources/extensions/gsd/auto/loop.ts +0 -2
- package/src/resources/extensions/gsd/auto/phases.ts +7 -20
- package/src/resources/extensions/gsd/auto/types.ts +0 -1
- package/src/resources/extensions/gsd/auto-dashboard.ts +20 -16
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +34 -19
- package/src/resources/extensions/gsd/auto-dispatch.ts +38 -21
- package/src/resources/extensions/gsd/auto-post-unit.ts +150 -15
- package/src/resources/extensions/gsd/auto-prompts.ts +186 -103
- package/src/resources/extensions/gsd/auto-recovery.ts +77 -142
- package/src/resources/extensions/gsd/auto-start.ts +14 -0
- package/src/resources/extensions/gsd/auto-supervisor.ts +14 -0
- package/src/resources/extensions/gsd/auto-timeout-recovery.ts +6 -7
- package/src/resources/extensions/gsd/auto-verification.ts +4 -9
- package/src/resources/extensions/gsd/auto-worktree.ts +126 -30
- package/src/resources/extensions/gsd/auto.ts +0 -9
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +675 -4
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +31 -3
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +7 -0
- package/src/resources/extensions/gsd/commands/catalog.ts +3 -1
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +15 -1
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +8 -0
- package/src/resources/extensions/gsd/commands-handlers.ts +1 -1
- package/src/resources/extensions/gsd/commands-maintenance.ts +86 -3
- package/src/resources/extensions/gsd/dashboard-overlay.ts +17 -13
- package/src/resources/extensions/gsd/db-writer.ts +105 -4
- package/src/resources/extensions/gsd/dispatch-guard.ts +32 -30
- package/src/resources/extensions/gsd/doctor-checks.ts +25 -11
- package/src/resources/extensions/gsd/doctor-environment.ts +31 -0
- package/src/resources/extensions/gsd/doctor-types.ts +0 -23
- package/src/resources/extensions/gsd/doctor.ts +45 -295
- package/src/resources/extensions/gsd/file-watcher.ts +4 -1
- package/src/resources/extensions/gsd/files.ts +16 -220
- package/src/resources/extensions/gsd/git-service.ts +4 -0
- package/src/resources/extensions/gsd/gitignore.ts +4 -0
- package/src/resources/extensions/gsd/gsd-db.ts +1157 -370
- package/src/resources/extensions/gsd/guided-flow.ts +20 -8
- package/src/resources/extensions/gsd/markdown-renderer.ts +1098 -0
- package/src/resources/extensions/gsd/md-importer.ts +211 -2
- package/src/resources/extensions/gsd/native-git-bridge.ts +12 -1
- package/src/resources/extensions/gsd/parallel-eligibility.ts +14 -18
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +43 -0
- package/src/resources/extensions/gsd/parsers-legacy.ts +271 -0
- package/src/resources/extensions/gsd/preferences-types.ts +3 -0
- package/src/resources/extensions/gsd/preferences-validation.ts +9 -0
- package/src/resources/extensions/gsd/preferences.ts +1 -0
- package/src/resources/extensions/gsd/prompts/complete-slice.md +22 -9
- package/src/resources/extensions/gsd/prompts/discuss.md +2 -2
- package/src/resources/extensions/gsd/prompts/execute-task.md +15 -5
- package/src/resources/extensions/gsd/prompts/guided-complete-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-execute-task.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-plan-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +6 -10
- package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -7
- package/src/resources/extensions/gsd/prompts/reactive-execute.md +3 -3
- package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -7
- package/src/resources/extensions/gsd/prompts/replan-slice.md +6 -6
- package/src/resources/extensions/gsd/reactive-graph.ts +33 -3
- package/src/resources/extensions/gsd/skill-health.ts +2 -1
- package/src/resources/extensions/gsd/state.ts +547 -29
- package/src/resources/extensions/gsd/tests/all-milestones-complete-merge.test.ts +99 -99
- package/src/resources/extensions/gsd/tests/atomic-task-closeout.test.ts +8 -120
- package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +14 -16
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +20 -11
- 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 +600 -513
- 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 +121 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +540 -668
- 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 +39 -60
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +375 -0
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +387 -0
- 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/custom-engine-loop-integration.test.ts +0 -2
- 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 +512 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +644 -84
- 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 +192 -161
- 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 +30 -90
- package/src/resources/extensions/gsd/tests/doctor-delimiter-fix.test.ts +34 -38
- package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +57 -80
- package/src/resources/extensions/gsd/tests/doctor-environment-worktree.test.ts +164 -0
- package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +72 -97
- package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +55 -153
- 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 +53 -97
- package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +72 -93
- package/src/resources/extensions/gsd/tests/doctor.test.ts +109 -149
- 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 +278 -0
- package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +232 -0
- package/src/resources/extensions/gsd/tests/git-locale.test.ts +13 -27
- package/src/resources/extensions/gsd/tests/git-service.test.ts +291 -390
- 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 +440 -0
- 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 -270
- 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 +643 -0
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +0 -3
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +1161 -0
- 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 +81 -94
- package/src/resources/extensions/gsd/tests/migrate-command.test.ts +57 -66
- package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +429 -0
- 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 +89 -97
- package/src/resources/extensions/gsd/tests/migrate-writer.test.ts +127 -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 +548 -612
- package/src/resources/extensions/gsd/tests/paths.test.ts +72 -87
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +176 -113
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +179 -0
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +145 -0
- package/src/resources/extensions/gsd/tests/planning-crossval.test.ts +305 -0
- package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +77 -117
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +139 -0
- 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-handler.test.ts +325 -0
- package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +28 -38
- package/src/resources/extensions/gsd/tests/replan-handler.test.ts +410 -0
- 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/roadmap-slices.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/rogue-file-detection.test.ts +296 -0
- 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/schema-v9-sequence.test.ts +176 -0
- 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 +209 -0
- 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-cost-display.test.ts +118 -0
- 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 +19 -13
- package/src/resources/extensions/gsd/tests/undo.test.ts +321 -1
- 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/validate-milestone.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/verification-evidence.test.ts +0 -142
- 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-dispatch.test.ts +12 -5
- 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/complete-milestone.ts +176 -0
- package/src/resources/extensions/gsd/tools/complete-slice.ts +300 -0
- package/src/resources/extensions/gsd/tools/complete-task.ts +245 -0
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +249 -0
- package/src/resources/extensions/gsd/tools/plan-slice.ts +194 -0
- package/src/resources/extensions/gsd/tools/plan-task.ts +116 -0
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +203 -0
- package/src/resources/extensions/gsd/tools/replan-slice.ts +192 -0
- package/src/resources/extensions/gsd/triage-resolution.ts +20 -1
- package/src/resources/extensions/gsd/types.ts +50 -0
- package/src/resources/extensions/gsd/undo.ts +247 -3
- package/src/resources/extensions/gsd/visualizer-data.ts +54 -17
- package/src/resources/extensions/gsd/workspace-index.ts +64 -46
- package/dist/resources/extensions/gsd/auto-observability.js +0 -56
- package/dist/resources/extensions/gsd/observability-validator.js +0 -422
- package/dist/resources/extensions/gsd/roadmap-mutations.js +0 -110
- package/dist/web/standalone/.next/static/VvclDCW6TAWjEyLU-EYL1/_buildManifest.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/_not-found/page-e07acdb7dd069836.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/captures/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/files/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/git/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/history/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/projects/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/steer/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/undo/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/update/route-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-d07a2c023f1aef1e.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/app-error-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-d07a2c023f1aef1e.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/chunks/next/dist/client/components/builtin/not-found-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-d07a2c023f1aef1e.js +0 -1
- package/dist/web/standalone/.next/static/css/123c0bb039697968.css +0 -1
- package/src/resources/extensions/gsd/auto-observability.ts +0 -74
- package/src/resources/extensions/gsd/observability-validator.ts +0 -456
- package/src/resources/extensions/gsd/roadmap-mutations.ts +0 -134
- package/src/resources/extensions/gsd/tests/doctor-task-done-missing-summary-slice-loop.test.ts +0 -174
- package/src/resources/extensions/gsd/tests/plan-quality-validator.test.ts +0 -474
- /package/dist/web/standalone/.next/static/{VvclDCW6TAWjEyLU-EYL1 → alS4hoANx0TK4UVZY27da}/_ssgManifest.js +0 -0
|
@@ -13,9 +13,18 @@ import {
|
|
|
13
13
|
selfHealRuntimeRecords,
|
|
14
14
|
hasImplementationArtifacts,
|
|
15
15
|
} from "../auto-recovery.ts";
|
|
16
|
-
import { parseRoadmap,
|
|
16
|
+
import { parseRoadmap, parsePlan } from "../parsers-legacy.ts";
|
|
17
|
+
import { parseTaskPlanFile, clearParseCache } from "../files.ts";
|
|
17
18
|
import { invalidateAllCaches } from "../cache.ts";
|
|
18
19
|
import { deriveState, invalidateStateCache } from "../state.ts";
|
|
20
|
+
import {
|
|
21
|
+
openDatabase,
|
|
22
|
+
closeDatabase,
|
|
23
|
+
insertMilestone,
|
|
24
|
+
insertSlice,
|
|
25
|
+
insertTask,
|
|
26
|
+
} from "../gsd-db.ts";
|
|
27
|
+
import { renderPlanFromDb } from "../markdown-renderer.ts";
|
|
19
28
|
|
|
20
29
|
function makeTmpBase(): string {
|
|
21
30
|
const base = join(tmpdir(), `gsd-test-${randomUUID()}`);
|
|
@@ -30,526 +39,616 @@ function cleanup(base: string): void {
|
|
|
30
39
|
|
|
31
40
|
// ─── resolveExpectedArtifactPath ──────────────────────────────────────────
|
|
32
41
|
|
|
33
|
-
test("resolveExpectedArtifactPath returns correct path for research-milestone", () => {
|
|
42
|
+
test("resolveExpectedArtifactPath returns correct path for research-milestone", (t) => {
|
|
34
43
|
const base = makeTmpBase();
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
cleanup(base);
|
|
42
|
-
}
|
|
44
|
+
t.after(() => cleanup(base));
|
|
45
|
+
|
|
46
|
+
const result = resolveExpectedArtifactPath("research-milestone", "M001", base);
|
|
47
|
+
assert.ok(result);
|
|
48
|
+
assert.ok(result!.includes("M001"));
|
|
49
|
+
assert.ok(result!.includes("RESEARCH"));
|
|
43
50
|
});
|
|
44
51
|
|
|
45
|
-
test("resolveExpectedArtifactPath returns correct path for execute-task", () => {
|
|
52
|
+
test("resolveExpectedArtifactPath returns correct path for execute-task", (t) => {
|
|
46
53
|
const base = makeTmpBase();
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
cleanup(base);
|
|
54
|
-
}
|
|
54
|
+
t.after(() => cleanup(base));
|
|
55
|
+
|
|
56
|
+
const result = resolveExpectedArtifactPath("execute-task", "M001/S01/T01", base);
|
|
57
|
+
assert.ok(result);
|
|
58
|
+
assert.ok(result!.includes("tasks"));
|
|
59
|
+
assert.ok(result!.includes("SUMMARY"));
|
|
55
60
|
});
|
|
56
61
|
|
|
57
|
-
test("resolveExpectedArtifactPath returns correct path for complete-slice", () => {
|
|
62
|
+
test("resolveExpectedArtifactPath returns correct path for complete-slice", (t) => {
|
|
58
63
|
const base = makeTmpBase();
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
cleanup(base);
|
|
65
|
-
}
|
|
64
|
+
t.after(() => cleanup(base));
|
|
65
|
+
|
|
66
|
+
const result = resolveExpectedArtifactPath("complete-slice", "M001/S01", base);
|
|
67
|
+
assert.ok(result);
|
|
68
|
+
assert.ok(result!.includes("SUMMARY"));
|
|
66
69
|
});
|
|
67
70
|
|
|
68
|
-
test("resolveExpectedArtifactPath returns correct path for plan-slice", () => {
|
|
71
|
+
test("resolveExpectedArtifactPath returns correct path for plan-slice", (t) => {
|
|
69
72
|
const base = makeTmpBase();
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
cleanup(base);
|
|
76
|
-
}
|
|
73
|
+
t.after(() => cleanup(base));
|
|
74
|
+
|
|
75
|
+
const result = resolveExpectedArtifactPath("plan-slice", "M001/S01", base);
|
|
76
|
+
assert.ok(result);
|
|
77
|
+
assert.ok(result!.includes("PLAN"));
|
|
77
78
|
});
|
|
78
79
|
|
|
79
|
-
test("resolveExpectedArtifactPath returns null for unknown type", () => {
|
|
80
|
+
test("resolveExpectedArtifactPath returns null for unknown type", (t) => {
|
|
80
81
|
const base = makeTmpBase();
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
cleanup(base);
|
|
86
|
-
}
|
|
82
|
+
t.after(() => cleanup(base));
|
|
83
|
+
|
|
84
|
+
const result = resolveExpectedArtifactPath("unknown-type", "M001", base);
|
|
85
|
+
assert.equal(result, null);
|
|
87
86
|
});
|
|
88
87
|
|
|
89
|
-
test("resolveExpectedArtifactPath returns correct path for all milestone-level types", () => {
|
|
88
|
+
test("resolveExpectedArtifactPath returns correct path for all milestone-level types", (t) => {
|
|
90
89
|
const base = makeTmpBase();
|
|
91
|
-
|
|
92
|
-
const planResult = resolveExpectedArtifactPath("plan-milestone", "M001", base);
|
|
93
|
-
assert.ok(planResult);
|
|
94
|
-
assert.ok(planResult!.includes("ROADMAP"));
|
|
90
|
+
t.after(() => cleanup(base));
|
|
95
91
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
92
|
+
const planResult = resolveExpectedArtifactPath("plan-milestone", "M001", base);
|
|
93
|
+
assert.ok(planResult);
|
|
94
|
+
assert.ok(planResult!.includes("ROADMAP"));
|
|
95
|
+
|
|
96
|
+
const completeResult = resolveExpectedArtifactPath("complete-milestone", "M001", base);
|
|
97
|
+
assert.ok(completeResult);
|
|
98
|
+
assert.ok(completeResult!.includes("SUMMARY"));
|
|
102
99
|
});
|
|
103
100
|
|
|
104
|
-
test("resolveExpectedArtifactPath returns correct path for all slice-level types", () => {
|
|
101
|
+
test("resolveExpectedArtifactPath returns correct path for all slice-level types", (t) => {
|
|
105
102
|
const base = makeTmpBase();
|
|
106
|
-
|
|
107
|
-
const researchResult = resolveExpectedArtifactPath("research-slice", "M001/S01", base);
|
|
108
|
-
assert.ok(researchResult);
|
|
109
|
-
assert.ok(researchResult!.includes("RESEARCH"));
|
|
103
|
+
t.after(() => cleanup(base));
|
|
110
104
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
105
|
+
const researchResult = resolveExpectedArtifactPath("research-slice", "M001/S01", base);
|
|
106
|
+
assert.ok(researchResult);
|
|
107
|
+
assert.ok(researchResult!.includes("RESEARCH"));
|
|
114
108
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
109
|
+
const assessResult = resolveExpectedArtifactPath("reassess-roadmap", "M001/S01", base);
|
|
110
|
+
assert.ok(assessResult);
|
|
111
|
+
assert.ok(assessResult!.includes("ASSESSMENT"));
|
|
112
|
+
|
|
113
|
+
const uatResult = resolveExpectedArtifactPath("run-uat", "M001/S01", base);
|
|
114
|
+
assert.ok(uatResult);
|
|
115
|
+
assert.ok(uatResult!.includes("UAT-RESULT"));
|
|
121
116
|
});
|
|
122
117
|
|
|
123
118
|
// ─── diagnoseExpectedArtifact ─────────────────────────────────────────────
|
|
124
119
|
|
|
125
|
-
test("diagnoseExpectedArtifact returns description for known types", () => {
|
|
120
|
+
test("diagnoseExpectedArtifact returns description for known types", (t) => {
|
|
126
121
|
const base = makeTmpBase();
|
|
127
|
-
|
|
128
|
-
const research = diagnoseExpectedArtifact("research-milestone", "M001", base);
|
|
129
|
-
assert.ok(research);
|
|
130
|
-
assert.ok(research!.includes("research"));
|
|
122
|
+
t.after(() => cleanup(base));
|
|
131
123
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
124
|
+
const research = diagnoseExpectedArtifact("research-milestone", "M001", base);
|
|
125
|
+
assert.ok(research);
|
|
126
|
+
assert.ok(research!.includes("research"));
|
|
135
127
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
128
|
+
const plan = diagnoseExpectedArtifact("plan-slice", "M001/S01", base);
|
|
129
|
+
assert.ok(plan);
|
|
130
|
+
assert.ok(plan!.includes("plan"));
|
|
131
|
+
|
|
132
|
+
const task = diagnoseExpectedArtifact("execute-task", "M001/S01/T01", base);
|
|
133
|
+
assert.ok(task);
|
|
134
|
+
assert.ok(task!.includes("T01"));
|
|
142
135
|
});
|
|
143
136
|
|
|
144
|
-
test("diagnoseExpectedArtifact returns null for unknown type", () => {
|
|
137
|
+
test("diagnoseExpectedArtifact returns null for unknown type", (t) => {
|
|
145
138
|
const base = makeTmpBase();
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
cleanup(base);
|
|
150
|
-
}
|
|
139
|
+
t.after(() => cleanup(base));
|
|
140
|
+
|
|
141
|
+
assert.equal(diagnoseExpectedArtifact("unknown", "M001", base), null);
|
|
151
142
|
});
|
|
152
143
|
|
|
153
144
|
// ─── buildLoopRemediationSteps ────────────────────────────────────────────
|
|
154
145
|
|
|
155
|
-
test("buildLoopRemediationSteps returns steps for execute-task", () => {
|
|
146
|
+
test("buildLoopRemediationSteps returns steps for execute-task", (t) => {
|
|
156
147
|
const base = makeTmpBase();
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
} finally {
|
|
164
|
-
cleanup(base);
|
|
165
|
-
}
|
|
148
|
+
t.after(() => cleanup(base));
|
|
149
|
+
|
|
150
|
+
const steps = buildLoopRemediationSteps("execute-task", "M001/S01/T01", base);
|
|
151
|
+
assert.ok(steps);
|
|
152
|
+
assert.ok(steps!.includes("T01"));
|
|
153
|
+
assert.ok(steps!.includes("gsd undo-task"));
|
|
166
154
|
});
|
|
167
155
|
|
|
168
|
-
test("buildLoopRemediationSteps returns steps for plan-slice", () => {
|
|
156
|
+
test("buildLoopRemediationSteps returns steps for plan-slice", (t) => {
|
|
169
157
|
const base = makeTmpBase();
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
cleanup(base);
|
|
177
|
-
}
|
|
158
|
+
t.after(() => cleanup(base));
|
|
159
|
+
|
|
160
|
+
const steps = buildLoopRemediationSteps("plan-slice", "M001/S01", base);
|
|
161
|
+
assert.ok(steps);
|
|
162
|
+
assert.ok(steps!.includes("PLAN"));
|
|
163
|
+
assert.ok(steps!.includes("gsd recover"));
|
|
178
164
|
});
|
|
179
165
|
|
|
180
|
-
test("buildLoopRemediationSteps returns steps for complete-slice", () => {
|
|
166
|
+
test("buildLoopRemediationSteps returns steps for complete-slice", (t) => {
|
|
181
167
|
const base = makeTmpBase();
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
cleanup(base);
|
|
189
|
-
}
|
|
168
|
+
t.after(() => cleanup(base));
|
|
169
|
+
|
|
170
|
+
const steps = buildLoopRemediationSteps("complete-slice", "M001/S01", base);
|
|
171
|
+
assert.ok(steps);
|
|
172
|
+
assert.ok(steps!.includes("S01"));
|
|
173
|
+
assert.ok(steps!.includes("gsd reset-slice"));
|
|
190
174
|
});
|
|
191
175
|
|
|
192
|
-
test("buildLoopRemediationSteps returns null for unknown type", () => {
|
|
176
|
+
test("buildLoopRemediationSteps returns null for unknown type", (t) => {
|
|
193
177
|
const base = makeTmpBase();
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
cleanup(base);
|
|
198
|
-
}
|
|
178
|
+
t.after(() => cleanup(base));
|
|
179
|
+
|
|
180
|
+
assert.equal(buildLoopRemediationSteps("unknown", "M001", base), null);
|
|
199
181
|
});
|
|
200
182
|
|
|
201
183
|
// ─── verifyExpectedArtifact: parse cache collision regression ─────────────
|
|
202
184
|
|
|
203
|
-
test("verifyExpectedArtifact detects roadmap [x] change despite parse cache", () => {
|
|
185
|
+
test("verifyExpectedArtifact detects roadmap [x] change despite parse cache", (t) => {
|
|
204
186
|
// Regression test: cacheKey collision when [ ] → [x] doesn't change
|
|
205
187
|
// file length or first/last 100 chars. Without the fix, parseRoadmap
|
|
206
188
|
// returns stale cached data with done=false even though the file has [x].
|
|
207
189
|
const base = makeTmpBase();
|
|
208
|
-
|
|
209
|
-
// Build a roadmap long enough that the [x] change is outside the first/last 100 chars
|
|
210
|
-
const padding = "A".repeat(200);
|
|
211
|
-
const roadmapBefore = [
|
|
212
|
-
`# M001: Test Milestone ${padding}`,
|
|
213
|
-
"",
|
|
214
|
-
"## Slices",
|
|
215
|
-
"",
|
|
216
|
-
"- [ ] **S01: First slice** `risk:low`",
|
|
217
|
-
"",
|
|
218
|
-
`## Footer ${padding}`,
|
|
219
|
-
].join("\n");
|
|
220
|
-
const roadmapAfter = roadmapBefore.replace("- [ ] **S01:", "- [x] **S01:");
|
|
221
|
-
|
|
222
|
-
// Verify lengths are identical (the key collision condition)
|
|
223
|
-
assert.equal(roadmapBefore.length, roadmapAfter.length);
|
|
224
|
-
|
|
225
|
-
// Populate parse cache with the pre-edit roadmap
|
|
226
|
-
const before = parseRoadmap(roadmapBefore);
|
|
227
|
-
const sliceBefore = before.slices.find(s => s.id === "S01");
|
|
228
|
-
assert.ok(sliceBefore);
|
|
229
|
-
assert.equal(sliceBefore!.done, false);
|
|
230
|
-
|
|
231
|
-
// Now write the post-edit roadmap to disk and create required artifacts
|
|
232
|
-
const roadmapPath = join(base, ".gsd", "milestones", "M001", "M001-ROADMAP.md");
|
|
233
|
-
writeFileSync(roadmapPath, roadmapAfter);
|
|
234
|
-
const summaryPath = join(base, ".gsd", "milestones", "M001", "slices", "S01", "S01-SUMMARY.md");
|
|
235
|
-
writeFileSync(summaryPath, "# Summary\nDone.");
|
|
236
|
-
const uatPath = join(base, ".gsd", "milestones", "M001", "slices", "S01", "S01-UAT.md");
|
|
237
|
-
writeFileSync(uatPath, "# UAT\nPassed.");
|
|
238
|
-
|
|
239
|
-
// verifyExpectedArtifact should see the [x] despite the parse cache
|
|
240
|
-
// having the [ ] version. The fix clears the parse cache inside verify.
|
|
241
|
-
const verified = verifyExpectedArtifact("complete-slice", "M001/S01", base);
|
|
242
|
-
assert.equal(verified, true, "verifyExpectedArtifact should return true when roadmap has [x]");
|
|
243
|
-
} finally {
|
|
190
|
+
t.after(() => {
|
|
244
191
|
clearParseCache();
|
|
245
192
|
cleanup(base);
|
|
246
|
-
}
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
// Build a roadmap long enough that the [x] change is outside the first/last 100 chars
|
|
196
|
+
const padding = "A".repeat(200);
|
|
197
|
+
const roadmapBefore = [
|
|
198
|
+
`# M001: Test Milestone ${padding}`,
|
|
199
|
+
"",
|
|
200
|
+
"## Slices",
|
|
201
|
+
"",
|
|
202
|
+
"- [ ] **S01: First slice** `risk:low`",
|
|
203
|
+
"",
|
|
204
|
+
`## Footer ${padding}`,
|
|
205
|
+
].join("\n");
|
|
206
|
+
const roadmapAfter = roadmapBefore.replace("- [ ] **S01:", "- [x] **S01:");
|
|
207
|
+
|
|
208
|
+
// Verify lengths are identical (the key collision condition)
|
|
209
|
+
assert.equal(roadmapBefore.length, roadmapAfter.length);
|
|
210
|
+
|
|
211
|
+
// Populate parse cache with the pre-edit roadmap
|
|
212
|
+
const before = parseRoadmap(roadmapBefore);
|
|
213
|
+
const sliceBefore = before.slices.find(s => s.id === "S01");
|
|
214
|
+
assert.ok(sliceBefore);
|
|
215
|
+
assert.equal(sliceBefore!.done, false);
|
|
216
|
+
|
|
217
|
+
// Now write the post-edit roadmap to disk and create required artifacts
|
|
218
|
+
const roadmapPath = join(base, ".gsd", "milestones", "M001", "M001-ROADMAP.md");
|
|
219
|
+
writeFileSync(roadmapPath, roadmapAfter);
|
|
220
|
+
const summaryPath = join(base, ".gsd", "milestones", "M001", "slices", "S01", "S01-SUMMARY.md");
|
|
221
|
+
writeFileSync(summaryPath, "# Summary\nDone.");
|
|
222
|
+
const uatPath = join(base, ".gsd", "milestones", "M001", "slices", "S01", "S01-UAT.md");
|
|
223
|
+
writeFileSync(uatPath, "# UAT\nPassed.");
|
|
224
|
+
|
|
225
|
+
// verifyExpectedArtifact should see the [x] despite the parse cache
|
|
226
|
+
// having the [ ] version. The fix clears the parse cache inside verify.
|
|
227
|
+
const verified = verifyExpectedArtifact("complete-slice", "M001/S01", base);
|
|
228
|
+
assert.equal(verified, true, "verifyExpectedArtifact should return true when roadmap has [x]");
|
|
247
229
|
});
|
|
248
230
|
|
|
249
231
|
// ─── verifyExpectedArtifact: plan-slice empty scaffold regression (#699) ──
|
|
250
232
|
|
|
251
|
-
test("verifyExpectedArtifact rejects plan-slice with empty scaffold", () => {
|
|
233
|
+
test("verifyExpectedArtifact rejects plan-slice with empty scaffold", (t) => {
|
|
252
234
|
const base = makeTmpBase();
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
cleanup(base);
|
|
264
|
-
}
|
|
235
|
+
t.after(() => cleanup(base));
|
|
236
|
+
|
|
237
|
+
const sliceDir = join(base, ".gsd", "milestones", "M001", "slices", "S01");
|
|
238
|
+
mkdirSync(sliceDir, { recursive: true });
|
|
239
|
+
writeFileSync(join(sliceDir, "S01-PLAN.md"), "# S01: Test Slice\n\n## Tasks\n\n");
|
|
240
|
+
assert.strictEqual(
|
|
241
|
+
verifyExpectedArtifact("plan-slice", "M001/S01", base),
|
|
242
|
+
false,
|
|
243
|
+
"Empty scaffold should not be treated as completed artifact",
|
|
244
|
+
);
|
|
265
245
|
});
|
|
266
246
|
|
|
267
|
-
test("verifyExpectedArtifact accepts plan-slice with actual tasks", () => {
|
|
247
|
+
test("verifyExpectedArtifact accepts plan-slice with actual tasks", (t) => {
|
|
268
248
|
const base = makeTmpBase();
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
]
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
cleanup(base);
|
|
290
|
-
}
|
|
249
|
+
t.after(() => cleanup(base));
|
|
250
|
+
|
|
251
|
+
const sliceDir = join(base, ".gsd", "milestones", "M001", "slices", "S01");
|
|
252
|
+
const tasksDir = join(sliceDir, "tasks");
|
|
253
|
+
mkdirSync(tasksDir, { recursive: true });
|
|
254
|
+
writeFileSync(join(sliceDir, "S01-PLAN.md"), [
|
|
255
|
+
"# S01: Test Slice",
|
|
256
|
+
"",
|
|
257
|
+
"## Tasks",
|
|
258
|
+
"",
|
|
259
|
+
"- [ ] **T01: Implement feature** `est:2h`",
|
|
260
|
+
"- [ ] **T02: Write tests** `est:1h`",
|
|
261
|
+
].join("\n"));
|
|
262
|
+
writeFileSync(join(tasksDir, "T01-PLAN.md"), "# T01 Plan");
|
|
263
|
+
writeFileSync(join(tasksDir, "T02-PLAN.md"), "# T02 Plan");
|
|
264
|
+
assert.strictEqual(
|
|
265
|
+
verifyExpectedArtifact("plan-slice", "M001/S01", base),
|
|
266
|
+
true,
|
|
267
|
+
"Plan with task entries should be treated as completed artifact",
|
|
268
|
+
);
|
|
291
269
|
});
|
|
292
270
|
|
|
293
|
-
test("verifyExpectedArtifact accepts plan-slice with completed tasks", () => {
|
|
271
|
+
test("verifyExpectedArtifact accepts plan-slice with completed tasks", (t) => {
|
|
294
272
|
const base = makeTmpBase();
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
]
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
cleanup(base);
|
|
316
|
-
}
|
|
273
|
+
t.after(() => cleanup(base));
|
|
274
|
+
|
|
275
|
+
const sliceDir = join(base, ".gsd", "milestones", "M001", "slices", "S01");
|
|
276
|
+
const tasksDir = join(sliceDir, "tasks");
|
|
277
|
+
mkdirSync(tasksDir, { recursive: true });
|
|
278
|
+
writeFileSync(join(sliceDir, "S01-PLAN.md"), [
|
|
279
|
+
"# S01: Test Slice",
|
|
280
|
+
"",
|
|
281
|
+
"## Tasks",
|
|
282
|
+
"",
|
|
283
|
+
"- [x] **T01: Implement feature** `est:2h`",
|
|
284
|
+
"- [ ] **T02: Write tests** `est:1h`",
|
|
285
|
+
].join("\n"));
|
|
286
|
+
writeFileSync(join(tasksDir, "T01-PLAN.md"), "# T01 Plan");
|
|
287
|
+
writeFileSync(join(tasksDir, "T02-PLAN.md"), "# T02 Plan");
|
|
288
|
+
assert.strictEqual(
|
|
289
|
+
verifyExpectedArtifact("plan-slice", "M001/S01", base),
|
|
290
|
+
true,
|
|
291
|
+
"Plan with completed task entries should be treated as completed artifact",
|
|
292
|
+
);
|
|
317
293
|
});
|
|
318
294
|
|
|
319
295
|
// ─── verifyExpectedArtifact: plan-slice task plan check (#739) ────────────
|
|
320
296
|
|
|
321
|
-
test("verifyExpectedArtifact plan-slice passes when all task plan files exist", () => {
|
|
297
|
+
test("verifyExpectedArtifact plan-slice passes when all task plan files exist", (t) => {
|
|
322
298
|
const base = makeTmpBase();
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
]
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
cleanup(base);
|
|
342
|
-
}
|
|
299
|
+
t.after(() => cleanup(base));
|
|
300
|
+
|
|
301
|
+
const tasksDir = join(base, ".gsd", "milestones", "M001", "slices", "S01", "tasks");
|
|
302
|
+
const planPath = join(base, ".gsd", "milestones", "M001", "slices", "S01", "S01-PLAN.md");
|
|
303
|
+
const planContent = [
|
|
304
|
+
"# S01: Test Slice",
|
|
305
|
+
"",
|
|
306
|
+
"## Tasks",
|
|
307
|
+
"",
|
|
308
|
+
"- [ ] **T01: First task** `est:1h`",
|
|
309
|
+
"- [ ] **T02: Second task** `est:2h`",
|
|
310
|
+
].join("\n");
|
|
311
|
+
writeFileSync(planPath, planContent);
|
|
312
|
+
writeFileSync(join(tasksDir, "T01-PLAN.md"), "# T01 Plan\n\nDo the thing.");
|
|
313
|
+
writeFileSync(join(tasksDir, "T02-PLAN.md"), "# T02 Plan\n\nDo the other thing.");
|
|
314
|
+
|
|
315
|
+
const result = verifyExpectedArtifact("plan-slice", "M001/S01", base);
|
|
316
|
+
assert.equal(result, true, "should pass when all task plan files exist");
|
|
343
317
|
});
|
|
344
318
|
|
|
345
|
-
test("verifyExpectedArtifact plan-slice fails when a task plan file is missing (#739)", () => {
|
|
319
|
+
test("verifyExpectedArtifact plan-slice fails when a task plan file is missing (#739)", (t) => {
|
|
346
320
|
const base = makeTmpBase();
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
]
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
cleanup(base);
|
|
366
|
-
}
|
|
321
|
+
t.after(() => cleanup(base));
|
|
322
|
+
|
|
323
|
+
const tasksDir = join(base, ".gsd", "milestones", "M001", "slices", "S01", "tasks");
|
|
324
|
+
const planPath = join(base, ".gsd", "milestones", "M001", "slices", "S01", "S01-PLAN.md");
|
|
325
|
+
const planContent = [
|
|
326
|
+
"# S01: Test Slice",
|
|
327
|
+
"",
|
|
328
|
+
"## Tasks",
|
|
329
|
+
"",
|
|
330
|
+
"- [ ] **T01: First task** `est:1h`",
|
|
331
|
+
"- [ ] **T02: Second task** `est:2h`",
|
|
332
|
+
].join("\n");
|
|
333
|
+
writeFileSync(planPath, planContent);
|
|
334
|
+
// Only write T01-PLAN.md — T02 is missing
|
|
335
|
+
writeFileSync(join(tasksDir, "T01-PLAN.md"), "# T01 Plan\n\nDo the thing.");
|
|
336
|
+
|
|
337
|
+
const result = verifyExpectedArtifact("plan-slice", "M001/S01", base);
|
|
338
|
+
assert.equal(result, false, "should fail when T02-PLAN.md is missing");
|
|
367
339
|
});
|
|
368
340
|
|
|
369
|
-
test("verifyExpectedArtifact plan-slice fails for plan with no tasks (#699)", () => {
|
|
341
|
+
test("verifyExpectedArtifact plan-slice fails for plan with no tasks (#699)", (t) => {
|
|
370
342
|
const base = makeTmpBase();
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
cleanup(base);
|
|
386
|
-
}
|
|
343
|
+
t.after(() => cleanup(base));
|
|
344
|
+
|
|
345
|
+
const planPath = join(base, ".gsd", "milestones", "M001", "slices", "S01", "S01-PLAN.md");
|
|
346
|
+
const planContent = [
|
|
347
|
+
"# S01: Test Slice",
|
|
348
|
+
"",
|
|
349
|
+
"## Goal",
|
|
350
|
+
"",
|
|
351
|
+
"Just some documentation updates, no tasks.",
|
|
352
|
+
].join("\n");
|
|
353
|
+
writeFileSync(planPath, planContent);
|
|
354
|
+
|
|
355
|
+
const result = verifyExpectedArtifact("plan-slice", "M001/S01", base);
|
|
356
|
+
assert.equal(result, false, "should fail when plan has no task entries (empty scaffold, #699)");
|
|
387
357
|
});
|
|
388
358
|
|
|
389
359
|
// ─── verifyExpectedArtifact: heading-style plan tasks (#1691) ─────────────
|
|
390
360
|
|
|
391
|
-
test("verifyExpectedArtifact accepts plan-slice with heading-style tasks (### T01 --)", () => {
|
|
361
|
+
test("verifyExpectedArtifact accepts plan-slice with heading-style tasks (### T01 --)", (t) => {
|
|
392
362
|
const base = makeTmpBase();
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
cleanup(base);
|
|
419
|
-
}
|
|
363
|
+
t.after(() => cleanup(base));
|
|
364
|
+
|
|
365
|
+
const sliceDir = join(base, ".gsd", "milestones", "M001", "slices", "S01");
|
|
366
|
+
const tasksDir = join(sliceDir, "tasks");
|
|
367
|
+
mkdirSync(tasksDir, { recursive: true });
|
|
368
|
+
writeFileSync(join(sliceDir, "S01-PLAN.md"), [
|
|
369
|
+
"# S01: Test Slice",
|
|
370
|
+
"",
|
|
371
|
+
"## Tasks",
|
|
372
|
+
"",
|
|
373
|
+
"### T01 -- Implement feature",
|
|
374
|
+
"",
|
|
375
|
+
"Feature description.",
|
|
376
|
+
"",
|
|
377
|
+
"### T02 -- Write tests",
|
|
378
|
+
"",
|
|
379
|
+
"Test description.",
|
|
380
|
+
].join("\n"));
|
|
381
|
+
writeFileSync(join(tasksDir, "T01-PLAN.md"), "# T01 Plan");
|
|
382
|
+
writeFileSync(join(tasksDir, "T02-PLAN.md"), "# T02 Plan");
|
|
383
|
+
assert.strictEqual(
|
|
384
|
+
verifyExpectedArtifact("plan-slice", "M001/S01", base),
|
|
385
|
+
true,
|
|
386
|
+
"Heading-style plan with task entries should be treated as completed artifact",
|
|
387
|
+
);
|
|
420
388
|
});
|
|
421
389
|
|
|
422
|
-
test("verifyExpectedArtifact accepts plan-slice with colon-style heading tasks (### T01:)", () => {
|
|
390
|
+
test("verifyExpectedArtifact accepts plan-slice with colon-style heading tasks (### T01:)", (t) => {
|
|
423
391
|
const base = makeTmpBase();
|
|
392
|
+
t.after(() => cleanup(base));
|
|
393
|
+
|
|
394
|
+
const sliceDir = join(base, ".gsd", "milestones", "M001", "slices", "S01");
|
|
395
|
+
const tasksDir = join(sliceDir, "tasks");
|
|
396
|
+
mkdirSync(tasksDir, { recursive: true });
|
|
397
|
+
writeFileSync(join(sliceDir, "S01-PLAN.md"), [
|
|
398
|
+
"# S01: Test Slice",
|
|
399
|
+
"",
|
|
400
|
+
"## Tasks",
|
|
401
|
+
"",
|
|
402
|
+
"### T01: Implement feature",
|
|
403
|
+
"",
|
|
404
|
+
"Feature description.",
|
|
405
|
+
].join("\n"));
|
|
406
|
+
writeFileSync(join(tasksDir, "T01-PLAN.md"), "# T01 Plan");
|
|
407
|
+
assert.strictEqual(
|
|
408
|
+
verifyExpectedArtifact("plan-slice", "M001/S01", base),
|
|
409
|
+
true,
|
|
410
|
+
"Colon heading-style plan should be treated as completed artifact",
|
|
411
|
+
);
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
test("verifyExpectedArtifact execute-task passes for heading-style plan entry (#1691)", (t) => {
|
|
415
|
+
const base = makeTmpBase();
|
|
416
|
+
t.after(() => cleanup(base));
|
|
417
|
+
|
|
418
|
+
const sliceDir = join(base, ".gsd", "milestones", "M001", "slices", "S01");
|
|
419
|
+
const tasksDir = join(sliceDir, "tasks");
|
|
420
|
+
mkdirSync(tasksDir, { recursive: true });
|
|
421
|
+
writeFileSync(join(sliceDir, "S01-PLAN.md"), [
|
|
422
|
+
"# S01: Test Slice",
|
|
423
|
+
"",
|
|
424
|
+
"## Tasks",
|
|
425
|
+
"",
|
|
426
|
+
"### T01 -- Implement feature",
|
|
427
|
+
"",
|
|
428
|
+
"Feature description.",
|
|
429
|
+
].join("\n"));
|
|
430
|
+
writeFileSync(join(tasksDir, "T01-SUMMARY.md"), "# T01 Summary\n\nDone.");
|
|
431
|
+
assert.strictEqual(
|
|
432
|
+
verifyExpectedArtifact("execute-task", "M001/S01/T01", base),
|
|
433
|
+
true,
|
|
434
|
+
"execute-task should pass for heading-style plan entry when summary exists",
|
|
435
|
+
);
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
test("verifyExpectedArtifact plan-slice passes for rendered slice/task plan artifacts from DB", async () => {
|
|
439
|
+
const base = makeTmpBase();
|
|
440
|
+
const dbPath = join(base, ".gsd", "gsd.db");
|
|
441
|
+
openDatabase(dbPath);
|
|
424
442
|
try {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
"",
|
|
431
|
-
"
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
+
insertMilestone({ id: "M001", title: "Milestone", status: "active" });
|
|
444
|
+
insertSlice({
|
|
445
|
+
id: "S01",
|
|
446
|
+
milestoneId: "M001",
|
|
447
|
+
title: "Rendered slice",
|
|
448
|
+
status: "pending",
|
|
449
|
+
demo: "Rendered plan artifacts exist.",
|
|
450
|
+
planning: {
|
|
451
|
+
goal: "Render plans from DB rows.",
|
|
452
|
+
successCriteria: "- Slice plan parses\n- Task plan files exist on disk",
|
|
453
|
+
proofLevel: "integration",
|
|
454
|
+
integrationClosure: "DB rows are the source of truth for PLAN artifacts.",
|
|
455
|
+
observabilityImpact: "- Recovery verification fails if a task plan file is missing",
|
|
456
|
+
},
|
|
457
|
+
});
|
|
458
|
+
insertTask({
|
|
459
|
+
id: "T01",
|
|
460
|
+
sliceId: "S01",
|
|
461
|
+
milestoneId: "M001",
|
|
462
|
+
title: "Render plan",
|
|
463
|
+
status: "pending",
|
|
464
|
+
planning: {
|
|
465
|
+
description: "Create the slice plan from DB state.",
|
|
466
|
+
estimate: "30m",
|
|
467
|
+
files: ["src/resources/extensions/gsd/markdown-renderer.ts"],
|
|
468
|
+
verify: "node --test markdown-renderer.test.ts",
|
|
469
|
+
inputs: ["src/resources/extensions/gsd/gsd-db.ts"],
|
|
470
|
+
expectedOutput: ["src/resources/extensions/gsd/tests/markdown-renderer.test.ts"],
|
|
471
|
+
observabilityImpact: "Renderer tests cover the failure mode.",
|
|
472
|
+
},
|
|
473
|
+
});
|
|
474
|
+
insertTask({
|
|
475
|
+
id: "T02",
|
|
476
|
+
sliceId: "S01",
|
|
477
|
+
milestoneId: "M001",
|
|
478
|
+
title: "Verify recovery",
|
|
479
|
+
status: "pending",
|
|
480
|
+
planning: {
|
|
481
|
+
description: "Prove task plan files remain present for recovery.",
|
|
482
|
+
estimate: "20m",
|
|
483
|
+
files: ["src/resources/extensions/gsd/auto-recovery.ts"],
|
|
484
|
+
verify: "node --test auto-recovery.test.ts",
|
|
485
|
+
inputs: ["src/resources/extensions/gsd/auto-recovery.ts"],
|
|
486
|
+
expectedOutput: ["src/resources/extensions/gsd/tests/auto-recovery.test.ts"],
|
|
487
|
+
observabilityImpact: "Missing plan files surface as explicit verification failures.",
|
|
488
|
+
},
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
const rendered = await renderPlanFromDb(base, "M001", "S01");
|
|
492
|
+
assert.ok(existsSync(rendered.planPath), "renderPlanFromDb should write the slice plan");
|
|
493
|
+
assert.equal(rendered.taskPlanPaths.length, 2, "renderPlanFromDb should render one task plan per task");
|
|
494
|
+
|
|
495
|
+
const planContent = readFileSync(rendered.planPath, "utf-8");
|
|
496
|
+
const parsedPlan = parsePlan(planContent);
|
|
497
|
+
assert.equal(parsedPlan.tasks.length, 2, "rendered slice plan should parse into task entries");
|
|
498
|
+
|
|
499
|
+
const taskPlanContent = readFileSync(rendered.taskPlanPaths[0], "utf-8");
|
|
500
|
+
const taskPlan = parseTaskPlanFile(taskPlanContent);
|
|
501
|
+
assert.deepEqual(taskPlan.frontmatter.skills_used, [], "rendered task plans should use conservative empty skills_used");
|
|
502
|
+
|
|
503
|
+
const result = verifyExpectedArtifact("plan-slice", "M001/S01", base);
|
|
504
|
+
assert.equal(result, true, "plan-slice verification should pass when rendered task plan files exist");
|
|
443
505
|
} finally {
|
|
506
|
+
closeDatabase();
|
|
444
507
|
cleanup(base);
|
|
445
508
|
}
|
|
446
509
|
});
|
|
447
510
|
|
|
448
|
-
test("verifyExpectedArtifact
|
|
511
|
+
test("verifyExpectedArtifact plan-slice fails after deleting a rendered task plan file", async () => {
|
|
449
512
|
const base = makeTmpBase();
|
|
513
|
+
const dbPath = join(base, ".gsd", "gsd.db");
|
|
514
|
+
openDatabase(dbPath);
|
|
450
515
|
try {
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
"",
|
|
457
|
-
"
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
516
|
+
insertMilestone({ id: "M001", title: "Milestone", status: "active" });
|
|
517
|
+
insertSlice({
|
|
518
|
+
id: "S01",
|
|
519
|
+
milestoneId: "M001",
|
|
520
|
+
title: "Rendered slice",
|
|
521
|
+
status: "pending",
|
|
522
|
+
demo: "Rendered plan artifacts exist.",
|
|
523
|
+
planning: {
|
|
524
|
+
goal: "Render plans from DB rows.",
|
|
525
|
+
successCriteria: "- Slice plan parses\n- Task plan files exist on disk",
|
|
526
|
+
proofLevel: "integration",
|
|
527
|
+
integrationClosure: "DB rows are the source of truth for PLAN artifacts.",
|
|
528
|
+
observabilityImpact: "- Recovery verification fails if a task plan file is missing",
|
|
529
|
+
},
|
|
530
|
+
});
|
|
531
|
+
insertTask({
|
|
532
|
+
id: "T01",
|
|
533
|
+
sliceId: "S01",
|
|
534
|
+
milestoneId: "M001",
|
|
535
|
+
title: "Render plan",
|
|
536
|
+
status: "pending",
|
|
537
|
+
planning: {
|
|
538
|
+
description: "Create the slice plan from DB state.",
|
|
539
|
+
estimate: "30m",
|
|
540
|
+
files: ["src/resources/extensions/gsd/markdown-renderer.ts"],
|
|
541
|
+
verify: "node --test markdown-renderer.test.ts",
|
|
542
|
+
inputs: ["src/resources/extensions/gsd/gsd-db.ts"],
|
|
543
|
+
expectedOutput: ["src/resources/extensions/gsd/tests/markdown-renderer.test.ts"],
|
|
544
|
+
observabilityImpact: "Renderer tests cover the failure mode.",
|
|
545
|
+
},
|
|
546
|
+
});
|
|
547
|
+
insertTask({
|
|
548
|
+
id: "T02",
|
|
549
|
+
sliceId: "S01",
|
|
550
|
+
milestoneId: "M001",
|
|
551
|
+
title: "Verify recovery",
|
|
552
|
+
status: "pending",
|
|
553
|
+
planning: {
|
|
554
|
+
description: "Prove task plan files remain present for recovery.",
|
|
555
|
+
estimate: "20m",
|
|
556
|
+
files: ["src/resources/extensions/gsd/auto-recovery.ts"],
|
|
557
|
+
verify: "node --test auto-recovery.test.ts",
|
|
558
|
+
inputs: ["src/resources/extensions/gsd/auto-recovery.ts"],
|
|
559
|
+
expectedOutput: ["src/resources/extensions/gsd/tests/auto-recovery.test.ts"],
|
|
560
|
+
observabilityImpact: "Missing plan files surface as explicit verification failures.",
|
|
561
|
+
},
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
const rendered = await renderPlanFromDb(base, "M001", "S01");
|
|
565
|
+
rmSync(rendered.taskPlanPaths[1]);
|
|
566
|
+
|
|
567
|
+
const result = verifyExpectedArtifact("plan-slice", "M001/S01", base);
|
|
568
|
+
assert.equal(result, false, "plan-slice verification should fail when a rendered task plan file is removed");
|
|
469
569
|
} finally {
|
|
570
|
+
closeDatabase();
|
|
470
571
|
cleanup(base);
|
|
471
572
|
}
|
|
472
573
|
});
|
|
473
574
|
|
|
474
575
|
// ─── selfHealRuntimeRecords — worktree base path (#769) ──────────────────
|
|
475
576
|
|
|
476
|
-
test("selfHealRuntimeRecords clears stale dispatched records (#769)", async () => {
|
|
577
|
+
test("selfHealRuntimeRecords clears stale dispatched records (#769)", async (t) => {
|
|
477
578
|
// selfHealRuntimeRecords now only clears stale dispatched records (>1h).
|
|
478
579
|
// No completedKeySet parameter — deriveState is sole authority.
|
|
479
580
|
const worktreeBase = makeTmpBase();
|
|
480
581
|
const mainBase = makeTmpBase();
|
|
481
|
-
|
|
482
|
-
const { writeUnitRuntimeRecord, readUnitRuntimeRecord } = await import("../unit-runtime.ts");
|
|
483
|
-
|
|
484
|
-
// Write a stale runtime record in the worktree .gsd/runtime/units/
|
|
485
|
-
writeUnitRuntimeRecord(worktreeBase, "run-uat", "M001/S01", Date.now() - 7200_000, {
|
|
486
|
-
phase: "dispatched",
|
|
487
|
-
});
|
|
488
|
-
|
|
489
|
-
// Verify the runtime record exists before heal
|
|
490
|
-
const before = readUnitRuntimeRecord(worktreeBase, "run-uat", "M001/S01");
|
|
491
|
-
assert.ok(before, "runtime record should exist before heal");
|
|
492
|
-
|
|
493
|
-
// Mock ExtensionContext with minimal notify
|
|
494
|
-
const notifications: string[] = [];
|
|
495
|
-
const mockCtx = {
|
|
496
|
-
ui: { notify: (msg: string) => { notifications.push(msg); } },
|
|
497
|
-
} as any;
|
|
498
|
-
|
|
499
|
-
// Call selfHeal with worktreeBase — should clear the stale record
|
|
500
|
-
await selfHealRuntimeRecords(worktreeBase, mockCtx);
|
|
501
|
-
|
|
502
|
-
// The stale record should be cleared
|
|
503
|
-
const after = readUnitRuntimeRecord(worktreeBase, "run-uat", "M001/S01");
|
|
504
|
-
assert.equal(after, null, "runtime record should be cleared after heal");
|
|
505
|
-
assert.ok(notifications.some(n => n.includes("Self-heal")), "should emit self-heal notification");
|
|
506
|
-
|
|
507
|
-
// Write a stale record at mainBase
|
|
508
|
-
writeUnitRuntimeRecord(mainBase, "run-uat", "M001/S01", Date.now() - 7200_000, {
|
|
509
|
-
phase: "dispatched",
|
|
510
|
-
});
|
|
511
|
-
await selfHealRuntimeRecords(mainBase, mockCtx);
|
|
512
|
-
|
|
513
|
-
// The record at mainBase should also be cleared by the stale timeout (>1h)
|
|
514
|
-
const afterMain = readUnitRuntimeRecord(mainBase, "run-uat", "M001/S01");
|
|
515
|
-
assert.equal(afterMain, null, "stale record at main base should be cleared by timeout");
|
|
516
|
-
} finally {
|
|
582
|
+
t.after(() => {
|
|
517
583
|
cleanup(worktreeBase);
|
|
518
584
|
cleanup(mainBase);
|
|
519
|
-
}
|
|
585
|
+
});
|
|
586
|
+
|
|
587
|
+
const { writeUnitRuntimeRecord, readUnitRuntimeRecord } = await import("../unit-runtime.ts");
|
|
588
|
+
|
|
589
|
+
// Write a stale runtime record in the worktree .gsd/runtime/units/
|
|
590
|
+
writeUnitRuntimeRecord(worktreeBase, "run-uat", "M001/S01", Date.now() - 7200_000, {
|
|
591
|
+
phase: "dispatched",
|
|
592
|
+
});
|
|
593
|
+
|
|
594
|
+
// Verify the runtime record exists before heal
|
|
595
|
+
const before = readUnitRuntimeRecord(worktreeBase, "run-uat", "M001/S01");
|
|
596
|
+
assert.ok(before, "runtime record should exist before heal");
|
|
597
|
+
|
|
598
|
+
// Mock ExtensionContext with minimal notify
|
|
599
|
+
const notifications: string[] = [];
|
|
600
|
+
const mockCtx = {
|
|
601
|
+
ui: { notify: (msg: string) => { notifications.push(msg); } },
|
|
602
|
+
} as any;
|
|
603
|
+
|
|
604
|
+
// Call selfHeal with worktreeBase — should clear the stale record
|
|
605
|
+
await selfHealRuntimeRecords(worktreeBase, mockCtx);
|
|
606
|
+
|
|
607
|
+
// The stale record should be cleared
|
|
608
|
+
const after = readUnitRuntimeRecord(worktreeBase, "run-uat", "M001/S01");
|
|
609
|
+
assert.equal(after, null, "runtime record should be cleared after heal");
|
|
610
|
+
assert.ok(notifications.some(n => n.includes("Self-heal")), "should emit self-heal notification");
|
|
611
|
+
|
|
612
|
+
// Write a stale record at mainBase
|
|
613
|
+
writeUnitRuntimeRecord(mainBase, "run-uat", "M001/S01", Date.now() - 7200_000, {
|
|
614
|
+
phase: "dispatched",
|
|
615
|
+
});
|
|
616
|
+
await selfHealRuntimeRecords(mainBase, mockCtx);
|
|
617
|
+
|
|
618
|
+
// The record at mainBase should also be cleared by the stale timeout (>1h)
|
|
619
|
+
const afterMain = readUnitRuntimeRecord(mainBase, "run-uat", "M001/S01");
|
|
620
|
+
assert.equal(afterMain, null, "stale record at main base should be cleared by timeout");
|
|
520
621
|
});
|
|
521
622
|
|
|
522
623
|
// ─── #1625: selfHealRuntimeRecords on resume clears paused-session leftovers ──
|
|
523
624
|
|
|
524
|
-
test("selfHealRuntimeRecords clears recently-paused dispatched records on resume (#1625)", async () => {
|
|
625
|
+
test("selfHealRuntimeRecords clears recently-paused dispatched records on resume (#1625)", async (t) => {
|
|
525
626
|
// When pauseAuto closes out a unit but clearUnitRuntimeRecord silently fails
|
|
526
627
|
// (e.g. permission error), selfHealRuntimeRecords on resume should still
|
|
527
628
|
// clean up stale dispatched records that are >1h old.
|
|
528
629
|
const base = makeTmpBase();
|
|
529
|
-
|
|
530
|
-
const { writeUnitRuntimeRecord, readUnitRuntimeRecord } = await import("../unit-runtime.ts");
|
|
630
|
+
t.after(() => cleanup(base));
|
|
531
631
|
|
|
532
|
-
|
|
533
|
-
writeUnitRuntimeRecord(base, "execute-task", "M001/S01/T01", Date.now() - 3700_000, {
|
|
534
|
-
phase: "dispatched",
|
|
535
|
-
});
|
|
632
|
+
const { writeUnitRuntimeRecord, readUnitRuntimeRecord } = await import("../unit-runtime.ts");
|
|
536
633
|
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
634
|
+
// Simulate a record left behind after a pause — aged >1h to be considered stale
|
|
635
|
+
writeUnitRuntimeRecord(base, "execute-task", "M001/S01/T01", Date.now() - 3700_000, {
|
|
636
|
+
phase: "dispatched",
|
|
637
|
+
});
|
|
540
638
|
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
} as any;
|
|
639
|
+
const before = readUnitRuntimeRecord(base, "execute-task", "M001/S01/T01");
|
|
640
|
+
assert.ok(before, "dispatched record should exist before resume heal");
|
|
641
|
+
assert.equal(before!.phase, "dispatched");
|
|
545
642
|
|
|
546
|
-
|
|
643
|
+
const notifications: string[] = [];
|
|
644
|
+
const mockCtx = {
|
|
645
|
+
ui: { notify: (msg: string) => { notifications.push(msg); } },
|
|
646
|
+
} as any;
|
|
547
647
|
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
}
|
|
648
|
+
await selfHealRuntimeRecords(base, mockCtx);
|
|
649
|
+
|
|
650
|
+
const after = readUnitRuntimeRecord(base, "execute-task", "M001/S01/T01");
|
|
651
|
+
assert.equal(after, null, "stale dispatched record should be cleared on resume (#1625)");
|
|
553
652
|
});
|
|
554
653
|
|
|
555
654
|
// ─── #793: invalidateAllCaches unblocks skip-loop ─────────────────────────
|
|
@@ -557,51 +656,49 @@ test("selfHealRuntimeRecords clears recently-paused dispatched records on resume
|
|
|
557
656
|
// just invalidateStateCache()) to clear path/parse caches that deriveState
|
|
558
657
|
// depends on. Without this, even after cache invalidation, deriveState reads
|
|
559
658
|
// stale directory listings and returns the same unit, looping forever.
|
|
560
|
-
test("#793: invalidateAllCaches clears all caches so deriveState sees fresh disk state", async () => {
|
|
659
|
+
test("#793: invalidateAllCaches clears all caches so deriveState sees fresh disk state", async (t) => {
|
|
561
660
|
const base = makeTmpBase();
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
cleanup(base);
|
|
604
|
-
}
|
|
661
|
+
t.after(() => cleanup(base));
|
|
662
|
+
|
|
663
|
+
const mid = "M001";
|
|
664
|
+
const sid = "S01";
|
|
665
|
+
const planDir = join(base, ".gsd", "milestones", mid, "slices", sid);
|
|
666
|
+
const tasksDir = join(planDir, "tasks");
|
|
667
|
+
mkdirSync(tasksDir, { recursive: true });
|
|
668
|
+
mkdirSync(join(base, ".gsd", "milestones", mid), { recursive: true });
|
|
669
|
+
|
|
670
|
+
writeFileSync(
|
|
671
|
+
join(base, ".gsd", "milestones", mid, `${mid}-ROADMAP.md`),
|
|
672
|
+
`# M001: Test Milestone\n\n**Vision:** test.\n\n## Slices\n\n- [ ] **${sid}: Slice One** \`risk:low\` \`depends:[]\`\n > After this: done.\n`,
|
|
673
|
+
);
|
|
674
|
+
const planUnchecked = `# ${sid}: Slice One\n\n**Goal:** test.\n\n## Tasks\n\n- [ ] **T01: Task One** \`est:10m\`\n- [ ] **T02: Task Two** \`est:10m\`\n`;
|
|
675
|
+
writeFileSync(join(planDir, `${sid}-PLAN.md`), planUnchecked);
|
|
676
|
+
writeFileSync(join(tasksDir, "T01-PLAN.md"), "# T01: Task One\n\n**Goal:** t\n\n## Steps\n- step\n\n## Verification\n- v\n");
|
|
677
|
+
writeFileSync(join(tasksDir, "T02-PLAN.md"), "# T02: Task Two\n\n**Goal:** t\n\n## Steps\n- step\n\n## Verification\n- v\n");
|
|
678
|
+
|
|
679
|
+
// Warm all caches
|
|
680
|
+
const state1 = await deriveState(base);
|
|
681
|
+
assert.equal(state1.activeTask?.id, "T01", "initial: T01 is active");
|
|
682
|
+
|
|
683
|
+
// Simulate task completion on disk (what the LLM does)
|
|
684
|
+
const planChecked = `# ${sid}: Slice One\n\n**Goal:** test.\n\n## Tasks\n\n- [x] **T01: Task One** \`est:10m\`\n- [ ] **T02: Task Two** \`est:10m\`\n`;
|
|
685
|
+
writeFileSync(join(planDir, `${sid}-PLAN.md`), planChecked);
|
|
686
|
+
writeFileSync(join(tasksDir, "T01-SUMMARY.md"), "---\nid: T01\n---\n# Summary\n");
|
|
687
|
+
|
|
688
|
+
// invalidateStateCache alone: _stateCache cleared but path/parse caches warm
|
|
689
|
+
invalidateStateCache();
|
|
690
|
+
|
|
691
|
+
// invalidateAllCaches: all caches cleared — deriveState must re-read disk
|
|
692
|
+
invalidateAllCaches();
|
|
693
|
+
const state2 = await deriveState(base);
|
|
694
|
+
|
|
695
|
+
// After full invalidation, T01 should be complete and T02 should be next
|
|
696
|
+
assert.notEqual(state2.activeTask?.id, "T01", "#793: T01 not re-dispatched after full invalidation");
|
|
697
|
+
|
|
698
|
+
// Verify the caches are truly cleared by calling clearParseCache and clearPathCache
|
|
699
|
+
// do not throw (they should be no-ops after invalidateAllCaches already cleared them)
|
|
700
|
+
clearParseCache(); // no-op, but should not throw
|
|
701
|
+
assert.ok(true, "clearParseCache after invalidateAllCaches is safe");
|
|
605
702
|
});
|
|
606
703
|
|
|
607
704
|
// ─── hasImplementationArtifacts (#1703) ───────────────────────────────────
|
|
@@ -621,88 +718,78 @@ function makeGitBase(): string {
|
|
|
621
718
|
return base;
|
|
622
719
|
}
|
|
623
720
|
|
|
624
|
-
test("hasImplementationArtifacts returns false when only .gsd/ files committed (#1703)", () => {
|
|
721
|
+
test("hasImplementationArtifacts returns false when only .gsd/ files committed (#1703)", (t) => {
|
|
625
722
|
const base = makeGitBase();
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
cleanup(base);
|
|
639
|
-
}
|
|
723
|
+
t.after(() => cleanup(base));
|
|
724
|
+
|
|
725
|
+
// Create a feature branch and commit only .gsd/ files
|
|
726
|
+
execFileSync("git", ["checkout", "-b", "feat/test-milestone"], { cwd: base, stdio: "ignore" });
|
|
727
|
+
mkdirSync(join(base, ".gsd", "milestones", "M001"), { recursive: true });
|
|
728
|
+
writeFileSync(join(base, ".gsd", "milestones", "M001", "M001-ROADMAP.md"), "# Roadmap");
|
|
729
|
+
writeFileSync(join(base, ".gsd", "milestones", "M001", "M001-SUMMARY.md"), "# Summary");
|
|
730
|
+
execFileSync("git", ["add", "."], { cwd: base, stdio: "ignore" });
|
|
731
|
+
execFileSync("git", ["commit", "-m", "chore: add plan files"], { cwd: base, stdio: "ignore" });
|
|
732
|
+
|
|
733
|
+
const result = hasImplementationArtifacts(base);
|
|
734
|
+
assert.equal(result, false, "should return false when only .gsd/ files were committed");
|
|
640
735
|
});
|
|
641
736
|
|
|
642
|
-
test("hasImplementationArtifacts returns true when implementation files committed (#1703)", () => {
|
|
737
|
+
test("hasImplementationArtifacts returns true when implementation files committed (#1703)", (t) => {
|
|
643
738
|
const base = makeGitBase();
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
cleanup(base);
|
|
658
|
-
}
|
|
739
|
+
t.after(() => cleanup(base));
|
|
740
|
+
|
|
741
|
+
// Create a feature branch with both .gsd/ and implementation files
|
|
742
|
+
execFileSync("git", ["checkout", "-b", "feat/test-impl"], { cwd: base, stdio: "ignore" });
|
|
743
|
+
mkdirSync(join(base, ".gsd", "milestones", "M001"), { recursive: true });
|
|
744
|
+
writeFileSync(join(base, ".gsd", "milestones", "M001", "M001-ROADMAP.md"), "# Roadmap");
|
|
745
|
+
mkdirSync(join(base, "src"), { recursive: true });
|
|
746
|
+
writeFileSync(join(base, "src", "feature.ts"), "export function feature() {}");
|
|
747
|
+
execFileSync("git", ["add", "."], { cwd: base, stdio: "ignore" });
|
|
748
|
+
execFileSync("git", ["commit", "-m", "feat: add feature"], { cwd: base, stdio: "ignore" });
|
|
749
|
+
|
|
750
|
+
const result = hasImplementationArtifacts(base);
|
|
751
|
+
assert.equal(result, true, "should return true when implementation files are present");
|
|
659
752
|
});
|
|
660
753
|
|
|
661
|
-
test("hasImplementationArtifacts returns true on non-git directory (fail-open)", () => {
|
|
754
|
+
test("hasImplementationArtifacts returns true on non-git directory (fail-open)", (t) => {
|
|
662
755
|
const base = join(tmpdir(), `gsd-test-nogit-${randomUUID()}`);
|
|
663
756
|
mkdirSync(base, { recursive: true });
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
cleanup(base);
|
|
669
|
-
}
|
|
757
|
+
t.after(() => cleanup(base));
|
|
758
|
+
|
|
759
|
+
const result = hasImplementationArtifacts(base);
|
|
760
|
+
assert.equal(result, true, "should return true (fail-open) in non-git directory");
|
|
670
761
|
});
|
|
671
762
|
|
|
672
763
|
// ─── verifyExpectedArtifact: complete-milestone requires impl artifacts (#1703) ──
|
|
673
764
|
|
|
674
|
-
test("verifyExpectedArtifact complete-milestone fails with only .gsd/ files (#1703)", () => {
|
|
765
|
+
test("verifyExpectedArtifact complete-milestone fails with only .gsd/ files (#1703)", (t) => {
|
|
675
766
|
const base = makeGitBase();
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
cleanup(base);
|
|
688
|
-
}
|
|
767
|
+
t.after(() => cleanup(base));
|
|
768
|
+
|
|
769
|
+
// Create feature branch with only .gsd/ files
|
|
770
|
+
execFileSync("git", ["checkout", "-b", "feat/ms-only-gsd"], { cwd: base, stdio: "ignore" });
|
|
771
|
+
mkdirSync(join(base, ".gsd", "milestones", "M001"), { recursive: true });
|
|
772
|
+
writeFileSync(join(base, ".gsd", "milestones", "M001", "M001-SUMMARY.md"), "# Milestone Summary\nDone.");
|
|
773
|
+
execFileSync("git", ["add", "."], { cwd: base, stdio: "ignore" });
|
|
774
|
+
execFileSync("git", ["commit", "-m", "chore: milestone plan files"], { cwd: base, stdio: "ignore" });
|
|
775
|
+
|
|
776
|
+
const result = verifyExpectedArtifact("complete-milestone", "M001", base);
|
|
777
|
+
assert.equal(result, false, "complete-milestone should fail verification when only .gsd/ files present");
|
|
689
778
|
});
|
|
690
779
|
|
|
691
|
-
test("verifyExpectedArtifact complete-milestone passes with impl files (#1703)", () => {
|
|
780
|
+
test("verifyExpectedArtifact complete-milestone passes with impl files (#1703)", (t) => {
|
|
692
781
|
const base = makeGitBase();
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
cleanup(base);
|
|
707
|
-
}
|
|
782
|
+
t.after(() => cleanup(base));
|
|
783
|
+
|
|
784
|
+
// Create feature branch with implementation files AND milestone summary
|
|
785
|
+
execFileSync("git", ["checkout", "-b", "feat/ms-with-impl"], { cwd: base, stdio: "ignore" });
|
|
786
|
+
mkdirSync(join(base, ".gsd", "milestones", "M001"), { recursive: true });
|
|
787
|
+
writeFileSync(join(base, ".gsd", "milestones", "M001", "M001-SUMMARY.md"), "# Milestone Summary\nDone.");
|
|
788
|
+
mkdirSync(join(base, "src"), { recursive: true });
|
|
789
|
+
writeFileSync(join(base, "src", "app.ts"), "console.log('hello');");
|
|
790
|
+
execFileSync("git", ["add", "."], { cwd: base, stdio: "ignore" });
|
|
791
|
+
execFileSync("git", ["commit", "-m", "feat: implementation"], { cwd: base, stdio: "ignore" });
|
|
792
|
+
|
|
793
|
+
const result = verifyExpectedArtifact("complete-milestone", "M001", base);
|
|
794
|
+
assert.equal(result, true, "complete-milestone should pass verification with implementation files");
|
|
708
795
|
});
|