zidane 7.2.5 → 8.0.4

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 (376) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +34 -6
  3. package/dist/{acp-D-tVyUjw.js → acp-DQDhi2dj.js} +230 -77
  4. package/dist/acp-DQDhi2dj.js.map +1 -0
  5. package/dist/acp-cli.d.ts +1 -1
  6. package/dist/acp-cli.js +9 -66
  7. package/dist/acp-cli.js.map +1 -1
  8. package/dist/acp.d.ts +10 -590
  9. package/dist/acp.d.ts.map +1 -1
  10. package/dist/acp.js +3 -3
  11. package/dist/{agent-D0zZnGbt.js → agent-DSLNmBp0.js} +14401 -13214
  12. package/dist/agent-DSLNmBp0.js.map +1 -0
  13. package/dist/agent.d.ts +1 -1
  14. package/dist/agent.js +3 -2
  15. package/dist/aliasing-lVFbm81n.js +217 -0
  16. package/dist/aliasing-lVFbm81n.js.map +1 -0
  17. package/dist/{anthropic-C2aole0G.js → anthropic-CD00LhUP.js} +1442 -1264
  18. package/dist/anthropic-CD00LhUP.js.map +1 -0
  19. package/dist/artifacts-CV2hUKnL.js.map +1 -1
  20. package/dist/{atomic-write-B7zr1ddF.js → atomic-write-Ijgf2Mhc.js} +13 -3
  21. package/dist/atomic-write-Ijgf2Mhc.js.map +1 -0
  22. package/dist/call-tool-dHlbGOIY.js +70 -0
  23. package/dist/call-tool-dHlbGOIY.js.map +1 -0
  24. package/dist/chat/pure.d.ts +372 -6
  25. package/dist/chat/pure.d.ts.map +1 -1
  26. package/dist/chat/pure.js +35 -244
  27. package/dist/chat/pure.js.map +1 -1
  28. package/dist/{approvals-DKaJZYlm.js → chat-JPJJ8uu5.js} +15879 -14631
  29. package/dist/chat-JPJJ8uu5.js.map +1 -0
  30. package/dist/chat.d.ts +4 -6
  31. package/dist/chat.js +23 -12
  32. package/dist/cli-shared-C-YCaglL.js +159 -0
  33. package/dist/cli-shared-C-YCaglL.js.map +1 -0
  34. package/dist/client-core-BQSyDALT.d.ts +2115 -0
  35. package/dist/client-core-BQSyDALT.d.ts.map +1 -0
  36. package/dist/codemode-worker.d.ts +1 -0
  37. package/dist/codemode-worker.js +155 -0
  38. package/dist/codemode-worker.js.map +1 -0
  39. package/dist/codemode.d.ts +352 -0
  40. package/dist/codemode.d.ts.map +1 -0
  41. package/dist/codemode.js +5 -0
  42. package/dist/connection-Dr-Js4yZ.d.ts +28 -0
  43. package/dist/connection-Dr-Js4yZ.d.ts.map +1 -0
  44. package/dist/connection-loop-gdh22LTI.js +112 -0
  45. package/dist/connection-loop-gdh22LTI.js.map +1 -0
  46. package/dist/context-segments-BHKlagL6.js +1016 -0
  47. package/dist/context-segments-BHKlagL6.js.map +1 -0
  48. package/dist/{context-transport-T_6AYIvy.js → context-transport-DSMTUsK1.js} +3 -3
  49. package/dist/{context-transport-T_6AYIvy.js.map → context-transport-DSMTUsK1.js.map} +1 -1
  50. package/dist/contexts/daytona.d.ts +19 -8
  51. package/dist/contexts/daytona.d.ts.map +1 -1
  52. package/dist/contexts/daytona.js +1 -440
  53. package/dist/contexts/docker.d.ts +36 -7
  54. package/dist/contexts/docker.d.ts.map +1 -1
  55. package/dist/contexts/docker.js +1 -456
  56. package/dist/contexts/e2b.d.ts +68 -13
  57. package/dist/contexts/e2b.d.ts.map +1 -1
  58. package/dist/contexts/e2b.js +1 -382
  59. package/dist/contexts/sandbox.d.ts +1 -1
  60. package/dist/contexts/sandbox.js +5 -0
  61. package/dist/contexts/sandbox.js.map +1 -1
  62. package/dist/{contexts-CRE9pw07.js → contexts-d7UolYot.js} +1059 -524
  63. package/dist/contexts-d7UolYot.js.map +1 -0
  64. package/dist/contexts.d.ts +3 -3
  65. package/dist/contexts.js +1 -1
  66. package/dist/cred-keys-GpBg71cP.js +105 -0
  67. package/dist/cred-keys-GpBg71cP.js.map +1 -0
  68. package/dist/{auth-BG2rVKSt.js → credentials-JttEuRON.js} +55 -206
  69. package/dist/credentials-JttEuRON.js.map +1 -0
  70. package/dist/{cursor-iojRXHF9.js → cursor-CdjaQTBW.js} +3 -3
  71. package/dist/{cursor-iojRXHF9.js.map → cursor-CdjaQTBW.js.map} +1 -1
  72. package/dist/daemon-cli.d.ts +1 -1
  73. package/dist/daemon-cli.js +3 -2
  74. package/dist/daemon-cli.js.map +1 -1
  75. package/dist/daytona-DG3omipZ.js +513 -0
  76. package/dist/daytona-DG3omipZ.js.map +1 -0
  77. package/dist/defaults-Cx3zvDOV.js +23 -0
  78. package/dist/defaults-Cx3zvDOV.js.map +1 -0
  79. package/dist/dispatcher-BMlu2BmZ.js +4941 -0
  80. package/dist/dispatcher-BMlu2BmZ.js.map +1 -0
  81. package/dist/docker-BZhMMJUp.js +727 -0
  82. package/dist/docker-BZhMMJUp.js.map +1 -0
  83. package/dist/e2b-CEVOdRib.js +480 -0
  84. package/dist/e2b-CEVOdRib.js.map +1 -0
  85. package/dist/edit-utils-EGosADZq.js +234 -0
  86. package/dist/edit-utils-EGosADZq.js.map +1 -0
  87. package/dist/environment-8wsKE2Ln.js +214 -0
  88. package/dist/environment-8wsKE2Ln.js.map +1 -0
  89. package/dist/eval-BNcvle_J.js +1595 -0
  90. package/dist/eval-BNcvle_J.js.map +1 -0
  91. package/dist/eval.d.ts +2 -2
  92. package/dist/eval.js +1 -1489
  93. package/dist/executor-Cx5-8yqi.js +621 -0
  94. package/dist/executor-Cx5-8yqi.js.map +1 -0
  95. package/dist/extension-authoring-DyGGmq9V.js +385 -0
  96. package/dist/extension-authoring-DyGGmq9V.js.map +1 -0
  97. package/dist/extensions.d.ts +2 -2
  98. package/dist/extensions.js +3 -3
  99. package/dist/{fetch-url-DX75gpL0.js → fetch-url-Ct2TjDWt.js} +4 -4
  100. package/dist/{fetch-url-DX75gpL0.js.map → fetch-url-Ct2TjDWt.js.map} +1 -1
  101. package/dist/{format-BF745pLL.js → format-C2NQEVUH.js} +39 -2
  102. package/dist/format-C2NQEVUH.js.map +1 -0
  103. package/dist/format-bytes-C7tfc3Zm.js +55 -0
  104. package/dist/format-bytes-C7tfc3Zm.js.map +1 -0
  105. package/dist/headless-C_rNUuYC.js +960 -0
  106. package/dist/headless-C_rNUuYC.js.map +1 -0
  107. package/dist/headless.d.ts +1 -1
  108. package/dist/headless.js +1 -413
  109. package/dist/{history-search-C4bk1Wz_.js → history-search-CcYzF8-0.js} +7 -3
  110. package/dist/history-search-CcYzF8-0.js.map +1 -0
  111. package/dist/history-search-worker.d.ts +1 -1
  112. package/dist/history-search-worker.js +1 -1
  113. package/dist/host-D7NrI03V.js +378 -0
  114. package/dist/host-D7NrI03V.js.map +1 -0
  115. package/dist/host-signals-BcP5QKUD.js +118 -0
  116. package/dist/host-signals-BcP5QKUD.js.map +1 -0
  117. package/dist/identity-CwfO8K-t.js +26 -0
  118. package/dist/identity-CwfO8K-t.js.map +1 -0
  119. package/dist/{index-BgN1T3lk.d.ts → index-BGe1fQT7.d.ts} +10987 -9320
  120. package/dist/index-BGe1fQT7.d.ts.map +1 -0
  121. package/dist/index-BVQsIKGn.d.ts +448 -0
  122. package/dist/index-BVQsIKGn.d.ts.map +1 -0
  123. package/dist/{index-C6NEd5y_.d.ts → index-CHABJd-L.d.ts} +3386 -502
  124. package/dist/index-CHABJd-L.d.ts.map +1 -0
  125. package/dist/{index-C37_ppWv.d.ts → index-D6a7qXpg.d.ts} +2 -3
  126. package/dist/index-D6a7qXpg.d.ts.map +1 -0
  127. package/dist/index.d.ts +6 -6
  128. package/dist/index.js +27 -23
  129. package/dist/{completion-core-BRo86R_L.js → inline-ghost-BVRQeGoL.js} +50 -2
  130. package/dist/inline-ghost-BVRQeGoL.js.map +1 -0
  131. package/dist/ipc/remote.d.ts +313 -0
  132. package/dist/ipc/remote.d.ts.map +1 -0
  133. package/dist/ipc/remote.js +4 -0
  134. package/dist/ipc.d.ts +6 -964
  135. package/dist/ipc.js +403 -4
  136. package/dist/ipc.js.map +1 -0
  137. package/dist/{isolation-Kfoof0MM.d.ts → isolation-D9L650W5.d.ts} +100 -15
  138. package/dist/isolation-D9L650W5.d.ts.map +1 -0
  139. package/dist/json-rpc--HXQti1E.js +350 -0
  140. package/dist/json-rpc--HXQti1E.js.map +1 -0
  141. package/dist/links-j8rED1sR.js +603 -0
  142. package/dist/links-j8rED1sR.js.map +1 -0
  143. package/dist/local-terminal-D8QThwo_.js +252 -0
  144. package/dist/local-terminal-D8QThwo_.js.map +1 -0
  145. package/dist/{logger--C1VQjwJ.js → logger-Gtqlayx8.js} +199 -173
  146. package/dist/logger-Gtqlayx8.js.map +1 -0
  147. package/dist/logs-view-CWG8aUAG.js.map +1 -1
  148. package/dist/{mcp-CgNd-f3F.js → mcp-_wecH9Qe.js} +608 -562
  149. package/dist/mcp-_wecH9Qe.js.map +1 -0
  150. package/dist/mcp.d.ts +2 -2
  151. package/dist/mcp.js +2 -2
  152. package/dist/media-sniff-UKijEaiQ.js.map +1 -1
  153. package/dist/{messages-2jcOA_5R.js → messages-BqiwcD2Q.js} +1017 -1014
  154. package/dist/messages-BqiwcD2Q.js.map +1 -0
  155. package/dist/{oauth-DxHO17JE.js → oauth-Px_pBB9W.js} +5 -5
  156. package/dist/{oauth-DxHO17JE.js.map → oauth-Px_pBB9W.js.map} +1 -1
  157. package/dist/{openai-compat-Dy56weK8.js → openai-compat-CFrpH7uq.js} +432 -589
  158. package/dist/openai-compat-CFrpH7uq.js.map +1 -0
  159. package/dist/orchestration-BCGmB8Ps.js +511 -0
  160. package/dist/orchestration-BCGmB8Ps.js.map +1 -0
  161. package/dist/output/stream-json.d.ts +1 -2
  162. package/dist/output/stream-json.d.ts.map +1 -1
  163. package/dist/output/stream-json.js +1 -1
  164. package/dist/output/terminal.d.ts +1 -2
  165. package/dist/output/terminal.d.ts.map +1 -1
  166. package/dist/output/terminal.js +13 -7
  167. package/dist/output/terminal.js.map +1 -1
  168. package/dist/{plugins-gbI7SBA6.js → plugins-DS7mahzZ.js} +20 -101
  169. package/dist/plugins-DS7mahzZ.js.map +1 -0
  170. package/dist/plugins.d.ts +1 -1
  171. package/dist/plugins.js +1 -2
  172. package/dist/prelude-Cxo4t74B.js +517 -0
  173. package/dist/prelude-Cxo4t74B.js.map +1 -0
  174. package/dist/presets.d.ts +1 -1
  175. package/dist/presets.js +1 -2
  176. package/dist/project-root-B8zADr4o.js +167 -0
  177. package/dist/project-root-B8zADr4o.js.map +1 -0
  178. package/dist/project-user-paths-BSgtrRxl.js +58 -0
  179. package/dist/project-user-paths-BSgtrRxl.js.map +1 -0
  180. package/dist/{prompts-Pqc3JdW_.d.ts → prompts-DYcvqShf.d.ts} +14 -11
  181. package/dist/prompts-DYcvqShf.d.ts.map +1 -0
  182. package/dist/protocol-DnhqqSmE.js +13 -0
  183. package/dist/protocol-DnhqqSmE.js.map +1 -0
  184. package/dist/providers/anthropic.d.ts +2 -2
  185. package/dist/providers/anthropic.js +1 -2
  186. package/dist/providers/arcee.d.ts +1 -1
  187. package/dist/providers/arcee.js +1 -1
  188. package/dist/providers/baseten.d.ts +1 -1
  189. package/dist/providers/baseten.js +1 -1
  190. package/dist/providers/cerebras.d.ts +1 -1
  191. package/dist/providers/cerebras.js +3 -2
  192. package/dist/providers/cerebras.js.map +1 -1
  193. package/dist/providers/local.d.ts +1 -1
  194. package/dist/providers/local.js +1 -1
  195. package/dist/providers/openai-compat.d.ts +1 -1
  196. package/dist/providers/openai-compat.js +1 -2
  197. package/dist/providers/openai.d.ts +1 -1
  198. package/dist/providers/openai.js +15 -12
  199. package/dist/providers/openai.js.map +1 -1
  200. package/dist/providers/openrouter.d.ts +1 -1
  201. package/dist/providers/openrouter.js +3 -2
  202. package/dist/providers/openrouter.js.map +1 -1
  203. package/dist/providers/xai.d.ts +1 -1
  204. package/dist/providers/xai.js +3 -3
  205. package/dist/{providers-BVhnFyiY.js → providers-XUR7F4Hi.js} +4 -4
  206. package/dist/{providers-BVhnFyiY.js.map → providers-XUR7F4Hi.js.map} +1 -1
  207. package/dist/providers.d.ts +1 -1
  208. package/dist/providers.js +4 -4
  209. package/dist/registry-D6ShBWJU.js +5234 -0
  210. package/dist/registry-D6ShBWJU.js.map +1 -0
  211. package/dist/remote-hosts-BtA_9ZGp.js +97 -0
  212. package/dist/remote-hosts-BtA_9ZGp.js.map +1 -0
  213. package/dist/restate.d.ts +2 -3
  214. package/dist/restate.d.ts.map +1 -1
  215. package/dist/restate.js +631 -572
  216. package/dist/restate.js.map +1 -1
  217. package/dist/run-summary-CklLiZ4y.js +288 -0
  218. package/dist/run-summary-CklLiZ4y.js.map +1 -0
  219. package/dist/{sandbox-BH0WQkXn.d.ts → sandbox-C5dR5DwQ.d.ts} +6 -3
  220. package/dist/sandbox-C5dR5DwQ.d.ts.map +1 -0
  221. package/dist/session/sqlite.d.ts +1 -2
  222. package/dist/session/sqlite.d.ts.map +1 -1
  223. package/dist/session/sqlite.js +1 -616
  224. package/dist/session-factory-BUGY5P40.js +1576 -0
  225. package/dist/session-factory-BUGY5P40.js.map +1 -0
  226. package/dist/{session-BqRP1hS7.js → session-xh9JXu6i.js} +94 -52
  227. package/dist/session-xh9JXu6i.js.map +1 -0
  228. package/dist/session.d.ts +1 -1
  229. package/dist/session.js +2 -2
  230. package/dist/settings-keys-Ckf29NeM.js +677 -0
  231. package/dist/settings-keys-Ckf29NeM.js.map +1 -0
  232. package/dist/shell-path-Dqaoow2J.js +412 -0
  233. package/dist/shell-path-Dqaoow2J.js.map +1 -0
  234. package/dist/{skills-BC3dodWp.js → skills-DKqZJm4X.js} +430 -470
  235. package/dist/skills-DKqZJm4X.js.map +1 -0
  236. package/dist/skills.d.ts +2 -2
  237. package/dist/skills.js +1 -2
  238. package/dist/source-mPExaUm8.js +381 -0
  239. package/dist/source-mPExaUm8.js.map +1 -0
  240. package/dist/sqlite-DV1DQzN2.js +698 -0
  241. package/dist/sqlite-DV1DQzN2.js.map +1 -0
  242. package/dist/{src-CkNQKFKr.js → src-BRMYRJib.js} +903 -1121
  243. package/dist/src-BRMYRJib.js.map +1 -0
  244. package/dist/{stdio-DPpBDPx5.js → stdio-C6YyoW3I.js} +4 -4
  245. package/dist/{stdio-DPpBDPx5.js.map → stdio-C6YyoW3I.js.map} +1 -1
  246. package/dist/{stdio-loader-Bbx19dMZ.js → stdio-loader-C830Vg-Z.js} +4 -4
  247. package/dist/{stdio-loader-Bbx19dMZ.js.map → stdio-loader-C830Vg-Z.js.map} +1 -1
  248. package/dist/system-prompt-MNVHatSD.d.ts.map +1 -1
  249. package/dist/timeout-DEaqslLO.d.ts.map +1 -1
  250. package/dist/todo-edits-Dn251YUP.js +1790 -0
  251. package/dist/todo-edits-Dn251YUP.js.map +1 -0
  252. package/dist/{turn-operations-DrbJlpq9.js → tool-formatters-IQFDrdrs.js} +1456 -2120
  253. package/dist/tool-formatters-IQFDrdrs.js.map +1 -0
  254. package/dist/tool-state-Dku6YqAB.js +989 -0
  255. package/dist/tool-state-Dku6YqAB.js.map +1 -0
  256. package/dist/tools/fetch-url.d.ts +1 -2
  257. package/dist/tools/fetch-url.d.ts.map +1 -1
  258. package/dist/tools/fetch-url.js +1 -2
  259. package/dist/tools/prompts.d.ts +1 -1
  260. package/dist/tools/prompts.js +7 -7
  261. package/dist/tools/prompts.js.map +1 -1
  262. package/dist/tools/web-search.d.ts +1 -2
  263. package/dist/tools/web-search.d.ts.map +1 -1
  264. package/dist/tools/web-search.js +2 -2
  265. package/dist/tools/web-search.js.map +1 -1
  266. package/dist/tools-_DnT3AGM.js +578 -0
  267. package/dist/tools-_DnT3AGM.js.map +1 -0
  268. package/dist/tools.d.ts +3 -3
  269. package/dist/tools.js +4 -2
  270. package/dist/tui.d.ts +534 -517
  271. package/dist/tui.d.ts.map +1 -1
  272. package/dist/tui.js +34933 -27243
  273. package/dist/tui.js.map +1 -1
  274. package/dist/turn-operations-B8sokwi5.js +333 -0
  275. package/dist/turn-operations-B8sokwi5.js.map +1 -0
  276. package/dist/turn-operations-DQX5ZZni.d.ts +3089 -0
  277. package/dist/turn-operations-DQX5ZZni.d.ts.map +1 -0
  278. package/dist/types-C7ZFOztE.d.ts +132 -0
  279. package/dist/types-C7ZFOztE.d.ts.map +1 -0
  280. package/dist/types-CH5XpIHw.js +114 -0
  281. package/dist/types-CH5XpIHw.js.map +1 -0
  282. package/dist/{types-CWgENVLY.js → types-Cu0ZGDu9.js} +10 -6
  283. package/dist/types-Cu0ZGDu9.js.map +1 -0
  284. package/dist/types-IqegbJEE.d.ts +624 -0
  285. package/dist/types-IqegbJEE.d.ts.map +1 -0
  286. package/dist/types.d.ts +4 -4
  287. package/dist/types.js +1 -1
  288. package/dist/url-D8HCl65b.js +1259 -0
  289. package/dist/url-D8HCl65b.js.map +1 -0
  290. package/dist/wasm-BVT-j5cl.js +33 -0
  291. package/dist/wasm-BVT-j5cl.js.map +1 -0
  292. package/dist/workspace-exec-stream-SV2R9d5S.js +355 -0
  293. package/dist/workspace-exec-stream-SV2R9d5S.js.map +1 -0
  294. package/dist/ws-CIHMvlSh.js +952 -0
  295. package/dist/ws-CIHMvlSh.js.map +1 -0
  296. package/dist/ws-client-N7NxzvQp.js +230 -0
  297. package/dist/ws-client-N7NxzvQp.js.map +1 -0
  298. package/dist/{xai-CazjStOK.js → xai-CvJTeLrI.js} +165 -5
  299. package/dist/xai-CvJTeLrI.js.map +1 -0
  300. package/dist/xdg-zweed0-t.js +117 -0
  301. package/dist/xdg-zweed0-t.js.map +1 -0
  302. package/docs/ACP.md +52 -0
  303. package/docs/ARCHITECTURE.md +103 -6
  304. package/docs/ARTIFACTS.md +8 -4
  305. package/docs/CHAT.md +165 -14
  306. package/docs/EXECUTION_CONTEXT.md +8 -0
  307. package/docs/EXTENSIONS.md +123 -2
  308. package/docs/HEADLESS.md +2 -0
  309. package/docs/IPC.md +775 -64
  310. package/docs/MACHINES.md +456 -0
  311. package/docs/PANELS.md +3 -0
  312. package/docs/README.md +4 -0
  313. package/docs/RESTATE.md +3 -2
  314. package/docs/RUN_IN_BACKGROUND.md +10 -2
  315. package/docs/SERVER.md +1085 -0
  316. package/docs/SKILL.md +6 -1
  317. package/docs/TERMINAL.md +75 -0
  318. package/docs/TUI.md +65 -14
  319. package/package.json +58 -26
  320. package/scripts/eval.ts +4 -0
  321. package/dist/acp-D-tVyUjw.js.map +0 -1
  322. package/dist/agent-D0zZnGbt.js.map +0 -1
  323. package/dist/anthropic-C2aole0G.js.map +0 -1
  324. package/dist/approvals-DKaJZYlm.js.map +0 -1
  325. package/dist/atomic-write-B7zr1ddF.js.map +0 -1
  326. package/dist/auth-BG2rVKSt.js.map +0 -1
  327. package/dist/completion-core-BRo86R_L.js.map +0 -1
  328. package/dist/contexts/daytona.js.map +0 -1
  329. package/dist/contexts/docker.js.map +0 -1
  330. package/dist/contexts/e2b.js.map +0 -1
  331. package/dist/contexts-CRE9pw07.js.map +0 -1
  332. package/dist/eval.js.map +0 -1
  333. package/dist/format-BF745pLL.js.map +0 -1
  334. package/dist/glob-DluQFSw1.js +0 -270
  335. package/dist/glob-DluQFSw1.js.map +0 -1
  336. package/dist/headless.js.map +0 -1
  337. package/dist/history-search-C4bk1Wz_.js.map +0 -1
  338. package/dist/index-BgN1T3lk.d.ts.map +0 -1
  339. package/dist/index-C37_ppWv.d.ts.map +0 -1
  340. package/dist/index-C6NEd5y_.d.ts.map +0 -1
  341. package/dist/ipc-BKVIIOqH.js +0 -331
  342. package/dist/ipc-BKVIIOqH.js.map +0 -1
  343. package/dist/ipc.d.ts.map +0 -1
  344. package/dist/isolation-Kfoof0MM.d.ts.map +0 -1
  345. package/dist/json-rpc-rSWMUh9b.js +0 -192
  346. package/dist/json-rpc-rSWMUh9b.js.map +0 -1
  347. package/dist/logger--C1VQjwJ.js.map +0 -1
  348. package/dist/mcp-CgNd-f3F.js.map +0 -1
  349. package/dist/messages-2jcOA_5R.js.map +0 -1
  350. package/dist/openai-compat-Dy56weK8.js.map +0 -1
  351. package/dist/output-cap-C9zukcCj.js +0 -100
  352. package/dist/output-cap-C9zukcCj.js.map +0 -1
  353. package/dist/panels-B6gRk4bf.js +0 -789
  354. package/dist/panels-B6gRk4bf.js.map +0 -1
  355. package/dist/plugins-gbI7SBA6.js.map +0 -1
  356. package/dist/prompts-Pqc3JdW_.d.ts.map +0 -1
  357. package/dist/run-summary-BU_NgwUT.js +0 -269
  358. package/dist/run-summary-BU_NgwUT.js.map +0 -1
  359. package/dist/sandbox-BH0WQkXn.d.ts.map +0 -1
  360. package/dist/session/sqlite.js.map +0 -1
  361. package/dist/session-BqRP1hS7.js.map +0 -1
  362. package/dist/shell-path-DfdXrGg9.js +0 -1549
  363. package/dist/shell-path-DfdXrGg9.js.map +0 -1
  364. package/dist/skills-BC3dodWp.js.map +0 -1
  365. package/dist/src-CkNQKFKr.js.map +0 -1
  366. package/dist/todo-edits-UOwgxGKu.js +0 -528
  367. package/dist/todo-edits-UOwgxGKu.js.map +0 -1
  368. package/dist/tool-formatters-DoRLnfuD.d.ts +0 -759
  369. package/dist/tool-formatters-DoRLnfuD.d.ts.map +0 -1
  370. package/dist/transcript-anchors-BeudMbXx.d.ts +0 -1762
  371. package/dist/transcript-anchors-BeudMbXx.d.ts.map +0 -1
  372. package/dist/turn-operations-C8bMBDl_.d.ts +0 -1258
  373. package/dist/turn-operations-C8bMBDl_.d.ts.map +0 -1
  374. package/dist/turn-operations-DrbJlpq9.js.map +0 -1
  375. package/dist/types-CWgENVLY.js.map +0 -1
  376. package/dist/xai-CazjStOK.js.map +0 -1
@@ -0,0 +1,698 @@
1
+ import { u as errorMessage } from "./errors-DKiMrOKq.js";
2
+ import { c as mergeArtifact, u as selectArtifactEvictions } from "./artifacts-CV2hUKnL.js";
3
+ import { i as planWorktreeProjectRootRemaps } from "./project-root-B8zADr4o.js";
4
+ import { copyFileSync, existsSync, mkdirSync } from "node:fs";
5
+ import { dirname } from "node:path";
6
+ import { Database } from "bun:sqlite";
7
+ //#region src/session/sqlite-rows.ts
8
+ const ARTIFACT_COLUMNS = "id, session_id, run_id, turn_id, kind, uri, label, project_root, meta, created_at, updated_at";
9
+ function rowToArtifact(r) {
10
+ let meta;
11
+ if (r.meta) try {
12
+ meta = JSON.parse(r.meta);
13
+ } catch {
14
+ meta = void 0;
15
+ }
16
+ return {
17
+ id: r.id,
18
+ sessionId: r.session_id,
19
+ ...r.run_id ? { runId: r.run_id } : {},
20
+ ...r.turn_id ? { turnId: r.turn_id } : {},
21
+ kind: r.kind,
22
+ uri: r.uri,
23
+ label: r.label,
24
+ ...r.project_root ? { projectRoot: r.project_root } : {},
25
+ ...meta !== void 0 ? { meta } : {},
26
+ createdAt: r.created_at,
27
+ updatedAt: r.updated_at
28
+ };
29
+ }
30
+ /**
31
+ * Compose the WHERE / LIMIT fragments shared by `list` and `listMeta`.
32
+ *
33
+ * `projectRoot: string` → `WHERE project_root = ?` (excludes untagged).
34
+ * `projectRoot: null` → `WHERE project_root IS NULL` (untagged only).
35
+ * `projectRoot: undefined` → axis omitted (untagged + tagged).
36
+ *
37
+ * The `null` case lets a future "show legacy" debug toggle query pre-v3
38
+ * sessions explicitly without leaking them into normal per-project lists.
39
+ */
40
+ function buildListFilter(filter) {
41
+ const conditions = [];
42
+ const params = [];
43
+ if (filter?.agentId) {
44
+ conditions.push("agent_id = ?");
45
+ params.push(filter.agentId);
46
+ }
47
+ if ("projectRoot" in (filter ?? {})) {
48
+ const v = filter.projectRoot;
49
+ if (v === null) conditions.push("project_root IS NULL");
50
+ else if (typeof v === "string") {
51
+ conditions.push("project_root = ?");
52
+ params.push(v);
53
+ }
54
+ }
55
+ return {
56
+ where: conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "",
57
+ limit: typeof filter?.limit === "number" && filter.limit > 0 ? `LIMIT ${filter.limit}` : "",
58
+ params
59
+ };
60
+ }
61
+ /**
62
+ * WHERE / LIMIT fragments for `listArtifacts`. `projectRoot` follows the
63
+ * same tri-state contract as {@link buildListFilter}.
64
+ */
65
+ function buildArtifactFilter(filter) {
66
+ const conditions = [];
67
+ const params = [];
68
+ if (filter?.sessionId !== void 0) {
69
+ conditions.push("session_id = ?");
70
+ params.push(filter.sessionId);
71
+ }
72
+ if (filter?.kind !== void 0) {
73
+ conditions.push("kind = ?");
74
+ params.push(filter.kind);
75
+ }
76
+ if (filter?.uri !== void 0) {
77
+ conditions.push("uri = ?");
78
+ params.push(filter.uri);
79
+ }
80
+ if (filter && "projectRoot" in filter) {
81
+ if (filter.projectRoot === null) conditions.push("project_root IS NULL");
82
+ else if (typeof filter.projectRoot === "string") {
83
+ conditions.push("project_root = ?");
84
+ params.push(filter.projectRoot);
85
+ }
86
+ }
87
+ if (typeof filter?.since === "number") {
88
+ conditions.push("updated_at >= ?");
89
+ params.push(filter.since);
90
+ }
91
+ return {
92
+ where: conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "",
93
+ limit: typeof filter?.limit === "number" && filter.limit > 0 ? `LIMIT ${filter.limit}` : "",
94
+ params
95
+ };
96
+ }
97
+ /**
98
+ * Guarded per-row parse for `turns.data` / `runs.data`. One corrupt row
99
+ * (truncated write, hand-edited DB, disk bitflip) must not make the whole
100
+ * session unloadable — log + skip it instead, mirroring the migration's
101
+ * per-row backfill policy. The structural check matches the minimal shape
102
+ * both `SessionTurn` and `SessionRun` share (an object with a string `id`).
103
+ */
104
+ function safeParseRow(text, sessionId, kind) {
105
+ try {
106
+ const parsed = JSON.parse(text);
107
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || typeof parsed.id !== "string") {
108
+ console.error(`[zidane/sqlite] session "${sessionId}": skipping malformed ${kind} row (not a ${kind}-shaped object)`);
109
+ return null;
110
+ }
111
+ return parsed;
112
+ } catch (err) {
113
+ console.error(`[zidane/sqlite] session "${sessionId}": skipping corrupt ${kind} row: ${errorMessage(err)}`);
114
+ return null;
115
+ }
116
+ }
117
+ /**
118
+ * `JSON.parse` with a fallback to `{}` for the metadata column. v3→v4
119
+ * migration writes well-formed JSON, fresh v4 writes go through
120
+ * `JSON.stringify(metadata ?? {})` — but a hand-edited DB or a botched
121
+ * external migration could leave a row with malformed JSON, and we'd
122
+ * rather surface an empty metadata object than crash the entire load
123
+ * path. Logged under `ZIDANE_DEBUG` so the corruption isn't fully
124
+ * silent.
125
+ */
126
+ function safeParseRecord(text) {
127
+ try {
128
+ const parsed = JSON.parse(text);
129
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
130
+ } catch (err) {
131
+ if (process.env.ZIDANE_DEBUG) process.stderr.write(`[zidane/sqlite] metadata JSON parse failed, defaulting to {}: ${errorMessage(err)}\n`);
132
+ return {};
133
+ }
134
+ }
135
+ //#endregion
136
+ //#region src/session/sqlite-schema.ts
137
+ const SCHEMA_VERSION = 4;
138
+ /**
139
+ * Connection pragmas, table/index DDL, migrations, and the worktree
140
+ * project-root fix-up — everything `openSqliteStore` runs on a fresh
141
+ * connection before preparing statements.
142
+ */
143
+ function initSqliteSchema(db, dbPath) {
144
+ db.run("PRAGMA busy_timeout = 5000");
145
+ db.run("PRAGMA journal_mode = WAL");
146
+ db.run("PRAGMA foreign_keys = ON");
147
+ db.run(`
148
+ CREATE TABLE IF NOT EXISTS sessions (
149
+ id TEXT PRIMARY KEY,
150
+ agent_id TEXT,
151
+ project_root TEXT,
152
+ status TEXT NOT NULL DEFAULT 'idle',
153
+ metadata TEXT NOT NULL DEFAULT '{}',
154
+ created_at INTEGER NOT NULL,
155
+ updated_at INTEGER NOT NULL,
156
+ rev INTEGER NOT NULL DEFAULT 0
157
+ )
158
+ `);
159
+ db.run(`CREATE INDEX IF NOT EXISTS idx_sessions_agent_id ON sessions(agent_id)`);
160
+ db.run(`CREATE INDEX IF NOT EXISTS idx_sessions_project_root ON sessions(project_root)`);
161
+ db.run(`
162
+ CREATE TABLE IF NOT EXISTS turns (
163
+ session_id TEXT NOT NULL,
164
+ seq INTEGER NOT NULL,
165
+ role TEXT,
166
+ data TEXT NOT NULL,
167
+ PRIMARY KEY (session_id, seq),
168
+ FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
169
+ )
170
+ `);
171
+ db.run(`
172
+ CREATE TABLE IF NOT EXISTS runs (
173
+ session_id TEXT NOT NULL,
174
+ run_id TEXT NOT NULL,
175
+ started_at INTEGER NOT NULL,
176
+ data TEXT NOT NULL,
177
+ PRIMARY KEY (session_id, run_id),
178
+ FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
179
+ )
180
+ `);
181
+ migrate(db, dbPath);
182
+ db.run(`
183
+ CREATE TABLE IF NOT EXISTS artifacts (
184
+ id TEXT PRIMARY KEY,
185
+ session_id TEXT NOT NULL,
186
+ run_id TEXT,
187
+ turn_id TEXT,
188
+ kind TEXT NOT NULL,
189
+ uri TEXT NOT NULL,
190
+ label TEXT NOT NULL,
191
+ project_root TEXT,
192
+ meta TEXT,
193
+ created_at INTEGER NOT NULL,
194
+ updated_at INTEGER NOT NULL,
195
+ UNIQUE (session_id, kind, uri),
196
+ FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
197
+ )
198
+ `);
199
+ db.run(`CREATE INDEX IF NOT EXISTS idx_artifacts_session ON artifacts(session_id, updated_at)`);
200
+ db.run(`CREATE INDEX IF NOT EXISTS idx_artifacts_project_kind ON artifacts(project_root, kind, updated_at)`);
201
+ db.run(`CREATE INDEX IF NOT EXISTS idx_artifacts_kind_uri ON artifacts(kind, uri)`);
202
+ remapWorktreeProjectRoots(db);
203
+ }
204
+ /**
205
+ * Data fix-up, not a schema step (no `user_version` bump): rows tagged with a
206
+ * linked worktree's checkout root — how sessions started inside a worktree
207
+ * were stamped before `projectRoot` meant the main checkout — move to that
208
+ * main checkout, so they list and group with the rest of the project.
209
+ * Artifacts carry the same column and move with them.
210
+ *
211
+ * Idempotent and cheap (distinct roots are few; each probe is a couple of
212
+ * small file reads), so it runs on every open: a row a live session's stale
213
+ * full-document save wrote back under the old root converges next time.
214
+ * Best-effort — a failure here must never block opening the store.
215
+ */
216
+ function remapWorktreeProjectRoots(db) {
217
+ try {
218
+ const rows = db.query(`
219
+ SELECT project_root AS root FROM sessions WHERE project_root IS NOT NULL
220
+ UNION
221
+ SELECT project_root AS root FROM artifacts WHERE project_root IS NOT NULL
222
+ `).all();
223
+ const remaps = planWorktreeProjectRootRemaps(rows.map((row) => row.root));
224
+ if (remaps.length === 0) return;
225
+ const sessions = db.prepare("UPDATE sessions SET project_root = ? WHERE project_root = ?");
226
+ const artifacts = db.prepare("UPDATE artifacts SET project_root = ? WHERE project_root = ?");
227
+ db.transaction(() => {
228
+ for (const { from, to } of remaps) {
229
+ sessions.run(to, from);
230
+ artifacts.run(to, from);
231
+ }
232
+ })();
233
+ } catch (err) {
234
+ if (process.env.ZIDANE_DEBUG) process.stderr.write(`[zidane/sqlite] worktree project-root remap skipped: ${errorMessage(err)}\n`);
235
+ }
236
+ }
237
+ /**
238
+ * Forward-only schema migration runner. Idempotent — every step
239
+ * feature-detects rather than relying on the `PRAGMA user_version`
240
+ * number alone, so a partially-migrated DB (e.g. interrupted v3→v4
241
+ * backfill) is brought to a consistent v4 state on the next open.
242
+ *
243
+ * The legacy `data` column is the v3 sentinel: when present we treat
244
+ * the DB as v3-or-older and run the backfill. Before any destructive
245
+ * change we copy the entire DB file to `<path>.zidane-pre-v4.bak` (see
246
+ * {@link backupBeforeV3Migration}) so the user has a guaranteed
247
+ * recovery path if anything goes sideways.
248
+ *
249
+ * After backfill we attempt to drop the column (SQLite 3.35+; Bun
250
+ * ships ≥ 3.43 so this always succeeds in practice). If it does fail,
251
+ * we throw rather than limp along — leaving the column with `NOT NULL`
252
+ * while the new write paths omit it would silently break every future
253
+ * `INSERT`. The `.bak` file lets the user roll back and report the bug.
254
+ */
255
+ function migrate(db, dbPath) {
256
+ const onDiskVersion = db.query("PRAGMA user_version").get()?.user_version ?? 0;
257
+ if (onDiskVersion > SCHEMA_VERSION && onDiskVersion !== 5) throw new Error(`[zidane/sqlite] "${dbPath}" has schema version ${onDiskVersion}, but this zidane build only supports up to ${SCHEMA_VERSION}. A newer zidane wrote it. Upgrade zidane, or point this build at another sessions DB.`);
258
+ const sessionCols = db.query("PRAGMA table_info(sessions)").all();
259
+ const hasCol = (n) => sessionCols.some((c) => c.name === n);
260
+ if (!hasCol("project_root")) db.run("ALTER TABLE sessions ADD COLUMN project_root TEXT");
261
+ if (!hasCol("status")) db.run(`ALTER TABLE sessions ADD COLUMN status TEXT NOT NULL DEFAULT 'idle'`);
262
+ if (!hasCol("metadata")) db.run(`ALTER TABLE sessions ADD COLUMN metadata TEXT NOT NULL DEFAULT '{}'`);
263
+ if (hasCol("data")) {
264
+ backupBeforeV3Migration(db, dbPath);
265
+ backfillV3Blobs(db);
266
+ try {
267
+ db.run("ALTER TABLE sessions DROP COLUMN data");
268
+ } catch (err) {
269
+ throw new Error(`[zidane/sqlite] v3→v4 migration could not drop legacy "data" column: ${errorMessage(err)}. Restore from "${dbPath}.zidane-pre-v4.bak" with an older zidane build and report this. your sessions are intact in the backup file.`);
270
+ }
271
+ }
272
+ if (!db.query("PRAGMA table_info(turns)").all().some((c) => c.name === "role")) db.run("ALTER TABLE turns ADD COLUMN role TEXT");
273
+ db.run("CREATE INDEX IF NOT EXISTS idx_turns_role_null ON turns(session_id) WHERE role IS NULL");
274
+ if (db.query(`SELECT 1 FROM turns WHERE role IS NULL AND json_valid(data) LIMIT 1`).get()) db.run(`UPDATE turns SET role = json_extract(data, '$.role') WHERE role IS NULL AND json_valid(data)`);
275
+ db.run("CREATE INDEX IF NOT EXISTS idx_turns_session_role ON turns(session_id, role, seq)");
276
+ if (!hasCol("rev")) db.run("ALTER TABLE sessions ADD COLUMN rev INTEGER NOT NULL DEFAULT 0");
277
+ if ((db.query("PRAGMA user_version").get()?.user_version ?? 0) !== SCHEMA_VERSION) db.run(`PRAGMA user_version = ${SCHEMA_VERSION}`);
278
+ }
279
+ /**
280
+ * Pre-migration safety net for v3 → v4: copy the source DB file to
281
+ * `<path>.zidane-pre-v4.bak` so the user can recover by restoring the
282
+ * snapshot if anything in the migration goes sideways.
283
+ *
284
+ * - Skipped for non-filesystem paths (`:memory:`, empty string) — no
285
+ * file to copy.
286
+ * - Skipped when the file is missing (fresh install, never reached
287
+ * migration territory).
288
+ * - Skipped when the backup already exists — re-runs of the migration
289
+ * (idempotent path) reuse the same snapshot rather than overwrite a
290
+ * potentially-earlier good copy with a later partial state.
291
+ * - WAL is checkpointed first so the .db file contains everything that
292
+ * was committed up to this point (otherwise pending WAL frames would
293
+ * be missing from the snapshot).
294
+ * - On copy failure the whole migration is aborted with a thrown error
295
+ * — we refuse to modify the DB without a recovery path. The user
296
+ * sees a clear diagnostic; their sessions stay intact.
297
+ *
298
+ * Surfaces a one-line stderr message on success so the user knows where
299
+ * the snapshot landed. They can delete it once they've confirmed the
300
+ * post-migration TUI behaves correctly.
301
+ */
302
+ function backupBeforeV3Migration(db, dbPath) {
303
+ if (dbPath === "" || dbPath === ":memory:" || dbPath.startsWith("file::memory:")) return;
304
+ if (!existsSync(dbPath)) return;
305
+ const backupPath = `${dbPath}.zidane-pre-v4.bak`;
306
+ if (existsSync(backupPath)) return;
307
+ let checkpointed = true;
308
+ try {
309
+ db.run("PRAGMA wal_checkpoint(TRUNCATE)");
310
+ } catch {
311
+ checkpointed = false;
312
+ }
313
+ try {
314
+ copyFileSync(dbPath, backupPath);
315
+ if (!checkpointed) for (const ext of ["-wal", "-shm"]) {
316
+ const sidecar = `${dbPath}${ext}`;
317
+ if (existsSync(sidecar)) copyFileSync(sidecar, `${backupPath}${ext}`);
318
+ }
319
+ process.stderr.write(`[zidane/sqlite] v3→v4 migration: backed up your sessions DB to "${backupPath}".\n To roll back if anything looks wrong:\n 1. quit zidane\n 2. cp "${backupPath}" "${dbPath}" && rm -f "${dbPath}-wal" "${dbPath}-shm"\n 3. pin an older zidane that knows the v3 schema, or upgrade to a fix\n Delete the .bak once every session loads correctly.\n`);
320
+ } catch (err) {
321
+ throw new Error(`[zidane/sqlite] failed to back up "${dbPath}" before v3→v4 migration: ${errorMessage(err)}. Refusing to modify the DB without a recovery path. Move the file aside or fix the permissions and retry.`);
322
+ }
323
+ }
324
+ /**
325
+ * Parse each session's legacy `data` blob and fan its `turns` + `runs`
326
+ * arrays out into the dedicated tables, then overwrite the synthetic
327
+ * `status`/`metadata` defaults with the values from the blob.
328
+ *
329
+ * Skips rows that already have at least one entry in `turns` for them —
330
+ * a previous run of this migration already landed those bytes, and
331
+ * re-inserting them would either duplicate (if seq numbering shifted)
332
+ * or crash on the PK. The "header already exists, turns table populated"
333
+ * combination is the idempotency signal.
334
+ *
335
+ * Per-row failures (corrupt JSON, …) log + skip rather than abort the
336
+ * whole migration: one bad row shouldn't prevent the rest of the DB
337
+ * from coming forward to v4.
338
+ */
339
+ function backfillV3Blobs(db) {
340
+ const rows = db.query("SELECT id, data FROM sessions").all();
341
+ if (rows.length === 0) return;
342
+ const insertTurn = db.prepare("INSERT INTO turns (session_id, seq, data) VALUES (?, ?, ?)");
343
+ const upsertRun = db.prepare(`
344
+ INSERT INTO runs (session_id, run_id, started_at, data) VALUES (?, ?, ?, ?)
345
+ ON CONFLICT(session_id, run_id) DO UPDATE SET
346
+ data = excluded.data,
347
+ started_at = excluded.started_at
348
+ `);
349
+ const updateHeader = db.prepare("UPDATE sessions SET status = ?, metadata = ? WHERE id = ?");
350
+ const countTurns = db.prepare("SELECT COUNT(*) as c FROM turns WHERE session_id = ?");
351
+ for (const row of rows) {
352
+ if (!row.data) continue;
353
+ try {
354
+ const data = JSON.parse(row.data);
355
+ if (countTurns.get(row.id).c > 0) continue;
356
+ const turns = Array.isArray(data.turns) ? data.turns : [];
357
+ const runs = Array.isArray(data.runs) ? data.runs : [];
358
+ db.transaction(() => {
359
+ turns.forEach((t, i) => insertTurn.run(row.id, i, JSON.stringify(t)));
360
+ for (const run of runs) {
361
+ if (!run || typeof run.id !== "string") continue;
362
+ upsertRun.run(row.id, run.id, run.startedAt ?? 0, JSON.stringify(run));
363
+ }
364
+ updateHeader.run(data.status ?? "idle", JSON.stringify(data.metadata ?? {}), row.id);
365
+ }).immediate();
366
+ } catch (err) {
367
+ process.stderr.write(`[zidane/sqlite] v3→v4 migrate: session "${row.id}" skipped: ${errorMessage(err)}\n`);
368
+ }
369
+ }
370
+ }
371
+ //#endregion
372
+ //#region src/session/sqlite-transactions.ts
373
+ function prepareSqliteStatements(db) {
374
+ return {
375
+ stmtLoadHeader: db.prepare(`
376
+ SELECT id, agent_id, project_root, status, metadata, created_at, updated_at
377
+ FROM sessions WHERE id = ?
378
+ `),
379
+ stmtLoadTurns: db.prepare("SELECT data FROM turns WHERE session_id = ? ORDER BY seq"),
380
+ stmtLoadTurnsRange: db.prepare("SELECT data FROM turns WHERE session_id = ? ORDER BY seq LIMIT ? OFFSET ?"),
381
+ stmtLoadRuns: db.prepare("SELECT data FROM runs WHERE session_id = ? ORDER BY started_at, run_id"),
382
+ stmtUpsertHeader: db.prepare(`
383
+ INSERT INTO sessions (id, agent_id, project_root, status, metadata, created_at, updated_at)
384
+ VALUES (?, ?, ?, ?, ?, ?, ?)
385
+ ON CONFLICT(id) DO UPDATE SET
386
+ agent_id = excluded.agent_id,
387
+ project_root = excluded.project_root,
388
+ status = excluded.status,
389
+ metadata = excluded.metadata,
390
+ updated_at = excluded.updated_at,
391
+ rev = sessions.rev + 1
392
+ `),
393
+ stmtDelete: db.prepare("DELETE FROM sessions WHERE id = ?"),
394
+ stmtDeleteTurnsForSession: db.prepare("DELETE FROM turns WHERE session_id = ?"),
395
+ stmtDeleteRunsForSession: db.prepare("DELETE FROM runs WHERE session_id = ?"),
396
+ stmtInsertTurn: db.prepare("INSERT INTO turns (session_id, seq, role, data) VALUES (?, ?, ?, ?)"),
397
+ stmtUpsertRun: db.prepare(`
398
+ INSERT INTO runs (session_id, run_id, started_at, data) VALUES (?, ?, ?, ?)
399
+ ON CONFLICT(session_id, run_id) DO UPDATE SET
400
+ data = excluded.data,
401
+ started_at = excluded.started_at
402
+ `),
403
+ stmtMaxSeq: db.prepare("SELECT MAX(seq) as m FROM turns WHERE session_id = ?"),
404
+ stmtTouch: db.prepare("UPDATE sessions SET updated_at = ?, rev = rev + 1 WHERE id = ?"),
405
+ stmtUpdateStatus: db.prepare("UPDATE sessions SET status = ?, updated_at = ?, rev = rev + 1 WHERE id = ?"),
406
+ stmtUpdateStatusOnly: db.prepare("UPDATE sessions SET status = ?, rev = rev + 1 WHERE id = ?"),
407
+ stmtFindArtifact: db.prepare(`SELECT ${ARTIFACT_COLUMNS} FROM artifacts WHERE session_id = ? AND kind = ? AND uri = ?`),
408
+ stmtSessionArtifacts: db.prepare(`SELECT ${ARTIFACT_COLUMNS} FROM artifacts WHERE session_id = ? ORDER BY created_at, rowid`),
409
+ stmtInsertArtifact: db.prepare(`
410
+ INSERT INTO artifacts (${ARTIFACT_COLUMNS}) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
411
+ `),
412
+ stmtRefreshArtifact: db.prepare(`
413
+ UPDATE artifacts SET label = ?, project_root = ?, meta = ?, updated_at = ? WHERE id = ?
414
+ `),
415
+ stmtDeleteArtifact: db.prepare("DELETE FROM artifacts WHERE session_id = ? AND id = ?")
416
+ };
417
+ }
418
+ function createSqliteTransactions(db, stmts) {
419
+ const { stmtLoadHeader, stmtLoadTurns, stmtLoadRuns, stmtUpsertHeader, stmtDeleteTurnsForSession, stmtDeleteRunsForSession, stmtInsertTurn, stmtUpsertRun, stmtMaxSeq, stmtTouch, stmtUpdateStatus, stmtUpdateStatusOnly, stmtFindArtifact, stmtSessionArtifacts, stmtInsertArtifact, stmtRefreshArtifact, stmtDeleteArtifact } = stmts;
420
+ const loadSync = (sessionId) => {
421
+ const header = stmtLoadHeader.get(sessionId);
422
+ if (!header) return null;
423
+ const turnRows = stmtLoadTurns.all(sessionId);
424
+ const runRows = stmtLoadRuns.all(sessionId);
425
+ return {
426
+ id: header.id,
427
+ ...header.agent_id ? { agentId: header.agent_id } : {},
428
+ ...header.project_root ? { projectRoot: header.project_root } : {},
429
+ turns: turnRows.map((r) => safeParseRow(r.data, header.id, "turn")).filter((t) => t !== null),
430
+ runs: runRows.map((r) => safeParseRow(r.data, header.id, "run")).filter((r) => r !== null),
431
+ status: header.status,
432
+ metadata: safeParseRecord(header.metadata),
433
+ createdAt: header.created_at,
434
+ updatedAt: header.updated_at
435
+ };
436
+ };
437
+ const txnSave = db.transaction((session) => {
438
+ stmtUpsertHeader.run(session.id, session.agentId ?? null, session.projectRoot ?? null, session.status, JSON.stringify(session.metadata ?? {}), session.createdAt, session.updatedAt);
439
+ stmtDeleteTurnsForSession.run(session.id);
440
+ stmtDeleteRunsForSession.run(session.id);
441
+ session.turns.forEach((t, i) => stmtInsertTurn.run(session.id, i, t.role ?? null, JSON.stringify(t)));
442
+ for (const run of session.runs) stmtUpsertRun.run(session.id, run.id, run.startedAt, JSON.stringify(run));
443
+ });
444
+ const txnSaveMeta = db.transaction((session) => {
445
+ stmtUpsertHeader.run(session.id, session.agentId ?? null, session.projectRoot ?? null, session.status, JSON.stringify(session.metadata ?? {}), session.createdAt, session.updatedAt);
446
+ for (const run of session.runs) stmtUpsertRun.run(session.id, run.id, run.startedAt, JSON.stringify(run));
447
+ });
448
+ const txnMutateTurns = db.transaction((sessionId, mutate) => {
449
+ if (!stmtLoadHeader.get(sessionId)) return "no-session";
450
+ const next = mutate(stmtLoadTurns.all(sessionId).map((r) => safeParseRow(r.data, sessionId, "turn")).filter((t) => t !== null));
451
+ if (next === null) return "unchanged";
452
+ stmtDeleteTurnsForSession.run(sessionId);
453
+ next.forEach((t, i) => stmtInsertTurn.run(sessionId, i, t.role ?? null, JSON.stringify(t)));
454
+ stmtTouch.run(Date.now(), sessionId);
455
+ return "ok";
456
+ });
457
+ const ensureHeaderSync = (sessionId) => {
458
+ if (stmtLoadHeader.get(sessionId)) return;
459
+ const now = Date.now();
460
+ stmtUpsertHeader.run(sessionId, null, null, "idle", "{}", now, now);
461
+ };
462
+ return {
463
+ loadSync,
464
+ txnSave,
465
+ txnSaveMeta,
466
+ txnMutateTurns,
467
+ txnAppendTurns: db.transaction((sessionId, turns) => {
468
+ ensureHeaderSync(sessionId);
469
+ let nextSeq = (stmtMaxSeq.get(sessionId).m ?? -1) + 1;
470
+ for (const turn of turns) {
471
+ stmtInsertTurn.run(sessionId, nextSeq, turn.role ?? null, JSON.stringify(turn));
472
+ nextSeq += 1;
473
+ }
474
+ stmtTouch.run(Date.now(), sessionId);
475
+ }),
476
+ txnUpdateRun: db.transaction((sessionId, run) => {
477
+ if (!stmtLoadHeader.get(sessionId)) return;
478
+ stmtUpsertRun.run(sessionId, run.id, run.startedAt, JSON.stringify(run));
479
+ stmtTouch.run(Date.now(), sessionId);
480
+ }),
481
+ txnUpdateStatus: db.transaction((sessionId, status, preserveUpdatedAt) => {
482
+ if (preserveUpdatedAt) stmtUpdateStatusOnly.run(status, sessionId);
483
+ else stmtUpdateStatus.run(status, Date.now(), sessionId);
484
+ }),
485
+ txnUpsertArtifact: db.transaction((artifact) => {
486
+ if (!stmtLoadHeader.get(artifact.sessionId)) return null;
487
+ const existingRow = stmtFindArtifact.get(artifact.sessionId, artifact.kind, artifact.uri);
488
+ if (existingRow) {
489
+ const merged = mergeArtifact(rowToArtifact(existingRow), artifact);
490
+ stmtRefreshArtifact.run(merged.label, merged.projectRoot ?? null, merged.meta !== void 0 ? JSON.stringify(merged.meta) : null, merged.updatedAt, merged.id);
491
+ return merged;
492
+ }
493
+ const current = stmtSessionArtifacts.all(artifact.sessionId).map(rowToArtifact);
494
+ for (const id of selectArtifactEvictions(current)) stmtDeleteArtifact.run(artifact.sessionId, id);
495
+ stmtInsertArtifact.run(artifact.id, artifact.sessionId, artifact.runId ?? null, artifact.turnId ?? null, artifact.kind, artifact.uri, artifact.label, artifact.projectRoot ?? null, artifact.meta !== void 0 ? JSON.stringify(artifact.meta) : null, artifact.createdAt, artifact.updatedAt);
496
+ return artifact;
497
+ })
498
+ };
499
+ }
500
+ //#endregion
501
+ //#region src/session/sqlite.ts
502
+ /**
503
+ * True when `err` is SQLite reporting a damaged file (`SQLITE_CORRUPT`,
504
+ * `SQLITE_NOTADB`). Matched on the message because bun:sqlite's error
505
+ * class exposes the code inconsistently across versions.
506
+ */
507
+ function isCorruptDbError(err) {
508
+ const msg = errorMessage(err);
509
+ return /database disk image is malformed|SQLITE_CORRUPT|SQLITE_NOTADB|file is not a database/i.test(msg);
510
+ }
511
+ /**
512
+ * Re-wrap a corruption error with the file path and a recovery recipe.
513
+ * The bare SQLite string ("database disk image is malformed") tells the
514
+ * user nothing about WHICH file or what to do; every host (TUI, daemon,
515
+ * headless) surfaces this message instead. Non-corruption errors pass
516
+ * through untouched.
517
+ *
518
+ * Deliberately no auto-repair / quarantine: the file is the only copy of
519
+ * the user's history and `.recover` salvages most of it. Never touch it.
520
+ */
521
+ function describeCorruptDb(err, dbPath) {
522
+ if (!isCorruptDbError(err)) return err;
523
+ return new Error(`[zidane/sqlite] sessions database at "${dbPath}" is corrupt (${errorMessage(err)}).\n Your sessions are still on disk; zidane will not modify the file. To recover:\n 1. quit zidane (and any running daemon)\n 2. sqlite3 "${dbPath}" ".recover" | sqlite3 "${dbPath}.recovered"\n 3. mv "${dbPath}" "${dbPath}.corrupt" && rm -f "${dbPath}-wal" "${dbPath}-shm" && mv "${dbPath}.recovered" "${dbPath}"\n Common causes: git checkout/stash swapping a project .zidane/sessions.db under its -wal, a cloud-synced or network folder (iCloud, Dropbox, SMB), or a backup restored without deleting -wal / -shm.`, { cause: err });
524
+ }
525
+ function createSqliteStore(options) {
526
+ let store;
527
+ try {
528
+ store = openSqliteStore(options);
529
+ } catch (err) {
530
+ throw describeCorruptDb(err, options.path);
531
+ }
532
+ const wrapped = { ...store };
533
+ for (const key of Object.keys(store)) {
534
+ const fn = store[key];
535
+ if (typeof fn !== "function" || key === "close") continue;
536
+ wrapped[key] = async (...args) => {
537
+ try {
538
+ return await fn.apply(store, args);
539
+ } catch (err) {
540
+ throw describeCorruptDb(err, options.path);
541
+ }
542
+ };
543
+ }
544
+ return wrapped;
545
+ }
546
+ function openSqliteStore(options) {
547
+ const db = new Database(options.path);
548
+ initSqliteSchema(db, options.path);
549
+ const stmts = prepareSqliteStatements(db);
550
+ const { stmtDelete, stmtLoadTurnsRange, stmtDeleteArtifact } = stmts;
551
+ const { loadSync, txnSave, txnSaveMeta, txnMutateTurns, txnAppendTurns, txnUpdateRun, txnUpdateStatus, txnUpsertArtifact } = createSqliteTransactions(db, stmts);
552
+ return {
553
+ async load(sessionId) {
554
+ return loadSync(sessionId);
555
+ },
556
+ async save(session) {
557
+ txnSave.immediate(session);
558
+ },
559
+ async saveMeta(session) {
560
+ txnSaveMeta.immediate(session);
561
+ },
562
+ async delete(sessionId) {
563
+ stmtDelete.run(sessionId);
564
+ },
565
+ async list(filter) {
566
+ const { where, limit, params } = buildListFilter(filter);
567
+ const sql = `SELECT id FROM sessions ${where} ORDER BY updated_at DESC ${limit}`.replace(/\s+/g, " ").trim();
568
+ return db.query(sql).all(...params).map((r) => r.id);
569
+ },
570
+ async getMeta(sessionId) {
571
+ const row = db.query(`
572
+ SELECT
573
+ s.id,
574
+ s.project_root,
575
+ s.metadata,
576
+ s.updated_at,
577
+ s.rev,
578
+ s.agent_id,
579
+ s.created_at,
580
+ s.status,
581
+ (SELECT COUNT(*) FROM turns t WHERE t.session_id = s.id) AS turn_count,
582
+ (SELECT COUNT(*) FROM turns t WHERE t.session_id = s.id AND t.role = 'user') AS user_count,
583
+ (SELECT COUNT(*) FROM runs r WHERE r.session_id = s.id) AS run_count,
584
+ (SELECT COUNT(*) FROM artifacts a WHERE a.session_id = s.id) AS artifact_count,
585
+ NULL AS first_user_turn
586
+ FROM sessions s WHERE s.id = ?
587
+ `).get(sessionId);
588
+ if (!row) return null;
589
+ return {
590
+ id: row.id,
591
+ metadata: safeParseRecord(row.metadata),
592
+ ...row.project_root ? { projectRoot: row.project_root } : {},
593
+ updatedAt: row.updated_at,
594
+ rev: row.rev,
595
+ ...row.agent_id ? { agentId: row.agent_id } : {},
596
+ createdAt: row.created_at,
597
+ status: row.status,
598
+ turnCount: row.turn_count,
599
+ userMessageCount: row.user_count,
600
+ runCount: row.run_count,
601
+ artifactCount: row.artifact_count
602
+ };
603
+ },
604
+ async listMeta(filter) {
605
+ const { where, limit, params } = buildListFilter(filter);
606
+ const sql = `
607
+ SELECT
608
+ s.id,
609
+ s.project_root,
610
+ s.metadata,
611
+ s.updated_at,
612
+ s.agent_id,
613
+ s.created_at,
614
+ s.status,
615
+ (SELECT COUNT(*) FROM turns t WHERE t.session_id = s.id) AS turn_count,
616
+ (SELECT COUNT(*) FROM turns t WHERE t.session_id = s.id AND t.role = 'user') AS user_count,
617
+ (SELECT COUNT(*) FROM runs r WHERE r.session_id = s.id) AS run_count,
618
+ (SELECT COUNT(*) FROM artifacts a WHERE a.session_id = s.id) AS artifact_count,
619
+ CASE WHEN json_valid(s.metadata)
620
+ AND TRIM(COALESCE(json_extract(s.metadata, '$.title'), '')) <> '' THEN NULL
621
+ ELSE (SELECT t.data FROM turns t WHERE t.session_id = s.id AND t.role = 'user'
622
+ ORDER BY t.seq LIMIT 1)
623
+ END AS first_user_turn
624
+ FROM sessions s ${where} ORDER BY s.updated_at DESC ${limit}
625
+ `;
626
+ return db.query(sql).all(...params).map((r) => {
627
+ const firstUserTurn = r.first_user_turn ? safeParseRow(r.first_user_turn, r.id, "turn") : null;
628
+ return {
629
+ id: r.id,
630
+ metadata: safeParseRecord(r.metadata),
631
+ ...r.project_root ? { projectRoot: r.project_root } : {},
632
+ updatedAt: r.updated_at,
633
+ ...r.agent_id ? { agentId: r.agent_id } : {},
634
+ createdAt: r.created_at,
635
+ status: r.status,
636
+ turnCount: r.turn_count,
637
+ userMessageCount: r.user_count,
638
+ runCount: r.run_count,
639
+ artifactCount: r.artifact_count,
640
+ ...firstUserTurn ? { firstUserTurn } : {}
641
+ };
642
+ });
643
+ },
644
+ async appendTurns(sessionId, turns) {
645
+ txnAppendTurns.immediate(sessionId, turns);
646
+ },
647
+ async mutateTurns(sessionId, mutate) {
648
+ return txnMutateTurns.immediate(sessionId, mutate);
649
+ },
650
+ async getTurns(sessionId, from = 0, limit) {
651
+ const lim = typeof limit === "number" ? limit : -1;
652
+ return stmtLoadTurnsRange.all(sessionId, lim, from).map((r) => safeParseRow(r.data, sessionId, "turn")).filter((t) => t !== null);
653
+ },
654
+ async updateRun(sessionId, run) {
655
+ txnUpdateRun.immediate(sessionId, run);
656
+ },
657
+ async updateStatus(sessionId, status, options) {
658
+ txnUpdateStatus.immediate(sessionId, status, options?.preserveUpdatedAt === true);
659
+ },
660
+ async upsertArtifact(artifact) {
661
+ return txnUpsertArtifact.immediate(artifact);
662
+ },
663
+ async listArtifacts(filter) {
664
+ const { where, limit, params } = buildArtifactFilter(filter);
665
+ const sql = `SELECT ${ARTIFACT_COLUMNS} FROM artifacts ${where} ORDER BY updated_at DESC, created_at DESC, id ${limit}`.replace(/\s+/g, " ").trim();
666
+ return db.query(sql).all(...params).map(rowToArtifact);
667
+ },
668
+ async deleteArtifact(sessionId, artifactId) {
669
+ stmtDeleteArtifact.run(sessionId, artifactId);
670
+ },
671
+ close() {
672
+ db.close(false);
673
+ }
674
+ };
675
+ }
676
+ /**
677
+ * Convenience: open a SQLite store at `dbPath`, creating its parent
678
+ * directory if it doesn't yet exist. Used by the TUI launcher to spin up
679
+ * the default session store at `~/.zidane/sessions.db`.
680
+ *
681
+ * Lives here (and not in `chat/store.ts`) so the renderer-agnostic
682
+ * `zidane/chat` entry stays free of `bun:sqlite` — non-Bun consumers
683
+ * (a future GUI, an SDK) can import `zidane/chat` without pulling in the
684
+ * Bun-only binding.
685
+ */
686
+ function createTuiStore(dbPath) {
687
+ const dir = dirname(dbPath);
688
+ if (!existsSync(dir)) try {
689
+ mkdirSync(dir, { recursive: true });
690
+ } catch (err) {
691
+ throw new Error(`Could not create TUI storage directory at "${dir}". Override the location via \`runTui({ storageDir, prefix })\` or the \`ZIDANE_STORAGE_DIR\` env var. Original error: ${errorMessage(err)}`);
692
+ }
693
+ return createSqliteStore({ path: dbPath });
694
+ }
695
+ //#endregion
696
+ export { isCorruptDbError as i, createTuiStore as n, describeCorruptDb as r, createSqliteStore as t };
697
+
698
+ //# sourceMappingURL=sqlite-DV1DQzN2.js.map