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
|
@@ -24,12 +24,15 @@ import {
|
|
|
24
24
|
import { detectStuck } from "./detect-stuck.js";
|
|
25
25
|
import { runUnit } from "./run-unit.js";
|
|
26
26
|
import { debugLog } from "../debug-logger.js";
|
|
27
|
-
import { gsdRoot } from "../paths.js";
|
|
28
|
-
import { atomicWriteSync } from "../atomic-write.js";
|
|
29
27
|
import { PROJECT_FILES } from "../detection.js";
|
|
30
28
|
import { MergeConflictError } from "../git-service.js";
|
|
31
29
|
import { join } from "node:path";
|
|
32
30
|
import { existsSync, cpSync } from "node:fs";
|
|
31
|
+
import { logWarning, logError } from "../workflow-logger.js";
|
|
32
|
+
import { gsdRoot } from "../paths.js";
|
|
33
|
+
import { atomicWriteSync } from "../atomic-write.js";
|
|
34
|
+
import { verifyExpectedArtifact } from "../auto-recovery.js";
|
|
35
|
+
import { writeUnitRuntimeRecord } from "../unit-runtime.js";
|
|
33
36
|
|
|
34
37
|
// ─── generateMilestoneReport ──────────────────────────────────────────────────
|
|
35
38
|
|
|
@@ -164,8 +167,8 @@ export async function runPreDispatch(
|
|
|
164
167
|
debugLog("autoLoop", { phase: "exit", reason: "health-gate-failed" });
|
|
165
168
|
return { action: "break", reason: "health-gate-failed" };
|
|
166
169
|
}
|
|
167
|
-
} catch {
|
|
168
|
-
|
|
170
|
+
} catch (e) {
|
|
171
|
+
logWarning("engine", "Pre-dispatch health gate threw unexpectedly", { error: String(e) });
|
|
169
172
|
}
|
|
170
173
|
|
|
171
174
|
// Sync project root artifacts into worktree
|
|
@@ -247,7 +250,8 @@ export async function runPreDispatch(
|
|
|
247
250
|
await deps.stopAuto(ctx, pi, `Merge conflict on milestone ${s.currentMilestoneId}`);
|
|
248
251
|
return { action: "break", reason: "merge-conflict" };
|
|
249
252
|
}
|
|
250
|
-
// Non-conflict errors — log and continue
|
|
253
|
+
// Non-conflict merge errors — log and continue
|
|
254
|
+
logWarning("engine", "Milestone merge failed with non-conflict error", { milestone: s.currentMilestoneId!, error: String(mergeErr) });
|
|
251
255
|
}
|
|
252
256
|
|
|
253
257
|
// PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
|
|
@@ -275,11 +279,7 @@ export async function runPreDispatch(
|
|
|
275
279
|
.map((m: { id: string }) => m.id);
|
|
276
280
|
deps.pruneQueueOrder(s.basePath, pendingIds);
|
|
277
281
|
|
|
278
|
-
// Reset completed-units tracking for the new milestone — stale entries
|
|
279
|
-
// from the previous milestone cause the dispatch loop to skip units
|
|
280
|
-
// that haven't actually been completed in the new milestone's context.
|
|
281
282
|
// Archive the old completed-units.json instead of wiping it (#2313).
|
|
282
|
-
s.completedUnits = [];
|
|
283
283
|
try {
|
|
284
284
|
const completedKeysPath = join(gsdRoot(s.basePath), "completed-units.json");
|
|
285
285
|
if (existsSync(completedKeysPath) && s.currentMilestoneId) {
|
|
@@ -290,7 +290,9 @@ export async function runPreDispatch(
|
|
|
290
290
|
cpSync(completedKeysPath, archivePath);
|
|
291
291
|
}
|
|
292
292
|
atomicWriteSync(completedKeysPath, JSON.stringify([], null, 2));
|
|
293
|
-
} catch {
|
|
293
|
+
} catch (e) {
|
|
294
|
+
logWarning("engine", "Failed to archive completed-units on milestone transition", { error: String(e) });
|
|
295
|
+
}
|
|
294
296
|
|
|
295
297
|
// Rebuild STATE.md immediately so it reflects the new active milestone.
|
|
296
298
|
// This bypasses the 30-second throttle in the normal rebuild path —
|
|
@@ -298,8 +300,8 @@ export async function runPreDispatch(
|
|
|
298
300
|
// immediate write.
|
|
299
301
|
try {
|
|
300
302
|
await deps.rebuildState(s.basePath);
|
|
301
|
-
} catch {
|
|
302
|
-
|
|
303
|
+
} catch (e) {
|
|
304
|
+
logWarning("engine", "STATE.md rebuild failed after milestone transition", { error: String(e) });
|
|
303
305
|
}
|
|
304
306
|
}
|
|
305
307
|
|
|
@@ -536,7 +538,7 @@ export async function runDispatch(
|
|
|
536
538
|
if (loopState.stuckRecoveryAttempts === 0) {
|
|
537
539
|
// Level 1: try verifying the artifact, then cache invalidation + retry
|
|
538
540
|
loopState.stuckRecoveryAttempts++;
|
|
539
|
-
const artifactExists =
|
|
541
|
+
const artifactExists = verifyExpectedArtifact(
|
|
540
542
|
unitType,
|
|
541
543
|
unitId,
|
|
542
544
|
s.basePath,
|
|
@@ -845,7 +847,7 @@ export async function runUnitPhase(
|
|
|
845
847
|
const unitStartSeq = ic.nextSeq();
|
|
846
848
|
deps.emitJournalEvent({ ts: new Date().toISOString(), flowId: ic.flowId, seq: unitStartSeq, eventType: "unit-start", data: { unitType, unitId } });
|
|
847
849
|
deps.captureAvailableSkills();
|
|
848
|
-
|
|
850
|
+
writeUnitRuntimeRecord(
|
|
849
851
|
s.basePath,
|
|
850
852
|
unitType,
|
|
851
853
|
unitId,
|
|
@@ -919,8 +921,8 @@ export async function runUnitPhase(
|
|
|
919
921
|
(decisionsContent?.length ?? 0) +
|
|
920
922
|
(requirementsContent?.length ?? 0) +
|
|
921
923
|
(projectContent?.length ?? 0);
|
|
922
|
-
} catch {
|
|
923
|
-
|
|
924
|
+
} catch (e) {
|
|
925
|
+
logWarning("engine", "Baseline char count measurement failed", { error: String(e) });
|
|
924
926
|
}
|
|
925
927
|
}
|
|
926
928
|
|
|
@@ -930,9 +932,7 @@ export async function runUnitPhase(
|
|
|
930
932
|
} catch (reorderErr) {
|
|
931
933
|
const msg =
|
|
932
934
|
reorderErr instanceof Error ? reorderErr.message : String(reorderErr);
|
|
933
|
-
|
|
934
|
-
`[gsd] prompt reorder failed (non-fatal): ${msg}\n`,
|
|
935
|
-
);
|
|
935
|
+
logWarning("engine", "Prompt reorder failed", { error: msg });
|
|
936
936
|
}
|
|
937
937
|
|
|
938
938
|
// Select and apply model (with tier escalation on retry — normal units only)
|
|
@@ -999,7 +999,6 @@ export async function runUnitPhase(
|
|
|
999
999
|
deps.lockBase(),
|
|
1000
1000
|
unitType,
|
|
1001
1001
|
unitId,
|
|
1002
|
-
s.completedUnits.length,
|
|
1003
1002
|
);
|
|
1004
1003
|
|
|
1005
1004
|
debugLog("autoLoop", {
|
|
@@ -1030,14 +1029,12 @@ export async function runUnitPhase(
|
|
|
1030
1029
|
deps.lockBase(),
|
|
1031
1030
|
unitType,
|
|
1032
1031
|
unitId,
|
|
1033
|
-
s.completedUnits.length,
|
|
1034
1032
|
sessionFile,
|
|
1035
1033
|
);
|
|
1036
1034
|
deps.writeLock(
|
|
1037
1035
|
deps.lockBase(),
|
|
1038
1036
|
unitType,
|
|
1039
1037
|
unitId,
|
|
1040
|
-
s.completedUnits.length,
|
|
1041
1038
|
sessionFile,
|
|
1042
1039
|
);
|
|
1043
1040
|
|
|
@@ -1101,8 +1098,8 @@ export async function runUnitPhase(
|
|
|
1101
1098
|
`${unitType} ${unitId} completed with 0 tool calls — hallucinated summary, will retry`,
|
|
1102
1099
|
"warning",
|
|
1103
1100
|
);
|
|
1104
|
-
//
|
|
1105
|
-
//
|
|
1101
|
+
// Fall through to next iteration where dispatch will re-derive
|
|
1102
|
+
// and re-dispatch this task.
|
|
1106
1103
|
return { action: "next", data: { unitStartedAt: s.currentUnit.startedAt } };
|
|
1107
1104
|
}
|
|
1108
1105
|
}
|
|
@@ -1119,25 +1116,8 @@ export async function runUnitPhase(
|
|
|
1119
1116
|
const skipArtifactVerification = unitType.startsWith("hook/") || unitType === "custom-step";
|
|
1120
1117
|
const artifactVerified =
|
|
1121
1118
|
skipArtifactVerification ||
|
|
1122
|
-
|
|
1119
|
+
verifyExpectedArtifact(unitType, unitId, s.basePath);
|
|
1123
1120
|
if (artifactVerified) {
|
|
1124
|
-
s.completedUnits.push({
|
|
1125
|
-
type: unitType,
|
|
1126
|
-
id: unitId,
|
|
1127
|
-
startedAt: s.currentUnit.startedAt,
|
|
1128
|
-
finishedAt: Date.now(),
|
|
1129
|
-
});
|
|
1130
|
-
if (s.completedUnits.length > 200) {
|
|
1131
|
-
s.completedUnits = s.completedUnits.slice(-200);
|
|
1132
|
-
}
|
|
1133
|
-
// Flush completed-units to disk so the record survives crashes
|
|
1134
|
-
try {
|
|
1135
|
-
const completedKeysPath = join(gsdRoot(s.basePath), "completed-units.json");
|
|
1136
|
-
const keys = s.completedUnits.map((u) => `${u.type}/${u.id}`);
|
|
1137
|
-
atomicWriteSync(completedKeysPath, JSON.stringify(keys, null, 2));
|
|
1138
|
-
} catch { /* non-fatal: disk flush failure */ }
|
|
1139
|
-
|
|
1140
|
-
deps.clearUnitRuntimeRecord(s.basePath, unitType, unitId);
|
|
1141
1121
|
s.unitDispatchCount.delete(`${unitType}/${unitId}`);
|
|
1142
1122
|
s.unitRecoveryCount.delete(`${unitType}/${unitId}`);
|
|
1143
1123
|
}
|
|
@@ -1182,8 +1162,8 @@ export async function runFinalize(
|
|
|
1182
1162
|
// Sidecar items use lightweight pre-verification opts
|
|
1183
1163
|
const preVerificationOpts: PreVerificationOpts | undefined = sidecarItem
|
|
1184
1164
|
? sidecarItem.kind === "hook"
|
|
1185
|
-
? { skipSettleDelay: true,
|
|
1186
|
-
: { skipSettleDelay: true
|
|
1165
|
+
? { skipSettleDelay: true, skipWorktreeSync: true }
|
|
1166
|
+
: { skipSettleDelay: true }
|
|
1187
1167
|
: undefined;
|
|
1188
1168
|
const preResult = await deps.postUnitPreVerification(postUnitCtx, preVerificationOpts);
|
|
1189
1169
|
if (preResult === "dispatched") {
|
|
@@ -11,6 +11,7 @@ import { NEW_SESSION_TIMEOUT_MS } from "./session.js";
|
|
|
11
11
|
import type { UnitResult } from "./types.js";
|
|
12
12
|
import { _setCurrentResolve, _setSessionSwitchInFlight } from "./resolve.js";
|
|
13
13
|
import { debugLog } from "../debug-logger.js";
|
|
14
|
+
import { logWarning, logError } from "../workflow-logger.js";
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* Execute a single unit: create a new session, send the prompt, and await
|
|
@@ -85,7 +86,9 @@ export async function runUnit(
|
|
|
85
86
|
if (process.cwd() !== s.basePath) {
|
|
86
87
|
process.chdir(s.basePath);
|
|
87
88
|
}
|
|
88
|
-
} catch {
|
|
89
|
+
} catch (e) {
|
|
90
|
+
logWarning("engine", "Failed to chdir to basePath before dispatch", { basePath: s.basePath, error: String(e) });
|
|
91
|
+
}
|
|
89
92
|
|
|
90
93
|
// ── Send the prompt ──
|
|
91
94
|
debugLog("runUnit", { phase: "send-message", unitType, unitId });
|
|
@@ -115,8 +118,8 @@ export async function runUnit(
|
|
|
115
118
|
if (typeof cmdCtxAny?.clearQueue === "function") {
|
|
116
119
|
(cmdCtxAny.clearQueue as () => unknown)();
|
|
117
120
|
}
|
|
118
|
-
} catch {
|
|
119
|
-
|
|
121
|
+
} catch (e) {
|
|
122
|
+
logWarning("engine", "clearQueue failed after unit completion", { error: String(e) });
|
|
120
123
|
}
|
|
121
124
|
|
|
122
125
|
return result;
|
|
@@ -23,13 +23,6 @@ import type { BudgetAlertLevel } from "../auto-budget.js";
|
|
|
23
23
|
|
|
24
24
|
// ─── Exported Types ──────────────────────────────────────────────────────────
|
|
25
25
|
|
|
26
|
-
export interface CompletedUnit {
|
|
27
|
-
type: string;
|
|
28
|
-
id: string;
|
|
29
|
-
startedAt: number;
|
|
30
|
-
finishedAt: number;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
26
|
export interface CurrentUnit {
|
|
34
27
|
type: string;
|
|
35
28
|
id: string;
|
|
@@ -106,7 +99,6 @@ export class AutoSession {
|
|
|
106
99
|
// ── Current unit ─────────────────────────────────────────────────────────
|
|
107
100
|
currentUnit: CurrentUnit | null = null;
|
|
108
101
|
currentUnitRouting: UnitRouting | null = null;
|
|
109
|
-
completedUnits: CompletedUnit[] = [];
|
|
110
102
|
currentMilestoneId: string | null = null;
|
|
111
103
|
|
|
112
104
|
// ── Model state ──────────────────────────────────────────────────────────
|
|
@@ -160,14 +152,6 @@ export class AutoSession {
|
|
|
160
152
|
return this.originalBasePath || this.basePath;
|
|
161
153
|
}
|
|
162
154
|
|
|
163
|
-
completeCurrentUnit(): CompletedUnit | null {
|
|
164
|
-
if (!this.currentUnit) return null;
|
|
165
|
-
const done: CompletedUnit = { ...this.currentUnit, finishedAt: Date.now() };
|
|
166
|
-
this.completedUnits.push(done);
|
|
167
|
-
this.currentUnit = null;
|
|
168
|
-
return done;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
155
|
reset(): void {
|
|
172
156
|
this.clearTimers();
|
|
173
157
|
|
|
@@ -193,7 +177,6 @@ export class AutoSession {
|
|
|
193
177
|
// Unit
|
|
194
178
|
this.currentUnit = null;
|
|
195
179
|
this.currentUnitRouting = null;
|
|
196
|
-
this.completedUnits = [];
|
|
197
180
|
this.currentMilestoneId = null;
|
|
198
181
|
|
|
199
182
|
// Model
|
|
@@ -234,7 +217,6 @@ export class AutoSession {
|
|
|
234
217
|
activeRunDir: this.activeRunDir,
|
|
235
218
|
currentMilestoneId: this.currentMilestoneId,
|
|
236
219
|
currentUnit: this.currentUnit,
|
|
237
|
-
completedUnits: this.completedUnits.length,
|
|
238
220
|
unitDispatchCount: Object.fromEntries(this.unitDispatchCount),
|
|
239
221
|
};
|
|
240
222
|
}
|
|
@@ -0,0 +1,131 @@
|
|
|
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
|
+
|
|
7
|
+
import {
|
|
8
|
+
resolveMilestonePath,
|
|
9
|
+
resolveSlicePath,
|
|
10
|
+
relMilestoneFile,
|
|
11
|
+
relSliceFile,
|
|
12
|
+
buildMilestoneFileName,
|
|
13
|
+
buildSliceFileName,
|
|
14
|
+
buildTaskFileName,
|
|
15
|
+
} from "./paths.js";
|
|
16
|
+
import { join } from "node:path";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Resolve the expected artifact for a unit to an absolute path.
|
|
20
|
+
*/
|
|
21
|
+
export function resolveExpectedArtifactPath(
|
|
22
|
+
unitType: string,
|
|
23
|
+
unitId: string,
|
|
24
|
+
base: string,
|
|
25
|
+
): string | null {
|
|
26
|
+
const parts = unitId.split("/");
|
|
27
|
+
const mid = parts[0]!;
|
|
28
|
+
const sid = parts[1];
|
|
29
|
+
switch (unitType) {
|
|
30
|
+
case "discuss-milestone": {
|
|
31
|
+
const dir = resolveMilestonePath(base, mid);
|
|
32
|
+
return dir ? join(dir, buildMilestoneFileName(mid, "CONTEXT")) : null;
|
|
33
|
+
}
|
|
34
|
+
case "research-milestone": {
|
|
35
|
+
const dir = resolveMilestonePath(base, mid);
|
|
36
|
+
return dir ? join(dir, buildMilestoneFileName(mid, "RESEARCH")) : null;
|
|
37
|
+
}
|
|
38
|
+
case "plan-milestone": {
|
|
39
|
+
const dir = resolveMilestonePath(base, mid);
|
|
40
|
+
return dir ? join(dir, buildMilestoneFileName(mid, "ROADMAP")) : null;
|
|
41
|
+
}
|
|
42
|
+
case "research-slice": {
|
|
43
|
+
const dir = resolveSlicePath(base, mid, sid!);
|
|
44
|
+
return dir ? join(dir, buildSliceFileName(sid!, "RESEARCH")) : null;
|
|
45
|
+
}
|
|
46
|
+
case "plan-slice": {
|
|
47
|
+
const dir = resolveSlicePath(base, mid, sid!);
|
|
48
|
+
return dir ? join(dir, buildSliceFileName(sid!, "PLAN")) : null;
|
|
49
|
+
}
|
|
50
|
+
case "reassess-roadmap": {
|
|
51
|
+
const dir = resolveSlicePath(base, mid, sid!);
|
|
52
|
+
return dir ? join(dir, buildSliceFileName(sid!, "ASSESSMENT")) : null;
|
|
53
|
+
}
|
|
54
|
+
case "run-uat": {
|
|
55
|
+
const dir = resolveSlicePath(base, mid, sid!);
|
|
56
|
+
return dir ? join(dir, buildSliceFileName(sid!, "UAT-RESULT")) : null;
|
|
57
|
+
}
|
|
58
|
+
case "execute-task": {
|
|
59
|
+
const tid = parts[2];
|
|
60
|
+
const dir = resolveSlicePath(base, mid, sid!);
|
|
61
|
+
return dir && tid
|
|
62
|
+
? join(dir, "tasks", buildTaskFileName(tid, "SUMMARY"))
|
|
63
|
+
: null;
|
|
64
|
+
}
|
|
65
|
+
case "complete-slice": {
|
|
66
|
+
const dir = resolveSlicePath(base, mid, sid!);
|
|
67
|
+
return dir ? join(dir, buildSliceFileName(sid!, "SUMMARY")) : null;
|
|
68
|
+
}
|
|
69
|
+
case "validate-milestone": {
|
|
70
|
+
const dir = resolveMilestonePath(base, mid);
|
|
71
|
+
return dir ? join(dir, buildMilestoneFileName(mid, "VALIDATION")) : null;
|
|
72
|
+
}
|
|
73
|
+
case "complete-milestone": {
|
|
74
|
+
const dir = resolveMilestonePath(base, mid);
|
|
75
|
+
return dir ? join(dir, buildMilestoneFileName(mid, "SUMMARY")) : null;
|
|
76
|
+
}
|
|
77
|
+
case "replan-slice": {
|
|
78
|
+
const dir = resolveSlicePath(base, mid, sid!);
|
|
79
|
+
return dir ? join(dir, buildSliceFileName(sid!, "REPLAN")) : null;
|
|
80
|
+
}
|
|
81
|
+
case "rewrite-docs":
|
|
82
|
+
return null;
|
|
83
|
+
case "reactive-execute":
|
|
84
|
+
// Reactive execute produces multiple task summaries — verified separately
|
|
85
|
+
return null;
|
|
86
|
+
default:
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function diagnoseExpectedArtifact(
|
|
92
|
+
unitType: string,
|
|
93
|
+
unitId: string,
|
|
94
|
+
base: string,
|
|
95
|
+
): string | null {
|
|
96
|
+
const parts = unitId.split("/");
|
|
97
|
+
const mid = parts[0];
|
|
98
|
+
const sid = parts[1];
|
|
99
|
+
switch (unitType) {
|
|
100
|
+
case "discuss-milestone":
|
|
101
|
+
return `${relMilestoneFile(base, mid!, "CONTEXT")} (milestone context from discussion)`;
|
|
102
|
+
case "research-milestone":
|
|
103
|
+
return `${relMilestoneFile(base, mid!, "RESEARCH")} (milestone research)`;
|
|
104
|
+
case "plan-milestone":
|
|
105
|
+
return `${relMilestoneFile(base, mid!, "ROADMAP")} (milestone roadmap)`;
|
|
106
|
+
case "research-slice":
|
|
107
|
+
return `${relSliceFile(base, mid!, sid!, "RESEARCH")} (slice research)`;
|
|
108
|
+
case "plan-slice":
|
|
109
|
+
return `${relSliceFile(base, mid!, sid!, "PLAN")} (slice plan)`;
|
|
110
|
+
case "execute-task": {
|
|
111
|
+
const tid = parts[2];
|
|
112
|
+
return `Task ${tid} marked [x] in ${relSliceFile(base, mid!, sid!, "PLAN")} + summary written`;
|
|
113
|
+
}
|
|
114
|
+
case "complete-slice":
|
|
115
|
+
return `Slice ${sid} marked [x] in ${relMilestoneFile(base, mid!, "ROADMAP")} + summary + UAT written`;
|
|
116
|
+
case "replan-slice":
|
|
117
|
+
return `${relSliceFile(base, mid!, sid!, "REPLAN")} + updated ${relSliceFile(base, mid!, sid!, "PLAN")}`;
|
|
118
|
+
case "rewrite-docs":
|
|
119
|
+
return "Active overrides resolved in .gsd/OVERRIDES.md + plan documents updated";
|
|
120
|
+
case "reassess-roadmap":
|
|
121
|
+
return `${relSliceFile(base, mid!, sid!, "ASSESSMENT")} (roadmap reassessment)`;
|
|
122
|
+
case "run-uat":
|
|
123
|
+
return `${relSliceFile(base, mid!, sid!, "UAT-RESULT")} (UAT result)`;
|
|
124
|
+
case "validate-milestone":
|
|
125
|
+
return `${relMilestoneFile(base, mid!, "VALIDATION")} (milestone validation report)`;
|
|
126
|
+
case "complete-milestone":
|
|
127
|
+
return `${relMilestoneFile(base, mid!, "SUMMARY")} (milestone summary)`;
|
|
128
|
+
default:
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -48,7 +48,6 @@ export interface AutoDashboardData {
|
|
|
48
48
|
startTime: number;
|
|
49
49
|
elapsed: number;
|
|
50
50
|
currentUnit: { type: string; id: string; startedAt: number } | null;
|
|
51
|
-
completedUnits: { type: string; id: string; startedAt: number; finishedAt: number }[];
|
|
52
51
|
basePath: string;
|
|
53
52
|
/** Running cost and token totals from metrics ledger */
|
|
54
53
|
totalCost: number;
|
|
@@ -17,12 +17,10 @@ import { loadFile, parseSummary, resolveAllOverrides } from "./files.js";
|
|
|
17
17
|
import { loadPrompt } from "./prompt-loader.js";
|
|
18
18
|
import {
|
|
19
19
|
resolveSliceFile,
|
|
20
|
-
resolveSlicePath,
|
|
21
20
|
resolveTaskFile,
|
|
22
21
|
resolveMilestoneFile,
|
|
23
22
|
resolveTasksDir,
|
|
24
23
|
buildTaskFileName,
|
|
25
|
-
gsdRoot,
|
|
26
24
|
} from "./paths.js";
|
|
27
25
|
import { invalidateAllCaches } from "./cache.js";
|
|
28
26
|
import { closeoutUnit, type CloseoutOptions } from "./auto-unit-closeout.js";
|
|
@@ -34,9 +32,7 @@ import {
|
|
|
34
32
|
verifyExpectedArtifact,
|
|
35
33
|
resolveExpectedArtifactPath,
|
|
36
34
|
} from "./auto-recovery.js";
|
|
37
|
-
import {
|
|
38
|
-
import { runGSDDoctor, rebuildState, summarizeDoctorIssues } from "./doctor.js";
|
|
39
|
-
import { recordHealthSnapshot, checkHealEscalation } from "./doctor-proactive.js";
|
|
35
|
+
import { regenerateIfMissing } from "./workflow-projections.js";
|
|
40
36
|
import { syncStateToProjectRoot } from "./auto-worktree-sync.js";
|
|
41
37
|
import { isDbAvailable, getTask, getSlice, getMilestone, updateTaskStatus, _getAdapter } from "./gsd-db.js";
|
|
42
38
|
import { renderPlanCheckboxes } from "./markdown-renderer.js";
|
|
@@ -57,9 +53,8 @@ import {
|
|
|
57
53
|
unitVerb,
|
|
58
54
|
hideFooter,
|
|
59
55
|
} from "./auto-dashboard.js";
|
|
60
|
-
import { existsSync, unlinkSync
|
|
56
|
+
import { existsSync, unlinkSync } from "node:fs";
|
|
61
57
|
import { join } from "node:path";
|
|
62
|
-
import { atomicWriteSync } from "./atomic-write.js";
|
|
63
58
|
import { _resetHasChangesCache } from "./native-git-bridge.js";
|
|
64
59
|
|
|
65
60
|
// ─── Rogue File Detection ──────────────────────────────────────────────────
|
|
@@ -186,13 +181,8 @@ export function detectRogueFileWrites(
|
|
|
186
181
|
return rogues;
|
|
187
182
|
}
|
|
188
183
|
|
|
189
|
-
/** Throttle STATE.md rebuilds — at most once per 30 seconds */
|
|
190
|
-
const STATE_REBUILD_MIN_INTERVAL_MS = 30_000;
|
|
191
|
-
|
|
192
184
|
export interface PreVerificationOpts {
|
|
193
185
|
skipSettleDelay?: boolean;
|
|
194
|
-
skipDoctor?: boolean;
|
|
195
|
-
skipStateRebuild?: boolean;
|
|
196
186
|
skipWorktreeSync?: boolean;
|
|
197
187
|
}
|
|
198
188
|
|
|
@@ -306,78 +296,6 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
306
296
|
debugLog("postUnit", { phase: "github-sync", error: String(e) });
|
|
307
297
|
}
|
|
308
298
|
|
|
309
|
-
// Doctor: fix mechanical bookkeeping (skipped for lightweight sidecars)
|
|
310
|
-
if (!opts?.skipDoctor) try {
|
|
311
|
-
const scopeParts = s.currentUnit.id.split("/").slice(0, 2);
|
|
312
|
-
const doctorScope = scopeParts.join("/");
|
|
313
|
-
const sliceTerminalUnits = new Set(["complete-slice", "run-uat"]);
|
|
314
|
-
const effectiveFixLevel = sliceTerminalUnits.has(s.currentUnit.type) ? "all" as const : "task" as const;
|
|
315
|
-
const report = await runGSDDoctor(s.basePath, { fix: true, scope: doctorScope, fixLevel: effectiveFixLevel });
|
|
316
|
-
// Human-readable fix notification with details
|
|
317
|
-
if (report.fixesApplied.length > 0) {
|
|
318
|
-
const fixSummary = report.fixesApplied.length <= 2
|
|
319
|
-
? report.fixesApplied.join("; ")
|
|
320
|
-
: `${report.fixesApplied[0]}; +${report.fixesApplied.length - 1} more`;
|
|
321
|
-
ctx.ui.notify(`Doctor: ${fixSummary}`, "info");
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
// Proactive health tracking — filter to current milestone to avoid
|
|
325
|
-
// cross-milestone stale errors inflating the escalation counter
|
|
326
|
-
const currentMilestoneId = s.currentUnit.id.split("/")[0];
|
|
327
|
-
const milestoneIssues = currentMilestoneId
|
|
328
|
-
? report.issues.filter(i =>
|
|
329
|
-
i.unitId === currentMilestoneId ||
|
|
330
|
-
i.unitId.startsWith(`${currentMilestoneId}/`))
|
|
331
|
-
: report.issues;
|
|
332
|
-
const summary = summarizeDoctorIssues(milestoneIssues);
|
|
333
|
-
// Pass issue details + scope for real-time visibility in the progress widget
|
|
334
|
-
const issueDetails = milestoneIssues
|
|
335
|
-
.filter(i => i.severity === "error" || i.severity === "warning")
|
|
336
|
-
.map(i => ({ code: i.code, message: i.message, severity: i.severity, unitId: i.unitId }));
|
|
337
|
-
recordHealthSnapshot(summary.errors, summary.warnings, report.fixesApplied.length, issueDetails, report.fixesApplied, doctorScope);
|
|
338
|
-
|
|
339
|
-
// Check if we should escalate to LLM-assisted heal
|
|
340
|
-
if (summary.errors > 0) {
|
|
341
|
-
const unresolvedErrors = milestoneIssues
|
|
342
|
-
.filter(i => i.severity === "error" && !i.fixable)
|
|
343
|
-
.map(i => ({ code: i.code, message: i.message, unitId: i.unitId }));
|
|
344
|
-
const escalation = checkHealEscalation(summary.errors, unresolvedErrors);
|
|
345
|
-
if (escalation.shouldEscalate) {
|
|
346
|
-
ctx.ui.notify(
|
|
347
|
-
`Doctor heal escalation: ${escalation.reason}. Dispatching LLM-assisted heal.`,
|
|
348
|
-
"warning",
|
|
349
|
-
);
|
|
350
|
-
try {
|
|
351
|
-
const { formatDoctorIssuesForPrompt, formatDoctorReport } = await import("./doctor.js");
|
|
352
|
-
const { dispatchDoctorHeal } = await import("./commands-handlers.js");
|
|
353
|
-
const actionable = report.issues.filter(i => i.severity === "error");
|
|
354
|
-
const reportText = formatDoctorReport(report, { scope: doctorScope, includeWarnings: true });
|
|
355
|
-
const structuredIssues = formatDoctorIssuesForPrompt(actionable);
|
|
356
|
-
dispatchDoctorHeal(pi, doctorScope, reportText, structuredIssues);
|
|
357
|
-
return "dispatched";
|
|
358
|
-
} catch (e) {
|
|
359
|
-
debugLog("postUnit", { phase: "doctor-heal-dispatch", error: String(e) });
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
} catch (e) {
|
|
364
|
-
debugLog("postUnit", { phase: "doctor", error: String(e) });
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
// Throttled STATE.md rebuild (skipped for lightweight sidecars)
|
|
368
|
-
if (!opts?.skipStateRebuild) {
|
|
369
|
-
const now = Date.now();
|
|
370
|
-
if (now - s.lastStateRebuildAt >= STATE_REBUILD_MIN_INTERVAL_MS) {
|
|
371
|
-
try {
|
|
372
|
-
await rebuildState(s.basePath);
|
|
373
|
-
s.lastStateRebuildAt = now;
|
|
374
|
-
autoCommitCurrentBranch(s.basePath, "state-rebuild", s.currentUnit.id);
|
|
375
|
-
} catch (e) {
|
|
376
|
-
debugLog("postUnit", { phase: "state-rebuild", error: String(e) });
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
|
|
381
299
|
// Prune dead bg-shell processes
|
|
382
300
|
try {
|
|
383
301
|
const { pruneDeadProcesses } = await import("../bg-shell/process-manager.js");
|
|
@@ -503,6 +421,27 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
503
421
|
debugLog("postUnit", { phase: "artifact-verify", error: String(e) });
|
|
504
422
|
}
|
|
505
423
|
|
|
424
|
+
// If verification failed, attempt to regenerate missing projection files
|
|
425
|
+
// from DB data before giving up (e.g. research-slice produces PLAN from engine).
|
|
426
|
+
if (!triggerArtifactVerified) {
|
|
427
|
+
try {
|
|
428
|
+
const parts = s.currentUnit.id.split("/");
|
|
429
|
+
const [mid, sid] = parts;
|
|
430
|
+
if (mid && sid) {
|
|
431
|
+
const regenerated = regenerateIfMissing(s.basePath, mid, sid, "PLAN");
|
|
432
|
+
if (regenerated) {
|
|
433
|
+
// Re-check after regeneration
|
|
434
|
+
triggerArtifactVerified = verifyExpectedArtifact(s.currentUnit.type, s.currentUnit.id, s.basePath);
|
|
435
|
+
if (triggerArtifactVerified) {
|
|
436
|
+
invalidateAllCaches();
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
} catch (e) {
|
|
441
|
+
debugLog("postUnit", { phase: "regenerate-projection", error: String(e) });
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
506
445
|
// When artifact verification fails for a unit type that has a known expected
|
|
507
446
|
// artifact, return "retry" so the caller re-dispatches with failure context
|
|
508
447
|
// instead of blindly re-dispatching the same unit (#1571).
|
|
@@ -526,17 +465,7 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|
|
526
465
|
}
|
|
527
466
|
}
|
|
528
467
|
} else {
|
|
529
|
-
// Hook unit completed —
|
|
530
|
-
try {
|
|
531
|
-
writeUnitRuntimeRecord(s.basePath, s.currentUnit.type, s.currentUnit.id, s.currentUnit.startedAt, {
|
|
532
|
-
phase: "finalized",
|
|
533
|
-
progressCount: 1,
|
|
534
|
-
lastProgressKind: "hook-completed",
|
|
535
|
-
});
|
|
536
|
-
clearUnitRuntimeRecord(s.basePath, s.currentUnit.type, s.currentUnit.id);
|
|
537
|
-
} catch (e) {
|
|
538
|
-
debugLog("postUnit", { phase: "hook-finalize", error: String(e) });
|
|
539
|
-
}
|
|
468
|
+
// Hook unit completed — no additional processing needed
|
|
540
469
|
}
|
|
541
470
|
}
|
|
542
471
|
|
|
@@ -625,17 +554,7 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
|
|
|
625
554
|
}
|
|
626
555
|
}
|
|
627
556
|
|
|
628
|
-
// 3.
|
|
629
|
-
s.completedUnits = s.completedUnits.filter(
|
|
630
|
-
u => !(u.type === trigger.unitType && u.id === trigger.unitId),
|
|
631
|
-
);
|
|
632
|
-
try {
|
|
633
|
-
const completedKeysPath = join(gsdRoot(s.basePath), "completed-units.json");
|
|
634
|
-
const keys = s.completedUnits.map(u => `${u.type}/${u.id}`);
|
|
635
|
-
atomicWriteSync(completedKeysPath, JSON.stringify(keys, null, 2));
|
|
636
|
-
} catch { /* non-fatal: disk flush failure */ }
|
|
637
|
-
|
|
638
|
-
// 4. Delete the retry_on artifact (e.g. NEEDS-REWORK.md)
|
|
557
|
+
// 3. Delete the retry_on artifact (e.g. NEEDS-REWORK.md)
|
|
639
558
|
if (trigger.retryArtifact) {
|
|
640
559
|
const retryArtifactPath = resolveHookArtifactPath(s.basePath, trigger.unitId, trigger.retryArtifact);
|
|
641
560
|
if (existsSync(retryArtifactPath)) {
|
|
@@ -494,7 +494,6 @@ export async function bootstrapAutoSession(
|
|
|
494
494
|
});
|
|
495
495
|
s.autoStartTime = Date.now();
|
|
496
496
|
s.resourceVersionOnStart = readResourceVersion();
|
|
497
|
-
s.completedUnits = [];
|
|
498
497
|
s.pendingQuickTasks = [];
|
|
499
498
|
s.currentUnit = null;
|
|
500
499
|
s.currentMilestoneId = state.activeMilestone?.id ?? null;
|
|
@@ -624,9 +623,8 @@ export async function bootstrapAutoSession(
|
|
|
624
623
|
lockBase(),
|
|
625
624
|
"starting",
|
|
626
625
|
s.currentMilestoneId ?? "unknown",
|
|
627
|
-
0,
|
|
628
626
|
);
|
|
629
|
-
writeLock(lockBase(), "starting", s.currentMilestoneId ?? "unknown"
|
|
627
|
+
writeLock(lockBase(), "starting", s.currentMilestoneId ?? "unknown");
|
|
630
628
|
|
|
631
629
|
// Secrets collection gate
|
|
632
630
|
const mid = state.activeMilestone!.id;
|
|
@@ -42,6 +42,7 @@ import {
|
|
|
42
42
|
} from "./worktree.js";
|
|
43
43
|
import { MergeConflictError, readIntegrationBranch, RUNTIME_EXCLUSION_PATHS } from "./git-service.js";
|
|
44
44
|
import { debugLog } from "./debug-logger.js";
|
|
45
|
+
import { logWarning } from "./workflow-logger.js";
|
|
45
46
|
import { loadEffectiveGSDPreferences } from "./preferences.js";
|
|
46
47
|
import {
|
|
47
48
|
nativeGetCurrentBranch,
|
|
@@ -700,7 +701,7 @@ export function createAutoWorktree(
|
|
|
700
701
|
const hookError = runWorktreePostCreateHook(basePath, info.path);
|
|
701
702
|
if (hookError) {
|
|
702
703
|
// Non-fatal — log but don't prevent worktree usage
|
|
703
|
-
|
|
704
|
+
logWarning("reconcile", hookError, { worktree: info.name });
|
|
704
705
|
}
|
|
705
706
|
|
|
706
707
|
const previousCwd = process.cwd();
|
|
@@ -793,10 +794,12 @@ export function teardownAutoWorktree(
|
|
|
793
794
|
// backslashes (#1436), leaving ~1 GB+ orphaned directories.
|
|
794
795
|
const wtDir = worktreePath(originalBasePath, milestoneId);
|
|
795
796
|
if (existsSync(wtDir)) {
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
`
|
|
797
|
+
logWarning(
|
|
798
|
+
"reconcile",
|
|
799
|
+
`Worktree directory still exists after teardown: ${wtDir}. ` +
|
|
800
|
+
`This is likely an orphaned directory consuming disk space. ` +
|
|
801
|
+
`Remove it manually with: rm -rf "${wtDir.replaceAll("\\", "/")}"`,
|
|
802
|
+
{ worktree: milestoneId },
|
|
800
803
|
);
|
|
801
804
|
// Attempt a direct filesystem removal as a fallback
|
|
802
805
|
try {
|