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
package/README.md CHANGED
@@ -24,10 +24,34 @@ One command. Walk away. Come back to a built project with clean git history.
24
24
 
25
25
  ---
26
26
 
27
- ## What's New in v2.42.0
27
+ ## What's New in v2.44.0
28
28
 
29
29
  ### New Features
30
30
 
31
+ - **Non-API-key provider extensions** — support for provider extensions like Claude Code CLI that don't require traditional API keys. (#2382)
32
+ - **Docker sandbox template** — official Docker template for running GSD auto mode in an isolated container. (#2360)
33
+ - **Per-prompt token cost display** — opt-in `show_token_cost` preference shows per-prompt and cumulative session cost in the footer. (#2357)
34
+ - **"Change project root" in web UI** — switch project directories from the web interface without restarting. (#2355)
35
+ - **DB-backed planning tools** — write-side state transitions now use atomic SQLite tool calls instead of markdown mutation, improving reliability and enabling structured queries. (#2141)
36
+
37
+ ### Key Fixes
38
+
39
+ - **Post-migration cleanup** — pragmas, rollbacks, tool gaps, and stale code cleaned up after DB migration. (#2410)
40
+ - **Planning data loss prevention** — destructive upsert and post-unit re-import no longer overwrite planning data. (#2370)
41
+ - **Memory and resource leaks** — fixes across TUI, LSP, DB, and automation subsystems. (#2314)
42
+ - **DECISIONS.md preservation** — freeform content in DECISIONS.md is no longer overwritten on decision save. (#2319)
43
+ - **Auto-stash before squash merge** — dirty files are automatically stashed before merge, with filenames surfaced in errors. (#2298)
44
+ - **Extension TypeScript detection** — `.js` extension files containing TypeScript syntax are detected with a suggestion to rename. (#2386)
45
+
46
+ ### v2.43.0 Highlights
47
+
48
+ - **Forensics dedup** — opt-in duplicate detection before issue creation. (#2105)
49
+ - **Fast service tier outside auto-mode** — `/gsd fast` now applies in interactive sessions too. (#2126)
50
+ - **Startup optimizations** — pre-compiled extensions, compile cache, and batch discovery for faster boot. (#2125)
51
+ - **Stale process cleanup** — web server kills stale process before launch to prevent EADDRINUSE. (#2034)
52
+
53
+ ### v2.42.0 Highlights
54
+
31
55
  - **Declarative workflow engine** — define YAML workflows that execute through auto-loop, enabling repeatable multi-step automations without code. (#2024)
32
56
  - **Unified rule registry & event journal** — centralized rule registry, event journal with query tool, and standardized tool naming convention. (#1928)
33
57
  - **PR risk checker** — CI classifies changed files by system area and surfaces risk level on pull requests. (#1930)
@@ -35,16 +59,6 @@ One command. Walk away. Come back to a built project with clean git history.
35
59
  - **Web mode CLI flags** — `--host`, `--port`, and `--allowed-origins` flags give full control over the web server bind address and CORS policy. (#1873)
36
60
  - **ADR attribution** — architecture decision records now distinguish human, agent, and collaborative authorship. (#1830)
37
61
 
38
- ### Key Fixes
39
-
40
- - **Node v24 web boot** — resolved `ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING` that prevented `gsd --web` from starting on Node v24. (#1864)
41
- - **Worktree health check for all ecosystems** — broadened from JS-only to 17+ ecosystems (Rust, Go, Python, Java, etc.). (#1860)
42
- - **Doctor roadmap atomicity** — roadmap checkbox gating now checks summary on disk, not issue detection, preventing false unchecks. (#1915)
43
- - **Windows path handling** — 8.3 short path resolution, backslash normalization in bash commands, PowerShell browser launch, and parenthesis escaping. (#1960, #1863, #1870, #1872)
44
- - **Auth token persistence** — web UI auth token survives page refreshes via sessionStorage. (#1877)
45
- - **German/non-English locale git errors** — git commands now force `LC_ALL=C` to prevent locale-dependent parse failures.
46
- - **Orphan web server process** — stale web server processes on port 3000 are now cleaned up automatically.
47
-
48
62
  ---
49
63
 
50
64
  ## What's New in v2.41.0
@@ -107,12 +121,14 @@ This release includes 7 fixes preventing silent data loss in auto-mode:
107
121
 
108
122
  See the full [Changelog](./CHANGELOG.md) for all 70+ fixes in this release.
109
123
 
110
- ### Previous highlights (v2.39–v2.40)
124
+ ### Previous highlights (v2.39–v2.41)
111
125
 
126
+ - **Browser-based web interface** — run GSD from the browser with `gsd --web`
112
127
  - **GitHub sync extension** — auto-sync milestones to GitHub Issues, PRs, and Milestones
113
128
  - **Skill tool resolution** — skills auto-activate in dispatched prompts
114
129
  - **Health check phase 2** — real-time doctor issues in dashboard and visualizer
115
130
  - **Forensics upgrade** — full-access GSD debugger with anomaly detection
131
+ - **7 data-loss prevention fixes** — hallucination guard, merge anchor verification, dirty tree detection, and more
116
132
  - **Pipeline decomposition** — auto-loop rewritten as linear phase pipeline
117
133
  - **Sliding-window stuck detection** — pattern-aware, fewer false positives
118
134
  - **Data-loss recovery** — automatic detection and recovery from v2.30–v2.38 migration issues
@@ -141,7 +157,9 @@ Full documentation is available in the [`docs/`](./docs/) directory:
141
157
  - **[Visualizer](./docs/visualizer.md)** — workflow visualizer with stats and discussion status
142
158
  - **[Remote Questions](./docs/remote-questions.md)** — route decisions to Slack or Discord when human input is needed
143
159
  - **[Dynamic Model Routing](./docs/dynamic-model-routing.md)** — complexity-based model selection and budget pressure
160
+ - **[Web Interface](./docs/web-interface.md)** — browser-based project management and real-time progress
144
161
  - **[Pipeline Simplification (ADR-003)](./docs/ADR-003-pipeline-simplification.md)** — merged research into planning, mechanical completion
162
+ - **[Docker Sandbox](./docker/README.md)** — run GSD auto mode in an isolated Docker container
145
163
  - **[Migration from v1](./docs/migration.md)** — `.planning` → `.gsd` migration
146
164
 
147
165
  ---
@@ -134,6 +134,13 @@ export function pruneActivityLogs(activityDir, retentionDays) {
134
134
  for (const entry of entries) {
135
135
  if (entry.seq === maxSeq)
136
136
  continue; // always preserve highest-seq
137
+ if (retentionDays === 0) {
138
+ try {
139
+ unlinkSync(entry.filePath);
140
+ }
141
+ catch { /* skip */ }
142
+ continue;
143
+ }
137
144
  try {
138
145
  const mtime = statSync(entry.filePath).mtimeMs;
139
146
  if (Math.floor(mtime) <= cutoff)
@@ -17,6 +17,9 @@ export const INFRA_ERROR_CODES = new Set([
17
17
  "EDQUOT", // disk quota exceeded
18
18
  "EMFILE", // too many open files (process)
19
19
  "ENFILE", // too many open files (system)
20
+ "ECONNREFUSED", // connection refused (offline / local server down)
21
+ "ENOTFOUND", // DNS lookup failed (offline / no network)
22
+ "ENETUNREACH", // network unreachable (offline / no route)
20
23
  ]);
21
24
  /**
22
25
  * Detect whether an error is an unrecoverable infrastructure failure.
@@ -14,7 +14,9 @@ import { debugLog } from "../debug-logger.js";
14
14
  import { gsdRoot } from "../paths.js";
15
15
  import { atomicWriteSync } from "../atomic-write.js";
16
16
  import { PROJECT_FILES } from "../detection.js";
17
+ import { MergeConflictError } from "../git-service.js";
17
18
  import { join } from "node:path";
19
+ import { existsSync, cpSync } from "node:fs";
18
20
  // ─── generateMilestoneReport ──────────────────────────────────────────────────
19
21
  /**
20
22
  * Generate and write an HTML milestone report snapshot.
@@ -145,20 +147,19 @@ export async function runPreDispatch(ic, loopState) {
145
147
  loopState.recentUnits.length = 0;
146
148
  loopState.stuckRecoveryAttempts = 0;
147
149
  // Worktree lifecycle on milestone transition — merge current, enter next
148
- deps.resolver.mergeAndExit(s.currentMilestoneId, ctx.ui);
149
- // Opt-in: create draft PR on milestone completion
150
- if (prefs?.git?.auto_pr) {
151
- try {
152
- const { createDraftPR } = await import("../git-service.js");
153
- const prUrl = createDraftPR(s.basePath, s.currentMilestoneId, `[GSD] ${s.currentMilestoneId} complete`, `Milestone ${s.currentMilestoneId} completed by GSD auto-mode.\n\nSee .gsd/${s.currentMilestoneId}/ for details.`);
154
- if (prUrl) {
155
- ctx.ui.notify(`Draft PR created: ${prUrl}`, "info");
156
- }
157
- }
158
- catch {
159
- // Non-fatal — PR creation is best-effort
150
+ try {
151
+ deps.resolver.mergeAndExit(s.currentMilestoneId, ctx.ui);
152
+ }
153
+ catch (mergeErr) {
154
+ if (mergeErr instanceof MergeConflictError) {
155
+ // Real code conflicts stop the loop instead of retrying forever (#2330)
156
+ ctx.ui.notify(`Merge conflict: ${mergeErr.conflictedFiles.join(", ")}. Resolve conflicts manually and run /gsd auto to resume.`, "error");
157
+ await deps.stopAuto(ctx, pi, `Merge conflict on milestone ${s.currentMilestoneId}`);
158
+ return { action: "break", reason: "merge-conflict" };
160
159
  }
160
+ // Non-conflict errors — log and continue
161
161
  }
162
+ // PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
162
163
  deps.invalidateAllCaches();
163
164
  state = await deps.deriveState(s.basePath);
164
165
  mid = state.activeMilestone?.id;
@@ -179,9 +180,14 @@ export async function runPreDispatch(ic, loopState) {
179
180
  // Reset completed-units tracking for the new milestone — stale entries
180
181
  // from the previous milestone cause the dispatch loop to skip units
181
182
  // that haven't actually been completed in the new milestone's context.
183
+ // Archive the old completed-units.json instead of wiping it (#2313).
182
184
  s.completedUnits = [];
183
185
  try {
184
186
  const completedKeysPath = join(gsdRoot(s.basePath), "completed-units.json");
187
+ if (existsSync(completedKeysPath) && s.currentMilestoneId) {
188
+ const archivePath = join(gsdRoot(s.basePath), `completed-units-${s.currentMilestoneId}.json`);
189
+ cpSync(completedKeysPath, archivePath);
190
+ }
185
191
  atomicWriteSync(completedKeysPath, JSON.stringify([], null, 2));
186
192
  }
187
193
  catch { /* non-fatal */ }
@@ -209,20 +215,17 @@ export async function runPreDispatch(ic, loopState) {
209
215
  if (incomplete.length === 0 && state.registry.length > 0) {
210
216
  // All milestones complete — merge milestone branch before stopping
211
217
  if (s.currentMilestoneId) {
212
- deps.resolver.mergeAndExit(s.currentMilestoneId, ctx.ui);
213
- // Opt-in: create draft PR on milestone completion
214
- if (prefs?.git?.auto_pr) {
215
- try {
216
- const { createDraftPR } = await import("../git-service.js");
217
- const prUrl = createDraftPR(s.basePath, s.currentMilestoneId, `[GSD] ${s.currentMilestoneId} complete`, `Milestone ${s.currentMilestoneId} completed by GSD auto-mode.\n\nSee .gsd/${s.currentMilestoneId}/ for details.`);
218
- if (prUrl) {
219
- ctx.ui.notify(`Draft PR created: ${prUrl}`, "info");
220
- }
221
- }
222
- catch {
223
- // Non-fatal — PR creation is best-effort
218
+ try {
219
+ deps.resolver.mergeAndExit(s.currentMilestoneId, ctx.ui);
220
+ }
221
+ catch (mergeErr) {
222
+ if (mergeErr instanceof MergeConflictError) {
223
+ ctx.ui.notify(`Merge conflict: ${mergeErr.conflictedFiles.join(", ")}. Resolve conflicts manually and run /gsd auto to resume.`, "error");
224
+ await deps.stopAuto(ctx, pi, `Merge conflict on milestone ${s.currentMilestoneId}`);
225
+ return { action: "break", reason: "merge-conflict" };
224
226
  }
225
227
  }
228
+ // PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
226
229
  }
227
230
  deps.sendDesktopNotification("GSD", "All milestones complete!", "success", "milestone");
228
231
  deps.logCmuxEvent(prefs, "All milestones complete.", "success");
@@ -277,20 +280,17 @@ export async function runPreDispatch(ic, loopState) {
277
280
  if (state.phase === "complete") {
278
281
  // Milestone merge on complete (before closeout so branch state is clean)
279
282
  if (s.currentMilestoneId) {
280
- deps.resolver.mergeAndExit(s.currentMilestoneId, ctx.ui);
281
- // Opt-in: create draft PR on milestone completion
282
- if (prefs?.git?.auto_pr) {
283
- try {
284
- const { createDraftPR } = await import("../git-service.js");
285
- const prUrl = createDraftPR(s.basePath, s.currentMilestoneId, `[GSD] ${s.currentMilestoneId} complete`, `Milestone ${s.currentMilestoneId} completed by GSD auto-mode.\n\nSee .gsd/${s.currentMilestoneId}/ for details.`);
286
- if (prUrl) {
287
- ctx.ui.notify(`Draft PR created: ${prUrl}`, "info");
288
- }
289
- }
290
- catch {
291
- // Non-fatal — PR creation is best-effort
283
+ try {
284
+ deps.resolver.mergeAndExit(s.currentMilestoneId, ctx.ui);
285
+ }
286
+ catch (mergeErr) {
287
+ if (mergeErr instanceof MergeConflictError) {
288
+ ctx.ui.notify(`Merge conflict: ${mergeErr.conflictedFiles.join(", ")}. Resolve conflicts manually and run /gsd auto to resume.`, "error");
289
+ await deps.stopAuto(ctx, pi, `Merge conflict on milestone ${s.currentMilestoneId}`);
290
+ return { action: "break", reason: "merge-conflict" };
292
291
  }
293
292
  }
293
+ // PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
294
294
  }
295
295
  deps.sendDesktopNotification("GSD", `Milestone ${mid} complete!`, "success", "milestone");
296
296
  deps.logCmuxEvent(prefs, `Milestone ${mid} complete.`, "success");
@@ -591,6 +591,7 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
591
591
  lastProgressAt: s.currentUnit.startedAt,
592
592
  progressCount: 0,
593
593
  lastProgressKind: "dispatch",
594
+ recoveryAttempts: 0, // Reset so re-dispatched units get full recovery budget (#2322)
594
595
  });
595
596
  // Status bar + progress widget
596
597
  ctx.ui.setStatus("gsd-auto", "auto");
@@ -1156,6 +1156,12 @@ export async function buildCompleteMilestonePrompt(mid, midTitle, base, level) {
1156
1156
  roadmapPath: roadmapRel,
1157
1157
  inlinedContext,
1158
1158
  milestoneSummaryPath,
1159
+ skillActivation: buildSkillActivationBlock({
1160
+ base,
1161
+ milestoneId: mid,
1162
+ milestoneTitle: midTitle,
1163
+ extraContext: [inlinedContext],
1164
+ }),
1159
1165
  });
1160
1166
  }
1161
1167
  export async function buildValidateMilestonePrompt(mid, midTitle, base, level) {
@@ -1236,6 +1242,12 @@ export async function buildValidateMilestonePrompt(mid, midTitle, base, level) {
1236
1242
  inlinedContext,
1237
1243
  validationPath: validationOutputPath,
1238
1244
  remediationRound: String(remediationRound),
1245
+ skillActivation: buildSkillActivationBlock({
1246
+ base,
1247
+ milestoneId: mid,
1248
+ milestoneTitle: midTitle,
1249
+ extraContext: [inlinedContext],
1250
+ }),
1239
1251
  });
1240
1252
  }
1241
1253
  export async function buildReplanSlicePrompt(mid, midTitle, sid, sTitle, base) {
@@ -1332,6 +1344,12 @@ export async function buildRunUatPrompt(mid, sliceId, uatPath, uatContent, base)
1332
1344
  uatResultPath,
1333
1345
  uatType,
1334
1346
  inlinedContext,
1347
+ skillActivation: buildSkillActivationBlock({
1348
+ base,
1349
+ milestoneId: mid,
1350
+ sliceId,
1351
+ extraContext: [inlinedContext],
1352
+ }),
1335
1353
  });
1336
1354
  }
1337
1355
  export async function buildReassessRoadmapPrompt(mid, midTitle, completedSliceId, base, level) {
@@ -1378,11 +1396,16 @@ export async function buildReassessRoadmapPrompt(mid, midTitle, completedSliceId
1378
1396
  milestoneTitle: midTitle,
1379
1397
  completedSliceId,
1380
1398
  roadmapPath: roadmapRel,
1381
- completedSliceSummaryPath: summaryRel,
1382
1399
  assessmentPath,
1383
1400
  inlinedContext,
1384
1401
  deferredCaptures,
1385
1402
  commitInstruction: reassessCommitInstruction,
1403
+ skillActivation: buildSkillActivationBlock({
1404
+ base,
1405
+ milestoneId: mid,
1406
+ milestoneTitle: midTitle,
1407
+ extraContext: [inlinedContext, deferredCaptures],
1408
+ }),
1386
1409
  });
1387
1410
  }
1388
1411
  // ─── Reactive Execute Prompt ──────────────────────────────────────────────
@@ -197,10 +197,13 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
197
197
  state = await deriveState(wtPath);
198
198
  }
199
199
  }
200
- // Milestone branch recovery (#601)
200
+ // Milestone branch recovery (#601, #2358)
201
+ // Detect survivor milestone branches in both pre-planning and complete phases.
202
+ // In phase=complete, the milestone artifacts exist but finalization (merge,
203
+ // worktree cleanup) was never run — the survivor branch must be merged.
201
204
  let hasSurvivorBranch = false;
202
205
  if (state.activeMilestone &&
203
- state.phase === "pre-planning" &&
206
+ (state.phase === "pre-planning" || state.phase === "complete") &&
204
207
  shouldUseWorktreeIsolation() &&
205
208
  !detectWorktreeName(base) &&
206
209
  !base.includes(`${pathSep}.gsd${pathSep}worktrees${pathSep}`)) {
@@ -231,6 +234,22 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
231
234
  return releaseLockAndReturn();
232
235
  }
233
236
  }
237
+ // Survivor branch exists and milestone is complete (#2358):
238
+ // The milestone artifacts were written but finalization (merge, worktree
239
+ // cleanup) never ran. Run mergeAndExit to finalize, then re-derive state
240
+ // so the normal "all milestones complete" or "next milestone" path runs.
241
+ if (hasSurvivorBranch && state.phase === "complete") {
242
+ const mid = state.activeMilestone.id;
243
+ ctx.ui.notify(`Milestone ${mid} is complete but branch/worktree was not finalized. Running merge now.`, "info");
244
+ const resolver = buildResolver();
245
+ resolver.mergeAndExit(mid, {
246
+ notify: ctx.ui.notify.bind(ctx.ui),
247
+ });
248
+ invalidateAllCaches();
249
+ state = await deriveState(base);
250
+ // Clear survivor flag — finalization is done
251
+ hasSurvivorBranch = false;
252
+ }
234
253
  if (!hasSurvivorBranch) {
235
254
  // No active work — start a new milestone via discuss flow
236
255
  if (!state.activeMilestone || state.phase === "complete") {
@@ -402,6 +421,16 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
402
421
  process.stderr.write(`gsd-db: failed to open existing database: ${err.message}\n`);
403
422
  }
404
423
  }
424
+ // Gate: abort bootstrap if the DB file exists but the provider is
425
+ // still unavailable after both open attempts above. Without this,
426
+ // auto-mode starts but every gsd_task_complete / gsd_slice_complete
427
+ // call returns "db_unavailable", triggering artifact-retry which
428
+ // re-dispatches the same task — producing an infinite loop (#2419).
429
+ if (existsSync(gsdDbPath) && !isDbAvailable()) {
430
+ ctx.ui.notify("SQLite database exists but failed to open. Auto-mode cannot proceed without a working database provider. " +
431
+ "Check for corrupt gsd.db or missing native SQLite bindings.", "error");
432
+ return releaseLockAndReturn();
433
+ }
405
434
  // Initialize metrics
406
435
  initMetrics(s.basePath);
407
436
  // Initialize routing history
@@ -6,6 +6,7 @@
6
6
  * via startUnitSupervision() and torn down by the caller via clearUnitTimeout().
7
7
  */
8
8
  import { readUnitRuntimeRecord, writeUnitRuntimeRecord } from "./unit-runtime.js";
9
+ import { isDbAvailable, getMilestoneSlices, getSliceTasks } from "./gsd-db.js";
9
10
  import { resolveAutoSupervisorConfig } from "./preferences.js";
10
11
  import { computeBudgets, resolveExecutorContextWindow } from "./context-budget.js";
11
12
  import { getInFlightToolCount, getOldestInFlightToolStart, } from "./auto-tool-tracking.js";
@@ -21,12 +22,65 @@ import { resolveAgentEndCancelled } from "./auto/resolve.js";
21
22
  * 3. Hard timeout (pause + recovery)
22
23
  * 4. Context-pressure monitor (continue-here)
23
24
  */
25
+ /**
26
+ * Parse a task estimate string (e.g. "30m", "2h", "1h30m") into minutes.
27
+ * Returns null if the string cannot be parsed.
28
+ */
29
+ export function parseEstimateMinutes(estimate) {
30
+ if (!estimate || typeof estimate !== "string")
31
+ return null;
32
+ const trimmed = estimate.trim();
33
+ if (!trimmed)
34
+ return null;
35
+ let totalMinutes = 0;
36
+ let matched = false;
37
+ // Match hours component
38
+ const hoursMatch = trimmed.match(/(\d+)\s*h/i);
39
+ if (hoursMatch) {
40
+ totalMinutes += Number(hoursMatch[1]) * 60;
41
+ matched = true;
42
+ }
43
+ // Match minutes component
44
+ const minutesMatch = trimmed.match(/(\d+)\s*m/i);
45
+ if (minutesMatch) {
46
+ totalMinutes += Number(minutesMatch[1]);
47
+ matched = true;
48
+ }
49
+ return matched ? totalMinutes : null;
50
+ }
24
51
  export function startUnitSupervision(sctx) {
25
52
  const { s, ctx, pi, unitType, unitId, prefs, buildSnapshotOpts, buildRecoveryContext, pauseAuto } = sctx;
26
53
  const supervisor = resolveAutoSupervisorConfig();
27
- const softTimeoutMs = (supervisor.soft_timeout_minutes ?? 0) * 60 * 1000;
28
- const idleTimeoutMs = (supervisor.idle_timeout_minutes ?? 0) * 60 * 1000;
29
- const hardTimeoutMs = (supervisor.hard_timeout_minutes ?? 0) * 60 * 1000;
54
+ // Scale timeouts based on task estimate annotations (#2243).
55
+ // If the task has an est: annotation, use it to extend the hard and soft timeouts
56
+ // so longer tasks don't get prematurely timed out.
57
+ let taskEstimate = sctx.taskEstimate;
58
+ if (!taskEstimate && unitType === "task" && isDbAvailable()) {
59
+ // Look up the task estimate from the DB (#2243).
60
+ try {
61
+ if (s.currentMilestoneId) {
62
+ const slices = getMilestoneSlices(s.currentMilestoneId);
63
+ for (const slice of slices) {
64
+ const tasks = getSliceTasks(s.currentMilestoneId, slice.id);
65
+ const task = tasks.find(t => t.id === unitId);
66
+ if (task?.estimate) {
67
+ taskEstimate = task.estimate;
68
+ break;
69
+ }
70
+ }
71
+ }
72
+ }
73
+ catch {
74
+ // Non-fatal — fall through with no estimate
75
+ }
76
+ }
77
+ const estimateMinutes = taskEstimate ? parseEstimateMinutes(taskEstimate) : null;
78
+ const timeoutScale = estimateMinutes && estimateMinutes > 0
79
+ ? Math.max(1, estimateMinutes / 10) // 10min task = 1x, 30min = 3x, 2h = 12x
80
+ : 1;
81
+ const softTimeoutMs = (supervisor.soft_timeout_minutes ?? 0) * 60 * 1000 * timeoutScale;
82
+ const idleTimeoutMs = (supervisor.idle_timeout_minutes ?? 0) * 60 * 1000; // idle not scaled — idle is idle
83
+ const hardTimeoutMs = (supervisor.hard_timeout_minutes ?? 0) * 60 * 1000 * timeoutScale;
30
84
  // ── 1. Soft timeout warning ──
31
85
  s.wrapupWarningHandle = setTimeout(() => {
32
86
  s.wrapupWarningHandle = null;
@@ -63,6 +63,10 @@ export function syncStateToProjectRoot(worktreePath, projectRoot, milestoneId) {
63
63
  // 2. Milestone directory — ROADMAP, slice PLANs, task summaries
64
64
  // Copy the entire milestone .gsd subtree so deriveState reads current checkboxes
65
65
  safeCopyRecursive(join(wtGsd, "milestones", milestoneId), join(prGsd, "milestones", milestoneId), { force: true });
66
+ // 3. metrics.json — session cost/token tracking (#2313).
67
+ // Without this, metrics accumulated in the worktree are invisible from the
68
+ // project root and never appear in the dashboard or skill-health reports.
69
+ safeCopy(join(wtGsd, "metrics.json"), join(prGsd, "metrics.json"), { force: true });
66
70
  // 4. Runtime records — unit dispatch state used by selfHealRuntimeRecords().
67
71
  // Without this, a crash during a unit leaves the runtime record only in the
68
72
  // worktree. If the next session resolves basePath before worktree re-entry,
@@ -109,6 +109,7 @@ export function syncGsdStateToWorktree(mainBasePath, worktreePath_) {
109
109
  "OVERRIDES.md",
110
110
  "QUEUE.md",
111
111
  "completed-units.json",
112
+ "metrics.json",
112
113
  ];
113
114
  for (const f of rootFiles) {
114
115
  const src = join(mainGsd, f);
@@ -269,8 +270,9 @@ export function syncWorktreeStateBack(mainBasePath, worktreePath, milestoneId) {
269
270
  // ── 1. Sync root-level .gsd/ files back ──────────────────────────────
270
271
  // The worktree is authoritative — complete-milestone updates REQUIREMENTS,
271
272
  // PROJECT, etc. These must overwrite main's copies so they survive teardown.
272
- // Also includes QUEUE.md and completed-units.json which are written during
273
- // milestone closeout and lost on teardown without explicit sync (#1787).
273
+ // Also includes QUEUE.md, completed-units.json, and metrics.json which are
274
+ // written during milestone closeout and lost on teardown without explicit sync
275
+ // (#1787, #2313).
274
276
  const rootFiles = [
275
277
  "DECISIONS.md",
276
278
  "REQUIREMENTS.md",
@@ -279,6 +281,7 @@ export function syncWorktreeStateBack(mainBasePath, worktreePath, milestoneId) {
279
281
  "OVERRIDES.md",
280
282
  "QUEUE.md",
281
283
  "completed-units.json",
284
+ "metrics.json",
282
285
  ];
283
286
  for (const f of rootFiles) {
284
287
  const src = join(wtGsd, f);
@@ -1133,9 +1136,9 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
1133
1136
  // Push failure is non-fatal
1134
1137
  }
1135
1138
  }
1136
- // 9b. Auto-create PR if enabled (requires push_branches + push succeeded)
1139
+ // 9b. Auto-create PR if enabled (#2302: no longer gated on pushed/auto_push)
1137
1140
  let prCreated = false;
1138
- if (prefs.auto_pr === true && pushed) {
1141
+ if (prefs.auto_pr === true && !nothingToCommit) {
1139
1142
  const remote = prefs.remote ?? "origin";
1140
1143
  const prTarget = prefs.pr_target_branch ?? mainBranch;
1141
1144
  try {
@@ -1145,9 +1148,9 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
1145
1148
  stdio: ["ignore", "pipe", "pipe"],
1146
1149
  encoding: "utf-8",
1147
1150
  });
1148
- // Create PR via gh CLI
1151
+ // Create PR via gh CLI with explicit --head and --base (#2302)
1149
1152
  execFileSync("gh", [
1150
- "pr", "create",
1153
+ "pr", "create", "--draft",
1151
1154
  "--base", prTarget,
1152
1155
  "--head", milestoneBranch,
1153
1156
  "--title", `Milestone ${milestoneId} complete`,
@@ -369,14 +369,41 @@ export async function stopAuto(ctx, pi, reason) {
369
369
  debugLog("stop-cleanup-sigterm", { error: e instanceof Error ? e.message : String(e) });
370
370
  }
371
371
  // ── Step 4: Auto-worktree exit ──
372
+ // When the milestone is complete (has a SUMMARY), merge the worktree branch
373
+ // back to main so code isn't stranded on the worktree branch (#2317).
374
+ // For incomplete milestones, preserve the branch for later resumption.
372
375
  try {
373
376
  if (s.currentMilestoneId) {
374
377
  const notifyCtx = ctx
375
378
  ? { notify: ctx.ui.notify.bind(ctx.ui) }
376
379
  : { notify: () => { } };
377
- buildResolver().exitMilestone(s.currentMilestoneId, notifyCtx, {
378
- preserveBranch: true,
379
- });
380
+ const resolver = buildResolver();
381
+ // Check if the milestone is complete — SUMMARY file is the authoritative signal.
382
+ let milestoneComplete = false;
383
+ try {
384
+ const summaryPath = resolveMilestoneFile(s.originalBasePath || s.basePath, s.currentMilestoneId, "SUMMARY");
385
+ if (!summaryPath) {
386
+ // Also check in the worktree path (SUMMARY may not be synced yet)
387
+ const wtSummaryPath = resolveMilestoneFile(s.basePath, s.currentMilestoneId, "SUMMARY");
388
+ milestoneComplete = wtSummaryPath !== null;
389
+ }
390
+ else {
391
+ milestoneComplete = true;
392
+ }
393
+ }
394
+ catch {
395
+ // Non-fatal — fall through to preserveBranch path
396
+ }
397
+ if (milestoneComplete) {
398
+ // Milestone is complete — merge worktree branch back to main
399
+ resolver.mergeAndExit(s.currentMilestoneId, notifyCtx);
400
+ }
401
+ else {
402
+ // Milestone still in progress — preserve branch for later resumption
403
+ resolver.exitMilestone(s.currentMilestoneId, notifyCtx, {
404
+ preserveBranch: true,
405
+ });
406
+ }
380
407
  }
381
408
  }
382
409
  catch (e) {