gsd-pi 2.44.0 → 2.45.0-dev.6b9da3e

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 (463) hide show
  1. package/README.md +30 -12
  2. package/dist/resources/extensions/gsd/activity-log.js +7 -0
  3. package/dist/resources/extensions/gsd/auto/infra-errors.js +3 -0
  4. package/dist/resources/extensions/gsd/auto/phases.js +37 -36
  5. package/dist/resources/extensions/gsd/auto-prompts.js +24 -1
  6. package/dist/resources/extensions/gsd/auto-start.js +31 -2
  7. package/dist/resources/extensions/gsd/auto-timers.js +57 -3
  8. package/dist/resources/extensions/gsd/auto-worktree-sync.js +4 -0
  9. package/dist/resources/extensions/gsd/auto-worktree.js +9 -6
  10. package/dist/resources/extensions/gsd/auto.js +30 -3
  11. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +156 -0
  12. package/dist/resources/extensions/gsd/bootstrap/system-context.js +46 -12
  13. package/dist/resources/extensions/gsd/commands/catalog.js +7 -1
  14. package/dist/resources/extensions/gsd/commands/handlers/core.js +2 -0
  15. package/dist/resources/extensions/gsd/commands/handlers/ops.js +10 -0
  16. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +5 -0
  17. package/dist/resources/extensions/gsd/commands-mcp-status.js +187 -0
  18. package/dist/resources/extensions/gsd/db-writer.js +34 -16
  19. package/dist/resources/extensions/gsd/doctor.js +8 -0
  20. package/dist/resources/extensions/gsd/git-service.js +8 -3
  21. package/dist/resources/extensions/gsd/gsd-db.js +12 -1
  22. package/dist/resources/extensions/gsd/markdown-renderer.js +1 -1
  23. package/dist/resources/extensions/gsd/preferences.js +9 -1
  24. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +2 -4
  25. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  26. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -6
  27. package/dist/resources/extensions/gsd/prompts/replan-slice.md +3 -14
  28. package/dist/resources/extensions/gsd/prompts/rethink.md +78 -0
  29. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +7 -37
  30. package/dist/resources/extensions/gsd/provider-error-pause.js +7 -0
  31. package/dist/resources/extensions/gsd/repo-identity.js +45 -7
  32. package/dist/resources/extensions/gsd/rethink.js +115 -0
  33. package/dist/resources/extensions/gsd/state.js +41 -3
  34. package/dist/resources/extensions/gsd/tools/plan-slice.js +1 -0
  35. package/dist/resources/extensions/gsd/tools/plan-task.js +1 -0
  36. package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -0
  37. package/dist/resources/extensions/gsd/tools/validate-milestone.js +88 -0
  38. package/dist/resources/extensions/gsd/worktree-manager.js +32 -2
  39. package/dist/resources/extensions/gsd/worktree-resolver.js +6 -0
  40. package/dist/resources/extensions/mcp-client/index.js +14 -0
  41. package/dist/web/standalone/.next/BUILD_ID +1 -1
  42. package/dist/web/standalone/.next/app-path-routes-manifest.json +8 -8
  43. package/dist/web/standalone/.next/build-manifest.json +4 -4
  44. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  45. package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
  46. package/dist/web/standalone/.next/required-server-files.json +3 -3
  47. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  48. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  49. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  50. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  51. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  52. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  53. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  54. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  55. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  56. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  57. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  58. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  59. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  60. package/dist/web/standalone/.next/server/app/_not-found.rsc +5 -5
  61. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +5 -5
  62. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  63. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
  64. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  65. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  66. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  67. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  68. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  69. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  70. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  71. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  72. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  73. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  74. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  75. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  76. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  77. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  78. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  79. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  80. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  81. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  82. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  83. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  84. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  85. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  86. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  87. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  88. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  89. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  90. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  91. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  92. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  93. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  94. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  95. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  96. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  97. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  98. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  99. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  100. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  101. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  102. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  103. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  104. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  105. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  106. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  107. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  108. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  109. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  110. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +5 -5
  112. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  118. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  132. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  134. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  136. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  138. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/index.html +1 -1
  148. package/dist/web/standalone/.next/server/app/index.rsc +6 -6
  149. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  150. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +6 -6
  151. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  152. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
  153. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  154. package/dist/web/standalone/.next/server/app/page.js +2 -2
  155. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app-paths-manifest.json +8 -8
  157. package/dist/web/standalone/.next/server/chunks/229.js +1 -1
  158. package/dist/web/standalone/.next/server/chunks/471.js +3 -3
  159. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/middleware.js +2 -2
  162. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  164. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  165. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  166. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  167. package/dist/web/standalone/.next/static/chunks/4024.11ca5c01938e5948.js +9 -0
  168. package/dist/web/standalone/.next/static/chunks/{3721.bf31263de6d5fa46.js → 485.243af25f0cdf50d6.js} +2 -2
  169. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  170. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  171. package/dist/web/standalone/.next/static/chunks/app/page-6654a8cca61a3d1c.js +1 -0
  172. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  173. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  174. package/dist/web/standalone/.next/static/chunks/webpack-0a4cd455ec4197d2.js +1 -0
  175. package/dist/web/standalone/.next/static/css/dd4ae3f58ac9b600.css +1 -0
  176. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  177. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  178. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  179. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  180. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  181. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  182. package/dist/web/standalone/server.js +1 -1
  183. package/package.json +1 -1
  184. package/packages/native/dist/stream-process/index.js +2 -2
  185. package/packages/native/src/__tests__/stream-process.test.mjs +34 -0
  186. package/packages/native/src/stream-process/index.ts +2 -2
  187. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +3 -1
  188. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  189. package/packages/pi-coding-agent/dist/core/auth-storage.js +15 -1
  190. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  191. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +6 -8
  192. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  193. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +24 -26
  194. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  195. package/packages/pi-coding-agent/dist/core/fs-utils.test.js +29 -48
  196. package/packages/pi-coding-agent/dist/core/fs-utils.test.js.map +1 -1
  197. package/packages/pi-coding-agent/dist/core/local-model-check.d.ts +15 -0
  198. package/packages/pi-coding-agent/dist/core/local-model-check.d.ts.map +1 -0
  199. package/packages/pi-coding-agent/dist/core/local-model-check.js +41 -0
  200. package/packages/pi-coding-agent/dist/core/local-model-check.js.map +1 -0
  201. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +11 -0
  202. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  203. package/packages/pi-coding-agent/dist/core/model-registry.js +20 -1
  204. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  205. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +34 -44
  206. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
  207. package/packages/pi-coding-agent/dist/core/session-manager.test.js +30 -34
  208. package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
  209. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
  210. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  211. package/packages/pi-coding-agent/dist/core/settings-manager.js +6 -0
  212. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  213. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +10 -12
  214. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -1
  215. package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
  216. package/packages/pi-coding-agent/dist/main.js +17 -0
  217. package/packages/pi-coding-agent/dist/main.js.map +1 -1
  218. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.d.ts +2 -0
  219. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.d.ts.map +1 -0
  220. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.js +32 -0
  221. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/timestamp.test.js.map +1 -0
  222. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +3 -1
  223. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  224. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +8 -1
  225. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  226. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  227. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  228. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +12 -0
  229. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
  230. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.d.ts +15 -0
  231. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.d.ts.map +1 -0
  232. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.js +40 -0
  233. package/packages/pi-coding-agent/dist/modes/interactive/components/timestamp.js.map +1 -0
  234. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  235. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +4 -1
  236. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  237. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts +5 -2
  238. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  239. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +13 -2
  240. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
  241. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  242. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +17 -8
  243. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  244. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  245. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +7 -3
  246. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  247. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js +43 -47
  248. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js.map +1 -1
  249. package/packages/pi-coding-agent/package.json +1 -1
  250. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +7 -7
  251. package/packages/pi-coding-agent/src/core/auth-storage.ts +15 -1
  252. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +26 -26
  253. package/packages/pi-coding-agent/src/core/fs-utils.test.ts +31 -43
  254. package/packages/pi-coding-agent/src/core/local-model-check.ts +45 -0
  255. package/packages/pi-coding-agent/src/core/model-registry.ts +21 -1
  256. package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +40 -45
  257. package/packages/pi-coding-agent/src/core/session-manager.test.ts +33 -33
  258. package/packages/pi-coding-agent/src/core/settings-manager.ts +9 -0
  259. package/packages/pi-coding-agent/src/core/tools/edit-diff.test.ts +17 -17
  260. package/packages/pi-coding-agent/src/main.ts +19 -0
  261. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/timestamp.test.ts +38 -0
  262. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +10 -0
  263. package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +15 -0
  264. package/packages/pi-coding-agent/src/modes/interactive/components/timestamp.ts +48 -0
  265. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +3 -1
  266. package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +18 -3
  267. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +16 -7
  268. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +8 -1
  269. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.test.ts +74 -74
  270. package/pkg/package.json +1 -1
  271. package/src/resources/extensions/gsd/activity-log.ts +1 -0
  272. package/src/resources/extensions/gsd/auto/infra-errors.ts +3 -0
  273. package/src/resources/extensions/gsd/auto/phases.ts +46 -48
  274. package/src/resources/extensions/gsd/auto-prompts.ts +24 -1
  275. package/src/resources/extensions/gsd/auto-start.ts +39 -2
  276. package/src/resources/extensions/gsd/auto-timers.ts +64 -3
  277. package/src/resources/extensions/gsd/auto-worktree-sync.ts +5 -0
  278. package/src/resources/extensions/gsd/auto-worktree.ts +9 -6
  279. package/src/resources/extensions/gsd/auto.ts +37 -3
  280. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +148 -0
  281. package/src/resources/extensions/gsd/bootstrap/system-context.ts +48 -11
  282. package/src/resources/extensions/gsd/commands/catalog.ts +7 -1
  283. package/src/resources/extensions/gsd/commands/handlers/core.ts +2 -0
  284. package/src/resources/extensions/gsd/commands/handlers/ops.ts +10 -0
  285. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +8 -0
  286. package/src/resources/extensions/gsd/commands-mcp-status.ts +247 -0
  287. package/src/resources/extensions/gsd/db-writer.ts +39 -17
  288. package/src/resources/extensions/gsd/doctor.ts +7 -1
  289. package/src/resources/extensions/gsd/git-service.ts +6 -2
  290. package/src/resources/extensions/gsd/gsd-db.ts +16 -1
  291. package/src/resources/extensions/gsd/markdown-renderer.ts +1 -1
  292. package/src/resources/extensions/gsd/preferences.ts +11 -1
  293. package/src/resources/extensions/gsd/prompts/complete-milestone.md +2 -4
  294. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  295. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -6
  296. package/src/resources/extensions/gsd/prompts/replan-slice.md +3 -14
  297. package/src/resources/extensions/gsd/prompts/rethink.md +78 -0
  298. package/src/resources/extensions/gsd/prompts/validate-milestone.md +7 -37
  299. package/src/resources/extensions/gsd/provider-error-pause.ts +9 -0
  300. package/src/resources/extensions/gsd/repo-identity.ts +46 -7
  301. package/src/resources/extensions/gsd/rethink.ts +154 -0
  302. package/src/resources/extensions/gsd/state.ts +41 -1
  303. package/src/resources/extensions/gsd/tests/all-milestones-complete-merge.test.ts +99 -99
  304. package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +14 -16
  305. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +43 -57
  306. package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +88 -0
  307. package/src/resources/extensions/gsd/tests/auto-preflight.test.ts +11 -13
  308. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +465 -523
  309. package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +73 -75
  310. package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +34 -56
  311. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +533 -656
  312. package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +165 -143
  313. package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +29 -52
  314. package/src/resources/extensions/gsd/tests/captures.test.ts +148 -176
  315. package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +32 -33
  316. package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +141 -143
  317. package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +25 -25
  318. package/src/resources/extensions/gsd/tests/commands-logs.test.ts +81 -81
  319. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +38 -59
  320. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +228 -263
  321. package/src/resources/extensions/gsd/tests/complete-task.test.ts +250 -302
  322. package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +114 -0
  323. package/src/resources/extensions/gsd/tests/context-store.test.ts +354 -367
  324. package/src/resources/extensions/gsd/tests/continue-here.test.ts +68 -72
  325. package/src/resources/extensions/gsd/tests/cost-projection.test.ts +92 -106
  326. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +27 -35
  327. package/src/resources/extensions/gsd/tests/dashboard-budget.test.ts +220 -237
  328. package/src/resources/extensions/gsd/tests/db-writer.test.ts +465 -416
  329. package/src/resources/extensions/gsd/tests/definition-loader.test.ts +76 -92
  330. package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +68 -83
  331. package/src/resources/extensions/gsd/tests/derive-state-db-disk-reconcile.test.ts +121 -0
  332. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +210 -181
  333. package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +78 -101
  334. package/src/resources/extensions/gsd/tests/derive-state.test.ts +192 -227
  335. package/src/resources/extensions/gsd/tests/detection.test.ts +232 -278
  336. package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +30 -34
  337. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +164 -180
  338. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +43 -49
  339. package/src/resources/extensions/gsd/tests/dispatch-uat-last-completed.test.ts +28 -32
  340. package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +27 -29
  341. package/src/resources/extensions/gsd/tests/doctor-delimiter-fix.test.ts +34 -38
  342. package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +54 -75
  343. package/src/resources/extensions/gsd/tests/doctor-environment-worktree.test.ts +21 -32
  344. package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +72 -97
  345. package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +38 -44
  346. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +104 -145
  347. package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +84 -106
  348. package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +54 -60
  349. package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +72 -93
  350. package/src/resources/extensions/gsd/tests/doctor.test.ts +104 -134
  351. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +123 -131
  352. package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +120 -0
  353. package/src/resources/extensions/gsd/tests/exit-command.test.ts +20 -24
  354. package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +48 -57
  355. package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +5 -7
  356. package/src/resources/extensions/gsd/tests/flag-file-db.test.ts +30 -42
  357. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +198 -206
  358. package/src/resources/extensions/gsd/tests/git-locale.test.ts +13 -27
  359. package/src/resources/extensions/gsd/tests/git-service.test.ts +285 -388
  360. package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +31 -39
  361. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +63 -69
  362. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +255 -264
  363. package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +108 -119
  364. package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +81 -103
  365. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +229 -262
  366. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +13 -13
  367. package/src/resources/extensions/gsd/tests/health-widget.test.ts +29 -37
  368. package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +81 -102
  369. package/src/resources/extensions/gsd/tests/infra-error.test.ts +20 -2
  370. package/src/resources/extensions/gsd/tests/inherited-repo-home-dir.test.ts +121 -0
  371. package/src/resources/extensions/gsd/tests/init-wizard.test.ts +16 -18
  372. package/src/resources/extensions/gsd/tests/integration-edge.test.ts +41 -46
  373. package/src/resources/extensions/gsd/tests/integration-lifecycle.test.ts +42 -53
  374. package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +75 -91
  375. package/src/resources/extensions/gsd/tests/integration-proof.test.ts +18 -18
  376. package/src/resources/extensions/gsd/tests/knowledge.test.ts +89 -0
  377. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +150 -194
  378. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +103 -0
  379. package/src/resources/extensions/gsd/tests/md-importer.test.ts +101 -125
  380. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +45 -54
  381. package/src/resources/extensions/gsd/tests/memory-store.test.ts +80 -93
  382. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +66 -0
  383. package/src/resources/extensions/gsd/tests/migrate-command.test.ts +57 -66
  384. package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +83 -93
  385. package/src/resources/extensions/gsd/tests/migrate-parser.test.ts +161 -170
  386. package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +125 -141
  387. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +107 -131
  388. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +87 -96
  389. package/src/resources/extensions/gsd/tests/migrate-writer.test.ts +125 -164
  390. package/src/resources/extensions/gsd/tests/must-have-parser.test.ts +81 -94
  391. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +35 -36
  392. package/src/resources/extensions/gsd/tests/overrides.test.ts +99 -106
  393. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +40 -47
  394. package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +25 -28
  395. package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +66 -83
  396. package/src/resources/extensions/gsd/tests/park-edge-cases.test.ts +54 -77
  397. package/src/resources/extensions/gsd/tests/park-milestone.test.ts +68 -115
  398. package/src/resources/extensions/gsd/tests/parsers.test.ts +546 -611
  399. package/src/resources/extensions/gsd/tests/paths.test.ts +72 -87
  400. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +77 -117
  401. package/src/resources/extensions/gsd/tests/preferences.test.ts +27 -0
  402. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +11 -7
  403. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +56 -56
  404. package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +93 -119
  405. package/src/resources/extensions/gsd/tests/queue-order.test.ts +70 -82
  406. package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +42 -55
  407. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +100 -0
  408. package/src/resources/extensions/gsd/tests/quick-branch-lifecycle.test.ts +45 -73
  409. package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +28 -38
  410. package/src/resources/extensions/gsd/tests/recovery-attempts-reset.test.ts +176 -0
  411. package/src/resources/extensions/gsd/tests/replan-slice.test.ts +73 -80
  412. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +71 -74
  413. package/src/resources/extensions/gsd/tests/requirements.test.ts +70 -75
  414. package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +44 -66
  415. package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +114 -181
  416. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +63 -65
  417. package/src/resources/extensions/gsd/tests/run-uat.test.ts +66 -128
  418. package/src/resources/extensions/gsd/tests/session-lock-multipath.test.ts +18 -25
  419. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +37 -44
  420. package/src/resources/extensions/gsd/tests/shared-wal.test.ts +19 -26
  421. package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +63 -0
  422. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +6 -8
  423. package/src/resources/extensions/gsd/tests/stop-auto-merge-back.test.ts +67 -0
  424. package/src/resources/extensions/gsd/tests/survivor-branch-complete.test.ts +108 -0
  425. package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +22 -28
  426. package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +49 -0
  427. package/src/resources/extensions/gsd/tests/token-savings.test.ts +54 -56
  428. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +23 -25
  429. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +10 -11
  430. package/src/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +66 -82
  431. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +46 -47
  432. package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -22
  433. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -86
  434. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +41 -43
  435. package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +94 -96
  436. package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +11 -13
  437. package/src/resources/extensions/gsd/tests/worker-registry.test.ts +27 -29
  438. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +50 -52
  439. package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +10 -13
  440. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +14 -18
  441. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +38 -39
  442. package/src/resources/extensions/gsd/tests/worktree-e2e.test.ts +17 -21
  443. package/src/resources/extensions/gsd/tests/worktree-health.test.ts +25 -30
  444. package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +30 -37
  445. package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +65 -0
  446. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +15 -22
  447. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +59 -66
  448. package/src/resources/extensions/gsd/tests/worktree.test.ts +44 -50
  449. package/src/resources/extensions/gsd/tools/plan-slice.ts +2 -0
  450. package/src/resources/extensions/gsd/tools/plan-task.ts +2 -0
  451. package/src/resources/extensions/gsd/tools/replan-slice.ts +3 -0
  452. package/src/resources/extensions/gsd/tools/validate-milestone.ts +127 -0
  453. package/src/resources/extensions/gsd/worktree-manager.ts +43 -2
  454. package/src/resources/extensions/gsd/worktree-resolver.ts +7 -0
  455. package/src/resources/extensions/mcp-client/index.ts +20 -0
  456. package/dist/web/standalone/.next/static/chunks/4024.0de81b543b28b9fe.js +0 -9
  457. package/dist/web/standalone/.next/static/chunks/app/page-7e9530a7122506c5.js +0 -1
  458. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  459. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  460. package/dist/web/standalone/.next/static/chunks/webpack-9014b5adb127a98a.js +0 -1
  461. package/dist/web/standalone/.next/static/css/8a727f372cf53002.css +0 -1
  462. /package/dist/web/standalone/.next/static/{mgkxN0mGP6gSUmGPEzbk_ → rzO54ZboyINyEt7cVM_uS}/_buildManifest.js +0 -0
  463. /package/dist/web/standalone/.next/static/{mgkxN0mGP6gSUmGPEzbk_ → rzO54ZboyINyEt7cVM_uS}/_ssgManifest.js +0 -0
@@ -1,4 +1,5 @@
1
- import { createTestContext } from './test-helpers.ts';
1
+ import { describe, test, afterEach } from "node:test";
2
+ import assert from "node:assert/strict";
2
3
  import * as fs from 'node:fs';
3
4
  import * as path from 'node:path';
4
5
  import * as os from 'node:os';
@@ -17,8 +18,6 @@ import {
17
18
  import { handleCompleteSlice } from '../tools/complete-slice.ts';
18
19
  import type { CompleteSliceParams } from '../types.ts';
19
20
 
20
- const { assertEq, assertTrue, assertMatch, report } = createTestContext();
21
-
22
21
  // ═══════════════════════════════════════════════════════════════════════════
23
22
  // Helpers
24
23
  // ═══════════════════════════════════════════════════════════════════════════
@@ -115,296 +114,262 @@ Run the test suite and verify all assertions pass.
115
114
  }
116
115
 
117
116
  // ═══════════════════════════════════════════════════════════════════════════
118
- // complete-slice: Schema v6 migration
119
- // ═══════════════════════════════════════════════════════════════════════════
120
-
121
- console.log('\n=== complete-slice: schema v6 migration ===');
122
- {
123
- const dbPath = tempDbPath();
124
- openDatabase(dbPath);
125
-
126
- const adapter = _getAdapter()!;
127
-
128
- // Verify schema version is current (v10 after M001 planning migrations)
129
- const versionRow = adapter.prepare('SELECT MAX(version) as v FROM schema_version').get();
130
- assertEq(versionRow?.['v'], 10, 'schema version should be 10');
131
-
132
- // Verify slices table has full_summary_md and full_uat_md columns
133
- const cols = adapter.prepare("PRAGMA table_info(slices)").all();
134
- const colNames = cols.map(c => c['name'] as string);
135
- assertTrue(colNames.includes('full_summary_md'), 'slices table should have full_summary_md column');
136
- assertTrue(colNames.includes('full_uat_md'), 'slices table should have full_uat_md column');
137
-
138
- cleanup(dbPath);
139
- }
140
-
141
- // ═══════════════════════════════════════════════════════════════════════════
142
- // complete-slice: getSlice/updateSliceStatus accessors
143
- // ═══════════════════════════════════════════════════════════════════════════
144
-
145
- console.log('\n=== complete-slice: getSlice/updateSliceStatus accessors ===');
146
- {
147
- const dbPath = tempDbPath();
148
- openDatabase(dbPath);
149
-
150
- // Insert milestone and slice
151
- insertMilestone({ id: 'M001' });
152
- insertSlice({ id: 'S01', milestoneId: 'M001', title: 'Test Slice', risk: 'high' });
153
-
154
- // getSlice returns correct row
155
- const slice = getSlice('M001', 'S01');
156
- assertTrue(slice !== null, 'getSlice should return non-null for existing slice');
157
- assertEq(slice!.id, 'S01', 'slice id');
158
- assertEq(slice!.milestone_id, 'M001', 'slice milestone_id');
159
- assertEq(slice!.title, 'Test Slice', 'slice title');
160
- assertEq(slice!.risk, 'high', 'slice risk');
161
- assertEq(slice!.status, 'pending', 'slice default status should be pending');
162
- assertEq(slice!.completed_at, null, 'slice completed_at should be null initially');
163
- assertEq(slice!.full_summary_md, '', 'slice full_summary_md should be empty initially');
164
- assertEq(slice!.full_uat_md, '', 'slice full_uat_md should be empty initially');
165
-
166
- // getSlice returns null for non-existent
167
- const noSlice = getSlice('M001', 'S99');
168
- assertEq(noSlice, null, 'non-existent slice should return null');
169
-
170
- // updateSliceStatus changes status and completed_at
171
- const now = new Date().toISOString();
172
- updateSliceStatus('M001', 'S01', 'complete', now);
173
- const updated = getSlice('M001', 'S01');
174
- assertEq(updated!.status, 'complete', 'slice status should be updated to complete');
175
- assertEq(updated!.completed_at, now, 'slice completed_at should be set');
176
-
177
- cleanup(dbPath);
178
- }
179
-
117
+ // Tests
180
118
  // ═══════════════════════════════════════════════════════════════════════════
181
- // complete-slice: Handler happy path
182
- // ═══════════════════════════════════════════════════════════════════════════
183
-
184
- console.log('\n=== complete-slice: handler happy path ===');
185
- {
186
- const dbPath = tempDbPath();
187
- openDatabase(dbPath);
188
-
189
- const { basePath, roadmapPath } = createTempProject();
190
-
191
- // Set up DB state: milestone, slice, 2 complete tasks
192
- insertMilestone({ id: 'M001' });
193
- insertSlice({ id: 'S01', milestoneId: 'M001' });
194
- insertTask({ id: 'T01', sliceId: 'S01', milestoneId: 'M001', status: 'complete', title: 'Task 1' });
195
- insertTask({ id: 'T02', sliceId: 'S01', milestoneId: 'M001', status: 'complete', title: 'Task 2' });
196
-
197
- const params = makeValidSliceParams();
198
- const result = await handleCompleteSlice(params, basePath);
199
-
200
- assertTrue(!('error' in result), 'handler should succeed without error');
201
- if (!('error' in result)) {
202
- assertEq(result.sliceId, 'S01', 'result sliceId');
203
- assertEq(result.milestoneId, 'M001', 'result milestoneId');
204
- assertTrue(result.summaryPath.endsWith('S01-SUMMARY.md'), 'summaryPath should end with S01-SUMMARY.md');
205
- assertTrue(result.uatPath.endsWith('S01-UAT.md'), 'uatPath should end with S01-UAT.md');
206
-
207
- // (a) Verify SUMMARY.md exists on disk with correct YAML frontmatter
208
- assertTrue(fs.existsSync(result.summaryPath), 'summary file should exist on disk');
209
- const summaryContent = fs.readFileSync(result.summaryPath, 'utf-8');
210
- assertMatch(summaryContent, /^---\n/, 'summary should start with YAML frontmatter');
211
- assertMatch(summaryContent, /id: S01/, 'summary should contain id: S01');
212
- assertMatch(summaryContent, /parent: M001/, 'summary should contain parent: M001');
213
- assertMatch(summaryContent, /milestone: M001/, 'summary should contain milestone: M001');
214
- assertMatch(summaryContent, /blocker_discovered: false/, 'summary should contain blocker_discovered');
215
- assertMatch(summaryContent, /verification_result: passed/, 'summary should contain verification_result');
216
- assertMatch(summaryContent, /key_files:/, 'summary should contain key_files');
217
- assertMatch(summaryContent, /patterns_established:/, 'summary should contain patterns_established');
218
- assertMatch(summaryContent, /observability_surfaces:/, 'summary should contain observability_surfaces');
219
- assertMatch(summaryContent, /provides:/, 'summary should contain provides');
220
- assertMatch(summaryContent, /# S01: Test Slice/, 'summary should have H1 with slice ID and title');
221
- assertMatch(summaryContent, /\*\*Implemented test slice with full coverage\*\*/, 'summary should have one-liner in bold');
222
- assertMatch(summaryContent, /## What Happened/, 'summary should have What Happened section');
223
- assertMatch(summaryContent, /## Verification/, 'summary should have Verification section');
224
- assertMatch(summaryContent, /## Requirements Advanced/, 'summary should have Requirements Advanced section');
225
-
226
- // (b) Verify UAT.md exists on disk
227
- assertTrue(fs.existsSync(result.uatPath), 'UAT file should exist on disk');
228
- const uatContent = fs.readFileSync(result.uatPath, 'utf-8');
229
- assertMatch(uatContent, /# S01: Test Slice — UAT/, 'UAT should have correct title');
230
- assertMatch(uatContent, /Milestone:\*\* M001/, 'UAT should reference milestone');
231
- assertMatch(uatContent, /Smoke Test/, 'UAT should contain smoke test from params');
232
-
233
- // (c) Verify roadmap checkbox toggled to [x]
234
- 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
-
238
- // (d) Verify full_summary_md and full_uat_md stored in DB for D004 recovery
239
- const sliceAfter = getSlice('M001', 'S01');
240
- assertTrue(sliceAfter !== null, 'slice should exist in DB after handler');
241
- assertTrue(sliceAfter!.full_summary_md.length > 0, 'full_summary_md should be non-empty in DB');
242
- assertMatch(sliceAfter!.full_summary_md, /id: S01/, 'full_summary_md should contain frontmatter');
243
- assertTrue(sliceAfter!.full_uat_md.length > 0, 'full_uat_md should be non-empty in DB');
244
- assertMatch(sliceAfter!.full_uat_md, /S01: Test Slice — UAT/, 'full_uat_md should contain UAT title');
245
-
246
- // (e) Verify slice status is complete in DB
247
- assertEq(sliceAfter!.status, 'complete', 'slice status should be complete in DB');
248
- assertTrue(sliceAfter!.completed_at !== null, 'completed_at should be set in DB');
249
- }
250
-
251
- cleanupDir(basePath);
252
- cleanup(dbPath);
253
- }
254
-
255
- // ═══════════════════════════════════════════════════════════════════════════
256
- // complete-slice: Handler rejects incomplete tasks
257
- // ═══════════════════════════════════════════════════════════════════════════
258
-
259
- console.log('\n=== complete-slice: handler rejects incomplete tasks ===');
260
- {
261
- const dbPath = tempDbPath();
262
- openDatabase(dbPath);
263
-
264
- // Insert milestone, slice, 2 tasks — one complete, one pending
265
- insertMilestone({ id: 'M001' });
266
- insertSlice({ id: 'S01', milestoneId: 'M001' });
267
- insertTask({ id: 'T01', sliceId: 'S01', milestoneId: 'M001', status: 'complete', title: 'Task 1' });
268
- insertTask({ id: 'T02', sliceId: 'S01', milestoneId: 'M001', status: 'pending', title: 'Task 2' });
269
-
270
- const params = makeValidSliceParams();
271
- const result = await handleCompleteSlice(params, '/tmp/fake');
272
-
273
- assertTrue('error' in result, 'should return error when tasks are incomplete');
274
- if ('error' in result) {
275
- assertMatch(result.error, /incomplete tasks/, 'error should mention incomplete tasks');
276
- assertMatch(result.error, /T02/, 'error should mention the specific incomplete task ID');
277
- }
278
119
 
279
- cleanup(dbPath);
280
- }
120
+ describe("complete-slice: schema v6 migration", () => {
121
+ test("schema version and columns exist", () => {
122
+ const dbPath = tempDbPath();
123
+ openDatabase(dbPath);
124
+
125
+ const adapter = _getAdapter()!;
126
+
127
+ // Verify schema version is current (v10 after M001 planning migrations)
128
+ const versionRow = adapter.prepare('SELECT MAX(version) as v FROM schema_version').get();
129
+ assert.strictEqual(versionRow?.['v'], 10, 'schema version should be 10');
130
+
131
+ // Verify slices table has full_summary_md and full_uat_md columns
132
+ const cols = adapter.prepare("PRAGMA table_info(slices)").all();
133
+ const colNames = cols.map(c => c['name'] as string);
134
+ assert.ok(colNames.includes('full_summary_md'), 'slices table should have full_summary_md column');
135
+ assert.ok(colNames.includes('full_uat_md'), 'slices table should have full_uat_md column');
136
+
137
+ cleanup(dbPath);
138
+ });
139
+ });
140
+
141
+ describe("complete-slice: getSlice/updateSliceStatus accessors", () => {
142
+ test("getSlice and updateSliceStatus work correctly", () => {
143
+ const dbPath = tempDbPath();
144
+ openDatabase(dbPath);
145
+
146
+ // Insert milestone and slice
147
+ insertMilestone({ id: 'M001' });
148
+ insertSlice({ id: 'S01', milestoneId: 'M001', title: 'Test Slice', risk: 'high' });
149
+
150
+ // getSlice returns correct row
151
+ const slice = getSlice('M001', 'S01');
152
+ assert.ok(slice !== null, 'getSlice should return non-null for existing slice');
153
+ assert.strictEqual(slice!.id, 'S01', 'slice id');
154
+ assert.strictEqual(slice!.milestone_id, 'M001', 'slice milestone_id');
155
+ assert.strictEqual(slice!.title, 'Test Slice', 'slice title');
156
+ assert.strictEqual(slice!.risk, 'high', 'slice risk');
157
+ assert.strictEqual(slice!.status, 'pending', 'slice default status should be pending');
158
+ assert.strictEqual(slice!.completed_at, null, 'slice completed_at should be null initially');
159
+ assert.strictEqual(slice!.full_summary_md, '', 'slice full_summary_md should be empty initially');
160
+ assert.strictEqual(slice!.full_uat_md, '', 'slice full_uat_md should be empty initially');
161
+
162
+ // getSlice returns null for non-existent
163
+ const noSlice = getSlice('M001', 'S99');
164
+ assert.strictEqual(noSlice, null, 'non-existent slice should return null');
165
+
166
+ // updateSliceStatus changes status and completed_at
167
+ const now = new Date().toISOString();
168
+ updateSliceStatus('M001', 'S01', 'complete', now);
169
+ const updated = getSlice('M001', 'S01');
170
+ assert.strictEqual(updated!.status, 'complete', 'slice status should be updated to complete');
171
+ assert.strictEqual(updated!.completed_at, now, 'slice completed_at should be set');
172
+
173
+ cleanup(dbPath);
174
+ });
175
+ });
176
+
177
+ describe("complete-slice: handler", () => {
178
+ test("happy path", async () => {
179
+ const dbPath = tempDbPath();
180
+ openDatabase(dbPath);
181
+
182
+ const { basePath, roadmapPath } = createTempProject();
183
+
184
+ // Set up DB state: milestone, slice, 2 complete tasks
185
+ insertMilestone({ id: 'M001' });
186
+ insertSlice({ id: 'S01', milestoneId: 'M001' });
187
+ insertTask({ id: 'T01', sliceId: 'S01', milestoneId: 'M001', status: 'complete', title: 'Task 1' });
188
+ insertTask({ id: 'T02', sliceId: 'S01', milestoneId: 'M001', status: 'complete', title: 'Task 2' });
189
+
190
+ const params = makeValidSliceParams();
191
+ const result = await handleCompleteSlice(params, basePath);
192
+
193
+ assert.ok(!('error' in result), 'handler should succeed without error');
194
+ if (!('error' in result)) {
195
+ assert.strictEqual(result.sliceId, 'S01', 'result sliceId');
196
+ assert.strictEqual(result.milestoneId, 'M001', 'result milestoneId');
197
+ assert.ok(result.summaryPath.endsWith('S01-SUMMARY.md'), 'summaryPath should end with S01-SUMMARY.md');
198
+ assert.ok(result.uatPath.endsWith('S01-UAT.md'), 'uatPath should end with S01-UAT.md');
199
+
200
+ // (a) Verify SUMMARY.md exists on disk with correct YAML frontmatter
201
+ assert.ok(fs.existsSync(result.summaryPath), 'summary file should exist on disk');
202
+ const summaryContent = fs.readFileSync(result.summaryPath, 'utf-8');
203
+ assert.match(summaryContent, /^---\n/, 'summary should start with YAML frontmatter');
204
+ assert.match(summaryContent, /id: S01/, 'summary should contain id: S01');
205
+ assert.match(summaryContent, /parent: M001/, 'summary should contain parent: M001');
206
+ assert.match(summaryContent, /milestone: M001/, 'summary should contain milestone: M001');
207
+ assert.match(summaryContent, /blocker_discovered: false/, 'summary should contain blocker_discovered');
208
+ assert.match(summaryContent, /verification_result: passed/, 'summary should contain verification_result');
209
+ assert.match(summaryContent, /key_files:/, 'summary should contain key_files');
210
+ assert.match(summaryContent, /patterns_established:/, 'summary should contain patterns_established');
211
+ assert.match(summaryContent, /observability_surfaces:/, 'summary should contain observability_surfaces');
212
+ assert.match(summaryContent, /provides:/, 'summary should contain provides');
213
+ assert.match(summaryContent, /# S01: Test Slice/, 'summary should have H1 with slice ID and title');
214
+ assert.match(summaryContent, /\*\*Implemented test slice with full coverage\*\*/, 'summary should have one-liner in bold');
215
+ assert.match(summaryContent, /## What Happened/, 'summary should have What Happened section');
216
+ assert.match(summaryContent, /## Verification/, 'summary should have Verification section');
217
+ assert.match(summaryContent, /## Requirements Advanced/, 'summary should have Requirements Advanced section');
218
+
219
+ // (b) Verify UAT.md exists on disk
220
+ assert.ok(fs.existsSync(result.uatPath), 'UAT file should exist on disk');
221
+ const uatContent = fs.readFileSync(result.uatPath, 'utf-8');
222
+ assert.match(uatContent, /# S01: Test Slice — UAT/, 'UAT should have correct title');
223
+ assert.match(uatContent, /Milestone:\*\* M001/, 'UAT should reference milestone');
224
+ assert.match(uatContent, /Smoke Test/, 'UAT should contain smoke test from params');
225
+
226
+ // (c) Verify roadmap checkbox toggled to [x]
227
+ const roadmapContent = fs.readFileSync(roadmapPath, 'utf-8');
228
+ assert.match(roadmapContent, /\[x\]\s+\*\*S01:/, 'S01 should be checked in roadmap');
229
+ assert.match(roadmapContent, /\[ \]\s+\*\*S02:/, 'S02 should still be unchecked in roadmap');
230
+
231
+ // (d) Verify full_summary_md and full_uat_md stored in DB for D004 recovery
232
+ const sliceAfter = getSlice('M001', 'S01');
233
+ assert.ok(sliceAfter !== null, 'slice should exist in DB after handler');
234
+ assert.ok(sliceAfter!.full_summary_md.length > 0, 'full_summary_md should be non-empty in DB');
235
+ assert.match(sliceAfter!.full_summary_md, /id: S01/, 'full_summary_md should contain frontmatter');
236
+ assert.ok(sliceAfter!.full_uat_md.length > 0, 'full_uat_md should be non-empty in DB');
237
+ assert.match(sliceAfter!.full_uat_md, /S01: Test Slice — UAT/, 'full_uat_md should contain UAT title');
238
+
239
+ // (e) Verify slice status is complete in DB
240
+ assert.strictEqual(sliceAfter!.status, 'complete', 'slice status should be complete in DB');
241
+ assert.ok(sliceAfter!.completed_at !== null, 'completed_at should be set in DB');
242
+ }
281
243
 
282
- // ═══════════════════════════════════════════════════════════════════════════
283
- // complete-slice: Handler rejects no tasks
284
- // ═══════════════════════════════════════════════════════════════════════════
244
+ cleanupDir(basePath);
245
+ cleanup(dbPath);
246
+ });
285
247
 
286
- console.log('\n=== complete-slice: handler rejects no tasks ===');
287
- {
288
- const dbPath = tempDbPath();
289
- openDatabase(dbPath);
248
+ test("rejects incomplete tasks", async () => {
249
+ const dbPath = tempDbPath();
250
+ openDatabase(dbPath);
290
251
 
291
- // Insert milestone and slice but NO tasks
292
- insertMilestone({ id: 'M001' });
293
- insertSlice({ id: 'S01', milestoneId: 'M001' });
252
+ // Insert milestone, slice, 2 tasks — one complete, one pending
253
+ insertMilestone({ id: 'M001' });
254
+ insertSlice({ id: 'S01', milestoneId: 'M001' });
255
+ insertTask({ id: 'T01', sliceId: 'S01', milestoneId: 'M001', status: 'complete', title: 'Task 1' });
256
+ insertTask({ id: 'T02', sliceId: 'S01', milestoneId: 'M001', status: 'pending', title: 'Task 2' });
294
257
 
295
- const params = makeValidSliceParams();
296
- const result = await handleCompleteSlice(params, '/tmp/fake');
258
+ const params = makeValidSliceParams();
259
+ const result = await handleCompleteSlice(params, '/tmp/fake');
297
260
 
298
- assertTrue('error' in result, 'should return error when no tasks exist');
299
- if ('error' in result) {
300
- assertMatch(result.error, /no tasks found/, 'error should say no tasks found');
301
- }
261
+ assert.ok('error' in result, 'should return error when tasks are incomplete');
262
+ if ('error' in result) {
263
+ assert.match(result.error, /incomplete tasks/, 'error should mention incomplete tasks');
264
+ assert.match(result.error, /T02/, 'error should mention the specific incomplete task ID');
265
+ }
302
266
 
303
- cleanup(dbPath);
304
- }
267
+ cleanup(dbPath);
268
+ });
305
269
 
306
- // ═══════════════════════════════════════════════════════════════════════════
307
- // complete-slice: Handler validation errors
308
- // ═══════════════════════════════════════════════════════════════════════════
270
+ test("rejects no tasks", async () => {
271
+ const dbPath = tempDbPath();
272
+ openDatabase(dbPath);
309
273
 
310
- console.log('\n=== complete-slice: handler validation errors ===');
311
- {
312
- const dbPath = tempDbPath();
313
- openDatabase(dbPath);
274
+ // Insert milestone and slice but NO tasks
275
+ insertMilestone({ id: 'M001' });
276
+ insertSlice({ id: 'S01', milestoneId: 'M001' });
314
277
 
315
- const params = makeValidSliceParams();
278
+ const params = makeValidSliceParams();
279
+ const result = await handleCompleteSlice(params, '/tmp/fake');
316
280
 
317
- // Empty sliceId
318
- const r1 = await handleCompleteSlice({ ...params, sliceId: '' }, '/tmp/fake');
319
- assertTrue('error' in r1, 'should return error for empty sliceId');
320
- if ('error' in r1) {
321
- assertMatch(r1.error, /sliceId/, 'error should mention sliceId');
322
- }
281
+ assert.ok('error' in result, 'should return error when no tasks exist');
282
+ if ('error' in result) {
283
+ assert.match(result.error, /no tasks found/, 'error should say no tasks found');
284
+ }
323
285
 
324
- // Empty milestoneId
325
- const r2 = await handleCompleteSlice({ ...params, milestoneId: '' }, '/tmp/fake');
326
- assertTrue('error' in r2, 'should return error for empty milestoneId');
327
- if ('error' in r2) {
328
- assertMatch(r2.error, /milestoneId/, 'error should mention milestoneId');
329
- }
286
+ cleanup(dbPath);
287
+ });
330
288
 
331
- cleanup(dbPath);
332
- }
289
+ test("validation errors", async () => {
290
+ const dbPath = tempDbPath();
291
+ openDatabase(dbPath);
333
292
 
334
- // ═══════════════════════════════════════════════════════════════════════════
335
- // complete-slice: Handler idempotency
336
- // ═══════════════════════════════════════════════════════════════════════════
293
+ const params = makeValidSliceParams();
337
294
 
338
- console.log('\n=== complete-slice: handler idempotency ===');
339
- {
340
- const dbPath = tempDbPath();
341
- openDatabase(dbPath);
295
+ // Empty sliceId
296
+ const r1 = await handleCompleteSlice({ ...params, sliceId: '' }, '/tmp/fake');
297
+ assert.ok('error' in r1, 'should return error for empty sliceId');
298
+ if ('error' in r1) {
299
+ assert.match(r1.error, /sliceId/, 'error should mention sliceId');
300
+ }
342
301
 
343
- const { basePath, roadmapPath } = createTempProject();
302
+ // Empty milestoneId
303
+ const r2 = await handleCompleteSlice({ ...params, milestoneId: '' }, '/tmp/fake');
304
+ assert.ok('error' in r2, 'should return error for empty milestoneId');
305
+ if ('error' in r2) {
306
+ assert.match(r2.error, /milestoneId/, 'error should mention milestoneId');
307
+ }
344
308
 
345
- // Set up DB state
346
- insertMilestone({ id: 'M001' });
347
- insertSlice({ id: 'S01', milestoneId: 'M001' });
348
- insertTask({ id: 'T01', sliceId: 'S01', milestoneId: 'M001', status: 'complete', title: 'Task 1' });
309
+ cleanup(dbPath);
310
+ });
349
311
 
350
- const params = makeValidSliceParams();
312
+ test("idempotency", async () => {
313
+ const dbPath = tempDbPath();
314
+ openDatabase(dbPath);
351
315
 
352
- // First call
353
- const r1 = await handleCompleteSlice(params, basePath);
354
- assertTrue(!('error' in r1), 'first call should succeed');
316
+ const { basePath, roadmapPath } = createTempProject();
355
317
 
356
- // Second call with same params — should not crash
357
- const r2 = await handleCompleteSlice(params, basePath);
358
- assertTrue(!('error' in r2), 'second call should succeed (idempotent)');
318
+ // Set up DB state
319
+ insertMilestone({ id: 'M001' });
320
+ insertSlice({ id: 'S01', milestoneId: 'M001' });
321
+ insertTask({ id: 'T01', sliceId: 'S01', milestoneId: 'M001', status: 'complete', title: 'Task 1' });
359
322
 
360
- // Verify only 1 slice row (not duplicated)
361
- const adapter = _getAdapter()!;
362
- 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');
323
+ const params = makeValidSliceParams();
364
324
 
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
- }
325
+ // First call
326
+ const r1 = await handleCompleteSlice(params, basePath);
327
+ assert.ok(!('error' in r1), 'first call should succeed');
370
328
 
371
- cleanupDir(basePath);
372
- cleanup(dbPath);
373
- }
329
+ // Second call with same params — should not crash
330
+ const r2 = await handleCompleteSlice(params, basePath);
331
+ assert.ok(!('error' in r2), 'second call should succeed (idempotent)');
374
332
 
375
- // ═══════════════════════════════════════════════════════════════════════════
376
- // complete-slice: Handler with missing roadmap (graceful)
377
- // ═══════════════════════════════════════════════════════════════════════════
333
+ // Verify only 1 slice row (not duplicated)
334
+ const adapter = _getAdapter()!;
335
+ const sliceRows = adapter.prepare("SELECT * FROM slices WHERE milestone_id = 'M001' AND id = 'S01'").all();
336
+ assert.strictEqual(sliceRows.length, 1, 'should have exactly 1 slice row after 2 calls');
378
337
 
379
- console.log('\n=== complete-slice: handler with missing roadmap ===');
380
- {
381
- const dbPath = tempDbPath();
382
- openDatabase(dbPath);
338
+ // Files should still exist
339
+ if (!('error' in r2)) {
340
+ assert.ok(fs.existsSync(r2.summaryPath), 'summary should still exist after second call');
341
+ assert.ok(fs.existsSync(r2.uatPath), 'UAT should still exist after second call');
342
+ }
383
343
 
384
- // Create a temp dir WITHOUT a roadmap file
385
- const basePath = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-no-roadmap-'));
386
- const sliceDir = path.join(basePath, '.gsd', 'milestones', 'M001', 'slices', 'S01');
387
- fs.mkdirSync(sliceDir, { recursive: true });
344
+ cleanupDir(basePath);
345
+ cleanup(dbPath);
346
+ });
388
347
 
389
- // Set up DB state
390
- insertMilestone({ id: 'M001' });
391
- insertSlice({ id: 'S01', milestoneId: 'M001' });
392
- insertTask({ id: 'T01', sliceId: 'S01', milestoneId: 'M001', status: 'complete', title: 'Task 1' });
348
+ test("missing roadmap (graceful)", async () => {
349
+ const dbPath = tempDbPath();
350
+ openDatabase(dbPath);
393
351
 
394
- const params = makeValidSliceParams();
395
- const result = await handleCompleteSlice(params, basePath);
352
+ // Create a temp dir WITHOUT a roadmap file
353
+ const basePath = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-no-roadmap-'));
354
+ const sliceDir = path.join(basePath, '.gsd', 'milestones', 'M001', 'slices', 'S01');
355
+ fs.mkdirSync(sliceDir, { recursive: true });
396
356
 
397
- // Should succeed even without roadmap file — just skip checkbox toggle
398
- assertTrue(!('error' in result), 'handler should succeed without roadmap file');
399
- if (!('error' in result)) {
400
- assertTrue(fs.existsSync(result.summaryPath), 'summary should be written even without roadmap');
401
- assertTrue(fs.existsSync(result.uatPath), 'UAT should be written even without roadmap');
402
- }
357
+ // Set up DB state
358
+ insertMilestone({ id: 'M001' });
359
+ insertSlice({ id: 'S01', milestoneId: 'M001' });
360
+ insertTask({ id: 'T01', sliceId: 'S01', milestoneId: 'M001', status: 'complete', title: 'Task 1' });
403
361
 
404
- cleanupDir(basePath);
405
- cleanup(dbPath);
406
- }
362
+ const params = makeValidSliceParams();
363
+ const result = await handleCompleteSlice(params, basePath);
407
364
 
408
- // ═══════════════════════════════════════════════════════════════════════════
365
+ // Should succeed even without roadmap file — just skip checkbox toggle
366
+ assert.ok(!('error' in result), 'handler should succeed without roadmap file');
367
+ if (!('error' in result)) {
368
+ assert.ok(fs.existsSync(result.summaryPath), 'summary should be written even without roadmap');
369
+ assert.ok(fs.existsSync(result.uatPath), 'UAT should be written even without roadmap');
370
+ }
409
371
 
410
- report();
372
+ cleanupDir(basePath);
373
+ cleanup(dbPath);
374
+ });
375
+ });