gsd-pi 2.44.0 → 2.45.0-dev.e0ee972

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (505) hide show
  1. package/README.md +30 -12
  2. package/dist/help-text.js +1 -1
  3. package/dist/loader.js +34 -0
  4. package/dist/resources/extensions/gsd/activity-log.js +7 -0
  5. package/dist/resources/extensions/gsd/auto/infra-errors.js +3 -0
  6. package/dist/resources/extensions/gsd/auto/phases.js +52 -45
  7. package/dist/resources/extensions/gsd/auto/run-unit.js +6 -3
  8. package/dist/resources/extensions/gsd/auto-prompts.js +24 -1
  9. package/dist/resources/extensions/gsd/auto-start.js +31 -2
  10. package/dist/resources/extensions/gsd/auto-timers.js +57 -3
  11. package/dist/resources/extensions/gsd/auto-worktree-sync.js +4 -0
  12. package/dist/resources/extensions/gsd/auto-worktree.js +14 -10
  13. package/dist/resources/extensions/gsd/auto.js +34 -8
  14. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +168 -11
  15. package/dist/resources/extensions/gsd/bootstrap/system-context.js +46 -12
  16. package/dist/resources/extensions/gsd/commands/catalog.js +7 -1
  17. package/dist/resources/extensions/gsd/commands/handlers/core.js +2 -0
  18. package/dist/resources/extensions/gsd/commands/handlers/ops.js +10 -0
  19. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +5 -0
  20. package/dist/resources/extensions/gsd/commands-mcp-status.js +187 -0
  21. package/dist/resources/extensions/gsd/db-writer.js +40 -22
  22. package/dist/resources/extensions/gsd/doctor-checks.js +1 -1
  23. package/dist/resources/extensions/gsd/doctor.js +10 -2
  24. package/dist/resources/extensions/gsd/git-service.js +8 -3
  25. package/dist/resources/extensions/gsd/gsd-db.js +17 -2
  26. package/dist/resources/extensions/gsd/markdown-renderer.js +1 -1
  27. package/dist/resources/extensions/gsd/preferences-types.js +2 -2
  28. package/dist/resources/extensions/gsd/preferences.js +17 -5
  29. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +2 -4
  30. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  31. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -6
  32. package/dist/resources/extensions/gsd/prompts/replan-slice.md +3 -14
  33. package/dist/resources/extensions/gsd/prompts/rethink.md +78 -0
  34. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +7 -37
  35. package/dist/resources/extensions/gsd/provider-error-pause.js +7 -0
  36. package/dist/resources/extensions/gsd/repo-identity.js +45 -7
  37. package/dist/resources/extensions/gsd/rethink.js +115 -0
  38. package/dist/resources/extensions/gsd/state.js +41 -3
  39. package/dist/resources/extensions/gsd/tools/plan-slice.js +1 -0
  40. package/dist/resources/extensions/gsd/tools/plan-task.js +1 -0
  41. package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -0
  42. package/dist/resources/extensions/gsd/tools/validate-milestone.js +88 -0
  43. package/dist/resources/extensions/gsd/workflow-logger.js +138 -0
  44. package/dist/resources/extensions/gsd/worktree-manager.js +34 -3
  45. package/dist/resources/extensions/gsd/worktree-resolver.js +43 -0
  46. package/dist/resources/extensions/mcp-client/index.js +14 -0
  47. package/dist/resources/extensions/voice/index.js +11 -16
  48. package/dist/resources/extensions/voice/linux-ready.js +67 -0
  49. package/dist/web/standalone/.next/BUILD_ID +1 -1
  50. package/dist/web/standalone/.next/app-path-routes-manifest.json +15 -15
  51. package/dist/web/standalone/.next/build-manifest.json +4 -4
  52. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  53. package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
  54. package/dist/web/standalone/.next/required-server-files.json +3 -3
  55. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  56. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  57. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  58. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  59. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  60. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  61. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  62. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  63. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  64. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  65. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  66. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  67. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  68. package/dist/web/standalone/.next/server/app/_not-found.rsc +5 -5
  69. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +5 -5
  70. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  71. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
  72. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  73. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  74. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  75. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  76. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  77. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  78. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  79. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  80. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  81. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  82. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  83. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  84. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  85. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  86. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  87. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  88. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  89. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  90. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  91. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  92. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  93. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  94. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  95. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  96. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  97. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  98. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  99. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  100. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  101. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  102. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  103. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  104. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  105. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  106. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  107. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  108. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  109. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  110. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +5 -5
  120. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  126. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  140. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  142. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  144. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  146. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/index.html +1 -1
  156. package/dist/web/standalone/.next/server/app/index.rsc +6 -6
  157. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  158. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +6 -6
  159. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  160. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
  161. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  162. package/dist/web/standalone/.next/server/app/page.js +2 -2
  163. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app-paths-manifest.json +15 -15
  165. package/dist/web/standalone/.next/server/chunks/229.js +1 -1
  166. package/dist/web/standalone/.next/server/chunks/471.js +3 -3
  167. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  168. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/middleware.js +2 -2
  170. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  172. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  173. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  174. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  175. package/dist/web/standalone/.next/static/chunks/4024.11ca5c01938e5948.js +9 -0
  176. package/dist/web/standalone/.next/static/chunks/{3721.bf31263de6d5fa46.js → 485.243af25f0cdf50d6.js} +2 -2
  177. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  178. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  179. package/dist/web/standalone/.next/static/chunks/app/page-6654a8cca61a3d1c.js +1 -0
  180. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  181. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  182. package/dist/web/standalone/.next/static/chunks/webpack-0a4cd455ec4197d2.js +1 -0
  183. package/dist/web/standalone/.next/static/css/dd4ae3f58ac9b600.css +1 -0
  184. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  185. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  186. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  187. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  188. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  189. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  190. package/dist/web/standalone/server.js +1 -1
  191. package/package.json +1 -1
  192. package/packages/native/dist/stream-process/index.js +2 -2
  193. package/packages/native/src/__tests__/stream-process.test.mjs +34 -0
  194. package/packages/native/src/stream-process/index.ts +2 -2
  195. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +3 -1
  196. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  197. package/packages/pi-coding-agent/dist/core/auth-storage.js +15 -1
  198. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  199. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +6 -8
  200. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  201. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts.map +1 -1
  202. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +2 -0
  203. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -1
  204. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +24 -26
  205. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  206. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +2 -1
  207. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  208. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  209. package/packages/pi-coding-agent/dist/core/fs-utils.test.js +29 -48
  210. package/packages/pi-coding-agent/dist/core/fs-utils.test.js.map +1 -1
  211. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.d.ts +4 -0
  212. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.d.ts.map +1 -1
  213. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.js +10 -5
  214. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.js.map +1 -1
  215. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.test.d.ts +2 -0
  216. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.test.d.ts.map +1 -0
  217. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.test.js +185 -0
  218. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.test.js.map +1 -0
  219. package/packages/pi-coding-agent/dist/core/local-model-check.d.ts +15 -0
  220. package/packages/pi-coding-agent/dist/core/local-model-check.d.ts.map +1 -0
  221. package/packages/pi-coding-agent/dist/core/local-model-check.js +41 -0
  222. package/packages/pi-coding-agent/dist/core/local-model-check.js.map +1 -0
  223. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +239 -10
  224. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  225. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +13 -1
  226. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  227. package/packages/pi-coding-agent/dist/core/model-registry.js +40 -3
  228. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  229. package/packages/pi-coding-agent/dist/core/package-commands.test.js +206 -195
  230. package/packages/pi-coding-agent/dist/core/package-commands.test.js.map +1 -1
  231. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +34 -44
  232. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
  233. package/packages/pi-coding-agent/dist/core/session-manager.test.js +30 -34
  234. package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
  235. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
  236. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  237. package/packages/pi-coding-agent/dist/core/settings-manager.js +6 -0
  238. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  239. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +10 -12
  240. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -1
  241. package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
  242. package/packages/pi-coding-agent/dist/main.js +17 -0
  243. package/packages/pi-coding-agent/dist/main.js.map +1 -1
  244. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.d.ts +2 -0
  245. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.d.ts.map +1 -0
  246. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.js +32 -0
  247. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.js.map +1 -0
  248. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +3 -1
  249. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  250. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +8 -1
  251. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  252. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  253. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  254. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +12 -0
  255. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
  256. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.d.ts +15 -0
  257. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.d.ts.map +1 -0
  258. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.js +40 -0
  259. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.js.map +1 -0
  260. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  261. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +4 -1
  262. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  263. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts +5 -2
  264. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  265. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +13 -2
  266. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
  267. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  268. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +17 -8
  269. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  270. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  271. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +7 -3
  272. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  273. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js +43 -47
  274. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js.map +1 -1
  275. package/packages/pi-coding-agent/package.json +1 -1
  276. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +7 -7
  277. package/packages/pi-coding-agent/src/core/auth-storage.ts +15 -1
  278. package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +2 -0
  279. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +26 -26
  280. package/packages/pi-coding-agent/src/core/extensions/types.ts +2 -1
  281. package/packages/pi-coding-agent/src/core/fs-utils.test.ts +31 -43
  282. package/packages/pi-coding-agent/src/core/lifecycle-hooks.test.ts +227 -0
  283. package/packages/pi-coding-agent/src/core/lifecycle-hooks.ts +11 -5
  284. package/packages/pi-coding-agent/src/core/local-model-check.ts +45 -0
  285. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +297 -11
  286. package/packages/pi-coding-agent/src/core/model-registry.ts +51 -4
  287. package/packages/pi-coding-agent/src/core/package-commands.test.ts +227 -205
  288. package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +40 -45
  289. package/packages/pi-coding-agent/src/core/session-manager.test.ts +33 -33
  290. package/packages/pi-coding-agent/src/core/settings-manager.ts +9 -0
  291. package/packages/pi-coding-agent/src/core/tools/edit-diff.test.ts +17 -17
  292. package/packages/pi-coding-agent/src/main.ts +19 -0
  293. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/timestamp.test.ts +38 -0
  294. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +10 -0
  295. package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +15 -0
  296. package/packages/pi-coding-agent/src/modes/interactive/components/timestamp.ts +48 -0
  297. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +3 -1
  298. package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +18 -3
  299. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +16 -7
  300. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +8 -1
  301. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.test.ts +74 -74
  302. package/pkg/package.json +1 -1
  303. package/src/resources/extensions/gsd/activity-log.ts +1 -0
  304. package/src/resources/extensions/gsd/auto/infra-errors.ts +3 -0
  305. package/src/resources/extensions/gsd/auto/phases.ts +61 -59
  306. package/src/resources/extensions/gsd/auto/run-unit.ts +6 -3
  307. package/src/resources/extensions/gsd/auto-prompts.ts +24 -1
  308. package/src/resources/extensions/gsd/auto-start.ts +39 -2
  309. package/src/resources/extensions/gsd/auto-timers.ts +64 -3
  310. package/src/resources/extensions/gsd/auto-worktree-sync.ts +5 -0
  311. package/src/resources/extensions/gsd/auto-worktree.ts +17 -11
  312. package/src/resources/extensions/gsd/auto.ts +40 -6
  313. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +160 -11
  314. package/src/resources/extensions/gsd/bootstrap/system-context.ts +48 -11
  315. package/src/resources/extensions/gsd/commands/catalog.ts +7 -1
  316. package/src/resources/extensions/gsd/commands/handlers/core.ts +2 -0
  317. package/src/resources/extensions/gsd/commands/handlers/ops.ts +10 -0
  318. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +8 -0
  319. package/src/resources/extensions/gsd/commands-mcp-status.ts +247 -0
  320. package/src/resources/extensions/gsd/db-writer.ts +41 -27
  321. package/src/resources/extensions/gsd/doctor-checks.ts +1 -1
  322. package/src/resources/extensions/gsd/doctor.ts +9 -3
  323. package/src/resources/extensions/gsd/git-service.ts +6 -2
  324. package/src/resources/extensions/gsd/gsd-db.ts +21 -2
  325. package/src/resources/extensions/gsd/journal.ts +6 -1
  326. package/src/resources/extensions/gsd/markdown-renderer.ts +1 -1
  327. package/src/resources/extensions/gsd/preferences-types.ts +2 -2
  328. package/src/resources/extensions/gsd/preferences.ts +18 -4
  329. package/src/resources/extensions/gsd/prompts/complete-milestone.md +2 -4
  330. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  331. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -6
  332. package/src/resources/extensions/gsd/prompts/replan-slice.md +3 -14
  333. package/src/resources/extensions/gsd/prompts/rethink.md +78 -0
  334. package/src/resources/extensions/gsd/prompts/validate-milestone.md +7 -37
  335. package/src/resources/extensions/gsd/provider-error-pause.ts +9 -0
  336. package/src/resources/extensions/gsd/repo-identity.ts +46 -7
  337. package/src/resources/extensions/gsd/rethink.ts +154 -0
  338. package/src/resources/extensions/gsd/state.ts +41 -1
  339. package/src/resources/extensions/gsd/tests/all-milestones-complete-merge.test.ts +99 -99
  340. package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +14 -16
  341. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +43 -57
  342. package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +88 -0
  343. package/src/resources/extensions/gsd/tests/auto-preflight.test.ts +11 -13
  344. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +465 -523
  345. package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +73 -75
  346. package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +34 -56
  347. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +533 -656
  348. package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +165 -143
  349. package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +29 -52
  350. package/src/resources/extensions/gsd/tests/captures.test.ts +148 -176
  351. package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +32 -33
  352. package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +141 -143
  353. package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +25 -25
  354. package/src/resources/extensions/gsd/tests/commands-logs.test.ts +81 -81
  355. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +38 -59
  356. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +228 -263
  357. package/src/resources/extensions/gsd/tests/complete-task.test.ts +250 -302
  358. package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +114 -0
  359. package/src/resources/extensions/gsd/tests/context-store.test.ts +354 -367
  360. package/src/resources/extensions/gsd/tests/continue-here.test.ts +68 -72
  361. package/src/resources/extensions/gsd/tests/cost-projection.test.ts +92 -106
  362. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +27 -35
  363. package/src/resources/extensions/gsd/tests/dashboard-budget.test.ts +220 -237
  364. package/src/resources/extensions/gsd/tests/db-writer.test.ts +465 -416
  365. package/src/resources/extensions/gsd/tests/definition-loader.test.ts +76 -92
  366. package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +68 -83
  367. package/src/resources/extensions/gsd/tests/derive-state-db-disk-reconcile.test.ts +121 -0
  368. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +210 -181
  369. package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +78 -101
  370. package/src/resources/extensions/gsd/tests/derive-state.test.ts +192 -227
  371. package/src/resources/extensions/gsd/tests/detection.test.ts +232 -278
  372. package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +30 -34
  373. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +164 -180
  374. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +43 -49
  375. package/src/resources/extensions/gsd/tests/dispatch-uat-last-completed.test.ts +28 -32
  376. package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +27 -29
  377. package/src/resources/extensions/gsd/tests/doctor-delimiter-fix.test.ts +34 -38
  378. package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +54 -75
  379. package/src/resources/extensions/gsd/tests/doctor-environment-worktree.test.ts +21 -32
  380. package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +72 -97
  381. package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +38 -44
  382. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +104 -145
  383. package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +84 -106
  384. package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +54 -60
  385. package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +72 -93
  386. package/src/resources/extensions/gsd/tests/doctor.test.ts +104 -134
  387. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +123 -131
  388. package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +120 -0
  389. package/src/resources/extensions/gsd/tests/exit-command.test.ts +20 -24
  390. package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +48 -57
  391. package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +5 -7
  392. package/src/resources/extensions/gsd/tests/flag-file-db.test.ts +30 -42
  393. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +198 -206
  394. package/src/resources/extensions/gsd/tests/git-locale.test.ts +13 -27
  395. package/src/resources/extensions/gsd/tests/git-service.test.ts +285 -388
  396. package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +31 -39
  397. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +63 -69
  398. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +255 -264
  399. package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +108 -119
  400. package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +81 -103
  401. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +229 -262
  402. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +13 -13
  403. package/src/resources/extensions/gsd/tests/health-widget.test.ts +29 -37
  404. package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +81 -102
  405. package/src/resources/extensions/gsd/tests/infra-error.test.ts +20 -2
  406. package/src/resources/extensions/gsd/tests/inherited-repo-home-dir.test.ts +121 -0
  407. package/src/resources/extensions/gsd/tests/init-wizard.test.ts +16 -18
  408. package/src/resources/extensions/gsd/tests/integration-edge.test.ts +41 -46
  409. package/src/resources/extensions/gsd/tests/integration-lifecycle.test.ts +42 -53
  410. package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +75 -91
  411. package/src/resources/extensions/gsd/tests/integration-proof.test.ts +18 -18
  412. package/src/resources/extensions/gsd/tests/knowledge.test.ts +89 -0
  413. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +150 -194
  414. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +103 -0
  415. package/src/resources/extensions/gsd/tests/md-importer.test.ts +101 -125
  416. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +45 -54
  417. package/src/resources/extensions/gsd/tests/memory-store.test.ts +80 -93
  418. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +66 -0
  419. package/src/resources/extensions/gsd/tests/migrate-command.test.ts +57 -66
  420. package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +83 -93
  421. package/src/resources/extensions/gsd/tests/migrate-parser.test.ts +161 -170
  422. package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +125 -141
  423. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +107 -131
  424. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +87 -96
  425. package/src/resources/extensions/gsd/tests/migrate-writer.test.ts +125 -164
  426. package/src/resources/extensions/gsd/tests/must-have-parser.test.ts +81 -94
  427. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +75 -37
  428. package/src/resources/extensions/gsd/tests/overrides.test.ts +99 -106
  429. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +40 -47
  430. package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +25 -28
  431. package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +66 -83
  432. package/src/resources/extensions/gsd/tests/park-edge-cases.test.ts +54 -77
  433. package/src/resources/extensions/gsd/tests/park-milestone.test.ts +68 -115
  434. package/src/resources/extensions/gsd/tests/parsers.test.ts +546 -611
  435. package/src/resources/extensions/gsd/tests/paths.test.ts +72 -87
  436. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +77 -117
  437. package/src/resources/extensions/gsd/tests/preferences.test.ts +34 -9
  438. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +11 -7
  439. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +56 -56
  440. package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +93 -119
  441. package/src/resources/extensions/gsd/tests/queue-order.test.ts +70 -82
  442. package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +42 -55
  443. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +100 -0
  444. package/src/resources/extensions/gsd/tests/quick-branch-lifecycle.test.ts +45 -73
  445. package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +28 -38
  446. package/src/resources/extensions/gsd/tests/recovery-attempts-reset.test.ts +176 -0
  447. package/src/resources/extensions/gsd/tests/replan-slice.test.ts +73 -80
  448. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +71 -74
  449. package/src/resources/extensions/gsd/tests/requirements.test.ts +70 -75
  450. package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +44 -66
  451. package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +114 -181
  452. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +63 -65
  453. package/src/resources/extensions/gsd/tests/run-uat.test.ts +66 -128
  454. package/src/resources/extensions/gsd/tests/session-lock-multipath.test.ts +18 -25
  455. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +37 -44
  456. package/src/resources/extensions/gsd/tests/shared-wal.test.ts +19 -26
  457. package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +63 -0
  458. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +6 -8
  459. package/src/resources/extensions/gsd/tests/stop-auto-merge-back.test.ts +67 -0
  460. package/src/resources/extensions/gsd/tests/survivor-branch-complete.test.ts +108 -0
  461. package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +22 -28
  462. package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +49 -0
  463. package/src/resources/extensions/gsd/tests/token-savings.test.ts +54 -56
  464. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +23 -25
  465. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +10 -11
  466. package/src/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +66 -82
  467. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +46 -47
  468. package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -22
  469. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -86
  470. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +41 -43
  471. package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +94 -96
  472. package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +11 -13
  473. package/src/resources/extensions/gsd/tests/worker-registry.test.ts +27 -29
  474. package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +275 -0
  475. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +50 -52
  476. package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +10 -13
  477. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +14 -18
  478. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +38 -39
  479. package/src/resources/extensions/gsd/tests/worktree-e2e.test.ts +17 -21
  480. package/src/resources/extensions/gsd/tests/worktree-health.test.ts +25 -30
  481. package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +30 -37
  482. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +220 -0
  483. package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +65 -0
  484. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +15 -22
  485. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +59 -66
  486. package/src/resources/extensions/gsd/tests/worktree.test.ts +44 -50
  487. package/src/resources/extensions/gsd/tools/plan-slice.ts +2 -0
  488. package/src/resources/extensions/gsd/tools/plan-task.ts +2 -0
  489. package/src/resources/extensions/gsd/tools/replan-slice.ts +3 -0
  490. package/src/resources/extensions/gsd/tools/validate-milestone.ts +127 -0
  491. package/src/resources/extensions/gsd/workflow-logger.ts +193 -0
  492. package/src/resources/extensions/gsd/worktree-manager.ts +41 -5
  493. package/src/resources/extensions/gsd/worktree-resolver.ts +44 -0
  494. package/src/resources/extensions/mcp-client/index.ts +20 -0
  495. package/src/resources/extensions/voice/index.ts +11 -21
  496. package/src/resources/extensions/voice/linux-ready.ts +87 -0
  497. package/src/resources/extensions/voice/tests/linux-ready.test.ts +124 -0
  498. package/dist/web/standalone/.next/static/chunks/4024.0de81b543b28b9fe.js +0 -9
  499. package/dist/web/standalone/.next/static/chunks/app/page-7e9530a7122506c5.js +0 -1
  500. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  501. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  502. package/dist/web/standalone/.next/static/chunks/webpack-9014b5adb127a98a.js +0 -1
  503. package/dist/web/standalone/.next/static/css/8a727f372cf53002.css +0 -1
  504. /package/dist/web/standalone/.next/static/{mgkxN0mGP6gSUmGPEzbk_ → dFMji9G1LZ-Tv36el9pRT}/_buildManifest.js +0 -0
  505. /package/dist/web/standalone/.next/static/{mgkxN0mGP6gSUmGPEzbk_ → dFMji9G1LZ-Tv36el9pRT}/_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
  ---
package/dist/help-text.js CHANGED
@@ -32,7 +32,7 @@ const SUBCOMMAND_HELP = {
32
32
  install: [
33
33
  'Usage: gsd install <source> [-l, --local]',
34
34
  '',
35
- 'Install a package/extension source and run declared lifecycle hooks.',
35
+ 'Install a package/extension source and run post-install validation (dependency checks, setup).',
36
36
  '',
37
37
  'Examples:',
38
38
  ' gsd install npm:@foo/bar',
package/dist/loader.js CHANGED
@@ -26,6 +26,40 @@ if (firstArg === '--help' || firstArg === '-h') {
26
26
  printHelp(gsdVersion);
27
27
  process.exit(0);
28
28
  }
29
+ // ---------------------------------------------------------------------------
30
+ // Runtime dependency checks — fail fast with clear diagnostics before any
31
+ // heavy imports. Reads minimum Node version from the engines field in
32
+ // package.json (already parsed above) and verifies git is available.
33
+ // ---------------------------------------------------------------------------
34
+ {
35
+ const MIN_NODE_MAJOR = 22;
36
+ const red = '\x1b[31m';
37
+ const bold = '\x1b[1m';
38
+ const dim = '\x1b[2m';
39
+ const reset = '\x1b[0m';
40
+ // -- Node version --
41
+ const nodeMajor = parseInt(process.versions.node.split('.')[0], 10);
42
+ if (nodeMajor < MIN_NODE_MAJOR) {
43
+ process.stderr.write(`\n${red}${bold}Error:${reset} GSD requires Node.js >= ${MIN_NODE_MAJOR}.0.0\n` +
44
+ ` You are running Node.js ${process.versions.node}\n\n` +
45
+ `${dim}Install a supported version:${reset}\n` +
46
+ ` nvm install ${MIN_NODE_MAJOR} ${dim}# if using nvm${reset}\n` +
47
+ ` fnm install ${MIN_NODE_MAJOR} ${dim}# if using fnm${reset}\n` +
48
+ ` brew install node@${MIN_NODE_MAJOR} ${dim}# macOS Homebrew${reset}\n\n`);
49
+ process.exit(1);
50
+ }
51
+ // -- git --
52
+ try {
53
+ const { execFileSync } = await import('child_process');
54
+ execFileSync('git', ['--version'], { stdio: 'ignore' });
55
+ }
56
+ catch {
57
+ process.stderr.write(`\n${red}${bold}Error:${reset} GSD requires git but it was not found on PATH.\n\n` +
58
+ `${dim}Install git:${reset}\n` +
59
+ ` https://git-scm.com/downloads\n\n`);
60
+ process.exit(1);
61
+ }
62
+ }
29
63
  import { agentDir, appRoot } from './app-paths.js';
30
64
  import { serializeBundledExtensionPaths } from './bundled-extension-paths.js';
31
65
  import { discoverExtensionEntryPaths } from './extension-discovery.js';
@@ -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,10 @@ 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";
20
+ import { logWarning } from "../workflow-logger.js";
18
21
  // ─── generateMilestoneReport ──────────────────────────────────────────────────
19
22
  /**
20
23
  * Generate and write an HTML milestone report snapshot.
@@ -100,8 +103,8 @@ export async function runPreDispatch(ic, loopState) {
100
103
  return { action: "break", reason: "health-gate-failed" };
101
104
  }
102
105
  }
103
- catch {
104
- // Non-fatal
106
+ catch (e) {
107
+ logWarning("engine", "Pre-dispatch health gate threw unexpectedly", { error: String(e) });
105
108
  }
106
109
  // Sync project root artifacts into worktree
107
110
  if (s.originalBasePath &&
@@ -145,20 +148,20 @@ export async function runPreDispatch(ic, loopState) {
145
148
  loopState.recentUnits.length = 0;
146
149
  loopState.stuckRecoveryAttempts = 0;
147
150
  // 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
151
+ try {
152
+ deps.resolver.mergeAndExit(s.currentMilestoneId, ctx.ui);
153
+ }
154
+ catch (mergeErr) {
155
+ if (mergeErr instanceof MergeConflictError) {
156
+ // Real code conflicts stop the loop instead of retrying forever (#2330)
157
+ ctx.ui.notify(`Merge conflict: ${mergeErr.conflictedFiles.join(", ")}. Resolve conflicts manually and run /gsd auto to resume.`, "error");
158
+ await deps.stopAuto(ctx, pi, `Merge conflict on milestone ${s.currentMilestoneId}`);
159
+ return { action: "break", reason: "merge-conflict" };
160
160
  }
161
+ // Non-conflict merge errors — log and continue
162
+ logWarning("engine", "Milestone merge failed with non-conflict error", { milestone: s.currentMilestoneId, error: String(mergeErr) });
161
163
  }
164
+ // PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
162
165
  deps.invalidateAllCaches();
163
166
  state = await deps.deriveState(s.basePath);
164
167
  mid = state.activeMilestone?.id;
@@ -179,12 +182,19 @@ export async function runPreDispatch(ic, loopState) {
179
182
  // Reset completed-units tracking for the new milestone — stale entries
180
183
  // from the previous milestone cause the dispatch loop to skip units
181
184
  // that haven't actually been completed in the new milestone's context.
185
+ // Archive the old completed-units.json instead of wiping it (#2313).
182
186
  s.completedUnits = [];
183
187
  try {
184
188
  const completedKeysPath = join(gsdRoot(s.basePath), "completed-units.json");
189
+ if (existsSync(completedKeysPath) && s.currentMilestoneId) {
190
+ const archivePath = join(gsdRoot(s.basePath), `completed-units-${s.currentMilestoneId}.json`);
191
+ cpSync(completedKeysPath, archivePath);
192
+ }
185
193
  atomicWriteSync(completedKeysPath, JSON.stringify([], null, 2));
186
194
  }
187
- catch { /* non-fatal */ }
195
+ catch (e) {
196
+ logWarning("engine", "Failed to archive completed-units on milestone transition", { error: String(e) });
197
+ }
188
198
  // Rebuild STATE.md immediately so it reflects the new active milestone.
189
199
  // This bypasses the 30-second throttle in the normal rebuild path —
190
200
  // milestone transitions are rare and important enough to warrant an
@@ -192,8 +202,8 @@ export async function runPreDispatch(ic, loopState) {
192
202
  try {
193
203
  await deps.rebuildState(s.basePath);
194
204
  }
195
- catch {
196
- // Non-fatal — STATE.md will be rebuilt on the next regular cycle
205
+ catch (e) {
206
+ logWarning("engine", "STATE.md rebuild failed after milestone transition", { error: String(e) });
197
207
  }
198
208
  }
199
209
  if (mid) {
@@ -209,20 +219,17 @@ export async function runPreDispatch(ic, loopState) {
209
219
  if (incomplete.length === 0 && state.registry.length > 0) {
210
220
  // All milestones complete — merge milestone branch before stopping
211
221
  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
222
+ try {
223
+ deps.resolver.mergeAndExit(s.currentMilestoneId, ctx.ui);
224
+ }
225
+ catch (mergeErr) {
226
+ if (mergeErr instanceof MergeConflictError) {
227
+ ctx.ui.notify(`Merge conflict: ${mergeErr.conflictedFiles.join(", ")}. Resolve conflicts manually and run /gsd auto to resume.`, "error");
228
+ await deps.stopAuto(ctx, pi, `Merge conflict on milestone ${s.currentMilestoneId}`);
229
+ return { action: "break", reason: "merge-conflict" };
224
230
  }
225
231
  }
232
+ // PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
226
233
  }
227
234
  deps.sendDesktopNotification("GSD", "All milestones complete!", "success", "milestone");
228
235
  deps.logCmuxEvent(prefs, "All milestones complete.", "success");
@@ -277,20 +284,17 @@ export async function runPreDispatch(ic, loopState) {
277
284
  if (state.phase === "complete") {
278
285
  // Milestone merge on complete (before closeout so branch state is clean)
279
286
  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
287
+ try {
288
+ deps.resolver.mergeAndExit(s.currentMilestoneId, ctx.ui);
289
+ }
290
+ catch (mergeErr) {
291
+ if (mergeErr instanceof MergeConflictError) {
292
+ ctx.ui.notify(`Merge conflict: ${mergeErr.conflictedFiles.join(", ")}. Resolve conflicts manually and run /gsd auto to resume.`, "error");
293
+ await deps.stopAuto(ctx, pi, `Merge conflict on milestone ${s.currentMilestoneId}`);
294
+ return { action: "break", reason: "merge-conflict" };
292
295
  }
293
296
  }
297
+ // PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
294
298
  }
295
299
  deps.sendDesktopNotification("GSD", `Milestone ${mid} complete!`, "success", "milestone");
296
300
  deps.logCmuxEvent(prefs, `Milestone ${mid} complete.`, "success");
@@ -591,6 +595,7 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
591
595
  lastProgressAt: s.currentUnit.startedAt,
592
596
  progressCount: 0,
593
597
  lastProgressKind: "dispatch",
598
+ recoveryAttempts: 0, // Reset so re-dispatched units get full recovery budget (#2322)
594
599
  });
595
600
  // Status bar + progress widget
596
601
  ctx.ui.setStatus("gsd-auto", "auto");
@@ -643,8 +648,8 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
643
648
  (requirementsContent?.length ?? 0) +
644
649
  (projectContent?.length ?? 0);
645
650
  }
646
- catch {
647
- // Non-fatal
651
+ catch (e) {
652
+ logWarning("engine", "Baseline char count measurement failed", { error: String(e) });
648
653
  }
649
654
  }
650
655
  // Cache-optimize prompt section ordering
@@ -653,7 +658,7 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
653
658
  }
654
659
  catch (reorderErr) {
655
660
  const msg = reorderErr instanceof Error ? reorderErr.message : String(reorderErr);
656
- process.stderr.write(`[gsd] prompt reorder failed (non-fatal): ${msg}\n`);
661
+ logWarning("engine", "Prompt reorder failed", { error: msg });
657
662
  }
658
663
  // Select and apply model (with tier escalation on retry — normal units only)
659
664
  const modelResult = await deps.selectAndApplyModel(ctx, pi, unitType, unitId, s.basePath, prefs, s.verbose, s.autoModeStartModel, sidecarItem ? undefined : { isRetry, previousTier });
@@ -788,7 +793,9 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
788
793
  const keys = s.completedUnits.map((u) => `${u.type}/${u.id}`);
789
794
  atomicWriteSync(completedKeysPath, JSON.stringify(keys, null, 2));
790
795
  }
791
- catch { /* non-fatal: disk flush failure */ }
796
+ catch (e) {
797
+ logWarning("engine", "Failed to flush completed-units to disk", { error: String(e) });
798
+ }
792
799
  deps.clearUnitRuntimeRecord(s.basePath, unitType, unitId);
793
800
  s.unitDispatchCount.delete(`${unitType}/${unitId}`);
794
801
  s.unitRecoveryCount.delete(`${unitType}/${unitId}`);
@@ -6,6 +6,7 @@
6
6
  import { NEW_SESSION_TIMEOUT_MS } from "./session.js";
7
7
  import { _setCurrentResolve, _setSessionSwitchInFlight } from "./resolve.js";
8
8
  import { debugLog } from "../debug-logger.js";
9
+ import { logWarning } from "../workflow-logger.js";
9
10
  /**
10
11
  * Execute a single unit: create a new session, send the prompt, and await
11
12
  * the agent_end promise. Returns a UnitResult describing what happened.
@@ -66,7 +67,9 @@ export async function runUnit(ctx, pi, s, unitType, unitId, prompt) {
66
67
  process.chdir(s.basePath);
67
68
  }
68
69
  }
69
- catch { /* non-fatal — chdir may fail if dir was removed */ }
70
+ catch (e) {
71
+ logWarning("engine", "Failed to chdir to basePath before dispatch", { basePath: s.basePath, error: String(e) });
72
+ }
70
73
  // ── Send the prompt ──
71
74
  debugLog("runUnit", { phase: "send-message", unitType, unitId });
72
75
  pi.sendMessage({ customType: "gsd-auto", content: prompt, display: s.verbose }, { triggerTurn: true });
@@ -90,8 +93,8 @@ export async function runUnit(ctx, pi, s, unitType, unitId, prompt) {
90
93
  cmdCtxAny.clearQueue();
91
94
  }
92
95
  }
93
- catch {
94
- // Non-fatal clearQueue may not be available in all contexts
96
+ catch (e) {
97
+ logWarning("engine", "clearQueue failed after unit completion", { error: String(e) });
95
98
  }
96
99
  return result;
97
100
  }
@@ -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,