gsd-pi 2.44.0 → 2.45.0-dev.6b9da3e

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.
Files changed (463) hide show
  1. package/README.md +30 -12
  2. package/dist/resources/extensions/gsd/activity-log.js +7 -0
  3. package/dist/resources/extensions/gsd/auto/infra-errors.js +3 -0
  4. package/dist/resources/extensions/gsd/auto/phases.js +37 -36
  5. package/dist/resources/extensions/gsd/auto-prompts.js +24 -1
  6. package/dist/resources/extensions/gsd/auto-start.js +31 -2
  7. package/dist/resources/extensions/gsd/auto-timers.js +57 -3
  8. package/dist/resources/extensions/gsd/auto-worktree-sync.js +4 -0
  9. package/dist/resources/extensions/gsd/auto-worktree.js +9 -6
  10. package/dist/resources/extensions/gsd/auto.js +30 -3
  11. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +156 -0
  12. package/dist/resources/extensions/gsd/bootstrap/system-context.js +46 -12
  13. package/dist/resources/extensions/gsd/commands/catalog.js +7 -1
  14. package/dist/resources/extensions/gsd/commands/handlers/core.js +2 -0
  15. package/dist/resources/extensions/gsd/commands/handlers/ops.js +10 -0
  16. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +5 -0
  17. package/dist/resources/extensions/gsd/commands-mcp-status.js +187 -0
  18. package/dist/resources/extensions/gsd/db-writer.js +34 -16
  19. package/dist/resources/extensions/gsd/doctor.js +8 -0
  20. package/dist/resources/extensions/gsd/git-service.js +8 -3
  21. package/dist/resources/extensions/gsd/gsd-db.js +12 -1
  22. package/dist/resources/extensions/gsd/markdown-renderer.js +1 -1
  23. package/dist/resources/extensions/gsd/preferences.js +9 -1
  24. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +2 -4
  25. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  26. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -6
  27. package/dist/resources/extensions/gsd/prompts/replan-slice.md +3 -14
  28. package/dist/resources/extensions/gsd/prompts/rethink.md +78 -0
  29. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +7 -37
  30. package/dist/resources/extensions/gsd/provider-error-pause.js +7 -0
  31. package/dist/resources/extensions/gsd/repo-identity.js +45 -7
  32. package/dist/resources/extensions/gsd/rethink.js +115 -0
  33. package/dist/resources/extensions/gsd/state.js +41 -3
  34. package/dist/resources/extensions/gsd/tools/plan-slice.js +1 -0
  35. package/dist/resources/extensions/gsd/tools/plan-task.js +1 -0
  36. package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -0
  37. package/dist/resources/extensions/gsd/tools/validate-milestone.js +88 -0
  38. package/dist/resources/extensions/gsd/worktree-manager.js +32 -2
  39. package/dist/resources/extensions/gsd/worktree-resolver.js +6 -0
  40. package/dist/resources/extensions/mcp-client/index.js +14 -0
  41. package/dist/web/standalone/.next/BUILD_ID +1 -1
  42. package/dist/web/standalone/.next/app-path-routes-manifest.json +8 -8
  43. package/dist/web/standalone/.next/build-manifest.json +4 -4
  44. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  45. package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
  46. package/dist/web/standalone/.next/required-server-files.json +3 -3
  47. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  48. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  49. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  50. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  51. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  52. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  53. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  54. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  55. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  56. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  57. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  58. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  59. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  60. package/dist/web/standalone/.next/server/app/_not-found.rsc +5 -5
  61. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +5 -5
  62. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  63. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
  64. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  65. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  66. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  67. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  68. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  69. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  70. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  71. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  72. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  73. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  74. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  75. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  76. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  77. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  78. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  79. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  80. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  81. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  82. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  83. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  84. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  85. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  86. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  87. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  88. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  89. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  90. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  91. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  92. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  93. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  94. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  95. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  96. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  97. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  98. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  99. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  100. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  101. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  102. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  103. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  104. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  105. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  106. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  107. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  108. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  109. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  110. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +5 -5
  112. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  118. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  132. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  134. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  136. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  138. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/index.html +1 -1
  148. package/dist/web/standalone/.next/server/app/index.rsc +6 -6
  149. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  150. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +6 -6
  151. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  152. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
  153. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  154. package/dist/web/standalone/.next/server/app/page.js +2 -2
  155. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app-paths-manifest.json +8 -8
  157. package/dist/web/standalone/.next/server/chunks/229.js +1 -1
  158. package/dist/web/standalone/.next/server/chunks/471.js +3 -3
  159. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/middleware.js +2 -2
  162. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  164. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  165. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  166. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  167. package/dist/web/standalone/.next/static/chunks/4024.11ca5c01938e5948.js +9 -0
  168. package/dist/web/standalone/.next/static/chunks/{3721.bf31263de6d5fa46.js → 485.243af25f0cdf50d6.js} +2 -2
  169. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  170. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  171. package/dist/web/standalone/.next/static/chunks/app/page-6654a8cca61a3d1c.js +1 -0
  172. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  173. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  174. package/dist/web/standalone/.next/static/chunks/webpack-0a4cd455ec4197d2.js +1 -0
  175. package/dist/web/standalone/.next/static/css/dd4ae3f58ac9b600.css +1 -0
  176. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  177. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  178. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  179. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  180. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  181. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  182. package/dist/web/standalone/server.js +1 -1
  183. package/package.json +1 -1
  184. package/packages/native/dist/stream-process/index.js +2 -2
  185. package/packages/native/src/__tests__/stream-process.test.mjs +34 -0
  186. package/packages/native/src/stream-process/index.ts +2 -2
  187. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +3 -1
  188. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  189. package/packages/pi-coding-agent/dist/core/auth-storage.js +15 -1
  190. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  191. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +6 -8
  192. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  193. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +24 -26
  194. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  195. package/packages/pi-coding-agent/dist/core/fs-utils.test.js +29 -48
  196. package/packages/pi-coding-agent/dist/core/fs-utils.test.js.map +1 -1
  197. package/packages/pi-coding-agent/dist/core/local-model-check.d.ts +15 -0
  198. package/packages/pi-coding-agent/dist/core/local-model-check.d.ts.map +1 -0
  199. package/packages/pi-coding-agent/dist/core/local-model-check.js +41 -0
  200. package/packages/pi-coding-agent/dist/core/local-model-check.js.map +1 -0
  201. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +11 -0
  202. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  203. package/packages/pi-coding-agent/dist/core/model-registry.js +20 -1
  204. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  205. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +34 -44
  206. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
  207. package/packages/pi-coding-agent/dist/core/session-manager.test.js +30 -34
  208. package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
  209. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
  210. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  211. package/packages/pi-coding-agent/dist/core/settings-manager.js +6 -0
  212. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  213. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +10 -12
  214. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -1
  215. package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
  216. package/packages/pi-coding-agent/dist/main.js +17 -0
  217. package/packages/pi-coding-agent/dist/main.js.map +1 -1
  218. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.d.ts +2 -0
  219. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.d.ts.map +1 -0
  220. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.js +32 -0
  221. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.js.map +1 -0
  222. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +3 -1
  223. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  224. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +8 -1
  225. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  226. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  227. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  228. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +12 -0
  229. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
  230. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.d.ts +15 -0
  231. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.d.ts.map +1 -0
  232. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.js +40 -0
  233. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.js.map +1 -0
  234. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  235. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +4 -1
  236. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  237. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts +5 -2
  238. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  239. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +13 -2
  240. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
  241. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  242. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +17 -8
  243. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  244. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  245. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +7 -3
  246. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  247. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js +43 -47
  248. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js.map +1 -1
  249. package/packages/pi-coding-agent/package.json +1 -1
  250. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +7 -7
  251. package/packages/pi-coding-agent/src/core/auth-storage.ts +15 -1
  252. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +26 -26
  253. package/packages/pi-coding-agent/src/core/fs-utils.test.ts +31 -43
  254. package/packages/pi-coding-agent/src/core/local-model-check.ts +45 -0
  255. package/packages/pi-coding-agent/src/core/model-registry.ts +21 -1
  256. package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +40 -45
  257. package/packages/pi-coding-agent/src/core/session-manager.test.ts +33 -33
  258. package/packages/pi-coding-agent/src/core/settings-manager.ts +9 -0
  259. package/packages/pi-coding-agent/src/core/tools/edit-diff.test.ts +17 -17
  260. package/packages/pi-coding-agent/src/main.ts +19 -0
  261. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/timestamp.test.ts +38 -0
  262. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +10 -0
  263. package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +15 -0
  264. package/packages/pi-coding-agent/src/modes/interactive/components/timestamp.ts +48 -0
  265. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +3 -1
  266. package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +18 -3
  267. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +16 -7
  268. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +8 -1
  269. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.test.ts +74 -74
  270. package/pkg/package.json +1 -1
  271. package/src/resources/extensions/gsd/activity-log.ts +1 -0
  272. package/src/resources/extensions/gsd/auto/infra-errors.ts +3 -0
  273. package/src/resources/extensions/gsd/auto/phases.ts +46 -48
  274. package/src/resources/extensions/gsd/auto-prompts.ts +24 -1
  275. package/src/resources/extensions/gsd/auto-start.ts +39 -2
  276. package/src/resources/extensions/gsd/auto-timers.ts +64 -3
  277. package/src/resources/extensions/gsd/auto-worktree-sync.ts +5 -0
  278. package/src/resources/extensions/gsd/auto-worktree.ts +9 -6
  279. package/src/resources/extensions/gsd/auto.ts +37 -3
  280. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +148 -0
  281. package/src/resources/extensions/gsd/bootstrap/system-context.ts +48 -11
  282. package/src/resources/extensions/gsd/commands/catalog.ts +7 -1
  283. package/src/resources/extensions/gsd/commands/handlers/core.ts +2 -0
  284. package/src/resources/extensions/gsd/commands/handlers/ops.ts +10 -0
  285. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +8 -0
  286. package/src/resources/extensions/gsd/commands-mcp-status.ts +247 -0
  287. package/src/resources/extensions/gsd/db-writer.ts +39 -17
  288. package/src/resources/extensions/gsd/doctor.ts +7 -1
  289. package/src/resources/extensions/gsd/git-service.ts +6 -2
  290. package/src/resources/extensions/gsd/gsd-db.ts +16 -1
  291. package/src/resources/extensions/gsd/markdown-renderer.ts +1 -1
  292. package/src/resources/extensions/gsd/preferences.ts +11 -1
  293. package/src/resources/extensions/gsd/prompts/complete-milestone.md +2 -4
  294. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  295. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -6
  296. package/src/resources/extensions/gsd/prompts/replan-slice.md +3 -14
  297. package/src/resources/extensions/gsd/prompts/rethink.md +78 -0
  298. package/src/resources/extensions/gsd/prompts/validate-milestone.md +7 -37
  299. package/src/resources/extensions/gsd/provider-error-pause.ts +9 -0
  300. package/src/resources/extensions/gsd/repo-identity.ts +46 -7
  301. package/src/resources/extensions/gsd/rethink.ts +154 -0
  302. package/src/resources/extensions/gsd/state.ts +41 -1
  303. package/src/resources/extensions/gsd/tests/all-milestones-complete-merge.test.ts +99 -99
  304. package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +14 -16
  305. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +43 -57
  306. package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +88 -0
  307. package/src/resources/extensions/gsd/tests/auto-preflight.test.ts +11 -13
  308. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +465 -523
  309. package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +73 -75
  310. package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +34 -56
  311. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +533 -656
  312. package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +165 -143
  313. package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +29 -52
  314. package/src/resources/extensions/gsd/tests/captures.test.ts +148 -176
  315. package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +32 -33
  316. package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +141 -143
  317. package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +25 -25
  318. package/src/resources/extensions/gsd/tests/commands-logs.test.ts +81 -81
  319. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +38 -59
  320. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +228 -263
  321. package/src/resources/extensions/gsd/tests/complete-task.test.ts +250 -302
  322. package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +114 -0
  323. package/src/resources/extensions/gsd/tests/context-store.test.ts +354 -367
  324. package/src/resources/extensions/gsd/tests/continue-here.test.ts +68 -72
  325. package/src/resources/extensions/gsd/tests/cost-projection.test.ts +92 -106
  326. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +27 -35
  327. package/src/resources/extensions/gsd/tests/dashboard-budget.test.ts +220 -237
  328. package/src/resources/extensions/gsd/tests/db-writer.test.ts +465 -416
  329. package/src/resources/extensions/gsd/tests/definition-loader.test.ts +76 -92
  330. package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +68 -83
  331. package/src/resources/extensions/gsd/tests/derive-state-db-disk-reconcile.test.ts +121 -0
  332. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +210 -181
  333. package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +78 -101
  334. package/src/resources/extensions/gsd/tests/derive-state.test.ts +192 -227
  335. package/src/resources/extensions/gsd/tests/detection.test.ts +232 -278
  336. package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +30 -34
  337. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +164 -180
  338. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +43 -49
  339. package/src/resources/extensions/gsd/tests/dispatch-uat-last-completed.test.ts +28 -32
  340. package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +27 -29
  341. package/src/resources/extensions/gsd/tests/doctor-delimiter-fix.test.ts +34 -38
  342. package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +54 -75
  343. package/src/resources/extensions/gsd/tests/doctor-environment-worktree.test.ts +21 -32
  344. package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +72 -97
  345. package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +38 -44
  346. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +104 -145
  347. package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +84 -106
  348. package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +54 -60
  349. package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +72 -93
  350. package/src/resources/extensions/gsd/tests/doctor.test.ts +104 -134
  351. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +123 -131
  352. package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +120 -0
  353. package/src/resources/extensions/gsd/tests/exit-command.test.ts +20 -24
  354. package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +48 -57
  355. package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +5 -7
  356. package/src/resources/extensions/gsd/tests/flag-file-db.test.ts +30 -42
  357. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +198 -206
  358. package/src/resources/extensions/gsd/tests/git-locale.test.ts +13 -27
  359. package/src/resources/extensions/gsd/tests/git-service.test.ts +285 -388
  360. package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +31 -39
  361. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +63 -69
  362. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +255 -264
  363. package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +108 -119
  364. package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +81 -103
  365. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +229 -262
  366. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +13 -13
  367. package/src/resources/extensions/gsd/tests/health-widget.test.ts +29 -37
  368. package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +81 -102
  369. package/src/resources/extensions/gsd/tests/infra-error.test.ts +20 -2
  370. package/src/resources/extensions/gsd/tests/inherited-repo-home-dir.test.ts +121 -0
  371. package/src/resources/extensions/gsd/tests/init-wizard.test.ts +16 -18
  372. package/src/resources/extensions/gsd/tests/integration-edge.test.ts +41 -46
  373. package/src/resources/extensions/gsd/tests/integration-lifecycle.test.ts +42 -53
  374. package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +75 -91
  375. package/src/resources/extensions/gsd/tests/integration-proof.test.ts +18 -18
  376. package/src/resources/extensions/gsd/tests/knowledge.test.ts +89 -0
  377. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +150 -194
  378. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +103 -0
  379. package/src/resources/extensions/gsd/tests/md-importer.test.ts +101 -125
  380. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +45 -54
  381. package/src/resources/extensions/gsd/tests/memory-store.test.ts +80 -93
  382. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +66 -0
  383. package/src/resources/extensions/gsd/tests/migrate-command.test.ts +57 -66
  384. package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +83 -93
  385. package/src/resources/extensions/gsd/tests/migrate-parser.test.ts +161 -170
  386. package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +125 -141
  387. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +107 -131
  388. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +87 -96
  389. package/src/resources/extensions/gsd/tests/migrate-writer.test.ts +125 -164
  390. package/src/resources/extensions/gsd/tests/must-have-parser.test.ts +81 -94
  391. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +35 -36
  392. package/src/resources/extensions/gsd/tests/overrides.test.ts +99 -106
  393. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +40 -47
  394. package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +25 -28
  395. package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +66 -83
  396. package/src/resources/extensions/gsd/tests/park-edge-cases.test.ts +54 -77
  397. package/src/resources/extensions/gsd/tests/park-milestone.test.ts +68 -115
  398. package/src/resources/extensions/gsd/tests/parsers.test.ts +546 -611
  399. package/src/resources/extensions/gsd/tests/paths.test.ts +72 -87
  400. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +77 -117
  401. package/src/resources/extensions/gsd/tests/preferences.test.ts +27 -0
  402. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +11 -7
  403. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +56 -56
  404. package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +93 -119
  405. package/src/resources/extensions/gsd/tests/queue-order.test.ts +70 -82
  406. package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +42 -55
  407. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +100 -0
  408. package/src/resources/extensions/gsd/tests/quick-branch-lifecycle.test.ts +45 -73
  409. package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +28 -38
  410. package/src/resources/extensions/gsd/tests/recovery-attempts-reset.test.ts +176 -0
  411. package/src/resources/extensions/gsd/tests/replan-slice.test.ts +73 -80
  412. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +71 -74
  413. package/src/resources/extensions/gsd/tests/requirements.test.ts +70 -75
  414. package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +44 -66
  415. package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +114 -181
  416. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +63 -65
  417. package/src/resources/extensions/gsd/tests/run-uat.test.ts +66 -128
  418. package/src/resources/extensions/gsd/tests/session-lock-multipath.test.ts +18 -25
  419. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +37 -44
  420. package/src/resources/extensions/gsd/tests/shared-wal.test.ts +19 -26
  421. package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +63 -0
  422. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +6 -8
  423. package/src/resources/extensions/gsd/tests/stop-auto-merge-back.test.ts +67 -0
  424. package/src/resources/extensions/gsd/tests/survivor-branch-complete.test.ts +108 -0
  425. package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +22 -28
  426. package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +49 -0
  427. package/src/resources/extensions/gsd/tests/token-savings.test.ts +54 -56
  428. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +23 -25
  429. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +10 -11
  430. package/src/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +66 -82
  431. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +46 -47
  432. package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -22
  433. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -86
  434. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +41 -43
  435. package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +94 -96
  436. package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +11 -13
  437. package/src/resources/extensions/gsd/tests/worker-registry.test.ts +27 -29
  438. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +50 -52
  439. package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +10 -13
  440. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +14 -18
  441. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +38 -39
  442. package/src/resources/extensions/gsd/tests/worktree-e2e.test.ts +17 -21
  443. package/src/resources/extensions/gsd/tests/worktree-health.test.ts +25 -30
  444. package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +30 -37
  445. package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +65 -0
  446. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +15 -22
  447. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +59 -66
  448. package/src/resources/extensions/gsd/tests/worktree.test.ts +44 -50
  449. package/src/resources/extensions/gsd/tools/plan-slice.ts +2 -0
  450. package/src/resources/extensions/gsd/tools/plan-task.ts +2 -0
  451. package/src/resources/extensions/gsd/tools/replan-slice.ts +3 -0
  452. package/src/resources/extensions/gsd/tools/validate-milestone.ts +127 -0
  453. package/src/resources/extensions/gsd/worktree-manager.ts +43 -2
  454. package/src/resources/extensions/gsd/worktree-resolver.ts +7 -0
  455. package/src/resources/extensions/mcp-client/index.ts +20 -0
  456. package/dist/web/standalone/.next/static/chunks/4024.0de81b543b28b9fe.js +0 -9
  457. package/dist/web/standalone/.next/static/chunks/app/page-7e9530a7122506c5.js +0 -1
  458. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  459. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  460. package/dist/web/standalone/.next/static/chunks/webpack-9014b5adb127a98a.js +0 -1
  461. package/dist/web/standalone/.next/static/css/8a727f372cf53002.css +0 -1
  462. /package/dist/web/standalone/.next/static/{mgkxN0mGP6gSUmGPEzbk_ → rzO54ZboyINyEt7cVM_uS}/_buildManifest.js +0 -0
  463. /package/dist/web/standalone/.next/static/{mgkxN0mGP6gSUmGPEzbk_ → rzO54ZboyINyEt7cVM_uS}/_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,9 @@ 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";
31
33
 
32
34
  // ─── generateMilestoneReport ──────────────────────────────────────────────────
33
35
 
@@ -233,26 +235,23 @@ export async function runPreDispatch(
233
235
  loopState.stuckRecoveryAttempts = 0;
234
236
 
235
237
  // Worktree lifecycle on milestone transition — merge current, enter next
236
- deps.resolver.mergeAndExit(s.currentMilestoneId!, ctx.ui);
237
-
238
- // Opt-in: create draft PR on milestone completion
239
- if (prefs?.git?.auto_pr) {
240
- try {
241
- const { createDraftPR } = await import("../git-service.js");
242
- const prUrl = createDraftPR(
243
- s.basePath,
244
- s.currentMilestoneId!,
245
- `[GSD] ${s.currentMilestoneId} complete`,
246
- `Milestone ${s.currentMilestoneId} completed by GSD auto-mode.\n\nSee .gsd/${s.currentMilestoneId}/ for details.`,
238
+ try {
239
+ deps.resolver.mergeAndExit(s.currentMilestoneId!, ctx.ui);
240
+ } catch (mergeErr) {
241
+ if (mergeErr instanceof MergeConflictError) {
242
+ // Real code conflicts — stop the loop instead of retrying forever (#2330)
243
+ ctx.ui.notify(
244
+ `Merge conflict: ${mergeErr.conflictedFiles.join(", ")}. Resolve conflicts manually and run /gsd auto to resume.`,
245
+ "error",
247
246
  );
248
- if (prUrl) {
249
- ctx.ui.notify(`Draft PR created: ${prUrl}`, "info");
250
- }
251
- } catch {
252
- // Non-fatal — PR creation is best-effort
247
+ await deps.stopAuto(ctx, pi, `Merge conflict on milestone ${s.currentMilestoneId}`);
248
+ return { action: "break", reason: "merge-conflict" };
253
249
  }
250
+ // Non-conflict errors — log and continue
254
251
  }
255
252
 
253
+ // PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
254
+
256
255
  deps.invalidateAllCaches();
257
256
 
258
257
  state = await deps.deriveState(s.basePath);
@@ -279,9 +278,17 @@ export async function runPreDispatch(
279
278
  // Reset completed-units tracking for the new milestone — stale entries
280
279
  // from the previous milestone cause the dispatch loop to skip units
281
280
  // that haven't actually been completed in the new milestone's context.
281
+ // Archive the old completed-units.json instead of wiping it (#2313).
282
282
  s.completedUnits = [];
283
283
  try {
284
284
  const completedKeysPath = join(gsdRoot(s.basePath), "completed-units.json");
285
+ if (existsSync(completedKeysPath) && s.currentMilestoneId) {
286
+ const archivePath = join(
287
+ gsdRoot(s.basePath),
288
+ `completed-units-${s.currentMilestoneId}.json`,
289
+ );
290
+ cpSync(completedKeysPath, archivePath);
291
+ }
285
292
  atomicWriteSync(completedKeysPath, JSON.stringify([], null, 2));
286
293
  } catch { /* non-fatal */ }
287
294
 
@@ -322,25 +329,20 @@ export async function runPreDispatch(
322
329
  if (incomplete.length === 0 && state.registry.length > 0) {
323
330
  // All milestones complete — merge milestone branch before stopping
324
331
  if (s.currentMilestoneId) {
325
- deps.resolver.mergeAndExit(s.currentMilestoneId, ctx.ui);
326
-
327
- // Opt-in: create draft PR on milestone completion
328
- if (prefs?.git?.auto_pr) {
329
- try {
330
- const { createDraftPR } = await import("../git-service.js");
331
- const prUrl = createDraftPR(
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.`,
332
+ try {
333
+ deps.resolver.mergeAndExit(s.currentMilestoneId, ctx.ui);
334
+ } catch (mergeErr) {
335
+ if (mergeErr instanceof MergeConflictError) {
336
+ ctx.ui.notify(
337
+ `Merge conflict: ${mergeErr.conflictedFiles.join(", ")}. Resolve conflicts manually and run /gsd auto to resume.`,
338
+ "error",
336
339
  );
337
- if (prUrl) {
338
- ctx.ui.notify(`Draft PR created: ${prUrl}`, "info");
339
- }
340
- } catch {
341
- // Non-fatal — PR creation is best-effort
340
+ await deps.stopAuto(ctx, pi, `Merge conflict on milestone ${s.currentMilestoneId}`);
341
+ return { action: "break", reason: "merge-conflict" };
342
342
  }
343
343
  }
344
+
345
+ // PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
344
346
  }
345
347
  deps.sendDesktopNotification(
346
348
  "GSD",
@@ -422,25 +424,20 @@ export async function runPreDispatch(
422
424
  if (state.phase === "complete") {
423
425
  // Milestone merge on complete (before closeout so branch state is clean)
424
426
  if (s.currentMilestoneId) {
425
- deps.resolver.mergeAndExit(s.currentMilestoneId, ctx.ui);
426
-
427
- // Opt-in: create draft PR on milestone completion
428
- if (prefs?.git?.auto_pr) {
429
- try {
430
- const { createDraftPR } = await import("../git-service.js");
431
- const prUrl = createDraftPR(
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.`,
427
+ try {
428
+ deps.resolver.mergeAndExit(s.currentMilestoneId, ctx.ui);
429
+ } catch (mergeErr) {
430
+ if (mergeErr instanceof MergeConflictError) {
431
+ ctx.ui.notify(
432
+ `Merge conflict: ${mergeErr.conflictedFiles.join(", ")}. Resolve conflicts manually and run /gsd auto to resume.`,
433
+ "error",
436
434
  );
437
- if (prUrl) {
438
- ctx.ui.notify(`Draft PR created: ${prUrl}`, "info");
439
- }
440
- } catch {
441
- // Non-fatal — PR creation is best-effort
435
+ await deps.stopAuto(ctx, pi, `Merge conflict on milestone ${s.currentMilestoneId}`);
436
+ return { action: "break", reason: "merge-conflict" };
442
437
  }
443
438
  }
439
+
440
+ // PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
444
441
  }
445
442
  deps.sendDesktopNotification(
446
443
  "GSD",
@@ -860,6 +857,7 @@ export async function runUnitPhase(
860
857
  lastProgressAt: s.currentUnit.startedAt,
861
858
  progressCount: 0,
862
859
  lastProgressKind: "dispatch",
860
+ recoveryAttempts: 0, // Reset so re-dispatched units get full recovery budget (#2322)
863
861
  },
864
862
  );
865
863
 
@@ -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
- const softTimeoutMs = (supervisor.soft_timeout_minutes ?? 0) * 60 * 1000;
49
- const idleTimeoutMs = (supervisor.idle_timeout_minutes ?? 0) * 60 * 1000;
50
- const hardTimeoutMs = (supervisor.hard_timeout_minutes ?? 0) * 60 * 1000;
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,
@@ -162,6 +162,7 @@ export function syncGsdStateToWorktree(
162
162
  "OVERRIDES.md",
163
163
  "QUEUE.md",
164
164
  "completed-units.json",
165
+ "metrics.json",
165
166
  ];
166
167
  for (const f of rootFiles) {
167
168
  const src = join(mainGsd, f);
@@ -325,8 +326,9 @@ export function syncWorktreeStateBack(
325
326
  // ── 1. Sync root-level .gsd/ files back ──────────────────────────────
326
327
  // The worktree is authoritative — complete-milestone updates REQUIREMENTS,
327
328
  // PROJECT, etc. These must overwrite main's copies so they survive teardown.
328
- // Also includes QUEUE.md and completed-units.json which are written during
329
- // milestone closeout and lost on teardown without explicit sync (#1787).
329
+ // Also includes QUEUE.md, completed-units.json, and metrics.json which are
330
+ // written during milestone closeout and lost on teardown without explicit sync
331
+ // (#1787, #2313).
330
332
  const rootFiles = [
331
333
  "DECISIONS.md",
332
334
  "REQUIREMENTS.md",
@@ -335,6 +337,7 @@ export function syncWorktreeStateBack(
335
337
  "OVERRIDES.md",
336
338
  "QUEUE.md",
337
339
  "completed-units.json",
340
+ "metrics.json",
338
341
  ];
339
342
  for (const f of rootFiles) {
340
343
  const src = join(wtGsd, f);
@@ -1320,9 +1323,9 @@ export function mergeMilestoneToMain(
1320
1323
  }
1321
1324
  }
1322
1325
 
1323
- // 9b. Auto-create PR if enabled (requires push_branches + push succeeded)
1326
+ // 9b. Auto-create PR if enabled (#2302: no longer gated on pushed/auto_push)
1324
1327
  let prCreated = false;
1325
- if (prefs.auto_pr === true && pushed) {
1328
+ if (prefs.auto_pr === true && !nothingToCommit) {
1326
1329
  const remote = prefs.remote ?? "origin";
1327
1330
  const prTarget = prefs.pr_target_branch ?? mainBranch;
1328
1331
  try {
@@ -1332,9 +1335,9 @@ export function mergeMilestoneToMain(
1332
1335
  stdio: ["ignore", "pipe", "pipe"],
1333
1336
  encoding: "utf-8",
1334
1337
  });
1335
- // Create PR via gh CLI
1338
+ // Create PR via gh CLI with explicit --head and --base (#2302)
1336
1339
  execFileSync("gh", [
1337
- "pr", "create",
1340
+ "pr", "create", "--draft",
1338
1341
  "--base", prTarget,
1339
1342
  "--head", milestoneBranch,
1340
1343
  "--title", `Milestone ${milestoneId} complete`,
@@ -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().exitMilestone(s.currentMilestoneId, notifyCtx, {
619
- preserveBranch: true,
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) });