gsd-pi 2.45.0 → 2.46.0-dev.cc9d310
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/dist/help-text.js +1 -1
- package/dist/loader.js +34 -0
- package/dist/resources/extensions/gsd/auto/phases.js +27 -42
- package/dist/resources/extensions/gsd/auto/run-unit.js +6 -3
- package/dist/resources/extensions/gsd/auto/session.js +0 -11
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +112 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +25 -96
- package/dist/resources/extensions/gsd/auto-start.js +2 -3
- package/dist/resources/extensions/gsd/auto-worktree.js +5 -4
- package/dist/resources/extensions/gsd/auto.js +12 -57
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +15 -12
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +18 -0
- package/dist/resources/extensions/gsd/commands/context.js +0 -4
- package/dist/resources/extensions/gsd/commands/handlers/parallel.js +1 -1
- package/dist/resources/extensions/gsd/crash-recovery.js +2 -4
- package/dist/resources/extensions/gsd/dashboard-overlay.js +0 -44
- package/dist/resources/extensions/gsd/db-writer.js +9 -9
- package/dist/resources/extensions/gsd/doctor-checks.js +167 -2
- package/dist/resources/extensions/gsd/doctor.js +5 -3
- package/dist/resources/extensions/gsd/gsd-db.js +16 -3
- package/dist/resources/extensions/gsd/guided-flow.js +1 -2
- package/dist/resources/extensions/gsd/parallel-merge.js +1 -1
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +5 -18
- package/dist/resources/extensions/gsd/preferences-types.js +2 -2
- package/dist/resources/extensions/gsd/preferences.js +8 -4
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +21 -8
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +10 -23
- package/dist/resources/extensions/gsd/prompts/discuss.md +2 -2
- package/dist/resources/extensions/gsd/prompts/execute-task.md +5 -15
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/guided-research-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -2
- package/dist/resources/extensions/gsd/prompts/queue.md +2 -2
- package/dist/resources/extensions/gsd/prompts/quick-task.md +2 -0
- package/dist/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
- package/dist/resources/extensions/gsd/prompts/research-slice.md +3 -3
- package/dist/resources/extensions/gsd/prompts/rethink.md +7 -2
- package/dist/resources/extensions/gsd/prompts/system.md +1 -1
- package/dist/resources/extensions/gsd/session-lock.js +1 -3
- package/dist/resources/extensions/gsd/state.js +7 -0
- package/dist/resources/extensions/gsd/sync-lock.js +89 -0
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +61 -11
- package/dist/resources/extensions/gsd/tools/complete-slice.js +56 -11
- package/dist/resources/extensions/gsd/tools/complete-task.js +50 -2
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +37 -1
- package/dist/resources/extensions/gsd/tools/plan-slice.js +30 -1
- package/dist/resources/extensions/gsd/tools/plan-task.js +27 -1
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +32 -2
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +86 -0
- package/dist/resources/extensions/gsd/tools/reopen-task.js +90 -0
- package/dist/resources/extensions/gsd/tools/replan-slice.js +32 -2
- package/dist/resources/extensions/gsd/unit-ownership.js +85 -0
- package/dist/resources/extensions/gsd/workflow-events.js +102 -0
- package/dist/resources/extensions/gsd/workflow-logger.js +193 -0
- package/dist/resources/extensions/gsd/workflow-manifest.js +244 -0
- package/dist/resources/extensions/gsd/workflow-migration.js +280 -0
- package/dist/resources/extensions/gsd/workflow-projections.js +373 -0
- package/dist/resources/extensions/gsd/workflow-reconcile.js +411 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +4 -3
- package/dist/resources/extensions/gsd/worktree-resolver.js +37 -0
- package/dist/resources/extensions/gsd/write-intercept.js +84 -0
- package/dist/resources/extensions/voice/index.js +11 -16
- package/dist/resources/extensions/voice/linux-ready.js +67 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +17 -17
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/required-server-files.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +5 -5
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +17 -17
- package/dist/web/standalone/.next/server/chunks/229.js +1 -1
- package/dist/web/standalone/.next/server/chunks/471.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +2 -2
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-6654a8cca61a3d1c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.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/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 +2 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +2 -0
- package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +2 -1
- 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/lifecycle-hooks.d.ts +4 -0
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.js +10 -5
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.test.js +185 -0
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +239 -10
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts +2 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +20 -2
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/package-commands.test.js +206 -195
- package/packages/pi-coding-agent/dist/core/package-commands.test.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +2 -0
- package/packages/pi-coding-agent/src/core/extensions/types.ts +2 -1
- package/packages/pi-coding-agent/src/core/lifecycle-hooks.test.ts +227 -0
- package/packages/pi-coding-agent/src/core/lifecycle-hooks.ts +11 -5
- package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +297 -11
- package/packages/pi-coding-agent/src/core/model-registry.ts +30 -3
- package/packages/pi-coding-agent/src/core/package-commands.test.ts +227 -205
- package/pkg/package.json +1 -1
- package/src/resources/extensions/gsd/auto/loop-deps.ts +0 -19
- package/src/resources/extensions/gsd/auto/phases.ts +24 -44
- package/src/resources/extensions/gsd/auto/run-unit.ts +6 -3
- package/src/resources/extensions/gsd/auto/session.ts +0 -18
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +131 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +0 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +25 -106
- package/src/resources/extensions/gsd/auto-start.ts +1 -3
- package/src/resources/extensions/gsd/auto-worktree.ts +8 -5
- package/src/resources/extensions/gsd/auto.ts +7 -83
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +15 -12
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +22 -0
- package/src/resources/extensions/gsd/commands/context.ts +0 -5
- package/src/resources/extensions/gsd/commands/handlers/parallel.ts +1 -1
- package/src/resources/extensions/gsd/crash-recovery.ts +1 -5
- package/src/resources/extensions/gsd/dashboard-overlay.ts +0 -50
- package/src/resources/extensions/gsd/db-writer.ts +9 -17
- package/src/resources/extensions/gsd/doctor-checks.ts +180 -2
- package/src/resources/extensions/gsd/doctor-types.ts +7 -1
- package/src/resources/extensions/gsd/doctor.ts +6 -3
- package/src/resources/extensions/gsd/gsd-db.ts +16 -3
- package/src/resources/extensions/gsd/guided-flow.ts +1 -2
- package/src/resources/extensions/gsd/journal.ts +6 -1
- package/src/resources/extensions/gsd/parallel-merge.ts +1 -1
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +5 -21
- package/src/resources/extensions/gsd/preferences-types.ts +2 -2
- package/src/resources/extensions/gsd/preferences.ts +7 -3
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +21 -8
- package/src/resources/extensions/gsd/prompts/complete-slice.md +10 -23
- package/src/resources/extensions/gsd/prompts/discuss.md +2 -2
- package/src/resources/extensions/gsd/prompts/execute-task.md +5 -15
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/guided-research-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -2
- package/src/resources/extensions/gsd/prompts/queue.md +2 -2
- package/src/resources/extensions/gsd/prompts/quick-task.md +2 -0
- package/src/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
- package/src/resources/extensions/gsd/prompts/research-slice.md +3 -3
- package/src/resources/extensions/gsd/prompts/rethink.md +7 -2
- package/src/resources/extensions/gsd/prompts/system.md +1 -1
- package/src/resources/extensions/gsd/session-lock.ts +0 -4
- package/src/resources/extensions/gsd/state.ts +8 -0
- package/src/resources/extensions/gsd/sync-lock.ts +94 -0
- package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +5 -13
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +6 -10
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +96 -0
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +264 -228
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +317 -250
- package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +2 -8
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +0 -3
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/integration-proof.test.ts +15 -24
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +0 -3
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +8 -9
- package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +42 -3
- package/src/resources/extensions/gsd/tests/parallel-budget-atomicity.test.ts +0 -1
- package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +0 -7
- package/src/resources/extensions/gsd/tests/parallel-merge.test.ts +7 -8
- package/src/resources/extensions/gsd/tests/parallel-orchestration.test.ts +20 -24
- package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +0 -2
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +9 -6
- package/src/resources/extensions/gsd/tests/post-mutation-hook.test.ts +171 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +7 -9
- package/src/resources/extensions/gsd/tests/projection-regression.test.ts +174 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +15 -14
- package/src/resources/extensions/gsd/tests/reopen-slice.test.ts +155 -0
- package/src/resources/extensions/gsd/tests/reopen-task.test.ts +165 -0
- package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +1 -4
- package/src/resources/extensions/gsd/tests/stop-auto-remote.test.ts +2 -3
- package/src/resources/extensions/gsd/tests/sync-lock.test.ts +122 -0
- package/src/resources/extensions/gsd/tests/unit-ownership.test.ts +175 -0
- package/src/resources/extensions/gsd/tests/workflow-events.test.ts +205 -0
- package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +275 -0
- package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +186 -0
- package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +171 -0
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +220 -0
- package/src/resources/extensions/gsd/tests/write-intercept.test.ts +76 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +74 -11
- package/src/resources/extensions/gsd/tools/complete-slice.ts +68 -11
- package/src/resources/extensions/gsd/tools/complete-task.ts +63 -1
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +45 -0
- package/src/resources/extensions/gsd/tools/plan-slice.ts +38 -0
- package/src/resources/extensions/gsd/tools/plan-task.ts +35 -1
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +39 -1
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +125 -0
- package/src/resources/extensions/gsd/tools/reopen-task.ts +129 -0
- package/src/resources/extensions/gsd/tools/replan-slice.ts +38 -1
- package/src/resources/extensions/gsd/types.ts +8 -0
- package/src/resources/extensions/gsd/unit-ownership.ts +104 -0
- package/src/resources/extensions/gsd/workflow-events.ts +154 -0
- package/src/resources/extensions/gsd/workflow-logger.ts +243 -0
- package/src/resources/extensions/gsd/workflow-manifest.ts +334 -0
- package/src/resources/extensions/gsd/workflow-migration.ts +345 -0
- package/src/resources/extensions/gsd/workflow-projections.ts +425 -0
- package/src/resources/extensions/gsd/workflow-reconcile.ts +503 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +4 -9
- package/src/resources/extensions/gsd/worktree-resolver.ts +37 -0
- package/src/resources/extensions/gsd/write-intercept.ts +90 -0
- package/src/resources/extensions/voice/index.ts +11 -21
- package/src/resources/extensions/voice/linux-ready.ts +87 -0
- package/src/resources/extensions/voice/tests/linux-ready.test.ts +124 -0
- package/dist/web/standalone/.next/static/chunks/app/page-12dd5ece0df4badc.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
- /package/dist/web/standalone/.next/static/{wUzEX1U3CmFcMry2SUDJn → ZIDqryyYDroh_8AnaAOSG}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{wUzEX1U3CmFcMry2SUDJn → ZIDqryyYDroh_8AnaAOSG}/_ssgManifest.js +0 -0
package/dist/help-text.js
CHANGED
|
@@ -32,7 +32,7 @@ const SUBCOMMAND_HELP = {
|
|
|
32
32
|
install: [
|
|
33
33
|
'Usage: gsd install <source> [-l, --local]',
|
|
34
34
|
'',
|
|
35
|
-
'Install a package/extension source and run
|
|
35
|
+
'Install a package/extension source and run post-install validation (dependency checks, setup).',
|
|
36
36
|
'',
|
|
37
37
|
'Examples:',
|
|
38
38
|
' gsd install npm:@foo/bar',
|
package/dist/loader.js
CHANGED
|
@@ -26,6 +26,40 @@ if (firstArg === '--help' || firstArg === '-h') {
|
|
|
26
26
|
printHelp(gsdVersion);
|
|
27
27
|
process.exit(0);
|
|
28
28
|
}
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// Runtime dependency checks — fail fast with clear diagnostics before any
|
|
31
|
+
// heavy imports. Reads minimum Node version from the engines field in
|
|
32
|
+
// package.json (already parsed above) and verifies git is available.
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
{
|
|
35
|
+
const MIN_NODE_MAJOR = 22;
|
|
36
|
+
const red = '\x1b[31m';
|
|
37
|
+
const bold = '\x1b[1m';
|
|
38
|
+
const dim = '\x1b[2m';
|
|
39
|
+
const reset = '\x1b[0m';
|
|
40
|
+
// -- Node version --
|
|
41
|
+
const nodeMajor = parseInt(process.versions.node.split('.')[0], 10);
|
|
42
|
+
if (nodeMajor < MIN_NODE_MAJOR) {
|
|
43
|
+
process.stderr.write(`\n${red}${bold}Error:${reset} GSD requires Node.js >= ${MIN_NODE_MAJOR}.0.0\n` +
|
|
44
|
+
` You are running Node.js ${process.versions.node}\n\n` +
|
|
45
|
+
`${dim}Install a supported version:${reset}\n` +
|
|
46
|
+
` nvm install ${MIN_NODE_MAJOR} ${dim}# if using nvm${reset}\n` +
|
|
47
|
+
` fnm install ${MIN_NODE_MAJOR} ${dim}# if using fnm${reset}\n` +
|
|
48
|
+
` brew install node@${MIN_NODE_MAJOR} ${dim}# macOS Homebrew${reset}\n\n`);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
// -- git --
|
|
52
|
+
try {
|
|
53
|
+
const { execFileSync } = await import('child_process');
|
|
54
|
+
execFileSync('git', ['--version'], { stdio: 'ignore' });
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
process.stderr.write(`\n${red}${bold}Error:${reset} GSD requires git but it was not found on PATH.\n\n` +
|
|
58
|
+
`${dim}Install git:${reset}\n` +
|
|
59
|
+
` https://git-scm.com/downloads\n\n`);
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
29
63
|
import { agentDir, appRoot } from './app-paths.js';
|
|
30
64
|
import { serializeBundledExtensionPaths } from './bundled-extension-paths.js';
|
|
31
65
|
import { discoverExtensionEntryPaths } from './extension-discovery.js';
|
|
@@ -11,12 +11,15 @@ import { MAX_RECOVERY_CHARS, BUDGET_THRESHOLDS, } from "./types.js";
|
|
|
11
11
|
import { detectStuck } from "./detect-stuck.js";
|
|
12
12
|
import { runUnit } from "./run-unit.js";
|
|
13
13
|
import { debugLog } from "../debug-logger.js";
|
|
14
|
-
import { gsdRoot } from "../paths.js";
|
|
15
|
-
import { atomicWriteSync } from "../atomic-write.js";
|
|
16
14
|
import { PROJECT_FILES } from "../detection.js";
|
|
17
15
|
import { MergeConflictError } from "../git-service.js";
|
|
18
16
|
import { join } from "node:path";
|
|
19
17
|
import { existsSync, cpSync } from "node:fs";
|
|
18
|
+
import { logWarning } from "../workflow-logger.js";
|
|
19
|
+
import { gsdRoot } from "../paths.js";
|
|
20
|
+
import { atomicWriteSync } from "../atomic-write.js";
|
|
21
|
+
import { verifyExpectedArtifact } from "../auto-recovery.js";
|
|
22
|
+
import { writeUnitRuntimeRecord } from "../unit-runtime.js";
|
|
20
23
|
// ─── generateMilestoneReport ──────────────────────────────────────────────────
|
|
21
24
|
/**
|
|
22
25
|
* Generate and write an HTML milestone report snapshot.
|
|
@@ -102,8 +105,8 @@ export async function runPreDispatch(ic, loopState) {
|
|
|
102
105
|
return { action: "break", reason: "health-gate-failed" };
|
|
103
106
|
}
|
|
104
107
|
}
|
|
105
|
-
catch {
|
|
106
|
-
|
|
108
|
+
catch (e) {
|
|
109
|
+
logWarning("engine", "Pre-dispatch health gate threw unexpectedly", { error: String(e) });
|
|
107
110
|
}
|
|
108
111
|
// Sync project root artifacts into worktree
|
|
109
112
|
if (s.originalBasePath &&
|
|
@@ -157,7 +160,8 @@ export async function runPreDispatch(ic, loopState) {
|
|
|
157
160
|
await deps.stopAuto(ctx, pi, `Merge conflict on milestone ${s.currentMilestoneId}`);
|
|
158
161
|
return { action: "break", reason: "merge-conflict" };
|
|
159
162
|
}
|
|
160
|
-
// Non-conflict errors — log and continue
|
|
163
|
+
// Non-conflict merge errors — log and continue
|
|
164
|
+
logWarning("engine", "Milestone merge failed with non-conflict error", { milestone: s.currentMilestoneId, error: String(mergeErr) });
|
|
161
165
|
}
|
|
162
166
|
// PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
|
|
163
167
|
deps.invalidateAllCaches();
|
|
@@ -177,11 +181,7 @@ export async function runPreDispatch(ic, loopState) {
|
|
|
177
181
|
.filter((m) => m.status !== "complete" && m.status !== "parked")
|
|
178
182
|
.map((m) => m.id);
|
|
179
183
|
deps.pruneQueueOrder(s.basePath, pendingIds);
|
|
180
|
-
// Reset completed-units tracking for the new milestone — stale entries
|
|
181
|
-
// from the previous milestone cause the dispatch loop to skip units
|
|
182
|
-
// that haven't actually been completed in the new milestone's context.
|
|
183
184
|
// Archive the old completed-units.json instead of wiping it (#2313).
|
|
184
|
-
s.completedUnits = [];
|
|
185
185
|
try {
|
|
186
186
|
const completedKeysPath = join(gsdRoot(s.basePath), "completed-units.json");
|
|
187
187
|
if (existsSync(completedKeysPath) && s.currentMilestoneId) {
|
|
@@ -190,7 +190,9 @@ export async function runPreDispatch(ic, loopState) {
|
|
|
190
190
|
}
|
|
191
191
|
atomicWriteSync(completedKeysPath, JSON.stringify([], null, 2));
|
|
192
192
|
}
|
|
193
|
-
catch {
|
|
193
|
+
catch (e) {
|
|
194
|
+
logWarning("engine", "Failed to archive completed-units on milestone transition", { error: String(e) });
|
|
195
|
+
}
|
|
194
196
|
// Rebuild STATE.md immediately so it reflects the new active milestone.
|
|
195
197
|
// This bypasses the 30-second throttle in the normal rebuild path —
|
|
196
198
|
// milestone transitions are rare and important enough to warrant an
|
|
@@ -198,8 +200,8 @@ export async function runPreDispatch(ic, loopState) {
|
|
|
198
200
|
try {
|
|
199
201
|
await deps.rebuildState(s.basePath);
|
|
200
202
|
}
|
|
201
|
-
catch {
|
|
202
|
-
|
|
203
|
+
catch (e) {
|
|
204
|
+
logWarning("engine", "STATE.md rebuild failed after milestone transition", { error: String(e) });
|
|
203
205
|
}
|
|
204
206
|
}
|
|
205
207
|
if (mid) {
|
|
@@ -364,7 +366,7 @@ export async function runDispatch(ic, preData, loopState) {
|
|
|
364
366
|
if (loopState.stuckRecoveryAttempts === 0) {
|
|
365
367
|
// Level 1: try verifying the artifact, then cache invalidation + retry
|
|
366
368
|
loopState.stuckRecoveryAttempts++;
|
|
367
|
-
const artifactExists =
|
|
369
|
+
const artifactExists = verifyExpectedArtifact(unitType, unitId, s.basePath);
|
|
368
370
|
if (artifactExists) {
|
|
369
371
|
debugLog("autoLoop", {
|
|
370
372
|
phase: "stuck-recovery",
|
|
@@ -584,7 +586,7 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
584
586
|
const unitStartSeq = ic.nextSeq();
|
|
585
587
|
deps.emitJournalEvent({ ts: new Date().toISOString(), flowId: ic.flowId, seq: unitStartSeq, eventType: "unit-start", data: { unitType, unitId } });
|
|
586
588
|
deps.captureAvailableSkills();
|
|
587
|
-
|
|
589
|
+
writeUnitRuntimeRecord(s.basePath, unitType, unitId, s.currentUnit.startedAt, {
|
|
588
590
|
phase: "dispatched",
|
|
589
591
|
wrapupWarningSent: false,
|
|
590
592
|
timeoutAt: null,
|
|
@@ -644,8 +646,8 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
644
646
|
(requirementsContent?.length ?? 0) +
|
|
645
647
|
(projectContent?.length ?? 0);
|
|
646
648
|
}
|
|
647
|
-
catch {
|
|
648
|
-
|
|
649
|
+
catch (e) {
|
|
650
|
+
logWarning("engine", "Baseline char count measurement failed", { error: String(e) });
|
|
649
651
|
}
|
|
650
652
|
}
|
|
651
653
|
// Cache-optimize prompt section ordering
|
|
@@ -654,7 +656,7 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
654
656
|
}
|
|
655
657
|
catch (reorderErr) {
|
|
656
658
|
const msg = reorderErr instanceof Error ? reorderErr.message : String(reorderErr);
|
|
657
|
-
|
|
659
|
+
logWarning("engine", "Prompt reorder failed", { error: msg });
|
|
658
660
|
}
|
|
659
661
|
// Select and apply model (with tier escalation on retry — normal units only)
|
|
660
662
|
const modelResult = await deps.selectAndApplyModel(ctx, pi, unitType, unitId, s.basePath, prefs, s.verbose, s.autoModeStartModel, sidecarItem ? undefined : { isRetry, previousTier });
|
|
@@ -699,7 +701,7 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
699
701
|
});
|
|
700
702
|
// Write preliminary lock (no session path yet — runUnit creates a new session).
|
|
701
703
|
// Crash recovery can still identify the in-flight unit from this lock.
|
|
702
|
-
deps.writeLock(deps.lockBase(), unitType, unitId
|
|
704
|
+
deps.writeLock(deps.lockBase(), unitType, unitId);
|
|
703
705
|
debugLog("autoLoop", {
|
|
704
706
|
phase: "runUnit-start",
|
|
705
707
|
iteration: ic.iteration,
|
|
@@ -716,8 +718,8 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
716
718
|
});
|
|
717
719
|
// Now that runUnit has called newSession(), the session file path is correct.
|
|
718
720
|
const sessionFile = deps.getSessionFile(ctx);
|
|
719
|
-
deps.updateSessionLock(deps.lockBase(), unitType, unitId,
|
|
720
|
-
deps.writeLock(deps.lockBase(), unitType, unitId,
|
|
721
|
+
deps.updateSessionLock(deps.lockBase(), unitType, unitId, sessionFile);
|
|
722
|
+
deps.writeLock(deps.lockBase(), unitType, unitId, sessionFile);
|
|
721
723
|
// Tag the most recent window entry with error info for stuck detection
|
|
722
724
|
if (unitResult.status === "error" || unitResult.status === "cancelled") {
|
|
723
725
|
const lastEntry = loopState.recentUnits[loopState.recentUnits.length - 1];
|
|
@@ -761,8 +763,8 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
761
763
|
warning: "Task completed with 0 tool calls — likely hallucinated, marking as failed",
|
|
762
764
|
});
|
|
763
765
|
ctx.ui.notify(`${unitType} ${unitId} completed with 0 tool calls — hallucinated summary, will retry`, "warning");
|
|
764
|
-
//
|
|
765
|
-
//
|
|
766
|
+
// Fall through to next iteration where dispatch will re-derive
|
|
767
|
+
// and re-dispatch this task.
|
|
766
768
|
return { action: "next", data: { unitStartedAt: s.currentUnit.startedAt } };
|
|
767
769
|
}
|
|
768
770
|
}
|
|
@@ -772,25 +774,8 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
772
774
|
}
|
|
773
775
|
const skipArtifactVerification = unitType.startsWith("hook/") || unitType === "custom-step";
|
|
774
776
|
const artifactVerified = skipArtifactVerification ||
|
|
775
|
-
|
|
777
|
+
verifyExpectedArtifact(unitType, unitId, s.basePath);
|
|
776
778
|
if (artifactVerified) {
|
|
777
|
-
s.completedUnits.push({
|
|
778
|
-
type: unitType,
|
|
779
|
-
id: unitId,
|
|
780
|
-
startedAt: s.currentUnit.startedAt,
|
|
781
|
-
finishedAt: Date.now(),
|
|
782
|
-
});
|
|
783
|
-
if (s.completedUnits.length > 200) {
|
|
784
|
-
s.completedUnits = s.completedUnits.slice(-200);
|
|
785
|
-
}
|
|
786
|
-
// Flush completed-units to disk so the record survives crashes
|
|
787
|
-
try {
|
|
788
|
-
const completedKeysPath = join(gsdRoot(s.basePath), "completed-units.json");
|
|
789
|
-
const keys = s.completedUnits.map((u) => `${u.type}/${u.id}`);
|
|
790
|
-
atomicWriteSync(completedKeysPath, JSON.stringify(keys, null, 2));
|
|
791
|
-
}
|
|
792
|
-
catch { /* non-fatal: disk flush failure */ }
|
|
793
|
-
deps.clearUnitRuntimeRecord(s.basePath, unitType, unitId);
|
|
794
779
|
s.unitDispatchCount.delete(`${unitType}/${unitId}`);
|
|
795
780
|
s.unitRecoveryCount.delete(`${unitType}/${unitId}`);
|
|
796
781
|
}
|
|
@@ -823,8 +808,8 @@ export async function runFinalize(ic, iterData, sidecarItem) {
|
|
|
823
808
|
// Sidecar items use lightweight pre-verification opts
|
|
824
809
|
const preVerificationOpts = sidecarItem
|
|
825
810
|
? sidecarItem.kind === "hook"
|
|
826
|
-
? { skipSettleDelay: true,
|
|
827
|
-
: { skipSettleDelay: true
|
|
811
|
+
? { skipSettleDelay: true, skipWorktreeSync: true }
|
|
812
|
+
: { skipSettleDelay: true }
|
|
828
813
|
: undefined;
|
|
829
814
|
const preResult = await deps.postUnitPreVerification(postUnitCtx, preVerificationOpts);
|
|
830
815
|
if (preResult === "dispatched") {
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import { NEW_SESSION_TIMEOUT_MS } from "./session.js";
|
|
7
7
|
import { _setCurrentResolve, _setSessionSwitchInFlight } from "./resolve.js";
|
|
8
8
|
import { debugLog } from "../debug-logger.js";
|
|
9
|
+
import { logWarning } from "../workflow-logger.js";
|
|
9
10
|
/**
|
|
10
11
|
* Execute a single unit: create a new session, send the prompt, and await
|
|
11
12
|
* the agent_end promise. Returns a UnitResult describing what happened.
|
|
@@ -66,7 +67,9 @@ export async function runUnit(ctx, pi, s, unitType, unitId, prompt) {
|
|
|
66
67
|
process.chdir(s.basePath);
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
|
-
catch {
|
|
70
|
+
catch (e) {
|
|
71
|
+
logWarning("engine", "Failed to chdir to basePath before dispatch", { basePath: s.basePath, error: String(e) });
|
|
72
|
+
}
|
|
70
73
|
// ── Send the prompt ──
|
|
71
74
|
debugLog("runUnit", { phase: "send-message", unitType, unitId });
|
|
72
75
|
pi.sendMessage({ customType: "gsd-auto", content: prompt, display: s.verbose }, { triggerTurn: true });
|
|
@@ -90,8 +93,8 @@ export async function runUnit(ctx, pi, s, unitType, unitId, prompt) {
|
|
|
90
93
|
cmdCtxAny.clearQueue();
|
|
91
94
|
}
|
|
92
95
|
}
|
|
93
|
-
catch {
|
|
94
|
-
|
|
96
|
+
catch (e) {
|
|
97
|
+
logWarning("engine", "clearQueue failed after unit completion", { error: String(e) });
|
|
95
98
|
}
|
|
96
99
|
return result;
|
|
97
100
|
}
|
|
@@ -46,7 +46,6 @@ export class AutoSession {
|
|
|
46
46
|
// ── Current unit ─────────────────────────────────────────────────────────
|
|
47
47
|
currentUnit = null;
|
|
48
48
|
currentUnitRouting = null;
|
|
49
|
-
completedUnits = [];
|
|
50
49
|
currentMilestoneId = null;
|
|
51
50
|
// ── Model state ──────────────────────────────────────────────────────────
|
|
52
51
|
autoModeStartModel = null;
|
|
@@ -100,14 +99,6 @@ export class AutoSession {
|
|
|
100
99
|
get lockBasePath() {
|
|
101
100
|
return this.originalBasePath || this.basePath;
|
|
102
101
|
}
|
|
103
|
-
completeCurrentUnit() {
|
|
104
|
-
if (!this.currentUnit)
|
|
105
|
-
return null;
|
|
106
|
-
const done = { ...this.currentUnit, finishedAt: Date.now() };
|
|
107
|
-
this.completedUnits.push(done);
|
|
108
|
-
this.currentUnit = null;
|
|
109
|
-
return done;
|
|
110
|
-
}
|
|
111
102
|
reset() {
|
|
112
103
|
this.clearTimers();
|
|
113
104
|
// Lifecycle
|
|
@@ -129,7 +120,6 @@ export class AutoSession {
|
|
|
129
120
|
// Unit
|
|
130
121
|
this.currentUnit = null;
|
|
131
122
|
this.currentUnitRouting = null;
|
|
132
|
-
this.completedUnits = [];
|
|
133
123
|
this.currentMilestoneId = null;
|
|
134
124
|
// Model
|
|
135
125
|
this.autoModeStartModel = null;
|
|
@@ -164,7 +154,6 @@ export class AutoSession {
|
|
|
164
154
|
activeRunDir: this.activeRunDir,
|
|
165
155
|
currentMilestoneId: this.currentMilestoneId,
|
|
166
156
|
currentUnit: this.currentUnit,
|
|
167
|
-
completedUnits: this.completedUnits.length,
|
|
168
157
|
unitDispatchCount: Object.fromEntries(this.unitDispatchCount),
|
|
169
158
|
};
|
|
170
159
|
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// GSD Auto-mode — Artifact Path Resolution
|
|
2
|
+
//
|
|
3
|
+
// resolveExpectedArtifactPath and diagnoseExpectedArtifact moved here from
|
|
4
|
+
// auto-recovery.ts (Phase 5 dead-code cleanup). The artifact verification
|
|
5
|
+
// function was removed entirely — callers now query WorkflowEngine directly.
|
|
6
|
+
import { resolveMilestonePath, resolveSlicePath, relMilestoneFile, relSliceFile, buildMilestoneFileName, buildSliceFileName, buildTaskFileName, } from "./paths.js";
|
|
7
|
+
import { join } from "node:path";
|
|
8
|
+
/**
|
|
9
|
+
* Resolve the expected artifact for a unit to an absolute path.
|
|
10
|
+
*/
|
|
11
|
+
export function resolveExpectedArtifactPath(unitType, unitId, base) {
|
|
12
|
+
const parts = unitId.split("/");
|
|
13
|
+
const mid = parts[0];
|
|
14
|
+
const sid = parts[1];
|
|
15
|
+
switch (unitType) {
|
|
16
|
+
case "discuss-milestone": {
|
|
17
|
+
const dir = resolveMilestonePath(base, mid);
|
|
18
|
+
return dir ? join(dir, buildMilestoneFileName(mid, "CONTEXT")) : null;
|
|
19
|
+
}
|
|
20
|
+
case "research-milestone": {
|
|
21
|
+
const dir = resolveMilestonePath(base, mid);
|
|
22
|
+
return dir ? join(dir, buildMilestoneFileName(mid, "RESEARCH")) : null;
|
|
23
|
+
}
|
|
24
|
+
case "plan-milestone": {
|
|
25
|
+
const dir = resolveMilestonePath(base, mid);
|
|
26
|
+
return dir ? join(dir, buildMilestoneFileName(mid, "ROADMAP")) : null;
|
|
27
|
+
}
|
|
28
|
+
case "research-slice": {
|
|
29
|
+
const dir = resolveSlicePath(base, mid, sid);
|
|
30
|
+
return dir ? join(dir, buildSliceFileName(sid, "RESEARCH")) : null;
|
|
31
|
+
}
|
|
32
|
+
case "plan-slice": {
|
|
33
|
+
const dir = resolveSlicePath(base, mid, sid);
|
|
34
|
+
return dir ? join(dir, buildSliceFileName(sid, "PLAN")) : null;
|
|
35
|
+
}
|
|
36
|
+
case "reassess-roadmap": {
|
|
37
|
+
const dir = resolveSlicePath(base, mid, sid);
|
|
38
|
+
return dir ? join(dir, buildSliceFileName(sid, "ASSESSMENT")) : null;
|
|
39
|
+
}
|
|
40
|
+
case "run-uat": {
|
|
41
|
+
const dir = resolveSlicePath(base, mid, sid);
|
|
42
|
+
return dir ? join(dir, buildSliceFileName(sid, "UAT-RESULT")) : null;
|
|
43
|
+
}
|
|
44
|
+
case "execute-task": {
|
|
45
|
+
const tid = parts[2];
|
|
46
|
+
const dir = resolveSlicePath(base, mid, sid);
|
|
47
|
+
return dir && tid
|
|
48
|
+
? join(dir, "tasks", buildTaskFileName(tid, "SUMMARY"))
|
|
49
|
+
: null;
|
|
50
|
+
}
|
|
51
|
+
case "complete-slice": {
|
|
52
|
+
const dir = resolveSlicePath(base, mid, sid);
|
|
53
|
+
return dir ? join(dir, buildSliceFileName(sid, "SUMMARY")) : null;
|
|
54
|
+
}
|
|
55
|
+
case "validate-milestone": {
|
|
56
|
+
const dir = resolveMilestonePath(base, mid);
|
|
57
|
+
return dir ? join(dir, buildMilestoneFileName(mid, "VALIDATION")) : null;
|
|
58
|
+
}
|
|
59
|
+
case "complete-milestone": {
|
|
60
|
+
const dir = resolveMilestonePath(base, mid);
|
|
61
|
+
return dir ? join(dir, buildMilestoneFileName(mid, "SUMMARY")) : null;
|
|
62
|
+
}
|
|
63
|
+
case "replan-slice": {
|
|
64
|
+
const dir = resolveSlicePath(base, mid, sid);
|
|
65
|
+
return dir ? join(dir, buildSliceFileName(sid, "REPLAN")) : null;
|
|
66
|
+
}
|
|
67
|
+
case "rewrite-docs":
|
|
68
|
+
return null;
|
|
69
|
+
case "reactive-execute":
|
|
70
|
+
// Reactive execute produces multiple task summaries — verified separately
|
|
71
|
+
return null;
|
|
72
|
+
default:
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
export function diagnoseExpectedArtifact(unitType, unitId, base) {
|
|
77
|
+
const parts = unitId.split("/");
|
|
78
|
+
const mid = parts[0];
|
|
79
|
+
const sid = parts[1];
|
|
80
|
+
switch (unitType) {
|
|
81
|
+
case "discuss-milestone":
|
|
82
|
+
return `${relMilestoneFile(base, mid, "CONTEXT")} (milestone context from discussion)`;
|
|
83
|
+
case "research-milestone":
|
|
84
|
+
return `${relMilestoneFile(base, mid, "RESEARCH")} (milestone research)`;
|
|
85
|
+
case "plan-milestone":
|
|
86
|
+
return `${relMilestoneFile(base, mid, "ROADMAP")} (milestone roadmap)`;
|
|
87
|
+
case "research-slice":
|
|
88
|
+
return `${relSliceFile(base, mid, sid, "RESEARCH")} (slice research)`;
|
|
89
|
+
case "plan-slice":
|
|
90
|
+
return `${relSliceFile(base, mid, sid, "PLAN")} (slice plan)`;
|
|
91
|
+
case "execute-task": {
|
|
92
|
+
const tid = parts[2];
|
|
93
|
+
return `Task ${tid} marked [x] in ${relSliceFile(base, mid, sid, "PLAN")} + summary written`;
|
|
94
|
+
}
|
|
95
|
+
case "complete-slice":
|
|
96
|
+
return `Slice ${sid} marked [x] in ${relMilestoneFile(base, mid, "ROADMAP")} + summary + UAT written`;
|
|
97
|
+
case "replan-slice":
|
|
98
|
+
return `${relSliceFile(base, mid, sid, "REPLAN")} + updated ${relSliceFile(base, mid, sid, "PLAN")}`;
|
|
99
|
+
case "rewrite-docs":
|
|
100
|
+
return "Active overrides resolved in .gsd/OVERRIDES.md + plan documents updated";
|
|
101
|
+
case "reassess-roadmap":
|
|
102
|
+
return `${relSliceFile(base, mid, sid, "ASSESSMENT")} (roadmap reassessment)`;
|
|
103
|
+
case "run-uat":
|
|
104
|
+
return `${relSliceFile(base, mid, sid, "UAT-RESULT")} (UAT result)`;
|
|
105
|
+
case "validate-milestone":
|
|
106
|
+
return `${relMilestoneFile(base, mid, "VALIDATION")} (milestone validation report)`;
|
|
107
|
+
case "complete-milestone":
|
|
108
|
+
return `${relMilestoneFile(base, mid, "SUMMARY")} (milestone summary)`;
|
|
109
|
+
default:
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -13,14 +13,12 @@
|
|
|
13
13
|
import { deriveState } from "./state.js";
|
|
14
14
|
import { loadFile, parseSummary, resolveAllOverrides } from "./files.js";
|
|
15
15
|
import { loadPrompt } from "./prompt-loader.js";
|
|
16
|
-
import { resolveSliceFile, resolveTaskFile, resolveMilestoneFile, resolveTasksDir, buildTaskFileName,
|
|
16
|
+
import { resolveSliceFile, resolveTaskFile, resolveMilestoneFile, resolveTasksDir, buildTaskFileName, } from "./paths.js";
|
|
17
17
|
import { invalidateAllCaches } from "./cache.js";
|
|
18
18
|
import { closeoutUnit } from "./auto-unit-closeout.js";
|
|
19
19
|
import { autoCommitCurrentBranch, } from "./worktree.js";
|
|
20
20
|
import { verifyExpectedArtifact, resolveExpectedArtifactPath, } from "./auto-recovery.js";
|
|
21
|
-
import {
|
|
22
|
-
import { runGSDDoctor, rebuildState, summarizeDoctorIssues } from "./doctor.js";
|
|
23
|
-
import { recordHealthSnapshot, checkHealEscalation } from "./doctor-proactive.js";
|
|
21
|
+
import { regenerateIfMissing } from "./workflow-projections.js";
|
|
24
22
|
import { syncStateToProjectRoot } from "./auto-worktree-sync.js";
|
|
25
23
|
import { isDbAvailable, getTask, getSlice, getMilestone, updateTaskStatus, _getAdapter } from "./gsd-db.js";
|
|
26
24
|
import { renderPlanCheckboxes } from "./markdown-renderer.js";
|
|
@@ -30,7 +28,6 @@ import { hasPendingCaptures, loadPendingCaptures } from "./captures.js";
|
|
|
30
28
|
import { debugLog } from "./debug-logger.js";
|
|
31
29
|
import { existsSync, unlinkSync } from "node:fs";
|
|
32
30
|
import { join } from "node:path";
|
|
33
|
-
import { atomicWriteSync } from "./atomic-write.js";
|
|
34
31
|
import { _resetHasChangesCache } from "./native-git-bridge.js";
|
|
35
32
|
/**
|
|
36
33
|
* Detect summary files written directly to disk without the LLM calling
|
|
@@ -137,8 +134,6 @@ export function detectRogueFileWrites(unitType, unitId, basePath) {
|
|
|
137
134
|
}
|
|
138
135
|
return rogues;
|
|
139
136
|
}
|
|
140
|
-
/** Throttle STATE.md rebuilds — at most once per 30 seconds */
|
|
141
|
-
const STATE_REBUILD_MIN_INTERVAL_MS = 30_000;
|
|
142
137
|
/**
|
|
143
138
|
* Pre-verification processing: parallel worker signal check, cache invalidation,
|
|
144
139
|
* auto-commit, doctor run, state rebuild, worktree sync, artifact verification.
|
|
@@ -232,74 +227,6 @@ export async function postUnitPreVerification(pctx, opts) {
|
|
|
232
227
|
catch (e) {
|
|
233
228
|
debugLog("postUnit", { phase: "github-sync", error: String(e) });
|
|
234
229
|
}
|
|
235
|
-
// Doctor: fix mechanical bookkeeping (skipped for lightweight sidecars)
|
|
236
|
-
if (!opts?.skipDoctor)
|
|
237
|
-
try {
|
|
238
|
-
const scopeParts = s.currentUnit.id.split("/").slice(0, 2);
|
|
239
|
-
const doctorScope = scopeParts.join("/");
|
|
240
|
-
const sliceTerminalUnits = new Set(["complete-slice", "run-uat"]);
|
|
241
|
-
const effectiveFixLevel = sliceTerminalUnits.has(s.currentUnit.type) ? "all" : "task";
|
|
242
|
-
const report = await runGSDDoctor(s.basePath, { fix: true, scope: doctorScope, fixLevel: effectiveFixLevel });
|
|
243
|
-
// Human-readable fix notification with details
|
|
244
|
-
if (report.fixesApplied.length > 0) {
|
|
245
|
-
const fixSummary = report.fixesApplied.length <= 2
|
|
246
|
-
? report.fixesApplied.join("; ")
|
|
247
|
-
: `${report.fixesApplied[0]}; +${report.fixesApplied.length - 1} more`;
|
|
248
|
-
ctx.ui.notify(`Doctor: ${fixSummary}`, "info");
|
|
249
|
-
}
|
|
250
|
-
// Proactive health tracking — filter to current milestone to avoid
|
|
251
|
-
// cross-milestone stale errors inflating the escalation counter
|
|
252
|
-
const currentMilestoneId = s.currentUnit.id.split("/")[0];
|
|
253
|
-
const milestoneIssues = currentMilestoneId
|
|
254
|
-
? report.issues.filter(i => i.unitId === currentMilestoneId ||
|
|
255
|
-
i.unitId.startsWith(`${currentMilestoneId}/`))
|
|
256
|
-
: report.issues;
|
|
257
|
-
const summary = summarizeDoctorIssues(milestoneIssues);
|
|
258
|
-
// Pass issue details + scope for real-time visibility in the progress widget
|
|
259
|
-
const issueDetails = milestoneIssues
|
|
260
|
-
.filter(i => i.severity === "error" || i.severity === "warning")
|
|
261
|
-
.map(i => ({ code: i.code, message: i.message, severity: i.severity, unitId: i.unitId }));
|
|
262
|
-
recordHealthSnapshot(summary.errors, summary.warnings, report.fixesApplied.length, issueDetails, report.fixesApplied, doctorScope);
|
|
263
|
-
// Check if we should escalate to LLM-assisted heal
|
|
264
|
-
if (summary.errors > 0) {
|
|
265
|
-
const unresolvedErrors = milestoneIssues
|
|
266
|
-
.filter(i => i.severity === "error" && !i.fixable)
|
|
267
|
-
.map(i => ({ code: i.code, message: i.message, unitId: i.unitId }));
|
|
268
|
-
const escalation = checkHealEscalation(summary.errors, unresolvedErrors);
|
|
269
|
-
if (escalation.shouldEscalate) {
|
|
270
|
-
ctx.ui.notify(`Doctor heal escalation: ${escalation.reason}. Dispatching LLM-assisted heal.`, "warning");
|
|
271
|
-
try {
|
|
272
|
-
const { formatDoctorIssuesForPrompt, formatDoctorReport } = await import("./doctor.js");
|
|
273
|
-
const { dispatchDoctorHeal } = await import("./commands-handlers.js");
|
|
274
|
-
const actionable = report.issues.filter(i => i.severity === "error");
|
|
275
|
-
const reportText = formatDoctorReport(report, { scope: doctorScope, includeWarnings: true });
|
|
276
|
-
const structuredIssues = formatDoctorIssuesForPrompt(actionable);
|
|
277
|
-
dispatchDoctorHeal(pi, doctorScope, reportText, structuredIssues);
|
|
278
|
-
return "dispatched";
|
|
279
|
-
}
|
|
280
|
-
catch (e) {
|
|
281
|
-
debugLog("postUnit", { phase: "doctor-heal-dispatch", error: String(e) });
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
catch (e) {
|
|
287
|
-
debugLog("postUnit", { phase: "doctor", error: String(e) });
|
|
288
|
-
}
|
|
289
|
-
// Throttled STATE.md rebuild (skipped for lightweight sidecars)
|
|
290
|
-
if (!opts?.skipStateRebuild) {
|
|
291
|
-
const now = Date.now();
|
|
292
|
-
if (now - s.lastStateRebuildAt >= STATE_REBUILD_MIN_INTERVAL_MS) {
|
|
293
|
-
try {
|
|
294
|
-
await rebuildState(s.basePath);
|
|
295
|
-
s.lastStateRebuildAt = now;
|
|
296
|
-
autoCommitCurrentBranch(s.basePath, "state-rebuild", s.currentUnit.id);
|
|
297
|
-
}
|
|
298
|
-
catch (e) {
|
|
299
|
-
debugLog("postUnit", { phase: "state-rebuild", error: String(e) });
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
230
|
// Prune dead bg-shell processes
|
|
304
231
|
try {
|
|
305
232
|
const { pruneDeadProcesses } = await import("../bg-shell/process-manager.js");
|
|
@@ -411,6 +338,27 @@ export async function postUnitPreVerification(pctx, opts) {
|
|
|
411
338
|
catch (e) {
|
|
412
339
|
debugLog("postUnit", { phase: "artifact-verify", error: String(e) });
|
|
413
340
|
}
|
|
341
|
+
// If verification failed, attempt to regenerate missing projection files
|
|
342
|
+
// from DB data before giving up (e.g. research-slice produces PLAN from engine).
|
|
343
|
+
if (!triggerArtifactVerified) {
|
|
344
|
+
try {
|
|
345
|
+
const parts = s.currentUnit.id.split("/");
|
|
346
|
+
const [mid, sid] = parts;
|
|
347
|
+
if (mid && sid) {
|
|
348
|
+
const regenerated = regenerateIfMissing(s.basePath, mid, sid, "PLAN");
|
|
349
|
+
if (regenerated) {
|
|
350
|
+
// Re-check after regeneration
|
|
351
|
+
triggerArtifactVerified = verifyExpectedArtifact(s.currentUnit.type, s.currentUnit.id, s.basePath);
|
|
352
|
+
if (triggerArtifactVerified) {
|
|
353
|
+
invalidateAllCaches();
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
catch (e) {
|
|
359
|
+
debugLog("postUnit", { phase: "regenerate-projection", error: String(e) });
|
|
360
|
+
}
|
|
361
|
+
}
|
|
414
362
|
// When artifact verification fails for a unit type that has a known expected
|
|
415
363
|
// artifact, return "retry" so the caller re-dispatches with failure context
|
|
416
364
|
// instead of blindly re-dispatching the same unit (#1571).
|
|
@@ -432,18 +380,7 @@ export async function postUnitPreVerification(pctx, opts) {
|
|
|
432
380
|
}
|
|
433
381
|
}
|
|
434
382
|
else {
|
|
435
|
-
// Hook unit completed —
|
|
436
|
-
try {
|
|
437
|
-
writeUnitRuntimeRecord(s.basePath, s.currentUnit.type, s.currentUnit.id, s.currentUnit.startedAt, {
|
|
438
|
-
phase: "finalized",
|
|
439
|
-
progressCount: 1,
|
|
440
|
-
lastProgressKind: "hook-completed",
|
|
441
|
-
});
|
|
442
|
-
clearUnitRuntimeRecord(s.basePath, s.currentUnit.type, s.currentUnit.id);
|
|
443
|
-
}
|
|
444
|
-
catch (e) {
|
|
445
|
-
debugLog("postUnit", { phase: "hook-finalize", error: String(e) });
|
|
446
|
-
}
|
|
383
|
+
// Hook unit completed — no additional processing needed
|
|
447
384
|
}
|
|
448
385
|
}
|
|
449
386
|
return "continue";
|
|
@@ -517,15 +454,7 @@ export async function postUnitPostVerification(pctx) {
|
|
|
517
454
|
}
|
|
518
455
|
}
|
|
519
456
|
}
|
|
520
|
-
// 3.
|
|
521
|
-
s.completedUnits = s.completedUnits.filter(u => !(u.type === trigger.unitType && u.id === trigger.unitId));
|
|
522
|
-
try {
|
|
523
|
-
const completedKeysPath = join(gsdRoot(s.basePath), "completed-units.json");
|
|
524
|
-
const keys = s.completedUnits.map(u => `${u.type}/${u.id}`);
|
|
525
|
-
atomicWriteSync(completedKeysPath, JSON.stringify(keys, null, 2));
|
|
526
|
-
}
|
|
527
|
-
catch { /* non-fatal: disk flush failure */ }
|
|
528
|
-
// 4. Delete the retry_on artifact (e.g. NEEDS-REWORK.md)
|
|
457
|
+
// 3. Delete the retry_on artifact (e.g. NEEDS-REWORK.md)
|
|
529
458
|
if (trigger.retryArtifact) {
|
|
530
459
|
const retryArtifactPath = resolveHookArtifactPath(s.basePath, trigger.unitId, trigger.retryArtifact);
|
|
531
460
|
if (existsSync(retryArtifactPath)) {
|
|
@@ -352,7 +352,6 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
352
352
|
});
|
|
353
353
|
s.autoStartTime = Date.now();
|
|
354
354
|
s.resourceVersionOnStart = readResourceVersion();
|
|
355
|
-
s.completedUnits = [];
|
|
356
355
|
s.pendingQuickTasks = [];
|
|
357
356
|
s.currentUnit = null;
|
|
358
357
|
s.currentMilestoneId = state.activeMilestone?.id ?? null;
|
|
@@ -455,8 +454,8 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
455
454
|
? `Will loop through ${pendingCount} milestones.`
|
|
456
455
|
: "Will loop until milestone complete.";
|
|
457
456
|
ctx.ui.notify(`${modeLabel} started. ${scopeMsg}`, "info");
|
|
458
|
-
updateSessionLock(lockBase(), "starting", s.currentMilestoneId ?? "unknown"
|
|
459
|
-
writeLock(lockBase(), "starting", s.currentMilestoneId ?? "unknown"
|
|
457
|
+
updateSessionLock(lockBase(), "starting", s.currentMilestoneId ?? "unknown");
|
|
458
|
+
writeLock(lockBase(), "starting", s.currentMilestoneId ?? "unknown");
|
|
460
459
|
// Secrets collection gate
|
|
461
460
|
const mid = state.activeMilestone.id;
|
|
462
461
|
try {
|
|
@@ -17,6 +17,7 @@ import { createWorktree, removeWorktree, resolveGitDir, worktreePath, } from "./
|
|
|
17
17
|
import { detectWorktreeName, nudgeGitBranchCache, } from "./worktree.js";
|
|
18
18
|
import { MergeConflictError, readIntegrationBranch, RUNTIME_EXCLUSION_PATHS } from "./git-service.js";
|
|
19
19
|
import { debugLog } from "./debug-logger.js";
|
|
20
|
+
import { logWarning } from "./workflow-logger.js";
|
|
20
21
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
21
22
|
import { nativeGetCurrentBranch, nativeDetectMainBranch, nativeWorkingTreeStatus, nativeAddAllWithExclusions, nativeCommit, nativeCheckoutBranch, nativeMergeSquash, nativeConflictFiles, nativeCheckoutTheirs, nativeAddPaths, nativeRmForce, nativeBranchDelete, nativeBranchExists, nativeDiffNumstat, nativeUpdateRef, nativeIsAncestor, } from "./native-git-bridge.js";
|
|
22
23
|
// ─── Module State ──────────────────────────────────────────────────────────
|
|
@@ -615,7 +616,7 @@ export function createAutoWorktree(basePath, milestoneId) {
|
|
|
615
616
|
const hookError = runWorktreePostCreateHook(basePath, info.path);
|
|
616
617
|
if (hookError) {
|
|
617
618
|
// Non-fatal — log but don't prevent worktree usage
|
|
618
|
-
|
|
619
|
+
logWarning("reconcile", hookError, { worktree: info.name });
|
|
619
620
|
}
|
|
620
621
|
const previousCwd = process.cwd();
|
|
621
622
|
try {
|
|
@@ -690,9 +691,9 @@ export function teardownAutoWorktree(originalBasePath, milestoneId, opts = {}) {
|
|
|
690
691
|
// backslashes (#1436), leaving ~1 GB+ orphaned directories.
|
|
691
692
|
const wtDir = worktreePath(originalBasePath, milestoneId);
|
|
692
693
|
if (existsSync(wtDir)) {
|
|
693
|
-
|
|
694
|
-
`
|
|
695
|
-
`
|
|
694
|
+
logWarning("reconcile", `Worktree directory still exists after teardown: ${wtDir}. ` +
|
|
695
|
+
`This is likely an orphaned directory consuming disk space. ` +
|
|
696
|
+
`Remove it manually with: rm -rf "${wtDir.replaceAll("\\", "/")}"`, { worktree: milestoneId });
|
|
696
697
|
// Attempt a direct filesystem removal as a fallback
|
|
697
698
|
try {
|
|
698
699
|
rmSync(wtDir, { recursive: true, force: true });
|