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
@@ -1,9 +1,10 @@
1
1
  // GSD Extension — Hook Engine Tests (Post-Unit, Pre-Dispatch, State Persistence)
2
2
 
3
+ import { describe, test } from 'node:test';
4
+ import assert from 'node:assert/strict';
3
5
  import { mkdtempSync, mkdirSync, rmSync, writeFileSync, existsSync, readFileSync } from "node:fs";
4
6
  import { join } from "node:path";
5
7
  import { tmpdir } from "node:os";
6
- import { createTestContext } from "./test-helpers.ts";
7
8
  import {
8
9
  checkPostUnitHooks,
9
10
  getActiveHook,
@@ -20,8 +21,6 @@ import {
20
21
  triggerHookManually,
21
22
  } from "../post-unit-hooks.ts";
22
23
 
23
- const { assertEq, assertTrue, assertMatch, report } = createTestContext();
24
-
25
24
  // ─── Fixture Helpers ───────────────────────────────────────────────────────
26
25
 
27
26
  function createFixtureBase(): string {
@@ -36,14 +35,14 @@ function createFixtureBase(): string {
36
35
 
37
36
  // ─── resolveHookArtifactPath ───────────────────────────────────────────────
38
37
 
39
- console.log("\n=== resolveHookArtifactPath ===");
40
38
 
41
- {
39
+ describe('post-unit-hooks', () => {
40
+ test('resolveHookArtifactPath', () => {
42
41
  const base = "/project";
43
42
 
44
43
  // Task-level
45
44
  const taskPath = resolveHookArtifactPath(base, "M001/S01/T01", "REVIEW-PASS.md");
46
- assertEq(
45
+ assert.deepStrictEqual(
47
46
  taskPath,
48
47
  join(base, ".gsd", "milestones", "M001", "slices", "S01", "tasks", "T01-REVIEW-PASS.md"),
49
48
  "task-level artifact path",
@@ -51,7 +50,7 @@ console.log("\n=== resolveHookArtifactPath ===");
51
50
 
52
51
  // Slice-level
53
52
  const slicePath = resolveHookArtifactPath(base, "M001/S01", "REVIEW-PASS.md");
54
- assertEq(
53
+ assert.deepStrictEqual(
55
54
  slicePath,
56
55
  join(base, ".gsd", "milestones", "M001", "slices", "S01", "REVIEW-PASS.md"),
57
56
  "slice-level artifact path",
@@ -59,129 +58,106 @@ console.log("\n=== resolveHookArtifactPath ===");
59
58
 
60
59
  // Milestone-level
61
60
  const milestonePath = resolveHookArtifactPath(base, "M001", "REVIEW-PASS.md");
62
- assertEq(
61
+ assert.deepStrictEqual(
63
62
  milestonePath,
64
63
  join(base, ".gsd", "milestones", "M001", "REVIEW-PASS.md"),
65
64
  "milestone-level artifact path",
66
65
  );
67
- }
66
+ });
68
67
 
69
68
  // ─── resetHookState ────────────────────────────────────────────────────────
70
-
71
- console.log("\n=== resetHookState ===");
72
-
73
- {
69
+ test('resetHookState', () => {
74
70
  resetHookState();
75
- assertEq(getActiveHook(), null, "no active hook after reset");
76
- assertTrue(!isRetryPending(), "no retry pending after reset");
77
- assertEq(consumeRetryTrigger(), null, "no retry trigger after reset");
78
- }
71
+ assert.deepStrictEqual(getActiveHook(), null, "no active hook after reset");
72
+ assert.ok(!isRetryPending(), "no retry pending after reset");
73
+ assert.deepStrictEqual(consumeRetryTrigger(), null, "no retry trigger after reset");
74
+ });
79
75
 
80
76
  // ─── checkPostUnitHooks with no hooks configured ───────────────────────────
81
-
82
- console.log("\n=== No hooks configured ===");
83
-
84
- {
77
+ test('No hooks configured', () => {
85
78
  resetHookState();
86
79
  const base = createFixtureBase();
87
80
  try {
88
81
  const result = checkPostUnitHooks("execute-task", "M001/S01/T01", base);
89
- assertEq(result, null, "returns null when no hooks configured");
82
+ assert.deepStrictEqual(result, null, "returns null when no hooks configured");
90
83
  } finally {
91
84
  rmSync(base, { recursive: true, force: true });
92
85
  }
93
- }
86
+ });
94
87
 
95
88
  // ─── Hook units don't trigger hooks (no hook-on-hook) ──────────────────────
96
-
97
- console.log("\n=== Hook-on-hook prevention ===");
98
-
99
- {
89
+ test('Hook-on-hook prevention', () => {
100
90
  resetHookState();
101
91
  const base = createFixtureBase();
102
92
  try {
103
93
  const result = checkPostUnitHooks("hook/code-review", "M001/S01/T01", base);
104
- assertEq(result, null, "hook units don't trigger other hooks");
94
+ assert.deepStrictEqual(result, null, "hook units don't trigger other hooks");
105
95
  } finally {
106
96
  rmSync(base, { recursive: true, force: true });
107
97
  }
108
- }
98
+ });
109
99
 
110
100
  // ─── consumeRetryTrigger clears state ──────────────────────────────────────
111
-
112
- console.log("\n=== consumeRetryTrigger clears state ===");
113
-
114
- {
101
+ test('consumeRetryTrigger clears state', () => {
115
102
  resetHookState();
116
- assertEq(consumeRetryTrigger(), null, "no trigger initially");
117
- assertTrue(!isRetryPending(), "no retry initially");
118
- }
103
+ assert.deepStrictEqual(consumeRetryTrigger(), null, "no trigger initially");
104
+ assert.ok(!isRetryPending(), "no retry initially");
105
+ });
119
106
 
120
107
  // ─── Variable substitution in prompts ──────────────────────────────────────
121
-
122
- console.log("\n=== Variable substitution ===");
123
-
124
- {
108
+ test('Variable substitution', () => {
125
109
  const base = "/project";
126
110
 
127
111
  // 3-part ID
128
112
  const path3 = resolveHookArtifactPath(base, "M002/S03/T05", "result.md");
129
- assertTrue(path3.includes("M002"), "3-part ID extracts milestoneId");
130
- assertTrue(path3.includes("S03"), "3-part ID extracts sliceId");
131
- assertTrue(path3.includes("T05"), "3-part ID extracts taskId");
132
- assertTrue(path3.includes("milestones"), "3-part ID includes milestones/ segment");
113
+ assert.ok(path3.includes("M002"), "3-part ID extracts milestoneId");
114
+ assert.ok(path3.includes("S03"), "3-part ID extracts sliceId");
115
+ assert.ok(path3.includes("T05"), "3-part ID extracts taskId");
116
+ assert.ok(path3.includes("milestones"), "3-part ID includes milestones/ segment");
133
117
 
134
118
  // 2-part ID
135
119
  const path2 = resolveHookArtifactPath(base, "M002/S03", "result.md");
136
- assertTrue(path2.includes("M002"), "2-part ID extracts milestoneId");
137
- assertTrue(path2.includes("S03"), "2-part ID extracts sliceId");
138
- assertTrue(path2.includes("milestones"), "2-part ID includes milestones/ segment");
120
+ assert.ok(path2.includes("M002"), "2-part ID extracts milestoneId");
121
+ assert.ok(path2.includes("S03"), "2-part ID extracts sliceId");
122
+ assert.ok(path2.includes("milestones"), "2-part ID includes milestones/ segment");
139
123
 
140
124
  // 1-part ID
141
125
  const path1 = resolveHookArtifactPath(base, "M002", "result.md");
142
- assertTrue(path1.includes("M002"), "1-part ID extracts milestoneId");
143
- assertTrue(path1.includes("milestones"), "1-part ID includes milestones/ segment");
144
- }
126
+ assert.ok(path1.includes("M002"), "1-part ID extracts milestoneId");
127
+ assert.ok(path1.includes("milestones"), "1-part ID includes milestones/ segment");
128
+ });
145
129
 
146
130
  // ═══════════════════════════════════════════════════════════════════════════
147
131
  // Phase 2: Pre-Dispatch Hook Tests
148
132
  // ═══════════════════════════════════════════════════════════════════════════
149
-
150
- console.log("\n=== Pre-dispatch: no hooks configured ===");
151
-
152
- {
133
+ test('Pre-dispatch: no hooks configured', () => {
153
134
  const base = createFixtureBase();
154
135
  try {
155
136
  const result = runPreDispatchHooks("execute-task", "M001/S01/T01", "original prompt", base);
156
- assertEq(result.action, "proceed", "proceeds when no hooks");
157
- assertEq(result.prompt, "original prompt", "prompt unchanged");
158
- assertEq(result.firedHooks.length, 0, "no hooks fired");
137
+ assert.deepStrictEqual(result.action, "proceed", "proceeds when no hooks");
138
+ assert.deepStrictEqual(result.prompt, "original prompt", "prompt unchanged");
139
+ assert.deepStrictEqual(result.firedHooks.length, 0, "no hooks fired");
159
140
  } finally {
160
141
  rmSync(base, { recursive: true, force: true });
161
142
  }
162
- }
163
-
164
- console.log("\n=== Pre-dispatch: hook units bypass ===");
143
+ });
165
144
 
166
- {
145
+ test('Pre-dispatch: hook units bypass', () => {
167
146
  const base = createFixtureBase();
168
147
  try {
169
148
  const result = runPreDispatchHooks("hook/review", "M001/S01/T01", "hook prompt", base);
170
- assertEq(result.action, "proceed", "hook units always proceed");
171
- assertEq(result.prompt, "hook prompt", "hook prompt unchanged");
172
- assertEq(result.firedHooks.length, 0, "no hooks fired for hook units");
149
+ assert.deepStrictEqual(result.action, "proceed", "hook units always proceed");
150
+ assert.deepStrictEqual(result.prompt, "hook prompt", "hook prompt unchanged");
151
+ assert.deepStrictEqual(result.firedHooks.length, 0, "no hooks fired for hook units");
173
152
  } finally {
174
153
  rmSync(base, { recursive: true, force: true });
175
154
  }
176
- }
155
+ });
177
156
 
178
157
  // ═══════════════════════════════════════════════════════════════════════════
179
158
  // Phase 3: State Persistence Tests
180
159
  // ═══════════════════════════════════════════════════════════════════════════
181
-
182
- console.log("\n=== State persistence: persist and restore ===");
183
-
184
- {
160
+ test('State persistence: persist and restore', () => {
185
161
  const base = createFixtureBase();
186
162
  try {
187
163
  resetHookState();
@@ -189,19 +165,17 @@ console.log("\n=== State persistence: persist and restore ===");
189
165
  // Persist empty state
190
166
  persistHookState(base);
191
167
  const filePath = join(base, ".gsd", "hook-state.json");
192
- assertTrue(existsSync(filePath), "hook-state.json created");
168
+ assert.ok(existsSync(filePath), "hook-state.json created");
193
169
 
194
170
  const content = JSON.parse(readFileSync(filePath, "utf-8"));
195
- assertEq(typeof content.savedAt, "string", "savedAt is a string");
196
- assertEq(Object.keys(content.cycleCounts).length, 0, "empty cycle counts");
171
+ assert.deepStrictEqual(typeof content.savedAt, "string", "savedAt is a string");
172
+ assert.deepStrictEqual(Object.keys(content.cycleCounts).length, 0, "empty cycle counts");
197
173
  } finally {
198
174
  rmSync(base, { recursive: true, force: true });
199
175
  }
200
- }
201
-
202
- console.log("\n=== State persistence: restore from disk ===");
176
+ });
203
177
 
204
- {
178
+ test('State persistence: restore from disk', () => {
205
179
  const base = createFixtureBase();
206
180
  try {
207
181
  resetHookState();
@@ -222,16 +196,14 @@ console.log("\n=== State persistence: restore from disk ===");
222
196
  // Verify by persisting and reading back
223
197
  persistHookState(base);
224
198
  const restored = JSON.parse(readFileSync(stateFile, "utf-8"));
225
- assertEq(restored.cycleCounts["review/execute-task/M001/S01/T01"], 2, "cycle count restored for review");
226
- assertEq(restored.cycleCounts["simplify/execute-task/M001/S01/T02"], 1, "cycle count restored for simplify");
199
+ assert.deepStrictEqual(restored.cycleCounts["review/execute-task/M001/S01/T01"], 2, "cycle count restored for review");
200
+ assert.deepStrictEqual(restored.cycleCounts["simplify/execute-task/M001/S01/T02"], 1, "cycle count restored for simplify");
227
201
  } finally {
228
202
  rmSync(base, { recursive: true, force: true });
229
203
  }
230
- }
231
-
232
- console.log("\n=== State persistence: clear ===");
204
+ });
233
205
 
234
- {
206
+ test('State persistence: clear', () => {
235
207
  const base = createFixtureBase();
236
208
  try {
237
209
  resetHookState();
@@ -246,77 +218,65 @@ console.log("\n=== State persistence: clear ===");
246
218
  clearPersistedHookState(base);
247
219
 
248
220
  const cleared = JSON.parse(readFileSync(stateFile, "utf-8"));
249
- assertEq(Object.keys(cleared.cycleCounts).length, 0, "cycle counts cleared");
221
+ assert.deepStrictEqual(Object.keys(cleared.cycleCounts).length, 0, "cycle counts cleared");
250
222
  } finally {
251
223
  rmSync(base, { recursive: true, force: true });
252
224
  }
253
- }
225
+ });
254
226
 
255
- console.log("\n=== State persistence: restore handles missing file ===");
256
-
257
- {
227
+ test('State persistence: restore handles missing file', () => {
258
228
  const base = createFixtureBase();
259
229
  try {
260
230
  resetHookState();
261
231
  // Should not throw
262
232
  restoreHookState(base);
263
- assertEq(getActiveHook(), null, "no active hook after restore from missing file");
233
+ assert.deepStrictEqual(getActiveHook(), null, "no active hook after restore from missing file");
264
234
  } finally {
265
235
  rmSync(base, { recursive: true, force: true });
266
236
  }
267
- }
237
+ });
268
238
 
269
- console.log("\n=== State persistence: restore handles corrupt file ===");
270
-
271
- {
239
+ test('State persistence: restore handles corrupt file', () => {
272
240
  const base = createFixtureBase();
273
241
  try {
274
242
  resetHookState();
275
243
  writeFileSync(join(base, ".gsd", "hook-state.json"), "not json", "utf-8");
276
244
  // Should not throw
277
245
  restoreHookState(base);
278
- assertEq(getActiveHook(), null, "no active hook after corrupt restore");
246
+ assert.deepStrictEqual(getActiveHook(), null, "no active hook after corrupt restore");
279
247
  } finally {
280
248
  rmSync(base, { recursive: true, force: true });
281
249
  }
282
- }
250
+ });
283
251
 
284
252
  // ═══════════════════════════════════════════════════════════════════════════
285
253
  // Phase 3: Hook Status Reporting Tests
286
254
  // ═══════════════════════════════════════════════════════════════════════════
287
-
288
- console.log("\n=== Hook status: no hooks ===");
289
-
290
- {
255
+ test('Hook status: no hooks', () => {
291
256
  resetHookState();
292
257
  const entries = getHookStatus();
293
258
  // No preferences file = no hooks
294
- assertEq(entries.length, 0, "no entries when no hooks configured");
259
+ assert.deepStrictEqual(entries.length, 0, "no entries when no hooks configured");
295
260
 
296
261
  const formatted = formatHookStatus();
297
- assertMatch(formatted, /No hooks configured/, "status message says no hooks");
298
- }
262
+ assert.match(formatted, /No hooks configured/, "status message says no hooks");
263
+ });
299
264
 
300
265
  // ═══════════════════════════════════════════════════════════════════════════
301
266
  // Phase 4: Manual Hook Trigger Tests
302
267
  // ═══════════════════════════════════════════════════════════════════════════
303
-
304
- console.log("\n=== triggerHookManually: hook not found ===");
305
-
306
- {
268
+ test('triggerHookManually: hook not found', () => {
307
269
  resetHookState();
308
270
  const base = createFixtureBase();
309
271
  try {
310
272
  const result = triggerHookManually("nonexistent-hook", "execute-task", "M001/S01/T01", base);
311
- assertEq(result, null, "returns null when hook not found");
273
+ assert.deepStrictEqual(result, null, "returns null when hook not found");
312
274
  } finally {
313
275
  rmSync(base, { recursive: true, force: true });
314
276
  }
315
- }
277
+ });
316
278
 
317
- console.log("\n=== triggerHookManually: with configured hook ===");
318
-
319
- {
279
+ test('triggerHookManually: with configured hook', () => {
320
280
  resetHookState();
321
281
  const base = createFixtureBase();
322
282
  try {
@@ -325,16 +285,16 @@ console.log("\n=== triggerHookManually: with configured hook ===");
325
285
  const result = triggerHookManually("code-review", "execute-task", "M001/S01/T01", base);
326
286
  // Result depends on whether code-review hook is configured in preferences
327
287
  // The function should either return null or a valid HookDispatchResult
328
- assertTrue(result === null || typeof result === "object", "returns null or object");
288
+ assert.ok(result === null || typeof result === "object", "returns null or object");
329
289
  if (result) {
330
- assertEq(result.hookName, "code-review", "hook name in result");
331
- assertEq(result.unitType, "hook/code-review", "unit type is hook-prefixed");
332
- assertEq(result.unitId, "M001/S01/T01", "unit ID preserved");
333
- assertTrue(typeof result.prompt === "string", "prompt is a string");
290
+ assert.deepStrictEqual(result.hookName, "code-review", "hook name in result");
291
+ assert.deepStrictEqual(result.unitType, "hook/code-review", "unit type is hook-prefixed");
292
+ assert.deepStrictEqual(result.unitId, "M001/S01/T01", "unit ID preserved");
293
+ assert.ok(typeof result.prompt === "string", "prompt is a string");
334
294
  }
335
295
  } finally {
336
296
  rmSync(base, { recursive: true, force: true });
337
297
  }
338
- }
298
+ });
339
299
 
340
- report();
300
+ });
@@ -15,6 +15,7 @@ import {
15
15
  applyModeDefaults,
16
16
  getIsolationMode,
17
17
  parsePreferencesMarkdown,
18
+ _resetParseWarningFlag,
18
19
  } from "../preferences.ts";
19
20
  import type { GSDPreferences, GSDModelConfigV2, GSDPhaseModelConfig } from "../preferences.ts";
20
21
 
@@ -40,18 +41,16 @@ test("git.merge_to_main produces deprecation warning", () => {
40
41
  });
41
42
 
42
43
 
43
- test("getIsolationMode defaults to worktree when preferences have no isolation setting", () => {
44
+ test("getIsolationMode defaults to none when preferences have no isolation setting", () => {
44
45
  // Validate the default via validatePreferences: when no isolation is set,
45
- // preferences.git.isolation is undefined, and getIsolationMode returns "worktree".
46
- // We test the function's logic by verifying its documented default.
46
+ // preferences.git.isolation is undefined, and getIsolationMode returns "none".
47
+ // Default changed from "worktree" to "none" so GSD works out of the box
48
+ // without preferences.md (#2480).
47
49
  const { preferences } = validatePreferences({});
48
50
  assert.equal(preferences.git?.isolation, undefined, "no isolation in empty prefs");
49
- // The function returns "worktree" when prefs?.git?.isolation is not "none" or "branch"
50
- // This is a compile-time-verifiable truth from the function body — test it directly
51
- // by constructing the same conditions getIsolationMode checks.
52
51
  const isolation = preferences.git?.isolation;
53
- const expected = isolation === "none" ? "none" : isolation === "branch" ? "branch" : "worktree";
54
- assert.equal(expected, "worktree", "default isolation mode is worktree");
52
+ const expected = isolation === "worktree" ? "worktree" : isolation === "branch" ? "branch" : "none";
53
+ assert.equal(expected, "none", "default isolation mode is none");
55
54
  });
56
55
 
57
56
  // ── Mode defaults ────────────────────────────────────────────────────────────
@@ -62,7 +61,7 @@ test("solo mode applies correct defaults", () => {
62
61
  assert.equal(result.git?.push_branches, false);
63
62
  assert.equal(result.git?.pre_merge_check, false);
64
63
  assert.equal(result.git?.merge_strategy, "squash");
65
- assert.equal(result.git?.isolation, "worktree");
64
+ assert.equal(result.git?.isolation, "none");
66
65
  assert.equal(result.unique_milestone_ids, false);
67
66
  });
68
67
 
@@ -352,3 +351,29 @@ test("handles empty models config", () => {
352
351
  assert.notEqual(prefs, null);
353
352
  assert.equal(prefs!.models, undefined);
354
353
  });
354
+
355
+ // ── Warn-once for unrecognized format (#2373) ────────────────────────────────
356
+
357
+ test("unrecognized format warning is emitted at most once (#2373)", () => {
358
+ const warnings: string[] = [];
359
+ const origWarn = console.warn;
360
+ console.warn = (...args: unknown[]) => warnings.push(args.join(" "));
361
+ try {
362
+ // Reset internal warned flag so the test starts clean
363
+ _resetParseWarningFlag();
364
+
365
+ const unrecognized = "This is just plain text with no frontmatter or headings.";
366
+
367
+ // Call multiple times — simulates repeated preference loads
368
+ parsePreferencesMarkdown(unrecognized);
369
+ parsePreferencesMarkdown(unrecognized);
370
+ parsePreferencesMarkdown(unrecognized);
371
+
372
+ const relevant = warnings.filter(w => w.includes("unrecognized format"));
373
+ assert.equal(relevant.length, 1, `expected exactly 1 warning, got ${relevant.length}: ${JSON.stringify(relevant)}`);
374
+ } finally {
375
+ console.warn = origWarn;
376
+ // Reset so other tests aren't affected by the flag state
377
+ _resetParseWarningFlag();
378
+ }
379
+ });
@@ -0,0 +1,174 @@
1
+ // GSD — projection renderer regression tests
2
+ // Verifies that "done" vs "complete" status mismatch doesn't recur.
3
+ // Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
4
+
5
+ import test from 'node:test';
6
+ import assert from 'node:assert/strict';
7
+
8
+ import { renderPlanContent, renderRoadmapContent } from '../workflow-projections.ts';
9
+ import type { SliceRow, TaskRow } from '../gsd-db.ts';
10
+
11
+ // ─── Helpers ─────────────────────────────────────────────────────────────
12
+
13
+ function makeSliceRow(overrides?: Partial<SliceRow>): SliceRow {
14
+ return {
15
+ milestone_id: 'M001',
16
+ id: 'S01',
17
+ title: 'Test Slice',
18
+ status: 'pending',
19
+ risk: 'medium',
20
+ depends: [],
21
+ demo: 'Demo.',
22
+ created_at: '2026-01-01T00:00:00Z',
23
+ completed_at: null,
24
+ full_summary_md: '',
25
+ full_uat_md: '',
26
+ goal: 'Test goal',
27
+ success_criteria: '',
28
+ proof_level: '',
29
+ integration_closure: '',
30
+ observability_impact: '',
31
+ sequence: 0,
32
+ replan_triggered_at: null,
33
+ ...overrides,
34
+ };
35
+ }
36
+
37
+ function makeTaskRow(overrides?: Partial<TaskRow>): TaskRow {
38
+ return {
39
+ milestone_id: 'M001',
40
+ slice_id: 'S01',
41
+ id: 'T01',
42
+ title: 'Test Task',
43
+ status: 'pending',
44
+ one_liner: '',
45
+ narrative: '',
46
+ verification_result: '',
47
+ duration: '',
48
+ completed_at: null,
49
+ blocker_discovered: false,
50
+ deviations: '',
51
+ known_issues: '',
52
+ key_files: [],
53
+ key_decisions: [],
54
+ full_summary_md: '',
55
+ full_plan_md: '',
56
+ description: 'Test description',
57
+ estimate: '30m',
58
+ files: ['src/test.ts'],
59
+ verify: 'npm test',
60
+ inputs: [],
61
+ expected_output: [],
62
+ observability_impact: '',
63
+ sequence: 0,
64
+ ...overrides,
65
+ };
66
+ }
67
+
68
+ function makeMilestoneRow() {
69
+ return {
70
+ id: 'M001',
71
+ title: 'Test Milestone',
72
+ status: 'active',
73
+ depends_on: [],
74
+ created_at: '2026-01-01T00:00:00Z',
75
+ completed_at: null,
76
+ vision: 'Test vision',
77
+ success_criteria: [],
78
+ key_risks: [],
79
+ proof_strategy: [],
80
+ verification_contract: '',
81
+ verification_integration: '',
82
+ verification_operational: '',
83
+ verification_uat: '',
84
+ definition_of_done: [],
85
+ requirement_coverage: '',
86
+ boundary_map_markdown: '',
87
+ };
88
+ }
89
+
90
+ // ─── renderPlanContent: checkbox regression ──────────────────────────────
91
+
92
+ test('renderPlanContent: task with status "complete" renders [x] checkbox', () => {
93
+ const slice = makeSliceRow();
94
+ const tasks = [makeTaskRow({ id: 'T01', status: 'complete', title: 'Completed Task' })];
95
+
96
+ const content = renderPlanContent(slice, tasks);
97
+
98
+ assert.match(content, /\[x\]\s+\*\*T01:/, 'complete task should have [x] checkbox');
99
+ });
100
+
101
+ test('renderPlanContent: task with status "done" renders [x] checkbox', () => {
102
+ const slice = makeSliceRow();
103
+ const tasks = [makeTaskRow({ id: 'T01', status: 'done', title: 'Done Task' })];
104
+
105
+ const content = renderPlanContent(slice, tasks);
106
+
107
+ assert.match(content, /\[x\]\s+\*\*T01:/, 'done task should have [x] checkbox');
108
+ });
109
+
110
+ test('renderPlanContent: task with status "pending" renders [ ] checkbox', () => {
111
+ const slice = makeSliceRow();
112
+ const tasks = [makeTaskRow({ id: 'T01', status: 'pending', title: 'Pending Task' })];
113
+
114
+ const content = renderPlanContent(slice, tasks);
115
+
116
+ assert.match(content, /\[ \]\s+\*\*T01:/, 'pending task should have [ ] checkbox');
117
+ });
118
+
119
+ test('renderPlanContent: mixed statuses render correct checkboxes', () => {
120
+ const slice = makeSliceRow();
121
+ const tasks = [
122
+ makeTaskRow({ id: 'T01', status: 'complete', title: 'Done One' }),
123
+ makeTaskRow({ id: 'T02', status: 'pending', title: 'Pending One' }),
124
+ makeTaskRow({ id: 'T03', status: 'done', title: 'Done Two' }),
125
+ ];
126
+
127
+ const content = renderPlanContent(slice, tasks);
128
+
129
+ assert.match(content, /\[x\]\s+\*\*T01:/, 'T01 (complete) should be checked');
130
+ assert.match(content, /\[ \]\s+\*\*T02:/, 'T02 (pending) should be unchecked');
131
+ assert.match(content, /\[x\]\s+\*\*T03:/, 'T03 (done) should be checked');
132
+ });
133
+
134
+ // ─── renderPlanContent: format regression (parsePlan compatibility) ──────
135
+
136
+ test('renderPlanContent: format matches parsePlan regex **ID: title**', () => {
137
+ const slice = makeSliceRow();
138
+ const tasks = [makeTaskRow({ id: 'T01', status: 'pending', title: 'My Task' })];
139
+
140
+ const content = renderPlanContent(slice, tasks);
141
+
142
+ // parsePlan expects: **T01: My Task** (both ID and title inside bold)
143
+ // NOT: **T01:** My Task (only ID in bold)
144
+ assert.match(content, /\*\*T01: My Task\*\*/, 'ID and title should both be inside bold markers');
145
+ });
146
+
147
+ // ─── renderRoadmapContent: status regression ─────────────────────────────
148
+
149
+ test('renderRoadmapContent: slice with status "complete" shows ✅', () => {
150
+ const milestone = makeMilestoneRow();
151
+ const slices = [makeSliceRow({ id: 'S01', status: 'complete' })];
152
+
153
+ const content = renderRoadmapContent(milestone, slices);
154
+
155
+ assert.ok(content.includes('✅'), 'complete slice should show ✅');
156
+ });
157
+
158
+ test('renderRoadmapContent: slice with status "done" shows ✅', () => {
159
+ const milestone = makeMilestoneRow();
160
+ const slices = [makeSliceRow({ id: 'S01', status: 'done' })];
161
+
162
+ const content = renderRoadmapContent(milestone, slices);
163
+
164
+ assert.ok(content.includes('✅'), 'done slice should show ✅');
165
+ });
166
+
167
+ test('renderRoadmapContent: slice with status "pending" shows ⬜', () => {
168
+ const milestone = makeMilestoneRow();
169
+ const slices = [makeSliceRow({ id: 'S01', status: 'pending' })];
170
+
171
+ const content = renderRoadmapContent(milestone, slices);
172
+
173
+ assert.ok(content.includes('⬜'), 'pending slice should show ⬜');
174
+ });