gsd-pi 2.43.0 → 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 (693) 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/bg-shell/overlay.js +3 -0
  5. package/dist/resources/extensions/github-sync/sync.js +2 -1
  6. package/dist/resources/extensions/gsd/auto/loop.js +0 -2
  7. package/dist/resources/extensions/gsd/auto/phases.js +7 -12
  8. package/dist/resources/extensions/gsd/auto-dashboard.js +19 -18
  9. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +34 -19
  10. package/dist/resources/extensions/gsd/auto-dispatch.js +36 -21
  11. package/dist/resources/extensions/gsd/auto-post-unit.js +128 -14
  12. package/dist/resources/extensions/gsd/auto-prompts.js +202 -92
  13. package/dist/resources/extensions/gsd/auto-recovery.js +83 -135
  14. package/dist/resources/extensions/gsd/auto-start.js +10 -0
  15. package/dist/resources/extensions/gsd/auto-supervisor.js +14 -0
  16. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +4 -7
  17. package/dist/resources/extensions/gsd/auto-verification.js +5 -10
  18. package/dist/resources/extensions/gsd/auto-worktree.js +123 -30
  19. package/dist/resources/extensions/gsd/auto.js +1 -4
  20. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +611 -0
  21. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +28 -3
  22. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +7 -0
  23. package/dist/resources/extensions/gsd/commands/catalog.js +3 -1
  24. package/dist/resources/extensions/gsd/commands/handlers/ops.js +15 -1
  25. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +5 -0
  26. package/dist/resources/extensions/gsd/commands-handlers.js +1 -1
  27. package/dist/resources/extensions/gsd/commands-maintenance.js +78 -3
  28. package/dist/resources/extensions/gsd/dashboard-overlay.js +32 -31
  29. package/dist/resources/extensions/gsd/db-writer.js +95 -4
  30. package/dist/resources/extensions/gsd/dispatch-guard.js +35 -30
  31. package/dist/resources/extensions/gsd/doctor-checks.js +28 -11
  32. package/dist/resources/extensions/gsd/doctor-environment.js +28 -0
  33. package/dist/resources/extensions/gsd/doctor-types.js +0 -15
  34. package/dist/resources/extensions/gsd/doctor.js +46 -282
  35. package/dist/resources/extensions/gsd/file-watcher.js +5 -1
  36. package/dist/resources/extensions/gsd/files.js +14 -198
  37. package/dist/resources/extensions/gsd/git-service.js +4 -0
  38. package/dist/resources/extensions/gsd/gitignore.js +4 -0
  39. package/dist/resources/extensions/gsd/gsd-db.js +819 -197
  40. package/dist/resources/extensions/gsd/guided-flow.js +18 -8
  41. package/dist/resources/extensions/gsd/markdown-renderer.js +862 -0
  42. package/dist/resources/extensions/gsd/md-importer.js +182 -4
  43. package/dist/resources/extensions/gsd/native-git-bridge.js +10 -1
  44. package/dist/resources/extensions/gsd/parallel-eligibility.js +14 -19
  45. package/dist/resources/extensions/gsd/parallel-orchestrator.js +38 -0
  46. package/dist/resources/extensions/gsd/parsers-legacy.js +239 -0
  47. package/dist/resources/extensions/gsd/preferences-types.js +1 -0
  48. package/dist/resources/extensions/gsd/preferences-validation.js +9 -0
  49. package/dist/resources/extensions/gsd/preferences.js +1 -0
  50. package/dist/resources/extensions/gsd/prompts/complete-slice.md +22 -9
  51. package/dist/resources/extensions/gsd/prompts/discuss.md +2 -2
  52. package/dist/resources/extensions/gsd/prompts/execute-task.md +15 -5
  53. package/dist/resources/extensions/gsd/prompts/guided-complete-slice.md +1 -1
  54. package/dist/resources/extensions/gsd/prompts/guided-execute-task.md +1 -1
  55. package/dist/resources/extensions/gsd/prompts/guided-plan-milestone.md +1 -1
  56. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +6 -10
  57. package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -7
  58. package/dist/resources/extensions/gsd/prompts/reactive-execute.md +3 -3
  59. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -7
  60. package/dist/resources/extensions/gsd/prompts/replan-slice.md +6 -6
  61. package/dist/resources/extensions/gsd/reactive-graph.js +33 -3
  62. package/dist/resources/extensions/gsd/skill-health.js +3 -1
  63. package/dist/resources/extensions/gsd/state.js +484 -30
  64. package/dist/resources/extensions/gsd/tools/complete-milestone.js +128 -0
  65. package/dist/resources/extensions/gsd/tools/complete-slice.js +244 -0
  66. package/dist/resources/extensions/gsd/tools/complete-task.js +204 -0
  67. package/dist/resources/extensions/gsd/tools/plan-milestone.js +205 -0
  68. package/dist/resources/extensions/gsd/tools/plan-slice.js +155 -0
  69. package/dist/resources/extensions/gsd/tools/plan-task.js +94 -0
  70. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +152 -0
  71. package/dist/resources/extensions/gsd/tools/replan-slice.js +146 -0
  72. package/dist/resources/extensions/gsd/triage-resolution.js +17 -1
  73. package/dist/resources/extensions/gsd/undo.js +197 -3
  74. package/dist/resources/extensions/gsd/visualizer-data.js +53 -16
  75. package/dist/resources/extensions/gsd/workspace-index.js +63 -39
  76. package/dist/web/standalone/.next/BUILD_ID +1 -1
  77. package/dist/web/standalone/.next/app-path-routes-manifest.json +18 -17
  78. package/dist/web/standalone/.next/build-manifest.json +4 -4
  79. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  80. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  81. package/dist/web/standalone/.next/required-server-files.json +4 -4
  82. package/dist/web/standalone/.next/routes-manifest.json +6 -0
  83. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  84. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  85. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  86. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  87. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  88. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  89. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  90. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  91. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  92. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  94. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  95. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  96. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -4
  97. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
  98. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
  100. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  101. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  102. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  103. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  104. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  105. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  106. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  107. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  108. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  109. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  110. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +5 -5
  148. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  154. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -0
  166. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -0
  167. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -0
  168. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  171. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  173. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  175. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/index.html +1 -1
  185. package/dist/web/standalone/.next/server/app/index.rsc +5 -5
  186. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  187. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -5
  188. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  189. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
  190. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  191. package/dist/web/standalone/.next/server/app/page.js +2 -2
  192. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app-paths-manifest.json +18 -17
  194. package/dist/web/standalone/.next/server/chunks/229.js +3 -3
  195. package/dist/web/standalone/.next/server/chunks/471.js +3 -3
  196. package/dist/web/standalone/.next/server/functions-config-manifest.json +1 -0
  197. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  198. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  199. package/dist/web/standalone/.next/server/middleware.js +2 -2
  200. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  201. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  202. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  203. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  204. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  205. package/dist/web/standalone/.next/static/alS4hoANx0TK4UVZY27da/_buildManifest.js +1 -0
  206. package/dist/web/standalone/.next/static/chunks/{4024.c195dc1fdd2adbea.js → 4024.0de81b543b28b9fe.js} +2 -2
  207. package/dist/web/standalone/.next/static/chunks/app/_global-error/{page-d07a2c023f1aef1e.js → page-d83ba70a25a85472.js} +1 -1
  208. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-f2a7482d42a5614b.js +1 -0
  209. package/dist/web/standalone/.next/static/chunks/app/api/boot/{route-d07a2c023f1aef1e.js → route-d83ba70a25a85472.js} +1 -1
  210. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/{route-d07a2c023f1aef1e.js → route-d83ba70a25a85472.js} +1 -1
  211. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/{route-d07a2c023f1aef1e.js → route-d83ba70a25a85472.js} +1 -1
  212. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-d83ba70a25a85472.js +1 -0
  213. package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-d83ba70a25a85472.js +1 -0
  214. package/dist/web/standalone/.next/static/chunks/app/api/captures/route-d83ba70a25a85472.js +1 -0
  215. package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-d83ba70a25a85472.js +1 -0
  216. package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-d83ba70a25a85472.js +1 -0
  217. package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-d83ba70a25a85472.js +1 -0
  218. package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-d83ba70a25a85472.js +1 -0
  219. package/dist/web/standalone/.next/static/chunks/app/api/files/route-d83ba70a25a85472.js +1 -0
  220. package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-d83ba70a25a85472.js +1 -0
  221. package/dist/web/standalone/.next/static/chunks/app/api/git/route-d83ba70a25a85472.js +1 -0
  222. package/dist/web/standalone/.next/static/chunks/app/api/history/route-d83ba70a25a85472.js +1 -0
  223. package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-d83ba70a25a85472.js +1 -0
  224. package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-d83ba70a25a85472.js +1 -0
  225. package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-d83ba70a25a85472.js +1 -0
  226. package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-d83ba70a25a85472.js +1 -0
  227. package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-d83ba70a25a85472.js +1 -0
  228. package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-d83ba70a25a85472.js +1 -0
  229. package/dist/web/standalone/.next/static/chunks/app/api/projects/route-d83ba70a25a85472.js +1 -0
  230. package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-d83ba70a25a85472.js +1 -0
  231. package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-d83ba70a25a85472.js +1 -0
  232. package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-d83ba70a25a85472.js +1 -0
  233. package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-d83ba70a25a85472.js +1 -0
  234. package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-d83ba70a25a85472.js +1 -0
  235. package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-d83ba70a25a85472.js +1 -0
  236. package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-d83ba70a25a85472.js +1 -0
  237. package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-d83ba70a25a85472.js +1 -0
  238. package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-d83ba70a25a85472.js +1 -0
  239. package/dist/web/standalone/.next/static/chunks/app/api/steer/route-d83ba70a25a85472.js +1 -0
  240. package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-d83ba70a25a85472.js +1 -0
  241. package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-d83ba70a25a85472.js +1 -0
  242. package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-d83ba70a25a85472.js +1 -0
  243. package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-d83ba70a25a85472.js +1 -0
  244. package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-d83ba70a25a85472.js +1 -0
  245. package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-d83ba70a25a85472.js +1 -0
  246. package/dist/web/standalone/.next/static/chunks/app/api/undo/route-d83ba70a25a85472.js +1 -0
  247. package/dist/web/standalone/.next/static/chunks/app/api/update/route-d83ba70a25a85472.js +1 -0
  248. package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-d83ba70a25a85472.js +1 -0
  249. package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +1 -0
  250. package/dist/web/standalone/.next/static/chunks/app/page-b9367c5ae13b99c6.js +1 -0
  251. package/dist/web/standalone/.next/static/chunks/{main-app-2f2ee7b85712c2bd.js → main-app-fdab67f7802d7832.js} +1 -1
  252. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-d83ba70a25a85472.js +1 -0
  253. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-d83ba70a25a85472.js +1 -0
  254. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  255. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-d83ba70a25a85472.js +1 -0
  256. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-d83ba70a25a85472.js +1 -0
  257. package/dist/web/standalone/.next/static/chunks/{webpack-fa307370fcf9fb2c.js → webpack-9014b5adb127a98a.js} +1 -1
  258. package/dist/web/standalone/.next/static/css/8a727f372cf53002.css +1 -0
  259. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  260. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  261. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  262. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  263. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  264. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  265. package/dist/web/standalone/server.js +1 -1
  266. package/package.json +4 -4
  267. package/packages/pi-ai/dist/models.custom.d.ts +173 -0
  268. package/packages/pi-ai/dist/models.custom.d.ts.map +1 -0
  269. package/packages/pi-ai/dist/models.custom.js +170 -0
  270. package/packages/pi-ai/dist/models.custom.js.map +1 -0
  271. package/packages/pi-ai/dist/models.d.ts.map +1 -1
  272. package/packages/pi-ai/dist/models.js +16 -1
  273. package/packages/pi-ai/dist/models.js.map +1 -1
  274. package/packages/pi-ai/dist/models.test.d.ts +2 -0
  275. package/packages/pi-ai/dist/models.test.d.ts.map +1 -0
  276. package/packages/pi-ai/dist/models.test.js +67 -0
  277. package/packages/pi-ai/dist/models.test.js.map +1 -0
  278. package/packages/pi-ai/src/models.custom.ts +172 -0
  279. package/packages/pi-ai/src/models.test.ts +85 -0
  280. package/packages/pi-ai/src/models.ts +17 -1
  281. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +10 -3
  282. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  283. package/packages/pi-coding-agent/dist/core/agent-session.js +21 -34
  284. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  285. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +6 -8
  286. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  287. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.d.ts +2 -2
  288. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  289. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.js.map +1 -1
  290. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +2 -2
  291. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  292. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  293. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +4 -4
  294. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -1
  295. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +1 -1
  296. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  297. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  298. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +6 -0
  299. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  300. package/packages/pi-coding-agent/dist/core/extensions/loader.js +80 -0
  301. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  302. package/packages/pi-coding-agent/dist/core/extensions/loader.test.js +63 -0
  303. package/packages/pi-coding-agent/dist/core/extensions/loader.test.js.map +1 -1
  304. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +24 -26
  305. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  306. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +37 -0
  307. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  308. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  309. package/packages/pi-coding-agent/dist/core/fallback-resolver.d.ts.map +1 -1
  310. package/packages/pi-coding-agent/dist/core/fallback-resolver.js +2 -3
  311. package/packages/pi-coding-agent/dist/core/fallback-resolver.js.map +1 -1
  312. package/packages/pi-coding-agent/dist/core/fallback-resolver.test.js +12 -2
  313. package/packages/pi-coding-agent/dist/core/fallback-resolver.test.js.map +1 -1
  314. package/packages/pi-coding-agent/dist/core/fs-utils.test.js +29 -48
  315. package/packages/pi-coding-agent/dist/core/fs-utils.test.js.map +1 -1
  316. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.d.ts +38 -0
  317. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.d.ts.map +1 -0
  318. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.js +192 -0
  319. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.js.map +1 -0
  320. package/packages/pi-coding-agent/dist/core/lsp/client.d.ts +5 -0
  321. package/packages/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -1
  322. package/packages/pi-coding-agent/dist/core/lsp/client.js +69 -21
  323. package/packages/pi-coding-agent/dist/core/lsp/client.js.map +1 -1
  324. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.d.ts +2 -0
  325. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.d.ts.map +1 -0
  326. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +255 -0
  327. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -0
  328. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +15 -0
  329. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  330. package/packages/pi-coding-agent/dist/core/model-registry.js +40 -3
  331. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  332. package/packages/pi-coding-agent/dist/core/package-commands.d.ts +25 -0
  333. package/packages/pi-coding-agent/dist/core/package-commands.d.ts.map +1 -0
  334. package/packages/pi-coding-agent/dist/core/package-commands.js +253 -0
  335. package/packages/pi-coding-agent/dist/core/package-commands.js.map +1 -0
  336. package/packages/pi-coding-agent/dist/core/package-commands.test.d.ts +2 -0
  337. package/packages/pi-coding-agent/dist/core/package-commands.test.d.ts.map +1 -0
  338. package/packages/pi-coding-agent/dist/core/package-commands.test.js +225 -0
  339. package/packages/pi-coding-agent/dist/core/package-commands.test.js.map +1 -0
  340. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +34 -44
  341. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
  342. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  343. package/packages/pi-coding-agent/dist/core/sdk.js +4 -0
  344. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  345. package/packages/pi-coding-agent/dist/core/session-manager.test.js +30 -34
  346. package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
  347. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +10 -12
  348. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -1
  349. package/packages/pi-coding-agent/dist/index.d.ts +3 -1
  350. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  351. package/packages/pi-coding-agent/dist/index.js +1 -0
  352. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  353. package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
  354. package/packages/pi-coding-agent/dist/main.js +11 -199
  355. package/packages/pi-coding-agent/dist/main.js.map +1 -1
  356. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts +6 -0
  357. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  358. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +21 -0
  359. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  360. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +1 -1
  361. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  362. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +8 -15
  363. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  364. package/packages/pi-coding-agent/dist/modes/print-mode.d.ts.map +1 -1
  365. package/packages/pi-coding-agent/dist/modes/print-mode.js +45 -34
  366. package/packages/pi-coding-agent/dist/modes/print-mode.js.map +1 -1
  367. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts +1 -0
  368. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  369. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js +7 -2
  370. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js.map +1 -1
  371. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  372. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +2 -1
  373. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  374. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js +43 -47
  375. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js.map +1 -1
  376. package/packages/pi-coding-agent/package.json +1 -1
  377. package/packages/pi-coding-agent/src/core/agent-session.ts +26 -37
  378. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +7 -7
  379. package/packages/pi-coding-agent/src/core/compaction/branch-summarization.ts +2 -2
  380. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +3 -3
  381. package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +4 -4
  382. package/packages/pi-coding-agent/src/core/extensions/index.ts +5 -0
  383. package/packages/pi-coding-agent/src/core/extensions/loader.test.ts +96 -0
  384. package/packages/pi-coding-agent/src/core/extensions/loader.ts +89 -0
  385. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +26 -26
  386. package/packages/pi-coding-agent/src/core/extensions/types.ts +44 -0
  387. package/packages/pi-coding-agent/src/core/fallback-resolver.test.ts +15 -2
  388. package/packages/pi-coding-agent/src/core/fallback-resolver.ts +2 -3
  389. package/packages/pi-coding-agent/src/core/fs-utils.test.ts +31 -43
  390. package/packages/pi-coding-agent/src/core/lifecycle-hooks.ts +274 -0
  391. package/packages/pi-coding-agent/src/core/lsp/client.ts +83 -21
  392. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +288 -0
  393. package/packages/pi-coding-agent/src/core/model-registry.ts +39 -3
  394. package/packages/pi-coding-agent/src/core/package-commands.test.ts +240 -0
  395. package/packages/pi-coding-agent/src/core/package-commands.ts +310 -0
  396. package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +40 -45
  397. package/packages/pi-coding-agent/src/core/sdk.ts +4 -0
  398. package/packages/pi-coding-agent/src/core/session-manager.test.ts +33 -33
  399. package/packages/pi-coding-agent/src/core/tools/edit-diff.test.ts +17 -17
  400. package/packages/pi-coding-agent/src/index.ts +7 -0
  401. package/packages/pi-coding-agent/src/main.ts +11 -232
  402. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +20 -0
  403. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +9 -16
  404. package/packages/pi-coding-agent/src/modes/print-mode.ts +42 -32
  405. package/packages/pi-coding-agent/src/modes/rpc/rpc-client.ts +8 -2
  406. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +2 -1
  407. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.test.ts +74 -74
  408. package/pkg/dist/modes/interactive/theme/theme.d.ts +1 -1
  409. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  410. package/pkg/dist/modes/interactive/theme/theme.js +8 -15
  411. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  412. package/pkg/package.json +1 -1
  413. package/src/resources/extensions/bg-shell/overlay.ts +4 -0
  414. package/src/resources/extensions/github-sync/sync.ts +2 -1
  415. package/src/resources/extensions/gsd/auto/loop-deps.ts +0 -8
  416. package/src/resources/extensions/gsd/auto/loop.ts +0 -2
  417. package/src/resources/extensions/gsd/auto/phases.ts +7 -20
  418. package/src/resources/extensions/gsd/auto/types.ts +0 -1
  419. package/src/resources/extensions/gsd/auto-dashboard.ts +20 -16
  420. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +34 -19
  421. package/src/resources/extensions/gsd/auto-dispatch.ts +38 -21
  422. package/src/resources/extensions/gsd/auto-post-unit.ts +150 -15
  423. package/src/resources/extensions/gsd/auto-prompts.ts +186 -103
  424. package/src/resources/extensions/gsd/auto-recovery.ts +77 -142
  425. package/src/resources/extensions/gsd/auto-start.ts +14 -0
  426. package/src/resources/extensions/gsd/auto-supervisor.ts +14 -0
  427. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +6 -7
  428. package/src/resources/extensions/gsd/auto-verification.ts +4 -9
  429. package/src/resources/extensions/gsd/auto-worktree.ts +126 -30
  430. package/src/resources/extensions/gsd/auto.ts +0 -9
  431. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +675 -4
  432. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +31 -3
  433. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +7 -0
  434. package/src/resources/extensions/gsd/commands/catalog.ts +3 -1
  435. package/src/resources/extensions/gsd/commands/handlers/ops.ts +15 -1
  436. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +8 -0
  437. package/src/resources/extensions/gsd/commands-handlers.ts +1 -1
  438. package/src/resources/extensions/gsd/commands-maintenance.ts +86 -3
  439. package/src/resources/extensions/gsd/dashboard-overlay.ts +17 -13
  440. package/src/resources/extensions/gsd/db-writer.ts +105 -4
  441. package/src/resources/extensions/gsd/dispatch-guard.ts +32 -30
  442. package/src/resources/extensions/gsd/doctor-checks.ts +25 -11
  443. package/src/resources/extensions/gsd/doctor-environment.ts +31 -0
  444. package/src/resources/extensions/gsd/doctor-types.ts +0 -23
  445. package/src/resources/extensions/gsd/doctor.ts +45 -295
  446. package/src/resources/extensions/gsd/file-watcher.ts +4 -1
  447. package/src/resources/extensions/gsd/files.ts +16 -220
  448. package/src/resources/extensions/gsd/git-service.ts +4 -0
  449. package/src/resources/extensions/gsd/gitignore.ts +4 -0
  450. package/src/resources/extensions/gsd/gsd-db.ts +1157 -370
  451. package/src/resources/extensions/gsd/guided-flow.ts +20 -8
  452. package/src/resources/extensions/gsd/markdown-renderer.ts +1098 -0
  453. package/src/resources/extensions/gsd/md-importer.ts +211 -2
  454. package/src/resources/extensions/gsd/native-git-bridge.ts +12 -1
  455. package/src/resources/extensions/gsd/parallel-eligibility.ts +14 -18
  456. package/src/resources/extensions/gsd/parallel-orchestrator.ts +43 -0
  457. package/src/resources/extensions/gsd/parsers-legacy.ts +271 -0
  458. package/src/resources/extensions/gsd/preferences-types.ts +3 -0
  459. package/src/resources/extensions/gsd/preferences-validation.ts +9 -0
  460. package/src/resources/extensions/gsd/preferences.ts +1 -0
  461. package/src/resources/extensions/gsd/prompts/complete-slice.md +22 -9
  462. package/src/resources/extensions/gsd/prompts/discuss.md +2 -2
  463. package/src/resources/extensions/gsd/prompts/execute-task.md +15 -5
  464. package/src/resources/extensions/gsd/prompts/guided-complete-slice.md +1 -1
  465. package/src/resources/extensions/gsd/prompts/guided-execute-task.md +1 -1
  466. package/src/resources/extensions/gsd/prompts/guided-plan-milestone.md +1 -1
  467. package/src/resources/extensions/gsd/prompts/plan-milestone.md +6 -10
  468. package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -7
  469. package/src/resources/extensions/gsd/prompts/reactive-execute.md +3 -3
  470. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -7
  471. package/src/resources/extensions/gsd/prompts/replan-slice.md +6 -6
  472. package/src/resources/extensions/gsd/reactive-graph.ts +33 -3
  473. package/src/resources/extensions/gsd/skill-health.ts +2 -1
  474. package/src/resources/extensions/gsd/state.ts +547 -29
  475. package/src/resources/extensions/gsd/tests/all-milestones-complete-merge.test.ts +99 -99
  476. package/src/resources/extensions/gsd/tests/atomic-task-closeout.test.ts +8 -120
  477. package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +14 -16
  478. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +20 -11
  479. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +43 -57
  480. package/src/resources/extensions/gsd/tests/auto-preflight.test.ts +11 -13
  481. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +600 -513
  482. package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +73 -75
  483. package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +34 -56
  484. package/src/resources/extensions/gsd/tests/auto-stash-merge.test.ts +121 -0
  485. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +540 -668
  486. package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +165 -143
  487. package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +29 -52
  488. package/src/resources/extensions/gsd/tests/captures.test.ts +148 -176
  489. package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +32 -33
  490. package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +141 -143
  491. package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +25 -25
  492. package/src/resources/extensions/gsd/tests/commands-logs.test.ts +81 -81
  493. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +39 -60
  494. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +375 -0
  495. package/src/resources/extensions/gsd/tests/complete-task.test.ts +387 -0
  496. package/src/resources/extensions/gsd/tests/context-store.test.ts +354 -367
  497. package/src/resources/extensions/gsd/tests/continue-here.test.ts +68 -72
  498. package/src/resources/extensions/gsd/tests/cost-projection.test.ts +92 -106
  499. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +27 -35
  500. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +0 -2
  501. package/src/resources/extensions/gsd/tests/dashboard-budget.test.ts +220 -237
  502. package/src/resources/extensions/gsd/tests/db-writer.test.ts +390 -420
  503. package/src/resources/extensions/gsd/tests/definition-loader.test.ts +76 -92
  504. package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +512 -0
  505. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +644 -84
  506. package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +78 -101
  507. package/src/resources/extensions/gsd/tests/derive-state.test.ts +192 -227
  508. package/src/resources/extensions/gsd/tests/detection.test.ts +232 -278
  509. package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +30 -34
  510. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +192 -161
  511. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +43 -49
  512. package/src/resources/extensions/gsd/tests/dispatch-uat-last-completed.test.ts +28 -32
  513. package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +30 -90
  514. package/src/resources/extensions/gsd/tests/doctor-delimiter-fix.test.ts +34 -38
  515. package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +57 -80
  516. package/src/resources/extensions/gsd/tests/doctor-environment-worktree.test.ts +164 -0
  517. package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +72 -97
  518. package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +55 -153
  519. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +104 -145
  520. package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +84 -106
  521. package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +53 -97
  522. package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +72 -93
  523. package/src/resources/extensions/gsd/tests/doctor.test.ts +109 -149
  524. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +123 -131
  525. package/src/resources/extensions/gsd/tests/exit-command.test.ts +20 -24
  526. package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +48 -57
  527. package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +5 -7
  528. package/src/resources/extensions/gsd/tests/flag-file-db.test.ts +278 -0
  529. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +232 -0
  530. package/src/resources/extensions/gsd/tests/git-locale.test.ts +13 -27
  531. package/src/resources/extensions/gsd/tests/git-service.test.ts +291 -390
  532. package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +31 -39
  533. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +63 -69
  534. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +255 -264
  535. package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +108 -119
  536. package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +440 -0
  537. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +229 -262
  538. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +13 -13
  539. package/src/resources/extensions/gsd/tests/health-widget.test.ts +29 -37
  540. package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +81 -270
  541. package/src/resources/extensions/gsd/tests/init-wizard.test.ts +16 -18
  542. package/src/resources/extensions/gsd/tests/integration-edge.test.ts +41 -46
  543. package/src/resources/extensions/gsd/tests/integration-lifecycle.test.ts +42 -53
  544. package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +75 -91
  545. package/src/resources/extensions/gsd/tests/integration-proof.test.ts +643 -0
  546. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +0 -3
  547. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +1161 -0
  548. package/src/resources/extensions/gsd/tests/md-importer.test.ts +101 -125
  549. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +45 -54
  550. package/src/resources/extensions/gsd/tests/memory-store.test.ts +81 -94
  551. package/src/resources/extensions/gsd/tests/migrate-command.test.ts +57 -66
  552. package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +429 -0
  553. package/src/resources/extensions/gsd/tests/migrate-parser.test.ts +161 -170
  554. package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +125 -141
  555. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +107 -131
  556. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +89 -97
  557. package/src/resources/extensions/gsd/tests/migrate-writer.test.ts +127 -164
  558. package/src/resources/extensions/gsd/tests/must-have-parser.test.ts +81 -94
  559. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +35 -36
  560. package/src/resources/extensions/gsd/tests/overrides.test.ts +99 -106
  561. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +40 -47
  562. package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +25 -28
  563. package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +66 -83
  564. package/src/resources/extensions/gsd/tests/park-edge-cases.test.ts +54 -77
  565. package/src/resources/extensions/gsd/tests/park-milestone.test.ts +68 -115
  566. package/src/resources/extensions/gsd/tests/parsers.test.ts +548 -612
  567. package/src/resources/extensions/gsd/tests/paths.test.ts +72 -87
  568. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +176 -113
  569. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +7 -0
  570. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +179 -0
  571. package/src/resources/extensions/gsd/tests/plan-task.test.ts +145 -0
  572. package/src/resources/extensions/gsd/tests/planning-crossval.test.ts +305 -0
  573. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +77 -117
  574. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +139 -0
  575. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +56 -56
  576. package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +93 -119
  577. package/src/resources/extensions/gsd/tests/queue-order.test.ts +70 -82
  578. package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +42 -55
  579. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +100 -0
  580. package/src/resources/extensions/gsd/tests/quick-branch-lifecycle.test.ts +45 -73
  581. package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +325 -0
  582. package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +28 -38
  583. package/src/resources/extensions/gsd/tests/replan-handler.test.ts +410 -0
  584. package/src/resources/extensions/gsd/tests/replan-slice.test.ts +73 -80
  585. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +71 -74
  586. package/src/resources/extensions/gsd/tests/requirements.test.ts +70 -75
  587. package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +44 -66
  588. package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +114 -181
  589. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +1 -1
  590. package/src/resources/extensions/gsd/tests/rogue-file-detection.test.ts +296 -0
  591. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +63 -65
  592. package/src/resources/extensions/gsd/tests/run-uat.test.ts +66 -128
  593. package/src/resources/extensions/gsd/tests/schema-v9-sequence.test.ts +176 -0
  594. package/src/resources/extensions/gsd/tests/session-lock-multipath.test.ts +18 -25
  595. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +37 -44
  596. package/src/resources/extensions/gsd/tests/shared-wal.test.ts +209 -0
  597. package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +63 -0
  598. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +6 -8
  599. package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +22 -28
  600. package/src/resources/extensions/gsd/tests/token-cost-display.test.ts +118 -0
  601. package/src/resources/extensions/gsd/tests/token-savings.test.ts +54 -56
  602. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +23 -25
  603. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +19 -13
  604. package/src/resources/extensions/gsd/tests/undo.test.ts +321 -1
  605. package/src/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +66 -82
  606. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +46 -47
  607. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +1 -1
  608. package/src/resources/extensions/gsd/tests/verification-evidence.test.ts +0 -142
  609. package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -22
  610. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -86
  611. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +41 -43
  612. package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +94 -96
  613. package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +11 -13
  614. package/src/resources/extensions/gsd/tests/worker-registry.test.ts +27 -29
  615. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +50 -52
  616. package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +10 -13
  617. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +14 -18
  618. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +38 -39
  619. package/src/resources/extensions/gsd/tests/worktree-e2e.test.ts +17 -21
  620. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +12 -5
  621. package/src/resources/extensions/gsd/tests/worktree-health.test.ts +25 -30
  622. package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +30 -37
  623. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +15 -22
  624. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +59 -66
  625. package/src/resources/extensions/gsd/tests/worktree.test.ts +44 -50
  626. package/src/resources/extensions/gsd/tools/complete-milestone.ts +176 -0
  627. package/src/resources/extensions/gsd/tools/complete-slice.ts +300 -0
  628. package/src/resources/extensions/gsd/tools/complete-task.ts +245 -0
  629. package/src/resources/extensions/gsd/tools/plan-milestone.ts +249 -0
  630. package/src/resources/extensions/gsd/tools/plan-slice.ts +194 -0
  631. package/src/resources/extensions/gsd/tools/plan-task.ts +116 -0
  632. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +203 -0
  633. package/src/resources/extensions/gsd/tools/replan-slice.ts +192 -0
  634. package/src/resources/extensions/gsd/triage-resolution.ts +20 -1
  635. package/src/resources/extensions/gsd/types.ts +50 -0
  636. package/src/resources/extensions/gsd/undo.ts +247 -3
  637. package/src/resources/extensions/gsd/visualizer-data.ts +54 -17
  638. package/src/resources/extensions/gsd/workspace-index.ts +64 -46
  639. package/dist/resources/extensions/gsd/auto-observability.js +0 -56
  640. package/dist/resources/extensions/gsd/observability-validator.js +0 -422
  641. package/dist/resources/extensions/gsd/roadmap-mutations.js +0 -110
  642. package/dist/web/standalone/.next/static/VvclDCW6TAWjEyLU-EYL1/_buildManifest.js +0 -1
  643. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-e07acdb7dd069836.js +0 -1
  644. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-d07a2c023f1aef1e.js +0 -1
  645. package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-d07a2c023f1aef1e.js +0 -1
  646. package/dist/web/standalone/.next/static/chunks/app/api/captures/route-d07a2c023f1aef1e.js +0 -1
  647. package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-d07a2c023f1aef1e.js +0 -1
  648. package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-d07a2c023f1aef1e.js +0 -1
  649. package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-d07a2c023f1aef1e.js +0 -1
  650. package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-d07a2c023f1aef1e.js +0 -1
  651. package/dist/web/standalone/.next/static/chunks/app/api/files/route-d07a2c023f1aef1e.js +0 -1
  652. package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-d07a2c023f1aef1e.js +0 -1
  653. package/dist/web/standalone/.next/static/chunks/app/api/git/route-d07a2c023f1aef1e.js +0 -1
  654. package/dist/web/standalone/.next/static/chunks/app/api/history/route-d07a2c023f1aef1e.js +0 -1
  655. package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-d07a2c023f1aef1e.js +0 -1
  656. package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-d07a2c023f1aef1e.js +0 -1
  657. package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-d07a2c023f1aef1e.js +0 -1
  658. package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-d07a2c023f1aef1e.js +0 -1
  659. package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-d07a2c023f1aef1e.js +0 -1
  660. package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-d07a2c023f1aef1e.js +0 -1
  661. package/dist/web/standalone/.next/static/chunks/app/api/projects/route-d07a2c023f1aef1e.js +0 -1
  662. package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-d07a2c023f1aef1e.js +0 -1
  663. package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-d07a2c023f1aef1e.js +0 -1
  664. package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-d07a2c023f1aef1e.js +0 -1
  665. package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-d07a2c023f1aef1e.js +0 -1
  666. package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-d07a2c023f1aef1e.js +0 -1
  667. package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-d07a2c023f1aef1e.js +0 -1
  668. package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-d07a2c023f1aef1e.js +0 -1
  669. package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-d07a2c023f1aef1e.js +0 -1
  670. package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-d07a2c023f1aef1e.js +0 -1
  671. package/dist/web/standalone/.next/static/chunks/app/api/steer/route-d07a2c023f1aef1e.js +0 -1
  672. package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-d07a2c023f1aef1e.js +0 -1
  673. package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-d07a2c023f1aef1e.js +0 -1
  674. package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-d07a2c023f1aef1e.js +0 -1
  675. package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-d07a2c023f1aef1e.js +0 -1
  676. package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-d07a2c023f1aef1e.js +0 -1
  677. package/dist/web/standalone/.next/static/chunks/app/api/undo/route-d07a2c023f1aef1e.js +0 -1
  678. package/dist/web/standalone/.next/static/chunks/app/api/update/route-d07a2c023f1aef1e.js +0 -1
  679. package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-d07a2c023f1aef1e.js +0 -1
  680. package/dist/web/standalone/.next/static/chunks/app/layout-745c6ed5fea5fb06.js +0 -1
  681. package/dist/web/standalone/.next/static/chunks/app/page-801b53eff6e83579.js +0 -1
  682. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-d07a2c023f1aef1e.js +0 -1
  683. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-d07a2c023f1aef1e.js +0 -1
  684. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-e6255954dccfcf0a.js +0 -1
  685. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-d07a2c023f1aef1e.js +0 -1
  686. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-d07a2c023f1aef1e.js +0 -1
  687. package/dist/web/standalone/.next/static/css/123c0bb039697968.css +0 -1
  688. package/src/resources/extensions/gsd/auto-observability.ts +0 -74
  689. package/src/resources/extensions/gsd/observability-validator.ts +0 -456
  690. package/src/resources/extensions/gsd/roadmap-mutations.ts +0 -134
  691. package/src/resources/extensions/gsd/tests/doctor-task-done-missing-summary-slice-loop.test.ts +0 -174
  692. package/src/resources/extensions/gsd/tests/plan-quality-validator.test.ts +0 -474
  693. /package/dist/web/standalone/.next/static/{VvclDCW6TAWjEyLU-EYL1 → alS4hoANx0TK4UVZY27da}/_ssgManifest.js +0 -0
@@ -1,16 +1,41 @@
1
1
  import { existsSync } from "node:fs";
2
- import { join } from "node:path";
2
+ import { join, sep } from "node:path";
3
3
  import { createBashTool, createEditTool, createReadTool, createWriteTool } from "@gsd/pi-coding-agent";
4
4
  import { DEFAULT_BASH_TIMEOUT_SECS } from "../constants.js";
5
+ /**
6
+ * Resolve the correct DB path for the current working directory.
7
+ * If `basePath` is inside a `.gsd/worktrees/<MID>/` directory, returns
8
+ * the project root's `.gsd/gsd.db` (shared WAL — R012). Otherwise
9
+ * returns `<basePath>/.gsd/gsd.db`.
10
+ */
11
+ export function resolveProjectRootDbPath(basePath) {
12
+ // Detect worktree: look for `.gsd/worktrees/` in the path segments.
13
+ // A worktree path looks like: /project/root/.gsd/worktrees/M001/...
14
+ // We need to resolve back to /project/root/.gsd/gsd.db
15
+ const marker = `${sep}.gsd${sep}worktrees${sep}`;
16
+ const idx = basePath.indexOf(marker);
17
+ if (idx !== -1) {
18
+ const projectRoot = basePath.slice(0, idx);
19
+ return join(projectRoot, ".gsd", "gsd.db");
20
+ }
21
+ // Also handle forward-slash paths on all platforms
22
+ const fwdMarker = "/.gsd/worktrees/";
23
+ const fwdIdx = basePath.indexOf(fwdMarker);
24
+ if (fwdIdx !== -1) {
25
+ const projectRoot = basePath.slice(0, fwdIdx);
26
+ return join(projectRoot, ".gsd", "gsd.db");
27
+ }
28
+ return join(basePath, ".gsd", "gsd.db");
29
+ }
5
30
  export async function ensureDbOpen() {
6
31
  try {
7
32
  const db = await import("../gsd-db.js");
8
33
  if (db.isDbAvailable())
9
34
  return true;
10
35
  const basePath = process.cwd();
36
+ const dbPath = resolveProjectRootDbPath(basePath);
11
37
  const gsdDir = join(basePath, ".gsd");
12
- const dbPath = join(gsdDir, "gsd.db");
13
- // Open existing DB file
38
+ // Open existing DB file (may be at project root for worktrees)
14
39
  if (existsSync(dbPath)) {
15
40
  return db.openDatabase(dbPath);
16
41
  }
@@ -24,6 +24,13 @@ export function registerHooks(pi) {
24
24
  resetWriteGateState();
25
25
  resetToolCallLoopGuard();
26
26
  await syncServiceTierStatus(ctx);
27
+ // Apply show_token_cost preference (#1515)
28
+ try {
29
+ const { loadEffectiveGSDPreferences } = await import("../preferences.js");
30
+ const prefs = loadEffectiveGSDPreferences();
31
+ process.env.GSD_SHOW_TOKEN_COST = prefs?.preferences.show_token_cost ? "1" : "";
32
+ }
33
+ catch { /* non-fatal */ }
27
34
  if (isFirstSession) {
28
35
  isFirstSession = false;
29
36
  }
@@ -4,7 +4,7 @@ import { join } from "node:path";
4
4
  import { loadRegistry } from "../workflow-templates.js";
5
5
  import { resolveProjectRoot } from "../worktree.js";
6
6
  const gsdHome = process.env.GSD_HOME || join(homedir(), ".gsd");
7
- export const GSD_COMMAND_DESCRIPTION = "GSD — Get Shit Done: /gsd help|start|templates|next|auto|stop|pause|status|widget|visualize|queue|quick|discuss|capture|triage|dispatch|history|undo|rate|skip|export|cleanup|mode|prefs|config|keys|hooks|run-hook|skill-health|doctor|logs|forensics|changelog|migrate|remote|steer|knowledge|new-milestone|parallel|cmux|park|unpark|init|setup|inspect|extensions|update|fast";
7
+ export const GSD_COMMAND_DESCRIPTION = "GSD — Get Shit Done: /gsd help|start|templates|next|auto|stop|pause|status|widget|visualize|queue|quick|discuss|capture|triage|dispatch|history|undo|undo-task|reset-slice|rate|skip|export|cleanup|mode|prefs|config|keys|hooks|run-hook|skill-health|doctor|logs|forensics|changelog|migrate|remote|steer|knowledge|new-milestone|parallel|cmux|park|unpark|init|setup|inspect|extensions|update|fast";
8
8
  export const TOP_LEVEL_SUBCOMMANDS = [
9
9
  { cmd: "help", desc: "Categorized command reference with descriptions" },
10
10
  { cmd: "next", desc: "Explicit step mode (same as /gsd)" },
@@ -23,6 +23,8 @@ export const TOP_LEVEL_SUBCOMMANDS = [
23
23
  { cmd: "dispatch", desc: "Dispatch a specific phase directly" },
24
24
  { cmd: "history", desc: "View execution history" },
25
25
  { cmd: "undo", desc: "Revert last completed unit" },
26
+ { cmd: "undo-task", desc: "Reset a specific task's completion state (DB + markdown)" },
27
+ { cmd: "reset-slice", desc: "Reset a slice and all its tasks (DB + markdown)" },
26
28
  { cmd: "rate", desc: "Rate last unit's model tier (over/ok/under) — improves adaptive routing" },
27
29
  { cmd: "skip", desc: "Prevent a unit from auto-mode dispatch" },
28
30
  { cmd: "export", desc: "Export milestone/slice results" },
@@ -3,7 +3,7 @@ import { handleConfig } from "../../commands-config.js";
3
3
  import { handleDoctor, handleCapture, handleKnowledge, handleRunHook, handleSkillHealth, handleSteer, handleTriage, handleUpdate } from "../../commands-handlers.js";
4
4
  import { handleInspect } from "../../commands-inspect.js";
5
5
  import { handleLogs } from "../../commands-logs.js";
6
- import { handleCleanupBranches, handleCleanupSnapshots, handleSkip, handleCleanupProjects, handleCleanupWorktrees } from "../../commands-maintenance.js";
6
+ import { handleCleanupBranches, handleCleanupSnapshots, handleSkip, handleCleanupProjects, handleCleanupWorktrees, handleRecover } from "../../commands-maintenance.js";
7
7
  import { handleExport } from "../../export.js";
8
8
  import { handleHistory } from "../../history.js";
9
9
  import { handleUndo } from "../../undo.js";
@@ -50,6 +50,16 @@ export async function handleOpsCommand(trimmed, ctx, pi) {
50
50
  await handleHistory(trimmed.replace(/^history\s*/, "").trim(), ctx, projectRoot());
51
51
  return true;
52
52
  }
53
+ if (trimmed === "undo-task" || trimmed.startsWith("undo-task ")) {
54
+ const { handleUndoTask } = await import("../../undo.js");
55
+ await handleUndoTask(trimmed.replace(/^undo-task\s*/, "").trim(), ctx, pi, projectRoot());
56
+ return true;
57
+ }
58
+ if (trimmed === "reset-slice" || trimmed.startsWith("reset-slice ")) {
59
+ const { handleResetSlice } = await import("../../undo.js");
60
+ await handleResetSlice(trimmed.replace(/^reset-slice\s*/, "").trim(), ctx, pi, projectRoot());
61
+ return true;
62
+ }
53
63
  if (trimmed === "undo" || trimmed.startsWith("undo ")) {
54
64
  await handleUndo(trimmed.replace(/^undo\s*/, "").trim(), ctx, pi, projectRoot());
55
65
  return true;
@@ -62,6 +72,10 @@ export async function handleOpsCommand(trimmed, ctx, pi) {
62
72
  await handleSkip(trimmed.replace(/^skip\s*/, "").trim(), ctx, projectRoot());
63
73
  return true;
64
74
  }
75
+ if (trimmed === "recover") {
76
+ await handleRecover(ctx, projectRoot());
77
+ return true;
78
+ }
65
79
  if (trimmed === "export" || trimmed.startsWith("export ")) {
66
80
  await handleExport(trimmed.replace(/^export\s*/, "").trim(), ctx, projectRoot());
67
81
  return true;
@@ -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
  }
@@ -62,7 +62,7 @@ export async function handleDoctor(args, ctx, pi) {
62
62
  scope: effectiveScope,
63
63
  includeWarnings: true,
64
64
  });
65
- const actionable = unresolved.filter(issue => issue.severity === "error" || issue.code === "all_tasks_done_missing_slice_uat" || issue.code === "slice_checked_missing_uat");
65
+ const actionable = unresolved.filter(issue => issue.severity === "error");
66
66
  if (actionable.length === 0) {
67
67
  ctx.ui.notify("Doctor heal found nothing actionable to hand off to the LLM.", "info");
68
68
  return;
@@ -1,7 +1,7 @@
1
1
  /**
2
- * GSD Maintenance — cleanup, skip, and dry-run handlers.
2
+ * GSD Maintenance — cleanup, skip, dry-run, and recover handlers.
3
3
  *
4
- * Contains: handleCleanupBranches, handleCleanupSnapshots, handleCleanupWorktrees, handleSkip, handleDryRun
4
+ * Contains: handleCleanupBranches, handleCleanupSnapshots, handleCleanupWorktrees, handleSkip, handleDryRun, handleRecover
5
5
  */
6
6
  import { deriveState } from "./state.js";
7
7
  import { nativeBranchList, nativeDetectMainBranch, nativeBranchListMerged, nativeBranchDelete, nativeForEachRef, nativeUpdateRef } from "./native-git-bridge.js";
@@ -40,14 +40,32 @@ export async function handleCleanupBranches(ctx, basePath) {
40
40
  try {
41
41
  const { listWorktrees } = await import("./worktree-manager.js");
42
42
  const { resolveMilestoneFile } = await import("./paths.js");
43
- const { loadFile, parseRoadmap } = await import("./files.js");
43
+ const { loadFile } = await import("./files.js");
44
+ const { parseRoadmap } = await import("./parsers-legacy.js");
44
45
  const { isMilestoneComplete } = await import("./state.js");
46
+ const { isDbAvailable, getMilestone } = await import("./gsd-db.js");
45
47
  const attachedBranches = new Set(listWorktrees(basePath).map((wt) => wt.branch));
46
48
  const milestoneBranches = nativeBranchList(basePath, "milestone/*");
47
49
  for (const branch of milestoneBranches) {
48
50
  if (attachedBranches.has(branch))
49
51
  continue;
50
52
  const milestoneId = branch.replace(/^milestone\//, "");
53
+ // DB-first: check milestone status directly
54
+ if (isDbAvailable()) {
55
+ const dbRow = getMilestone(milestoneId);
56
+ if (dbRow) {
57
+ if (dbRow.status !== "complete" && dbRow.status !== "done")
58
+ continue;
59
+ // Milestone is complete per DB — proceed to delete branch
60
+ try {
61
+ nativeBranchDelete(basePath, branch, true);
62
+ deletedStaleMilestones++;
63
+ }
64
+ catch { /* non-fatal */ }
65
+ continue;
66
+ }
67
+ }
68
+ // Filesystem fallback
51
69
  const roadmapPath = resolveMilestoneFile(basePath, milestoneId, "ROADMAP");
52
70
  if (!roadmapPath)
53
71
  continue;
@@ -408,3 +426,60 @@ export async function handleCleanupProjects(args, ctx) {
408
426
  }
409
427
  ctx.ui.notify(lines.join("\n"), "info");
410
428
  }
429
+ /**
430
+ * `gsd recover` — Reconstruct DB hierarchy state from rendered markdown on disk.
431
+ *
432
+ * Deletes milestones, slices, and tasks table rows (preserves decisions,
433
+ * requirements, artifacts, memories), re-runs `migrateHierarchyToDb()` to
434
+ * repopulate from markdown, then calls `deriveState()` to verify sanity.
435
+ *
436
+ * Prints counts of recovered items and the resulting project phase.
437
+ */
438
+ export async function handleRecover(ctx, basePath) {
439
+ const { isDbAvailable: dbAvailable, _getAdapter, transaction: dbTransaction } = await import("./gsd-db.js");
440
+ const { migrateHierarchyToDb } = await import("./md-importer.js");
441
+ const { invalidateStateCache } = await import("./state.js");
442
+ if (!dbAvailable()) {
443
+ ctx.ui.notify("gsd recover: No database open. Run a GSD command first to initialize the DB.", "error");
444
+ return;
445
+ }
446
+ try {
447
+ // 1. Delete + re-populate inside a single transaction for atomicity
448
+ const db = _getAdapter();
449
+ const counts = dbTransaction(() => {
450
+ db.exec("DELETE FROM tasks");
451
+ db.exec("DELETE FROM slices");
452
+ db.exec("DELETE FROM milestones");
453
+ return migrateHierarchyToDb(basePath);
454
+ });
455
+ // 3. Invalidate state cache so deriveState() picks up fresh DB data
456
+ invalidateStateCache();
457
+ // 4. Derive state to verify sanity
458
+ const state = await deriveState(basePath);
459
+ // 5. Report
460
+ const lines = [
461
+ `gsd recover: reconstructed hierarchy from markdown`,
462
+ ` Milestones: ${counts.milestones}`,
463
+ ` Slices: ${counts.slices}`,
464
+ ` Tasks: ${counts.tasks}`,
465
+ ``,
466
+ ` Phase: ${state.phase}`,
467
+ ];
468
+ if (state.activeMilestone) {
469
+ lines.push(` Active: ${state.activeMilestone.id}: ${state.activeMilestone.title}`);
470
+ }
471
+ if (state.activeSlice) {
472
+ lines.push(` Slice: ${state.activeSlice.id}: ${state.activeSlice.title}`);
473
+ }
474
+ if (state.activeTask) {
475
+ lines.push(` Task: ${state.activeTask.id}: ${state.activeTask.title}`);
476
+ }
477
+ process.stderr.write(`gsd-recover: recovered ${counts.milestones}M/${counts.slices}S/${counts.tasks}T hierarchy\n`);
478
+ ctx.ui.notify(lines.join("\n"), "success");
479
+ }
480
+ catch (err) {
481
+ const msg = err instanceof Error ? err.message : String(err);
482
+ process.stderr.write(`gsd-recover: failed: ${msg}\n`);
483
+ ctx.ui.notify(`gsd recover failed: ${msg}`, "error");
484
+ }
485
+ }
@@ -7,8 +7,9 @@
7
7
  */
8
8
  import { truncateToWidth, visibleWidth, matchesKey, Key } from "@gsd/pi-tui";
9
9
  import { deriveState } from "./state.js";
10
- import { loadFile, parseRoadmap, parsePlan } from "./files.js";
11
- import { resolveMilestoneFile, resolveSliceFile } from "./paths.js";
10
+ import { loadFile } from "./files.js";
11
+ import { isDbAvailable, getMilestoneSlices, getSliceTasks } from "./gsd-db.js";
12
+ import { resolveMilestoneFile } from "./paths.js";
12
13
  import { getAutoDashboardData } from "./auto.js";
13
14
  import { getLedger, getProjectTotals, aggregateByPhase, aggregateBySlice, aggregateByModel, aggregateCacheHitRate, formatCost, formatTokenCount, formatCostProjection, } from "./metrics.js";
14
15
  import { loadEffectiveGSDPreferences } from "./preferences.js";
@@ -136,38 +137,38 @@ export class GSDDashboardOverlay {
136
137
  };
137
138
  const roadmapFile = resolveMilestoneFile(base, mid, "ROADMAP");
138
139
  const roadmapContent = roadmapFile ? await loadFile(roadmapFile) : null;
139
- if (roadmapContent) {
140
- const roadmap = parseRoadmap(roadmapContent);
141
- for (const s of roadmap.slices) {
142
- const sliceView = {
143
- id: s.id,
144
- title: s.title,
145
- done: s.done,
146
- risk: s.risk,
147
- active: state.activeSlice?.id === s.id,
148
- tasks: [],
149
- };
150
- if (sliceView.active) {
151
- const planFile = resolveSliceFile(base, mid, s.id, "PLAN");
152
- const planContent = planFile ? await loadFile(planFile) : null;
153
- if (planContent) {
154
- const plan = parsePlan(planContent);
155
- sliceView.taskProgress = {
156
- done: plan.tasks.filter(t => t.done).length,
157
- total: plan.tasks.length,
158
- };
159
- for (const t of plan.tasks) {
160
- sliceView.tasks.push({
161
- id: t.id,
162
- title: t.title,
163
- done: t.done,
164
- active: state.activeTask?.id === t.id,
165
- });
166
- }
140
+ let normSlices = [];
141
+ if (isDbAvailable()) {
142
+ normSlices = getMilestoneSlices(mid).map(s => ({ id: s.id, done: s.status === "complete", title: s.title, risk: s.risk || "medium" }));
143
+ }
144
+ for (const s of normSlices) {
145
+ const sliceView = {
146
+ id: s.id,
147
+ title: s.title,
148
+ done: s.done,
149
+ risk: s.risk,
150
+ active: state.activeSlice?.id === s.id,
151
+ tasks: [],
152
+ };
153
+ if (sliceView.active) {
154
+ // Normalize tasks from DB
155
+ if (isDbAvailable()) {
156
+ const dbTasks = getSliceTasks(mid, s.id);
157
+ sliceView.taskProgress = {
158
+ done: dbTasks.filter(t => t.status === "complete" || t.status === "done").length,
159
+ total: dbTasks.length,
160
+ };
161
+ for (const t of dbTasks) {
162
+ sliceView.tasks.push({
163
+ id: t.id,
164
+ title: t.title,
165
+ done: t.status === "complete" || t.status === "done",
166
+ active: state.activeTask?.id === t.id,
167
+ });
167
168
  }
168
169
  }
169
- view.slices.push(sliceView);
170
170
  }
171
+ view.slices.push(sliceView);
171
172
  }
172
173
  this.milestoneData = view;
173
174
  return true;
@@ -8,12 +8,60 @@
8
8
  // Critical invariant: generated markdown must round-trip through
9
9
  // parseDecisionsTable() and parseRequirementsSections() with field fidelity.
10
10
  import { resolve } from 'node:path';
11
+ import { readFileSync, existsSync } from 'node:fs';
11
12
  import { resolveGsdRootFile } from './paths.js';
12
13
  import { saveFile } from './files.js';
13
14
  import { GSDError, GSD_STALE_STATE, GSD_IO_ERROR } from './errors.js';
14
15
  import { invalidateStateCache } from './state.js';
15
16
  import { clearPathCache } from './paths.js';
16
17
  import { clearParseCache } from './files.js';
18
+ // ─── Freeform Detection ───────────────────────────────────────────────────
19
+ /**
20
+ * Detect whether a DECISIONS.md file is in canonical table format
21
+ * (generated by generateDecisionsMd).
22
+ *
23
+ * Returns true only if the file starts with the canonical header
24
+ * ("# Decisions Register") that generateDecisionsMd produces.
25
+ * Files with freeform content — even if they contain an appended
26
+ * decisions table section — return false so the freeform content
27
+ * is preserved.
28
+ */
29
+ export function isDecisionsTableFormat(content) {
30
+ // The canonical format always starts with "# Decisions Register"
31
+ const firstLine = content.split('\n')[0]?.trim() ?? '';
32
+ if (firstLine !== '# Decisions Register')
33
+ return false;
34
+ // Additionally verify the file has the canonical table header
35
+ return content.includes('| # | When | Scope | Decision | Choice | Rationale | Revisable?');
36
+ }
37
+ /**
38
+ * Generate a minimal decisions table section (header + rows) for appending
39
+ * to a freeform DECISIONS.md file.
40
+ */
41
+ function generateDecisionsAppendBlock(decisions) {
42
+ const lines = [];
43
+ lines.push('');
44
+ lines.push('---');
45
+ lines.push('');
46
+ lines.push('## Decisions Table');
47
+ lines.push('');
48
+ lines.push('| # | When | Scope | Decision | Choice | Rationale | Revisable? | Made By |');
49
+ lines.push('|---|------|-------|----------|--------|-----------|------------|---------|');
50
+ for (const d of decisions) {
51
+ const cells = [
52
+ d.id,
53
+ d.when_context,
54
+ d.scope,
55
+ d.decision,
56
+ d.choice,
57
+ d.rationale,
58
+ d.revisable,
59
+ d.made_by ?? 'agent',
60
+ ].map(cell => (cell ?? '').replace(/\|/g, '\\|'));
61
+ lines.push(`| ${cells.join(' | ')} |`);
62
+ }
63
+ return lines.join('\n') + '\n';
64
+ }
17
65
  // ─── Markdown Generators ──────────────────────────────────────────────────
18
66
  /**
19
67
  * Generate full DECISIONS.md content from an array of Decision objects.
@@ -194,9 +242,37 @@ export async function saveDecisionToDb(fields, basePath) {
194
242
  superseded_by: row['superseded_by'] ?? null,
195
243
  }));
196
244
  }
197
- const md = generateDecisionsMd(allDecisions);
198
245
  const filePath = resolveGsdRootFile(basePath, 'DECISIONS');
199
- await saveFile(filePath, md);
246
+ // Check if existing DECISIONS.md has freeform (non-table) content.
247
+ // If so, preserve that content and append/update the decisions table
248
+ // at the end instead of overwriting the entire file.
249
+ let existingContent = null;
250
+ if (existsSync(filePath)) {
251
+ existingContent = readFileSync(filePath, 'utf-8');
252
+ }
253
+ let md;
254
+ if (existingContent && !isDecisionsTableFormat(existingContent)) {
255
+ // Freeform content detected — preserve it and append decisions table.
256
+ // Strip any previously appended decisions table section to avoid duplication.
257
+ const marker = '---\n\n## Decisions Table';
258
+ const markerIdx = existingContent.indexOf(marker);
259
+ const freeformPart = markerIdx >= 0
260
+ ? existingContent.substring(0, markerIdx).trimEnd()
261
+ : existingContent.trimEnd();
262
+ md = freeformPart + '\n' + generateDecisionsAppendBlock(allDecisions);
263
+ }
264
+ else {
265
+ // Table format or no existing file — full regeneration (original behavior)
266
+ md = generateDecisionsMd(allDecisions);
267
+ }
268
+ try {
269
+ await saveFile(filePath, md);
270
+ }
271
+ catch (diskErr) {
272
+ process.stderr.write(`gsd-db: saveDecisionToDb — disk write failed, rolling back DB row: ${diskErr.message}\n`);
273
+ adapter?.prepare('DELETE FROM decisions WHERE id = :id').run({ ':id': id });
274
+ throw diskErr;
275
+ }
200
276
  // Invalidate file-read caches so deriveState() sees the updated markdown.
201
277
  // Do NOT clear the artifacts table — we just wrote to it intentionally.
202
278
  invalidateStateCache();
@@ -253,7 +329,14 @@ export async function updateRequirementInDb(id, updates, basePath) {
253
329
  const nonSuperseded = allRequirements.filter(r => r.superseded_by == null);
254
330
  const md = generateRequirementsMd(nonSuperseded);
255
331
  const filePath = resolveGsdRootFile(basePath, 'REQUIREMENTS');
256
- await saveFile(filePath, md);
332
+ try {
333
+ await saveFile(filePath, md);
334
+ }
335
+ catch (diskErr) {
336
+ process.stderr.write(`gsd-db: updateRequirementInDb — disk write failed, reverting DB row: ${diskErr.message}\n`);
337
+ db.upsertRequirement(existing);
338
+ throw diskErr;
339
+ }
257
340
  // Invalidate file-read caches so deriveState() sees the updated markdown.
258
341
  // Do NOT clear the artifacts table — we just wrote to it intentionally.
259
342
  invalidateStateCache();
@@ -287,7 +370,15 @@ export async function saveArtifactToDb(opts, basePath) {
287
370
  if (!fullPath.startsWith(gsdDir)) {
288
371
  throw new GSDError(GSD_IO_ERROR, `saveArtifactToDb: path escapes .gsd/ directory: ${opts.path}`);
289
372
  }
290
- await saveFile(fullPath, opts.content);
373
+ try {
374
+ await saveFile(fullPath, opts.content);
375
+ }
376
+ catch (diskErr) {
377
+ process.stderr.write(`gsd-db: saveArtifactToDb — disk write failed, rolling back DB row: ${diskErr.message}\n`);
378
+ const rollbackAdapter = db._getAdapter();
379
+ rollbackAdapter?.prepare('DELETE FROM artifacts WHERE path = :path').run({ ':path': opts.path });
380
+ throw diskErr;
381
+ }
291
382
  // Invalidate file-read caches so deriveState() sees the updated markdown.
292
383
  // Do NOT clear the artifacts table — we just wrote to it intentionally.
293
384
  invalidateStateCache();
@@ -1,8 +1,9 @@
1
1
  // GSD Dispatch Guard — prevents out-of-order slice dispatch
2
- import { readFileSync } from "node:fs";
3
2
  import { resolveMilestoneFile } from "./paths.js";
4
- import { parseRoadmapSlices } from "./roadmap-slices.js";
5
3
  import { findMilestoneIds } from "./guided-flow.js";
4
+ import { isDbAvailable, getMilestoneSlices } from "./gsd-db.js";
5
+ import { parseRoadmap } from "./parsers-legacy.js";
6
+ import { readFileSync } from "node:fs";
6
7
  const SLICE_DISPATCH_TYPES = new Set([
7
8
  "research-slice",
8
9
  "plan-slice",
@@ -10,29 +11,6 @@ const SLICE_DISPATCH_TYPES = new Set([
10
11
  "execute-task",
11
12
  "complete-slice",
12
13
  ]);
13
- /**
14
- * Read a roadmap file from disk (working tree) rather than from a git branch.
15
- *
16
- * Prior implementation used `git show <branch>:<path>` which read committed
17
- * state on a specific branch. This caused false-positive blockers when work
18
- * was committed on a milestone/worktree branch but the integration branch
19
- * (main) hadn't been updated yet — the guard would see prior slices as
20
- * incomplete on main even though they were done in the working tree (#530).
21
- *
22
- * Reading from disk always reflects the latest state, regardless of which
23
- * branch is checked out or whether changes have been committed.
24
- */
25
- function readRoadmapFromDisk(base, milestoneId) {
26
- try {
27
- const absPath = resolveMilestoneFile(base, milestoneId, "ROADMAP");
28
- if (!absPath)
29
- return null;
30
- return readFileSync(absPath, "utf-8").trim();
31
- }
32
- catch {
33
- return null;
34
- }
35
- }
36
14
  export function getPriorSliceCompletionBlocker(base, _mainBranch, unitType, unitId) {
37
15
  if (!SLICE_DISPATCH_TYPES.has(unitType))
38
16
  return null;
@@ -51,11 +29,38 @@ export function getPriorSliceCompletionBlocker(base, _mainBranch, unitType, unit
51
29
  continue;
52
30
  if (resolveMilestoneFile(base, mid, "SUMMARY"))
53
31
  continue;
54
- // Read from disk (working tree) — always has the latest state
55
- const roadmapContent = readRoadmapFromDisk(base, mid);
56
- if (!roadmapContent)
57
- continue;
58
- const slices = parseRoadmapSlices(roadmapContent);
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
+ }
59
64
  if (mid !== targetMid) {
60
65
  const incomplete = slices.find((slice) => !slice.done);
61
66
  if (incomplete) {
@@ -1,7 +1,9 @@
1
1
  import { existsSync, lstatSync, readdirSync, readFileSync, realpathSync, rmSync, statSync } from "node:fs";
2
2
  import { basename, dirname, join, sep } from "node:path";
3
3
  import { readRepoMeta, externalProjectsRoot, cleanNumberedGsdVariants } from "./repo-identity.js";
4
- import { loadFile, parseRoadmap } from "./files.js";
4
+ import { loadFile } from "./files.js";
5
+ import { parseRoadmap as parseLegacyRoadmap } from "./parsers-legacy.js";
6
+ import { isDbAvailable, getMilestoneSlices } from "./gsd-db.js";
5
7
  import { resolveMilestoneFile, milestonesDir, gsdRoot, resolveGsdRootFile } from "./paths.js";
6
8
  import { deriveState, isMilestoneComplete } from "./state.js";
7
9
  import { saveFile } from "./files.js";
@@ -37,12 +39,19 @@ export async function checkGitHealth(basePath, issues, fixesApplied, shouldFix,
37
39
  // Check if milestone is complete via roadmap
38
40
  let isComplete = false;
39
41
  if (milestoneEntry) {
40
- const roadmapPath = resolveMilestoneFile(basePath, milestoneId, "ROADMAP");
41
- const roadmapContent = roadmapPath ? await loadFile(roadmapPath) : null;
42
- if (roadmapContent) {
43
- const roadmap = parseRoadmap(roadmapContent);
44
- isComplete = isMilestoneComplete(roadmap);
42
+ if (isDbAvailable()) {
43
+ const dbSlices = getMilestoneSlices(milestoneId);
44
+ isComplete = dbSlices.length > 0 && dbSlices.every(s => s.status === "complete");
45
45
  }
46
+ else {
47
+ const roadmapPath = resolveMilestoneFile(basePath, milestoneId, "ROADMAP");
48
+ const roadmapContent = roadmapPath ? await loadFile(roadmapPath) : null;
49
+ if (roadmapContent) {
50
+ const roadmap = parseLegacyRoadmap(roadmapContent);
51
+ isComplete = isMilestoneComplete(roadmap);
52
+ }
53
+ }
54
+ // When DB unavailable and no roadmap, isComplete stays false
46
55
  }
47
56
  if (isComplete) {
48
57
  issues.push({
@@ -82,11 +91,19 @@ export async function checkGitHealth(basePath, issues, fixesApplied, shouldFix,
82
91
  continue;
83
92
  const milestoneId = branch.replace(/^milestone\//, "");
84
93
  const roadmapPath = resolveMilestoneFile(basePath, milestoneId, "ROADMAP");
85
- const roadmapContent = roadmapPath ? await loadFile(roadmapPath) : null;
86
- if (!roadmapContent)
87
- continue;
88
- const roadmap = parseRoadmap(roadmapContent);
89
- if (isMilestoneComplete(roadmap)) {
94
+ let branchMilestoneComplete = false;
95
+ if (isDbAvailable()) {
96
+ const dbSlices = getMilestoneSlices(milestoneId);
97
+ branchMilestoneComplete = dbSlices.length > 0 && dbSlices.every(s => s.status === "complete");
98
+ }
99
+ else {
100
+ const roadmapContent = roadmapPath ? await loadFile(roadmapPath) : null;
101
+ if (!roadmapContent)
102
+ continue;
103
+ const roadmap = parseLegacyRoadmap(roadmapContent);
104
+ branchMilestoneComplete = isMilestoneComplete(roadmap);
105
+ }
106
+ if (branchMilestoneComplete) {
90
107
  issues.push({
91
108
  severity: "info",
92
109
  code: "stale_milestone_branch",
@@ -19,6 +19,27 @@ const MIN_DISK_BYTES = 500 * 1024 * 1024;
19
19
  /** Timeout for external commands (ms). */
20
20
  const CMD_TIMEOUT = 5_000;
21
21
  // ── Helpers ────────────────────────────────────────────────────────────────
22
+ /** Worktree sentinel — path segment that marks an auto-worktree directory. */
23
+ const WORKTREE_PATH_SEGMENT = `${join(".gsd", "worktrees")}/`;
24
+ /**
25
+ * Resolve the project root when running inside a `.gsd/worktrees/<name>/`
26
+ * auto-worktree. Returns `null` if not in a worktree.
27
+ *
28
+ * Detection order:
29
+ * 1. `GSD_WORKTREE` env var (set by the worktree launcher)
30
+ * 2. `.gsd/worktrees/` segment in basePath
31
+ */
32
+ function resolveWorktreeProjectRoot(basePath) {
33
+ const envRoot = process.env.GSD_WORKTREE;
34
+ if (envRoot)
35
+ return envRoot;
36
+ const normalised = basePath.replace(/\\/g, "/");
37
+ const idx = normalised.indexOf(WORKTREE_PATH_SEGMENT.replace(/\\/g, "/"));
38
+ if (idx === -1)
39
+ return null;
40
+ // Everything before `.gsd/worktrees/` is the project root
41
+ return basePath.slice(0, idx);
42
+ }
22
43
  function tryExec(cmd, cwd) {
23
44
  try {
24
45
  return execSync(cmd, {
@@ -87,6 +108,13 @@ function checkDependenciesInstalled(basePath) {
87
108
  return null;
88
109
  const nodeModules = join(basePath, "node_modules");
89
110
  if (!existsSync(nodeModules)) {
111
+ // In auto-worktrees node_modules is absent by design — the worktree
112
+ // symlinks to (or expects) the project root's copy. Fall back to
113
+ // checking the project root before reporting an error (#2303).
114
+ const projectRoot = resolveWorktreeProjectRoot(basePath);
115
+ if (projectRoot && existsSync(join(projectRoot, "node_modules"))) {
116
+ return { name: "dependencies", status: "ok", message: "Dependencies installed (project root)" };
117
+ }
90
118
  return {
91
119
  name: "dependencies",
92
120
  status: "error",