gsd-pi 2.78.0 → 2.78.1-dev.9d08d820b

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 (548) hide show
  1. package/README.md +59 -23
  2. package/dist/bundled-resource-path.d.ts +7 -0
  3. package/dist/bundled-resource-path.js +34 -2
  4. package/dist/claude-cli-check.js +104 -33
  5. package/dist/cli-policy.d.ts +13 -0
  6. package/dist/cli-policy.js +17 -0
  7. package/dist/cli.js +95 -55
  8. package/dist/headless-query.d.ts +22 -0
  9. package/dist/headless-query.js +43 -8
  10. package/dist/headless.d.ts +10 -0
  11. package/dist/headless.js +16 -1
  12. package/dist/loader.js +9 -13
  13. package/dist/onboarding.d.ts +10 -0
  14. package/dist/onboarding.js +2 -2
  15. package/dist/provider-migrations.d.ts +2 -2
  16. package/dist/provider-migrations.js +5 -2
  17. package/dist/resource-loader.d.ts +5 -2
  18. package/dist/resource-loader.js +30 -13
  19. package/dist/resources/.managed-resources-content-hash +1 -0
  20. package/dist/resources/extensions/claude-code-cli/readiness.js +128 -32
  21. package/dist/resources/extensions/gsd/auto/loop.js +23 -0
  22. package/dist/resources/extensions/gsd/auto/phases.js +5 -13
  23. package/dist/resources/extensions/gsd/auto/run-unit.js +3 -1
  24. package/dist/resources/extensions/gsd/auto/session.js +5 -6
  25. package/dist/resources/extensions/gsd/auto-dashboard.js +3 -2
  26. package/dist/resources/extensions/gsd/auto-dispatch.js +18 -6
  27. package/dist/resources/extensions/gsd/auto-prompts.js +63 -2
  28. package/dist/resources/extensions/gsd/auto-recovery.js +43 -4
  29. package/dist/resources/extensions/gsd/auto-runtime-state.js +31 -0
  30. package/dist/resources/extensions/gsd/auto-start.js +1 -1
  31. package/dist/resources/extensions/gsd/auto-tool-tracking.js +2 -2
  32. package/dist/resources/extensions/gsd/auto-worktree.js +60 -13
  33. package/dist/resources/extensions/gsd/auto.js +14 -5
  34. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +14 -2
  35. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +7 -5
  36. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
  37. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +5 -4
  38. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +100 -31
  39. package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +11 -6
  40. package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +22 -0
  41. package/dist/resources/extensions/gsd/bootstrap/system-context.js +34 -8
  42. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +121 -3
  43. package/dist/resources/extensions/gsd/commands/catalog.js +69 -5
  44. package/dist/resources/extensions/gsd/commands/handlers/core.js +22 -1
  45. package/dist/resources/extensions/gsd/commands-config.js +3 -2
  46. package/dist/resources/extensions/gsd/commands-extensions.js +46 -3
  47. package/dist/resources/extensions/gsd/commands-handlers.js +3 -2
  48. package/dist/resources/extensions/gsd/commands-mcp-status.js +3 -1
  49. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +10 -1
  50. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -1
  51. package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  52. package/dist/resources/extensions/gsd/doctor-providers.js +2 -1
  53. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +39 -1
  54. package/dist/resources/extensions/gsd/error-classifier.js +1 -1
  55. package/dist/resources/extensions/gsd/forensics.js +10 -8
  56. package/dist/resources/extensions/gsd/git-service.js +12 -5
  57. package/dist/resources/extensions/gsd/gsd-db.js +11 -2
  58. package/dist/resources/extensions/gsd/guided-flow.js +25 -24
  59. package/dist/resources/extensions/gsd/home-dir.js +16 -0
  60. package/dist/resources/extensions/gsd/key-manager.js +2 -1
  61. package/dist/resources/extensions/gsd/memory-store.js +66 -31
  62. package/dist/resources/extensions/gsd/migrate/command.js +3 -2
  63. package/dist/resources/extensions/gsd/milestone-id-reservation.js +36 -0
  64. package/dist/resources/extensions/gsd/model-router.js +114 -9
  65. package/dist/resources/extensions/gsd/native-git-bridge.js +7 -1
  66. package/dist/resources/extensions/gsd/preferences-models.js +91 -15
  67. package/dist/resources/extensions/gsd/preferences-types.js +2 -0
  68. package/dist/resources/extensions/gsd/preferences-validation.js +32 -0
  69. package/dist/resources/extensions/gsd/preferences.js +5 -3
  70. package/dist/resources/extensions/gsd/prompt-loader.js +23 -12
  71. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +10 -0
  72. package/dist/resources/extensions/gsd/prompts/complete-slice.md +10 -0
  73. package/dist/resources/extensions/gsd/prompts/plan-slice.md +10 -0
  74. package/dist/resources/extensions/gsd/prompts/refine-slice.md +10 -0
  75. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +9 -3
  76. package/dist/resources/extensions/gsd/state.js +42 -0
  77. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
  78. package/dist/resources/extensions/gsd/tools/memory-tools.js +18 -1
  79. package/dist/resources/extensions/gsd/unit-context-manifest.js +29 -4
  80. package/dist/resources/extensions/gsd/visualizer-overlay.js +1 -1
  81. package/dist/resources/extensions/gsd/watch/header-renderer.js +3 -1
  82. package/dist/resources/extensions/gsd/worktree-command.js +26 -46
  83. package/dist/resources/extensions/gsd/worktree-manager.js +20 -1
  84. package/dist/resources/extensions/gsd/worktree-resolver.js +4 -13
  85. package/dist/resources/extensions/gsd/worktree-root.js +124 -0
  86. package/dist/resources/extensions/gsd/worktree-session-state.js +33 -0
  87. package/dist/resources/extensions/gsd/worktree.js +4 -115
  88. package/dist/resources/extensions/mcp-client/index.js +6 -3
  89. package/dist/resources/extensions/ollama/index.js +15 -2
  90. package/dist/resources/extensions/ollama/model-capabilities.js +31 -0
  91. package/dist/resources/extensions/ollama/ollama-client.js +40 -4
  92. package/dist/resources/extensions/slash-commands/create-extension.js +36 -22
  93. package/dist/resources/extensions/subagent/index.js +324 -178
  94. package/dist/resources/skills/create-gsd-extension/SKILL.md +9 -5
  95. package/dist/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
  96. package/dist/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
  97. package/dist/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
  98. package/dist/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
  99. package/dist/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
  100. package/dist/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
  101. package/dist/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
  102. package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +32 -12
  103. package/dist/rtk-shared.d.ts +3 -0
  104. package/dist/rtk-shared.js +17 -0
  105. package/dist/rtk.d.ts +2 -5
  106. package/dist/rtk.js +3 -20
  107. package/dist/runtime-checks.d.ts +27 -0
  108. package/dist/runtime-checks.js +38 -0
  109. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  110. package/dist/web/standalone/.next/BUILD_ID +1 -1
  111. package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
  112. package/dist/web/standalone/.next/build-manifest.json +4 -4
  113. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  114. package/dist/web/standalone/.next/react-loadable-manifest.json +44 -4
  115. package/dist/web/standalone/.next/required-server-files.json +3 -3
  116. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  117. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  118. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  119. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  127. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  128. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  129. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  130. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  131. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  133. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  143. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  155. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  175. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  185. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/session/events/route.js +4 -2
  191. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  203. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  204. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  205. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  206. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  207. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  208. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  209. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  210. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  211. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  212. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  213. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  214. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  215. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  216. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  217. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  218. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  219. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  220. package/dist/web/standalone/.next/server/app/index.html +1 -1
  221. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  222. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  223. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  224. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  225. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  226. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  227. package/dist/web/standalone/.next/server/app/page.js +2 -2
  228. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  229. package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
  230. package/dist/web/standalone/.next/server/chunks/63.js +3 -3
  231. package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
  232. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  233. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  234. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  235. package/dist/web/standalone/.next/server/middleware.js +2 -2
  236. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  237. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  238. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  239. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  240. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  241. package/dist/web/standalone/.next/server/webpack-runtime.js +1 -1
  242. package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +1 -0
  243. package/dist/web/standalone/.next/static/chunks/2824.08296bc2f9654698.js +1 -0
  244. package/dist/web/standalone/.next/static/chunks/3026.3af53b279375f082.js +1 -0
  245. package/dist/web/standalone/.next/static/chunks/315.6f68ae79b67d25cf.js +1 -0
  246. package/dist/web/standalone/.next/static/chunks/3497.4bfc60a3b3dea717.js +1 -0
  247. package/dist/web/standalone/.next/static/chunks/5516.4a07c872b5c3a663.js +1 -0
  248. package/dist/web/standalone/.next/static/chunks/8336.31b019697882acfb.js +10 -0
  249. package/dist/web/standalone/.next/static/chunks/8845.c9702695e8c5a9c5.js +2 -0
  250. package/dist/web/standalone/.next/static/chunks/9058.01ef3a463bda88f1.js +20 -0
  251. package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +1 -0
  252. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  253. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  254. package/dist/web/standalone/.next/static/chunks/app/page-9bf2e0c50fb2ca05.js +1 -0
  255. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  256. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  257. package/dist/web/standalone/.next/static/chunks/webpack-f9f0dc45e4f3ac10.js +1 -0
  258. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  259. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  260. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  261. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  262. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  263. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  264. package/dist/web/standalone/package.json +2 -1
  265. package/dist/web/standalone/server.js +1 -1
  266. package/dist/worktree-cli.d.ts +1 -0
  267. package/dist/worktree-cli.js +9 -3
  268. package/dist/worktree-status-banner.d.ts +1 -0
  269. package/dist/worktree-status-banner.js +132 -0
  270. package/package.json +1 -3
  271. package/packages/daemon/package.json +2 -2
  272. package/packages/mcp-server/dist/alias-telemetry.d.ts +8 -0
  273. package/packages/mcp-server/dist/alias-telemetry.d.ts.map +1 -0
  274. package/packages/mcp-server/dist/alias-telemetry.js +30 -0
  275. package/packages/mcp-server/dist/alias-telemetry.js.map +1 -0
  276. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  277. package/packages/mcp-server/dist/workflow-tools.js +74 -46
  278. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  279. package/packages/mcp-server/package.json +2 -2
  280. package/packages/mcp-server/src/alias-telemetry.test.ts +78 -0
  281. package/packages/mcp-server/src/alias-telemetry.ts +30 -0
  282. package/packages/mcp-server/src/workflow-tools.test.ts +78 -0
  283. package/packages/mcp-server/src/workflow-tools.ts +93 -58
  284. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  285. package/packages/native/package.json +1 -1
  286. package/packages/native/tsconfig.tsbuildinfo +1 -1
  287. package/packages/pi-agent-core/package.json +1 -1
  288. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  289. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts +2 -0
  290. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts.map +1 -0
  291. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js +231 -0
  292. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js.map +1 -0
  293. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  294. package/packages/pi-ai/dist/providers/anthropic-shared.js +48 -19
  295. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  296. package/packages/pi-ai/dist/types.d.ts +13 -0
  297. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  298. package/packages/pi-ai/dist/types.js.map +1 -1
  299. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -1
  300. package/packages/pi-ai/dist/utils/repair-tool-json.js +24 -3
  301. package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -1
  302. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +26 -0
  303. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -1
  304. package/packages/pi-ai/package.json +1 -1
  305. package/packages/pi-ai/src/providers/anthropic-shared.cache-breakpoint.test.ts +289 -0
  306. package/packages/pi-ai/src/providers/anthropic-shared.ts +52 -20
  307. package/packages/pi-ai/src/types.ts +13 -0
  308. package/packages/pi-ai/src/utils/repair-tool-json.ts +24 -3
  309. package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +32 -0
  310. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  311. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  312. package/packages/pi-coding-agent/dist/core/agent-session.js +6 -0
  313. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  314. package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
  315. package/packages/pi-coding-agent/dist/core/messages.js +4 -0
  316. package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
  317. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +19 -2
  318. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  319. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +10 -0
  320. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  321. package/packages/pi-coding-agent/dist/core/model-registry.js +18 -0
  322. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  323. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +13 -0
  324. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  325. package/packages/pi-coding-agent/dist/core/system-prompt.js +20 -16
  326. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  327. package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts +37 -0
  328. package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts.map +1 -0
  329. package/packages/pi-coding-agent/dist/core/token-telemetry.js +49 -0
  330. package/packages/pi-coding-agent/dist/core/token-telemetry.js.map +1 -0
  331. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts +2 -0
  332. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts.map +1 -0
  333. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +133 -0
  334. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -0
  335. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +1 -1
  336. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  337. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +14 -1
  338. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  339. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts +2 -0
  340. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts.map +1 -0
  341. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js +78 -0
  342. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js.map +1 -0
  343. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts +2 -0
  344. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts.map +1 -0
  345. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js +181 -0
  346. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js.map +1 -0
  347. package/packages/pi-coding-agent/package.json +1 -1
  348. package/packages/pi-coding-agent/src/core/agent-session.ts +7 -0
  349. package/packages/pi-coding-agent/src/core/messages.ts +4 -0
  350. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +32 -2
  351. package/packages/pi-coding-agent/src/core/model-registry.ts +21 -0
  352. package/packages/pi-coding-agent/src/core/system-prompt.ts +33 -15
  353. package/packages/pi-coding-agent/src/core/token-telemetry.ts +77 -0
  354. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +212 -0
  355. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +17 -1
  356. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +1 -1
  357. package/packages/pi-coding-agent/src/tests/system-prompt-cache-stability.test.ts +102 -0
  358. package/packages/pi-coding-agent/src/tests/token-telemetry.test.ts +200 -0
  359. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  360. package/packages/pi-tui/dist/__tests__/autocomplete.test.js +17 -3
  361. package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
  362. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts +2 -0
  363. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts.map +1 -0
  364. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js +161 -0
  365. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js.map +1 -0
  366. package/packages/pi-tui/package.json +1 -1
  367. package/packages/pi-tui/src/__tests__/autocomplete.test.ts +20 -3
  368. package/packages/pi-tui/src/components/__tests__/leak-fixes-runtime.test.ts +219 -0
  369. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  370. package/packages/rpc-client/package.json +1 -1
  371. package/pkg/package.json +1 -1
  372. package/src/resources/extensions/claude-code-cli/readiness.ts +130 -30
  373. package/src/resources/extensions/gsd/auto/loop.ts +24 -2
  374. package/src/resources/extensions/gsd/auto/phases.ts +6 -14
  375. package/src/resources/extensions/gsd/auto/run-unit.ts +3 -1
  376. package/src/resources/extensions/gsd/auto/session.ts +5 -6
  377. package/src/resources/extensions/gsd/auto/types.ts +1 -0
  378. package/src/resources/extensions/gsd/auto-dashboard.ts +3 -2
  379. package/src/resources/extensions/gsd/auto-dispatch.ts +18 -6
  380. package/src/resources/extensions/gsd/auto-prompts.ts +60 -2
  381. package/src/resources/extensions/gsd/auto-recovery.ts +46 -8
  382. package/src/resources/extensions/gsd/auto-runtime-state.ts +51 -0
  383. package/src/resources/extensions/gsd/auto-start.ts +1 -1
  384. package/src/resources/extensions/gsd/auto-tool-tracking.ts +2 -4
  385. package/src/resources/extensions/gsd/auto-worktree.ts +82 -12
  386. package/src/resources/extensions/gsd/auto.ts +14 -4
  387. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +15 -13
  388. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +8 -7
  389. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
  390. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +10 -9
  391. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +108 -31
  392. package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +12 -6
  393. package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +20 -0
  394. package/src/resources/extensions/gsd/bootstrap/system-context.ts +39 -8
  395. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +141 -11
  396. package/src/resources/extensions/gsd/commands/catalog.ts +75 -5
  397. package/src/resources/extensions/gsd/commands/handlers/core.ts +22 -1
  398. package/src/resources/extensions/gsd/commands-config.ts +3 -2
  399. package/src/resources/extensions/gsd/commands-extensions.ts +43 -3
  400. package/src/resources/extensions/gsd/commands-handlers.ts +3 -2
  401. package/src/resources/extensions/gsd/commands-mcp-status.ts +3 -1
  402. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +15 -1
  403. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -1
  404. package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  405. package/src/resources/extensions/gsd/doctor-providers.ts +2 -1
  406. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +39 -1
  407. package/src/resources/extensions/gsd/doctor-types.ts +3 -1
  408. package/src/resources/extensions/gsd/error-classifier.ts +1 -1
  409. package/src/resources/extensions/gsd/forensics.ts +12 -7
  410. package/src/resources/extensions/gsd/git-service.ts +13 -5
  411. package/src/resources/extensions/gsd/gsd-db.ts +12 -2
  412. package/src/resources/extensions/gsd/guided-flow.ts +27 -26
  413. package/src/resources/extensions/gsd/home-dir.ts +19 -0
  414. package/src/resources/extensions/gsd/journal.ts +4 -1
  415. package/src/resources/extensions/gsd/key-manager.ts +2 -1
  416. package/src/resources/extensions/gsd/memory-store.ts +81 -28
  417. package/src/resources/extensions/gsd/migrate/command.ts +3 -2
  418. package/src/resources/extensions/gsd/milestone-id-reservation.ts +47 -0
  419. package/src/resources/extensions/gsd/model-router.ts +172 -9
  420. package/src/resources/extensions/gsd/native-git-bridge.ts +7 -1
  421. package/src/resources/extensions/gsd/preferences-models.ts +101 -15
  422. package/src/resources/extensions/gsd/preferences-types.ts +6 -0
  423. package/src/resources/extensions/gsd/preferences-validation.ts +35 -0
  424. package/src/resources/extensions/gsd/preferences.ts +16 -2
  425. package/src/resources/extensions/gsd/prompt-loader.ts +26 -12
  426. package/src/resources/extensions/gsd/prompts/complete-milestone.md +10 -0
  427. package/src/resources/extensions/gsd/prompts/complete-slice.md +10 -0
  428. package/src/resources/extensions/gsd/prompts/plan-slice.md +10 -0
  429. package/src/resources/extensions/gsd/prompts/refine-slice.md +10 -0
  430. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +9 -3
  431. package/src/resources/extensions/gsd/state.ts +42 -0
  432. package/src/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
  433. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +178 -1
  434. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +58 -0
  435. package/src/resources/extensions/gsd/tests/auto-session-encapsulation.test.ts +24 -5
  436. package/src/resources/extensions/gsd/tests/auto-supervisor.test.mjs +21 -4
  437. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +1 -1
  438. package/src/resources/extensions/gsd/tests/budget-prediction.test.ts +138 -211
  439. package/src/resources/extensions/gsd/tests/commands-extensions-version-compare.test.ts +58 -0
  440. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +142 -59
  441. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +7 -4
  442. package/src/resources/extensions/gsd/tests/completed-at-reconcile.test.ts +89 -32
  443. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +41 -23
  444. package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +3 -43
  445. package/src/resources/extensions/gsd/tests/debug-logger.test.ts +5 -3
  446. package/src/resources/extensions/gsd/tests/deferred-milestone-dir-4996.test.ts +116 -0
  447. package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +22 -87
  448. package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +7 -118
  449. package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +18 -60
  450. package/src/resources/extensions/gsd/tests/doctor-orphan-milestone-4996.test.ts +100 -0
  451. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +14 -76
  452. package/src/resources/extensions/gsd/tests/ensure-preconditions-guard-4996.test.ts +93 -0
  453. package/src/resources/extensions/gsd/tests/false-degraded-mode-warning.test.ts +22 -83
  454. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +1 -63
  455. package/src/resources/extensions/gsd/tests/find-missing-summaries-closed-runtime.test.ts +47 -0
  456. package/src/resources/extensions/gsd/tests/forensics-stuck-loops.test.ts +26 -1
  457. package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +63 -0
  458. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +30 -0
  459. package/src/resources/extensions/gsd/tests/gsd-no-project-error-runtime.test.ts +81 -0
  460. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +14 -4
  461. package/src/resources/extensions/gsd/tests/health-widget.test.ts +22 -12
  462. package/src/resources/extensions/gsd/tests/help-menu-coverage.test.ts +57 -0
  463. package/src/resources/extensions/gsd/tests/home-dir.test.ts +52 -0
  464. package/src/resources/extensions/gsd/tests/import-done-milestones-runtime.test.ts +145 -0
  465. package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +64 -1
  466. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +72 -1
  467. package/src/resources/extensions/gsd/tests/integration/token-savings.test.ts +0 -23
  468. package/src/resources/extensions/gsd/tests/memory-store.test.ts +128 -0
  469. package/src/resources/extensions/gsd/tests/memory-tools.test.ts +33 -1
  470. package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +124 -0
  471. package/src/resources/extensions/gsd/tests/milestone-id-gap-reuse-4996.test.ts +152 -0
  472. package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +18 -1
  473. package/src/resources/extensions/gsd/tests/model-router.test.ts +169 -8
  474. package/src/resources/extensions/gsd/tests/native-git-infra-errors.test.ts +50 -0
  475. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +8 -0
  476. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +32 -43
  477. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +4 -10
  478. package/src/resources/extensions/gsd/tests/preferences.test.ts +127 -0
  479. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +16 -0
  480. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +7 -0
  481. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +6 -6
  482. package/src/resources/extensions/gsd/tests/register-hooks-compaction-checkpoint.test.ts +93 -0
  483. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +168 -19
  484. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +7 -1
  485. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +23 -1
  486. package/src/resources/extensions/gsd/tests/steer-worktree-path.test.ts +17 -1
  487. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +101 -0
  488. package/src/resources/extensions/gsd/tests/token-profile.test.ts +51 -4
  489. package/src/resources/extensions/gsd/tests/turn-epoch.test.ts +7 -16
  490. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +38 -3
  491. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -7
  492. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +15 -1
  493. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +6 -6
  494. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +34 -33
  495. package/src/resources/extensions/gsd/tests/worktree.test.ts +8 -0
  496. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +131 -1
  497. package/src/resources/extensions/gsd/tools/memory-tools.ts +17 -1
  498. package/src/resources/extensions/gsd/unit-context-manifest.ts +44 -12
  499. package/src/resources/extensions/gsd/visualizer-overlay.ts +1 -1
  500. package/src/resources/extensions/gsd/watch/header-renderer.ts +3 -1
  501. package/src/resources/extensions/gsd/workflow-logger.ts +1 -0
  502. package/src/resources/extensions/gsd/worktree-command.ts +31 -44
  503. package/src/resources/extensions/gsd/worktree-manager.ts +40 -1
  504. package/src/resources/extensions/gsd/worktree-resolver.ts +4 -14
  505. package/src/resources/extensions/gsd/worktree-root.ts +144 -0
  506. package/src/resources/extensions/gsd/worktree-session-state.ts +35 -0
  507. package/src/resources/extensions/gsd/worktree.ts +8 -119
  508. package/src/resources/extensions/mcp-client/index.ts +6 -3
  509. package/src/resources/extensions/mcp-client/tests/global-config.test.ts +91 -0
  510. package/src/resources/extensions/ollama/index.ts +16 -2
  511. package/src/resources/extensions/ollama/model-capabilities.ts +34 -0
  512. package/src/resources/extensions/ollama/ollama-client.ts +41 -4
  513. package/src/resources/extensions/ollama/tests/model-capabilities.test.ts +96 -0
  514. package/src/resources/extensions/ollama/tests/ollama-client-timeout-env.test.ts +147 -0
  515. package/src/resources/extensions/slash-commands/create-extension.ts +38 -24
  516. package/src/resources/extensions/subagent/index.ts +165 -7
  517. package/src/resources/skills/create-gsd-extension/SKILL.md +9 -5
  518. package/src/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
  519. package/src/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
  520. package/src/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
  521. package/src/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
  522. package/src/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
  523. package/src/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
  524. package/src/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
  525. package/src/resources/skills/create-gsd-extension/templates/extension-skeleton.ts +2 -2
  526. package/src/resources/skills/create-gsd-extension/templates/stateful-tool-skeleton.ts +3 -3
  527. package/src/resources/skills/create-gsd-extension/templates/templates.test.ts +58 -0
  528. package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +32 -12
  529. package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +0 -601
  530. package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +0 -651
  531. package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +0 -91
  532. package/dist/resources/extensions/gsd/tests/auto-supervisor.test.mjs +0 -53
  533. package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +0 -112
  534. package/dist/resources/extensions/gsd/tests/resolve-ts-hooks.mjs +0 -23
  535. package/dist/resources/extensions/gsd/tests/resolve-ts.mjs +0 -5
  536. package/dist/resources/skills/github-workflows/references/gh/tests/__init__.py +0 -0
  537. package/dist/resources/skills/github-workflows/references/gh/tests/test_github_project_setup.py +0 -608
  538. package/dist/web/standalone/.next/static/chunks/2826.e9f5195e91f9cad2.js +0 -11
  539. package/dist/web/standalone/.next/static/chunks/3621.fc7480022c972438.js +0 -20
  540. package/dist/web/standalone/.next/static/chunks/app/page-151349214571e2b6.js +0 -1
  541. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  542. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  543. package/dist/web/standalone/.next/static/chunks/webpack-2e68521d7c82f7c2.js +0 -1
  544. package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +0 -22
  545. package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +0 -47
  546. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +0 -75
  547. /package/dist/web/standalone/.next/static/{C1zT2kEfoLhDdbWPWKrXd → -Ukk6_YxRd4GY4iUOnRUE}/_buildManifest.js +0 -0
  548. /package/dist/web/standalone/.next/static/{C1zT2kEfoLhDdbWPWKrXd → -Ukk6_YxRd4GY4iUOnRUE}/_ssgManifest.js +0 -0
@@ -66,16 +66,22 @@ test("detectHealthWidgetProjectState: milestone without metrics returns active",
66
66
  assert.equal(detectHealthWidgetProjectState(dir), "active");
67
67
  });
68
68
 
69
- test("buildHealthLines: none state shows onboarding copy", (t) => {
70
- assert.deepEqual(buildHealthLines(activeData({ projectState: "none" })), [
71
- " GSD No project loaded run /gsd to start",
72
- ]);
69
+ test("buildHealthLines: none state shows single onboarding line pointing at /gsd", (t) => {
70
+ const lines = buildHealthLines(activeData({ projectState: "none" }));
71
+ assert.equal(lines.length, 1, "renders exactly one line");
72
+ // Should not show System OK / Budget / Last commit chrome when there's no project.
73
+ assert.ok(!/System OK|Budget|Last commit/.test(lines[0]!), "no active-project chrome");
74
+ // Should direct user to bootstrap via /gsd.
75
+ assert.match(lines[0]!, /\/gsd/);
73
76
  });
74
77
 
75
- test("buildHealthLines: initialized state shows continue setup copy", (t) => {
76
- assert.deepEqual(buildHealthLines(activeData({ projectState: "initialized" })), [
77
- " GSD Project initialized run /gsd to continue setup",
78
- ]);
78
+ test("buildHealthLines: initialized state shows single setup line pointing at /gsd", (t) => {
79
+ const lines = buildHealthLines(activeData({ projectState: "initialized" }));
80
+ assert.equal(lines.length, 1, "renders exactly one line");
81
+ assert.ok(!/System OK|Budget|Last commit/.test(lines[0]!), "no active-project chrome");
82
+ // Distinct from "none" — must mention initialized/setup language and /gsd.
83
+ assert.match(lines[0]!, /\/gsd/);
84
+ assert.match(lines[0]!, /initiali[sz]ed|setup/i);
79
85
  });
80
86
 
81
87
  test("buildHealthLines: active state with ledger-driven spend shows spent summary", (t) => {
@@ -115,16 +121,20 @@ test("buildHealthLines: shows last commit with relative time and message", (t) =
115
121
  assert.match(lines[0]!, /feat\(widget\): add health display/);
116
122
  });
117
123
 
118
- test("buildHealthLines: truncates long commit messages", (t) => {
124
+ test("buildHealthLines: truncates long commit messages with ellipsis", (t) => {
119
125
  const epoch = Math.floor(Date.now() / 1000) - 60;
120
- const longMsg = "a".repeat(80);
126
+ const longMsg = "a".repeat(200); // far longer than any reasonable widget cap
121
127
  const lines = buildHealthLines(activeData({
122
128
  lastCommitEpoch: epoch,
123
129
  lastCommitMessage: longMsg,
124
130
  }));
125
131
  assert.equal(lines.length, 1);
126
- assert.match(lines[0]!, /a{49}…/);
127
- assert.ok(!lines[0]!.includes("a".repeat(51)), "message is truncated");
132
+ // Behavioural contract: rendered output is shorter than the input message
133
+ // and ends the message portion with the ellipsis character.
134
+ const aRun = lines[0]!.match(/a+…/);
135
+ assert.ok(aRun, "rendered output contains a run of a-chars terminated by an ellipsis");
136
+ assert.ok(aRun![0].length - 1 < longMsg.length, "truncated message is shorter than input");
137
+ assert.ok(!lines[0]!.includes("a".repeat(longMsg.length)), "untruncated message must not appear in output");
128
138
  });
129
139
 
130
140
  test("buildHealthLines: no last commit section when epoch is null", (t) => {
@@ -0,0 +1,57 @@
1
+ // GSD-2 — Verify /gsd help menu covers all registered commands
2
+ // Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
3
+
4
+ import { describe, test } from "node:test";
5
+ import assert from "node:assert/strict";
6
+
7
+ import { TOP_LEVEL_SUBCOMMANDS } from "../commands/catalog.ts";
8
+
9
+ /**
10
+ * Extracts command names from the showHelp("full") lines array.
11
+ * Each help line follows the pattern: " /gsd <cmd> ..."
12
+ */
13
+ function extractHelpCommands(lines: string[]): Set<string> {
14
+ const cmds = new Set<string>();
15
+ for (const line of lines) {
16
+ const m = line.match(/^\s+\/gsd\s+(\S+)/);
17
+ if (m) cmds.add(m[1]);
18
+ }
19
+ return cmds;
20
+ }
21
+
22
+ describe("help menu coverage", () => {
23
+ test("every TOP_LEVEL_SUBCOMMAND appears in showHelp(\"full\") output", async () => {
24
+ // Import showHelp and capture its output via a mock ctx
25
+ const lines: string[] = [];
26
+ const mockCtx = {
27
+ ui: {
28
+ notify(message: string) {
29
+ lines.push(...message.split("\n"));
30
+ },
31
+ custom: async () => {},
32
+ },
33
+ };
34
+
35
+ const { showHelp } = await import("../commands/handlers/core.ts");
36
+ showHelp(mockCtx as any, "full");
37
+
38
+ const helpCmds = extractHelpCommands(lines);
39
+
40
+ // "help" is the command that shows the menu — it doesn't list itself
41
+ const SELF_REFERENTIAL = new Set(["help"]);
42
+
43
+ const missing: string[] = [];
44
+ for (const entry of TOP_LEVEL_SUBCOMMANDS) {
45
+ if (SELF_REFERENTIAL.has(entry.cmd)) continue;
46
+ if (!helpCmds.has(entry.cmd)) {
47
+ missing.push(entry.cmd);
48
+ }
49
+ }
50
+
51
+ assert.deepStrictEqual(
52
+ missing,
53
+ [],
54
+ `Commands registered in TOP_LEVEL_SUBCOMMANDS but missing from /gsd help full:\n ${missing.join(", ")}`,
55
+ );
56
+ });
57
+ });
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Tests for getHomeDir() — cross-platform home directory resolution.
3
+ *
4
+ * @see https://github.com/gsd-build/gsd-2/issues/5015
5
+ */
6
+ import { describe, it, beforeEach, afterEach } from "node:test";
7
+ import assert from "node:assert/strict";
8
+ import { homedir } from "node:os";
9
+
10
+ describe("getHomeDir", () => {
11
+ let savedHome: string | undefined;
12
+ let savedUserProfile: string | undefined;
13
+ let getHomeDir: () => string;
14
+
15
+ beforeEach(async () => {
16
+ savedHome = process.env.HOME;
17
+ savedUserProfile = process.env.USERPROFILE;
18
+ const mod = await import("../home-dir.ts");
19
+ getHomeDir = mod.getHomeDir;
20
+ });
21
+
22
+ afterEach(() => {
23
+ if (savedHome !== undefined) {
24
+ process.env.HOME = savedHome;
25
+ } else {
26
+ delete process.env.HOME;
27
+ }
28
+ if (savedUserProfile !== undefined) {
29
+ process.env.USERPROFILE = savedUserProfile;
30
+ } else {
31
+ delete process.env.USERPROFILE;
32
+ }
33
+ });
34
+
35
+ it("returns HOME when set", () => {
36
+ process.env.HOME = "/test/home";
37
+ delete process.env.USERPROFILE;
38
+ assert.equal(getHomeDir(), "/test/home");
39
+ });
40
+
41
+ it("falls back to USERPROFILE when HOME is unset", () => {
42
+ delete process.env.HOME;
43
+ process.env.USERPROFILE = String.raw`C:\Users\test`;
44
+ assert.equal(getHomeDir(), String.raw`C:\Users\test`);
45
+ });
46
+
47
+ it("falls back to os.homedir() when both HOME and USERPROFILE are unset", () => {
48
+ delete process.env.HOME;
49
+ delete process.env.USERPROFILE;
50
+ assert.equal(getHomeDir(), homedir());
51
+ });
52
+ });
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Runtime regression — milestones with all-done roadmap slices import as
3
+ * `complete` (#3699 / #3390 / #3379), follow-up #4902.
4
+ *
5
+ * The deleted `import-done-milestones.test.ts` was a source-grep check
6
+ * for the literal `roadmap.slices.every(s => s.done)`. This rewrite
7
+ * exercises `migrateHierarchyToDb()` against a fixture roadmap whose
8
+ * slices are all `[x]` and asserts the milestone row's `status` is
9
+ * `complete` — the actual behaviour the every() check exists to
10
+ * produce.
11
+ */
12
+
13
+ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
14
+ import { join } from 'node:path';
15
+ import { tmpdir } from 'node:os';
16
+
17
+ import {
18
+ openDatabase,
19
+ closeDatabase,
20
+ getAllMilestones,
21
+ } from '../gsd-db.ts';
22
+ import { migrateHierarchyToDb } from '../md-importer.ts';
23
+ import { describe, test } from 'node:test';
24
+ import assert from 'node:assert/strict';
25
+
26
+ function createFixtureBase(): string {
27
+ const base = mkdtempSync(join(tmpdir(), 'gsd-import-done-'));
28
+ mkdirSync(join(base, '.gsd', 'milestones'), { recursive: true });
29
+ return base;
30
+ }
31
+
32
+ function writeFile(base: string, relativePath: string, content: string): void {
33
+ const full = join(base, '.gsd', relativePath);
34
+ mkdirSync(join(full, '..'), { recursive: true });
35
+ writeFileSync(full, content);
36
+ }
37
+
38
+ function cleanup(base: string): void {
39
+ rmSync(base, { recursive: true, force: true });
40
+ }
41
+
42
+ const ROADMAP_ALL_DONE = `# M001: Finished Milestone
43
+
44
+ **Vision:** Done work.
45
+
46
+ ## Slices
47
+
48
+ - [x] **S01: First Slice** \`risk:low\` \`depends:[]\`
49
+ > After this: Done.
50
+
51
+ - [x] **S02: Second Slice** \`risk:medium\` \`depends:[S01]\`
52
+ > After this: Also done.
53
+ `;
54
+
55
+ const ROADMAP_PARTIAL = `# M002: In-Progress Milestone
56
+
57
+ **Vision:** Mid-flight.
58
+
59
+ ## Slices
60
+
61
+ - [x] **S01: Done Slice** \`risk:low\` \`depends:[]\`
62
+ > After this: Done.
63
+
64
+ - [ ] **S02: Pending Slice** \`risk:medium\` \`depends:[S01]\`
65
+ > After this: TBD.
66
+ `;
67
+
68
+ const ROADMAP_EMPTY = `# M003: Empty Milestone
69
+
70
+ **Vision:** No slices yet.
71
+
72
+ ## Slices
73
+
74
+ `;
75
+
76
+ describe('migrateHierarchyToDb: all-done milestones import as complete (#4902)', () => {
77
+ test('milestone with all [x] slices and no SUMMARY imports as complete', () => {
78
+ const base = createFixtureBase();
79
+ try {
80
+ writeFile(base, 'milestones/M001/M001-ROADMAP.md', ROADMAP_ALL_DONE);
81
+ // No SUMMARY.md — the all-done roadmap check is the authoritative signal.
82
+
83
+ openDatabase(':memory:');
84
+ migrateHierarchyToDb(base);
85
+
86
+ const milestones = getAllMilestones();
87
+ const m001 = milestones.find((m) => m.id === 'M001');
88
+ assert.ok(m001, 'M001 should be imported');
89
+ assert.equal(
90
+ m001!.status,
91
+ 'complete',
92
+ 'milestone with all-done slices must import as complete',
93
+ );
94
+ } finally {
95
+ closeDatabase();
96
+ cleanup(base);
97
+ }
98
+ });
99
+
100
+ test('milestone with one pending slice imports as active (negative case)', () => {
101
+ const base = createFixtureBase();
102
+ try {
103
+ writeFile(base, 'milestones/M002/M002-ROADMAP.md', ROADMAP_PARTIAL);
104
+
105
+ openDatabase(':memory:');
106
+ migrateHierarchyToDb(base);
107
+
108
+ const milestones = getAllMilestones();
109
+ const m002 = milestones.find((m) => m.id === 'M002');
110
+ assert.ok(m002, 'M002 should be imported');
111
+ assert.equal(
112
+ m002!.status,
113
+ 'active',
114
+ 'milestone with at least one pending slice must NOT be marked complete',
115
+ );
116
+ } finally {
117
+ closeDatabase();
118
+ cleanup(base);
119
+ }
120
+ });
121
+
122
+ test('milestone with empty slice list does not import as complete', () => {
123
+ // Guards the `roadmap.slices.length > 0` precondition: an empty roadmap
124
+ // must not be misread as "everything is done" (vacuous truth bug).
125
+ const base = createFixtureBase();
126
+ try {
127
+ writeFile(base, 'milestones/M003/M003-ROADMAP.md', ROADMAP_EMPTY);
128
+
129
+ openDatabase(':memory:');
130
+ migrateHierarchyToDb(base);
131
+
132
+ const milestones = getAllMilestones();
133
+ const m003 = milestones.find((m) => m.id === 'M003');
134
+ assert.ok(m003, 'M003 should be imported');
135
+ assert.notEqual(
136
+ m003!.status,
137
+ 'complete',
138
+ 'empty roadmap (no slices) must not import as complete',
139
+ );
140
+ } finally {
141
+ closeDatabase();
142
+ cleanup(base);
143
+ }
144
+ });
145
+ });
@@ -12,7 +12,7 @@ import { tmpdir } from "node:os";
12
12
  import { join } from "node:path";
13
13
 
14
14
  import { mapInitPrefsToWizardShape } from "../init-wizard.ts";
15
- import { writePreferencesFile } from "../commands-prefs-wizard.ts";
15
+ import { handlePrefsWizard, writePreferencesFile } from "../commands-prefs-wizard.ts";
16
16
 
17
17
  test("mapInitPrefsToWizardShape — full roundtrip with all fields", () => {
18
18
  const out = mapInitPrefsToWizardShape({
@@ -123,6 +123,69 @@ test("writePreferencesFile — falls back to default body for new files", async
123
123
  }
124
124
  });
125
125
 
126
+ test("handlePrefsWizard — Advanced config writes min_request_interval_ms", async () => {
127
+ const tmp = mkdtempSync(join(tmpdir(), "gsd-init-prefs-routing-"));
128
+ const path = join(tmp, "PREFERENCES.md");
129
+
130
+ try {
131
+ const selectResponses = [
132
+ "Advanced",
133
+ "(keep current)",
134
+ "(keep current)",
135
+ "(keep current)",
136
+ "(keep current)",
137
+ "(keep current)",
138
+ "(keep current)",
139
+ "(keep current)",
140
+ "── Save & Exit ──",
141
+ ];
142
+ const inputResponses = ["250"];
143
+ const ctx = {
144
+ ui: {
145
+ notify: () => {},
146
+ select: async (_label: string, options: string[]) => {
147
+ const response = selectResponses.shift();
148
+ if (response === undefined) {
149
+ throw new Error(
150
+ `Unexpected extra select prompt in handlePrefsWizard flow: selectResponses queue exhausted for "${_label}" ` +
151
+ "(expected no additional select prompts)",
152
+ );
153
+ }
154
+ if (response === "Advanced") {
155
+ const advancedOption = options.find((option) => option.startsWith("Advanced"));
156
+ if (!advancedOption) {
157
+ throw new Error(`Expected an "Advanced" option in "${_label}" menu`);
158
+ }
159
+ return advancedOption;
160
+ }
161
+ return response;
162
+ },
163
+ input: async () => {
164
+ const response = inputResponses.shift();
165
+ if (response === undefined) {
166
+ throw new Error(
167
+ "Unexpected extra input prompt in handlePrefsWizard flow: inputResponses queue exhausted " +
168
+ "(expected no additional input prompts)",
169
+ );
170
+ }
171
+ return response;
172
+ },
173
+ },
174
+ waitForIdle: async () => {},
175
+ reload: async () => {},
176
+ };
177
+
178
+ await handlePrefsWizard(ctx as any, "project", {}, { pathOverride: path });
179
+
180
+ assert.equal(selectResponses.length, 0, "Expected all queued selectResponses to be consumed");
181
+ assert.equal(inputResponses.length, 0, "Expected all queued inputResponses to be consumed");
182
+ const content = readFileSync(path, "utf-8");
183
+ assert.match(content, /^min_request_interval_ms:\s*250$/m);
184
+ } finally {
185
+ rmSync(tmp, { recursive: true, force: true });
186
+ }
187
+ });
188
+
126
189
  // ─── Regression tests from #4457 codex adversarial review ──────────────────
127
190
 
128
191
  test("init — Step 9b shape: 'not_yet' option is recognized as defer (#4457 review)", async () => {
@@ -7,7 +7,7 @@
7
7
 
8
8
  import { describe, test, afterEach } from "node:test";
9
9
  import assert from "node:assert/strict";
10
- import { mkdtempSync, mkdirSync, writeFileSync, rmSync, existsSync, realpathSync } from "node:fs";
10
+ import { mkdtempSync, mkdirSync, writeFileSync, rmSync, existsSync, realpathSync, symlinkSync } from "node:fs";
11
11
  import { join } from "node:path";
12
12
  import { tmpdir } from "node:os";
13
13
  import { execSync } from "node:child_process";
@@ -21,6 +21,7 @@ import {
21
21
  getAutoWorktreeOriginalBase,
22
22
  getActiveAutoWorktreeContext,
23
23
  syncGsdStateToWorktree,
24
+ _resetAutoWorktreeOriginalBaseForTests,
24
25
  } from "../../auto-worktree.ts";
25
26
 
26
27
  // Note: execSync is used intentionally in tests for git operations with
@@ -142,6 +143,54 @@ describe("auto-worktree lifecycle", () => {
142
143
  teardownAutoWorktree(tempDir, "M003");
143
144
  });
144
145
 
146
+ test("symlink-resolved auto worktree is detected after module state reset", () => {
147
+ tempDir = createTempRepo();
148
+ const savedGsdHome = process.env.GSD_HOME;
149
+ const fakeHome = realpathSync(mkdtempSync(join(tmpdir(), "auto-wt-home-")));
150
+ const storage = join(fakeHome, ".gsd", "projects", "abc123def456");
151
+ mkdirSync(join(storage, "milestones", "M001"), { recursive: true });
152
+ writeFileSync(join(storage, "milestones", "M001", "CONTEXT.md"), "# M001\n");
153
+ symlinkSync(storage, join(tempDir, ".gsd"));
154
+ process.env.GSD_HOME = join(fakeHome, ".gsd");
155
+
156
+ try {
157
+ const wtPath = createAutoWorktree(tempDir, "M001");
158
+ const realWtPath = realpathSync(wtPath);
159
+ assert.ok(realWtPath.startsWith(storage), "git registered the symlink-resolved worktree path");
160
+
161
+ _resetAutoWorktreeOriginalBaseForTests();
162
+ process.chdir(join(realWtPath, ".gsd", "milestones", "M001"));
163
+
164
+ assert.ok(isInAutoWorktree(tempDir), "structural detection works without module originalBase");
165
+ const resolved = getAutoWorktreePath(realWtPath, "M001");
166
+ assert.ok(resolved, "existing worktree is found when basePath is the worktree path");
167
+ assert.equal(realpathSync(resolved!), realWtPath);
168
+ assert.equal(existsSync(join(realWtPath, ".gsd", "worktrees", "M001")), false);
169
+
170
+ enterAutoWorktree(tempDir, "M001");
171
+ process.chdir(join(realWtPath, ".gsd", "milestones", "M001"));
172
+ assert.deepStrictEqual(
173
+ getActiveAutoWorktreeContext(),
174
+ {
175
+ originalBase: tempDir,
176
+ worktreeName: "M001",
177
+ branch: "milestone/M001",
178
+ },
179
+ "active context is detected from a symlink-resolved worktree cwd",
180
+ );
181
+ } finally {
182
+ process.chdir(tempDir);
183
+ try {
184
+ teardownAutoWorktree(tempDir, "M001");
185
+ } catch {
186
+ // Best-effort cleanup for partially-created temp worktrees.
187
+ }
188
+ if (savedGsdHome === undefined) delete process.env.GSD_HOME;
189
+ else process.env.GSD_HOME = savedGsdHome;
190
+ rmSync(fakeHome, { recursive: true, force: true });
191
+ }
192
+ });
193
+
145
194
  test("coexistence with manual worktree", async () => {
146
195
  tempDir = createTempRepo();
147
196
  const msDir = join(tempDir, ".gsd", "milestones", "M003");
@@ -345,4 +394,26 @@ describe("auto-worktree lifecycle", () => {
345
394
  teardownAutoWorktree(tempDir, "M003");
346
395
  }
347
396
  });
397
+
398
+ test("#2482: throws GSDError when repo has no commits", () => {
399
+ // Create a bare git init with no commits — HEAD is invalid
400
+ tempDir = realpathSync(mkdtempSync(join(tmpdir(), "auto-wt-empty-")));
401
+ run("git init", tempDir);
402
+ run("git config user.email test@test.com", tempDir);
403
+ run("git config user.name Test", tempDir);
404
+
405
+ assert.throws(
406
+ () => createAutoWorktree(tempDir, "M001"),
407
+ (err: unknown) => {
408
+ assert.ok(err instanceof Error, "should throw an Error");
409
+ assert.ok("code" in err, "should have a code property (GSDError)");
410
+ assert.strictEqual((err as { code: string }).code, "GSD_GIT_ERROR");
411
+ assert.ok(
412
+ err.message.includes("repository has no commits yet"),
413
+ `message should mention no commits, got: ${err.message}`,
414
+ );
415
+ return true;
416
+ },
417
+ );
418
+ });
348
419
  });
@@ -338,27 +338,4 @@ console.log('\n=== token-savings: quality — correct scoping, no cross-contamin
338
338
  rmSync(base, { recursive: true, force: true });
339
339
  }
340
340
 
341
- // ═══════════════════════════════════════════════════════════════════════════
342
- // Test: Fixture data realism — sufficient volume and distribution
343
- // ═══════════════════════════════════════════════════════════════════════════
344
-
345
- console.log('\n=== token-savings: fixture data realism ===');
346
- {
347
- // Verify fixture generators produce sufficient volume
348
- assert.ok(DECISIONS_COUNT >= 20, `decisions count ≥ 20 (actual: ${DECISIONS_COUNT})`);
349
- assert.ok(REQUIREMENTS_COUNT >= 20, `requirements count ≥ 20 (actual: ${REQUIREMENTS_COUNT})`);
350
- assert.ok(MILESTONES.length >= 3, `milestones ≥ 3 (actual: ${MILESTONES.length})`);
351
- assert.ok(SLICE_ASSIGNMENTS.length >= 5, `slice assignments ≥ 5 (actual: ${SLICE_ASSIGNMENTS.length})`);
352
-
353
- // Verify markdown content is substantial
354
- assert.ok(decisionsMarkdown.length > 1000, `decisions markdown > 1000 chars (actual: ${decisionsMarkdown.length})`);
355
- assert.ok(requirementsMarkdown.length > 1000, `requirements markdown > 1000 chars (actual: ${requirementsMarkdown.length})`);
356
-
357
- // Verify content structure
358
- assert.match(decisionsMarkdown, /\| D001 \|/, 'decisions markdown has D001');
359
- assert.match(decisionsMarkdown, /\| D024 \|/, 'decisions markdown has D024');
360
- assert.match(requirementsMarkdown, /### R001/, 'requirements markdown has R001');
361
- assert.match(requirementsMarkdown, /### R021/, 'requirements markdown has R021');
362
- }
363
-
364
341
  // ─── Report ────────────────────────────────────────────────────────────────
@@ -4,6 +4,11 @@ import {
4
4
  isDbAvailable,
5
5
  _getAdapter,
6
6
  } from '../gsd-db.ts';
7
+ import {
8
+ _resetLogs,
9
+ peekLogs,
10
+ setStderrLoggingEnabled,
11
+ } from '../workflow-logger.ts';
7
12
  import {
8
13
  getActiveMemories,
9
14
  getActiveMemoriesRanked,
@@ -329,3 +334,126 @@ test('memory-store: schema includes memories table', () => {
329
334
 
330
335
  closeDatabase();
331
336
  });
337
+
338
+ // ═══════════════════════════════════════════════════════════════════════════
339
+ // regression #4967 — createMemory must not silently swallow SQL errors
340
+ // ═══════════════════════════════════════════════════════════════════════════
341
+
342
+ test('memory-store: createMemory throws on memory-table SQL errors (regression #4967)', () => {
343
+ openDatabase(':memory:');
344
+
345
+ const adapter = _getAdapter()!;
346
+ // Drop FTS + dependents first to satisfy SQLite's trigger ordering, then
347
+ // the base memories table. IF EXISTS makes setup robust against schema
348
+ // versions that may not have created every dependent (e.g. embeddings).
349
+ adapter.prepare('DROP TABLE IF EXISTS memory_embeddings').run();
350
+ adapter.prepare('DROP TABLE IF EXISTS memories_fts').run();
351
+ adapter.prepare('DROP TABLE IF EXISTS memories').run();
352
+
353
+ // Pre-fix behaviour: returns null and the caller has no idea why.
354
+ // Post-fix behaviour: throws so the caller can surface the real SQL message.
355
+ assert.throws(
356
+ () => createMemory({ category: 'gotcha', content: 'broken store' }),
357
+ /memories|no such table/i,
358
+ 'createMemory must surface SQL errors instead of returning null',
359
+ );
360
+
361
+ closeDatabase();
362
+ });
363
+
364
+ test('memory-store: VACUUM retry rolls back partial memory and logs recovery', () => {
365
+ openDatabase(':memory:');
366
+
367
+ const adapter = _getAdapter()!;
368
+ const originalPrepareMethod = adapter.prepare;
369
+ const originalPrepare = adapter.prepare.bind(adapter);
370
+ const previousStderrLogging = setStderrLoggingEnabled(false);
371
+ const streamAny = process.stderr as unknown as {
372
+ write: (chunk: string | Uint8Array, ...rest: unknown[]) => boolean;
373
+ };
374
+ const originalStderrWrite = streamAny.write.bind(streamAny);
375
+ let selectFailures = 0;
376
+ let vacuumRuns = 0;
377
+ _resetLogs();
378
+
379
+ adapter.prepare = ((sql: string) => {
380
+ if (sql === 'SELECT seq FROM memories WHERE id = :id' && selectFailures === 0) {
381
+ const stmt = originalPrepare(sql);
382
+ return {
383
+ run: (...params: unknown[]) => stmt.run(...params),
384
+ get: (..._params: unknown[]) => {
385
+ selectFailures++;
386
+ throw new Error('database disk image is malformed');
387
+ },
388
+ all: (...params: unknown[]) => stmt.all(...params),
389
+ };
390
+ }
391
+
392
+ if (sql === 'VACUUM') {
393
+ const stmt = originalPrepare(sql);
394
+ return {
395
+ run: (...params: unknown[]) => {
396
+ vacuumRuns++;
397
+ return stmt.run(...params);
398
+ },
399
+ get: (...params: unknown[]) => stmt.get(...params),
400
+ all: (...params: unknown[]) => stmt.all(...params),
401
+ };
402
+ }
403
+
404
+ return originalPrepare(sql);
405
+ }) as typeof adapter.prepare;
406
+ streamAny.write = (): boolean => true;
407
+
408
+ try {
409
+ const id = createMemory({ category: 'gotcha', content: 'recover without duplicate' });
410
+ assert.equal(id, 'MEM001', 'retry should create a single first memory');
411
+
412
+ const rows = adapter.prepare('SELECT id FROM memories ORDER BY seq').all();
413
+ assert.deepStrictEqual(
414
+ rows.map((row) => row['id']),
415
+ ['MEM001'],
416
+ 'failed first attempt should not leave a live _TMP_ memory behind',
417
+ );
418
+ assert.equal(selectFailures, 1, 'test should simulate one malformed SELECT after INSERT');
419
+ assert.equal(vacuumRuns, 1, 'malformed recovery should run VACUUM once');
420
+ assert.ok(
421
+ peekLogs().some((entry) =>
422
+ entry.component === 'memory-store' &&
423
+ entry.message === 'recovered malformed memory store via VACUUM'
424
+ ),
425
+ 'successful VACUUM recovery should be emitted to the workflow logger',
426
+ );
427
+ } finally {
428
+ adapter.prepare = originalPrepareMethod;
429
+ streamAny.write = originalStderrWrite;
430
+ setStderrLoggingEnabled(previousStderrLogging);
431
+ _resetLogs();
432
+ closeDatabase();
433
+ }
434
+ });
435
+
436
+ test('memory-store: applyMemoryActions stays non-fatal when memory store is broken (regression #4967)', () => {
437
+ openDatabase(':memory:');
438
+
439
+ const adapter = _getAdapter()!;
440
+ // Drop FTS + dependents first to satisfy SQLite's trigger ordering, then
441
+ // the base memories table. IF EXISTS makes setup robust against schema
442
+ // versions that may not have created every dependent (e.g. embeddings).
443
+ adapter.prepare('DROP TABLE IF EXISTS memory_embeddings').run();
444
+ adapter.prepare('DROP TABLE IF EXISTS memories_fts').run();
445
+ adapter.prepare('DROP TABLE IF EXISTS memories').run();
446
+
447
+ // applyMemoryActions wraps createMemory in a transaction with an outer
448
+ // catch. Even with createMemory now throwing, applyMemoryActions must not
449
+ // crash the auto-mode flow that calls it (memory extraction is best-effort).
450
+ const actions: MemoryAction[] = [
451
+ { action: 'CREATE', category: 'gotcha', content: 'inside-transaction call' },
452
+ ];
453
+ assert.doesNotThrow(
454
+ () => applyMemoryActions(actions),
455
+ 'applyMemoryActions must absorb thrown errors so callers continue',
456
+ );
457
+
458
+ closeDatabase();
459
+ });