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,8 +1,9 @@
1
+ import { describe, test, afterEach } from "node:test";
2
+ import assert from "node:assert/strict";
1
3
  import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
2
4
  import { join, dirname } from "node:path";
3
5
  import { tmpdir } from "node:os";
4
6
  import { fileURLToPath } from "node:url";
5
- import { createTestContext } from './test-helpers.ts';
6
7
  import { invalidateAllCaches } from '../cache.ts';
7
8
 
8
9
  // loadPrompt reads from ~/.gsd/agent/extensions/gsd/prompts/ (main checkout).
@@ -11,7 +12,6 @@ import { invalidateAllCaches } from '../cache.ts';
11
12
  const __dirname = dirname(fileURLToPath(import.meta.url));
12
13
  const worktreePromptsDir = join(__dirname, "..", "prompts");
13
14
 
14
- const { assertEq, assertTrue, report } = createTestContext();
15
15
  /**
16
16
  * Load a prompt template from the worktree prompts directory
17
17
  * and apply variable substitution (mirrors loadPrompt logic).
@@ -59,11 +59,9 @@ function cleanup(base: string): void {
59
59
  // Tests
60
60
  // ═══════════════════════════════════════════════════════════════════════════
61
61
 
62
- async function main(): Promise<void> {
62
+ describe("complete-milestone", () => {
63
63
 
64
- // ─── Prompt Template Loading ───────────────────────────────────────────
65
- console.log("\n=== complete-milestone prompt template exists ===");
66
- {
64
+ test("prompt template exists and loads", () => {
67
65
  let result: string;
68
66
  let threw = false;
69
67
  try {
@@ -77,16 +75,13 @@ async function main(): Promise<void> {
77
75
  } catch (err) {
78
76
  threw = true;
79
77
  result = "";
80
- console.error(` ERROR: loadPrompt threw: ${err}`);
81
78
  }
82
79
 
83
- assertTrue(!threw, "loadPrompt does not throw for complete-milestone");
84
- assertTrue(typeof result === "string" && result.length > 0, "loadPrompt returns a non-empty string");
85
- }
80
+ assert.ok(!threw, "loadPrompt does not throw for complete-milestone");
81
+ assert.ok(typeof result === "string" && result.length > 0, "loadPrompt returns a non-empty string");
82
+ });
86
83
 
87
- // ─── Variable Substitution ─────────────────────────────────────────────
88
- console.log("\n=== prompt variable substitution ===");
89
- {
84
+ test("prompt variable substitution", () => {
90
85
  const prompt = loadPromptFromWorktree("complete-milestone", {
91
86
  workingDirectory: "/tmp/test-project",
92
87
  milestoneId: "M001",
@@ -95,19 +90,17 @@ async function main(): Promise<void> {
95
90
  inlinedContext: "--- inlined slice summaries and context ---",
96
91
  });
97
92
 
98
- assertTrue(prompt.includes("M001"), "prompt contains milestoneId 'M001'");
99
- assertTrue(prompt.includes("Integration Feature"), "prompt contains milestoneTitle");
100
- assertTrue(prompt.includes(".gsd/milestones/M001/M001-ROADMAP.md"), "prompt contains roadmapPath");
101
- assertTrue(prompt.includes("--- inlined slice summaries and context ---"), "prompt contains inlinedContext");
102
- assertTrue(!prompt.includes("{{milestoneId}}"), "no un-substituted {{milestoneId}}");
103
- assertTrue(!prompt.includes("{{milestoneTitle}}"), "no un-substituted {{milestoneTitle}}");
104
- assertTrue(!prompt.includes("{{roadmapPath}}"), "no un-substituted {{roadmapPath}}");
105
- assertTrue(!prompt.includes("{{inlinedContext}}"), "no un-substituted {{inlinedContext}}");
106
- }
107
-
108
- // ─── Prompt Content Integrity ──────────────────────────────────────────
109
- console.log("\n=== prompt content integrity ===");
110
- {
93
+ assert.ok(prompt.includes("M001"), "prompt contains milestoneId 'M001'");
94
+ assert.ok(prompt.includes("Integration Feature"), "prompt contains milestoneTitle");
95
+ assert.ok(prompt.includes(".gsd/milestones/M001/M001-ROADMAP.md"), "prompt contains roadmapPath");
96
+ assert.ok(prompt.includes("--- inlined slice summaries and context ---"), "prompt contains inlinedContext");
97
+ assert.ok(!prompt.includes("{{milestoneId}}"), "no un-substituted {{milestoneId}}");
98
+ assert.ok(!prompt.includes("{{milestoneTitle}}"), "no un-substituted {{milestoneTitle}}");
99
+ assert.ok(!prompt.includes("{{roadmapPath}}"), "no un-substituted {{roadmapPath}}");
100
+ assert.ok(!prompt.includes("{{inlinedContext}}"), "no un-substituted {{inlinedContext}}");
101
+ });
102
+
103
+ test("prompt content integrity", () => {
111
104
  const prompt = loadPromptFromWorktree("complete-milestone", {
112
105
  workingDirectory: "/tmp/test-project",
113
106
  milestoneId: "M002",
@@ -116,18 +109,109 @@ async function main(): Promise<void> {
116
109
  inlinedContext: "context",
117
110
  });
118
111
 
119
- assertTrue(prompt.includes("Complete Milestone"), "prompt contains 'Complete Milestone' heading");
120
- assertTrue(prompt.includes("success criter") || prompt.includes("success criteria"), "prompt mentions success criteria verification");
121
- assertTrue(prompt.includes("milestone-summary") || prompt.includes("milestoneSummary"), "prompt references milestone summary artifact");
122
- assertTrue(prompt.includes("Milestone M002 complete"), "prompt contains completion sentinel for M002");
123
- }
112
+ assert.ok(prompt.includes("Complete Milestone"), "prompt contains 'Complete Milestone' heading");
113
+ assert.ok(prompt.includes("success criter") || prompt.includes("success criteria"), "prompt mentions success criteria verification");
114
+ assert.ok(prompt.includes("milestone-summary") || prompt.includes("milestoneSummary"), "prompt references milestone summary artifact");
115
+ assert.ok(prompt.includes("Milestone M002 complete"), "prompt contains completion sentinel for M002");
116
+ });
117
+
118
+ test("prompt contains verification gate that blocks completion on failure", () => {
119
+ const prompt = loadPromptFromWorktree("complete-milestone", {
120
+ workingDirectory: "/tmp/test-project",
121
+ milestoneId: "M001",
122
+ milestoneTitle: "Gate Test",
123
+ roadmapPath: ".gsd/milestones/M001/M001-ROADMAP.md",
124
+ inlinedContext: "context",
125
+ });
126
+
127
+ // Verification gate section must exist
128
+ assert.ok(
129
+ prompt.includes("Verification Gate"),
130
+ "prompt contains 'Verification Gate' section",
131
+ );
132
+
133
+ // Failure path must block gsd_complete_milestone
134
+ assert.ok(
135
+ prompt.includes("Do NOT call `gsd_complete_milestone`"),
136
+ "failure path explicitly blocks calling the completion tool",
137
+ );
138
+
139
+ // Failure path must have its own sentinel distinct from success
140
+ assert.ok(
141
+ prompt.includes("verification FAILED"),
142
+ "failure path outputs a FAILED sentinel",
143
+ );
144
+
145
+ // verificationPassed parameter must be referenced
146
+ assert.ok(
147
+ prompt.includes("verificationPassed"),
148
+ "prompt references verificationPassed parameter",
149
+ );
150
+ });
151
+
152
+ test("handleCompleteMilestone rejects when verificationPassed is false", async () => {
153
+ const { handleCompleteMilestone } = await import("../tools/complete-milestone.ts");
154
+ const base = createFixtureBase();
155
+ try {
156
+ const result = await handleCompleteMilestone({
157
+ milestoneId: "M001",
158
+ title: "Test Milestone",
159
+ oneLiner: "Test",
160
+ narrative: "Test narrative",
161
+ successCriteriaResults: "None met",
162
+ definitionOfDoneResults: "Incomplete",
163
+ requirementOutcomes: "None validated",
164
+ keyDecisions: [],
165
+ keyFiles: [],
166
+ lessonsLearned: [],
167
+ followUps: "",
168
+ deviations: "",
169
+ verificationPassed: false,
170
+ }, base);
171
+
172
+ assert.ok("error" in result, "returns error when verificationPassed is false");
173
+ assert.ok(
174
+ (result as { error: string }).error.includes("verification did not pass"),
175
+ "error message mentions verification did not pass",
176
+ );
177
+ } finally {
178
+ cleanup(base);
179
+ }
180
+ });
124
181
 
125
- // ─── diagnoseExpectedArtifact behavior ─────────────────────────────────
126
- // Since diagnoseExpectedArtifact is not exported from auto.ts, we test
127
- // the same logic by reimplementing the switch case for complete-milestone
128
- // and verifying against known path patterns.
129
- console.log("\n=== diagnoseExpectedArtifact logic for complete-milestone ===");
130
- {
182
+ test("handleCompleteMilestone rejects when verificationPassed is omitted", async () => {
183
+ const { handleCompleteMilestone } = await import("../tools/complete-milestone.ts");
184
+ const base = createFixtureBase();
185
+ try {
186
+ // Simulate omitted verificationPassed (undefined coerced via any)
187
+ const params: any = {
188
+ milestoneId: "M001",
189
+ title: "Test Milestone",
190
+ oneLiner: "Test",
191
+ narrative: "Test narrative",
192
+ successCriteriaResults: "Results",
193
+ definitionOfDoneResults: "Done results",
194
+ requirementOutcomes: "Outcomes",
195
+ keyDecisions: [],
196
+ keyFiles: [],
197
+ lessonsLearned: [],
198
+ followUps: "",
199
+ deviations: "",
200
+ // verificationPassed intentionally omitted
201
+ };
202
+ const result = await handleCompleteMilestone(params, base);
203
+
204
+ assert.ok("error" in result, "returns error when verificationPassed is omitted");
205
+ assert.ok(
206
+ (result as { error: string }).error.includes("verification did not pass"),
207
+ "error message mentions verification did not pass",
208
+ );
209
+ } finally {
210
+ cleanup(base);
211
+ }
212
+ });
213
+
214
+ test("diagnoseExpectedArtifact logic for complete-milestone", async () => {
131
215
  // Import the path helpers used by diagnoseExpectedArtifact
132
216
  const { relMilestoneFile } = await import("../paths.ts");
133
217
 
@@ -144,18 +228,16 @@ async function main(): Promise<void> {
144
228
  // This is the exact logic from diagnoseExpectedArtifact for "complete-milestone"
145
229
  const result = `${relMilestoneFile(base, mid, "SUMMARY")} (milestone summary)`;
146
230
 
147
- assertTrue(typeof result === "string", "diagnose returns a string");
148
- assertTrue(result.includes("SUMMARY"), "diagnose result mentions SUMMARY");
149
- assertTrue(result.includes("milestone"), "diagnose result mentions milestone");
150
- assertTrue(result.includes("M001"), "diagnose result includes the milestone ID");
231
+ assert.ok(typeof result === "string", "diagnose returns a string");
232
+ assert.ok(result.includes("SUMMARY"), "diagnose result mentions SUMMARY");
233
+ assert.ok(result.includes("milestone"), "diagnose result mentions milestone");
234
+ assert.ok(result.includes("M001"), "diagnose result includes the milestone ID");
151
235
  } finally {
152
236
  cleanup(base);
153
237
  }
154
- }
238
+ });
155
239
 
156
- // ─── deriveState integration: completing-milestone dispatches correctly
157
- console.log("\n=== deriveState completing-milestone integration ===");
158
- {
240
+ test("deriveState completing-milestone integration", async () => {
159
241
  const { deriveState, isMilestoneComplete } = await import("../state.ts");
160
242
  const { invalidateAllCaches: invalidateAllCachesDynamic } = await import("../cache.ts");
161
243
  const { parseRoadmap } = await import("../parsers-legacy.ts");
@@ -180,30 +262,23 @@ async function main(): Promise<void> {
180
262
  const roadmapPath = join(base, ".gsd", "milestones", "M001", "M001-ROADMAP.md");
181
263
  const roadmapContent = await loadFile(roadmapPath);
182
264
  const roadmap = parseRoadmap(roadmapContent!);
183
- assertTrue(isMilestoneComplete(roadmap), "isMilestoneComplete returns true when all slices are [x]");
265
+ assert.ok(isMilestoneComplete(roadmap), "isMilestoneComplete returns true when all slices are [x]");
184
266
 
185
267
  // Verify deriveState returns completing-milestone phase (with validation already done)
186
268
  writeMilestoneValidation(base, "M001");
187
269
  const state = await deriveState(base);
188
- assertEq(state.phase, "completing-milestone", "deriveState returns completing-milestone when all slices done, no summary");
189
- assertEq(state.activeMilestone?.id, "M001", "active milestone is M001");
190
- assertEq(state.activeSlice, null, "no active slice in completing-milestone");
270
+ assert.strictEqual(state.phase, "completing-milestone", "deriveState returns completing-milestone when all slices done, no summary");
271
+ assert.strictEqual(state.activeMilestone?.id, "M001", "active milestone is M001");
272
+ assert.strictEqual(state.activeSlice, null, "no active slice in completing-milestone");
191
273
 
192
274
  // Now add the summary and verify it transitions to complete
193
275
  writeMilestoneSummary(base, "M001", "# M001 Summary\n\nDone.");
194
276
  invalidateAllCachesDynamic();
195
277
  const stateAfter = await deriveState(base);
196
- assertEq(stateAfter.phase, "complete", "deriveState returns complete after summary exists");
197
- assertEq(stateAfter.registry[0]?.status, "complete", "registry shows complete status");
278
+ assert.strictEqual(stateAfter.phase, "complete", "deriveState returns complete after summary exists");
279
+ assert.strictEqual(stateAfter.registry[0]?.status, "complete", "registry shows complete status");
198
280
  } finally {
199
281
  cleanup(base);
200
282
  }
201
- }
202
-
203
- report();
204
- }
205
-
206
- main().catch((error) => {
207
- console.error(error);
208
- process.exit(1);
283
+ });
209
284
  });
@@ -127,7 +127,7 @@ console.log('\n=== complete-slice: schema v6 migration ===');
127
127
 
128
128
  // Verify schema version is current (v10 after M001 planning migrations)
129
129
  const versionRow = adapter.prepare('SELECT MAX(version) as v FROM schema_version').get();
130
- assertEq(versionRow?.['v'], 10, 'schema version should be 10');
130
+ assertEq(versionRow?.['v'], 11, 'schema version should be 11');
131
131
 
132
132
  // Verify slices table has full_summary_md and full_uat_md columns
133
133
  const cols = adapter.prepare("PRAGMA table_info(slices)").all();
@@ -188,9 +188,10 @@ console.log('\n=== complete-slice: handler happy path ===');
188
188
 
189
189
  const { basePath, roadmapPath } = createTempProject();
190
190
 
191
- // Set up DB state: milestone, slice, 2 complete tasks
191
+ // Set up DB state: milestone, slices (S01 + S02), 2 complete tasks
192
192
  insertMilestone({ id: 'M001' });
193
193
  insertSlice({ id: 'S01', milestoneId: 'M001' });
194
+ insertSlice({ id: 'S02', milestoneId: 'M001', title: 'Second Slice' });
194
195
  insertTask({ id: 'T01', sliceId: 'S01', milestoneId: 'M001', status: 'complete', title: 'Task 1' });
195
196
  insertTask({ id: 'T02', sliceId: 'S01', milestoneId: 'M001', status: 'complete', title: 'Task 2' });
196
197
 
@@ -230,10 +231,13 @@ console.log('\n=== complete-slice: handler happy path ===');
230
231
  assertMatch(uatContent, /Milestone:\*\* M001/, 'UAT should reference milestone');
231
232
  assertMatch(uatContent, /Smoke Test/, 'UAT should contain smoke test from params');
232
233
 
233
- // (c) Verify roadmap checkbox toggled to [x]
234
+ // (c) Verify roadmap shows S01 complete (✅) and S02 pending (⬜) in table format
235
+ // Projection renders roadmap as a Slice Overview table, not checkbox list
234
236
  const roadmapContent = fs.readFileSync(roadmapPath, 'utf-8');
235
- assertMatch(roadmapContent, /\[x\]\s+\*\*S01:/, 'S01 should be checked in roadmap');
236
- assertMatch(roadmapContent, /\[ \]\s+\*\*S02:/, 'S02 should still be unchecked in roadmap');
237
+ assertMatch(roadmapContent, /\| S01 \|/, 'S01 should appear in roadmap table');
238
+ assertTrue(roadmapContent.includes('✅'), 'completed S01 should show in roadmap table');
239
+ assertMatch(roadmapContent, /\| S02 \|/, 'S02 should appear in roadmap table');
240
+ assertTrue(roadmapContent.includes('⬜'), 'pending S02 should show ⬜ in roadmap table');
237
241
 
238
242
  // (d) Verify full_summary_md and full_uat_md stored in DB for D004 recovery
239
243
  const sliceAfter = getSlice('M001', 'S01');
@@ -353,20 +357,17 @@ console.log('\n=== complete-slice: handler idempotency ===');
353
357
  const r1 = await handleCompleteSlice(params, basePath);
354
358
  assertTrue(!('error' in r1), 'first call should succeed');
355
359
 
356
- // Second call with same params should not crash
360
+ // Second call state machine guard rejects (slice is already complete)
357
361
  const r2 = await handleCompleteSlice(params, basePath);
358
- assertTrue(!('error' in r2), 'second call should succeed (idempotent)');
362
+ assertTrue('error' in r2, 'second call should return error (slice already complete)');
363
+ if ('error' in r2) {
364
+ assertMatch(r2.error, /already complete/, 'error should mention already complete');
365
+ }
359
366
 
360
367
  // Verify only 1 slice row (not duplicated)
361
368
  const adapter = _getAdapter()!;
362
369
  const sliceRows = adapter.prepare("SELECT * FROM slices WHERE milestone_id = 'M001' AND id = 'S01'").all();
363
- assertEq(sliceRows.length, 1, 'should have exactly 1 slice row after 2 calls');
364
-
365
- // Files should still exist
366
- if (!('error' in r2)) {
367
- assertTrue(fs.existsSync(r2.summaryPath), 'summary should still exist after second call');
368
- assertTrue(fs.existsSync(r2.uatPath), 'UAT should still exist after second call');
369
- }
370
+ assertEq(sliceRows.length, 1, 'should have exactly 1 slice row after calls');
370
371
 
371
372
  cleanupDir(basePath);
372
373
  cleanup(dbPath);
@@ -109,9 +109,9 @@ console.log('\n=== complete-task: schema v5 migration ===');
109
109
 
110
110
  const adapter = _getAdapter()!;
111
111
 
112
- // Verify schema version is current (v10 after M001 planning migrations)
112
+ // Verify schema version is current (v11 after state machine migration)
113
113
  const versionRow = adapter.prepare('SELECT MAX(version) as v FROM schema_version').get();
114
- assertEq(versionRow?.['v'], 10, 'schema version should be 10');
114
+ assertEq(versionRow?.['v'], 11, 'schema version should be 11');
115
115
 
116
116
  // Verify all 4 new tables exist
117
117
  const tables = adapter.prepare(
@@ -283,6 +283,11 @@ console.log('\n=== complete-task: handler happy path ===');
283
283
 
284
284
  const { basePath, planPath } = createTempProject();
285
285
 
286
+ // Seed milestone + slice + both tasks so projection renders T01 ([x]) and T02 ([ ])
287
+ insertMilestone({ id: 'M001', title: 'Test Milestone' });
288
+ insertSlice({ id: 'S01', milestoneId: 'M001', title: 'Test Slice' });
289
+ insertTask({ id: 'T02', sliceId: 'S01', milestoneId: 'M001', status: 'pending', title: 'Second task' });
290
+
286
291
  const params = makeValidParams();
287
292
  const result = await handleCompleteTask(params, basePath);
288
293
 
@@ -384,25 +389,31 @@ console.log('\n=== complete-task: handler idempotency ===');
384
389
 
385
390
  const { basePath, planPath } = createTempProject();
386
391
 
392
+ // Seed milestone + slice so state machine guards pass
393
+ insertMilestone({ id: 'M001', title: 'Test Milestone' });
394
+ insertSlice({ id: 'S01', milestoneId: 'M001', title: 'Test Slice' });
395
+
387
396
  const params = makeValidParams();
388
397
 
389
- // First call
398
+ // First call should succeed
390
399
  const r1 = await handleCompleteTask(params, basePath);
391
400
  assertTrue(!('error' in r1), 'first call should succeed');
392
401
 
393
- // Second call with same params — should not crash (INSERT OR REPLACE)
394
- const r2 = await handleCompleteTask(params, basePath);
395
- assertTrue(!('error' in r2), 'second call should succeed (idempotent)');
396
-
397
- // Verify only 1 task row (upserted, not duplicated)
402
+ // Verify only 1 task row
398
403
  const tasks = getSliceTasks('M001', 'S01');
399
- assertEq(tasks.length, 1, 'should have exactly 1 task row after 2 calls (upsert)');
404
+ assertEq(tasks.length, 1, 'should have exactly 1 task row after first call');
400
405
 
401
- // File should still exist
402
- if (!('error' in r2)) {
403
- assertTrue(fs.existsSync(r2.summaryPath), 'summary should still exist after second call');
406
+ // Second call with same params — state machine guard rejects (task is already complete)
407
+ const r2 = await handleCompleteTask(params, basePath);
408
+ assertTrue('error' in r2, 'second call should return error (task already complete)');
409
+ if ('error' in r2) {
410
+ assertMatch(r2.error, /already complete/, 'error should mention already complete');
404
411
  }
405
412
 
413
+ // Still only 1 task row (no duplication from rejected second call)
414
+ const tasksAfter = getSliceTasks('M001', 'S01');
415
+ assertEq(tasksAfter.length, 1, 'should still have exactly 1 task row after rejected second call');
416
+
406
417
  cleanupDir(basePath);
407
418
  cleanup(dbPath);
408
419
  }
@@ -421,6 +432,10 @@ console.log('\n=== complete-task: handler with missing plan file ===');
421
432
  const tasksDir = path.join(basePath, '.gsd', 'milestones', 'M001', 'slices', 'S01', 'tasks');
422
433
  fs.mkdirSync(tasksDir, { recursive: true });
423
434
 
435
+ // Seed milestone + slice so state machine guards pass
436
+ insertMilestone({ id: 'M001', title: 'Test Milestone' });
437
+ insertSlice({ id: 'S01', milestoneId: 'M001', title: 'Test Slice' });
438
+
424
439
  const params = makeValidParams();
425
440
  const result = await handleCompleteTask(params, basePath);
426
441
 
@@ -0,0 +1,114 @@
1
+ /**
2
+ * completed-units-metrics-sync.test.ts — Regression tests for #2313.
3
+ *
4
+ * 1. completed-units.json should be archived (not wiped) on milestone transition
5
+ * 2. metrics.json should be in the worktree → project root sync file list
6
+ */
7
+
8
+ import test from "node:test";
9
+ import assert from "node:assert/strict";
10
+ import { readFileSync, mkdtempSync, mkdirSync, writeFileSync, existsSync, cpSync } from "node:fs";
11
+ import { join } from "node:path";
12
+ import { tmpdir } from "node:os";
13
+
14
+ // ─── Bug 1: completed-units.json should be archived, not wiped ─────────────
15
+
16
+ const phasesSrcPath = join(import.meta.dirname, "..", "auto", "phases.ts");
17
+ const phasesSrc = readFileSync(phasesSrcPath, "utf-8");
18
+
19
+ test("#2313: completed-units.json should not be blindly wiped to [] on milestone transition", () => {
20
+ // The milestone transition block should NOT write an empty array to completed-units.json
21
+ // without first archiving the existing data. Look for the archive/rename pattern.
22
+ const transitionIdx = phasesSrc.indexOf("Milestone transition");
23
+ assert.ok(transitionIdx !== -1, "Milestone transition section exists");
24
+
25
+ // Find the completed-units handling block
26
+ const completedUnitsIdx = phasesSrc.indexOf("completed-units", transitionIdx);
27
+ assert.ok(completedUnitsIdx !== -1, "completed-units handling exists in transition");
28
+
29
+ // Get a window around the completed-units handling (1200 chars to
30
+ // accommodate CRLF line endings on Windows which inflate byte offsets).
31
+ const windowStart = Math.max(0, completedUnitsIdx - 300);
32
+ const windowEnd = Math.min(phasesSrc.length, completedUnitsIdx + 900);
33
+ const window = phasesSrc.slice(windowStart, windowEnd).toLowerCase();
34
+
35
+ // Should archive/rename the old file before resetting
36
+ const hasArchive = window.includes("archive") ||
37
+ window.includes("rename") ||
38
+ window.includes("cpsync") ||
39
+ window.includes("safecopy") ||
40
+ window.includes("completed-units-");
41
+
42
+ assert.ok(
43
+ hasArchive,
44
+ "completed-units.json should be archived before reset during milestone transition",
45
+ );
46
+ });
47
+
48
+ // ─── Bug 2: metrics.json should be in the sync file lists ──────────────────
49
+
50
+ test("#2313: syncStateToProjectRoot should sync metrics.json", () => {
51
+ const syncSrcPath = join(import.meta.dirname, "..", "auto-worktree-sync.ts");
52
+ const syncSrc = readFileSync(syncSrcPath, "utf-8");
53
+
54
+ // syncStateToProjectRoot should copy metrics.json from worktree to project root
55
+ assert.ok(
56
+ syncSrc.includes("metrics.json"),
57
+ "auto-worktree-sync.ts should reference metrics.json for sync",
58
+ );
59
+ });
60
+
61
+ test("#2313: syncWorktreeStateBack should include metrics.json in root files list", () => {
62
+ const autoWorktreeSrcPath = join(import.meta.dirname, "..", "auto-worktree.ts");
63
+ const autoWorktreeSrc = readFileSync(autoWorktreeSrcPath, "utf-8");
64
+
65
+ // Find the rootFiles array in syncWorktreeStateBack
66
+ const syncBackIdx = autoWorktreeSrc.indexOf("syncWorktreeStateBack");
67
+ assert.ok(syncBackIdx !== -1, "syncWorktreeStateBack exists");
68
+
69
+ const rootFilesIdx = autoWorktreeSrc.indexOf("rootFiles", syncBackIdx);
70
+ assert.ok(rootFilesIdx !== -1, "rootFiles list exists in syncWorktreeStateBack");
71
+
72
+ // Get the rootFiles array content
73
+ const arrayStart = autoWorktreeSrc.indexOf("[", rootFilesIdx);
74
+ const arrayEnd = autoWorktreeSrc.indexOf("]", arrayStart);
75
+ const rootFilesBlock = autoWorktreeSrc.slice(arrayStart, arrayEnd);
76
+
77
+ assert.ok(
78
+ rootFilesBlock.includes("metrics.json"),
79
+ "metrics.json should be in syncWorktreeStateBack rootFiles list",
80
+ );
81
+ });
82
+
83
+ // ─── Functional test: completed-units archive ────────────────────────────────
84
+
85
+ test("#2313: functional — completed-units archive creates milestone-specific file", () => {
86
+ const tmpBase = mkdtempSync(join(tmpdir(), "gsd-completed-units-"));
87
+ const gsdDir = join(tmpBase, ".gsd");
88
+ mkdirSync(gsdDir, { recursive: true });
89
+
90
+ // Simulate existing completed-units.json with data
91
+ const existing = [
92
+ { type: "task", id: "T01" },
93
+ { type: "slice", id: "S01" },
94
+ ];
95
+ const completedKeysPath = join(gsdDir, "completed-units.json");
96
+ writeFileSync(completedKeysPath, JSON.stringify(existing, null, 2));
97
+
98
+ // Simulate the archive behavior: copy to milestone-specific file
99
+ const milestoneId = "M001";
100
+ const archivePath = join(gsdDir, `completed-units-${milestoneId}.json`);
101
+ cpSync(completedKeysPath, archivePath);
102
+
103
+ // Reset the main file
104
+ writeFileSync(completedKeysPath, JSON.stringify([], null, 2));
105
+
106
+ // Verify archive exists with original data
107
+ assert.ok(existsSync(archivePath), "archive file should exist");
108
+ const archived = JSON.parse(readFileSync(archivePath, "utf-8"));
109
+ assert.deepEqual(archived, existing, "archived data should match original");
110
+
111
+ // Verify main file is reset
112
+ const current = JSON.parse(readFileSync(completedKeysPath, "utf-8"));
113
+ assert.deepEqual(current, [], "current completed-units should be empty after transition");
114
+ });