gsd-pi 2.44.0 → 2.45.0-dev.e0ee972
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -12
- package/dist/help-text.js +1 -1
- package/dist/loader.js +34 -0
- package/dist/resources/extensions/gsd/activity-log.js +7 -0
- package/dist/resources/extensions/gsd/auto/infra-errors.js +3 -0
- package/dist/resources/extensions/gsd/auto/phases.js +52 -45
- package/dist/resources/extensions/gsd/auto/run-unit.js +6 -3
- package/dist/resources/extensions/gsd/auto-prompts.js +24 -1
- package/dist/resources/extensions/gsd/auto-start.js +31 -2
- package/dist/resources/extensions/gsd/auto-timers.js +57 -3
- package/dist/resources/extensions/gsd/auto-worktree-sync.js +4 -0
- package/dist/resources/extensions/gsd/auto-worktree.js +14 -10
- package/dist/resources/extensions/gsd/auto.js +34 -8
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +168 -11
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +46 -12
- package/dist/resources/extensions/gsd/commands/catalog.js +7 -1
- package/dist/resources/extensions/gsd/commands/handlers/core.js +2 -0
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +10 -0
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +5 -0
- package/dist/resources/extensions/gsd/commands-mcp-status.js +187 -0
- package/dist/resources/extensions/gsd/db-writer.js +40 -22
- package/dist/resources/extensions/gsd/doctor-checks.js +1 -1
- package/dist/resources/extensions/gsd/doctor.js +10 -2
- package/dist/resources/extensions/gsd/git-service.js +8 -3
- package/dist/resources/extensions/gsd/gsd-db.js +17 -2
- package/dist/resources/extensions/gsd/markdown-renderer.js +1 -1
- package/dist/resources/extensions/gsd/preferences-types.js +2 -2
- package/dist/resources/extensions/gsd/preferences.js +17 -5
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +2 -4
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -6
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +3 -14
- package/dist/resources/extensions/gsd/prompts/rethink.md +78 -0
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +7 -37
- package/dist/resources/extensions/gsd/provider-error-pause.js +7 -0
- package/dist/resources/extensions/gsd/repo-identity.js +45 -7
- package/dist/resources/extensions/gsd/rethink.js +115 -0
- package/dist/resources/extensions/gsd/state.js +41 -3
- package/dist/resources/extensions/gsd/tools/plan-slice.js +1 -0
- package/dist/resources/extensions/gsd/tools/plan-task.js +1 -0
- package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -0
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +88 -0
- package/dist/resources/extensions/gsd/workflow-logger.js +138 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +34 -3
- package/dist/resources/extensions/gsd/worktree-resolver.js +43 -0
- package/dist/resources/extensions/mcp-client/index.js +14 -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 +15 -15
- package/dist/web/standalone/.next/build-manifest.json +4 -4
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
- 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 +5 -5
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +5 -5
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +5 -5
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -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 +6 -6
- 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 +6 -6
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +15 -15
- 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-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +2 -2
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/4024.11ca5c01938e5948.js +9 -0
- package/dist/web/standalone/.next/static/chunks/{3721.bf31263de6d5fa46.js → 485.243af25f0cdf50d6.js} +2 -2
- 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/.next/static/chunks/webpack-0a4cd455ec4197d2.js +1 -0
- package/dist/web/standalone/.next/static/css/dd4ae3f58ac9b600.css +1 -0
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/package.json +1 -1
- package/packages/native/dist/stream-process/index.js +2 -2
- package/packages/native/src/__tests__/stream-process.test.mjs +34 -0
- package/packages/native/src/stream-process/index.ts +2 -2
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +3 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +15 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js +6 -8
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-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/runner.test.js +24 -26
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +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/fs-utils.test.js +29 -48
- package/packages/pi-coding-agent/dist/core/fs-utils.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lifecycle-hooks.d.ts +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/local-model-check.d.ts +15 -0
- package/packages/pi-coding-agent/dist/core/local-model-check.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/local-model-check.js +41 -0
- package/packages/pi-coding-agent/dist/core/local-model-check.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 +13 -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 +40 -3
- 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/dist/core/resolve-config-value.test.js +34 -44
- package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.test.js +30 -34
- package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +6 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +10 -12
- package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/main.js +17 -0
- package/packages/pi-coding-agent/dist/main.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.js +32 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +3 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +8 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +12 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.d.ts +15 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.js +40 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +4 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts +5 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +13 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +17 -8
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +7 -3
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js +43 -47
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/auth-storage.test.ts +7 -7
- package/packages/pi-coding-agent/src/core/auth-storage.ts +15 -1
- package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +2 -0
- package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +26 -26
- package/packages/pi-coding-agent/src/core/extensions/types.ts +2 -1
- package/packages/pi-coding-agent/src/core/fs-utils.test.ts +31 -43
- 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/local-model-check.ts +45 -0
- 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 +51 -4
- package/packages/pi-coding-agent/src/core/package-commands.test.ts +227 -205
- package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +40 -45
- package/packages/pi-coding-agent/src/core/session-manager.test.ts +33 -33
- package/packages/pi-coding-agent/src/core/settings-manager.ts +9 -0
- package/packages/pi-coding-agent/src/core/tools/edit-diff.test.ts +17 -17
- package/packages/pi-coding-agent/src/main.ts +19 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/timestamp.test.ts +38 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +10 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +15 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/timestamp.ts +48 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +3 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +18 -3
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +16 -7
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +8 -1
- package/packages/pi-coding-agent/src/resources/extensions/memory/storage.test.ts +74 -74
- package/pkg/package.json +1 -1
- package/src/resources/extensions/gsd/activity-log.ts +1 -0
- package/src/resources/extensions/gsd/auto/infra-errors.ts +3 -0
- package/src/resources/extensions/gsd/auto/phases.ts +61 -59
- package/src/resources/extensions/gsd/auto/run-unit.ts +6 -3
- package/src/resources/extensions/gsd/auto-prompts.ts +24 -1
- package/src/resources/extensions/gsd/auto-start.ts +39 -2
- package/src/resources/extensions/gsd/auto-timers.ts +64 -3
- package/src/resources/extensions/gsd/auto-worktree-sync.ts +5 -0
- package/src/resources/extensions/gsd/auto-worktree.ts +17 -11
- package/src/resources/extensions/gsd/auto.ts +40 -6
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +160 -11
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +48 -11
- package/src/resources/extensions/gsd/commands/catalog.ts +7 -1
- package/src/resources/extensions/gsd/commands/handlers/core.ts +2 -0
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +10 -0
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +8 -0
- package/src/resources/extensions/gsd/commands-mcp-status.ts +247 -0
- package/src/resources/extensions/gsd/db-writer.ts +41 -27
- package/src/resources/extensions/gsd/doctor-checks.ts +1 -1
- package/src/resources/extensions/gsd/doctor.ts +9 -3
- package/src/resources/extensions/gsd/git-service.ts +6 -2
- package/src/resources/extensions/gsd/gsd-db.ts +21 -2
- package/src/resources/extensions/gsd/journal.ts +6 -1
- package/src/resources/extensions/gsd/markdown-renderer.ts +1 -1
- package/src/resources/extensions/gsd/preferences-types.ts +2 -2
- package/src/resources/extensions/gsd/preferences.ts +18 -4
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +2 -4
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -6
- package/src/resources/extensions/gsd/prompts/replan-slice.md +3 -14
- package/src/resources/extensions/gsd/prompts/rethink.md +78 -0
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +7 -37
- package/src/resources/extensions/gsd/provider-error-pause.ts +9 -0
- package/src/resources/extensions/gsd/repo-identity.ts +46 -7
- package/src/resources/extensions/gsd/rethink.ts +154 -0
- package/src/resources/extensions/gsd/state.ts +41 -1
- package/src/resources/extensions/gsd/tests/all-milestones-complete-merge.test.ts +99 -99
- package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +14 -16
- package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +43 -57
- package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +88 -0
- package/src/resources/extensions/gsd/tests/auto-preflight.test.ts +11 -13
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +465 -523
- package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +73 -75
- package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +34 -56
- package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +533 -656
- package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +165 -143
- package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +29 -52
- package/src/resources/extensions/gsd/tests/captures.test.ts +148 -176
- package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +32 -33
- package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +141 -143
- package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +25 -25
- package/src/resources/extensions/gsd/tests/commands-logs.test.ts +81 -81
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +38 -59
- package/src/resources/extensions/gsd/tests/complete-slice.test.ts +228 -263
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +250 -302
- package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +114 -0
- package/src/resources/extensions/gsd/tests/context-store.test.ts +354 -367
- package/src/resources/extensions/gsd/tests/continue-here.test.ts +68 -72
- package/src/resources/extensions/gsd/tests/cost-projection.test.ts +92 -106
- package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +27 -35
- package/src/resources/extensions/gsd/tests/dashboard-budget.test.ts +220 -237
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +465 -416
- package/src/resources/extensions/gsd/tests/definition-loader.test.ts +76 -92
- package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +68 -83
- package/src/resources/extensions/gsd/tests/derive-state-db-disk-reconcile.test.ts +121 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +210 -181
- package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +78 -101
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +192 -227
- package/src/resources/extensions/gsd/tests/detection.test.ts +232 -278
- package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +30 -34
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +164 -180
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +43 -49
- package/src/resources/extensions/gsd/tests/dispatch-uat-last-completed.test.ts +28 -32
- package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +27 -29
- package/src/resources/extensions/gsd/tests/doctor-delimiter-fix.test.ts +34 -38
- package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +54 -75
- package/src/resources/extensions/gsd/tests/doctor-environment-worktree.test.ts +21 -32
- package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +72 -97
- package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +38 -44
- package/src/resources/extensions/gsd/tests/doctor-git.test.ts +104 -145
- package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +84 -106
- package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +54 -60
- package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +72 -93
- package/src/resources/extensions/gsd/tests/doctor.test.ts +104 -134
- package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +123 -131
- package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +120 -0
- package/src/resources/extensions/gsd/tests/exit-command.test.ts +20 -24
- package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +48 -57
- package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +5 -7
- package/src/resources/extensions/gsd/tests/flag-file-db.test.ts +30 -42
- package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +198 -206
- package/src/resources/extensions/gsd/tests/git-locale.test.ts +13 -27
- package/src/resources/extensions/gsd/tests/git-service.test.ts +285 -388
- package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +31 -39
- package/src/resources/extensions/gsd/tests/graph-operations.test.ts +63 -69
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +255 -264
- package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +108 -119
- package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +81 -103
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +229 -262
- package/src/resources/extensions/gsd/tests/headless-answers.test.ts +13 -13
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +29 -37
- package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +81 -102
- package/src/resources/extensions/gsd/tests/infra-error.test.ts +20 -2
- package/src/resources/extensions/gsd/tests/inherited-repo-home-dir.test.ts +121 -0
- package/src/resources/extensions/gsd/tests/init-wizard.test.ts +16 -18
- package/src/resources/extensions/gsd/tests/integration-edge.test.ts +41 -46
- package/src/resources/extensions/gsd/tests/integration-lifecycle.test.ts +42 -53
- package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +75 -91
- package/src/resources/extensions/gsd/tests/integration-proof.test.ts +18 -18
- package/src/resources/extensions/gsd/tests/knowledge.test.ts +89 -0
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +150 -194
- package/src/resources/extensions/gsd/tests/mcp-status.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +101 -125
- package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +45 -54
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +80 -93
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/migrate-command.test.ts +57 -66
- package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +83 -93
- package/src/resources/extensions/gsd/tests/migrate-parser.test.ts +161 -170
- package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +125 -141
- package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +107 -131
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +87 -96
- package/src/resources/extensions/gsd/tests/migrate-writer.test.ts +125 -164
- package/src/resources/extensions/gsd/tests/must-have-parser.test.ts +81 -94
- package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +75 -37
- package/src/resources/extensions/gsd/tests/overrides.test.ts +99 -106
- package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +40 -47
- package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +25 -28
- package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +66 -83
- package/src/resources/extensions/gsd/tests/park-edge-cases.test.ts +54 -77
- package/src/resources/extensions/gsd/tests/park-milestone.test.ts +68 -115
- package/src/resources/extensions/gsd/tests/parsers.test.ts +546 -611
- package/src/resources/extensions/gsd/tests/paths.test.ts +72 -87
- package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +77 -117
- package/src/resources/extensions/gsd/tests/preferences.test.ts +34 -9
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +11 -7
- package/src/resources/extensions/gsd/tests/prompt-db.test.ts +56 -56
- package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +93 -119
- package/src/resources/extensions/gsd/tests/queue-order.test.ts +70 -82
- package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +42 -55
- package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +100 -0
- package/src/resources/extensions/gsd/tests/quick-branch-lifecycle.test.ts +45 -73
- package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +28 -38
- package/src/resources/extensions/gsd/tests/recovery-attempts-reset.test.ts +176 -0
- package/src/resources/extensions/gsd/tests/replan-slice.test.ts +73 -80
- package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +71 -74
- package/src/resources/extensions/gsd/tests/requirements.test.ts +70 -75
- package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +44 -66
- package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +114 -181
- package/src/resources/extensions/gsd/tests/rule-registry.test.ts +63 -65
- package/src/resources/extensions/gsd/tests/run-uat.test.ts +66 -128
- package/src/resources/extensions/gsd/tests/session-lock-multipath.test.ts +18 -25
- package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +37 -44
- package/src/resources/extensions/gsd/tests/shared-wal.test.ts +19 -26
- package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +63 -0
- package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +6 -8
- package/src/resources/extensions/gsd/tests/stop-auto-merge-back.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/survivor-branch-complete.test.ts +108 -0
- package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +22 -28
- package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/token-savings.test.ts +54 -56
- package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +23 -25
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +10 -11
- package/src/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +66 -82
- package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +46 -47
- package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -22
- package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -86
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +41 -43
- package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +94 -96
- package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +11 -13
- package/src/resources/extensions/gsd/tests/worker-registry.test.ts +27 -29
- package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +275 -0
- package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +50 -52
- package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +10 -13
- package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +14 -18
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +38 -39
- package/src/resources/extensions/gsd/tests/worktree-e2e.test.ts +17 -21
- package/src/resources/extensions/gsd/tests/worktree-health.test.ts +25 -30
- package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +30 -37
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +220 -0
- package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +15 -22
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +59 -66
- package/src/resources/extensions/gsd/tests/worktree.test.ts +44 -50
- package/src/resources/extensions/gsd/tools/plan-slice.ts +2 -0
- package/src/resources/extensions/gsd/tools/plan-task.ts +2 -0
- package/src/resources/extensions/gsd/tools/replan-slice.ts +3 -0
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +127 -0
- package/src/resources/extensions/gsd/workflow-logger.ts +193 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +41 -5
- package/src/resources/extensions/gsd/worktree-resolver.ts +44 -0
- package/src/resources/extensions/mcp-client/index.ts +20 -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/4024.0de81b543b28b9fe.js +0 -9
- package/dist/web/standalone/.next/static/chunks/app/page-7e9530a7122506c5.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/chunks/webpack-9014b5adb127a98a.js +0 -1
- package/dist/web/standalone/.next/static/css/8a727f372cf53002.css +0 -1
- /package/dist/web/standalone/.next/static/{mgkxN0mGP6gSUmGPEzbk_ → dFMji9G1LZ-Tv36el9pRT}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{mgkxN0mGP6gSUmGPEzbk_ → dFMji9G1LZ-Tv36el9pRT}/_ssgManifest.js +0 -0
|
@@ -18,6 +18,9 @@ export const INFRA_ERROR_CODES: ReadonlySet<string> = new Set([
|
|
|
18
18
|
"EDQUOT", // disk quota exceeded
|
|
19
19
|
"EMFILE", // too many open files (process)
|
|
20
20
|
"ENFILE", // too many open files (system)
|
|
21
|
+
"ECONNREFUSED", // connection refused (offline / local server down)
|
|
22
|
+
"ENOTFOUND", // DNS lookup failed (offline / no network)
|
|
23
|
+
"ENETUNREACH", // network unreachable (offline / no route)
|
|
21
24
|
]);
|
|
22
25
|
|
|
23
26
|
/**
|
|
@@ -27,7 +27,10 @@ import { debugLog } from "../debug-logger.js";
|
|
|
27
27
|
import { gsdRoot } from "../paths.js";
|
|
28
28
|
import { atomicWriteSync } from "../atomic-write.js";
|
|
29
29
|
import { PROJECT_FILES } from "../detection.js";
|
|
30
|
+
import { MergeConflictError } from "../git-service.js";
|
|
30
31
|
import { join } from "node:path";
|
|
32
|
+
import { existsSync, cpSync } from "node:fs";
|
|
33
|
+
import { logWarning, logError } from "../workflow-logger.js";
|
|
31
34
|
|
|
32
35
|
// ─── generateMilestoneReport ──────────────────────────────────────────────────
|
|
33
36
|
|
|
@@ -162,8 +165,8 @@ export async function runPreDispatch(
|
|
|
162
165
|
debugLog("autoLoop", { phase: "exit", reason: "health-gate-failed" });
|
|
163
166
|
return { action: "break", reason: "health-gate-failed" };
|
|
164
167
|
}
|
|
165
|
-
} catch {
|
|
166
|
-
|
|
168
|
+
} catch (e) {
|
|
169
|
+
logWarning("engine", "Pre-dispatch health gate threw unexpectedly", { error: String(e) });
|
|
167
170
|
}
|
|
168
171
|
|
|
169
172
|
// Sync project root artifacts into worktree
|
|
@@ -233,26 +236,24 @@ export async function runPreDispatch(
|
|
|
233
236
|
loopState.stuckRecoveryAttempts = 0;
|
|
234
237
|
|
|
235
238
|
// Worktree lifecycle on milestone transition — merge current, enter next
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
s.currentMilestoneId!,
|
|
245
|
-
`[GSD] ${s.currentMilestoneId} complete`,
|
|
246
|
-
`Milestone ${s.currentMilestoneId} completed by GSD auto-mode.\n\nSee .gsd/${s.currentMilestoneId}/ for details.`,
|
|
239
|
+
try {
|
|
240
|
+
deps.resolver.mergeAndExit(s.currentMilestoneId!, ctx.ui);
|
|
241
|
+
} catch (mergeErr) {
|
|
242
|
+
if (mergeErr instanceof MergeConflictError) {
|
|
243
|
+
// Real code conflicts — stop the loop instead of retrying forever (#2330)
|
|
244
|
+
ctx.ui.notify(
|
|
245
|
+
`Merge conflict: ${mergeErr.conflictedFiles.join(", ")}. Resolve conflicts manually and run /gsd auto to resume.`,
|
|
246
|
+
"error",
|
|
247
247
|
);
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
}
|
|
251
|
-
} catch {
|
|
252
|
-
// Non-fatal — PR creation is best-effort
|
|
248
|
+
await deps.stopAuto(ctx, pi, `Merge conflict on milestone ${s.currentMilestoneId}`);
|
|
249
|
+
return { action: "break", reason: "merge-conflict" };
|
|
253
250
|
}
|
|
251
|
+
// Non-conflict merge errors — log and continue
|
|
252
|
+
logWarning("engine", "Milestone merge failed with non-conflict error", { milestone: s.currentMilestoneId!, error: String(mergeErr) });
|
|
254
253
|
}
|
|
255
254
|
|
|
255
|
+
// PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
|
|
256
|
+
|
|
256
257
|
deps.invalidateAllCaches();
|
|
257
258
|
|
|
258
259
|
state = await deps.deriveState(s.basePath);
|
|
@@ -279,11 +280,21 @@ export async function runPreDispatch(
|
|
|
279
280
|
// Reset completed-units tracking for the new milestone — stale entries
|
|
280
281
|
// from the previous milestone cause the dispatch loop to skip units
|
|
281
282
|
// that haven't actually been completed in the new milestone's context.
|
|
283
|
+
// Archive the old completed-units.json instead of wiping it (#2313).
|
|
282
284
|
s.completedUnits = [];
|
|
283
285
|
try {
|
|
284
286
|
const completedKeysPath = join(gsdRoot(s.basePath), "completed-units.json");
|
|
287
|
+
if (existsSync(completedKeysPath) && s.currentMilestoneId) {
|
|
288
|
+
const archivePath = join(
|
|
289
|
+
gsdRoot(s.basePath),
|
|
290
|
+
`completed-units-${s.currentMilestoneId}.json`,
|
|
291
|
+
);
|
|
292
|
+
cpSync(completedKeysPath, archivePath);
|
|
293
|
+
}
|
|
285
294
|
atomicWriteSync(completedKeysPath, JSON.stringify([], null, 2));
|
|
286
|
-
} catch {
|
|
295
|
+
} catch (e) {
|
|
296
|
+
logWarning("engine", "Failed to archive completed-units on milestone transition", { error: String(e) });
|
|
297
|
+
}
|
|
287
298
|
|
|
288
299
|
// Rebuild STATE.md immediately so it reflects the new active milestone.
|
|
289
300
|
// This bypasses the 30-second throttle in the normal rebuild path —
|
|
@@ -291,8 +302,8 @@ export async function runPreDispatch(
|
|
|
291
302
|
// immediate write.
|
|
292
303
|
try {
|
|
293
304
|
await deps.rebuildState(s.basePath);
|
|
294
|
-
} catch {
|
|
295
|
-
|
|
305
|
+
} catch (e) {
|
|
306
|
+
logWarning("engine", "STATE.md rebuild failed after milestone transition", { error: String(e) });
|
|
296
307
|
}
|
|
297
308
|
}
|
|
298
309
|
|
|
@@ -322,25 +333,20 @@ export async function runPreDispatch(
|
|
|
322
333
|
if (incomplete.length === 0 && state.registry.length > 0) {
|
|
323
334
|
// All milestones complete — merge milestone branch before stopping
|
|
324
335
|
if (s.currentMilestoneId) {
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
s.basePath,
|
|
333
|
-
s.currentMilestoneId,
|
|
334
|
-
`[GSD] ${s.currentMilestoneId} complete`,
|
|
335
|
-
`Milestone ${s.currentMilestoneId} completed by GSD auto-mode.\n\nSee .gsd/${s.currentMilestoneId}/ for details.`,
|
|
336
|
+
try {
|
|
337
|
+
deps.resolver.mergeAndExit(s.currentMilestoneId, ctx.ui);
|
|
338
|
+
} catch (mergeErr) {
|
|
339
|
+
if (mergeErr instanceof MergeConflictError) {
|
|
340
|
+
ctx.ui.notify(
|
|
341
|
+
`Merge conflict: ${mergeErr.conflictedFiles.join(", ")}. Resolve conflicts manually and run /gsd auto to resume.`,
|
|
342
|
+
"error",
|
|
336
343
|
);
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
}
|
|
340
|
-
} catch {
|
|
341
|
-
// Non-fatal — PR creation is best-effort
|
|
344
|
+
await deps.stopAuto(ctx, pi, `Merge conflict on milestone ${s.currentMilestoneId}`);
|
|
345
|
+
return { action: "break", reason: "merge-conflict" };
|
|
342
346
|
}
|
|
343
347
|
}
|
|
348
|
+
|
|
349
|
+
// PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
|
|
344
350
|
}
|
|
345
351
|
deps.sendDesktopNotification(
|
|
346
352
|
"GSD",
|
|
@@ -422,25 +428,20 @@ export async function runPreDispatch(
|
|
|
422
428
|
if (state.phase === "complete") {
|
|
423
429
|
// Milestone merge on complete (before closeout so branch state is clean)
|
|
424
430
|
if (s.currentMilestoneId) {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
s.basePath,
|
|
433
|
-
s.currentMilestoneId,
|
|
434
|
-
`[GSD] ${s.currentMilestoneId} complete`,
|
|
435
|
-
`Milestone ${s.currentMilestoneId} completed by GSD auto-mode.\n\nSee .gsd/${s.currentMilestoneId}/ for details.`,
|
|
431
|
+
try {
|
|
432
|
+
deps.resolver.mergeAndExit(s.currentMilestoneId, ctx.ui);
|
|
433
|
+
} catch (mergeErr) {
|
|
434
|
+
if (mergeErr instanceof MergeConflictError) {
|
|
435
|
+
ctx.ui.notify(
|
|
436
|
+
`Merge conflict: ${mergeErr.conflictedFiles.join(", ")}. Resolve conflicts manually and run /gsd auto to resume.`,
|
|
437
|
+
"error",
|
|
436
438
|
);
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
}
|
|
440
|
-
} catch {
|
|
441
|
-
// Non-fatal — PR creation is best-effort
|
|
439
|
+
await deps.stopAuto(ctx, pi, `Merge conflict on milestone ${s.currentMilestoneId}`);
|
|
440
|
+
return { action: "break", reason: "merge-conflict" };
|
|
442
441
|
}
|
|
443
442
|
}
|
|
443
|
+
|
|
444
|
+
// PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
|
|
444
445
|
}
|
|
445
446
|
deps.sendDesktopNotification(
|
|
446
447
|
"GSD",
|
|
@@ -860,6 +861,7 @@ export async function runUnitPhase(
|
|
|
860
861
|
lastProgressAt: s.currentUnit.startedAt,
|
|
861
862
|
progressCount: 0,
|
|
862
863
|
lastProgressKind: "dispatch",
|
|
864
|
+
recoveryAttempts: 0, // Reset so re-dispatched units get full recovery budget (#2322)
|
|
863
865
|
},
|
|
864
866
|
);
|
|
865
867
|
|
|
@@ -921,8 +923,8 @@ export async function runUnitPhase(
|
|
|
921
923
|
(decisionsContent?.length ?? 0) +
|
|
922
924
|
(requirementsContent?.length ?? 0) +
|
|
923
925
|
(projectContent?.length ?? 0);
|
|
924
|
-
} catch {
|
|
925
|
-
|
|
926
|
+
} catch (e) {
|
|
927
|
+
logWarning("engine", "Baseline char count measurement failed", { error: String(e) });
|
|
926
928
|
}
|
|
927
929
|
}
|
|
928
930
|
|
|
@@ -932,9 +934,7 @@ export async function runUnitPhase(
|
|
|
932
934
|
} catch (reorderErr) {
|
|
933
935
|
const msg =
|
|
934
936
|
reorderErr instanceof Error ? reorderErr.message : String(reorderErr);
|
|
935
|
-
|
|
936
|
-
`[gsd] prompt reorder failed (non-fatal): ${msg}\n`,
|
|
937
|
-
);
|
|
937
|
+
logWarning("engine", "Prompt reorder failed", { error: msg });
|
|
938
938
|
}
|
|
939
939
|
|
|
940
940
|
// Select and apply model (with tier escalation on retry — normal units only)
|
|
@@ -1137,7 +1137,9 @@ export async function runUnitPhase(
|
|
|
1137
1137
|
const completedKeysPath = join(gsdRoot(s.basePath), "completed-units.json");
|
|
1138
1138
|
const keys = s.completedUnits.map((u) => `${u.type}/${u.id}`);
|
|
1139
1139
|
atomicWriteSync(completedKeysPath, JSON.stringify(keys, null, 2));
|
|
1140
|
-
} catch {
|
|
1140
|
+
} catch (e) {
|
|
1141
|
+
logWarning("engine", "Failed to flush completed-units to disk", { error: String(e) });
|
|
1142
|
+
}
|
|
1141
1143
|
|
|
1142
1144
|
deps.clearUnitRuntimeRecord(s.basePath, unitType, unitId);
|
|
1143
1145
|
s.unitDispatchCount.delete(`${unitType}/${unitId}`);
|
|
@@ -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;
|
|
@@ -1307,6 +1307,12 @@ export async function buildCompleteMilestonePrompt(
|
|
|
1307
1307
|
roadmapPath: roadmapRel,
|
|
1308
1308
|
inlinedContext,
|
|
1309
1309
|
milestoneSummaryPath,
|
|
1310
|
+
skillActivation: buildSkillActivationBlock({
|
|
1311
|
+
base,
|
|
1312
|
+
milestoneId: mid,
|
|
1313
|
+
milestoneTitle: midTitle,
|
|
1314
|
+
extraContext: [inlinedContext],
|
|
1315
|
+
}),
|
|
1310
1316
|
});
|
|
1311
1317
|
}
|
|
1312
1318
|
|
|
@@ -1390,6 +1396,12 @@ export async function buildValidateMilestonePrompt(
|
|
|
1390
1396
|
inlinedContext,
|
|
1391
1397
|
validationPath: validationOutputPath,
|
|
1392
1398
|
remediationRound: String(remediationRound),
|
|
1399
|
+
skillActivation: buildSkillActivationBlock({
|
|
1400
|
+
base,
|
|
1401
|
+
milestoneId: mid,
|
|
1402
|
+
milestoneTitle: midTitle,
|
|
1403
|
+
extraContext: [inlinedContext],
|
|
1404
|
+
}),
|
|
1393
1405
|
});
|
|
1394
1406
|
}
|
|
1395
1407
|
|
|
@@ -1500,6 +1512,12 @@ export async function buildRunUatPrompt(
|
|
|
1500
1512
|
uatResultPath,
|
|
1501
1513
|
uatType,
|
|
1502
1514
|
inlinedContext,
|
|
1515
|
+
skillActivation: buildSkillActivationBlock({
|
|
1516
|
+
base,
|
|
1517
|
+
milestoneId: mid,
|
|
1518
|
+
sliceId,
|
|
1519
|
+
extraContext: [inlinedContext],
|
|
1520
|
+
}),
|
|
1503
1521
|
});
|
|
1504
1522
|
}
|
|
1505
1523
|
|
|
@@ -1552,11 +1570,16 @@ export async function buildReassessRoadmapPrompt(
|
|
|
1552
1570
|
milestoneTitle: midTitle,
|
|
1553
1571
|
completedSliceId,
|
|
1554
1572
|
roadmapPath: roadmapRel,
|
|
1555
|
-
completedSliceSummaryPath: summaryRel,
|
|
1556
1573
|
assessmentPath,
|
|
1557
1574
|
inlinedContext,
|
|
1558
1575
|
deferredCaptures,
|
|
1559
1576
|
commitInstruction: reassessCommitInstruction,
|
|
1577
|
+
skillActivation: buildSkillActivationBlock({
|
|
1578
|
+
base,
|
|
1579
|
+
milestoneId: mid,
|
|
1580
|
+
milestoneTitle: midTitle,
|
|
1581
|
+
extraContext: [inlinedContext, deferredCaptures],
|
|
1582
|
+
}),
|
|
1560
1583
|
});
|
|
1561
1584
|
}
|
|
1562
1585
|
|
|
@@ -297,11 +297,14 @@ export async function bootstrapAutoSession(
|
|
|
297
297
|
}
|
|
298
298
|
}
|
|
299
299
|
|
|
300
|
-
// Milestone branch recovery (#601)
|
|
300
|
+
// Milestone branch recovery (#601, #2358)
|
|
301
|
+
// Detect survivor milestone branches in both pre-planning and complete phases.
|
|
302
|
+
// In phase=complete, the milestone artifacts exist but finalization (merge,
|
|
303
|
+
// worktree cleanup) was never run — the survivor branch must be merged.
|
|
301
304
|
let hasSurvivorBranch = false;
|
|
302
305
|
if (
|
|
303
306
|
state.activeMilestone &&
|
|
304
|
-
state.phase === "pre-planning" &&
|
|
307
|
+
(state.phase === "pre-planning" || state.phase === "complete") &&
|
|
305
308
|
shouldUseWorktreeIsolation() &&
|
|
306
309
|
!detectWorktreeName(base) &&
|
|
307
310
|
!base.includes(`${pathSep}.gsd${pathSep}worktrees${pathSep}`)
|
|
@@ -343,6 +346,26 @@ export async function bootstrapAutoSession(
|
|
|
343
346
|
}
|
|
344
347
|
}
|
|
345
348
|
|
|
349
|
+
// Survivor branch exists and milestone is complete (#2358):
|
|
350
|
+
// The milestone artifacts were written but finalization (merge, worktree
|
|
351
|
+
// cleanup) never ran. Run mergeAndExit to finalize, then re-derive state
|
|
352
|
+
// so the normal "all milestones complete" or "next milestone" path runs.
|
|
353
|
+
if (hasSurvivorBranch && state.phase === "complete") {
|
|
354
|
+
const mid = state.activeMilestone!.id;
|
|
355
|
+
ctx.ui.notify(
|
|
356
|
+
`Milestone ${mid} is complete but branch/worktree was not finalized. Running merge now.`,
|
|
357
|
+
"info",
|
|
358
|
+
);
|
|
359
|
+
const resolver = buildResolver();
|
|
360
|
+
resolver.mergeAndExit(mid, {
|
|
361
|
+
notify: ctx.ui.notify.bind(ctx.ui),
|
|
362
|
+
});
|
|
363
|
+
invalidateAllCaches();
|
|
364
|
+
state = await deriveState(base);
|
|
365
|
+
// Clear survivor flag — finalization is done
|
|
366
|
+
hasSurvivorBranch = false;
|
|
367
|
+
}
|
|
368
|
+
|
|
346
369
|
if (!hasSurvivorBranch) {
|
|
347
370
|
// No active work — start a new milestone via discuss flow
|
|
348
371
|
if (!state.activeMilestone || state.phase === "complete") {
|
|
@@ -551,6 +574,20 @@ export async function bootstrapAutoSession(
|
|
|
551
574
|
}
|
|
552
575
|
}
|
|
553
576
|
|
|
577
|
+
// Gate: abort bootstrap if the DB file exists but the provider is
|
|
578
|
+
// still unavailable after both open attempts above. Without this,
|
|
579
|
+
// auto-mode starts but every gsd_task_complete / gsd_slice_complete
|
|
580
|
+
// call returns "db_unavailable", triggering artifact-retry which
|
|
581
|
+
// re-dispatches the same task — producing an infinite loop (#2419).
|
|
582
|
+
if (existsSync(gsdDbPath) && !isDbAvailable()) {
|
|
583
|
+
ctx.ui.notify(
|
|
584
|
+
"SQLite database exists but failed to open. Auto-mode cannot proceed without a working database provider. " +
|
|
585
|
+
"Check for corrupt gsd.db or missing native SQLite bindings.",
|
|
586
|
+
"error",
|
|
587
|
+
);
|
|
588
|
+
return releaseLockAndReturn();
|
|
589
|
+
}
|
|
590
|
+
|
|
554
591
|
// Initialize metrics
|
|
555
592
|
initMetrics(s.basePath);
|
|
556
593
|
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
import type { ExtensionAPI, ExtensionContext } from "@gsd/pi-coding-agent";
|
|
10
10
|
import { readUnitRuntimeRecord, writeUnitRuntimeRecord } from "./unit-runtime.js";
|
|
11
|
+
import { isDbAvailable, getMilestoneSlices, getSliceTasks } from "./gsd-db.js";
|
|
11
12
|
import { resolveAutoSupervisorConfig } from "./preferences.js";
|
|
12
13
|
import type { GSDPreferences } from "./preferences.js";
|
|
13
14
|
import { computeBudgets, resolveExecutorContextWindow } from "./context-budget.js";
|
|
@@ -32,6 +33,8 @@ export interface SupervisionContext {
|
|
|
32
33
|
buildSnapshotOpts: () => CloseoutOptions & Record<string, unknown>;
|
|
33
34
|
buildRecoveryContext: () => RecoveryContext;
|
|
34
35
|
pauseAuto: (ctx?: ExtensionContext, pi?: ExtensionAPI) => Promise<void>;
|
|
36
|
+
/** Optional task estimate string (e.g. "30m", "2h") for timeout scaling (#2243). */
|
|
37
|
+
taskEstimate?: string;
|
|
35
38
|
}
|
|
36
39
|
|
|
37
40
|
/**
|
|
@@ -41,13 +44,71 @@ export interface SupervisionContext {
|
|
|
41
44
|
* 3. Hard timeout (pause + recovery)
|
|
42
45
|
* 4. Context-pressure monitor (continue-here)
|
|
43
46
|
*/
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Parse a task estimate string (e.g. "30m", "2h", "1h30m") into minutes.
|
|
50
|
+
* Returns null if the string cannot be parsed.
|
|
51
|
+
*/
|
|
52
|
+
export function parseEstimateMinutes(estimate: string): number | null {
|
|
53
|
+
if (!estimate || typeof estimate !== "string") return null;
|
|
54
|
+
const trimmed = estimate.trim();
|
|
55
|
+
if (!trimmed) return null;
|
|
56
|
+
|
|
57
|
+
let totalMinutes = 0;
|
|
58
|
+
let matched = false;
|
|
59
|
+
|
|
60
|
+
// Match hours component
|
|
61
|
+
const hoursMatch = trimmed.match(/(\d+)\s*h/i);
|
|
62
|
+
if (hoursMatch) {
|
|
63
|
+
totalMinutes += Number(hoursMatch[1]) * 60;
|
|
64
|
+
matched = true;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Match minutes component
|
|
68
|
+
const minutesMatch = trimmed.match(/(\d+)\s*m/i);
|
|
69
|
+
if (minutesMatch) {
|
|
70
|
+
totalMinutes += Number(minutesMatch[1]);
|
|
71
|
+
matched = true;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return matched ? totalMinutes : null;
|
|
75
|
+
}
|
|
76
|
+
|
|
44
77
|
export function startUnitSupervision(sctx: SupervisionContext): void {
|
|
45
78
|
const { s, ctx, pi, unitType, unitId, prefs, buildSnapshotOpts, buildRecoveryContext, pauseAuto } = sctx;
|
|
46
79
|
|
|
47
80
|
const supervisor = resolveAutoSupervisorConfig();
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
81
|
+
|
|
82
|
+
// Scale timeouts based on task estimate annotations (#2243).
|
|
83
|
+
// If the task has an est: annotation, use it to extend the hard and soft timeouts
|
|
84
|
+
// so longer tasks don't get prematurely timed out.
|
|
85
|
+
let taskEstimate = sctx.taskEstimate;
|
|
86
|
+
if (!taskEstimate && unitType === "task" && isDbAvailable()) {
|
|
87
|
+
// Look up the task estimate from the DB (#2243).
|
|
88
|
+
try {
|
|
89
|
+
if (s.currentMilestoneId) {
|
|
90
|
+
const slices = getMilestoneSlices(s.currentMilestoneId);
|
|
91
|
+
for (const slice of slices) {
|
|
92
|
+
const tasks = getSliceTasks(s.currentMilestoneId, slice.id);
|
|
93
|
+
const task = tasks.find(t => t.id === unitId);
|
|
94
|
+
if (task?.estimate) {
|
|
95
|
+
taskEstimate = task.estimate;
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
} catch {
|
|
101
|
+
// Non-fatal — fall through with no estimate
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const estimateMinutes = taskEstimate ? parseEstimateMinutes(taskEstimate) : null;
|
|
105
|
+
const timeoutScale = estimateMinutes && estimateMinutes > 0
|
|
106
|
+
? Math.max(1, estimateMinutes / 10) // 10min task = 1x, 30min = 3x, 2h = 12x
|
|
107
|
+
: 1;
|
|
108
|
+
|
|
109
|
+
const softTimeoutMs = (supervisor.soft_timeout_minutes ?? 0) * 60 * 1000 * timeoutScale;
|
|
110
|
+
const idleTimeoutMs = (supervisor.idle_timeout_minutes ?? 0) * 60 * 1000; // idle not scaled — idle is idle
|
|
111
|
+
const hardTimeoutMs = (supervisor.hard_timeout_minutes ?? 0) * 60 * 1000 * timeoutScale;
|
|
51
112
|
|
|
52
113
|
// ── 1. Soft timeout warning ──
|
|
53
114
|
s.wrapupWarningHandle = setTimeout(() => {
|
|
@@ -93,6 +93,11 @@ export function syncStateToProjectRoot(
|
|
|
93
93
|
{ force: true },
|
|
94
94
|
);
|
|
95
95
|
|
|
96
|
+
// 3. metrics.json — session cost/token tracking (#2313).
|
|
97
|
+
// Without this, metrics accumulated in the worktree are invisible from the
|
|
98
|
+
// project root and never appear in the dashboard or skill-health reports.
|
|
99
|
+
safeCopy(join(wtGsd, "metrics.json"), join(prGsd, "metrics.json"), { force: true });
|
|
100
|
+
|
|
96
101
|
// 4. Runtime records — unit dispatch state used by selfHealRuntimeRecords().
|
|
97
102
|
// Without this, a crash during a unit leaves the runtime record only in the
|
|
98
103
|
// worktree. If the next session resolves basePath before worktree re-entry,
|
|
@@ -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,
|
|
@@ -162,6 +163,7 @@ export function syncGsdStateToWorktree(
|
|
|
162
163
|
"OVERRIDES.md",
|
|
163
164
|
"QUEUE.md",
|
|
164
165
|
"completed-units.json",
|
|
166
|
+
"metrics.json",
|
|
165
167
|
];
|
|
166
168
|
for (const f of rootFiles) {
|
|
167
169
|
const src = join(mainGsd, f);
|
|
@@ -325,8 +327,9 @@ export function syncWorktreeStateBack(
|
|
|
325
327
|
// ── 1. Sync root-level .gsd/ files back ──────────────────────────────
|
|
326
328
|
// The worktree is authoritative — complete-milestone updates REQUIREMENTS,
|
|
327
329
|
// PROJECT, etc. These must overwrite main's copies so they survive teardown.
|
|
328
|
-
// Also includes QUEUE.md
|
|
329
|
-
// milestone closeout and lost on teardown without explicit sync
|
|
330
|
+
// Also includes QUEUE.md, completed-units.json, and metrics.json which are
|
|
331
|
+
// written during milestone closeout and lost on teardown without explicit sync
|
|
332
|
+
// (#1787, #2313).
|
|
330
333
|
const rootFiles = [
|
|
331
334
|
"DECISIONS.md",
|
|
332
335
|
"REQUIREMENTS.md",
|
|
@@ -335,6 +338,7 @@ export function syncWorktreeStateBack(
|
|
|
335
338
|
"OVERRIDES.md",
|
|
336
339
|
"QUEUE.md",
|
|
337
340
|
"completed-units.json",
|
|
341
|
+
"metrics.json",
|
|
338
342
|
];
|
|
339
343
|
for (const f of rootFiles) {
|
|
340
344
|
const src = join(wtGsd, f);
|
|
@@ -697,7 +701,7 @@ export function createAutoWorktree(
|
|
|
697
701
|
const hookError = runWorktreePostCreateHook(basePath, info.path);
|
|
698
702
|
if (hookError) {
|
|
699
703
|
// Non-fatal — log but don't prevent worktree usage
|
|
700
|
-
|
|
704
|
+
logWarning("reconcile", hookError, { worktree: info.name });
|
|
701
705
|
}
|
|
702
706
|
|
|
703
707
|
const previousCwd = process.cwd();
|
|
@@ -790,10 +794,12 @@ export function teardownAutoWorktree(
|
|
|
790
794
|
// backslashes (#1436), leaving ~1 GB+ orphaned directories.
|
|
791
795
|
const wtDir = worktreePath(originalBasePath, milestoneId);
|
|
792
796
|
if (existsSync(wtDir)) {
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
`
|
|
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 },
|
|
797
803
|
);
|
|
798
804
|
// Attempt a direct filesystem removal as a fallback
|
|
799
805
|
try {
|
|
@@ -1320,9 +1326,9 @@ export function mergeMilestoneToMain(
|
|
|
1320
1326
|
}
|
|
1321
1327
|
}
|
|
1322
1328
|
|
|
1323
|
-
// 9b. Auto-create PR if enabled (
|
|
1329
|
+
// 9b. Auto-create PR if enabled (#2302: no longer gated on pushed/auto_push)
|
|
1324
1330
|
let prCreated = false;
|
|
1325
|
-
if (prefs.auto_pr === true &&
|
|
1331
|
+
if (prefs.auto_pr === true && !nothingToCommit) {
|
|
1326
1332
|
const remote = prefs.remote ?? "origin";
|
|
1327
1333
|
const prTarget = prefs.pr_target_branch ?? mainBranch;
|
|
1328
1334
|
try {
|
|
@@ -1332,9 +1338,9 @@ export function mergeMilestoneToMain(
|
|
|
1332
1338
|
stdio: ["ignore", "pipe", "pipe"],
|
|
1333
1339
|
encoding: "utf-8",
|
|
1334
1340
|
});
|
|
1335
|
-
// Create PR via gh CLI
|
|
1341
|
+
// Create PR via gh CLI with explicit --head and --base (#2302)
|
|
1336
1342
|
execFileSync("gh", [
|
|
1337
|
-
"pr", "create",
|
|
1343
|
+
"pr", "create", "--draft",
|
|
1338
1344
|
"--base", prTarget,
|
|
1339
1345
|
"--head", milestoneBranch,
|
|
1340
1346
|
"--title", `Milestone ${milestoneId} complete`,
|
|
@@ -250,9 +250,9 @@ const STATE_REBUILD_MIN_INTERVAL_MS = 30_000;
|
|
|
250
250
|
|
|
251
251
|
export function shouldUseWorktreeIsolation(): boolean {
|
|
252
252
|
const prefs = loadEffectiveGSDPreferences()?.preferences?.git;
|
|
253
|
-
if (prefs?.isolation === "
|
|
254
|
-
|
|
255
|
-
return
|
|
253
|
+
if (prefs?.isolation === "worktree") return true;
|
|
254
|
+
// Default is false — worktree isolation requires explicit opt-in
|
|
255
|
+
return false;
|
|
256
256
|
}
|
|
257
257
|
|
|
258
258
|
/** Crash recovery prompt — set by startAuto, consumed by the main loop */
|
|
@@ -610,14 +610,48 @@ export async function stopAuto(
|
|
|
610
610
|
}
|
|
611
611
|
|
|
612
612
|
// ── Step 4: Auto-worktree exit ──
|
|
613
|
+
// When the milestone is complete (has a SUMMARY), merge the worktree branch
|
|
614
|
+
// back to main so code isn't stranded on the worktree branch (#2317).
|
|
615
|
+
// For incomplete milestones, preserve the branch for later resumption.
|
|
613
616
|
try {
|
|
614
617
|
if (s.currentMilestoneId) {
|
|
615
618
|
const notifyCtx = ctx
|
|
616
619
|
? { notify: ctx.ui.notify.bind(ctx.ui) }
|
|
617
620
|
: { notify: () => {} };
|
|
618
|
-
buildResolver()
|
|
619
|
-
|
|
620
|
-
|
|
621
|
+
const resolver = buildResolver();
|
|
622
|
+
|
|
623
|
+
// Check if the milestone is complete — SUMMARY file is the authoritative signal.
|
|
624
|
+
let milestoneComplete = false;
|
|
625
|
+
try {
|
|
626
|
+
const summaryPath = resolveMilestoneFile(
|
|
627
|
+
s.originalBasePath || s.basePath,
|
|
628
|
+
s.currentMilestoneId,
|
|
629
|
+
"SUMMARY",
|
|
630
|
+
);
|
|
631
|
+
if (!summaryPath) {
|
|
632
|
+
// Also check in the worktree path (SUMMARY may not be synced yet)
|
|
633
|
+
const wtSummaryPath = resolveMilestoneFile(
|
|
634
|
+
s.basePath,
|
|
635
|
+
s.currentMilestoneId,
|
|
636
|
+
"SUMMARY",
|
|
637
|
+
);
|
|
638
|
+
milestoneComplete = wtSummaryPath !== null;
|
|
639
|
+
} else {
|
|
640
|
+
milestoneComplete = true;
|
|
641
|
+
}
|
|
642
|
+
} catch {
|
|
643
|
+
// Non-fatal — fall through to preserveBranch path
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
if (milestoneComplete) {
|
|
647
|
+
// Milestone is complete — merge worktree branch back to main
|
|
648
|
+
resolver.mergeAndExit(s.currentMilestoneId, notifyCtx);
|
|
649
|
+
} else {
|
|
650
|
+
// Milestone still in progress — preserve branch for later resumption
|
|
651
|
+
resolver.exitMilestone(s.currentMilestoneId, notifyCtx, {
|
|
652
|
+
preserveBranch: true,
|
|
653
|
+
});
|
|
654
|
+
}
|
|
621
655
|
}
|
|
622
656
|
} catch (e) {
|
|
623
657
|
debugLog("stop-cleanup-worktree", { error: e instanceof Error ? e.message : String(e) });
|