gsd-pi 2.43.0-next.8 → 2.44.0-dev.0b97ffd

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 (399) hide show
  1. package/README.md +30 -12
  2. package/dist/cli.js +13 -1
  3. package/dist/help-text.js +24 -0
  4. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +21 -8
  5. package/dist/resources/extensions/gsd/auto-prompts.js +130 -51
  6. package/dist/resources/extensions/gsd/auto-start.js +10 -0
  7. package/dist/resources/extensions/gsd/auto-worktree.js +16 -2
  8. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +5 -0
  9. package/dist/resources/extensions/gsd/dispatch-guard.js +34 -10
  10. package/dist/resources/extensions/gsd/markdown-renderer.js +7 -5
  11. package/dist/resources/extensions/gsd/reactive-graph.js +13 -2
  12. package/dist/resources/extensions/gsd/skill-health.js +3 -1
  13. package/dist/resources/extensions/gsd/tools/plan-milestone.js +2 -11
  14. package/dist/resources/extensions/gsd/tools/plan-slice.js +2 -10
  15. package/dist/resources/extensions/gsd/visualizer-data.js +45 -13
  16. package/dist/resources/extensions/gsd/workspace-index.js +46 -15
  17. package/dist/web/standalone/.next/BUILD_ID +1 -1
  18. package/dist/web/standalone/.next/app-path-routes-manifest.json +18 -18
  19. package/dist/web/standalone/.next/build-manifest.json +3 -3
  20. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  21. package/dist/web/standalone/.next/required-server-files.json +4 -4
  22. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  23. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  24. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  25. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  26. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  27. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  28. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  29. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  30. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  31. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  32. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  33. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  34. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  35. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  36. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  37. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  38. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  39. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  40. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  41. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  42. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  43. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  44. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  45. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  46. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  47. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  48. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  49. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  50. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  51. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  52. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  53. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  54. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  55. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  56. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  57. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  58. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  59. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  60. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  61. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  62. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  63. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  64. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  65. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  66. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  67. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  68. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  69. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  70. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  71. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  72. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  73. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  74. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  75. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  76. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  77. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  78. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  79. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  80. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  81. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  82. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  83. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  84. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  85. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  86. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +5 -5
  87. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  88. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  89. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  90. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  91. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  92. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  93. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  94. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  95. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  96. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  97. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  98. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  99. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  100. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  101. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  102. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  103. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  104. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  105. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  106. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  107. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  108. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  109. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  110. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  111. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  113. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  122. package/dist/web/standalone/.next/server/app/index.html +1 -1
  123. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  124. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  125. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  126. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  128. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/page.js +2 -2
  130. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app-paths-manifest.json +18 -18
  132. package/dist/web/standalone/.next/server/chunks/229.js +1 -1
  133. package/dist/web/standalone/.next/server/chunks/471.js +3 -3
  134. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/middleware.js +2 -2
  136. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  138. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  139. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  140. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  141. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-f2a7482d42a5614b.js +1 -0
  142. package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +1 -0
  143. package/dist/web/standalone/.next/static/chunks/app/page-b9367c5ae13b99c6.js +1 -0
  144. package/dist/web/standalone/.next/static/chunks/{main-app-2f2ee7b85712c2bd.js → main-app-fdab67f7802d7832.js} +1 -1
  145. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  146. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  147. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  148. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  149. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  150. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  151. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  152. package/dist/web/standalone/server.js +1 -1
  153. package/package.json +4 -4
  154. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +3 -3
  155. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  156. package/packages/pi-coding-agent/dist/core/agent-session.js +11 -34
  157. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  158. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +6 -8
  159. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  160. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.d.ts +2 -2
  161. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  162. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.js.map +1 -1
  163. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +2 -2
  164. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  165. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  166. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +4 -4
  167. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -1
  168. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +1 -1
  169. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  170. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  171. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  172. package/packages/pi-coding-agent/dist/core/extensions/loader.js +18 -0
  173. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  174. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +24 -26
  175. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  176. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +37 -0
  177. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  178. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  179. package/packages/pi-coding-agent/dist/core/fallback-resolver.d.ts.map +1 -1
  180. package/packages/pi-coding-agent/dist/core/fallback-resolver.js +2 -3
  181. package/packages/pi-coding-agent/dist/core/fallback-resolver.js.map +1 -1
  182. package/packages/pi-coding-agent/dist/core/fallback-resolver.test.js +12 -2
  183. package/packages/pi-coding-agent/dist/core/fallback-resolver.test.js.map +1 -1
  184. package/packages/pi-coding-agent/dist/core/fs-utils.test.js +29 -48
  185. package/packages/pi-coding-agent/dist/core/fs-utils.test.js.map +1 -1
  186. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.d.ts +38 -0
  187. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.d.ts.map +1 -0
  188. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.js +192 -0
  189. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.js.map +1 -0
  190. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.d.ts +2 -0
  191. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.d.ts.map +1 -0
  192. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +255 -0
  193. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -0
  194. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +15 -0
  195. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  196. package/packages/pi-coding-agent/dist/core/model-registry.js +40 -3
  197. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  198. package/packages/pi-coding-agent/dist/core/package-commands.d.ts +25 -0
  199. package/packages/pi-coding-agent/dist/core/package-commands.d.ts.map +1 -0
  200. package/packages/pi-coding-agent/dist/core/package-commands.js +253 -0
  201. package/packages/pi-coding-agent/dist/core/package-commands.js.map +1 -0
  202. package/packages/pi-coding-agent/dist/core/package-commands.test.d.ts +2 -0
  203. package/packages/pi-coding-agent/dist/core/package-commands.test.d.ts.map +1 -0
  204. package/packages/pi-coding-agent/dist/core/package-commands.test.js +225 -0
  205. package/packages/pi-coding-agent/dist/core/package-commands.test.js.map +1 -0
  206. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +34 -44
  207. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
  208. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  209. package/packages/pi-coding-agent/dist/core/sdk.js +4 -0
  210. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  211. package/packages/pi-coding-agent/dist/core/session-manager.test.js +30 -34
  212. package/packages/pi-coding-agent/dist/core/session-manager.test.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/index.d.ts +3 -1
  216. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  217. package/packages/pi-coding-agent/dist/index.js +1 -0
  218. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  219. package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
  220. package/packages/pi-coding-agent/dist/main.js +11 -199
  221. package/packages/pi-coding-agent/dist/main.js.map +1 -1
  222. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js +43 -47
  223. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js.map +1 -1
  224. package/packages/pi-coding-agent/package.json +1 -1
  225. package/packages/pi-coding-agent/src/core/agent-session.ts +13 -37
  226. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +7 -7
  227. package/packages/pi-coding-agent/src/core/compaction/branch-summarization.ts +2 -2
  228. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +3 -3
  229. package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +4 -4
  230. package/packages/pi-coding-agent/src/core/extensions/index.ts +5 -0
  231. package/packages/pi-coding-agent/src/core/extensions/loader.ts +23 -0
  232. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +26 -26
  233. package/packages/pi-coding-agent/src/core/extensions/types.ts +44 -0
  234. package/packages/pi-coding-agent/src/core/fallback-resolver.test.ts +15 -2
  235. package/packages/pi-coding-agent/src/core/fallback-resolver.ts +2 -3
  236. package/packages/pi-coding-agent/src/core/fs-utils.test.ts +31 -43
  237. package/packages/pi-coding-agent/src/core/lifecycle-hooks.ts +274 -0
  238. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +288 -0
  239. package/packages/pi-coding-agent/src/core/model-registry.ts +39 -3
  240. package/packages/pi-coding-agent/src/core/package-commands.test.ts +240 -0
  241. package/packages/pi-coding-agent/src/core/package-commands.ts +310 -0
  242. package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +40 -45
  243. package/packages/pi-coding-agent/src/core/sdk.ts +4 -0
  244. package/packages/pi-coding-agent/src/core/session-manager.test.ts +33 -33
  245. package/packages/pi-coding-agent/src/core/tools/edit-diff.test.ts +17 -17
  246. package/packages/pi-coding-agent/src/index.ts +7 -0
  247. package/packages/pi-coding-agent/src/main.ts +11 -232
  248. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.test.ts +74 -74
  249. package/pkg/package.json +1 -1
  250. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +22 -7
  251. package/src/resources/extensions/gsd/auto-prompts.ts +109 -42
  252. package/src/resources/extensions/gsd/auto-start.ts +14 -0
  253. package/src/resources/extensions/gsd/auto-worktree.ts +16 -3
  254. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +8 -0
  255. package/src/resources/extensions/gsd/dispatch-guard.ts +28 -10
  256. package/src/resources/extensions/gsd/markdown-renderer.ts +7 -5
  257. package/src/resources/extensions/gsd/reactive-graph.ts +12 -2
  258. package/src/resources/extensions/gsd/skill-health.ts +2 -1
  259. package/src/resources/extensions/gsd/tests/all-milestones-complete-merge.test.ts +99 -99
  260. package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +14 -16
  261. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +43 -57
  262. package/src/resources/extensions/gsd/tests/auto-preflight.test.ts +11 -13
  263. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +465 -523
  264. package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +73 -75
  265. package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +34 -56
  266. package/src/resources/extensions/gsd/tests/auto-stash-merge.test.ts +3 -3
  267. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +533 -656
  268. package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +165 -143
  269. package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +29 -52
  270. package/src/resources/extensions/gsd/tests/captures.test.ts +148 -176
  271. package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +32 -33
  272. package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +141 -143
  273. package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +25 -25
  274. package/src/resources/extensions/gsd/tests/commands-logs.test.ts +81 -81
  275. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +38 -59
  276. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +228 -263
  277. package/src/resources/extensions/gsd/tests/complete-task.test.ts +250 -302
  278. package/src/resources/extensions/gsd/tests/context-store.test.ts +354 -367
  279. package/src/resources/extensions/gsd/tests/continue-here.test.ts +68 -72
  280. package/src/resources/extensions/gsd/tests/cost-projection.test.ts +92 -106
  281. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +27 -35
  282. package/src/resources/extensions/gsd/tests/dashboard-budget.test.ts +220 -237
  283. package/src/resources/extensions/gsd/tests/db-writer.test.ts +390 -420
  284. package/src/resources/extensions/gsd/tests/definition-loader.test.ts +76 -92
  285. package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +68 -83
  286. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +152 -183
  287. package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +78 -101
  288. package/src/resources/extensions/gsd/tests/derive-state.test.ts +192 -227
  289. package/src/resources/extensions/gsd/tests/detection.test.ts +232 -278
  290. package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +30 -34
  291. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +164 -180
  292. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +43 -49
  293. package/src/resources/extensions/gsd/tests/dispatch-uat-last-completed.test.ts +28 -32
  294. package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +27 -29
  295. package/src/resources/extensions/gsd/tests/doctor-delimiter-fix.test.ts +34 -38
  296. package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +54 -75
  297. package/src/resources/extensions/gsd/tests/doctor-environment-worktree.test.ts +21 -32
  298. package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +72 -97
  299. package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +38 -44
  300. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +104 -145
  301. package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +84 -106
  302. package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +54 -60
  303. package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +72 -93
  304. package/src/resources/extensions/gsd/tests/doctor.test.ts +104 -134
  305. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +123 -131
  306. package/src/resources/extensions/gsd/tests/exit-command.test.ts +20 -24
  307. package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +48 -57
  308. package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +5 -7
  309. package/src/resources/extensions/gsd/tests/flag-file-db.test.ts +30 -42
  310. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +198 -206
  311. package/src/resources/extensions/gsd/tests/git-locale.test.ts +13 -27
  312. package/src/resources/extensions/gsd/tests/git-service.test.ts +285 -388
  313. package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +31 -39
  314. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +63 -69
  315. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +255 -264
  316. package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +108 -119
  317. package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +81 -103
  318. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +229 -262
  319. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +13 -13
  320. package/src/resources/extensions/gsd/tests/health-widget.test.ts +29 -37
  321. package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +81 -102
  322. package/src/resources/extensions/gsd/tests/init-wizard.test.ts +16 -18
  323. package/src/resources/extensions/gsd/tests/integration-edge.test.ts +41 -46
  324. package/src/resources/extensions/gsd/tests/integration-lifecycle.test.ts +42 -53
  325. package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +75 -91
  326. package/src/resources/extensions/gsd/tests/integration-proof.test.ts +18 -18
  327. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +150 -194
  328. package/src/resources/extensions/gsd/tests/md-importer.test.ts +101 -125
  329. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +45 -54
  330. package/src/resources/extensions/gsd/tests/memory-store.test.ts +80 -93
  331. package/src/resources/extensions/gsd/tests/migrate-command.test.ts +57 -66
  332. package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +83 -93
  333. package/src/resources/extensions/gsd/tests/migrate-parser.test.ts +161 -170
  334. package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +125 -141
  335. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +107 -131
  336. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +87 -96
  337. package/src/resources/extensions/gsd/tests/migrate-writer.test.ts +125 -164
  338. package/src/resources/extensions/gsd/tests/must-have-parser.test.ts +81 -94
  339. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +35 -36
  340. package/src/resources/extensions/gsd/tests/overrides.test.ts +99 -106
  341. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +40 -47
  342. package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +25 -28
  343. package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +66 -83
  344. package/src/resources/extensions/gsd/tests/park-edge-cases.test.ts +54 -77
  345. package/src/resources/extensions/gsd/tests/park-milestone.test.ts +68 -115
  346. package/src/resources/extensions/gsd/tests/parsers.test.ts +546 -611
  347. package/src/resources/extensions/gsd/tests/paths.test.ts +72 -87
  348. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +77 -117
  349. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +56 -56
  350. package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +93 -119
  351. package/src/resources/extensions/gsd/tests/queue-order.test.ts +70 -82
  352. package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +42 -55
  353. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +100 -0
  354. package/src/resources/extensions/gsd/tests/quick-branch-lifecycle.test.ts +45 -73
  355. package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +28 -38
  356. package/src/resources/extensions/gsd/tests/replan-slice.test.ts +73 -80
  357. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +71 -74
  358. package/src/resources/extensions/gsd/tests/requirements.test.ts +70 -75
  359. package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +44 -66
  360. package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +114 -181
  361. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +63 -65
  362. package/src/resources/extensions/gsd/tests/run-uat.test.ts +66 -128
  363. package/src/resources/extensions/gsd/tests/session-lock-multipath.test.ts +18 -25
  364. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +37 -44
  365. package/src/resources/extensions/gsd/tests/shared-wal.test.ts +19 -26
  366. package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +63 -0
  367. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +6 -8
  368. package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +22 -28
  369. package/src/resources/extensions/gsd/tests/token-savings.test.ts +54 -56
  370. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +23 -25
  371. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +9 -11
  372. package/src/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +66 -82
  373. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +46 -47
  374. package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -22
  375. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -86
  376. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +41 -43
  377. package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +94 -96
  378. package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +11 -13
  379. package/src/resources/extensions/gsd/tests/worker-registry.test.ts +27 -29
  380. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +50 -52
  381. package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +10 -13
  382. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +14 -18
  383. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +38 -39
  384. package/src/resources/extensions/gsd/tests/worktree-e2e.test.ts +17 -21
  385. package/src/resources/extensions/gsd/tests/worktree-health.test.ts +25 -30
  386. package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +30 -37
  387. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +15 -22
  388. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +59 -66
  389. package/src/resources/extensions/gsd/tests/worktree.test.ts +44 -50
  390. package/src/resources/extensions/gsd/tools/plan-milestone.ts +1 -18
  391. package/src/resources/extensions/gsd/tools/plan-slice.ts +1 -15
  392. package/src/resources/extensions/gsd/visualizer-data.ts +46 -14
  393. package/src/resources/extensions/gsd/workspace-index.ts +49 -18
  394. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-e07acdb7dd069836.js +0 -1
  395. package/dist/web/standalone/.next/static/chunks/app/layout-745c6ed5fea5fb06.js +0 -1
  396. package/dist/web/standalone/.next/static/chunks/app/page-801b53eff6e83579.js +0 -1
  397. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-e6255954dccfcf0a.js +0 -1
  398. /package/dist/web/standalone/.next/static/{drUWS0zys9uepCfCwecJv → alS4hoANx0TK4UVZY27da}/_buildManifest.js +0 -0
  399. /package/dist/web/standalone/.next/static/{drUWS0zys9uepCfCwecJv → alS4hoANx0TK4UVZY27da}/_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/cli.js CHANGED
@@ -1,4 +1,4 @@
1
- import { AuthStorage, DefaultResourceLoader, ModelRegistry, SettingsManager, SessionManager, createAgentSession, InteractiveMode, runPrintMode, runRpcMode, } from '@gsd/pi-coding-agent';
1
+ import { AuthStorage, DefaultResourceLoader, ModelRegistry, runPackageCommand, SettingsManager, SessionManager, createAgentSession, InteractiveMode, runPrintMode, runRpcMode, } from '@gsd/pi-coding-agent';
2
2
  import { readFileSync } from 'node:fs';
3
3
  import { join } from 'node:path';
4
4
  import { agentDir, sessionsDir, authFilePath } from './app-paths.js';
@@ -121,6 +121,18 @@ if (subcommand && process.argv.includes('--help')) {
121
121
  process.exit(0);
122
122
  }
123
123
  }
124
+ const packageCommand = await runPackageCommand({
125
+ appName: 'gsd',
126
+ args: process.argv.slice(2),
127
+ cwd: process.cwd(),
128
+ agentDir,
129
+ stdout: process.stdout,
130
+ stderr: process.stderr,
131
+ allowedCommands: new Set(['install', 'remove', 'list']),
132
+ });
133
+ if (packageCommand.handled) {
134
+ process.exit(packageCommand.exitCode);
135
+ }
124
136
  // `gsd config` — replay the setup wizard and exit
125
137
  if (cliFlags.messages[0] === 'config') {
126
138
  const authStorage = AuthStorage.create(authFilePath);
package/dist/help-text.js CHANGED
@@ -29,6 +29,27 @@ const SUBCOMMAND_HELP = {
29
29
  '',
30
30
  'Compare with --continue (-c) which always resumes the most recent session.',
31
31
  ].join('\n'),
32
+ install: [
33
+ 'Usage: gsd install <source> [-l, --local]',
34
+ '',
35
+ 'Install a package/extension source and run declared lifecycle hooks.',
36
+ '',
37
+ 'Examples:',
38
+ ' gsd install npm:@foo/bar',
39
+ ' gsd install git:github.com/user/repo',
40
+ ' gsd install https://github.com/user/repo',
41
+ ' gsd install ./local/path',
42
+ ].join('\n'),
43
+ remove: [
44
+ 'Usage: gsd remove <source> [-l, --local]',
45
+ '',
46
+ 'Remove an installed package source and its settings entry.',
47
+ ].join('\n'),
48
+ list: [
49
+ 'Usage: gsd list',
50
+ '',
51
+ 'List installed package sources from user and project settings.',
52
+ ].join('\n'),
32
53
  worktree: [
33
54
  'Usage: gsd worktree <command> [args]',
34
55
  '',
@@ -122,6 +143,9 @@ export function printHelp(version) {
122
143
  process.stdout.write(' --help, -h Print this help and exit\n');
123
144
  process.stdout.write('\nSubcommands:\n');
124
145
  process.stdout.write(' config Re-run the setup wizard\n');
146
+ process.stdout.write(' install <source> Install a package/extension source\n');
147
+ process.stdout.write(' remove <source> Remove an installed package source\n');
148
+ process.stdout.write(' list List installed package sources\n');
125
149
  process.stdout.write(' update Update GSD to the latest version\n');
126
150
  process.stdout.write(' sessions List and resume a past session\n');
127
151
  process.stdout.write(' worktree <cmd> Manage worktrees (list, merge, clean, remove)\n');
@@ -5,7 +5,8 @@
5
5
  import { deriveState } from "./state.js";
6
6
  import { loadFile } from "./files.js";
7
7
  import { isDbAvailable, getMilestoneSlices } from "./gsd-db.js";
8
- import { resolveSliceFile, relSliceFile, } from "./paths.js";
8
+ import { parseRoadmap } from "./parsers-legacy.js";
9
+ import { resolveMilestoneFile, resolveSliceFile, relSliceFile, } from "./paths.js";
9
10
  import { buildResearchSlicePrompt, buildResearchMilestonePrompt, buildPlanSlicePrompt, buildPlanMilestonePrompt, buildExecuteTaskPrompt, buildCompleteSlicePrompt, buildCompleteMilestonePrompt, buildReassessRoadmapPrompt, buildRunUatPrompt, buildReplanSlicePrompt, } from "./auto-prompts.js";
10
11
  import { loadEffectiveGSDPreferences } from "./preferences.js";
11
12
  import { pauseAuto } from "./auto.js";
@@ -118,14 +119,20 @@ export async function dispatchDirectPhase(ctx, pi, phase, base) {
118
119
  }
119
120
  case "reassess":
120
121
  case "reassess-roadmap": {
121
- // DB primary path — get completed slices
122
+ // DB primary path — get completed slices, fall back to file parsing when DB has no data
122
123
  let completedSliceIds = [];
123
124
  if (isDbAvailable()) {
124
125
  completedSliceIds = getMilestoneSlices(mid).filter(s => s.status === "complete").map(s => s.id);
125
126
  }
126
- else {
127
- ctx.ui.notify("Cannot dispatch reassess-roadmap: DB unavailable.", "warning");
128
- return;
127
+ if (completedSliceIds.length === 0) {
128
+ // File-based fallback: parse roadmap checkboxes
129
+ const roadmapPath = resolveMilestoneFile(base, mid, "ROADMAP");
130
+ if (roadmapPath) {
131
+ const roadmapContent = await loadFile(roadmapPath);
132
+ if (roadmapContent) {
133
+ completedSliceIds = parseRoadmap(roadmapContent).slices.filter(s => s.done).map(s => s.id);
134
+ }
135
+ }
129
136
  }
130
137
  if (completedSliceIds.length === 0) {
131
138
  ctx.ui.notify("Cannot dispatch reassess-roadmap: no completed slices.", "warning");
@@ -147,9 +154,15 @@ export async function dispatchDirectPhase(ctx, pi, phase, base) {
147
154
  if (isDbAvailable()) {
148
155
  uatCompletedSliceIds = getMilestoneSlices(mid).filter(s => s.status === "complete").map(s => s.id);
149
156
  }
150
- else {
151
- ctx.ui.notify("Cannot dispatch run-uat: DB unavailable.", "warning");
152
- return;
157
+ if (uatCompletedSliceIds.length === 0) {
158
+ // File-based fallback: parse roadmap checkboxes
159
+ const roadmapPath = resolveMilestoneFile(base, mid, "ROADMAP");
160
+ if (roadmapPath) {
161
+ const roadmapContent = await loadFile(roadmapPath);
162
+ if (roadmapContent) {
163
+ uatCompletedSliceIds = parseRoadmap(roadmapContent).slices.filter(s => s.done).map(s => s.id);
164
+ }
165
+ }
153
166
  }
154
167
  if (uatCompletedSliceIds.length === 0) {
155
168
  ctx.ui.notify("Cannot dispatch run-uat: no completed slices.", "warning");
@@ -9,6 +9,7 @@ import { loadFile, parseContinue, parseSummary, extractUatType, loadActiveOverri
9
9
  import { loadPrompt, inlineTemplate } from "./prompt-loader.js";
10
10
  import { resolveMilestoneFile, resolveSliceFile, resolveSlicePath, resolveTasksDir, resolveTaskFiles, resolveTaskFile, relMilestoneFile, relSliceFile, relSlicePath, relMilestonePath, resolveGsdRootFile, relGsdRootFile, resolveRuntimeFile, } from "./paths.js";
11
11
  import { resolveSkillDiscoveryMode, resolveInlineLevel, loadEffectiveGSDPreferences, resolveAllSkillReferences } from "./preferences.js";
12
+ import { parseRoadmap } from "./parsers-legacy.js";
12
13
  import { getLoadedSkills } from "@gsd/pi-coding-agent";
13
14
  import { join, basename } from "node:path";
14
15
  import { existsSync } from "node:fs";
@@ -145,15 +146,31 @@ export async function inlineDependencySummaries(mid, sid, base, budgetChars) {
145
146
  const { isDbAvailable, getSlice } = await import("./gsd-db.js");
146
147
  if (isDbAvailable()) {
147
148
  const slice = getSlice(mid, sid);
148
- if (!slice || slice.depends.length === 0)
149
- return "- (no dependencies)";
150
- depends = slice.depends;
149
+ if (slice) {
150
+ if (slice.depends.length === 0)
151
+ return "- (no dependencies)";
152
+ depends = slice.depends;
153
+ }
154
+ // If slice not found in DB, fall through to file-based parsing
151
155
  }
152
156
  }
153
157
  catch { /* fall through */ }
154
- // If DB didn't provide depends, we can't determine them without parsers
158
+ // If DB didn't provide depends, fall back to roadmap parsing
155
159
  if (!depends) {
156
- return "- (no dependencies)";
160
+ const roadmapPath = resolveMilestoneFile(base, mid, "ROADMAP");
161
+ if (roadmapPath) {
162
+ const roadmapContent = await loadFile(roadmapPath);
163
+ if (roadmapContent) {
164
+ const parsed = parseRoadmap(roadmapContent);
165
+ const slice = parsed.slices.find(s => s.id === sid);
166
+ if (slice && slice.depends.length > 0) {
167
+ depends = slice.depends;
168
+ }
169
+ }
170
+ }
171
+ if (!depends) {
172
+ return "- (no dependencies)";
173
+ }
157
174
  }
158
175
  const sections = [];
159
176
  const seen = new Set();
@@ -565,32 +582,52 @@ export async function getDependencyTaskSummaryPaths(mid, sid, currentTid, depend
565
582
  * - All slices are complete (milestone done — no point reassessing)
566
583
  */
567
584
  export async function checkNeedsReassessment(base, mid, state) {
568
- // DB primary path
569
- let completedSliceIds = [];
570
- let hasIncomplete = false;
585
+ // DB primary path — fall through to file-based when DB has no data for this milestone
571
586
  try {
572
587
  const { isDbAvailable, getMilestoneSlices } = await import("./gsd-db.js");
573
588
  if (isDbAvailable()) {
574
589
  const slices = getMilestoneSlices(mid);
575
- completedSliceIds = slices.filter(s => s.status === "complete").map(s => s.id);
576
- hasIncomplete = slices.some(s => s.status !== "complete");
577
- if (completedSliceIds.length === 0 || !hasIncomplete)
578
- return null;
579
- const lastCompleted = completedSliceIds[completedSliceIds.length - 1];
580
- const assessmentFile = resolveSliceFile(base, mid, lastCompleted, "ASSESSMENT");
581
- const hasAssessment = !!(assessmentFile && await loadFile(assessmentFile));
582
- if (hasAssessment)
583
- return null;
584
- const summaryFile = resolveSliceFile(base, mid, lastCompleted, "SUMMARY");
585
- const hasSummary = !!(summaryFile && await loadFile(summaryFile));
586
- if (!hasSummary)
587
- return null;
588
- return { sliceId: lastCompleted };
590
+ if (slices.length > 0) {
591
+ const completedSliceIds = slices.filter(s => s.status === "complete").map(s => s.id);
592
+ const hasIncomplete = slices.some(s => s.status !== "complete");
593
+ if (completedSliceIds.length === 0 || !hasIncomplete)
594
+ return null;
595
+ const lastCompleted = completedSliceIds[completedSliceIds.length - 1];
596
+ const assessmentFile = resolveSliceFile(base, mid, lastCompleted, "ASSESSMENT");
597
+ const hasAssessment = !!(assessmentFile && await loadFile(assessmentFile));
598
+ if (hasAssessment)
599
+ return null;
600
+ const summaryFile = resolveSliceFile(base, mid, lastCompleted, "SUMMARY");
601
+ const hasSummary = !!(summaryFile && await loadFile(summaryFile));
602
+ if (!hasSummary)
603
+ return null;
604
+ return { sliceId: lastCompleted };
605
+ }
589
606
  }
590
607
  }
591
608
  catch { /* fall through */ }
592
- // DB unavailable cannot determine assessment needs
593
- return null;
609
+ // File-based fallback using roadmap checkboxes
610
+ const roadmapPath = resolveMilestoneFile(base, mid, "ROADMAP");
611
+ if (!roadmapPath)
612
+ return null;
613
+ const roadmapContent = await loadFile(roadmapPath);
614
+ if (!roadmapContent)
615
+ return null;
616
+ const parsed = parseRoadmap(roadmapContent);
617
+ const fileCompletedIds = parsed.slices.filter(s => s.done).map(s => s.id);
618
+ const fileHasIncomplete = parsed.slices.some(s => !s.done);
619
+ if (fileCompletedIds.length === 0 || !fileHasIncomplete)
620
+ return null;
621
+ const lastDone = fileCompletedIds[fileCompletedIds.length - 1];
622
+ const assessFile = resolveSliceFile(base, mid, lastDone, "ASSESSMENT");
623
+ const hasAssess = !!(assessFile && await loadFile(assessFile));
624
+ if (hasAssess)
625
+ return null;
626
+ const summFile = resolveSliceFile(base, mid, lastDone, "SUMMARY");
627
+ const hasSumm = !!(summFile && await loadFile(summFile));
628
+ if (!hasSumm)
629
+ return null;
630
+ return { sliceId: lastDone };
594
631
  }
595
632
  /**
596
633
  * Check if the most recently completed slice needs a UAT run.
@@ -604,40 +641,70 @@ export async function checkNeedsReassessment(base, mid, state) {
604
641
  * - UAT result file already exists (idempotent — already ran)
605
642
  */
606
643
  export async function checkNeedsRunUat(base, mid, state, prefs) {
607
- // DB primary path
644
+ // DB primary path — fall through to file-based when DB has no data for this milestone
608
645
  try {
609
646
  const { isDbAvailable, getMilestoneSlices } = await import("./gsd-db.js");
610
647
  if (isDbAvailable()) {
611
648
  const slices = getMilestoneSlices(mid);
612
- const completedSlices = slices.filter(s => s.status === "complete");
613
- const incompleteSlices = slices.filter(s => s.status !== "complete");
614
- if (completedSlices.length === 0)
615
- return null;
616
- if (incompleteSlices.length === 0)
617
- return null;
618
- if (!prefs?.uat_dispatch)
619
- return null;
620
- const lastCompleted = completedSlices[completedSlices.length - 1];
621
- const sid = lastCompleted.id;
622
- const uatFile = resolveSliceFile(base, mid, sid, "UAT");
623
- if (!uatFile)
624
- return null;
625
- const uatContent = await loadFile(uatFile);
626
- if (!uatContent)
627
- return null;
628
- const uatResultFile = resolveSliceFile(base, mid, sid, "UAT-RESULT");
629
- if (uatResultFile) {
630
- const hasResult = !!(await loadFile(uatResultFile));
631
- if (hasResult)
649
+ if (slices.length > 0) {
650
+ const completedSlices = slices.filter(s => s.status === "complete");
651
+ const incompleteSlices = slices.filter(s => s.status !== "complete");
652
+ if (completedSlices.length === 0)
653
+ return null;
654
+ if (incompleteSlices.length === 0)
632
655
  return null;
656
+ if (!prefs?.uat_dispatch)
657
+ return null;
658
+ const lastCompleted = completedSlices[completedSlices.length - 1];
659
+ const sid = lastCompleted.id;
660
+ const uatFile = resolveSliceFile(base, mid, sid, "UAT");
661
+ if (!uatFile)
662
+ return null;
663
+ const uatContent = await loadFile(uatFile);
664
+ if (!uatContent)
665
+ return null;
666
+ const uatResultFile = resolveSliceFile(base, mid, sid, "UAT-RESULT");
667
+ if (uatResultFile) {
668
+ const hasResult = !!(await loadFile(uatResultFile));
669
+ if (hasResult)
670
+ return null;
671
+ }
672
+ const uatType = extractUatType(uatContent) ?? "artifact-driven";
673
+ return { sliceId: sid, uatType };
633
674
  }
634
- const uatType = extractUatType(uatContent) ?? "artifact-driven";
635
- return { sliceId: sid, uatType };
636
675
  }
637
676
  }
638
677
  catch { /* fall through */ }
639
- // DB unavailable cannot determine UAT needs
640
- return null;
678
+ // File-based fallback using roadmap checkboxes
679
+ if (!prefs?.uat_dispatch)
680
+ return null;
681
+ const roadmapPath = resolveMilestoneFile(base, mid, "ROADMAP");
682
+ if (!roadmapPath)
683
+ return null;
684
+ const roadmapContent = await loadFile(roadmapPath);
685
+ if (!roadmapContent)
686
+ return null;
687
+ const parsed = parseRoadmap(roadmapContent);
688
+ const completedFileSlices = parsed.slices.filter(s => s.done);
689
+ const incompleteFileSlices = parsed.slices.filter(s => !s.done);
690
+ if (completedFileSlices.length === 0 || incompleteFileSlices.length === 0)
691
+ return null;
692
+ const lastCompletedFile = completedFileSlices[completedFileSlices.length - 1];
693
+ const uatSid = lastCompletedFile.id;
694
+ const uatFileFb = resolveSliceFile(base, mid, uatSid, "UAT");
695
+ if (!uatFileFb)
696
+ return null;
697
+ const uatContentFb = await loadFile(uatFileFb);
698
+ if (!uatContentFb)
699
+ return null;
700
+ const uatResultFb = resolveSliceFile(base, mid, uatSid, "UAT-RESULT");
701
+ if (uatResultFb) {
702
+ const hasResultFb = !!(await loadFile(uatResultFb));
703
+ if (hasResultFb)
704
+ return null;
705
+ }
706
+ const uatTypeFb = extractUatType(uatContentFb) ?? "artifact-driven";
707
+ return { sliceId: uatSid, uatType: uatTypeFb };
641
708
  }
642
709
  // ─── Prompt Builders ──────────────────────────────────────────────────────
643
710
  /**
@@ -1042,7 +1109,13 @@ export async function buildCompleteMilestonePrompt(mid, midTitle, base, level) {
1042
1109
  }
1043
1110
  }
1044
1111
  catch { /* fall through */ }
1045
- // If DB didn't provide slice IDs, sliceIds stays empty no summaries to inline
1112
+ // File-based fallback: parse roadmap for slice IDs when DB has no data
1113
+ if (sliceIds.length === 0 && roadmapPath) {
1114
+ const roadmapContent = await loadFile(roadmapPath);
1115
+ if (roadmapContent) {
1116
+ sliceIds = parseRoadmap(roadmapContent).slices.map(s => s.id);
1117
+ }
1118
+ }
1046
1119
  const seenSlices = new Set();
1047
1120
  for (const sid of sliceIds) {
1048
1121
  if (seenSlices.has(sid))
@@ -1100,7 +1173,13 @@ export async function buildValidateMilestonePrompt(mid, midTitle, base, level) {
1100
1173
  }
1101
1174
  }
1102
1175
  catch { /* fall through */ }
1103
- // If DB didn't provide slice IDs, valSliceIds stays empty
1176
+ // File-based fallback: parse roadmap for slice IDs when DB has no data
1177
+ if (valSliceIds.length === 0 && roadmapPath) {
1178
+ const roadmapContent = await loadFile(roadmapPath);
1179
+ if (roadmapContent) {
1180
+ valSliceIds = parseRoadmap(roadmapContent).slices.map(s => s.id);
1181
+ }
1182
+ }
1104
1183
  const seenValSlices = new Set();
1105
1184
  for (const sid of valSliceIds) {
1106
1185
  if (seenValSlices.has(sid))
@@ -402,6 +402,16 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
402
402
  process.stderr.write(`gsd-db: failed to open existing database: ${err.message}\n`);
403
403
  }
404
404
  }
405
+ // Gate: abort bootstrap if the DB file exists but the provider is
406
+ // still unavailable after both open attempts above. Without this,
407
+ // auto-mode starts but every gsd_task_complete / gsd_slice_complete
408
+ // call returns "db_unavailable", triggering artifact-retry which
409
+ // re-dispatches the same task — producing an infinite loop (#2419).
410
+ if (existsSync(gsdDbPath) && !isDbAvailable()) {
411
+ ctx.ui.notify("SQLite database exists but failed to open. Auto-mode cannot proceed without a working database provider. " +
412
+ "Check for corrupt gsd.db or missing native SQLite bindings.", "error");
413
+ return releaseLockAndReturn();
414
+ }
405
415
  // Initialize metrics
406
416
  initMetrics(s.basePath);
407
417
  // Initialize routing history
@@ -869,7 +869,14 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
869
869
  .filter(s => s.status === "complete")
870
870
  .map(s => ({ id: s.id, title: s.title }));
871
871
  }
872
- // When DB unavailable, completedSlices stays empty commit message will omit slice details
872
+ // Fallback: parse roadmap content when DB is unavailable
873
+ if (completedSlices.length === 0 && roadmapContent) {
874
+ const sliceRe = /- \[x\] \*\*(\w+):\s*(.+?)\*\*/gi;
875
+ let m;
876
+ while ((m = sliceRe.exec(roadmapContent)) !== null) {
877
+ completedSlices.push({ id: m[1], title: m[2] });
878
+ }
879
+ }
873
880
  // 3. chdir to original base
874
881
  const previousCwd = process.cwd();
875
882
  process.chdir(originalBasePath_);
@@ -891,7 +898,14 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
891
898
  }
892
899
  // 6. Build rich commit message
893
900
  const dbMilestone = getMilestone(milestoneId);
894
- const milestoneTitle = (dbMilestone?.title ?? "").replace(/^M\d+:\s*/, "").trim() || milestoneId;
901
+ let milestoneTitle = (dbMilestone?.title ?? "").replace(/^M\d+:\s*/, "").trim();
902
+ // Fallback: parse title from roadmap content header (e.g. "# M020: Backend foundation")
903
+ if (!milestoneTitle && roadmapContent) {
904
+ const titleMatch = roadmapContent.match(new RegExp(`^#\\s+${milestoneId}:\\s*(.+)`, "m"));
905
+ if (titleMatch)
906
+ milestoneTitle = titleMatch[1].trim();
907
+ }
908
+ milestoneTitle = milestoneTitle || milestoneId;
895
909
  const subject = `feat(${milestoneId}): ${milestoneTitle}`;
896
910
  let body = "";
897
911
  if (completedSlices.length > 0) {
@@ -166,6 +166,11 @@ export async function handleWorkflowCommand(trimmed, ctx, pi) {
166
166
  return true;
167
167
  }
168
168
  if (trimmed === "quick" || trimmed.startsWith("quick ")) {
169
+ if (isAutoActive()) {
170
+ ctx.ui.notify("/gsd quick cannot run while auto-mode is active.\n" +
171
+ "Stop auto-mode first with /gsd stop, then run /gsd quick.", "error");
172
+ return true;
173
+ }
169
174
  await handleQuick(trimmed.replace(/^quick\s*/, "").trim(), ctx, pi);
170
175
  return true;
171
176
  }
@@ -2,6 +2,8 @@
2
2
  import { resolveMilestoneFile } from "./paths.js";
3
3
  import { findMilestoneIds } from "./guided-flow.js";
4
4
  import { isDbAvailable, getMilestoneSlices } from "./gsd-db.js";
5
+ import { parseRoadmap } from "./parsers-legacy.js";
6
+ import { readFileSync } from "node:fs";
5
7
  const SLICE_DISPATCH_TYPES = new Set([
6
8
  "research-slice",
7
9
  "plan-slice",
@@ -27,16 +29,38 @@ export function getPriorSliceCompletionBlocker(base, _mainBranch, unitType, unit
27
29
  continue;
28
30
  if (resolveMilestoneFile(base, mid, "SUMMARY"))
29
31
  continue;
30
- if (!isDbAvailable())
31
- continue;
32
- const rows = getMilestoneSlices(mid);
33
- if (rows.length === 0)
34
- continue;
35
- const slices = rows.map((r) => ({
36
- id: r.id,
37
- done: r.status === "complete",
38
- depends: r.depends ?? [],
39
- }));
32
+ let slices = null;
33
+ if (isDbAvailable()) {
34
+ const rows = getMilestoneSlices(mid);
35
+ if (rows.length > 0) {
36
+ slices = rows.map((r) => ({
37
+ id: r.id,
38
+ done: r.status === "complete",
39
+ depends: r.depends ?? [],
40
+ }));
41
+ }
42
+ }
43
+ if (!slices) {
44
+ // File-based fallback: parse roadmap checkboxes
45
+ const roadmapPath = resolveMilestoneFile(base, mid, "ROADMAP");
46
+ if (!roadmapPath)
47
+ continue;
48
+ let roadmapContent;
49
+ try {
50
+ roadmapContent = readFileSync(roadmapPath, "utf-8");
51
+ }
52
+ catch {
53
+ continue;
54
+ }
55
+ const parsed = parseRoadmap(roadmapContent);
56
+ if (parsed.slices.length === 0)
57
+ continue;
58
+ slices = parsed.slices.map((s) => ({
59
+ id: s.id,
60
+ done: s.done,
61
+ depends: s.depends ?? [],
62
+ }));
63
+ }
40
64
  if (mid !== targetMid) {
41
65
  const incomplete = slices.find((slice) => !slice.done);
42
66
  if (incomplete) {
@@ -733,11 +733,13 @@ export async function repairStaleRenders(basePath) {
733
733
  for (const entry of staleEntries) {
734
734
  if (repairedPaths.has(entry.path))
735
735
  continue;
736
+ // Normalize path separators for cross-platform regex matching
737
+ const normPath = entry.path.replace(/\\/g, "/");
736
738
  try {
737
739
  // Determine repair action from the reason
738
740
  if (entry.reason.includes("in roadmap")) {
739
741
  // Roadmap checkbox mismatch — extract milestone ID from path
740
- const milestoneMatch = entry.path.match(/milestones\/([^/]+)\//);
742
+ const milestoneMatch = normPath.match(/milestones\/([^/]+)\//);
741
743
  if (milestoneMatch) {
742
744
  const ok = await renderRoadmapCheckboxes(basePath, milestoneMatch[1]);
743
745
  if (ok) {
@@ -748,7 +750,7 @@ export async function repairStaleRenders(basePath) {
748
750
  }
749
751
  else if (entry.reason.includes("in plan")) {
750
752
  // Plan checkbox mismatch — extract milestone + slice IDs from path
751
- const pathMatch = entry.path.match(/milestones\/([^/]+)\/slices\/([^/]+)\//);
753
+ const pathMatch = normPath.match(/milestones\/([^/]+)\/slices\/([^/]+)\//);
752
754
  if (pathMatch) {
753
755
  const ok = await renderPlanCheckboxes(basePath, pathMatch[1], pathMatch[2]);
754
756
  if (ok) {
@@ -759,7 +761,7 @@ export async function repairStaleRenders(basePath) {
759
761
  }
760
762
  else if (entry.reason.includes("SUMMARY.md missing") && entry.reason.match(/^T\d+/)) {
761
763
  // Missing task summary — extract IDs from path
762
- const pathMatch = entry.path.match(/milestones\/([^/]+)\/slices\/([^/]+)\/tasks\//);
764
+ const pathMatch = normPath.match(/milestones\/([^/]+)\/slices\/([^/]+)\/tasks\//);
763
765
  const taskMatch = entry.reason.match(/^(T\d+)/);
764
766
  if (pathMatch && taskMatch) {
765
767
  const ok = await renderTaskSummary(basePath, pathMatch[1], pathMatch[2], taskMatch[1]);
@@ -771,7 +773,7 @@ export async function repairStaleRenders(basePath) {
771
773
  }
772
774
  else if (entry.reason.includes("SUMMARY.md missing") && entry.reason.match(/^S\d+/)) {
773
775
  // Missing slice summary — extract IDs from path
774
- const pathMatch = entry.path.match(/milestones\/([^/]+)\/slices\/([^/]+)\//);
776
+ const pathMatch = normPath.match(/milestones\/([^/]+)\/slices\/([^/]+)\//);
775
777
  if (pathMatch) {
776
778
  const ok = await renderSliceSummary(basePath, pathMatch[1], pathMatch[2]);
777
779
  if (ok) {
@@ -782,7 +784,7 @@ export async function repairStaleRenders(basePath) {
782
784
  }
783
785
  else if (entry.reason.includes("UAT.md missing")) {
784
786
  // Missing slice UAT — renderSliceSummary handles both SUMMARY + UAT
785
- const pathMatch = entry.path.match(/milestones\/([^/]+)\/slices\/([^/]+)\//);
787
+ const pathMatch = normPath.match(/milestones\/([^/]+)\/slices\/([^/]+)\//);
786
788
  if (pathMatch) {
787
789
  const ok = await renderSliceSummary(basePath, pathMatch[1], pathMatch[2]);
788
790
  if (ok) {
@@ -10,6 +10,7 @@
10
10
  */
11
11
  import { loadFile, parseTaskPlanIO } from "./files.js";
12
12
  import { isDbAvailable, getSliceTasks } from "./gsd-db.js";
13
+ import { parsePlan } from "./parsers-legacy.js";
13
14
  import { resolveTasksDir, resolveTaskFiles } from "./paths.js";
14
15
  import { join } from "node:path";
15
16
  import { loadJsonFileOrNull, saveJsonFile } from "./json-persistence.js";
@@ -165,8 +166,18 @@ export async function loadSliceTaskIO(basePath, mid, sid) {
165
166
  }
166
167
  catch { /* fall through */ }
167
168
  if (!taskEntries) {
168
- // DB unavailable cannot determine task graph
169
- return [];
169
+ // File-based fallback: parse slice plan for task entries
170
+ const parsed = parsePlan(planContent);
171
+ if (parsed.tasks.length > 0) {
172
+ taskEntries = parsed.tasks.map(t => ({
173
+ id: t.id,
174
+ title: t.title,
175
+ done: t.done,
176
+ }));
177
+ }
178
+ else {
179
+ return [];
180
+ }
170
181
  }
171
182
  const tDir = resolveTasksDir(basePath, mid, sid);
172
183
  if (!tDir)