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
|
@@ -19,13 +19,11 @@ import { clearActivityLogState } from "./activity-log.js";
|
|
|
19
19
|
import { synthesizeCrashRecovery, getDeepDiagnostic, } from "./session-forensics.js";
|
|
20
20
|
import { writeLock, clearLock, readCrashLock, isLockProcessAlive, } from "./crash-recovery.js";
|
|
21
21
|
import { acquireSessionLock, getSessionLockStatus, releaseSessionLock, updateSessionLock, } from "./session-lock.js";
|
|
22
|
-
import { clearUnitRuntimeRecord, readUnitRuntimeRecord, writeUnitRuntimeRecord, } from "./unit-runtime.js";
|
|
23
22
|
import { resolveAutoSupervisorConfig, loadEffectiveGSDPreferences, getIsolationMode, } from "./preferences.js";
|
|
24
23
|
import { sendDesktopNotification } from "./notifications.js";
|
|
25
24
|
import { getBudgetAlertLevel, getNewBudgetAlertLevel, getBudgetEnforcementAction, } from "./auto-budget.js";
|
|
26
25
|
import { markToolStart as _markToolStart, markToolEnd as _markToolEnd, getOldestInFlightToolAgeMs as _getOldestInFlightToolAgeMs, clearInFlightTools, } from "./auto-tool-tracking.js";
|
|
27
26
|
import { closeoutUnit } from "./auto-unit-closeout.js";
|
|
28
|
-
import { selfHealRuntimeRecords } from "./auto-recovery.js";
|
|
29
27
|
import { selectAndApplyModel, resolveModelId } from "./auto-model-selection.js";
|
|
30
28
|
import { syncProjectRootToWorktree, checkResourcesStale, escapeStaleWorktree, } from "./auto-worktree-sync.js";
|
|
31
29
|
import { resetRoutingHistory, recordOutcome } from "./routing-history.js";
|
|
@@ -44,7 +42,7 @@ import { getPriorSliceCompletionBlocker } from "./dispatch-guard.js";
|
|
|
44
42
|
import { createAutoWorktree, enterAutoWorktree, teardownAutoWorktree, isInAutoWorktree, getAutoWorktreePath, mergeMilestoneToMain, autoWorktreeBranch, syncWorktreeStateBack, } from "./auto-worktree.js";
|
|
45
43
|
import { pruneQueueOrder } from "./queue-order.js";
|
|
46
44
|
import { debugLog, isDebugEnabled, writeDebugSummary } from "./debug-logger.js";
|
|
47
|
-
import {
|
|
45
|
+
import { reconcileMergeState, } from "./auto-recovery.js";
|
|
48
46
|
import { resolveDispatch, DISPATCH_RULES } from "./auto-dispatch.js";
|
|
49
47
|
import { initRegistry, convertDispatchRules } from "./rule-registry.js";
|
|
50
48
|
import { emitJournalEvent as _emitJournalEvent } from "./journal.js";
|
|
@@ -82,11 +80,10 @@ const s = new AutoSession();
|
|
|
82
80
|
const STATE_REBUILD_MIN_INTERVAL_MS = 30_000;
|
|
83
81
|
export function shouldUseWorktreeIsolation() {
|
|
84
82
|
const prefs = loadEffectiveGSDPreferences()?.preferences?.git;
|
|
85
|
-
if (prefs?.isolation === "
|
|
86
|
-
return
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
return true; // default: worktree
|
|
83
|
+
if (prefs?.isolation === "worktree")
|
|
84
|
+
return true;
|
|
85
|
+
// Default is false — worktree isolation requires explicit opt-in
|
|
86
|
+
return false;
|
|
90
87
|
}
|
|
91
88
|
/** Crash recovery prompt — set by startAuto, consumed by the main loop */
|
|
92
89
|
/** Pending verification retry — set when gate fails with retries remaining, consumed by autoLoop */
|
|
@@ -146,7 +143,6 @@ export function getAutoDashboardData() {
|
|
|
146
143
|
? (s.autoStartTime > 0 ? Date.now() - s.autoStartTime : 0)
|
|
147
144
|
: 0,
|
|
148
145
|
currentUnit: s.currentUnit ? { ...s.currentUnit } : null,
|
|
149
|
-
completedUnits: [...s.completedUnits],
|
|
150
146
|
basePath: s.basePath,
|
|
151
147
|
totalCost: totals?.cost ?? 0,
|
|
152
148
|
totalTokens: totals?.tokens.total ?? 0,
|
|
@@ -245,7 +241,6 @@ export function checkRemoteAutoSession(projectRoot) {
|
|
|
245
241
|
unitType: lock.unitType,
|
|
246
242
|
unitId: lock.unitId,
|
|
247
243
|
startedAt: lock.startedAt,
|
|
248
|
-
completedUnits: lock.completedUnits,
|
|
249
244
|
};
|
|
250
245
|
}
|
|
251
246
|
export function isStepMode() {
|
|
@@ -270,16 +265,12 @@ function clearUnitTimeout() {
|
|
|
270
265
|
}
|
|
271
266
|
clearInFlightTools();
|
|
272
267
|
}
|
|
273
|
-
/** Build snapshot metric opts
|
|
274
|
-
function buildSnapshotOpts(
|
|
275
|
-
const runtime = s.currentUnit
|
|
276
|
-
? readUnitRuntimeRecord(s.basePath, unitType, unitId)
|
|
277
|
-
: null;
|
|
268
|
+
/** Build snapshot metric opts. */
|
|
269
|
+
function buildSnapshotOpts(_unitType, _unitId) {
|
|
278
270
|
return {
|
|
279
271
|
promptCharCount: s.lastPromptCharCount,
|
|
280
272
|
baselineCharCount: s.lastBaselineCharCount,
|
|
281
273
|
...(s.currentUnitRouting ?? {}),
|
|
282
|
-
...(runtime?.continueHereFired ? { continueHereFired: true } : {}),
|
|
283
274
|
};
|
|
284
275
|
}
|
|
285
276
|
function handleLostSessionLock(ctx, lockStatus) {
|
|
@@ -587,12 +578,6 @@ export async function pauseAuto(ctx, _pi) {
|
|
|
587
578
|
catch {
|
|
588
579
|
// Non-fatal — best-effort closeout on pause
|
|
589
580
|
}
|
|
590
|
-
try {
|
|
591
|
-
clearUnitRuntimeRecord(s.basePath, s.currentUnit.type, s.currentUnit.id);
|
|
592
|
-
}
|
|
593
|
-
catch {
|
|
594
|
-
// Non-fatal
|
|
595
|
-
}
|
|
596
581
|
s.currentUnit = null;
|
|
597
582
|
}
|
|
598
583
|
if (lockBase()) {
|
|
@@ -711,9 +696,6 @@ function buildLoopDeps() {
|
|
|
711
696
|
getMainBranch,
|
|
712
697
|
// Unit closeout + runtime records
|
|
713
698
|
closeoutUnit,
|
|
714
|
-
verifyExpectedArtifact,
|
|
715
|
-
clearUnitRuntimeRecord,
|
|
716
|
-
writeUnitRuntimeRecord,
|
|
717
699
|
recordOutcome,
|
|
718
700
|
writeLock,
|
|
719
701
|
captureAvailableSkills,
|
|
@@ -862,15 +844,6 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
|
|
|
862
844
|
});
|
|
863
845
|
}
|
|
864
846
|
invalidateAllCaches();
|
|
865
|
-
// Clean stale runtime records left from the paused session
|
|
866
|
-
try {
|
|
867
|
-
await selfHealRuntimeRecords(s.basePath, ctx);
|
|
868
|
-
}
|
|
869
|
-
catch (e) {
|
|
870
|
-
debugLog("resume-self-heal-runtime-failed", {
|
|
871
|
-
error: e instanceof Error ? e.message : String(e),
|
|
872
|
-
});
|
|
873
|
-
}
|
|
874
847
|
if (s.pausedSessionFile) {
|
|
875
848
|
const activityDir = join(gsdRoot(s.basePath), "activity");
|
|
876
849
|
const recovery = synthesizeCrashRecovery(s.basePath, s.currentUnit?.type ?? "unknown", s.currentUnit?.id ?? "unknown", s.pausedSessionFile ?? undefined, activityDir);
|
|
@@ -880,11 +853,9 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
|
|
|
880
853
|
}
|
|
881
854
|
s.pausedSessionFile = null;
|
|
882
855
|
}
|
|
883
|
-
updateSessionLock(lockBase(), "resuming", s.currentMilestoneId ?? "unknown"
|
|
884
|
-
writeLock(lockBase(), "resuming", s.currentMilestoneId ?? "unknown"
|
|
856
|
+
updateSessionLock(lockBase(), "resuming", s.currentMilestoneId ?? "unknown");
|
|
857
|
+
writeLock(lockBase(), "resuming", s.currentMilestoneId ?? "unknown");
|
|
885
858
|
logCmuxEvent(loadEffectiveGSDPreferences()?.preferences, s.stepMode ? "Step-mode resumed." : "Auto-mode resumed.", "progress");
|
|
886
|
-
// Clear orphaned runtime records from prior process deaths before entering the loop
|
|
887
|
-
await selfHealRuntimeRecords(s.basePath, ctx);
|
|
888
859
|
await autoLoop(ctx, pi, s, buildLoopDeps());
|
|
889
860
|
cleanupAfterLoopExit(ctx);
|
|
890
861
|
return;
|
|
@@ -906,8 +877,6 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
|
|
|
906
877
|
// Best-effort only — sidebar sync must never block auto-mode startup
|
|
907
878
|
}
|
|
908
879
|
logCmuxEvent(loadEffectiveGSDPreferences()?.preferences, requestedStepMode ? "Step-mode started." : "Auto-mode started.", "progress");
|
|
909
|
-
// Clear orphaned runtime records from prior process deaths before entering the loop
|
|
910
|
-
await selfHealRuntimeRecords(s.basePath, ctx);
|
|
911
880
|
// Dispatch the first unit
|
|
912
881
|
await autoLoop(ctx, pi, s, buildLoopDeps());
|
|
913
882
|
cleanupAfterLoopExit(ctx);
|
|
@@ -1006,7 +975,6 @@ export async function dispatchHookUnit(ctx, pi, hookName, triggerUnitType, trigg
|
|
|
1006
975
|
s.basePath = targetBasePath;
|
|
1007
976
|
s.autoStartTime = Date.now();
|
|
1008
977
|
s.currentUnit = null;
|
|
1009
|
-
s.completedUnits = [];
|
|
1010
978
|
s.pendingQuickTasks = [];
|
|
1011
979
|
}
|
|
1012
980
|
const hookUnitType = `hook/${hookName}`;
|
|
@@ -1026,14 +994,6 @@ export async function dispatchHookUnit(ctx, pi, hookName, triggerUnitType, trigg
|
|
|
1026
994
|
id: triggerUnitId,
|
|
1027
995
|
startedAt: hookStartedAt,
|
|
1028
996
|
};
|
|
1029
|
-
writeUnitRuntimeRecord(s.basePath, hookUnitType, triggerUnitId, hookStartedAt, {
|
|
1030
|
-
phase: "dispatched",
|
|
1031
|
-
wrapupWarningSent: false,
|
|
1032
|
-
timeoutAt: null,
|
|
1033
|
-
lastProgressAt: hookStartedAt,
|
|
1034
|
-
progressCount: 0,
|
|
1035
|
-
lastProgressKind: "dispatch",
|
|
1036
|
-
});
|
|
1037
997
|
if (hookModel) {
|
|
1038
998
|
const availableModels = ctx.modelRegistry.getAvailable();
|
|
1039
999
|
const match = resolveModelId(hookModel, availableModels, ctx.model?.provider);
|
|
@@ -1051,7 +1011,7 @@ export async function dispatchHookUnit(ctx, pi, hookName, triggerUnitType, trigg
|
|
|
1051
1011
|
}
|
|
1052
1012
|
}
|
|
1053
1013
|
const sessionFile = ctx.sessionManager.getSessionFile();
|
|
1054
|
-
writeLock(lockBase(), hookUnitType, triggerUnitId,
|
|
1014
|
+
writeLock(lockBase(), hookUnitType, triggerUnitId, sessionFile);
|
|
1055
1015
|
clearUnitTimeout();
|
|
1056
1016
|
const supervisor = resolveAutoSupervisorConfig();
|
|
1057
1017
|
const hookHardTimeoutMs = (supervisor.hard_timeout_minutes ?? 30) * 60 * 1000;
|
|
@@ -1059,12 +1019,6 @@ export async function dispatchHookUnit(ctx, pi, hookName, triggerUnitType, trigg
|
|
|
1059
1019
|
s.unitTimeoutHandle = null;
|
|
1060
1020
|
if (!s.active)
|
|
1061
1021
|
return;
|
|
1062
|
-
if (s.currentUnit) {
|
|
1063
|
-
writeUnitRuntimeRecord(s.basePath, hookUnitType, triggerUnitId, hookStartedAt, {
|
|
1064
|
-
phase: "timeout",
|
|
1065
|
-
timeoutAt: Date.now(),
|
|
1066
|
-
});
|
|
1067
|
-
}
|
|
1068
1022
|
ctx.ui.notify(`Hook ${hookName} exceeded ${supervisor.hard_timeout_minutes ?? 30}min timeout. Pausing auto-mode.`, "warning");
|
|
1069
1023
|
resetHookState();
|
|
1070
1024
|
await pauseAuto(ctx, pi);
|
|
@@ -1087,4 +1041,5 @@ export async function dispatchHookUnit(ctx, pi, hookName, triggerUnitType, trigg
|
|
|
1087
1041
|
// Direct phase dispatch → auto-direct-dispatch.ts
|
|
1088
1042
|
export { dispatchDirectPhase } from "./auto-direct-dispatch.js";
|
|
1089
1043
|
// Re-export recovery functions for external consumers
|
|
1090
|
-
export {
|
|
1044
|
+
export { buildLoopRemediationSteps, } from "./auto-recovery.js";
|
|
1045
|
+
export { resolveExpectedArtifactPath } from "./auto-artifact-paths.js";
|
|
@@ -4,6 +4,7 @@ import { findMilestoneIds, nextMilestoneId, claimReservedId, getReservedMileston
|
|
|
4
4
|
import { loadEffectiveGSDPreferences } from "../preferences.js";
|
|
5
5
|
import { ensureDbOpen } from "./dynamic-tools.js";
|
|
6
6
|
import { StringEnum } from "@gsd/pi-ai";
|
|
7
|
+
import { logError } from "../workflow-logger.js";
|
|
7
8
|
/**
|
|
8
9
|
* Register an alias tool that shares the same execute function as its canonical counterpart.
|
|
9
10
|
* The alias description and promptGuidelines direct the LLM to prefer the canonical name.
|
|
@@ -45,7 +46,7 @@ export function registerDbTools(pi) {
|
|
|
45
46
|
}
|
|
46
47
|
catch (err) {
|
|
47
48
|
const msg = err instanceof Error ? err.message : String(err);
|
|
48
|
-
|
|
49
|
+
logError("tool", `gsd_decision_save tool failed: ${msg}`, { tool: "gsd_decision_save", error: String(err) });
|
|
49
50
|
return {
|
|
50
51
|
content: [{ type: "text", text: `Error saving decision: ${msg}` }],
|
|
51
52
|
details: { operation: "save_decision", error: msg },
|
|
@@ -142,7 +143,7 @@ export function registerDbTools(pi) {
|
|
|
142
143
|
}
|
|
143
144
|
catch (err) {
|
|
144
145
|
const msg = err instanceof Error ? err.message : String(err);
|
|
145
|
-
|
|
146
|
+
logError("tool", `gsd_requirement_update tool failed: ${msg}`, { tool: "gsd_requirement_update", error: String(err) });
|
|
146
147
|
return {
|
|
147
148
|
content: [{ type: "text", text: `Error updating requirement: ${msg}` }],
|
|
148
149
|
details: { operation: "update_requirement", id: params.id, error: msg },
|
|
@@ -235,7 +236,7 @@ export function registerDbTools(pi) {
|
|
|
235
236
|
}
|
|
236
237
|
catch (err) {
|
|
237
238
|
const msg = err instanceof Error ? err.message : String(err);
|
|
238
|
-
|
|
239
|
+
logError("tool", `gsd_summary_save tool failed: ${msg}`, { tool: "gsd_summary_save", error: String(err) });
|
|
239
240
|
return {
|
|
240
241
|
content: [{ type: "text", text: `Error saving artifact: ${msg}` }],
|
|
241
242
|
details: { operation: "save_summary", error: msg },
|
|
@@ -394,7 +395,7 @@ export function registerDbTools(pi) {
|
|
|
394
395
|
}
|
|
395
396
|
catch (err) {
|
|
396
397
|
const msg = err instanceof Error ? err.message : String(err);
|
|
397
|
-
|
|
398
|
+
logError("tool", `plan_milestone tool failed: ${msg}`, { tool: "gsd_plan_milestone", error: String(err) });
|
|
398
399
|
return {
|
|
399
400
|
content: [{ type: "text", text: `Error planning milestone: ${msg}` }],
|
|
400
401
|
details: { operation: "plan_milestone", error: msg },
|
|
@@ -483,7 +484,7 @@ export function registerDbTools(pi) {
|
|
|
483
484
|
}
|
|
484
485
|
catch (err) {
|
|
485
486
|
const msg = err instanceof Error ? err.message : String(err);
|
|
486
|
-
|
|
487
|
+
logError("tool", `plan_slice tool failed: ${msg}`, { tool: "gsd_plan_slice", error: String(err) });
|
|
487
488
|
return {
|
|
488
489
|
content: [{ type: "text", text: `Error planning slice: ${msg}` }],
|
|
489
490
|
details: { operation: "plan_slice", error: msg },
|
|
@@ -556,7 +557,7 @@ export function registerDbTools(pi) {
|
|
|
556
557
|
}
|
|
557
558
|
catch (err) {
|
|
558
559
|
const msg = err instanceof Error ? err.message : String(err);
|
|
559
|
-
|
|
560
|
+
logError("tool", `plan_task tool failed: ${msg}`, { tool: "gsd_plan_task", error: String(err) });
|
|
560
561
|
return {
|
|
561
562
|
content: [{ type: "text", text: `Error planning task: ${msg}` }],
|
|
562
563
|
details: { operation: "plan_task", error: msg },
|
|
@@ -622,7 +623,7 @@ export function registerDbTools(pi) {
|
|
|
622
623
|
}
|
|
623
624
|
catch (err) {
|
|
624
625
|
const msg = err instanceof Error ? err.message : String(err);
|
|
625
|
-
|
|
626
|
+
logError("tool", `complete_task tool failed: ${msg}`, { tool: "gsd_task_complete", error: String(err) });
|
|
626
627
|
return {
|
|
627
628
|
content: [{ type: "text", text: `Error completing task: ${msg}` }],
|
|
628
629
|
details: { operation: "complete_task", error: msg },
|
|
@@ -696,7 +697,7 @@ export function registerDbTools(pi) {
|
|
|
696
697
|
}
|
|
697
698
|
catch (err) {
|
|
698
699
|
const msg = err instanceof Error ? err.message : String(err);
|
|
699
|
-
|
|
700
|
+
logError("tool", `complete_slice tool failed: ${msg}`, { tool: "gsd_slice_complete", error: String(err) });
|
|
700
701
|
return {
|
|
701
702
|
content: [{ type: "text", text: `Error completing slice: ${msg}` }],
|
|
702
703
|
details: { operation: "complete_slice", error: msg },
|
|
@@ -788,7 +789,7 @@ export function registerDbTools(pi) {
|
|
|
788
789
|
}
|
|
789
790
|
catch (err) {
|
|
790
791
|
const msg = err instanceof Error ? err.message : String(err);
|
|
791
|
-
|
|
792
|
+
logError("tool", `complete_milestone tool failed: ${msg}`, { tool: "gsd_complete_milestone", error: String(err) });
|
|
792
793
|
return {
|
|
793
794
|
content: [{ type: "text", text: `Error completing milestone: ${msg}` }],
|
|
794
795
|
details: { operation: "complete_milestone", error: msg },
|
|
@@ -804,6 +805,7 @@ export function registerDbTools(pi) {
|
|
|
804
805
|
promptGuidelines: [
|
|
805
806
|
"Use gsd_complete_milestone when all slices in a milestone are finished and the milestone needs to be recorded.",
|
|
806
807
|
"All slices in the milestone must have status 'complete' — the handler validates this before proceeding.",
|
|
808
|
+
"verificationPassed must be explicitly set to true — the handler rejects completion if verification did not pass.",
|
|
807
809
|
"On success, returns summaryPath where the MILESTONE-SUMMARY.md was written.",
|
|
808
810
|
],
|
|
809
811
|
parameters: Type.Object({
|
|
@@ -819,6 +821,7 @@ export function registerDbTools(pi) {
|
|
|
819
821
|
lessonsLearned: Type.Array(Type.String(), { description: "Lessons learned during the milestone" }),
|
|
820
822
|
followUps: Type.Optional(Type.String({ description: "Follow-up items for future milestones" })),
|
|
821
823
|
deviations: Type.Optional(Type.String({ description: "Deviations from the original plan" })),
|
|
824
|
+
verificationPassed: Type.Boolean({ description: "Must be true — confirms that code change verification, success criteria, and definition of done checks all passed before completion" }),
|
|
822
825
|
}),
|
|
823
826
|
execute: milestoneCompleteExecute,
|
|
824
827
|
};
|
|
@@ -854,7 +857,7 @@ export function registerDbTools(pi) {
|
|
|
854
857
|
}
|
|
855
858
|
catch (err) {
|
|
856
859
|
const msg = err instanceof Error ? err.message : String(err);
|
|
857
|
-
|
|
860
|
+
logError("tool", `validate_milestone tool failed: ${msg}`, { tool: "gsd_validate_milestone", error: String(err) });
|
|
858
861
|
return {
|
|
859
862
|
content: [{ type: "text", text: `Error validating milestone: ${msg}` }],
|
|
860
863
|
details: { operation: "validate_milestone", error: msg },
|
|
@@ -919,7 +922,7 @@ export function registerDbTools(pi) {
|
|
|
919
922
|
}
|
|
920
923
|
catch (err) {
|
|
921
924
|
const msg = err instanceof Error ? err.message : String(err);
|
|
922
|
-
|
|
925
|
+
logError("tool", `replan_slice tool failed: ${msg}`, { tool: "gsd_replan_slice", error: String(err) });
|
|
923
926
|
return {
|
|
924
927
|
content: [{ type: "text", text: `Error replanning slice: ${msg}` }],
|
|
925
928
|
details: { operation: "replan_slice", error: msg },
|
|
@@ -992,7 +995,7 @@ export function registerDbTools(pi) {
|
|
|
992
995
|
}
|
|
993
996
|
catch (err) {
|
|
994
997
|
const msg = err instanceof Error ? err.message : String(err);
|
|
995
|
-
|
|
998
|
+
logError("tool", `reassess_roadmap tool failed: ${msg}`, { tool: "gsd_reassess_roadmap", error: String(err) });
|
|
996
999
|
return {
|
|
997
1000
|
content: [{ type: "text", text: `Error reassessing roadmap: ${msg}` }],
|
|
998
1001
|
details: { operation: "reassess_roadmap", error: msg },
|
|
@@ -4,6 +4,7 @@ import { buildMilestoneFileName, resolveMilestonePath, resolveSliceFile, resolve
|
|
|
4
4
|
import { buildBeforeAgentStartResult } from "./system-context.js";
|
|
5
5
|
import { handleAgentEnd } from "./agent-end-recovery.js";
|
|
6
6
|
import { isDepthVerified, isQueuePhaseActive, markDepthVerified, resetWriteGateState, shouldBlockContextWrite } from "./write-gate.js";
|
|
7
|
+
import { isBlockedStateFile, isBashWriteToStateFile, BLOCKED_WRITE_ERROR } from "../write-intercept.js";
|
|
7
8
|
import { getDiscussionMilestoneId } from "../guided-flow.js";
|
|
8
9
|
import { loadToolApiKeys } from "../commands-config.js";
|
|
9
10
|
import { loadFile, saveFile, formatContinue } from "../files.js";
|
|
@@ -128,6 +129,23 @@ export function registerHooks(pi) {
|
|
|
128
129
|
if (loopCheck.block) {
|
|
129
130
|
return { block: true, reason: loopCheck.reason };
|
|
130
131
|
}
|
|
132
|
+
// ── Single-writer engine: block direct writes to STATE.md ──────────
|
|
133
|
+
// Covers write, edit, and bash tools to prevent bypass vectors.
|
|
134
|
+
if (isToolCallEventType("write", event)) {
|
|
135
|
+
if (isBlockedStateFile(event.input.path)) {
|
|
136
|
+
return { block: true, reason: BLOCKED_WRITE_ERROR };
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (isToolCallEventType("edit", event)) {
|
|
140
|
+
if (isBlockedStateFile(event.input.path)) {
|
|
141
|
+
return { block: true, reason: BLOCKED_WRITE_ERROR };
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (isToolCallEventType("bash", event)) {
|
|
145
|
+
if (isBashWriteToStateFile(event.input.command)) {
|
|
146
|
+
return { block: true, reason: BLOCKED_WRITE_ERROR };
|
|
147
|
+
}
|
|
148
|
+
}
|
|
131
149
|
if (!isToolCallEventType("write", event))
|
|
132
150
|
return;
|
|
133
151
|
const result = shouldBlockContextWrite(event.toolName, event.input.path, getDiscussionMilestoneId(), isDepthVerified(), isQueuePhaseActive());
|
|
@@ -30,14 +30,10 @@ export async function guardRemoteSession(ctx, pi) {
|
|
|
30
30
|
`Stop it first with /gsd stop, or use /gsd steer to redirect it.`, "warning");
|
|
31
31
|
return false;
|
|
32
32
|
}
|
|
33
|
-
const unitsMsg = remote.completedUnits != null
|
|
34
|
-
? `${remote.completedUnits} units completed`
|
|
35
|
-
: "";
|
|
36
33
|
const choice = await showNextAction(ctx, {
|
|
37
34
|
title: `Auto-mode is running in another terminal (PID ${remote.pid})`,
|
|
38
35
|
summary: [
|
|
39
36
|
`Currently executing: ${unitLabel}`,
|
|
40
|
-
...(unitsMsg ? [unitsMsg] : []),
|
|
41
37
|
...(remote.startedAt ? [`Started: ${remote.startedAt}`] : []),
|
|
42
38
|
],
|
|
43
39
|
actions: [
|
|
@@ -44,7 +44,7 @@ export async function handleParallelCommand(trimmed, _ctx, pi) {
|
|
|
44
44
|
}
|
|
45
45
|
const lines = ["# Parallel Workers\n"];
|
|
46
46
|
for (const worker of workers) {
|
|
47
|
-
lines.push(`- **${worker.milestoneId}** (${worker.title}) — ${worker.state} —
|
|
47
|
+
lines.push(`- **${worker.milestoneId}** (${worker.title}) — ${worker.state} — $${worker.cost.toFixed(2)}`);
|
|
48
48
|
}
|
|
49
49
|
const state = getOrchestratorState();
|
|
50
50
|
if (state) {
|
|
@@ -18,7 +18,7 @@ function lockPath(basePath) {
|
|
|
18
18
|
return join(gsdRoot(basePath), LOCK_FILE);
|
|
19
19
|
}
|
|
20
20
|
/** Write or update the lock file with current auto-mode state. */
|
|
21
|
-
export function writeLock(basePath, unitType, unitId,
|
|
21
|
+
export function writeLock(basePath, unitType, unitId, sessionFile) {
|
|
22
22
|
try {
|
|
23
23
|
const data = {
|
|
24
24
|
pid: process.pid,
|
|
@@ -26,7 +26,6 @@ export function writeLock(basePath, unitType, unitId, completedUnits, sessionFil
|
|
|
26
26
|
unitType,
|
|
27
27
|
unitId,
|
|
28
28
|
unitStartedAt: new Date().toISOString(),
|
|
29
|
-
completedUnits,
|
|
30
29
|
sessionFile,
|
|
31
30
|
};
|
|
32
31
|
const lp = lockPath(basePath);
|
|
@@ -90,11 +89,10 @@ export function formatCrashInfo(lock) {
|
|
|
90
89
|
`Previous auto-mode session was interrupted.`,
|
|
91
90
|
` Was executing: ${lock.unitType} (${lock.unitId})`,
|
|
92
91
|
` Started at: ${lock.unitStartedAt}`,
|
|
93
|
-
` Units completed before crash: ${lock.completedUnits}`,
|
|
94
92
|
` PID: ${lock.pid}`,
|
|
95
93
|
];
|
|
96
94
|
// Add recovery guidance based on what was happening when it crashed
|
|
97
|
-
if (lock.unitType === "starting" && lock.unitId === "bootstrap"
|
|
95
|
+
if (lock.unitType === "starting" && lock.unitId === "bootstrap") {
|
|
98
96
|
lines.push(`No work was lost. Run /gsd auto to restart.`);
|
|
99
97
|
}
|
|
100
98
|
else if (lock.unitType.includes("research") || lock.unitType.includes("plan")) {
|
|
@@ -81,18 +81,11 @@ export class GSDDashboardOverlay {
|
|
|
81
81
|
const currentUnit = dashData.currentUnit
|
|
82
82
|
? `${dashData.currentUnit.type}:${dashData.currentUnit.id}:${dashData.currentUnit.startedAt}`
|
|
83
83
|
: "-";
|
|
84
|
-
const lastCompleted = dashData.completedUnits.length > 0
|
|
85
|
-
? dashData.completedUnits[dashData.completedUnits.length - 1]
|
|
86
|
-
: null;
|
|
87
|
-
const completedKey = lastCompleted
|
|
88
|
-
? `${dashData.completedUnits.length}:${lastCompleted.type}:${lastCompleted.id}:${lastCompleted.finishedAt}`
|
|
89
|
-
: "0";
|
|
90
84
|
return [
|
|
91
85
|
base,
|
|
92
86
|
dashData.active ? "1" : "0",
|
|
93
87
|
dashData.paused ? "1" : "0",
|
|
94
88
|
currentUnit,
|
|
95
|
-
completedKey,
|
|
96
89
|
].join("|");
|
|
97
90
|
}
|
|
98
91
|
async refreshDashboard(initial = false) {
|
|
@@ -393,43 +386,6 @@ export class GSDDashboardOverlay {
|
|
|
393
386
|
else {
|
|
394
387
|
lines.push(centered(th.fg("dim", "No active milestone.")));
|
|
395
388
|
}
|
|
396
|
-
if (this.dashData.completedUnits.length > 0) {
|
|
397
|
-
lines.push(blank());
|
|
398
|
-
lines.push(hr());
|
|
399
|
-
lines.push(row(th.fg("text", th.bold("Completed"))));
|
|
400
|
-
lines.push(blank());
|
|
401
|
-
// Build ledger lookup for budget indicators (last entry wins for retries)
|
|
402
|
-
const ledgerLookup = new Map();
|
|
403
|
-
const currentLedger = getLedger();
|
|
404
|
-
if (currentLedger) {
|
|
405
|
-
for (const lu of currentLedger.units) {
|
|
406
|
-
ledgerLookup.set(`${lu.type}:${lu.id}`, lu);
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
const recent = [...this.dashData.completedUnits].reverse().slice(0, 10);
|
|
410
|
-
for (const u of recent) {
|
|
411
|
-
// Budget indicators from ledger — use warning glyph for pressured units
|
|
412
|
-
const ledgerEntry = ledgerLookup.get(`${u.type}:${u.id}`);
|
|
413
|
-
const hadPressure = ledgerEntry?.continueHereFired === true;
|
|
414
|
-
const hadTruncation = (ledgerEntry?.truncationSections ?? 0) > 0;
|
|
415
|
-
const unitGlyph = hadPressure
|
|
416
|
-
? th.fg(STATUS_COLOR.warning, STATUS_GLYPH.warning)
|
|
417
|
-
: th.fg(STATUS_COLOR.done, STATUS_GLYPH.done);
|
|
418
|
-
const left = ` ${unitGlyph} ${th.fg("muted", unitLabel(u.type))} ${th.fg("muted", u.id)}`;
|
|
419
|
-
let budgetMarkers = "";
|
|
420
|
-
if (hadTruncation) {
|
|
421
|
-
budgetMarkers += th.fg("warning", ` ▼${ledgerEntry.truncationSections}`);
|
|
422
|
-
}
|
|
423
|
-
if (hadPressure) {
|
|
424
|
-
budgetMarkers += th.fg("error", " → wrap-up");
|
|
425
|
-
}
|
|
426
|
-
const right = th.fg("dim", formatDuration(u.finishedAt - u.startedAt));
|
|
427
|
-
lines.push(row(joinColumns(`${left}${budgetMarkers}`, right, contentWidth)));
|
|
428
|
-
}
|
|
429
|
-
if (this.dashData.completedUnits.length > 10) {
|
|
430
|
-
lines.push(row(th.fg("dim", ` ...and ${this.dashData.completedUnits.length - 10} more`)));
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
389
|
const ledger = getLedger();
|
|
434
390
|
if (ledger && ledger.units.length > 0) {
|
|
435
391
|
const totals = getProjectTotals(ledger.units);
|
|
@@ -12,6 +12,7 @@ import { readFileSync, existsSync, statSync } from 'node:fs';
|
|
|
12
12
|
import { resolveGsdRootFile } from './paths.js';
|
|
13
13
|
import { saveFile } from './files.js';
|
|
14
14
|
import { GSDError, GSD_STALE_STATE, GSD_IO_ERROR } from './errors.js';
|
|
15
|
+
import { logWarning, logError } from './workflow-logger.js';
|
|
15
16
|
import { invalidateStateCache } from './state.js';
|
|
16
17
|
import { clearPathCache } from './paths.js';
|
|
17
18
|
import { clearParseCache } from './files.js';
|
|
@@ -200,7 +201,7 @@ export async function nextDecisionId() {
|
|
|
200
201
|
return `D${String(next).padStart(3, '0')}`;
|
|
201
202
|
}
|
|
202
203
|
catch (err) {
|
|
203
|
-
|
|
204
|
+
logError('manifest', 'nextDecisionId failed', { fn: 'nextDecisionId', error: String(err.message) });
|
|
204
205
|
return 'D001';
|
|
205
206
|
}
|
|
206
207
|
}
|
|
@@ -269,7 +270,7 @@ export async function saveDecisionToDb(fields, basePath) {
|
|
|
269
270
|
await saveFile(filePath, md);
|
|
270
271
|
}
|
|
271
272
|
catch (diskErr) {
|
|
272
|
-
|
|
273
|
+
logError('manifest', 'disk write failed, rolling back DB row', { fn: 'saveDecisionToDb', error: String(diskErr.message) });
|
|
273
274
|
adapter?.prepare('DELETE FROM decisions WHERE id = :id').run({ ':id': id });
|
|
274
275
|
throw diskErr;
|
|
275
276
|
}
|
|
@@ -281,7 +282,7 @@ export async function saveDecisionToDb(fields, basePath) {
|
|
|
281
282
|
return { id };
|
|
282
283
|
}
|
|
283
284
|
catch (err) {
|
|
284
|
-
|
|
285
|
+
logError('manifest', 'saveDecisionToDb failed', { fn: 'saveDecisionToDb', error: String(err.message) });
|
|
285
286
|
throw err;
|
|
286
287
|
}
|
|
287
288
|
}
|
|
@@ -333,7 +334,7 @@ export async function updateRequirementInDb(id, updates, basePath) {
|
|
|
333
334
|
await saveFile(filePath, md);
|
|
334
335
|
}
|
|
335
336
|
catch (diskErr) {
|
|
336
|
-
|
|
337
|
+
logError('manifest', 'disk write failed, reverting DB row', { fn: 'updateRequirementInDb', error: String(diskErr.message) });
|
|
337
338
|
db.upsertRequirement(existing);
|
|
338
339
|
throw diskErr;
|
|
339
340
|
}
|
|
@@ -344,7 +345,7 @@ export async function updateRequirementInDb(id, updates, basePath) {
|
|
|
344
345
|
clearParseCache();
|
|
345
346
|
}
|
|
346
347
|
catch (err) {
|
|
347
|
-
|
|
348
|
+
logError('manifest', 'updateRequirementInDb failed', { fn: 'updateRequirementInDb', error: String(err.message) });
|
|
348
349
|
throw err;
|
|
349
350
|
}
|
|
350
351
|
}
|
|
@@ -371,8 +372,7 @@ export async function saveArtifactToDb(opts, basePath) {
|
|
|
371
372
|
const existingSize = statSync(fullPath).size;
|
|
372
373
|
const newSize = Buffer.byteLength(opts.content, 'utf-8');
|
|
373
374
|
if (existingSize > 0 && newSize < existingSize * 0.5) {
|
|
374
|
-
|
|
375
|
-
`(${existingSize}B) at ${opts.path}. Preserving disk file to prevent data loss.\n`);
|
|
375
|
+
logWarning('manifest', `new content (${newSize}B) is <50% of existing file (${existingSize}B), preserving disk file`, { fn: 'saveArtifactToDb', path: opts.path });
|
|
376
376
|
dbContent = readFileSync(fullPath, 'utf-8');
|
|
377
377
|
skipDiskWrite = true;
|
|
378
378
|
}
|
|
@@ -391,7 +391,7 @@ export async function saveArtifactToDb(opts, basePath) {
|
|
|
391
391
|
await saveFile(fullPath, opts.content);
|
|
392
392
|
}
|
|
393
393
|
catch (diskErr) {
|
|
394
|
-
|
|
394
|
+
logError('manifest', 'disk write failed, rolling back DB row', { fn: 'saveArtifactToDb', error: String(diskErr.message) });
|
|
395
395
|
const rollbackAdapter = db._getAdapter();
|
|
396
396
|
rollbackAdapter?.prepare('DELETE FROM artifacts WHERE path = :path').run({ ':path': opts.path });
|
|
397
397
|
throw diskErr;
|
|
@@ -404,7 +404,7 @@ export async function saveArtifactToDb(opts, basePath) {
|
|
|
404
404
|
clearParseCache();
|
|
405
405
|
}
|
|
406
406
|
catch (err) {
|
|
407
|
-
|
|
407
|
+
logError('manifest', 'saveArtifactToDb failed', { fn: 'saveArtifactToDb', error: String(err.message) });
|
|
408
408
|
throw err;
|
|
409
409
|
}
|
|
410
410
|
}
|