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
@@ -2,6 +2,9 @@ import { clearParseCache } from "../files.js";
2
2
  import { transaction, getSlice, getTask, insertTask, upsertTaskPlanning } from "../gsd-db.js";
3
3
  import { invalidateStateCache } from "../state.js";
4
4
  import { renderTaskPlanFromDb } from "../markdown-renderer.js";
5
+ import { renderAllProjections } from "../workflow-projections.js";
6
+ import { writeManifest } from "../workflow-manifest.js";
7
+ import { appendEvent } from "../workflow-events.js";
5
8
  function isNonEmptyString(value) {
6
9
  return typeof value === "string" && value.trim().length > 0;
7
10
  }
@@ -51,9 +54,16 @@ export async function handlePlanTask(rawParams, basePath) {
51
54
  if (!parentSlice) {
52
55
  return { error: `missing parent slice: ${params.milestoneId}/${params.sliceId}` };
53
56
  }
57
+ if (parentSlice.status === "complete" || parentSlice.status === "done") {
58
+ return { error: `cannot plan task in a closed slice: ${params.sliceId} (status: ${parentSlice.status})` };
59
+ }
60
+ const existingTask = getTask(params.milestoneId, params.sliceId, params.taskId);
61
+ if (existingTask && (existingTask.status === "complete" || existingTask.status === "done")) {
62
+ return { error: `cannot re-plan task ${params.taskId}: it is already complete — use gsd_task_reopen first` };
63
+ }
54
64
  try {
55
65
  transaction(() => {
56
- if (!getTask(params.milestoneId, params.sliceId, params.taskId)) {
66
+ if (!existingTask) {
57
67
  insertTask({
58
68
  id: params.taskId,
59
69
  sliceId: params.sliceId,
@@ -71,6 +81,7 @@ export async function handlePlanTask(rawParams, basePath) {
71
81
  inputs: params.inputs,
72
82
  expectedOutput: params.expectedOutput,
73
83
  observabilityImpact: params.observabilityImpact ?? "",
84
+ fullPlanMd: params.fullPlanMd,
74
85
  });
75
86
  });
76
87
  }
@@ -81,6 +92,22 @@ export async function handlePlanTask(rawParams, basePath) {
81
92
  const renderResult = await renderTaskPlanFromDb(basePath, params.milestoneId, params.sliceId, params.taskId);
82
93
  invalidateStateCache();
83
94
  clearParseCache();
95
+ // ── Post-mutation hook: projections, manifest, event log ─────────────
96
+ try {
97
+ await renderAllProjections(basePath, params.milestoneId);
98
+ writeManifest(basePath);
99
+ appendEvent(basePath, {
100
+ cmd: "plan-task",
101
+ params: { milestoneId: params.milestoneId, sliceId: params.sliceId, taskId: params.taskId },
102
+ ts: new Date().toISOString(),
103
+ actor: "agent",
104
+ actor_name: params.actorName,
105
+ trigger_reason: params.triggerReason,
106
+ });
107
+ }
108
+ catch (hookErr) {
109
+ process.stderr.write(`gsd: plan-task post-mutation hook warning: ${hookErr.message}\n`);
110
+ }
84
111
  return {
85
112
  milestoneId: params.milestoneId,
86
113
  sliceId: params.sliceId,
@@ -1,7 +1,10 @@
1
1
  import { clearParseCache } from "../files.js";
2
- import { transaction, getMilestone, getMilestoneSlices, insertSlice, updateSliceFields, insertAssessment, deleteSlice, } from "../gsd-db.js";
2
+ import { transaction, getMilestone, getMilestoneSlices, getSlice, insertSlice, updateSliceFields, insertAssessment, deleteSlice, } from "../gsd-db.js";
3
3
  import { invalidateStateCache } from "../state.js";
4
4
  import { renderRoadmapFromDb, renderAssessmentFromDb } from "../markdown-renderer.js";
5
+ import { renderAllProjections } from "../workflow-projections.js";
6
+ import { writeManifest } from "../workflow-manifest.js";
7
+ import { appendEvent } from "../workflow-events.js";
5
8
  import { join } from "node:path";
6
9
  function isNonEmptyString(value) {
7
10
  return typeof value === "string" && value.trim().length > 0;
@@ -58,11 +61,22 @@ export async function handleReassessRoadmap(rawParams, basePath) {
58
61
  catch (err) {
59
62
  return { error: `validation failed: ${err.message}` };
60
63
  }
61
- // ── Verify milestone exists ───────────────────────────────────────
64
+ // ── Verify milestone exists and is active ────────────────────────
62
65
  const milestone = getMilestone(params.milestoneId);
63
66
  if (!milestone) {
64
67
  return { error: `milestone not found: ${params.milestoneId}` };
65
68
  }
69
+ if (milestone.status === "complete" || milestone.status === "done") {
70
+ return { error: `cannot reassess a closed milestone: ${params.milestoneId} (status: ${milestone.status})` };
71
+ }
72
+ // ── Verify completedSliceId is actually complete ──────────────────
73
+ const completedSlice = getSlice(params.milestoneId, params.completedSliceId);
74
+ if (!completedSlice) {
75
+ return { error: `completedSliceId not found: ${params.milestoneId}/${params.completedSliceId}` };
76
+ }
77
+ if (completedSlice.status !== "complete" && completedSlice.status !== "done") {
78
+ return { error: `completedSliceId ${params.completedSliceId} is not complete (status: ${completedSlice.status}) — reassess can only be called after a slice finishes` };
79
+ }
66
80
  // ── Structural enforcement ────────────────────────────────────────
67
81
  const existingSlices = getMilestoneSlices(params.milestoneId);
68
82
  const completedSliceIds = new Set();
@@ -139,6 +153,22 @@ export async function handleReassessRoadmap(rawParams, basePath) {
139
153
  // ── Invalidate caches ─────────────────────────────────────────
140
154
  invalidateStateCache();
141
155
  clearParseCache();
156
+ // ── Post-mutation hook: projections, manifest, event log ─────
157
+ try {
158
+ await renderAllProjections(basePath, params.milestoneId);
159
+ writeManifest(basePath);
160
+ appendEvent(basePath, {
161
+ cmd: "reassess-roadmap",
162
+ params: { milestoneId: params.milestoneId, completedSliceId: params.completedSliceId },
163
+ ts: new Date().toISOString(),
164
+ actor: "agent",
165
+ actor_name: params.actorName,
166
+ trigger_reason: params.triggerReason,
167
+ });
168
+ }
169
+ catch (hookErr) {
170
+ process.stderr.write(`gsd: reassess-roadmap post-mutation hook warning: ${hookErr.message}\n`);
171
+ }
142
172
  return {
143
173
  milestoneId: params.milestoneId,
144
174
  completedSliceId: params.completedSliceId,
@@ -0,0 +1,86 @@
1
+ /**
2
+ * reopen-slice handler — the core operation behind gsd_slice_reopen.
3
+ *
4
+ * Resets a completed slice back to "in_progress" and resets ALL of its
5
+ * tasks back to "pending". This is intentional — if you're reopening a
6
+ * slice, you're re-doing the work. Partial resets create ambiguous state.
7
+ *
8
+ * The parent milestone must still be open (not complete).
9
+ */
10
+ // GSD — reopen-slice tool handler
11
+ // Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
12
+ import { getMilestone, getSlice, getSliceTasks, updateSliceStatus, updateTaskStatus, transaction, } from "../gsd-db.js";
13
+ import { invalidateStateCache } from "../state.js";
14
+ import { renderAllProjections } from "../workflow-projections.js";
15
+ import { writeManifest } from "../workflow-manifest.js";
16
+ import { appendEvent } from "../workflow-events.js";
17
+ export async function handleReopenSlice(params, basePath) {
18
+ // ── Validate required fields ────────────────────────────────────────────
19
+ if (!params.sliceId || typeof params.sliceId !== "string" || params.sliceId.trim() === "") {
20
+ return { error: "sliceId is required and must be a non-empty string" };
21
+ }
22
+ if (!params.milestoneId || typeof params.milestoneId !== "string" || params.milestoneId.trim() === "") {
23
+ return { error: "milestoneId is required and must be a non-empty string" };
24
+ }
25
+ // ── Guards + DB writes inside a single transaction (prevents TOCTOU) ───
26
+ let guardError = null;
27
+ let tasksResetCount = 0;
28
+ transaction(() => {
29
+ const milestone = getMilestone(params.milestoneId);
30
+ if (!milestone) {
31
+ guardError = `milestone not found: ${params.milestoneId}`;
32
+ return;
33
+ }
34
+ if (milestone.status === "complete" || milestone.status === "done") {
35
+ guardError = `cannot reopen slice inside a closed milestone: ${params.milestoneId} (status: ${milestone.status})`;
36
+ return;
37
+ }
38
+ const slice = getSlice(params.milestoneId, params.sliceId);
39
+ if (!slice) {
40
+ guardError = `slice not found: ${params.milestoneId}/${params.sliceId}`;
41
+ return;
42
+ }
43
+ if (slice.status !== "complete" && slice.status !== "done") {
44
+ guardError = `slice ${params.sliceId} is not complete (status: ${slice.status}) — nothing to reopen`;
45
+ return;
46
+ }
47
+ // Fetch tasks inside txn so the list is consistent with the slice status check
48
+ const tasks = getSliceTasks(params.milestoneId, params.sliceId);
49
+ tasksResetCount = tasks.length;
50
+ updateSliceStatus(params.milestoneId, params.sliceId, "in_progress");
51
+ for (const task of tasks) {
52
+ updateTaskStatus(params.milestoneId, params.sliceId, task.id, "pending");
53
+ }
54
+ });
55
+ if (guardError) {
56
+ return { error: guardError };
57
+ }
58
+ // ── Invalidate caches ────────────────────────────────────────────────────
59
+ invalidateStateCache();
60
+ // ── Post-mutation hook ───────────────────────────────────────────────────
61
+ try {
62
+ await renderAllProjections(basePath, params.milestoneId);
63
+ writeManifest(basePath);
64
+ appendEvent(basePath, {
65
+ cmd: "reopen-slice",
66
+ params: {
67
+ milestoneId: params.milestoneId,
68
+ sliceId: params.sliceId,
69
+ reason: params.reason ?? null,
70
+ tasksReset: tasksResetCount,
71
+ },
72
+ ts: new Date().toISOString(),
73
+ actor: "agent",
74
+ actor_name: params.actorName,
75
+ trigger_reason: params.triggerReason,
76
+ });
77
+ }
78
+ catch (hookErr) {
79
+ process.stderr.write(`gsd: reopen-slice post-mutation hook warning: ${hookErr.message}\n`);
80
+ }
81
+ return {
82
+ milestoneId: params.milestoneId,
83
+ sliceId: params.sliceId,
84
+ tasksReset: tasksResetCount,
85
+ };
86
+ }
@@ -0,0 +1,90 @@
1
+ /**
2
+ * reopen-task handler — the core operation behind gsd_task_reopen.
3
+ *
4
+ * Resets a completed task back to "pending" so it can be re-done
5
+ * without manual SQL surgery. The parent slice and milestone must
6
+ * still be open (not complete) — you cannot reopen tasks inside a
7
+ * closed slice.
8
+ */
9
+ // GSD — reopen-task tool handler
10
+ // Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
11
+ import { getMilestone, getSlice, getTask, updateTaskStatus, transaction, } from "../gsd-db.js";
12
+ import { invalidateStateCache } from "../state.js";
13
+ import { renderAllProjections } from "../workflow-projections.js";
14
+ import { writeManifest } from "../workflow-manifest.js";
15
+ import { appendEvent } from "../workflow-events.js";
16
+ export async function handleReopenTask(params, basePath) {
17
+ // ── Validate required fields ────────────────────────────────────────────
18
+ if (!params.taskId || typeof params.taskId !== "string" || params.taskId.trim() === "") {
19
+ return { error: "taskId is required and must be a non-empty string" };
20
+ }
21
+ if (!params.sliceId || typeof params.sliceId !== "string" || params.sliceId.trim() === "") {
22
+ return { error: "sliceId is required and must be a non-empty string" };
23
+ }
24
+ if (!params.milestoneId || typeof params.milestoneId !== "string" || params.milestoneId.trim() === "") {
25
+ return { error: "milestoneId is required and must be a non-empty string" };
26
+ }
27
+ // ── Guards + DB write inside a single transaction (prevents TOCTOU) ────
28
+ let guardError = null;
29
+ transaction(() => {
30
+ const milestone = getMilestone(params.milestoneId);
31
+ if (!milestone) {
32
+ guardError = `milestone not found: ${params.milestoneId}`;
33
+ return;
34
+ }
35
+ if (milestone.status === "complete" || milestone.status === "done") {
36
+ guardError = `cannot reopen task in a closed milestone: ${params.milestoneId} (status: ${milestone.status})`;
37
+ return;
38
+ }
39
+ const slice = getSlice(params.milestoneId, params.sliceId);
40
+ if (!slice) {
41
+ guardError = `slice not found: ${params.milestoneId}/${params.sliceId}`;
42
+ return;
43
+ }
44
+ if (slice.status === "complete" || slice.status === "done") {
45
+ guardError = `cannot reopen task inside a closed slice: ${params.sliceId} (status: ${slice.status}) — use gsd_slice_reopen first`;
46
+ return;
47
+ }
48
+ const task = getTask(params.milestoneId, params.sliceId, params.taskId);
49
+ if (!task) {
50
+ guardError = `task not found: ${params.milestoneId}/${params.sliceId}/${params.taskId}`;
51
+ return;
52
+ }
53
+ if (task.status !== "complete" && task.status !== "done") {
54
+ guardError = `task ${params.taskId} is not complete (status: ${task.status}) — nothing to reopen`;
55
+ return;
56
+ }
57
+ updateTaskStatus(params.milestoneId, params.sliceId, params.taskId, "pending");
58
+ });
59
+ if (guardError) {
60
+ return { error: guardError };
61
+ }
62
+ // ── Invalidate caches ────────────────────────────────────────────────────
63
+ invalidateStateCache();
64
+ // ── Post-mutation hook ───────────────────────────────────────────────────
65
+ try {
66
+ await renderAllProjections(basePath, params.milestoneId);
67
+ writeManifest(basePath);
68
+ appendEvent(basePath, {
69
+ cmd: "reopen-task",
70
+ params: {
71
+ milestoneId: params.milestoneId,
72
+ sliceId: params.sliceId,
73
+ taskId: params.taskId,
74
+ reason: params.reason ?? null,
75
+ },
76
+ ts: new Date().toISOString(),
77
+ actor: "agent",
78
+ actor_name: params.actorName,
79
+ trigger_reason: params.triggerReason,
80
+ });
81
+ }
82
+ catch (hookErr) {
83
+ process.stderr.write(`gsd: reopen-task post-mutation hook warning: ${hookErr.message}\n`);
84
+ }
85
+ return {
86
+ milestoneId: params.milestoneId,
87
+ sliceId: params.sliceId,
88
+ taskId: params.taskId,
89
+ };
90
+ }
@@ -1,7 +1,10 @@
1
1
  import { clearParseCache } from "../files.js";
2
- import { transaction, getSlice, getSliceTasks, insertTask, upsertTaskPlanning, insertReplanHistory, deleteTask, } from "../gsd-db.js";
2
+ import { transaction, getSlice, getSliceTasks, getTask, insertTask, upsertTaskPlanning, insertReplanHistory, deleteTask, } from "../gsd-db.js";
3
3
  import { invalidateStateCache } from "../state.js";
4
4
  import { renderPlanFromDb, renderReplanFromDb } from "../markdown-renderer.js";
5
+ import { renderAllProjections } from "../workflow-projections.js";
6
+ import { writeManifest } from "../workflow-manifest.js";
7
+ import { appendEvent } from "../workflow-events.js";
5
8
  function isNonEmptyString(value) {
6
9
  return typeof value === "string" && value.trim().length > 0;
7
10
  }
@@ -43,11 +46,22 @@ export async function handleReplanSlice(rawParams, basePath) {
43
46
  catch (err) {
44
47
  return { error: `validation failed: ${err.message}` };
45
48
  }
46
- // ── Verify parent slice exists ────────────────────────────────────
49
+ // ── Verify parent slice exists and is not closed ─────────────────
47
50
  const parentSlice = getSlice(params.milestoneId, params.sliceId);
48
51
  if (!parentSlice) {
49
52
  return { error: `missing parent slice: ${params.milestoneId}/${params.sliceId}` };
50
53
  }
54
+ if (parentSlice.status === "complete" || parentSlice.status === "done") {
55
+ return { error: `cannot replan a closed slice: ${params.sliceId} (status: ${parentSlice.status})` };
56
+ }
57
+ // ── Verify blocker task exists and is complete ────────────────────
58
+ const blockerTask = getTask(params.milestoneId, params.sliceId, params.blockerTaskId);
59
+ if (!blockerTask) {
60
+ return { error: `blockerTaskId not found: ${params.milestoneId}/${params.sliceId}/${params.blockerTaskId}` };
61
+ }
62
+ if (blockerTask.status !== "complete" && blockerTask.status !== "done") {
63
+ return { error: `blockerTaskId ${params.blockerTaskId} is not complete (status: ${blockerTask.status}) — the blocker task must be finished before a replan is triggered` };
64
+ }
51
65
  // ── Structural enforcement ────────────────────────────────────────
52
66
  const existingTasks = getSliceTasks(params.milestoneId, params.sliceId);
53
67
  const completedTaskIds = new Set();
@@ -91,6 +105,7 @@ export async function handleReplanSlice(rawParams, basePath) {
91
105
  verify: updatedTask.verify || "",
92
106
  inputs: updatedTask.inputs || [],
93
107
  expectedOutput: updatedTask.expectedOutput || [],
108
+ fullPlanMd: updatedTask.fullPlanMd,
94
109
  });
95
110
  }
96
111
  else {
@@ -110,6 +125,7 @@ export async function handleReplanSlice(rawParams, basePath) {
110
125
  verify: updatedTask.verify || "",
111
126
  inputs: updatedTask.inputs || [],
112
127
  expectedOutput: updatedTask.expectedOutput || [],
128
+ fullPlanMd: updatedTask.fullPlanMd,
113
129
  });
114
130
  }
115
131
  }
@@ -133,6 +149,22 @@ export async function handleReplanSlice(rawParams, basePath) {
133
149
  // ── Invalidate caches ─────────────────────────────────────────
134
150
  invalidateStateCache();
135
151
  clearParseCache();
152
+ // ── Post-mutation hook: projections, manifest, event log ─────
153
+ try {
154
+ await renderAllProjections(basePath, params.milestoneId);
155
+ writeManifest(basePath);
156
+ appendEvent(basePath, {
157
+ cmd: "replan-slice",
158
+ params: { milestoneId: params.milestoneId, sliceId: params.sliceId, blockerTaskId: params.blockerTaskId },
159
+ ts: new Date().toISOString(),
160
+ actor: "agent",
161
+ actor_name: params.actorName,
162
+ trigger_reason: params.triggerReason,
163
+ });
164
+ }
165
+ catch (hookErr) {
166
+ process.stderr.write(`gsd: replan-slice post-mutation hook warning: ${hookErr.message}\n`);
167
+ }
136
168
  return {
137
169
  milestoneId: params.milestoneId,
138
170
  sliceId: params.sliceId,
@@ -0,0 +1,88 @@
1
+ /**
2
+ * validate-milestone handler — the core operation behind gsd_validate_milestone.
3
+ *
4
+ * Persists milestone validation results to the assessments table,
5
+ * renders VALIDATION.md to disk, and invalidates caches.
6
+ */
7
+ import { join } from "node:path";
8
+ import { transaction, _getAdapter, } from "../gsd-db.js";
9
+ import { resolveMilestonePath, clearPathCache } from "../paths.js";
10
+ import { saveFile, clearParseCache } from "../files.js";
11
+ import { invalidateStateCache } from "../state.js";
12
+ function renderValidationMarkdown(params) {
13
+ let md = `---
14
+ verdict: ${params.verdict}
15
+ remediation_round: ${params.remediationRound}
16
+ ---
17
+
18
+ # Milestone Validation: ${params.milestoneId}
19
+
20
+ ## Success Criteria Checklist
21
+ ${params.successCriteriaChecklist}
22
+
23
+ ## Slice Delivery Audit
24
+ ${params.sliceDeliveryAudit}
25
+
26
+ ## Cross-Slice Integration
27
+ ${params.crossSliceIntegration}
28
+
29
+ ## Requirement Coverage
30
+ ${params.requirementCoverage}
31
+
32
+ ## Verdict Rationale
33
+ ${params.verdictRationale}
34
+ `;
35
+ if (params.verdict === "needs-remediation" && params.remediationPlan) {
36
+ md += `\n## Remediation Plan\n${params.remediationPlan}\n`;
37
+ }
38
+ return md;
39
+ }
40
+ export async function handleValidateMilestone(params, basePath) {
41
+ if (!params.milestoneId || typeof params.milestoneId !== "string" || params.milestoneId.trim() === "") {
42
+ return { error: "milestoneId is required and must be a non-empty string" };
43
+ }
44
+ const validVerdicts = ["pass", "needs-attention", "needs-remediation"];
45
+ if (!validVerdicts.includes(params.verdict)) {
46
+ return { error: `verdict must be one of: ${validVerdicts.join(", ")}` };
47
+ }
48
+ // ── Filesystem render ──────────────────────────────────────────────────
49
+ const validationMd = renderValidationMarkdown(params);
50
+ let validationPath;
51
+ const milestoneDir = resolveMilestonePath(basePath, params.milestoneId);
52
+ if (milestoneDir) {
53
+ validationPath = join(milestoneDir, `${params.milestoneId}-VALIDATION.md`);
54
+ }
55
+ else {
56
+ const gsdDir = join(basePath, ".gsd");
57
+ const manualDir = join(gsdDir, "milestones", params.milestoneId);
58
+ validationPath = join(manualDir, `${params.milestoneId}-VALIDATION.md`);
59
+ }
60
+ try {
61
+ await saveFile(validationPath, validationMd);
62
+ }
63
+ catch (renderErr) {
64
+ process.stderr.write(`gsd-db: validate_milestone — disk render failed: ${renderErr.message}\n`);
65
+ return { error: `disk render failed: ${renderErr.message}` };
66
+ }
67
+ // ── DB write — store in assessments table ──────────────────────────────
68
+ const validatedAt = new Date().toISOString();
69
+ transaction(() => {
70
+ const adapter = _getAdapter();
71
+ adapter.prepare(`INSERT OR REPLACE INTO assessments (path, milestone_id, slice_id, task_id, status, scope, full_content, created_at)
72
+ VALUES (:path, :mid, NULL, NULL, :verdict, 'milestone-validation', :content, :created_at)`).run({
73
+ ":path": validationPath,
74
+ ":mid": params.milestoneId,
75
+ ":verdict": params.verdict,
76
+ ":content": validationMd,
77
+ ":created_at": validatedAt,
78
+ });
79
+ });
80
+ invalidateStateCache();
81
+ clearPathCache();
82
+ clearParseCache();
83
+ return {
84
+ milestoneId: params.milestoneId,
85
+ verdict: params.verdict,
86
+ validationPath,
87
+ };
88
+ }
@@ -0,0 +1,85 @@
1
+ // GSD Extension — Unit Ownership
2
+ // Opt-in per-unit ownership claims for multi-agent safety.
3
+ //
4
+ // An agent can claim a unit (task, slice) before working on it.
5
+ // complete-task and complete-slice enforce ownership when claims exist.
6
+ // If no claim file is present, ownership is not enforced (backward compatible).
7
+ //
8
+ // Claim file location: .gsd/unit-claims.json
9
+ // Unit key format:
10
+ // task: "<milestoneId>/<sliceId>/<taskId>"
11
+ // slice: "<milestoneId>/<sliceId>"
12
+ //
13
+ // Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
14
+ import { existsSync, readFileSync, mkdirSync } from "node:fs";
15
+ import { join } from "node:path";
16
+ import { atomicWriteSync } from "./atomic-write.js";
17
+ // ─── Key Builders ────────────────────────────────────────────────────────
18
+ export function taskUnitKey(milestoneId, sliceId, taskId) {
19
+ return `${milestoneId}/${sliceId}/${taskId}`;
20
+ }
21
+ export function sliceUnitKey(milestoneId, sliceId) {
22
+ return `${milestoneId}/${sliceId}`;
23
+ }
24
+ // ─── File Path ───────────────────────────────────────────────────────────
25
+ function claimsPath(basePath) {
26
+ return join(basePath, ".gsd", "unit-claims.json");
27
+ }
28
+ // ─── Read Claims ─────────────────────────────────────────────────────────
29
+ function readClaims(basePath) {
30
+ const path = claimsPath(basePath);
31
+ if (!existsSync(path))
32
+ return null;
33
+ try {
34
+ return JSON.parse(readFileSync(path, "utf-8"));
35
+ }
36
+ catch {
37
+ return null;
38
+ }
39
+ }
40
+ // ─── Public API ──────────────────────────────────────────────────────────
41
+ /**
42
+ * Claim a unit for an agent.
43
+ * Overwrites any existing claim for this unit (last writer wins).
44
+ */
45
+ export function claimUnit(basePath, unitKey, agentName) {
46
+ const claims = readClaims(basePath) ?? {};
47
+ claims[unitKey] = { agent: agentName, claimed_at: new Date().toISOString() };
48
+ const dir = join(basePath, ".gsd");
49
+ mkdirSync(dir, { recursive: true });
50
+ atomicWriteSync(claimsPath(basePath), JSON.stringify(claims, null, 2) + "\n");
51
+ }
52
+ /**
53
+ * Release a unit claim (remove it from the claims map).
54
+ */
55
+ export function releaseUnit(basePath, unitKey) {
56
+ const claims = readClaims(basePath);
57
+ if (!claims || !(unitKey in claims))
58
+ return;
59
+ delete claims[unitKey];
60
+ atomicWriteSync(claimsPath(basePath), JSON.stringify(claims, null, 2) + "\n");
61
+ }
62
+ /**
63
+ * Get the current owner of a unit, or null if unclaimed / no claims file.
64
+ */
65
+ export function getOwner(basePath, unitKey) {
66
+ const claims = readClaims(basePath);
67
+ if (!claims)
68
+ return null;
69
+ return claims[unitKey]?.agent ?? null;
70
+ }
71
+ /**
72
+ * Check if an actor is authorized to operate on a unit.
73
+ * Returns null if ownership passes (or is unclaimed / no file).
74
+ * Returns an error string if a different agent owns the unit.
75
+ */
76
+ export function checkOwnership(basePath, unitKey, actorName) {
77
+ if (!actorName)
78
+ return null; // no actor identity provided — opt-in, so allow
79
+ const owner = getOwner(basePath, unitKey);
80
+ if (owner === null)
81
+ return null; // unit unclaimed or no claims file
82
+ if (owner === actorName)
83
+ return null; // actor is the owner
84
+ return `Unit ${unitKey} is owned by ${owner}, not ${actorName}`;
85
+ }
@@ -0,0 +1,102 @@
1
+ import { createHash, randomUUID } from "node:crypto";
2
+ import { appendFileSync, readFileSync, existsSync, mkdirSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { atomicWriteSync } from "./atomic-write.js";
5
+ // ─── Session ID ───────────────────────────────────────────────────────────
6
+ /**
7
+ * Engine-generated session ID — stable for the lifetime of this process.
8
+ * Agents can reference this to correlate all events from one run.
9
+ */
10
+ const ENGINE_SESSION_ID = randomUUID();
11
+ export function getSessionId() {
12
+ return ENGINE_SESSION_ID;
13
+ }
14
+ // ─── appendEvent ─────────────────────────────────────────────────────────
15
+ /**
16
+ * Append one event to .gsd/event-log.jsonl.
17
+ * Computes a content hash from cmd+params (deterministic, independent of ts/actor/session).
18
+ * Creates .gsd directory if needed.
19
+ */
20
+ export function appendEvent(basePath, event) {
21
+ const hash = createHash("sha256")
22
+ .update(JSON.stringify({ cmd: event.cmd, params: event.params, ts: event.ts }))
23
+ .digest("hex")
24
+ .slice(0, 16);
25
+ const fullEvent = {
26
+ ...event,
27
+ hash,
28
+ session_id: ENGINE_SESSION_ID,
29
+ };
30
+ const dir = join(basePath, ".gsd");
31
+ mkdirSync(dir, { recursive: true });
32
+ appendFileSync(join(dir, "event-log.jsonl"), JSON.stringify(fullEvent) + "\n", "utf-8");
33
+ }
34
+ // ─── readEvents ──────────────────────────────────────────────────────────
35
+ /**
36
+ * Read all events from a JSONL file.
37
+ * Returns empty array if file doesn't exist.
38
+ * Corrupted lines are skipped with stderr warning.
39
+ */
40
+ export function readEvents(logPath) {
41
+ if (!existsSync(logPath)) {
42
+ return [];
43
+ }
44
+ const content = readFileSync(logPath, "utf-8");
45
+ const lines = content.split("\n").filter((l) => l.length > 0);
46
+ const events = [];
47
+ for (const line of lines) {
48
+ try {
49
+ events.push(JSON.parse(line));
50
+ }
51
+ catch {
52
+ process.stderr.write(`workflow-events: skipping corrupted event line: ${line.slice(0, 80)}\n`);
53
+ }
54
+ }
55
+ return events;
56
+ }
57
+ // ─── findForkPoint ───────────────────────────────────────────────────────
58
+ /**
59
+ * Find the index of the last common event between two logs by comparing hashes.
60
+ * Returns -1 if the first events differ (completely diverged).
61
+ * If one log is a prefix of the other, returns length of shorter - 1.
62
+ */
63
+ export function findForkPoint(logA, logB) {
64
+ const minLen = Math.min(logA.length, logB.length);
65
+ let lastCommon = -1;
66
+ for (let i = 0; i < minLen; i++) {
67
+ if (logA[i].hash === logB[i].hash) {
68
+ lastCommon = i;
69
+ }
70
+ else {
71
+ break;
72
+ }
73
+ }
74
+ return lastCommon;
75
+ }
76
+ // ─── compactMilestoneEvents ─────────────────────────────────────────────────
77
+ /**
78
+ * Archive a milestone's events from the active log to a separate file.
79
+ * Active log retains only events from other milestones.
80
+ * Archived file is kept on disk for forensics.
81
+ *
82
+ * @param basePath - Project root (parent of .gsd/)
83
+ * @param milestoneId - The milestone whose events should be archived
84
+ * @returns { archived: number } — count of events moved to archive
85
+ */
86
+ export function compactMilestoneEvents(basePath, milestoneId) {
87
+ const logPath = join(basePath, ".gsd", "event-log.jsonl");
88
+ const archivePath = join(basePath, ".gsd", `event-log-${milestoneId}.jsonl.archived`);
89
+ const allEvents = readEvents(logPath);
90
+ const toArchive = allEvents.filter((e) => e.params.milestoneId === milestoneId);
91
+ const remaining = allEvents.filter((e) => e.params.milestoneId !== milestoneId);
92
+ if (toArchive.length === 0) {
93
+ return { archived: 0 };
94
+ }
95
+ // Write archived events to .jsonl.archived file (crash-safe)
96
+ atomicWriteSync(archivePath, toArchive.map((e) => JSON.stringify(e)).join("\n") + "\n");
97
+ // Truncate active log to remaining events only
98
+ atomicWriteSync(logPath, remaining.length > 0
99
+ ? remaining.map((e) => JSON.stringify(e)).join("\n") + "\n"
100
+ : "");
101
+ return { archived: toArchive.length };
102
+ }