gsd-pi 2.44.0 → 2.45.0-dev.1afbdaa

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 (608) hide show
  1. package/README.md +30 -12
  2. package/dist/help-text.js +1 -1
  3. package/dist/loader.js +34 -0
  4. package/dist/resources/extensions/gsd/activity-log.js +7 -0
  5. package/dist/resources/extensions/gsd/auto/infra-errors.js +3 -0
  6. package/dist/resources/extensions/gsd/auto/phases.js +63 -77
  7. package/dist/resources/extensions/gsd/auto/run-unit.js +6 -3
  8. package/dist/resources/extensions/gsd/auto/session.js +0 -11
  9. package/dist/resources/extensions/gsd/auto-artifact-paths.js +112 -0
  10. package/dist/resources/extensions/gsd/auto-post-unit.js +25 -96
  11. package/dist/resources/extensions/gsd/auto-prompts.js +24 -1
  12. package/dist/resources/extensions/gsd/auto-start.js +33 -5
  13. package/dist/resources/extensions/gsd/auto-timers.js +57 -3
  14. package/dist/resources/extensions/gsd/auto-worktree-sync.js +4 -0
  15. package/dist/resources/extensions/gsd/auto-worktree.js +14 -10
  16. package/dist/resources/extensions/gsd/auto.js +42 -60
  17. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +170 -11
  18. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +18 -0
  19. package/dist/resources/extensions/gsd/bootstrap/system-context.js +46 -12
  20. package/dist/resources/extensions/gsd/commands/catalog.js +7 -1
  21. package/dist/resources/extensions/gsd/commands/context.js +0 -4
  22. package/dist/resources/extensions/gsd/commands/handlers/core.js +2 -0
  23. package/dist/resources/extensions/gsd/commands/handlers/ops.js +10 -0
  24. package/dist/resources/extensions/gsd/commands/handlers/parallel.js +1 -1
  25. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +5 -0
  26. package/dist/resources/extensions/gsd/commands-mcp-status.js +187 -0
  27. package/dist/resources/extensions/gsd/crash-recovery.js +2 -4
  28. package/dist/resources/extensions/gsd/dashboard-overlay.js +0 -44
  29. package/dist/resources/extensions/gsd/db-writer.js +40 -22
  30. package/dist/resources/extensions/gsd/doctor-checks.js +167 -2
  31. package/dist/resources/extensions/gsd/doctor.js +13 -3
  32. package/dist/resources/extensions/gsd/git-service.js +8 -3
  33. package/dist/resources/extensions/gsd/gsd-db.js +28 -4
  34. package/dist/resources/extensions/gsd/guided-flow.js +1 -2
  35. package/dist/resources/extensions/gsd/markdown-renderer.js +1 -1
  36. package/dist/resources/extensions/gsd/parallel-merge.js +1 -1
  37. package/dist/resources/extensions/gsd/parallel-orchestrator.js +5 -18
  38. package/dist/resources/extensions/gsd/preferences-types.js +2 -2
  39. package/dist/resources/extensions/gsd/preferences.js +17 -5
  40. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +21 -10
  41. package/dist/resources/extensions/gsd/prompts/complete-slice.md +10 -23
  42. package/dist/resources/extensions/gsd/prompts/discuss.md +2 -2
  43. package/dist/resources/extensions/gsd/prompts/execute-task.md +5 -15
  44. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  45. package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
  46. package/dist/resources/extensions/gsd/prompts/guided-plan-slice.md +1 -1
  47. package/dist/resources/extensions/gsd/prompts/guided-research-slice.md +1 -1
  48. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  49. package/dist/resources/extensions/gsd/prompts/plan-slice.md +5 -3
  50. package/dist/resources/extensions/gsd/prompts/queue.md +2 -2
  51. package/dist/resources/extensions/gsd/prompts/quick-task.md +2 -0
  52. package/dist/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
  53. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -6
  54. package/dist/resources/extensions/gsd/prompts/replan-slice.md +3 -14
  55. package/dist/resources/extensions/gsd/prompts/research-slice.md +3 -3
  56. package/dist/resources/extensions/gsd/prompts/rethink.md +83 -0
  57. package/dist/resources/extensions/gsd/prompts/system.md +1 -1
  58. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +7 -37
  59. package/dist/resources/extensions/gsd/provider-error-pause.js +7 -0
  60. package/dist/resources/extensions/gsd/repo-identity.js +45 -7
  61. package/dist/resources/extensions/gsd/rethink.js +115 -0
  62. package/dist/resources/extensions/gsd/session-lock.js +1 -3
  63. package/dist/resources/extensions/gsd/state.js +48 -3
  64. package/dist/resources/extensions/gsd/sync-lock.js +89 -0
  65. package/dist/resources/extensions/gsd/tools/complete-milestone.js +61 -11
  66. package/dist/resources/extensions/gsd/tools/complete-slice.js +56 -11
  67. package/dist/resources/extensions/gsd/tools/complete-task.js +50 -2
  68. package/dist/resources/extensions/gsd/tools/plan-milestone.js +37 -1
  69. package/dist/resources/extensions/gsd/tools/plan-slice.js +31 -1
  70. package/dist/resources/extensions/gsd/tools/plan-task.js +28 -1
  71. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +32 -2
  72. package/dist/resources/extensions/gsd/tools/reopen-slice.js +86 -0
  73. package/dist/resources/extensions/gsd/tools/reopen-task.js +90 -0
  74. package/dist/resources/extensions/gsd/tools/replan-slice.js +34 -2
  75. package/dist/resources/extensions/gsd/tools/validate-milestone.js +88 -0
  76. package/dist/resources/extensions/gsd/unit-ownership.js +85 -0
  77. package/dist/resources/extensions/gsd/workflow-events.js +102 -0
  78. package/dist/resources/extensions/gsd/workflow-logger.js +193 -0
  79. package/dist/resources/extensions/gsd/workflow-manifest.js +244 -0
  80. package/dist/resources/extensions/gsd/workflow-migration.js +280 -0
  81. package/dist/resources/extensions/gsd/workflow-projections.js +373 -0
  82. package/dist/resources/extensions/gsd/workflow-reconcile.js +411 -0
  83. package/dist/resources/extensions/gsd/worktree-manager.js +34 -3
  84. package/dist/resources/extensions/gsd/worktree-resolver.js +43 -0
  85. package/dist/resources/extensions/gsd/write-intercept.js +84 -0
  86. package/dist/resources/extensions/mcp-client/index.js +14 -0
  87. package/dist/resources/extensions/voice/index.js +11 -16
  88. package/dist/resources/extensions/voice/linux-ready.js +67 -0
  89. package/dist/web/standalone/.next/BUILD_ID +1 -1
  90. package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
  91. package/dist/web/standalone/.next/build-manifest.json +4 -4
  92. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  93. package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
  94. package/dist/web/standalone/.next/required-server-files.json +3 -3
  95. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  96. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  97. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  98. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  100. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  101. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  102. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  103. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  104. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  106. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  107. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  108. package/dist/web/standalone/.next/server/app/_not-found.rsc +5 -5
  109. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +5 -5
  110. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
  112. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  115. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  122. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +5 -5
  160. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  166. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  180. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  182. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  184. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  186. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/app/index.html +1 -1
  196. package/dist/web/standalone/.next/server/app/index.rsc +6 -6
  197. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  198. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +6 -6
  199. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  200. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
  201. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  202. package/dist/web/standalone/.next/server/app/page.js +2 -2
  203. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  204. package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
  205. package/dist/web/standalone/.next/server/chunks/229.js +1 -1
  206. package/dist/web/standalone/.next/server/chunks/471.js +3 -3
  207. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  208. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  209. package/dist/web/standalone/.next/server/middleware.js +2 -2
  210. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  211. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  212. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  213. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  214. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  215. package/dist/web/standalone/.next/static/chunks/4024.11ca5c01938e5948.js +9 -0
  216. package/dist/web/standalone/.next/static/chunks/{3721.bf31263de6d5fa46.js → 485.243af25f0cdf50d6.js} +2 -2
  217. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  218. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  219. package/dist/web/standalone/.next/static/chunks/app/page-6654a8cca61a3d1c.js +1 -0
  220. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  221. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  222. package/dist/web/standalone/.next/static/chunks/webpack-0a4cd455ec4197d2.js +1 -0
  223. package/dist/web/standalone/.next/static/css/dd4ae3f58ac9b600.css +1 -0
  224. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  225. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  226. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  227. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  228. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  229. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  230. package/dist/web/standalone/server.js +1 -1
  231. package/package.json +2 -1
  232. package/packages/native/dist/stream-process/index.js +2 -2
  233. package/packages/native/src/__tests__/stream-process.test.mjs +34 -0
  234. package/packages/native/src/stream-process/index.ts +2 -2
  235. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +3 -1
  236. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  237. package/packages/pi-coding-agent/dist/core/auth-storage.js +15 -1
  238. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  239. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +6 -8
  240. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  241. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts.map +1 -1
  242. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +2 -0
  243. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -1
  244. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +24 -26
  245. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  246. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +2 -1
  247. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  248. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  249. package/packages/pi-coding-agent/dist/core/fs-utils.test.js +29 -48
  250. package/packages/pi-coding-agent/dist/core/fs-utils.test.js.map +1 -1
  251. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.d.ts +4 -0
  252. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.d.ts.map +1 -1
  253. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.js +10 -5
  254. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.js.map +1 -1
  255. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.test.d.ts +2 -0
  256. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.test.d.ts.map +1 -0
  257. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.test.js +185 -0
  258. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.test.js.map +1 -0
  259. package/packages/pi-coding-agent/dist/core/local-model-check.d.ts +15 -0
  260. package/packages/pi-coding-agent/dist/core/local-model-check.d.ts.map +1 -0
  261. package/packages/pi-coding-agent/dist/core/local-model-check.js +41 -0
  262. package/packages/pi-coding-agent/dist/core/local-model-check.js.map +1 -0
  263. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +239 -10
  264. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  265. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +13 -1
  266. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  267. package/packages/pi-coding-agent/dist/core/model-registry.js +40 -3
  268. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  269. package/packages/pi-coding-agent/dist/core/package-commands.test.js +206 -195
  270. package/packages/pi-coding-agent/dist/core/package-commands.test.js.map +1 -1
  271. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +34 -44
  272. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
  273. package/packages/pi-coding-agent/dist/core/session-manager.test.js +30 -34
  274. package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
  275. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
  276. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  277. package/packages/pi-coding-agent/dist/core/settings-manager.js +6 -0
  278. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +10 -12
  280. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -1
  281. package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
  282. package/packages/pi-coding-agent/dist/main.js +17 -0
  283. package/packages/pi-coding-agent/dist/main.js.map +1 -1
  284. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.d.ts +2 -0
  285. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.d.ts.map +1 -0
  286. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.js +32 -0
  287. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.js.map +1 -0
  288. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +3 -1
  289. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  290. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +8 -1
  291. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  292. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  293. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  294. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +12 -0
  295. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
  296. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.d.ts +15 -0
  297. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.d.ts.map +1 -0
  298. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.js +40 -0
  299. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.js.map +1 -0
  300. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  301. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +4 -1
  302. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  303. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts +5 -2
  304. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  305. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +13 -2
  306. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
  307. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  308. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +17 -8
  309. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  310. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  311. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +7 -3
  312. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  313. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js +43 -47
  314. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js.map +1 -1
  315. package/packages/pi-coding-agent/package.json +1 -1
  316. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +7 -7
  317. package/packages/pi-coding-agent/src/core/auth-storage.ts +15 -1
  318. package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +2 -0
  319. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +26 -26
  320. package/packages/pi-coding-agent/src/core/extensions/types.ts +2 -1
  321. package/packages/pi-coding-agent/src/core/fs-utils.test.ts +31 -43
  322. package/packages/pi-coding-agent/src/core/lifecycle-hooks.test.ts +227 -0
  323. package/packages/pi-coding-agent/src/core/lifecycle-hooks.ts +11 -5
  324. package/packages/pi-coding-agent/src/core/local-model-check.ts +45 -0
  325. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +297 -11
  326. package/packages/pi-coding-agent/src/core/model-registry.ts +51 -4
  327. package/packages/pi-coding-agent/src/core/package-commands.test.ts +227 -205
  328. package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +40 -45
  329. package/packages/pi-coding-agent/src/core/session-manager.test.ts +33 -33
  330. package/packages/pi-coding-agent/src/core/settings-manager.ts +9 -0
  331. package/packages/pi-coding-agent/src/core/tools/edit-diff.test.ts +17 -17
  332. package/packages/pi-coding-agent/src/main.ts +19 -0
  333. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/timestamp.test.ts +38 -0
  334. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +10 -0
  335. package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +15 -0
  336. package/packages/pi-coding-agent/src/modes/interactive/components/timestamp.ts +48 -0
  337. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +3 -1
  338. package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +18 -3
  339. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +16 -7
  340. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +8 -1
  341. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.test.ts +74 -74
  342. package/pkg/package.json +1 -1
  343. package/src/resources/extensions/gsd/activity-log.ts +1 -0
  344. package/src/resources/extensions/gsd/auto/infra-errors.ts +3 -0
  345. package/src/resources/extensions/gsd/auto/loop-deps.ts +0 -19
  346. package/src/resources/extensions/gsd/auto/phases.ts +69 -91
  347. package/src/resources/extensions/gsd/auto/run-unit.ts +6 -3
  348. package/src/resources/extensions/gsd/auto/session.ts +0 -18
  349. package/src/resources/extensions/gsd/auto-artifact-paths.ts +131 -0
  350. package/src/resources/extensions/gsd/auto-dashboard.ts +0 -1
  351. package/src/resources/extensions/gsd/auto-post-unit.ts +25 -106
  352. package/src/resources/extensions/gsd/auto-prompts.ts +24 -1
  353. package/src/resources/extensions/gsd/auto-start.ts +40 -5
  354. package/src/resources/extensions/gsd/auto-timers.ts +64 -3
  355. package/src/resources/extensions/gsd/auto-worktree-sync.ts +5 -0
  356. package/src/resources/extensions/gsd/auto-worktree.ts +17 -11
  357. package/src/resources/extensions/gsd/auto.ts +44 -86
  358. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +162 -11
  359. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +22 -0
  360. package/src/resources/extensions/gsd/bootstrap/system-context.ts +48 -11
  361. package/src/resources/extensions/gsd/commands/catalog.ts +7 -1
  362. package/src/resources/extensions/gsd/commands/context.ts +0 -5
  363. package/src/resources/extensions/gsd/commands/handlers/core.ts +2 -0
  364. package/src/resources/extensions/gsd/commands/handlers/ops.ts +10 -0
  365. package/src/resources/extensions/gsd/commands/handlers/parallel.ts +1 -1
  366. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +8 -0
  367. package/src/resources/extensions/gsd/commands-mcp-status.ts +247 -0
  368. package/src/resources/extensions/gsd/crash-recovery.ts +1 -5
  369. package/src/resources/extensions/gsd/dashboard-overlay.ts +0 -50
  370. package/src/resources/extensions/gsd/db-writer.ts +41 -27
  371. package/src/resources/extensions/gsd/doctor-checks.ts +180 -2
  372. package/src/resources/extensions/gsd/doctor-types.ts +7 -1
  373. package/src/resources/extensions/gsd/doctor.ts +13 -4
  374. package/src/resources/extensions/gsd/git-service.ts +6 -2
  375. package/src/resources/extensions/gsd/gsd-db.ts +32 -4
  376. package/src/resources/extensions/gsd/guided-flow.ts +1 -2
  377. package/src/resources/extensions/gsd/journal.ts +6 -1
  378. package/src/resources/extensions/gsd/markdown-renderer.ts +1 -1
  379. package/src/resources/extensions/gsd/parallel-merge.ts +1 -1
  380. package/src/resources/extensions/gsd/parallel-orchestrator.ts +5 -21
  381. package/src/resources/extensions/gsd/preferences-types.ts +2 -2
  382. package/src/resources/extensions/gsd/preferences.ts +18 -4
  383. package/src/resources/extensions/gsd/prompts/complete-milestone.md +21 -10
  384. package/src/resources/extensions/gsd/prompts/complete-slice.md +10 -23
  385. package/src/resources/extensions/gsd/prompts/discuss.md +2 -2
  386. package/src/resources/extensions/gsd/prompts/execute-task.md +5 -15
  387. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  388. package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
  389. package/src/resources/extensions/gsd/prompts/guided-plan-slice.md +1 -1
  390. package/src/resources/extensions/gsd/prompts/guided-research-slice.md +1 -1
  391. package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  392. package/src/resources/extensions/gsd/prompts/plan-slice.md +5 -3
  393. package/src/resources/extensions/gsd/prompts/queue.md +2 -2
  394. package/src/resources/extensions/gsd/prompts/quick-task.md +2 -0
  395. package/src/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
  396. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -6
  397. package/src/resources/extensions/gsd/prompts/replan-slice.md +3 -14
  398. package/src/resources/extensions/gsd/prompts/research-slice.md +3 -3
  399. package/src/resources/extensions/gsd/prompts/rethink.md +83 -0
  400. package/src/resources/extensions/gsd/prompts/system.md +1 -1
  401. package/src/resources/extensions/gsd/prompts/validate-milestone.md +7 -37
  402. package/src/resources/extensions/gsd/provider-error-pause.ts +9 -0
  403. package/src/resources/extensions/gsd/repo-identity.ts +46 -7
  404. package/src/resources/extensions/gsd/rethink.ts +154 -0
  405. package/src/resources/extensions/gsd/session-lock.ts +0 -4
  406. package/src/resources/extensions/gsd/state.ts +49 -1
  407. package/src/resources/extensions/gsd/sync-lock.ts +94 -0
  408. package/src/resources/extensions/gsd/tests/all-milestones-complete-merge.test.ts +99 -99
  409. package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +19 -29
  410. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +6 -10
  411. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +43 -57
  412. package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +88 -0
  413. package/src/resources/extensions/gsd/tests/auto-preflight.test.ts +11 -13
  414. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +465 -523
  415. package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +73 -75
  416. package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +34 -56
  417. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +533 -656
  418. package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +165 -143
  419. package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +29 -52
  420. package/src/resources/extensions/gsd/tests/captures.test.ts +148 -176
  421. package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +32 -33
  422. package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +141 -143
  423. package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +25 -25
  424. package/src/resources/extensions/gsd/tests/commands-logs.test.ts +81 -81
  425. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +134 -59
  426. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +15 -14
  427. package/src/resources/extensions/gsd/tests/complete-task.test.ts +27 -12
  428. package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +114 -0
  429. package/src/resources/extensions/gsd/tests/context-store.test.ts +354 -367
  430. package/src/resources/extensions/gsd/tests/continue-here.test.ts +68 -72
  431. package/src/resources/extensions/gsd/tests/cost-projection.test.ts +92 -106
  432. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +26 -40
  433. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +0 -3
  434. package/src/resources/extensions/gsd/tests/dashboard-budget.test.ts +220 -237
  435. package/src/resources/extensions/gsd/tests/db-writer.test.ts +465 -416
  436. package/src/resources/extensions/gsd/tests/definition-loader.test.ts +76 -92
  437. package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +68 -83
  438. package/src/resources/extensions/gsd/tests/derive-state-db-disk-reconcile.test.ts +121 -0
  439. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +210 -181
  440. package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +78 -101
  441. package/src/resources/extensions/gsd/tests/derive-state.test.ts +192 -227
  442. package/src/resources/extensions/gsd/tests/detection.test.ts +232 -278
  443. package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +30 -34
  444. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +164 -180
  445. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +43 -49
  446. package/src/resources/extensions/gsd/tests/dispatch-uat-last-completed.test.ts +28 -32
  447. package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +27 -29
  448. package/src/resources/extensions/gsd/tests/doctor-delimiter-fix.test.ts +34 -38
  449. package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +54 -75
  450. package/src/resources/extensions/gsd/tests/doctor-environment-worktree.test.ts +21 -32
  451. package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +72 -97
  452. package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +38 -44
  453. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +104 -145
  454. package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +84 -106
  455. package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +54 -60
  456. package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +72 -93
  457. package/src/resources/extensions/gsd/tests/doctor.test.ts +104 -134
  458. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +123 -131
  459. package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +120 -0
  460. package/src/resources/extensions/gsd/tests/exit-command.test.ts +20 -24
  461. package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +48 -57
  462. package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +5 -7
  463. package/src/resources/extensions/gsd/tests/flag-file-db.test.ts +30 -42
  464. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +198 -206
  465. package/src/resources/extensions/gsd/tests/git-locale.test.ts +13 -27
  466. package/src/resources/extensions/gsd/tests/git-service.test.ts +285 -388
  467. package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +31 -39
  468. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +63 -69
  469. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +255 -264
  470. package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +108 -119
  471. package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +81 -103
  472. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +229 -262
  473. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +13 -13
  474. package/src/resources/extensions/gsd/tests/health-widget.test.ts +29 -37
  475. package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +82 -103
  476. package/src/resources/extensions/gsd/tests/infra-error.test.ts +20 -2
  477. package/src/resources/extensions/gsd/tests/inherited-repo-home-dir.test.ts +121 -0
  478. package/src/resources/extensions/gsd/tests/init-wizard.test.ts +16 -18
  479. package/src/resources/extensions/gsd/tests/integration-edge.test.ts +41 -46
  480. package/src/resources/extensions/gsd/tests/integration-lifecycle.test.ts +42 -53
  481. package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +75 -91
  482. package/src/resources/extensions/gsd/tests/integration-proof.test.ts +33 -42
  483. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +0 -3
  484. package/src/resources/extensions/gsd/tests/knowledge.test.ts +89 -0
  485. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +150 -194
  486. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +103 -0
  487. package/src/resources/extensions/gsd/tests/md-importer.test.ts +101 -125
  488. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +45 -54
  489. package/src/resources/extensions/gsd/tests/memory-store.test.ts +81 -94
  490. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +66 -0
  491. package/src/resources/extensions/gsd/tests/migrate-command.test.ts +57 -66
  492. package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +83 -93
  493. package/src/resources/extensions/gsd/tests/migrate-parser.test.ts +161 -170
  494. package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +125 -141
  495. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +107 -131
  496. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +87 -96
  497. package/src/resources/extensions/gsd/tests/migrate-writer.test.ts +125 -164
  498. package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +8 -9
  499. package/src/resources/extensions/gsd/tests/must-have-parser.test.ts +81 -94
  500. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +75 -37
  501. package/src/resources/extensions/gsd/tests/overrides.test.ts +99 -106
  502. package/src/resources/extensions/gsd/tests/parallel-budget-atomicity.test.ts +0 -1
  503. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +39 -53
  504. package/src/resources/extensions/gsd/tests/parallel-merge.test.ts +7 -8
  505. package/src/resources/extensions/gsd/tests/parallel-orchestration.test.ts +20 -24
  506. package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +24 -29
  507. package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +66 -83
  508. package/src/resources/extensions/gsd/tests/park-edge-cases.test.ts +54 -77
  509. package/src/resources/extensions/gsd/tests/park-milestone.test.ts +68 -115
  510. package/src/resources/extensions/gsd/tests/parsers.test.ts +546 -611
  511. package/src/resources/extensions/gsd/tests/paths.test.ts +72 -87
  512. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +9 -6
  513. package/src/resources/extensions/gsd/tests/post-mutation-hook.test.ts +171 -0
  514. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +77 -117
  515. package/src/resources/extensions/gsd/tests/preferences.test.ts +34 -9
  516. package/src/resources/extensions/gsd/tests/projection-regression.test.ts +174 -0
  517. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +26 -21
  518. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +56 -56
  519. package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +93 -119
  520. package/src/resources/extensions/gsd/tests/queue-order.test.ts +70 -82
  521. package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +42 -55
  522. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +100 -0
  523. package/src/resources/extensions/gsd/tests/quick-branch-lifecycle.test.ts +45 -73
  524. package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +28 -38
  525. package/src/resources/extensions/gsd/tests/recovery-attempts-reset.test.ts +176 -0
  526. package/src/resources/extensions/gsd/tests/reopen-slice.test.ts +155 -0
  527. package/src/resources/extensions/gsd/tests/reopen-task.test.ts +165 -0
  528. package/src/resources/extensions/gsd/tests/replan-slice.test.ts +73 -80
  529. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +71 -74
  530. package/src/resources/extensions/gsd/tests/requirements.test.ts +70 -75
  531. package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +44 -66
  532. package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +114 -181
  533. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +63 -65
  534. package/src/resources/extensions/gsd/tests/run-uat.test.ts +66 -128
  535. package/src/resources/extensions/gsd/tests/session-lock-multipath.test.ts +18 -25
  536. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +37 -47
  537. package/src/resources/extensions/gsd/tests/shared-wal.test.ts +19 -26
  538. package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +63 -0
  539. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +6 -8
  540. package/src/resources/extensions/gsd/tests/stop-auto-merge-back.test.ts +67 -0
  541. package/src/resources/extensions/gsd/tests/stop-auto-remote.test.ts +2 -3
  542. package/src/resources/extensions/gsd/tests/survivor-branch-complete.test.ts +108 -0
  543. package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +22 -28
  544. package/src/resources/extensions/gsd/tests/sync-lock.test.ts +122 -0
  545. package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +49 -0
  546. package/src/resources/extensions/gsd/tests/token-savings.test.ts +54 -56
  547. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +23 -25
  548. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +10 -11
  549. package/src/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +66 -82
  550. package/src/resources/extensions/gsd/tests/unit-ownership.test.ts +175 -0
  551. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +46 -47
  552. package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -22
  553. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -86
  554. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +41 -43
  555. package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +94 -96
  556. package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +11 -13
  557. package/src/resources/extensions/gsd/tests/worker-registry.test.ts +27 -29
  558. package/src/resources/extensions/gsd/tests/workflow-events.test.ts +205 -0
  559. package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +275 -0
  560. package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +186 -0
  561. package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +171 -0
  562. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +50 -52
  563. package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +10 -13
  564. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +14 -18
  565. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +38 -39
  566. package/src/resources/extensions/gsd/tests/worktree-e2e.test.ts +17 -21
  567. package/src/resources/extensions/gsd/tests/worktree-health.test.ts +25 -30
  568. package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +30 -37
  569. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +220 -0
  570. package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +65 -0
  571. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +15 -22
  572. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +59 -66
  573. package/src/resources/extensions/gsd/tests/worktree.test.ts +44 -50
  574. package/src/resources/extensions/gsd/tests/write-intercept.test.ts +76 -0
  575. package/src/resources/extensions/gsd/tools/complete-milestone.ts +74 -11
  576. package/src/resources/extensions/gsd/tools/complete-slice.ts +68 -11
  577. package/src/resources/extensions/gsd/tools/complete-task.ts +63 -1
  578. package/src/resources/extensions/gsd/tools/plan-milestone.ts +45 -0
  579. package/src/resources/extensions/gsd/tools/plan-slice.ts +40 -0
  580. package/src/resources/extensions/gsd/tools/plan-task.ts +37 -1
  581. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +39 -1
  582. package/src/resources/extensions/gsd/tools/reopen-slice.ts +125 -0
  583. package/src/resources/extensions/gsd/tools/reopen-task.ts +129 -0
  584. package/src/resources/extensions/gsd/tools/replan-slice.ts +41 -1
  585. package/src/resources/extensions/gsd/tools/validate-milestone.ts +127 -0
  586. package/src/resources/extensions/gsd/types.ts +8 -0
  587. package/src/resources/extensions/gsd/unit-ownership.ts +104 -0
  588. package/src/resources/extensions/gsd/workflow-events.ts +154 -0
  589. package/src/resources/extensions/gsd/workflow-logger.ts +243 -0
  590. package/src/resources/extensions/gsd/workflow-manifest.ts +334 -0
  591. package/src/resources/extensions/gsd/workflow-migration.ts +345 -0
  592. package/src/resources/extensions/gsd/workflow-projections.ts +425 -0
  593. package/src/resources/extensions/gsd/workflow-reconcile.ts +503 -0
  594. package/src/resources/extensions/gsd/worktree-manager.ts +41 -5
  595. package/src/resources/extensions/gsd/worktree-resolver.ts +44 -0
  596. package/src/resources/extensions/gsd/write-intercept.ts +90 -0
  597. package/src/resources/extensions/mcp-client/index.ts +20 -0
  598. package/src/resources/extensions/voice/index.ts +11 -21
  599. package/src/resources/extensions/voice/linux-ready.ts +87 -0
  600. package/src/resources/extensions/voice/tests/linux-ready.test.ts +124 -0
  601. package/dist/web/standalone/.next/static/chunks/4024.0de81b543b28b9fe.js +0 -9
  602. package/dist/web/standalone/.next/static/chunks/app/page-7e9530a7122506c5.js +0 -1
  603. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  604. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  605. package/dist/web/standalone/.next/static/chunks/webpack-9014b5adb127a98a.js +0 -1
  606. package/dist/web/standalone/.next/static/css/8a727f372cf53002.css +0 -1
  607. /package/dist/web/standalone/.next/static/{mgkxN0mGP6gSUmGPEzbk_ → j-BskPs0nxxPeYY-bSrab}/_buildManifest.js +0 -0
  608. /package/dist/web/standalone/.next/static/{mgkxN0mGP6gSUmGPEzbk_ → j-BskPs0nxxPeYY-bSrab}/_ssgManifest.js +0 -0
@@ -0,0 +1,411 @@
1
+ import { join } from "node:path";
2
+ import { mkdirSync, existsSync, readFileSync, unlinkSync } from "node:fs";
3
+ import { readEvents, findForkPoint, appendEvent, getSessionId } from "./workflow-events.js";
4
+ import { transaction, updateTaskStatus, updateSliceStatus, insertVerificationEvidence, upsertDecision, openDatabase, } from "./gsd-db.js";
5
+ import { writeManifest } from "./workflow-manifest.js";
6
+ import { atomicWriteSync } from "./atomic-write.js";
7
+ import { acquireSyncLock, releaseSyncLock } from "./sync-lock.js";
8
+ // ─── replayEvents ─────────────────────────────────────────────────────────────
9
+ /**
10
+ * Replay a list of WorkflowEvents by dispatching each to the appropriate
11
+ * gsd-db function. This replaces the old engine.replayAll() pattern with
12
+ * direct DB calls.
13
+ */
14
+ function replayEvents(events) {
15
+ transaction(() => {
16
+ for (const event of events) {
17
+ const p = event.params;
18
+ switch (event.cmd) {
19
+ case "complete_task": {
20
+ const milestoneId = p["milestoneId"];
21
+ const sliceId = p["sliceId"];
22
+ const taskId = p["taskId"];
23
+ updateTaskStatus(milestoneId, sliceId, taskId, "done", event.ts);
24
+ break;
25
+ }
26
+ case "start_task": {
27
+ const milestoneId = p["milestoneId"];
28
+ const sliceId = p["sliceId"];
29
+ const taskId = p["taskId"];
30
+ updateTaskStatus(milestoneId, sliceId, taskId, "in-progress", event.ts);
31
+ break;
32
+ }
33
+ case "report_blocker": {
34
+ // report_blocker marks the task with blocker_discovered = 1
35
+ // The DB helper updateTaskStatus doesn't handle blockers,
36
+ // so we just update status to "blocked" as a best-effort replay.
37
+ const milestoneId = p["milestoneId"];
38
+ const sliceId = p["sliceId"];
39
+ const taskId = p["taskId"];
40
+ updateTaskStatus(milestoneId, sliceId, taskId, "blocked");
41
+ break;
42
+ }
43
+ case "record_verification": {
44
+ const milestoneId = p["milestoneId"];
45
+ const sliceId = p["sliceId"];
46
+ const taskId = p["taskId"];
47
+ insertVerificationEvidence({
48
+ taskId,
49
+ sliceId,
50
+ milestoneId,
51
+ command: p["command"] ?? "",
52
+ exitCode: p["exitCode"] ?? 0,
53
+ verdict: p["verdict"] ?? "",
54
+ durationMs: p["durationMs"] ?? 0,
55
+ });
56
+ break;
57
+ }
58
+ case "complete_slice": {
59
+ const milestoneId = p["milestoneId"];
60
+ const sliceId = p["sliceId"];
61
+ updateSliceStatus(milestoneId, sliceId, "done", event.ts);
62
+ break;
63
+ }
64
+ case "plan_slice": {
65
+ // plan_slice events are informational — slice should already exist.
66
+ // No DB mutation needed during replay (the slice was inserted at plan time).
67
+ break;
68
+ }
69
+ case "save_decision": {
70
+ upsertDecision({
71
+ id: p["id"] ?? `${p["scope"]}:${p["decision"]}`,
72
+ when_context: p["when_context"] ?? p["whenContext"] ?? "",
73
+ scope: p["scope"] ?? "",
74
+ decision: p["decision"] ?? "",
75
+ choice: p["choice"] ?? "",
76
+ rationale: p["rationale"] ?? "",
77
+ revisable: p["revisable"] ?? "yes",
78
+ made_by: (p["made_by"] ?? p["madeBy"] ?? "agent"),
79
+ superseded_by: p["superseded_by"] ?? p["supersededBy"] ?? null,
80
+ });
81
+ break;
82
+ }
83
+ default:
84
+ // Unknown commands are silently skipped during replay
85
+ break;
86
+ }
87
+ }
88
+ }); // end transaction
89
+ }
90
+ // ─── extractEntityKey ─────────────────────────────────────────────────────────
91
+ /**
92
+ * Map a WorkflowEvent command to its affected entity type and ID.
93
+ * Returns null for commands that don't touch a named entity
94
+ * (e.g. unknown or future cmds).
95
+ */
96
+ export function extractEntityKey(event) {
97
+ const p = event.params;
98
+ switch (event.cmd) {
99
+ case "complete_task":
100
+ case "start_task":
101
+ case "report_blocker":
102
+ case "record_verification":
103
+ return typeof p["taskId"] === "string"
104
+ ? { type: "task", id: p["taskId"] }
105
+ : null;
106
+ case "complete_slice":
107
+ return typeof p["sliceId"] === "string"
108
+ ? { type: "slice", id: p["sliceId"] }
109
+ : null;
110
+ case "plan_slice":
111
+ return typeof p["sliceId"] === "string"
112
+ ? { type: "slice_plan", id: p["sliceId"] }
113
+ : null;
114
+ case "save_decision":
115
+ if (typeof p["scope"] === "string" && typeof p["decision"] === "string") {
116
+ return { type: "decision", id: `${p["scope"]}:${p["decision"]}` };
117
+ }
118
+ return null;
119
+ default:
120
+ return null;
121
+ }
122
+ }
123
+ // ─── detectConflicts ──────────────────────────────────────────────────────────
124
+ /**
125
+ * Compare two sets of diverged events. Returns conflict entries for any
126
+ * entity touched by both sides.
127
+ *
128
+ * Entity-level granularity: if both sides touched task T01 (with any cmd),
129
+ * that is one conflict regardless of field-level differences.
130
+ */
131
+ export function detectConflicts(mainDiverged, wtDiverged) {
132
+ // Group each side's events by entity key
133
+ const mainByEntity = new Map();
134
+ for (const event of mainDiverged) {
135
+ const key = extractEntityKey(event);
136
+ if (!key)
137
+ continue;
138
+ const bucket = mainByEntity.get(`${key.type}:${key.id}`) ?? [];
139
+ bucket.push(event);
140
+ mainByEntity.set(`${key.type}:${key.id}`, bucket);
141
+ }
142
+ const wtByEntity = new Map();
143
+ for (const event of wtDiverged) {
144
+ const key = extractEntityKey(event);
145
+ if (!key)
146
+ continue;
147
+ const bucket = wtByEntity.get(`${key.type}:${key.id}`) ?? [];
148
+ bucket.push(event);
149
+ wtByEntity.set(`${key.type}:${key.id}`, bucket);
150
+ }
151
+ // Find entities touched by both sides
152
+ const conflicts = [];
153
+ for (const [entityKey, mainEvents] of mainByEntity) {
154
+ const wtEvents = wtByEntity.get(entityKey);
155
+ if (!wtEvents)
156
+ continue;
157
+ const colonIdx = entityKey.indexOf(":");
158
+ const entityType = entityKey.slice(0, colonIdx);
159
+ const entityId = entityKey.slice(colonIdx + 1);
160
+ conflicts.push({
161
+ entityType,
162
+ entityId,
163
+ mainSideEvents: mainEvents,
164
+ worktreeSideEvents: wtEvents,
165
+ });
166
+ }
167
+ return conflicts;
168
+ }
169
+ // ─── writeConflictsFile ───────────────────────────────────────────────────────
170
+ /**
171
+ * Write a human-readable CONFLICTS.md to basePath/.gsd/CONFLICTS.md.
172
+ * Lists each conflict with both sides' event payloads and resolution instructions.
173
+ */
174
+ export function writeConflictsFile(basePath, conflicts, worktreePath) {
175
+ const timestamp = new Date().toISOString();
176
+ const lines = [
177
+ `# Merge Conflicts — ${timestamp}`,
178
+ "",
179
+ `Conflicts detected merging worktree \`${worktreePath}\` into \`${basePath}\`.`,
180
+ `Run \`gsd resolve-conflict\` to resolve each conflict.`,
181
+ "",
182
+ ];
183
+ conflicts.forEach((conflict, idx) => {
184
+ lines.push(`## Conflict ${idx + 1}: ${conflict.entityType} ${conflict.entityId}`);
185
+ lines.push("");
186
+ lines.push("**Main side events:**");
187
+ for (const event of conflict.mainSideEvents) {
188
+ lines.push(`- ${event.cmd} at ${event.ts} (hash: ${event.hash})`);
189
+ lines.push(` params: ${JSON.stringify(event.params)}`);
190
+ }
191
+ lines.push("");
192
+ lines.push("**Worktree side events:**");
193
+ for (const event of conflict.worktreeSideEvents) {
194
+ lines.push(`- ${event.cmd} at ${event.ts} (hash: ${event.hash})`);
195
+ lines.push(` params: ${JSON.stringify(event.params)}`);
196
+ }
197
+ lines.push("");
198
+ lines.push(`**Resolve with:** \`gsd resolve-conflict --entity ${conflict.entityType}:${conflict.entityId} --pick [main|worktree]\``);
199
+ lines.push("");
200
+ });
201
+ const content = lines.join("\n");
202
+ const dir = join(basePath, ".gsd");
203
+ mkdirSync(dir, { recursive: true });
204
+ atomicWriteSync(join(dir, "CONFLICTS.md"), content);
205
+ }
206
+ // ─── reconcileWorktreeLogs ────────────────────────────────────────────────────
207
+ /**
208
+ * Event-log-based reconciliation algorithm:
209
+ *
210
+ * 1. Read both event logs
211
+ * 2. Find fork point (last common event by hash)
212
+ * 3. Slice diverged sets from each side
213
+ * 4. If no divergence on either side → return autoMerged: 0, conflicts: []
214
+ * 5. detectConflicts() — if any, writeConflictsFile + return early (D-04 all-or-nothing)
215
+ * 6. If clean: sort merged = mainDiverged + wtDiverged by timestamp, replayAll
216
+ * 7. Write merged event log (base + merged in timestamp order)
217
+ * 8. writeManifest
218
+ * 9. Return { autoMerged: merged.length, conflicts: [] }
219
+ */
220
+ export function reconcileWorktreeLogs(mainBasePath, worktreeBasePath) {
221
+ // Acquire advisory lock to prevent concurrent reconcile + append races
222
+ const lock = acquireSyncLock(mainBasePath);
223
+ if (!lock.acquired) {
224
+ process.stderr.write(`[gsd] reconcile: could not acquire sync lock — another reconciliation may be in progress\n`);
225
+ return { autoMerged: 0, conflicts: [] };
226
+ }
227
+ try {
228
+ return _reconcileWorktreeLogsInner(mainBasePath, worktreeBasePath);
229
+ }
230
+ finally {
231
+ releaseSyncLock(mainBasePath);
232
+ }
233
+ }
234
+ function _reconcileWorktreeLogsInner(mainBasePath, worktreeBasePath) {
235
+ // Step 1: Read both logs
236
+ const mainLogPath = join(mainBasePath, ".gsd", "event-log.jsonl");
237
+ const wtLogPath = join(worktreeBasePath, ".gsd", "event-log.jsonl");
238
+ const mainEvents = readEvents(mainLogPath);
239
+ const wtEvents = readEvents(wtLogPath);
240
+ // Step 2: Find fork point
241
+ const forkPoint = findForkPoint(mainEvents, wtEvents);
242
+ // Step 3: Slice diverged sets
243
+ const mainDiverged = mainEvents.slice(forkPoint + 1);
244
+ const wtDiverged = wtEvents.slice(forkPoint + 1);
245
+ // Step 4: No divergence on either side
246
+ if (mainDiverged.length === 0 && wtDiverged.length === 0) {
247
+ return { autoMerged: 0, conflicts: [] };
248
+ }
249
+ // Step 5: Detect conflicts (entity-level)
250
+ const conflicts = detectConflicts(mainDiverged, wtDiverged);
251
+ if (conflicts.length > 0) {
252
+ // D-04: atomic all-or-nothing — block entire merge
253
+ writeConflictsFile(mainBasePath, conflicts, worktreeBasePath);
254
+ process.stderr.write(`[gsd] reconcile: ${conflicts.length} conflict(s) detected — see ${join(mainBasePath, ".gsd", "CONFLICTS.md")}\n`);
255
+ return { autoMerged: 0, conflicts };
256
+ }
257
+ // Step 6: Clean merge — stable sort by timestamp (index-based tiebreaker)
258
+ const indexed = [...mainDiverged, ...wtDiverged].map((e, i) => ({ e, i }));
259
+ indexed.sort((a, b) => a.e.ts.localeCompare(b.e.ts) || a.i - b.i);
260
+ const merged = indexed.map(({ e }) => e);
261
+ // Step 7: Write merged event log FIRST (so crash recovery can re-derive DB state)
262
+ const baseEvents = mainEvents.slice(0, forkPoint + 1);
263
+ const mergedLog = baseEvents.concat(merged);
264
+ const logContent = mergedLog.map((e) => JSON.stringify(e)).join("\n") + (mergedLog.length > 0 ? "\n" : "");
265
+ mkdirSync(join(mainBasePath, ".gsd"), { recursive: true });
266
+ atomicWriteSync(join(mainBasePath, ".gsd", "event-log.jsonl"), logContent);
267
+ // Step 8: Replay into DB (wrapped in a transaction by replayEvents)
268
+ openDatabase(join(mainBasePath, ".gsd", "gsd.db"));
269
+ replayEvents(merged);
270
+ // Step 9: Write manifest
271
+ try {
272
+ writeManifest(mainBasePath);
273
+ }
274
+ catch (err) {
275
+ process.stderr.write(`[gsd] reconcile: manifest write failed (non-fatal): ${err.message}\n`);
276
+ }
277
+ return { autoMerged: merged.length, conflicts: [] };
278
+ }
279
+ // ─── Conflict Resolution (D-06) ─────────────────────────────────────────────
280
+ /**
281
+ * Parse CONFLICTS.md and return structured ConflictEntry[].
282
+ * Returns empty array when CONFLICTS.md does not exist.
283
+ *
284
+ * Parses the format written by writeConflictsFile:
285
+ * ## Conflict N: {entityType} {entityId}
286
+ * **Main side events:**
287
+ * - {cmd} at {ts} (hash: {hash})
288
+ * params: {JSON}
289
+ * **Worktree side events:**
290
+ * - {cmd} at {ts} (hash: {hash})
291
+ * params: {JSON}
292
+ */
293
+ export function listConflicts(basePath) {
294
+ const conflictsPath = join(basePath, ".gsd", "CONFLICTS.md");
295
+ if (!existsSync(conflictsPath))
296
+ return [];
297
+ const content = readFileSync(conflictsPath, "utf-8");
298
+ const conflicts = [];
299
+ // Split into per-conflict sections on "## Conflict N:" headings
300
+ const sections = content.split(/^## Conflict \d+:/m).slice(1);
301
+ for (const section of sections) {
302
+ // Extract entity type and id from first line: " {entityType} {entityId}"
303
+ const headingMatch = section.match(/^\s+(\S+)\s+(\S+)/);
304
+ if (!headingMatch)
305
+ continue;
306
+ const entityType = headingMatch[1];
307
+ const entityId = headingMatch[2];
308
+ // Split into main/worktree blocks
309
+ const mainMatch = section.split("**Main side events:**")[1];
310
+ const wtMatch = mainMatch?.split("**Worktree side events:**");
311
+ const mainBlock = wtMatch?.[0] ?? "";
312
+ const wtBlock = wtMatch?.[1] ?? "";
313
+ const mainSideEvents = parseEventBlock(mainBlock);
314
+ const worktreeSideEvents = parseEventBlock(wtBlock);
315
+ conflicts.push({ entityType, entityId, mainSideEvents, worktreeSideEvents });
316
+ }
317
+ return conflicts;
318
+ }
319
+ /**
320
+ * Parse a block of event lines from CONFLICTS.md into WorkflowEvent[].
321
+ * Each event spans two lines:
322
+ * - {cmd} at {ts} (hash: {hash})
323
+ * params: {JSON}
324
+ */
325
+ function parseEventBlock(block) {
326
+ const events = [];
327
+ // Find lines starting with "- " (event lines)
328
+ const lines = block.split("\n");
329
+ let i = 0;
330
+ while (i < lines.length) {
331
+ const line = lines[i].trim();
332
+ if (line.startsWith("- ")) {
333
+ // Parse: - {cmd} at {ts} (hash: {hash})
334
+ const eventMatch = line.match(/^-\s+(\S+)\s+at\s+(\S+)\s+\(hash:\s+(\S+)\)$/);
335
+ if (eventMatch) {
336
+ const cmd = eventMatch[1];
337
+ const ts = eventMatch[2];
338
+ const hash = eventMatch[3];
339
+ // Next line: " params: {JSON}"
340
+ let params = {};
341
+ const nextLine = lines[i + 1];
342
+ if (nextLine) {
343
+ const paramsMatch = nextLine.trim().match(/^params:\s+(.+)$/);
344
+ if (paramsMatch) {
345
+ try {
346
+ params = JSON.parse(paramsMatch[1]);
347
+ }
348
+ catch {
349
+ // Keep empty params on parse error
350
+ }
351
+ i++; // consume params line
352
+ }
353
+ }
354
+ events.push({ cmd, params, ts, hash, actor: "agent", session_id: getSessionId() });
355
+ }
356
+ }
357
+ i++;
358
+ }
359
+ return events;
360
+ }
361
+ /**
362
+ * Resolve a single conflict by picking one side's events.
363
+ * Replays the picked events through the DB helpers, appends them to the event log,
364
+ * and updates or removes CONFLICTS.md.
365
+ *
366
+ * When the last conflict is resolved, non-conflicting events from both sides
367
+ * are also replayed (they were blocked by the all-or-nothing D-04 rule).
368
+ */
369
+ export function resolveConflict(basePath, worktreeBasePath, entityKey, // e.g. "task:T01"
370
+ pick) {
371
+ const conflicts = listConflicts(basePath);
372
+ const colonIdx = entityKey.indexOf(":");
373
+ const entityType = entityKey.slice(0, colonIdx);
374
+ const entityId = entityKey.slice(colonIdx + 1);
375
+ const idx = conflicts.findIndex((c) => c.entityType === entityType && c.entityId === entityId);
376
+ if (idx === -1)
377
+ throw new Error(`No conflict found for entity ${entityKey}`);
378
+ const conflict = conflicts[idx];
379
+ const eventsToReplay = pick === "main" ? conflict.mainSideEvents : conflict.worktreeSideEvents;
380
+ // Replay resolved events through the DB (updates DB state)
381
+ openDatabase(join(basePath, ".gsd", "gsd.db"));
382
+ replayEvents(eventsToReplay);
383
+ // Append resolved events to the event log
384
+ for (const event of eventsToReplay) {
385
+ appendEvent(basePath, { cmd: event.cmd, params: event.params, ts: event.ts, actor: event.actor });
386
+ }
387
+ // Remove resolved conflict from list
388
+ conflicts.splice(idx, 1);
389
+ if (conflicts.length === 0) {
390
+ // All conflicts resolved — remove CONFLICTS.md and re-run reconciliation
391
+ // to pick up non-conflicting events that were blocked by D-04 all-or-nothing.
392
+ removeConflictsFile(basePath);
393
+ if (worktreeBasePath) {
394
+ reconcileWorktreeLogs(basePath, worktreeBasePath);
395
+ }
396
+ }
397
+ else {
398
+ // Re-write CONFLICTS.md with remaining conflicts
399
+ writeConflictsFile(basePath, conflicts, worktreeBasePath);
400
+ }
401
+ }
402
+ /**
403
+ * Remove CONFLICTS.md — called when all conflicts are resolved.
404
+ * No-op if CONFLICTS.md does not exist.
405
+ */
406
+ export function removeConflictsFile(basePath) {
407
+ const conflictsPath = join(basePath, ".gsd", "CONFLICTS.md");
408
+ if (existsSync(conflictsPath)) {
409
+ unlinkSync(conflictsPath);
410
+ }
411
+ }
@@ -15,8 +15,10 @@
15
15
  * 4. remove() — git worktree remove + branch cleanup
16
16
  */
17
17
  import { existsSync, mkdirSync, readFileSync, realpathSync, rmSync } from "node:fs";
18
+ import { execFileSync } from "node:child_process";
18
19
  import { join, resolve, sep } from "node:path";
19
20
  import { GSDError, GSD_PARSE_ERROR, GSD_STALE_STATE, GSD_LOCK_HELD, GSD_GIT_ERROR, GSD_MERGE_CONFLICT } from "./errors.js";
21
+ import { logWarning } from "./workflow-logger.js";
20
22
  import { nativeBranchDelete, nativeBranchExists, nativeBranchForceReset, nativeCommit, nativeDetectMainBranch, nativeDiffContent, nativeDiffNameStatus, nativeDiffNumstat, nativeGetCurrentBranch, nativeLogOneline, nativeMergeSquash, nativeWorktreeAdd, nativeWorktreeList, nativeWorktreePrune, nativeWorktreeRemove, } from "./native-git-bridge.js";
21
23
  // ─── Path Helpers ──────────────────────────────────────────────────────────
22
24
  function normalizePathForComparison(path) {
@@ -84,7 +86,7 @@ export function createWorktree(basePath, name, opts = {}) {
84
86
  // worktree can be created in its place.
85
87
  const gitFilePath = join(wtPath, ".git");
86
88
  if (!existsSync(gitFilePath)) {
87
- console.error(`[GSD] Removing stale worktree directory (no .git file): ${wtPath}`);
89
+ logWarning("reconcile", `Removing stale worktree directory (no .git file): ${wtPath}`, { worktree: name });
88
90
  rmSync(wtPath, { recursive: true, force: true });
89
91
  }
90
92
  else {
@@ -240,9 +242,38 @@ export function removeWorktree(basePath, name, opts = {}) {
240
242
  }
241
243
  return;
242
244
  }
243
- // Remove worktree using the resolved path (force if requested, to handle dirty worktrees)
245
+ // Submodule safety (#2337): detect submodules with uncommitted changes
246
+ // before force-removing the worktree. Force removal destroys all uncommitted
247
+ // state, which is especially destructive for submodule directories.
248
+ let hasSubmoduleChanges = false;
249
+ const gitmodulesPath = join(resolvedWtPath, ".gitmodules");
250
+ if (existsSync(gitmodulesPath)) {
251
+ try {
252
+ const submoduleStatus = execFileSync("git", ["submodule", "status"], { cwd: resolvedWtPath, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" }).trim();
253
+ // Lines starting with '+' indicate uncommitted submodule changes
254
+ hasSubmoduleChanges = submoduleStatus.split("\n").some((line) => line.startsWith("+") || line.startsWith("-"));
255
+ if (hasSubmoduleChanges) {
256
+ // Stash submodule changes so they are not lost during force removal.
257
+ // The stash is created in the worktree before it's torn down.
258
+ try {
259
+ execFileSync("git", ["stash", "push", "-m", "gsd: auto-stash submodule changes before worktree teardown"], { cwd: resolvedWtPath, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" });
260
+ logWarning("reconcile", `Stashed uncommitted submodule changes before worktree teardown`, { worktree: name, path: resolvedWtPath });
261
+ }
262
+ catch {
263
+ // Stash failed — warn the user that submodule changes may be lost
264
+ logWarning("reconcile", `Submodule changes detected — stash failed, changes may be lost during force removal`, { worktree: name, path: resolvedWtPath });
265
+ }
266
+ }
267
+ }
268
+ catch {
269
+ // submodule status failed — proceed with normal removal
270
+ }
271
+ }
272
+ // Remove worktree: try non-force first when submodules have changes,
273
+ // falling back to force only after submodule state has been preserved.
274
+ const useForce = hasSubmoduleChanges ? false : force;
244
275
  try {
245
- nativeWorktreeRemove(basePath, resolvedWtPath, force);
276
+ nativeWorktreeRemove(basePath, resolvedWtPath, useForce);
246
277
  }
247
278
  catch { /* may fail */ }
248
279
  // If the directory is still there (e.g. locked), try harder with force
@@ -13,8 +13,11 @@
13
13
  * `process.chdir()` internally — this class MUST NOT double-chdir.
14
14
  */
15
15
  import { existsSync, unlinkSync } from "node:fs";
16
+ import { randomUUID } from "node:crypto";
16
17
  import { join } from "node:path";
17
18
  import { debugLog } from "./debug-logger.js";
19
+ import { MergeConflictError } from "./git-service.js";
20
+ import { emitJournalEvent } from "./journal.js";
18
21
  // ─── WorktreeResolver ──────────────────────────────────────────────────────
19
22
  export class WorktreeResolver {
20
23
  s;
@@ -76,6 +79,13 @@ export class WorktreeResolver {
76
79
  skipped: true,
77
80
  reason: "isolation-disabled",
78
81
  });
82
+ emitJournalEvent(this.s.originalBasePath || this.s.basePath, {
83
+ ts: new Date().toISOString(),
84
+ flowId: randomUUID(),
85
+ seq: 0,
86
+ eventType: "worktree-skip",
87
+ data: { milestoneId, reason: "isolation-disabled" },
88
+ });
79
89
  return;
80
90
  }
81
91
  const basePath = this.s.originalBasePath || this.s.basePath;
@@ -101,6 +111,13 @@ export class WorktreeResolver {
101
111
  result: "success",
102
112
  wtPath,
103
113
  });
114
+ emitJournalEvent(this.s.originalBasePath || this.s.basePath, {
115
+ ts: new Date().toISOString(),
116
+ flowId: randomUUID(),
117
+ seq: 0,
118
+ eventType: "worktree-enter",
119
+ data: { milestoneId, wtPath, created: !existingPath },
120
+ });
104
121
  ctx.notify(`Entered worktree for ${milestoneId} at ${wtPath}`, "info");
105
122
  }
106
123
  catch (err) {
@@ -111,6 +128,13 @@ export class WorktreeResolver {
111
128
  result: "error",
112
129
  error: msg,
113
130
  });
131
+ emitJournalEvent(this.s.originalBasePath || this.s.basePath, {
132
+ ts: new Date().toISOString(),
133
+ flowId: randomUUID(),
134
+ seq: 0,
135
+ eventType: "worktree-create-failed",
136
+ data: { milestoneId, error: msg, fallback: "project-root" },
137
+ });
114
138
  ctx.notify(`Auto-worktree creation for ${milestoneId} failed: ${msg}. Continuing in project root.`, "warning");
115
139
  // Do NOT update s.basePath — stay in project root
116
140
  }
@@ -193,6 +217,13 @@ export class WorktreeResolver {
193
217
  mode,
194
218
  basePath: this.s.basePath,
195
219
  });
220
+ emitJournalEvent(this.s.originalBasePath || this.s.basePath, {
221
+ ts: new Date().toISOString(),
222
+ flowId: randomUUID(),
223
+ seq: 0,
224
+ eventType: "worktree-merge-start",
225
+ data: { milestoneId, mode },
226
+ });
196
227
  if (mode === "none") {
197
228
  debugLog("WorktreeResolver", {
198
229
  action: "mergeAndExit",
@@ -284,6 +315,13 @@ export class WorktreeResolver {
284
315
  error: msg,
285
316
  fallback: "chdir-to-project-root",
286
317
  });
318
+ emitJournalEvent(this.s.originalBasePath || this.s.basePath, {
319
+ ts: new Date().toISOString(),
320
+ flowId: randomUUID(),
321
+ seq: 0,
322
+ eventType: "worktree-merge-failed",
323
+ data: { milestoneId, error: msg },
324
+ });
287
325
  // Surface a clear, actionable error. The worktree and milestone branch are
288
326
  // intentionally preserved — nothing has been deleted. The user can retry
289
327
  // /gsd dispatch complete-milestone or merge manually once the underlying issue is fixed
@@ -308,6 +346,11 @@ export class WorktreeResolver {
308
346
  /* best-effort */
309
347
  }
310
348
  }
349
+ // Re-throw MergeConflictError so the auto loop can detect real code
350
+ // conflicts and stop instead of retrying forever (#2330).
351
+ if (err instanceof MergeConflictError) {
352
+ throw err;
353
+ }
311
354
  }
312
355
  // Always restore basePath and rebuild — whether merge succeeded or failed
313
356
  this.restoreToProjectRoot();
@@ -0,0 +1,84 @@
1
+ // GSD Extension — Write Intercept for Agent State File Blocks
2
+ // Detects agent attempts to write authoritative state files and returns
3
+ // an error directing the agent to use the engine tool API instead.
4
+ import { realpathSync } from "node:fs";
5
+ import { resolve } from "node:path";
6
+ /**
7
+ * Patterns matching authoritative .gsd/ state files that agents must NOT write directly.
8
+ *
9
+ * Only STATE.md is blocked — it is purely engine-rendered from DB state.
10
+ * All other .gsd/ files are agent-authored content that agents create and
11
+ * update during discuss, plan, and execute phases:
12
+ * - REQUIREMENTS.md — agents create during discuss, read during planning
13
+ * - PROJECT.md — agents create during discuss, update at milestone close
14
+ * - ROADMAP.md / PLAN.md — agents create during planning, engine renders checkboxes
15
+ * - SUMMARY.md, KNOWLEDGE.md, CONTEXT.md — non-authoritative content
16
+ */
17
+ const BLOCKED_PATTERNS = [
18
+ // STATE.md is the only purely engine-rendered file.
19
+ // Case-insensitive to prevent bypass on macOS (case-insensitive APFS).
20
+ // (^|[/\\]) matches both absolute paths (/project/.gsd/…) and bare relative
21
+ // paths (.gsd/STATE.md) so a path without a leading separator is also blocked.
22
+ /(^|[/\\])\.gsd[/\\]STATE\.md$/i,
23
+ // Also match resolved symlink paths under ~/.gsd/projects/ (Pitfall #6)
24
+ /(^|[/\\])\.gsd[/\\]projects[/\\][^/\\]+[/\\]STATE\.md$/i,
25
+ ];
26
+ /**
27
+ * Bash command patterns that target STATE.md.
28
+ * Covers common shell write patterns: redirect, tee, cp, mv, sed -i, etc.
29
+ */
30
+ const BASH_STATE_PATTERNS = [
31
+ // Redirect/pipe writes: > STATE.md, >> STATE.md, >| STATE.md
32
+ /[>|]+\s*\S*STATE\.md/i,
33
+ // tee to STATE.md
34
+ /\btee\b.*STATE\.md/i,
35
+ // cp/mv targeting STATE.md
36
+ /\b(cp|mv)\b.*STATE\.md/i,
37
+ // sed -i editing STATE.md
38
+ /\bsed\b.*-i.*STATE\.md/i,
39
+ // dd output to STATE.md
40
+ /\bdd\b.*of=\S*STATE\.md/i,
41
+ ];
42
+ /**
43
+ * Tests whether the given file path matches a blocked authoritative .gsd/ state file.
44
+ * Resolves `..` segments via path.resolve() and attempts realpathSync for symlinks.
45
+ */
46
+ export function isBlockedStateFile(filePath) {
47
+ // Check raw path first
48
+ if (matchesBlockedPattern(filePath))
49
+ return true;
50
+ // Resolve ".." segments (works even for non-existing files)
51
+ const resolved = resolve(filePath);
52
+ if (resolved !== filePath && matchesBlockedPattern(resolved))
53
+ return true;
54
+ // Also try symlink resolution — file may not exist yet, so wrap in try/catch
55
+ try {
56
+ const realpath = realpathSync(filePath);
57
+ if (realpath !== filePath && realpath !== resolved && matchesBlockedPattern(realpath))
58
+ return true;
59
+ }
60
+ catch {
61
+ // File doesn't exist yet — path matching above is sufficient
62
+ }
63
+ return false;
64
+ }
65
+ /**
66
+ * Tests whether a bash command appears to target STATE.md for writing.
67
+ */
68
+ export function isBashWriteToStateFile(command) {
69
+ return BASH_STATE_PATTERNS.some((pattern) => pattern.test(command));
70
+ }
71
+ function matchesBlockedPattern(path) {
72
+ return BLOCKED_PATTERNS.some((pattern) => pattern.test(path));
73
+ }
74
+ /**
75
+ * Error message returned when an agent attempts to directly write an authoritative .gsd/ state file.
76
+ * Directs the agent to use engine tool calls instead.
77
+ */
78
+ export const BLOCKED_WRITE_ERROR = `Direct writes to .gsd/STATE.md are blocked. Use engine tool calls instead:
79
+ - To complete a task: call gsd_complete_task(milestone_id, slice_id, task_id, summary)
80
+ - To complete a slice: call gsd_complete_slice(milestone_id, slice_id, summary, uat_result)
81
+ - To save a decision: call gsd_save_decision(scope, decision, choice, rationale)
82
+ - To start a task: call gsd_start_task(milestone_id, slice_id, task_id)
83
+ - To record verification: call gsd_record_verification(milestone_id, slice_id, task_id, evidence)
84
+ - To report a blocker: call gsd_report_blocker(milestone_id, slice_id, task_id, description)`;
@@ -162,6 +162,20 @@ function formatToolList(serverName, tools) {
162
162
  lines.push(`Call with: mcp_call(server="${serverName}", tool="<tool_name>", args={...})`);
163
163
  return lines.join("\n");
164
164
  }
165
+ // ─── Status helper (consumed by /gsd mcp) ─────────────────────────────────────
166
+ /**
167
+ * Return the live connection status for a named MCP server.
168
+ * Safe to call even when the server has never been connected.
169
+ */
170
+ export function getConnectionStatus(name) {
171
+ const conn = connections.get(name);
172
+ const cached = toolCache.get(name);
173
+ return {
174
+ connected: !!conn,
175
+ tools: cached ? cached.map((t) => t.name) : [],
176
+ error: undefined,
177
+ };
178
+ }
165
179
  // ─── Extension ────────────────────────────────────────────────────────────────
166
180
  export default function (pi) {
167
181
  // ── mcp_servers ──────────────────────────────────────────────────────────