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
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { describe, test } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
1
3
|
import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
2
4
|
import { join, dirname } from 'node:path';
|
|
3
5
|
import { tmpdir } from 'node:os';
|
|
@@ -22,7 +24,6 @@ function loadPromptFromWorktree(name: string, vars: Record<string, string> = {})
|
|
|
22
24
|
return content.trim();
|
|
23
25
|
}
|
|
24
26
|
|
|
25
|
-
const { assertEq, assertTrue, report } = createTestContext();
|
|
26
27
|
// ─── Fixture Helpers ───────────────────────────────────────────────────────
|
|
27
28
|
|
|
28
29
|
function createFixtureBase(): string {
|
|
@@ -161,7 +162,7 @@ Found a blocker.
|
|
|
161
162
|
`;
|
|
162
163
|
|
|
163
164
|
const s = parseSummary(content);
|
|
164
|
-
|
|
165
|
+
assert.deepStrictEqual(s.frontmatter.blocker_discovered, true, 'blocker_discovered: true (string) extracts as true');
|
|
165
166
|
}
|
|
166
167
|
|
|
167
168
|
console.log('\n=== parseSummary: blocker_discovered false (string) ===');
|
|
@@ -184,7 +185,7 @@ No blocker.
|
|
|
184
185
|
`;
|
|
185
186
|
|
|
186
187
|
const s = parseSummary(content);
|
|
187
|
-
|
|
188
|
+
assert.deepStrictEqual(s.frontmatter.blocker_discovered, false, 'blocker_discovered: false extracts as false');
|
|
188
189
|
}
|
|
189
190
|
|
|
190
191
|
console.log('\n=== parseSummary: blocker_discovered missing (defaults to false) ===');
|
|
@@ -206,7 +207,7 @@ No blocker field at all.
|
|
|
206
207
|
`;
|
|
207
208
|
|
|
208
209
|
const s = parseSummary(content);
|
|
209
|
-
|
|
210
|
+
assert.deepStrictEqual(s.frontmatter.blocker_discovered, false, 'blocker_discovered missing defaults to false');
|
|
210
211
|
}
|
|
211
212
|
|
|
212
213
|
console.log('\n=== parseSummary: blocker_discovered true (boolean from YAML) ===');
|
|
@@ -232,7 +233,7 @@ Blocker as boolean.
|
|
|
232
233
|
`;
|
|
233
234
|
|
|
234
235
|
const s = parseSummary(content);
|
|
235
|
-
|
|
236
|
+
assert.deepStrictEqual(s.frontmatter.blocker_discovered, true, 'blocker_discovered: true (YAML boolean) extracts as true');
|
|
236
237
|
}
|
|
237
238
|
|
|
238
239
|
console.log('\n=== parseSummary: blocker_discovered with full frontmatter ===');
|
|
@@ -275,10 +276,10 @@ Major deviation from plan.
|
|
|
275
276
|
`;
|
|
276
277
|
|
|
277
278
|
const s = parseSummary(content);
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
279
|
+
assert.deepStrictEqual(s.frontmatter.blocker_discovered, true, 'blocker_discovered true with full frontmatter');
|
|
280
|
+
assert.deepStrictEqual(s.frontmatter.id, 'T05', 'other fields still parse correctly alongside blocker_discovered');
|
|
281
|
+
assert.deepStrictEqual(s.frontmatter.duration, '15min', 'duration still parsed');
|
|
282
|
+
assert.deepStrictEqual(s.frontmatter.provides[0], 'something', 'provides still parsed');
|
|
282
283
|
}
|
|
283
284
|
|
|
284
285
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -294,11 +295,11 @@ console.log('\n=== deriveState: blocker found, no REPLAN → replanning-slice ==
|
|
|
294
295
|
writeTaskSummary(base, 'M001', 'S01', 'T01', makeTaskSummary('T01', true));
|
|
295
296
|
|
|
296
297
|
const state = await deriveState(base);
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
298
|
+
assert.deepStrictEqual(state.phase, 'replanning-slice', 'phase is replanning-slice when blocker found and no REPLAN.md');
|
|
299
|
+
assert.ok(state.nextAction.includes('T01'), 'nextAction mentions blocker task T01');
|
|
300
|
+
assert.ok(state.nextAction.includes('blocker_discovered'), 'nextAction mentions blocker_discovered');
|
|
301
|
+
assert.deepStrictEqual(state.activeTask?.id, 'T02', 'activeTask is still T02 (the next incomplete task)');
|
|
302
|
+
assert.ok(state.blockers.length > 0, 'blockers array is non-empty');
|
|
302
303
|
rmSync(base, { recursive: true, force: true });
|
|
303
304
|
}
|
|
304
305
|
|
|
@@ -312,8 +313,8 @@ console.log('\n=== deriveState: blocker found + REPLAN exists → executing (loo
|
|
|
312
313
|
writeReplanFile(base, 'M001', 'S01', '# Replan\n\nAlready replanned.');
|
|
313
314
|
|
|
314
315
|
const state = await deriveState(base);
|
|
315
|
-
|
|
316
|
-
|
|
316
|
+
assert.deepStrictEqual(state.phase, 'executing', 'phase is executing when REPLAN.md exists (loop protection)');
|
|
317
|
+
assert.deepStrictEqual(state.activeTask?.id, 'T02', 'activeTask is T02');
|
|
317
318
|
rmSync(base, { recursive: true, force: true });
|
|
318
319
|
}
|
|
319
320
|
|
|
@@ -326,8 +327,8 @@ console.log('\n=== deriveState: no blocker in completed tasks → executing ==='
|
|
|
326
327
|
writeTaskSummary(base, 'M001', 'S01', 'T01', makeTaskSummary('T01', false));
|
|
327
328
|
|
|
328
329
|
const state = await deriveState(base);
|
|
329
|
-
|
|
330
|
-
|
|
330
|
+
assert.deepStrictEqual(state.phase, 'executing', 'phase is executing when no blocker found');
|
|
331
|
+
assert.deepStrictEqual(state.activeTask?.id, 'T02', 'activeTask is T02');
|
|
331
332
|
rmSync(base, { recursive: true, force: true });
|
|
332
333
|
}
|
|
333
334
|
|
|
@@ -341,9 +342,9 @@ console.log('\n=== deriveState: multiple completed tasks, one blocker → replan
|
|
|
341
342
|
writeTaskSummary(base, 'M001', 'S01', 'T02', makeTaskSummary('T02', true));
|
|
342
343
|
|
|
343
344
|
const state = await deriveState(base);
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
345
|
+
assert.deepStrictEqual(state.phase, 'replanning-slice', 'phase is replanning-slice when T02 has blocker');
|
|
346
|
+
assert.ok(state.nextAction.includes('T02'), 'nextAction mentions blocker task T02');
|
|
347
|
+
assert.deepStrictEqual(state.activeTask?.id, 'T03', 'activeTask is T03 (next incomplete)');
|
|
347
348
|
rmSync(base, { recursive: true, force: true });
|
|
348
349
|
}
|
|
349
350
|
|
|
@@ -356,7 +357,7 @@ console.log('\n=== deriveState: completed task with no summary file → executin
|
|
|
356
357
|
// No summary file written for T01
|
|
357
358
|
|
|
358
359
|
const state = await deriveState(base);
|
|
359
|
-
|
|
360
|
+
assert.deepStrictEqual(state.phase, 'executing', 'phase is executing when completed task has no summary');
|
|
360
361
|
rmSync(base, { recursive: true, force: true });
|
|
361
362
|
}
|
|
362
363
|
|
|
@@ -376,11 +377,11 @@ console.log('\n=== prompt: replan-slice template loads and substitutes variables
|
|
|
376
377
|
inlinedContext: '## Inlined Context\n\nTest context here.',
|
|
377
378
|
});
|
|
378
379
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
380
|
+
assert.ok(prompt.includes('M001'), 'prompt contains milestoneId');
|
|
381
|
+
assert.ok(prompt.includes('S01'), 'prompt contains sliceId');
|
|
382
|
+
assert.ok(prompt.includes('Test Slice'), 'prompt contains sliceTitle');
|
|
383
|
+
assert.ok(prompt.includes('.gsd/milestones/M001/slices/S01/S01-PLAN.md'), 'prompt contains planPath');
|
|
384
|
+
assert.ok(prompt.includes('Test context here'), 'prompt contains inlined context');
|
|
384
385
|
}
|
|
385
386
|
|
|
386
387
|
console.log('\n=== prompt: replan-slice contains preserve-completed-tasks instruction ===');
|
|
@@ -397,10 +398,10 @@ console.log('\n=== prompt: replan-slice contains preserve-completed-tasks instru
|
|
|
397
398
|
inlinedContext: '',
|
|
398
399
|
});
|
|
399
400
|
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
401
|
+
assert.ok(prompt.includes('Do NOT renumber or remove completed tasks'), 'prompt contains preserve-completed-tasks instruction');
|
|
402
|
+
assert.ok(prompt.includes('[x]'), 'prompt mentions [x] checkmarks');
|
|
403
|
+
assert.ok(prompt.includes('REPLAN'), 'prompt references replan output path');
|
|
404
|
+
assert.ok(prompt.includes('blocker_discovered'), 'prompt mentions blocker_discovered');
|
|
404
405
|
}
|
|
405
406
|
|
|
406
407
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -421,8 +422,8 @@ console.log('\n=== dispatch: diagnoseExpectedArtifact returns REPLAN.md path ===
|
|
|
421
422
|
writeTaskSummary(base, 'M001', 'S01', 'T01', makeTaskSummary('T01', true));
|
|
422
423
|
|
|
423
424
|
const state = await deriveState(base);
|
|
424
|
-
|
|
425
|
-
|
|
425
|
+
assert.deepStrictEqual(state.phase, 'replanning-slice', 'dispatch: state routes to replanning-slice when blocker found');
|
|
426
|
+
assert.ok(state.activeSlice?.id === 'S01', 'dispatch: activeSlice is S01');
|
|
426
427
|
rmSync(base, { recursive: true, force: true });
|
|
427
428
|
}
|
|
428
429
|
|
|
@@ -443,8 +444,8 @@ console.log('\n=== display: replan-slice prompt template has correct unit header
|
|
|
443
444
|
inlinedContext: '',
|
|
444
445
|
});
|
|
445
446
|
|
|
446
|
-
|
|
447
|
-
|
|
447
|
+
assert.ok(prompt.includes('UNIT: Replan Slice'), 'prompt has Replan Slice unit header');
|
|
448
|
+
assert.ok(prompt.includes('Slice S01 replanned'), 'prompt has completion message');
|
|
448
449
|
}
|
|
449
450
|
|
|
450
451
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -452,8 +453,6 @@ console.log('\n=== display: replan-slice prompt template has correct unit header
|
|
|
452
453
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
453
454
|
|
|
454
455
|
import { runGSDDoctor } from '../doctor.ts';
|
|
455
|
-
import { createTestContext } from './test-helpers.ts';
|
|
456
|
-
|
|
457
456
|
// (a) blocker + no REPLAN.md → issue emitted
|
|
458
457
|
console.log('\n=== doctor: blocker + no REPLAN.md → blocker_discovered_no_replan issue ===');
|
|
459
458
|
{
|
|
@@ -464,10 +463,10 @@ console.log('\n=== doctor: blocker + no REPLAN.md → blocker_discovered_no_repl
|
|
|
464
463
|
|
|
465
464
|
const report = await runGSDDoctor(base, { fix: false, scope: 'M001/S01' });
|
|
466
465
|
const blockerIssues = report.issues.filter(i => i.code === 'blocker_discovered_no_replan');
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
466
|
+
assert.ok(blockerIssues.length > 0, 'doctor emits blocker_discovered_no_replan when blocker + no REPLAN');
|
|
467
|
+
assert.ok(blockerIssues[0]?.message.includes('T01'), 'issue message mentions the blocker task T01');
|
|
468
|
+
assert.deepStrictEqual(blockerIssues[0]?.severity, 'warning', 'blocker_discovered_no_replan is warning severity');
|
|
469
|
+
assert.deepStrictEqual(blockerIssues[0]?.scope, 'slice', 'blocker_discovered_no_replan has slice scope');
|
|
471
470
|
rmSync(base, { recursive: true, force: true });
|
|
472
471
|
}
|
|
473
472
|
|
|
@@ -482,7 +481,7 @@ console.log('\n=== doctor: blocker + REPLAN.md exists → no blocker_discovered_
|
|
|
482
481
|
|
|
483
482
|
const report = await runGSDDoctor(base, { fix: false, scope: 'M001/S01' });
|
|
484
483
|
const blockerIssues = report.issues.filter(i => i.code === 'blocker_discovered_no_replan');
|
|
485
|
-
|
|
484
|
+
assert.deepStrictEqual(blockerIssues.length, 0, 'no blocker_discovered_no_replan when REPLAN.md exists');
|
|
486
485
|
rmSync(base, { recursive: true, force: true });
|
|
487
486
|
}
|
|
488
487
|
|
|
@@ -496,7 +495,7 @@ console.log('\n=== doctor: no blocker → no blocker_discovered_no_replan issue
|
|
|
496
495
|
|
|
497
496
|
const report = await runGSDDoctor(base, { fix: false, scope: 'M001/S01' });
|
|
498
497
|
const blockerIssues = report.issues.filter(i => i.code === 'blocker_discovered_no_replan');
|
|
499
|
-
|
|
498
|
+
assert.deepStrictEqual(blockerIssues.length, 0, 'no blocker_discovered_no_replan when no blocker');
|
|
500
499
|
rmSync(base, { recursive: true, force: true });
|
|
501
500
|
}
|
|
502
501
|
|
|
@@ -506,48 +505,45 @@ console.log('\n=== doctor: no blocker → no blocker_discovered_no_replan issue
|
|
|
506
505
|
|
|
507
506
|
import { resolveExpectedArtifactPath, verifyExpectedArtifact } from '../auto-recovery.ts';
|
|
508
507
|
|
|
509
|
-
|
|
510
|
-
{
|
|
508
|
+
|
|
509
|
+
describe('replan-slice', () => {
|
|
510
|
+
test('artifact: resolveExpectedArtifactPath returns REPLAN.md path for replan-slice', () => {
|
|
511
511
|
const base = createFixtureBase();
|
|
512
512
|
writeRoadmap(base, 'M001', ROADMAP_ONE_SLICE);
|
|
513
513
|
writePlan(base, 'M001', 'S01', makePlanT01DoneT02Pending());
|
|
514
514
|
|
|
515
515
|
const path = resolveExpectedArtifactPath('replan-slice', 'M001/S01', base);
|
|
516
|
-
|
|
517
|
-
|
|
516
|
+
assert.ok(path !== null, 'resolveExpectedArtifactPath returns non-null for replan-slice');
|
|
517
|
+
assert.ok(path!.endsWith('S01-REPLAN.md'), 'path ends with S01-REPLAN.md');
|
|
518
518
|
rmSync(base, { recursive: true, force: true });
|
|
519
|
-
}
|
|
519
|
+
});
|
|
520
520
|
|
|
521
|
-
|
|
522
|
-
{
|
|
521
|
+
test('artifact: verifyExpectedArtifact fails when REPLAN.md missing (#858)', () => {
|
|
523
522
|
const base = createFixtureBase();
|
|
524
523
|
writeRoadmap(base, 'M001', ROADMAP_ONE_SLICE);
|
|
525
524
|
writePlan(base, 'M001', 'S01', makePlanT01DoneT02Pending());
|
|
526
525
|
|
|
527
526
|
const result = verifyExpectedArtifact('replan-slice', 'M001/S01', base);
|
|
528
|
-
|
|
527
|
+
assert.deepStrictEqual(result, false, 'verifyExpectedArtifact returns false when REPLAN.md is missing');
|
|
529
528
|
rmSync(base, { recursive: true, force: true });
|
|
530
|
-
}
|
|
529
|
+
});
|
|
531
530
|
|
|
532
|
-
|
|
533
|
-
{
|
|
531
|
+
test('artifact: verifyExpectedArtifact passes when REPLAN.md exists (#858)', () => {
|
|
534
532
|
const base = createFixtureBase();
|
|
535
533
|
writeRoadmap(base, 'M001', ROADMAP_ONE_SLICE);
|
|
536
534
|
writePlan(base, 'M001', 'S01', makePlanT01DoneT02Pending());
|
|
537
535
|
writeReplanFile(base, 'M001', 'S01', '# Replan\n\nBlocker addressed.');
|
|
538
536
|
|
|
539
537
|
const result = verifyExpectedArtifact('replan-slice', 'M001/S01', base);
|
|
540
|
-
|
|
538
|
+
assert.deepStrictEqual(result, true, 'verifyExpectedArtifact returns true when REPLAN.md exists');
|
|
541
539
|
rmSync(base, { recursive: true, force: true });
|
|
542
|
-
}
|
|
540
|
+
});
|
|
543
541
|
|
|
544
542
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
545
543
|
// REPLAN-TRIGGER.md detection (triage-initiated replan, #1701)
|
|
546
544
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
547
|
-
|
|
548
545
|
// (a) REPLAN-TRIGGER.md exists + no REPLAN.md → replanning-slice
|
|
549
|
-
|
|
550
|
-
{
|
|
546
|
+
test('deriveState: REPLAN-TRIGGER.md exists, no REPLAN → replanning-slice (#1701)', async () => {
|
|
551
547
|
const base = createFixtureBase();
|
|
552
548
|
writeRoadmap(base, 'M001', ROADMAP_ONE_SLICE);
|
|
553
549
|
writePlan(base, 'M001', 'S01', makePlanT01DoneT02Pending());
|
|
@@ -556,17 +552,16 @@ console.log('\n=== deriveState: REPLAN-TRIGGER.md exists, no REPLAN → replanni
|
|
|
556
552
|
writeReplanTrigger(base, 'M001', 'S01', '# Replan Trigger\n\n**Source:** Capture C001\n');
|
|
557
553
|
|
|
558
554
|
const state = await deriveState(base);
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
555
|
+
assert.deepStrictEqual(state.phase, 'replanning-slice', 'phase is replanning-slice when REPLAN-TRIGGER.md exists');
|
|
556
|
+
assert.ok(state.blockers.length > 0, 'blockers array is non-empty for triage replan trigger');
|
|
557
|
+
assert.ok(state.nextAction.includes('Triage replan'), 'nextAction mentions triage replan');
|
|
558
|
+
assert.deepStrictEqual(state.activeSlice?.id, 'S01', 'activeSlice is S01');
|
|
559
|
+
assert.deepStrictEqual(state.activeTask?.id, 'T02', 'activeTask is T02 (next incomplete task)');
|
|
564
560
|
rmSync(base, { recursive: true, force: true });
|
|
565
|
-
}
|
|
561
|
+
});
|
|
566
562
|
|
|
567
563
|
// (b) REPLAN-TRIGGER.md + REPLAN.md both exist → executing (loop protection)
|
|
568
|
-
|
|
569
|
-
{
|
|
564
|
+
test('deriveState: REPLAN-TRIGGER.md + REPLAN.md → executing (loop protection, #1701)', async () => {
|
|
570
565
|
const base = createFixtureBase();
|
|
571
566
|
writeRoadmap(base, 'M001', ROADMAP_ONE_SLICE);
|
|
572
567
|
writePlan(base, 'M001', 'S01', makePlanT01DoneT02Pending());
|
|
@@ -575,27 +570,25 @@ console.log('\n=== deriveState: REPLAN-TRIGGER.md + REPLAN.md → executing (loo
|
|
|
575
570
|
writeReplanFile(base, 'M001', 'S01', '# Replan\n\nAlready replanned.');
|
|
576
571
|
|
|
577
572
|
const state = await deriveState(base);
|
|
578
|
-
|
|
579
|
-
|
|
573
|
+
assert.deepStrictEqual(state.phase, 'executing', 'phase is executing when REPLAN.md exists (loop protection)');
|
|
574
|
+
assert.deepStrictEqual(state.activeTask?.id, 'T02', 'activeTask is T02');
|
|
580
575
|
rmSync(base, { recursive: true, force: true });
|
|
581
|
-
}
|
|
576
|
+
});
|
|
582
577
|
|
|
583
578
|
// (c) No REPLAN-TRIGGER.md, no blocker → executing (no false positive)
|
|
584
|
-
|
|
585
|
-
{
|
|
579
|
+
test('deriveState: no REPLAN-TRIGGER.md, no blocker → executing (#1701)', async () => {
|
|
586
580
|
const base = createFixtureBase();
|
|
587
581
|
writeRoadmap(base, 'M001', ROADMAP_ONE_SLICE);
|
|
588
582
|
writePlan(base, 'M001', 'S01', makePlanT01DoneT02Pending());
|
|
589
583
|
writeTaskSummary(base, 'M001', 'S01', 'T01', makeTaskSummary('T01', false));
|
|
590
584
|
|
|
591
585
|
const state = await deriveState(base);
|
|
592
|
-
|
|
586
|
+
assert.deepStrictEqual(state.phase, 'executing', 'phase is executing when no trigger and no blocker');
|
|
593
587
|
rmSync(base, { recursive: true, force: true });
|
|
594
|
-
}
|
|
588
|
+
});
|
|
595
589
|
|
|
596
590
|
// (d) blocker_discovered takes priority over REPLAN-TRIGGER.md
|
|
597
|
-
|
|
598
|
-
{
|
|
591
|
+
test('deriveState: blocker_discovered takes priority over REPLAN-TRIGGER.md (#1701)', async () => {
|
|
599
592
|
const base = createFixtureBase();
|
|
600
593
|
writeRoadmap(base, 'M001', ROADMAP_ONE_SLICE);
|
|
601
594
|
writePlan(base, 'M001', 'S01', makePlanT01DoneT02Pending());
|
|
@@ -603,10 +596,10 @@ console.log('\n=== deriveState: blocker_discovered takes priority over REPLAN-TR
|
|
|
603
596
|
writeReplanTrigger(base, 'M001', 'S01', '# Replan Trigger\n\n**Source:** Capture C001\n');
|
|
604
597
|
|
|
605
598
|
const state = await deriveState(base);
|
|
606
|
-
|
|
599
|
+
assert.deepStrictEqual(state.phase, 'replanning-slice', 'phase is replanning-slice');
|
|
607
600
|
// blocker_discovered path should fire first (blockerTaskId is set, so REPLAN-TRIGGER check is skipped)
|
|
608
|
-
|
|
601
|
+
assert.ok(state.nextAction.includes('T01'), 'nextAction mentions blocker task T01 (blocker path, not trigger path)');
|
|
609
602
|
rmSync(base, { recursive: true, force: true });
|
|
610
|
-
}
|
|
603
|
+
});
|
|
611
604
|
|
|
612
|
-
|
|
605
|
+
});
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
+
import { describe, test, before, after } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
1
3
|
import { mkdtempSync, rmSync, writeFileSync, existsSync, lstatSync, realpathSync, mkdirSync, symlinkSync, renameSync } from "node:fs";
|
|
2
4
|
import { join } from "node:path";
|
|
3
5
|
import { tmpdir } from "node:os";
|
|
4
6
|
import { execSync } from "node:child_process";
|
|
5
7
|
|
|
6
8
|
import { repoIdentity, externalGsdRoot, ensureGsdSymlink, validateProjectId, readRepoMeta, isInheritedRepo } from "../repo-identity.ts";
|
|
7
|
-
import { createTestContext } from "./test-helpers.ts";
|
|
8
|
-
|
|
9
|
-
const { assertEq, assertTrue, report } = createTestContext();
|
|
10
|
-
|
|
11
9
|
/**
|
|
12
10
|
* Normalize a path for reliable comparison on Windows CI runners.
|
|
13
11
|
* `os.tmpdir()` may return the 8.3 short-path form (e.g. `C:\Users\RUNNER~1`)
|
|
@@ -23,11 +21,15 @@ function run(command: string, cwd: string): string {
|
|
|
23
21
|
return execSync(command, { cwd, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" }).trim();
|
|
24
22
|
}
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
describe('repo-identity-worktree', () => {
|
|
25
|
+
let base: string;
|
|
26
|
+
let stateDir: string;
|
|
27
|
+
let worktreePath: string;
|
|
28
|
+
let expectedExternalState: string;
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
before(() => {
|
|
31
|
+
base = realpathSync(mkdtempSync(join(tmpdir(), "gsd-repo-identity-")));
|
|
32
|
+
stateDir = realpathSync(mkdtempSync(join(tmpdir(), "gsd-state-")));
|
|
31
33
|
process.env.GSD_STATE_DIR = stateDir;
|
|
32
34
|
|
|
33
35
|
run("git init -b main", base);
|
|
@@ -38,57 +40,69 @@ async function main(): Promise<void> {
|
|
|
38
40
|
run("git add README.md", base);
|
|
39
41
|
run('git commit -m "chore: init"', base);
|
|
40
42
|
|
|
41
|
-
|
|
43
|
+
worktreePath = join(base, ".gsd", "worktrees", "M001");
|
|
42
44
|
run(`git worktree add -b milestone/M001 ${worktreePath}`, base);
|
|
43
45
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
+
expectedExternalState = externalGsdRoot(base);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
after(() => {
|
|
50
|
+
delete process.env.GSD_PROJECT_ID;
|
|
51
|
+
delete process.env.GSD_STATE_DIR;
|
|
52
|
+
rmSync(base, { recursive: true, force: true });
|
|
53
|
+
rmSync(stateDir, { recursive: true, force: true });
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test('ensureGsdSymlink points worktree at main repo external state dir', () => {
|
|
46
57
|
const mainState = ensureGsdSymlink(base);
|
|
47
|
-
|
|
58
|
+
assert.deepStrictEqual(mainState, realpathSync(join(base, ".gsd")), "ensureGsdSymlink(base) returns the current main repo .gsd target");
|
|
48
59
|
const worktreeState = ensureGsdSymlink(worktreePath);
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
60
|
+
assert.deepStrictEqual(worktreeState, expectedExternalState, "worktree symlink target matches main repo external state dir");
|
|
61
|
+
assert.ok(existsSync(join(worktreePath, ".gsd")), "worktree .gsd exists");
|
|
62
|
+
assert.ok(lstatSync(join(worktreePath, ".gsd")).isSymbolicLink(), "worktree .gsd is a symlink");
|
|
63
|
+
assert.deepStrictEqual(realpathSync(join(worktreePath, ".gsd")), realpathSync(expectedExternalState), "worktree .gsd symlink resolves to main repo external state dir");
|
|
64
|
+
});
|
|
53
65
|
|
|
54
|
-
|
|
66
|
+
test('ensureGsdSymlink heals stale worktree symlinks', () => {
|
|
55
67
|
const staleState = join(stateDir, "projects", "stale-worktree-state");
|
|
56
68
|
mkdirSync(staleState, { recursive: true });
|
|
57
69
|
rmSync(join(worktreePath, ".gsd"), { recursive: true, force: true });
|
|
58
70
|
symlinkSync(staleState, join(worktreePath, ".gsd"), "junction");
|
|
59
71
|
const healedState = ensureGsdSymlink(worktreePath);
|
|
60
|
-
|
|
61
|
-
|
|
72
|
+
assert.deepStrictEqual(healedState, expectedExternalState, "stale worktree symlink is repaired to canonical external state dir");
|
|
73
|
+
assert.deepStrictEqual(realpathSync(join(worktreePath, ".gsd")), realpathSync(expectedExternalState), "healed worktree symlink resolves to canonical external state dir");
|
|
74
|
+
});
|
|
62
75
|
|
|
63
|
-
|
|
76
|
+
test('ensureGsdSymlink preserves worktree .gsd directories', () => {
|
|
64
77
|
rmSync(join(worktreePath, ".gsd"), { recursive: true, force: true });
|
|
65
78
|
mkdirSync(join(worktreePath, ".gsd", "milestones"), { recursive: true });
|
|
66
79
|
writeFileSync(join(worktreePath, ".gsd", "milestones", "stale.txt"), "stale\n", "utf-8");
|
|
67
80
|
const preservedDirState = ensureGsdSymlink(worktreePath);
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
81
|
+
assert.deepStrictEqual(preservedDirState, join(worktreePath, ".gsd"), "worktree .gsd directory is left in place for sync-based refresh");
|
|
82
|
+
assert.ok(lstatSync(join(worktreePath, ".gsd")).isDirectory(), "worktree .gsd directory remains a directory");
|
|
83
|
+
assert.ok(existsSync(join(worktreePath, ".gsd", "milestones", "stale.txt")), "existing worktree .gsd directory contents remain available for sync logic");
|
|
84
|
+
});
|
|
71
85
|
|
|
72
|
-
|
|
86
|
+
test('GSD_PROJECT_ID overrides computed repo hash', () => {
|
|
73
87
|
process.env.GSD_PROJECT_ID = "my-project";
|
|
74
|
-
|
|
75
|
-
|
|
88
|
+
assert.deepStrictEqual(repoIdentity(base), "my-project", "repoIdentity returns GSD_PROJECT_ID when set");
|
|
89
|
+
assert.deepStrictEqual(externalGsdRoot(base), join(stateDir, "projects", "my-project"), "externalGsdRoot uses GSD_PROJECT_ID");
|
|
76
90
|
delete process.env.GSD_PROJECT_ID;
|
|
91
|
+
});
|
|
77
92
|
|
|
78
|
-
|
|
93
|
+
test('GSD_PROJECT_ID falls back to hash when unset', () => {
|
|
79
94
|
const hashIdentity = repoIdentity(base);
|
|
80
|
-
|
|
95
|
+
assert.ok(/^[0-9a-f]{12}$/.test(hashIdentity), "repoIdentity returns 12-char hex hash when GSD_PROJECT_ID is unset");
|
|
96
|
+
});
|
|
81
97
|
|
|
82
|
-
|
|
83
|
-
{
|
|
98
|
+
test('readRepoMeta returns null for malformed metadata', () => {
|
|
84
99
|
const malformedPath = join(stateDir, "projects", "malformed");
|
|
85
100
|
mkdirSync(malformedPath, { recursive: true });
|
|
86
101
|
writeFileSync(join(malformedPath, "repo-meta.json"), JSON.stringify({ version: 1 }) + "\n", "utf-8");
|
|
87
|
-
|
|
88
|
-
|
|
102
|
+
assert.deepStrictEqual(readRepoMeta(malformedPath), null, "malformed repo-meta.json is treated as unknown metadata");
|
|
103
|
+
});
|
|
89
104
|
|
|
90
|
-
|
|
91
|
-
{
|
|
105
|
+
test('ensureGsdSymlink refreshes repo-meta gitRoot after repo move with fixed project id', () => {
|
|
92
106
|
const moveRepo = realpathSync(mkdtempSync(join(tmpdir(), "gsd-repo-identity-move-")));
|
|
93
107
|
run("git init -b main", moveRepo);
|
|
94
108
|
run('git config user.name "Pi Test"', moveRepo);
|
|
@@ -100,26 +114,25 @@ async function main(): Promise<void> {
|
|
|
100
114
|
process.env.GSD_PROJECT_ID = "fixed-project";
|
|
101
115
|
const fixedExternal = ensureGsdSymlink(moveRepo);
|
|
102
116
|
const before = readRepoMeta(fixedExternal);
|
|
103
|
-
|
|
104
|
-
|
|
117
|
+
assert.ok(before !== null, "repo metadata exists before repo move");
|
|
118
|
+
assert.deepStrictEqual(normalizePath(before!.gitRoot), normalizePath(moveRepo), "repo metadata tracks current git root before move");
|
|
105
119
|
|
|
106
120
|
const movedBaseRaw = join(tmpdir(), `gsd-repo-identity-moved-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
107
121
|
renameSync(moveRepo, movedBaseRaw);
|
|
108
122
|
const movedBase = realpathSync(movedBaseRaw);
|
|
109
123
|
const movedExternal = ensureGsdSymlink(movedBase);
|
|
110
|
-
|
|
124
|
+
assert.deepStrictEqual(realpathSync(movedExternal), realpathSync(fixedExternal), "fixed project id keeps the same external state dir");
|
|
111
125
|
|
|
112
126
|
const after = readRepoMeta(movedExternal);
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
127
|
+
assert.ok(after !== null, "repo metadata exists after repo move");
|
|
128
|
+
assert.deepStrictEqual(normalizePath(after!.gitRoot), normalizePath(movedBase), "repo metadata gitRoot is refreshed to moved repo path");
|
|
129
|
+
assert.deepStrictEqual(after!.createdAt, before!.createdAt, "repo metadata preserves createdAt on refresh");
|
|
116
130
|
|
|
117
131
|
rmSync(movedBase, { recursive: true, force: true });
|
|
118
132
|
delete process.env.GSD_PROJECT_ID;
|
|
119
|
-
|
|
133
|
+
});
|
|
120
134
|
|
|
121
|
-
|
|
122
|
-
{
|
|
135
|
+
test('isInheritedRepo detects subdirectory of parent repo without .gsd (#1639)', () => {
|
|
123
136
|
const parentRepo = realpathSync(mkdtempSync(join(tmpdir(), "gsd-inherited-parent-")));
|
|
124
137
|
run("git init -b main", parentRepo);
|
|
125
138
|
run('git config user.name "Pi Test"', parentRepo);
|
|
@@ -128,31 +141,26 @@ async function main(): Promise<void> {
|
|
|
128
141
|
run("git add README.md", parentRepo);
|
|
129
142
|
run('git commit -m "init"', parentRepo);
|
|
130
143
|
|
|
131
|
-
// Create a subdirectory — no .gsd at parent
|
|
132
144
|
const subdir = join(parentRepo, "newproject");
|
|
133
145
|
mkdirSync(subdir, { recursive: true });
|
|
134
|
-
|
|
146
|
+
assert.ok(isInheritedRepo(subdir), "subdirectory of parent repo without .gsd is inherited");
|
|
135
147
|
|
|
136
|
-
// After adding .gsd at parent, subdirectory is a legitimate child
|
|
137
148
|
mkdirSync(join(parentRepo, ".gsd"), { recursive: true });
|
|
138
|
-
|
|
149
|
+
assert.ok(!isInheritedRepo(subdir), "subdirectory of parent repo WITH .gsd is NOT inherited");
|
|
139
150
|
|
|
140
|
-
|
|
141
|
-
assertTrue(!isInheritedRepo(parentRepo), "git root is not inherited");
|
|
151
|
+
assert.ok(!isInheritedRepo(parentRepo), "git root is not inherited");
|
|
142
152
|
|
|
143
|
-
// A standalone repo (not a subdir) is not inherited
|
|
144
153
|
const standaloneRepo = realpathSync(mkdtempSync(join(tmpdir(), "gsd-inherited-standalone-")));
|
|
145
154
|
run("git init -b main", standaloneRepo);
|
|
146
155
|
run('git config user.name "Pi Test"', standaloneRepo);
|
|
147
156
|
run('git config user.email "pi@example.com"', standaloneRepo);
|
|
148
|
-
|
|
157
|
+
assert.ok(!isInheritedRepo(standaloneRepo), "standalone repo is not inherited");
|
|
149
158
|
|
|
150
159
|
rmSync(parentRepo, { recursive: true, force: true });
|
|
151
160
|
rmSync(standaloneRepo, { recursive: true, force: true });
|
|
152
|
-
|
|
161
|
+
});
|
|
153
162
|
|
|
154
|
-
|
|
155
|
-
{
|
|
163
|
+
test('subdirectory of parent repo gets unique identity after git init (#1639)', () => {
|
|
156
164
|
const parentRepo = realpathSync(mkdtempSync(join(tmpdir(), "gsd-identity-parent-")));
|
|
157
165
|
run("git init -b main", parentRepo);
|
|
158
166
|
run('git config user.name "Pi Test"', parentRepo);
|
|
@@ -165,38 +173,27 @@ async function main(): Promise<void> {
|
|
|
165
173
|
const subdir = join(parentRepo, "childproject");
|
|
166
174
|
mkdirSync(subdir, { recursive: true });
|
|
167
175
|
|
|
168
|
-
// Before git init, subdirectory shares parent's identity
|
|
169
176
|
const parentIdentity = repoIdentity(parentRepo);
|
|
170
177
|
const subdirIdentityBefore = repoIdentity(subdir);
|
|
171
|
-
|
|
178
|
+
assert.deepStrictEqual(subdirIdentityBefore, parentIdentity, "subdirectory shares parent identity before its own git init");
|
|
172
179
|
|
|
173
|
-
// After git init, subdirectory gets its own identity
|
|
174
180
|
run("git init -b main", subdir);
|
|
175
181
|
const subdirIdentityAfter = repoIdentity(subdir);
|
|
176
|
-
|
|
182
|
+
assert.ok(subdirIdentityAfter !== parentIdentity, "subdirectory gets unique identity after git init");
|
|
177
183
|
|
|
178
184
|
rmSync(parentRepo, { recursive: true, force: true });
|
|
179
|
-
|
|
185
|
+
});
|
|
180
186
|
|
|
181
|
-
|
|
187
|
+
test('validateProjectId rejects invalid values', () => {
|
|
182
188
|
for (const invalid of ["has spaces", "path/traversal", "dot..dot", "back\\slash"]) {
|
|
183
|
-
|
|
189
|
+
assert.ok(!validateProjectId(invalid), `validateProjectId rejects invalid value: "${invalid}"`);
|
|
184
190
|
}
|
|
191
|
+
});
|
|
185
192
|
|
|
186
|
-
|
|
193
|
+
test('validateProjectId accepts valid values', () => {
|
|
187
194
|
for (const valid of ["my-project", "foo_bar", "abc123", "A-Z_0-9"]) {
|
|
188
|
-
|
|
195
|
+
assert.ok(validateProjectId(valid), `validateProjectId accepts valid value: "${valid}"`);
|
|
189
196
|
}
|
|
190
|
-
|
|
191
|
-
delete process.env.GSD_PROJECT_ID;
|
|
192
|
-
delete process.env.GSD_STATE_DIR;
|
|
193
|
-
rmSync(base, { recursive: true, force: true });
|
|
194
|
-
rmSync(stateDir, { recursive: true, force: true });
|
|
195
|
-
report();
|
|
196
|
-
}
|
|
197
|
-
}
|
|
197
|
+
});
|
|
198
198
|
|
|
199
|
-
main().catch((error) => {
|
|
200
|
-
console.error(error);
|
|
201
|
-
process.exit(1);
|
|
202
199
|
});
|