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
@@ -22,9 +22,9 @@ import {
22
22
  import { getSliceBranchName } from "../worktree.ts";
23
23
  import { abortAndReset } from "../git-self-heal.ts";
24
24
  import { runGSDDoctor } from "../doctor.ts";
25
- import { createTestContext } from "./test-helpers.ts";
25
+ import { describe, test } from 'node:test';
26
+ import assert from 'node:assert/strict';
26
27
 
27
- const { assertEq, assertTrue, assertMatch, report } = createTestContext();
28
28
 
29
29
  // ---- Helpers ----
30
30
 
@@ -80,7 +80,7 @@ function addSliceToMilestone(
80
80
  run(`git merge --no-ff ${sliceBranch} -m "merge ${sliceId}"`, wtPath);
81
81
  }
82
82
 
83
- async function main(): Promise<void> {
83
+ describe('worktree-e2e', async () => {
84
84
  const savedCwd = process.cwd();
85
85
  const tempDirs: string[] = [];
86
86
 
@@ -100,7 +100,7 @@ async function main(): Promise<void> {
100
100
  // Create worktree for M001
101
101
  const wtPath = createAutoWorktree(repo, "M001");
102
102
  tempDirs.push(wtPath);
103
- assertTrue(existsSync(wtPath), "worktree directory created");
103
+ assert.ok(existsSync(wtPath), "worktree directory created");
104
104
 
105
105
  // Add two slices with commits
106
106
  addSliceToMilestone(repo, wtPath, "M001", "S01", "Add auth", [
@@ -124,19 +124,19 @@ async function main(): Promise<void> {
124
124
  // Assert exactly one new commit on main
125
125
  const mainLogAfter = run("git log --oneline main", repo);
126
126
  const commitCountAfter = mainLogAfter.split("\n").length;
127
- assertEq(commitCountAfter, commitCountBefore + 1, "exactly one new commit on main");
127
+ assert.deepStrictEqual(commitCountAfter, commitCountBefore + 1, "exactly one new commit on main");
128
128
 
129
129
  // Commit message contains both slice titles
130
130
  const lastCommitMsg = run("git log -1 --format=%B main", repo);
131
- assertMatch(lastCommitMsg, /Add auth/, "commit message contains S01 title");
132
- assertMatch(lastCommitMsg, /Add dashboard/, "commit message contains S02 title");
131
+ assert.match(lastCommitMsg, /Add auth/, "commit message contains S01 title");
132
+ assert.match(lastCommitMsg, /Add dashboard/, "commit message contains S02 title");
133
133
 
134
134
  // Worktree directory removed
135
- assertTrue(!existsSync(wtPath), "worktree directory removed after merge");
135
+ assert.ok(!existsSync(wtPath), "worktree directory removed after merge");
136
136
 
137
137
  // Milestone branch deleted
138
138
  const branches = run("git branch", repo);
139
- assertTrue(!branches.includes("milestone/M001"), "milestone branch deleted");
139
+ assert.ok(!branches.includes("milestone/M001"), "milestone branch deleted");
140
140
  }
141
141
 
142
142
  // ================================================================
@@ -159,11 +159,11 @@ async function main(): Promise<void> {
159
159
 
160
160
  // Trigger merge conflict
161
161
  try { run("git merge feature", repo); } catch { /* expected */ }
162
- assertTrue(existsSync(join(repo, ".git", "MERGE_HEAD")), "MERGE_HEAD exists before abort");
162
+ assert.ok(existsSync(join(repo, ".git", "MERGE_HEAD")), "MERGE_HEAD exists before abort");
163
163
 
164
164
  const abortResult = abortAndReset(repo);
165
- assertTrue(!existsSync(join(repo, ".git", "MERGE_HEAD")), "MERGE_HEAD removed after abort");
166
- assertTrue(abortResult.cleaned.length > 0, "abortAndReset reports cleaned items");
165
+ assert.ok(!existsSync(join(repo, ".git", "MERGE_HEAD")), "MERGE_HEAD removed after abort");
166
+ assert.ok(abortResult.cleaned.length > 0, "abortAndReset reports cleaned items");
167
167
  }
168
168
 
169
169
  // ================================================================
@@ -211,19 +211,19 @@ _None_
211
211
  // Detect
212
212
  const detect = await runGSDDoctor(repo, { isolationMode: "worktree" });
213
213
  const orphanIssues = detect.issues.filter(i => i.code === "orphaned_auto_worktree");
214
- assertTrue(orphanIssues.length > 0, "doctor detects orphaned worktree");
215
- assertEq(orphanIssues[0]?.unitId, "M001", "orphaned worktree unitId is M001");
214
+ assert.ok(orphanIssues.length > 0, "doctor detects orphaned worktree");
215
+ assert.deepStrictEqual(orphanIssues[0]?.unitId, "M001", "orphaned worktree unitId is M001");
216
216
 
217
217
  // Fix
218
218
  const fixed = await runGSDDoctor(repo, { fix: true, isolationMode: "worktree" });
219
- assertTrue(
219
+ assert.ok(
220
220
  fixed.fixesApplied.some(f => f.includes("removed orphaned worktree")),
221
221
  "doctor fix removes orphaned worktree",
222
222
  );
223
223
 
224
224
  // Verify gone
225
225
  const wtList = run("git worktree list", repo);
226
- assertTrue(!wtList.includes("milestone/M001"), "worktree gone after doctor fix");
226
+ assert.ok(!wtList.includes("milestone/M001"), "worktree gone after doctor fix");
227
227
  }
228
228
  } else {
229
229
  console.log("\n=== Doctor: orphaned worktree detection (skipped on Windows) ===");
@@ -234,8 +234,4 @@ _None_
234
234
  try { rmSync(d, { recursive: true, force: true }); } catch { /* ignore */ }
235
235
  }
236
236
  }
237
-
238
- report();
239
- }
240
-
241
- main();
237
+ });
@@ -12,9 +12,9 @@ import { execSync } from "node:child_process";
12
12
 
13
13
  import { getWorktreeHealth, formatWorktreeStatusLine } from "../worktree-health.ts";
14
14
  import { listWorktrees } from "../worktree-manager.ts";
15
- import { createTestContext } from "./test-helpers.ts";
15
+ import { describe, test } from 'node:test';
16
+ import assert from 'node:assert/strict';
16
17
 
17
- const { assertEq, assertTrue, report } = createTestContext();
18
18
 
19
19
  function run(cmd: string, cwd: string): string {
20
20
  return execSync(cmd, { cwd, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" }).trim();
@@ -32,11 +32,10 @@ function createBaseRepo(): string {
32
32
  return dir;
33
33
  }
34
34
 
35
- async function main(): Promise<void> {
35
+ describe('worktree-health', async () => {
36
36
  // Skip all tests on Windows — git worktree path resolution issues
37
37
  if (process.platform === "win32") {
38
38
  console.log("(all worktree-health tests skipped on Windows)");
39
- report();
40
39
  return;
41
40
  }
42
41
 
@@ -59,16 +58,16 @@ async function main(): Promise<void> {
59
58
 
60
59
  const worktrees = listWorktrees(dir);
61
60
  const wt = worktrees.find(w => w.name === "done-feature");
62
- assertTrue(!!wt, "worktree found");
61
+ assert.ok(!!wt, "worktree found");
63
62
 
64
63
  const health = getWorktreeHealth(dir, wt!);
65
- assertTrue(health.mergedIntoMain, "branch detected as merged");
66
- assertTrue(!health.dirty, "not dirty");
67
- assertTrue(health.safeToRemove, "safe to remove");
64
+ assert.ok(health.mergedIntoMain, "branch detected as merged");
65
+ assert.ok(!health.dirty, "not dirty");
66
+ assert.ok(health.safeToRemove, "safe to remove");
68
67
 
69
68
  const line = formatWorktreeStatusLine(health);
70
- assertTrue(line.includes("merged"), "status line mentions merged");
71
- assertTrue(line.includes("safe to remove"), "status line mentions safe to remove");
69
+ assert.ok(line.includes("merged"), "status line mentions merged");
70
+ assert.ok(line.includes("safe to remove"), "status line mentions safe to remove");
72
71
  }
73
72
 
74
73
  // ─── Test: unmerged worktree with dirty files ──────────────────────
@@ -89,13 +88,13 @@ async function main(): Promise<void> {
89
88
 
90
89
  const worktrees = listWorktrees(dir);
91
90
  const wt = worktrees.find(w => w.name === "dirty-wip");
92
- assertTrue(!!wt, "worktree found");
91
+ assert.ok(!!wt, "worktree found");
93
92
 
94
93
  const health = getWorktreeHealth(dir, wt!);
95
- assertTrue(!health.mergedIntoMain, "not merged");
96
- assertTrue(health.dirty, "dirty detected");
97
- assertTrue(health.dirtyFileCount > 0, "dirty file count > 0");
98
- assertTrue(!health.safeToRemove, "not safe to remove");
94
+ assert.ok(!health.mergedIntoMain, "not merged");
95
+ assert.ok(health.dirty, "dirty detected");
96
+ assert.ok(health.dirtyFileCount > 0, "dirty file count > 0");
97
+ assert.ok(!health.safeToRemove, "not safe to remove");
99
98
  }
100
99
 
101
100
  // ─── Test: unmerged worktree with unpushed commits ─────────────────
@@ -113,12 +112,12 @@ async function main(): Promise<void> {
113
112
 
114
113
  const worktrees = listWorktrees(dir);
115
114
  const wt = worktrees.find(w => w.name === "unpushed");
116
- assertTrue(!!wt, "worktree found");
115
+ assert.ok(!!wt, "worktree found");
117
116
 
118
117
  const health = getWorktreeHealth(dir, wt!);
119
- assertTrue(!health.mergedIntoMain, "not merged");
120
- assertTrue(health.unpushedCommits > 0, "unpushed commits detected");
121
- assertTrue(!health.safeToRemove, "not safe to remove");
118
+ assert.ok(!health.mergedIntoMain, "not merged");
119
+ assert.ok(health.unpushedCommits > 0, "unpushed commits detected");
120
+ assert.ok(!health.safeToRemove, "not safe to remove");
122
121
  }
123
122
 
124
123
  // ─── Test: stale detection with short threshold ────────────────────
@@ -137,17 +136,17 @@ async function main(): Promise<void> {
137
136
 
138
137
  const worktrees = listWorktrees(dir);
139
138
  const wt = worktrees.find(w => w.name === "stale-test");
140
- assertTrue(!!wt, "worktree found");
139
+ assert.ok(!!wt, "worktree found");
141
140
 
142
141
  // With staleDays=0, any worktree should be stale (commit was just now, but threshold is 0)
143
142
  // Actually, a just-created worktree has lastCommitAgeDays ~0 which is >= 0
144
143
  const health = getWorktreeHealth(dir, wt!, 0);
145
- assertTrue(health.stale, "stale with 0-day threshold");
146
- assertTrue(health.lastCommitAgeDays >= 0, "last commit age is non-negative");
144
+ assert.ok(health.stale, "stale with 0-day threshold");
145
+ assert.ok(health.lastCommitAgeDays >= 0, "last commit age is non-negative");
147
146
 
148
147
  // With staleDays=9999, should NOT be stale
149
148
  const healthNotStale = getWorktreeHealth(dir, wt!, 9999);
150
- assertTrue(!healthNotStale.stale, "not stale with high threshold");
149
+ assert.ok(!healthNotStale.stale, "not stale with high threshold");
151
150
  }
152
151
 
153
152
  // ─── Test: formatWorktreeStatusLine for clean active worktree ──────
@@ -166,12 +165,12 @@ async function main(): Promise<void> {
166
165
 
167
166
  const worktrees = listWorktrees(dir);
168
167
  const wt = worktrees.find(w => w.name === "clean-active");
169
- assertTrue(!!wt, "worktree found");
168
+ assert.ok(!!wt, "worktree found");
170
169
 
171
170
  const health = getWorktreeHealth(dir, wt!, 9999); // high threshold so not stale
172
171
  const line = formatWorktreeStatusLine(health);
173
172
  // Should show last commit age since it's not merged and not stale
174
- assertTrue(line.includes("last commit"), "shows last commit age for active worktree");
173
+ assert.ok(line.includes("last commit"), "shows last commit age for active worktree");
175
174
  }
176
175
 
177
176
  } finally {
@@ -179,8 +178,4 @@ async function main(): Promise<void> {
179
178
  try { rmSync(dir, { recursive: true, force: true }); } catch { /* ignore */ }
180
179
  }
181
180
  }
182
-
183
- report();
184
- }
185
-
186
- main();
181
+ });
@@ -29,9 +29,9 @@ import {
29
29
  } from "../worktree.ts";
30
30
 
31
31
  import { deriveState } from "../state.ts";
32
- import { createTestContext } from './test-helpers.ts';
32
+ import { describe, test } from 'node:test';
33
+ import assert from 'node:assert/strict';
33
34
 
34
- const { assertEq, assertTrue, report } = createTestContext();
35
35
  function run(command: string, cwd: string): string {
36
36
  return execSync(command, { cwd, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" }).trim();
37
37
  }
@@ -73,42 +73,42 @@ writeFileSync(
73
73
  run("git add .", base);
74
74
  run('git commit -m "chore: init"', base);
75
75
 
76
- async function main(): Promise<void> {
76
+ describe('worktree-integration', async () => {
77
77
  // ── Verify main tree baseline ──────────────────────────────────────────────
78
78
 
79
79
  console.log("\n=== Main tree baseline ===");
80
- assertEq(getMainBranch(base), "main", "main tree getMainBranch returns main");
81
- assertEq(detectWorktreeName(base), null, "main tree not detected as worktree");
80
+ assert.deepStrictEqual(getMainBranch(base), "main", "main tree getMainBranch returns main");
81
+ assert.deepStrictEqual(detectWorktreeName(base), null, "main tree not detected as worktree");
82
82
 
83
83
  // ── Create worktree and verify detection ───────────────────────────────────
84
84
 
85
85
  console.log("\n=== Create worktree ===");
86
86
  const wt = createWorktree(base, "alpha");
87
- assertTrue(existsSync(wt.path), "worktree created on disk");
88
- assertEq(wt.branch, "worktree/alpha", "worktree branch name");
87
+ assert.ok(existsSync(wt.path), "worktree created on disk");
88
+ assert.deepStrictEqual(wt.branch, "worktree/alpha", "worktree branch name");
89
89
 
90
90
  console.log("\n=== Worktree detection ===");
91
- assertEq(detectWorktreeName(wt.path), "alpha", "detectWorktreeName inside worktree");
92
- assertEq(getMainBranch(wt.path), "worktree/alpha", "getMainBranch returns worktree branch inside worktree");
91
+ assert.deepStrictEqual(detectWorktreeName(wt.path), "alpha", "detectWorktreeName inside worktree");
92
+ assert.deepStrictEqual(getMainBranch(wt.path), "worktree/alpha", "getMainBranch returns worktree branch inside worktree");
93
93
 
94
94
  // ── Verify current branch inside worktree ──────────────────────────────────
95
95
 
96
96
  console.log("\n=== Worktree initial branch ===");
97
- assertEq(getCurrentBranch(wt.path), "worktree/alpha", "worktree starts on its own branch");
97
+ assert.deepStrictEqual(getCurrentBranch(wt.path), "worktree/alpha", "worktree starts on its own branch");
98
98
 
99
99
  // ── Verify branch name helper ──────────────────────────────────────────────
100
100
 
101
101
  console.log("\n=== getSliceBranchName with worktree ===");
102
- assertEq(getSliceBranchName("M001", "S01", "alpha"), "gsd/alpha/M001/S01", "explicit worktree param");
103
- assertEq(getSliceBranchName("M001", "S01"), "gsd/M001/S01", "no worktree param = plain branch");
102
+ assert.deepStrictEqual(getSliceBranchName("M001", "S01", "alpha"), "gsd/alpha/M001/S01", "explicit worktree param");
103
+ assert.deepStrictEqual(getSliceBranchName("M001", "S01"), "gsd/M001/S01", "no worktree param = plain branch");
104
104
 
105
105
  // ── Slice branch creation and detection inside worktree ────────────────────
106
106
 
107
107
  console.log("\n=== Slice branch in worktree ===");
108
108
  const sliceBranch = getSliceBranchName("M001", "S01", "alpha");
109
109
  run(`git checkout -b ${sliceBranch}`, wt.path);
110
- assertEq(getCurrentBranch(wt.path), "gsd/alpha/M001/S01", "worktree-namespaced slice branch");
111
- assertTrue(SLICE_BRANCH_RE.test(getCurrentBranch(wt.path)), "slice branch regex matches namespaced branch");
110
+ assert.deepStrictEqual(getCurrentBranch(wt.path), "gsd/alpha/M001/S01", "worktree-namespaced slice branch");
111
+ assert.ok(SLICE_BRANCH_RE.test(getCurrentBranch(wt.path)), "slice branch regex matches namespaced branch");
112
112
 
113
113
  // ── Do work on slice branch, then merge to worktree branch ─────────────────
114
114
 
@@ -119,23 +119,23 @@ async function main(): Promise<void> {
119
119
 
120
120
  // Checkout worktree base branch and merge slice branch
121
121
  run("git checkout worktree/alpha", wt.path);
122
- assertEq(getCurrentBranch(wt.path), "worktree/alpha", "back on worktree branch");
122
+ assert.deepStrictEqual(getCurrentBranch(wt.path), "worktree/alpha", "back on worktree branch");
123
123
 
124
124
  run(`git merge --no-ff ${sliceBranch} -m "feat(M001/S01): First"`, wt.path);
125
125
  run(`git branch -d ${sliceBranch}`, wt.path);
126
- assertEq(getCurrentBranch(wt.path), "worktree/alpha", "still on worktree branch after merge");
127
- assertTrue(readFileSync(join(wt.path, "feature.txt"), "utf-8").includes("new feature"), "merge brought feature to worktree branch");
126
+ assert.deepStrictEqual(getCurrentBranch(wt.path), "worktree/alpha", "still on worktree branch after merge");
127
+ assert.ok(readFileSync(join(wt.path, "feature.txt"), "utf-8").includes("new feature"), "merge brought feature to worktree branch");
128
128
 
129
129
  // Verify slice branch is gone
130
130
  const branches = run("git branch", base);
131
- assertTrue(!branches.includes("gsd/alpha/M001/S01"), "slice branch cleaned up");
131
+ assert.ok(!branches.includes("gsd/alpha/M001/S01"), "slice branch cleaned up");
132
132
 
133
133
  // ── Second slice in same worktree ──────────────────────────────────────────
134
134
 
135
135
  console.log("\n=== Second slice in worktree ===");
136
136
  const sliceBranch2 = getSliceBranchName("M001", "S02", "alpha");
137
137
  run(`git checkout -b ${sliceBranch2}`, wt.path);
138
- assertEq(getCurrentBranch(wt.path), "gsd/alpha/M001/S02", "on S02 namespaced branch");
138
+ assert.deepStrictEqual(getCurrentBranch(wt.path), "gsd/alpha/M001/S02", "on S02 namespaced branch");
139
139
 
140
140
  writeFileSync(join(wt.path, "feature2.txt"), "second feature\n", "utf-8");
141
141
  run("git add .", wt.path);
@@ -144,28 +144,28 @@ async function main(): Promise<void> {
144
144
  run("git checkout worktree/alpha", wt.path);
145
145
  run(`git merge --no-ff ${sliceBranch2} -m "feat(M001/S02): Second"`, wt.path);
146
146
  run(`git branch -d ${sliceBranch2}`, wt.path);
147
- assertEq(getCurrentBranch(wt.path), "worktree/alpha", "back on worktree branch");
147
+ assert.deepStrictEqual(getCurrentBranch(wt.path), "worktree/alpha", "back on worktree branch");
148
148
 
149
149
  // ── Parallel worktrees don't conflict ──────────────────────────────────────
150
150
 
151
151
  console.log("\n=== Parallel worktrees ===");
152
152
  const wt2 = createWorktree(base, "beta");
153
- assertEq(getMainBranch(wt2.path), "worktree/beta", "second worktree has its own base branch");
153
+ assert.deepStrictEqual(getMainBranch(wt2.path), "worktree/beta", "second worktree has its own base branch");
154
154
 
155
155
  // Both worktrees can create S01 branches without conflict
156
156
  const betaBranch = getSliceBranchName("M001", "S01", "beta");
157
157
  run(`git checkout -b ${betaBranch}`, wt2.path);
158
- assertEq(getCurrentBranch(wt2.path), "gsd/beta/M001/S01", "beta has its own namespaced branch");
158
+ assert.deepStrictEqual(getCurrentBranch(wt2.path), "gsd/beta/M001/S01", "beta has its own namespaced branch");
159
159
 
160
160
  // Alpha worktree can re-create S01 too (it was already merged+deleted earlier)
161
161
  const alphaReBranch = getSliceBranchName("M001", "S01", "alpha");
162
162
  run(`git checkout -b ${alphaReBranch}`, wt.path);
163
- assertEq(getCurrentBranch(wt.path), "gsd/alpha/M001/S01", "alpha re-created S01");
163
+ assert.deepStrictEqual(getCurrentBranch(wt.path), "gsd/alpha/M001/S01", "alpha re-created S01");
164
164
 
165
165
  // Both exist simultaneously
166
166
  const allBranches = run("git branch", base);
167
- assertTrue(allBranches.includes("gsd/alpha/M001/S01"), "alpha S01 branch exists");
168
- assertTrue(allBranches.includes("gsd/beta/M001/S01"), "beta S01 branch exists");
167
+ assert.ok(allBranches.includes("gsd/alpha/M001/S01"), "alpha S01 branch exists");
168
+ assert.ok(allBranches.includes("gsd/beta/M001/S01"), "beta S01 branch exists");
169
169
 
170
170
  // ── State derivation in worktree ───────────────────────────────────────────
171
171
 
@@ -173,8 +173,8 @@ async function main(): Promise<void> {
173
173
  // Switch alpha back to its base so deriveState sees milestone files
174
174
  run("git checkout worktree/alpha", wt.path);
175
175
  const state = await deriveState(wt.path);
176
- assertTrue(state.activeMilestone !== null, "worktree has active milestone");
177
- assertEq(state.activeMilestone?.id, "M001", "correct milestone");
176
+ assert.ok(state.activeMilestone !== null, "worktree has active milestone");
177
+ assert.deepStrictEqual(state.activeMilestone?.id, "M001", "correct milestone");
178
178
 
179
179
  // ── autoCommitCurrentBranch in worktree ────────────────────────────────────
180
180
 
@@ -183,8 +183,8 @@ async function main(): Promise<void> {
183
183
  run(`git checkout ${betaBranch}`, wt2.path);
184
184
  writeFileSync(join(wt2.path, "dirty.txt"), "uncommitted\n", "utf-8");
185
185
  const commitMsg = autoCommitCurrentBranch(wt2.path, "execute-task", "M001/S01/T01");
186
- assertTrue(commitMsg !== null, "auto-commit works in worktree");
187
- assertEq(run("git status --short", wt2.path), "", "worktree clean after auto-commit");
186
+ assert.ok(commitMsg !== null, "auto-commit works in worktree");
187
+ assert.deepStrictEqual(run("git status --short", wt2.path), "", "worktree clean after auto-commit");
188
188
 
189
189
  // ── Cleanup ────────────────────────────────────────────────────────────────
190
190
 
@@ -194,14 +194,7 @@ async function main(): Promise<void> {
194
194
  run("git checkout worktree/beta", wt2.path);
195
195
  removeWorktree(base, "alpha", { deleteBranch: true });
196
196
  removeWorktree(base, "beta", { deleteBranch: true });
197
- assertEq(listWorktrees(base).length, 0, "all worktrees removed");
197
+ assert.deepStrictEqual(listWorktrees(base).length, 0, "all worktrees removed");
198
198
 
199
199
  rmSync(base, { recursive: true, force: true });
200
-
201
- report();
202
- }
203
-
204
- main().catch((error) => {
205
- console.error(error);
206
- process.exit(1);
207
200
  });
@@ -0,0 +1,220 @@
1
+ import { describe, test, beforeEach, afterEach } from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { mkdtempSync, rmSync, readFileSync, readdirSync } from "node:fs";
4
+ import { join } from "node:path";
5
+ import { tmpdir } from "node:os";
6
+ import {
7
+ WorktreeResolver,
8
+ type WorktreeResolverDeps,
9
+ type NotifyCtx,
10
+ } from "../worktree-resolver.js";
11
+ import { AutoSession } from "../auto/session.js";
12
+ import type { JournalEntry } from "../journal.js";
13
+
14
+ // ─── Helpers ─────────────────────────────────────────────────────────────────
15
+
16
+ function makeSession(
17
+ overrides?: Partial<{ basePath: string; originalBasePath: string }>,
18
+ ): AutoSession {
19
+ const s = new AutoSession();
20
+ s.basePath = overrides?.basePath ?? "/project";
21
+ s.originalBasePath = overrides?.originalBasePath ?? "/project";
22
+ return s;
23
+ }
24
+
25
+ function makeDeps(
26
+ overrides?: Partial<WorktreeResolverDeps>,
27
+ ): WorktreeResolverDeps {
28
+ const deps: WorktreeResolverDeps = {
29
+ isInAutoWorktree: () => false,
30
+ shouldUseWorktreeIsolation: () => true,
31
+ getIsolationMode: () => "worktree",
32
+ mergeMilestoneToMain: () => ({ pushed: false, codeFilesChanged: true }),
33
+ syncWorktreeStateBack: () => ({ synced: [] }),
34
+ teardownAutoWorktree: () => {},
35
+ createAutoWorktree: (_basePath: string, milestoneId: string) =>
36
+ `/project/.gsd/worktrees/${milestoneId}`,
37
+ enterAutoWorktree: (_basePath: string, milestoneId: string) =>
38
+ `/project/.gsd/worktrees/${milestoneId}`,
39
+ getAutoWorktreePath: () => null,
40
+ autoCommitCurrentBranch: () => {},
41
+ getCurrentBranch: () => "main",
42
+ autoWorktreeBranch: (milestoneId: string) => `milestone/${milestoneId}`,
43
+ resolveMilestoneFile: (_basePath: string, milestoneId: string) =>
44
+ `/project/.gsd/milestones/${milestoneId}/${milestoneId}-ROADMAP.md`,
45
+ readFileSync: () => "# Roadmap\n- [x] S01: Slice one\n",
46
+ GitServiceImpl: class {
47
+ constructor() {}
48
+ } as unknown as WorktreeResolverDeps["GitServiceImpl"],
49
+ loadEffectiveGSDPreferences: () => ({ preferences: { git: {} } }),
50
+ invalidateAllCaches: () => {},
51
+ captureIntegrationBranch: () => {},
52
+ ...overrides,
53
+ };
54
+ return deps;
55
+ }
56
+
57
+ function makeNotifyCtx(): NotifyCtx {
58
+ return {
59
+ notify: () => {},
60
+ };
61
+ }
62
+
63
+ /** Read all journal entries from a temp .gsd/journal directory. */
64
+ function readJournalEntries(basePath: string): JournalEntry[] {
65
+ const journalDir = join(basePath, ".gsd", "journal");
66
+ try {
67
+ const files = readdirSync(journalDir).filter(f => f.endsWith(".jsonl")).sort();
68
+ const entries: JournalEntry[] = [];
69
+ for (const file of files) {
70
+ const raw = readFileSync(join(journalDir, file), "utf-8");
71
+ for (const line of raw.split("\n")) {
72
+ if (!line.trim()) continue;
73
+ entries.push(JSON.parse(line) as JournalEntry);
74
+ }
75
+ }
76
+ return entries;
77
+ } catch {
78
+ return [];
79
+ }
80
+ }
81
+
82
+ // ─── Tests ───────────────────────────────────────────────────────────────────
83
+
84
+ describe("worktree journal events", () => {
85
+ let tmp: string;
86
+ const originalCwd = process.cwd();
87
+
88
+ beforeEach(() => {
89
+ tmp = mkdtempSync(join(tmpdir(), "wt-journal-"));
90
+ });
91
+ afterEach(() => {
92
+ // Restore cwd before cleanup — on Windows, rmSync fails with EPERM
93
+ // if the process cwd is inside the directory being deleted.
94
+ try { process.chdir(originalCwd); } catch { /* best-effort */ }
95
+ rmSync(tmp, { recursive: true, force: true });
96
+ });
97
+
98
+ test("enterMilestone emits worktree-enter on success (new worktree)", () => {
99
+ const s = makeSession({ basePath: tmp, originalBasePath: tmp });
100
+ const deps = makeDeps({ getAutoWorktreePath: () => null });
101
+ const resolver = new WorktreeResolver(s, deps);
102
+
103
+ resolver.enterMilestone("M001", makeNotifyCtx());
104
+
105
+ const entries = readJournalEntries(tmp);
106
+ const enter = entries.find(e => e.eventType === "worktree-enter");
107
+ assert.ok(enter, "worktree-enter event should be emitted");
108
+ assert.equal(enter!.data?.milestoneId, "M001");
109
+ assert.equal(enter!.data?.created, true);
110
+ assert.ok(enter!.data?.wtPath);
111
+ });
112
+
113
+ test("enterMilestone emits worktree-enter with created=false for existing worktree", () => {
114
+ const s = makeSession({ basePath: tmp, originalBasePath: tmp });
115
+ const deps = makeDeps({
116
+ getAutoWorktreePath: () => "/project/.gsd/worktrees/M001",
117
+ });
118
+ const resolver = new WorktreeResolver(s, deps);
119
+
120
+ resolver.enterMilestone("M001", makeNotifyCtx());
121
+
122
+ const entries = readJournalEntries(tmp);
123
+ const enter = entries.find(e => e.eventType === "worktree-enter");
124
+ assert.ok(enter, "worktree-enter event should be emitted");
125
+ assert.equal(enter!.data?.created, false);
126
+ });
127
+
128
+ test("enterMilestone emits worktree-skip when isolation disabled", () => {
129
+ const s = makeSession({ basePath: tmp, originalBasePath: tmp });
130
+ const deps = makeDeps({ shouldUseWorktreeIsolation: () => false });
131
+ const resolver = new WorktreeResolver(s, deps);
132
+
133
+ resolver.enterMilestone("M001", makeNotifyCtx());
134
+
135
+ const entries = readJournalEntries(tmp);
136
+ const skip = entries.find(e => e.eventType === "worktree-skip");
137
+ assert.ok(skip, "worktree-skip event should be emitted");
138
+ assert.equal(skip!.data?.milestoneId, "M001");
139
+ assert.equal(skip!.data?.reason, "isolation-disabled");
140
+ });
141
+
142
+ test("enterMilestone emits worktree-create-failed on error", () => {
143
+ const s = makeSession({ basePath: tmp, originalBasePath: tmp });
144
+ const deps = makeDeps({
145
+ getAutoWorktreePath: () => null,
146
+ createAutoWorktree: () => { throw new Error("disk full"); },
147
+ });
148
+ const resolver = new WorktreeResolver(s, deps);
149
+
150
+ resolver.enterMilestone("M001", makeNotifyCtx());
151
+
152
+ const entries = readJournalEntries(tmp);
153
+ const failed = entries.find(e => e.eventType === "worktree-create-failed");
154
+ assert.ok(failed, "worktree-create-failed event should be emitted");
155
+ assert.equal(failed!.data?.milestoneId, "M001");
156
+ assert.equal(failed!.data?.error, "disk full");
157
+ assert.equal(failed!.data?.fallback, "project-root");
158
+ });
159
+
160
+ test("mergeAndExit emits worktree-merge-start", () => {
161
+ const s = makeSession({
162
+ basePath: join(tmp, "worktree"),
163
+ originalBasePath: tmp,
164
+ });
165
+ const deps = makeDeps({
166
+ isInAutoWorktree: () => true,
167
+ getIsolationMode: () => "worktree",
168
+ });
169
+ const resolver = new WorktreeResolver(s, deps);
170
+
171
+ resolver.mergeAndExit("M001", makeNotifyCtx());
172
+
173
+ const entries = readJournalEntries(tmp);
174
+ const start = entries.find(e => e.eventType === "worktree-merge-start");
175
+ assert.ok(start, "worktree-merge-start event should be emitted");
176
+ assert.equal(start!.data?.milestoneId, "M001");
177
+ assert.equal(start!.data?.mode, "worktree");
178
+ });
179
+
180
+ test("mergeAndExit emits worktree-merge-failed on error", () => {
181
+ const s = makeSession({
182
+ basePath: join(tmp, "worktree"),
183
+ originalBasePath: tmp,
184
+ });
185
+ const deps = makeDeps({
186
+ isInAutoWorktree: () => true,
187
+ getIsolationMode: () => "worktree",
188
+ mergeMilestoneToMain: () => { throw new Error("conflict in main"); },
189
+ });
190
+ const resolver = new WorktreeResolver(s, deps);
191
+
192
+ resolver.mergeAndExit("M001", makeNotifyCtx());
193
+
194
+ const entries = readJournalEntries(tmp);
195
+ const failed = entries.find(e => e.eventType === "worktree-merge-failed");
196
+ assert.ok(failed, "worktree-merge-failed event should be emitted");
197
+ assert.equal(failed!.data?.milestoneId, "M001");
198
+ assert.equal(failed!.data?.error, "conflict in main");
199
+ });
200
+
201
+ test("journal entries have valid flowId, seq, and ts fields", () => {
202
+ const s = makeSession({ basePath: tmp, originalBasePath: tmp });
203
+ const deps = makeDeps({ shouldUseWorktreeIsolation: () => false });
204
+ const resolver = new WorktreeResolver(s, deps);
205
+
206
+ resolver.enterMilestone("M001", makeNotifyCtx());
207
+
208
+ const entries = readJournalEntries(tmp);
209
+ assert.ok(entries.length > 0, "at least one entry should exist");
210
+ const entry = entries[0];
211
+ assert.ok(entry.flowId, "flowId should be set");
212
+ assert.ok(
213
+ /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(entry.flowId),
214
+ "flowId should be a valid UUID",
215
+ );
216
+ assert.equal(entry.seq, 0);
217
+ assert.ok(entry.ts, "ts should be set");
218
+ assert.ok(!isNaN(Date.parse(entry.ts)), "ts should be a valid ISO date");
219
+ });
220
+ });