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 @@
1
+ {"version":3,"file":"history-search-CcYzF8-0.js","names":[],"sources":["../src/chat/history-search.ts"],"sourcesContent":["import type { SessionTurn, ToolResultContent } from '../types'\nimport type { SessionMeta } from './types'\n\nexport interface HighlightRange {\n start: number\n end: number\n}\n\nexport interface HighlightSegment {\n text: string\n highlighted: boolean\n}\n\nexport interface SearchExcerpt {\n text: string\n highlighted: HighlightRange[]\n}\n\nexport interface SearchTurnMatch {\n turn: SessionTurn\n text: string\n highlighted: HighlightRange[]\n excerpts: SearchExcerpt[]\n score: number\n matchKind: 'exact-phrase' | 'exact-terms' | 'fuzzy'\n}\n\nexport type SearchTurnResult = SearchTurnMatch\n\nexport interface SearchSessionResult {\n id: string\n score: number\n matchKind: 'exact-phrase' | 'exact-terms' | 'fuzzy'\n turn: SessionTurn\n text: string\n highlighted: HighlightRange[]\n excerpts: SearchExcerpt[]\n}\n\nexport interface SessionSearchExcerpt extends SearchExcerpt {\n turnId: string\n role: SessionTurn['role']\n}\n\n/** Aggregated row-level match used by the conversations list. */\nexport interface SessionHistoryMatch {\n score: number\n matchedTurnIds: string[]\n excerpts: SessionSearchExcerpt[]\n}\n\nexport interface IndexedSearchTurn {\n turn: SessionTurn\n /** Attachment/base64-free text shown in search results. */\n text: string\n /** Pre-normalized once, reused for every query. */\n lowerText: string\n}\n\nexport interface SessionSearchIndex {\n turns: IndexedSearchTurn[]\n}\n\ninterface QueryToken { text: string, start: number, end: number }\n\ntype MatchKind = 'exact-phrase' | 'exact-terms' | 'fuzzy'\n\ninterface LineMatch {\n lineIndex: number\n lineStart: number\n lineEnd: number\n ranges: HighlightRange[]\n}\n\nconst EXCERPT_WIDTH = 120\nconst EXCERPT_MARGIN = 28\n\nexport function buildSessionSearchIndex(turns: readonly SessionTurn[]): SessionSearchIndex {\n return { turns: turns.flatMap((turn) => {\n const text = searchableTurnText(turn)\n return text ? [{ turn, text, lowerText: text.toLocaleLowerCase() }] : []\n }) }\n}\n\n/** Yielding index builder for TUI callers — never monopolizes a frame. */\nexport async function buildSessionSearchIndexAsync(\n turns: readonly SessionTurn[],\n options: { yieldEvery?: number, onProgress?: (indexed: number, total: number) => void, signal?: AbortSignal } = {},\n): Promise<SessionSearchIndex> {\n const indexed: IndexedSearchTurn[] = []\n const yieldEvery = Math.max(1, options.yieldEvery ?? 80)\n for (let i = 0; i < turns.length; i++) {\n options.signal?.throwIfAborted()\n const turn = turns[i]!\n const text = searchableTurnText(turn)\n if (text)\n indexed.push({ turn, text, lowerText: text.toLocaleLowerCase() })\n if ((i + 1) % yieldEvery === 0) {\n options.onProgress?.(i + 1, turns.length)\n await yieldToEventLoop()\n }\n }\n if (turns.length === 0 || turns.length % yieldEvery !== 0)\n options.onProgress?.(turns.length, turns.length)\n return { turns: indexed }\n}\n\nexport function searchSessionIndex(index: SessionSearchIndex, query: string, limit = 10): SearchTurnMatch[] {\n if (limit <= 0)\n return []\n const matches = searchSessionIndexChunk(index, query, 0, index.turns.length)\n .map(result => ({ ...result.match, turn: index.turns[result.index]!.turn }))\n matches.sort(compareMatches)\n return matches.slice(0, limit)\n}\n\ninterface SearchIndexChunkMatch {\n index: number\n match: Omit<SearchTurnMatch, 'turn'>\n}\n\n/** Bounded synchronous matching unit backing `searchSessionIndex`. */\nfunction searchSessionIndexChunk(index: SessionSearchIndex, query: string, start: number, end: number): SearchIndexChunkMatch[] {\n const parsed = parseQuery(query)\n if (!parsed.tokens.length)\n return []\n const matches: SearchIndexChunkMatch[] = []\n const stop = Math.min(end, index.turns.length)\n for (let i = Math.max(0, start); i < stop; i++) {\n const indexed = index.turns[i]!\n const match = matchTurn(indexed.turn, indexed.text, indexed.lowerText, parsed)\n if (match)\n matches.push({ index: i, match })\n }\n return matches\n}\n\n/** Yielding matcher for very large indexes; progress is checked per chunk. */\nexport async function searchSessionIndexAsync(\n index: SessionSearchIndex,\n query: string,\n options: { limit?: number, yieldEvery?: number, onProgress?: (searched: number, total: number) => void, signal?: AbortSignal } = {},\n): Promise<SearchTurnMatch[]> {\n const parsed = parseQuery(query)\n const limit = options.limit ?? 10\n if (!parsed.tokens.length || limit <= 0)\n return []\n const matches: SearchTurnMatch[] = []\n const yieldEvery = Math.max(1, options.yieldEvery ?? 250)\n for (let i = 0; i < index.turns.length; i++) {\n options.signal?.throwIfAborted()\n const indexed = index.turns[i]!\n const match = matchTurn(indexed.turn, indexed.text, indexed.lowerText, parsed)\n if (match)\n matches.push({ ...match, turn: indexed.turn })\n if ((i + 1) % yieldEvery === 0) {\n options.onProgress?.(i + 1, index.turns.length)\n await yieldToEventLoop()\n }\n }\n if (index.turns.length === 0 || index.turns.length % yieldEvery !== 0)\n options.onProgress?.(index.turns.length, index.turns.length)\n matches.sort(compareMatches)\n return matches.slice(0, limit)\n}\n\nexport function searchTurns(turns: readonly SessionTurn[], query: string, limit = 10): SearchTurnMatch[] {\n return searchSessionIndex(buildSessionSearchIndex(turns), query, limit)\n}\n\nexport function searchSessionTurns(turns: readonly SessionTurn[], query: string, maxExcerpts = 3): SearchSessionResult[] {\n return searchTurns(turns, query, turns.length)\n .map(match => ({\n id: match.turn.id,\n score: match.score,\n matchKind: match.matchKind,\n turn: match.turn,\n text: match.text,\n highlighted: match.highlighted,\n excerpts: match.excerpts.slice(0, maxExcerpts),\n }))\n}\n\nexport function searchSessionHistory(turns: readonly SessionTurn[], query: string, maxExcerpts = 3): SessionHistoryMatch | null {\n return sessionHistoryFromMatches(searchTurns(turns, query, turns.length), maxExcerpts)\n}\n\nexport function searchSessionHistoryIndex(index: SessionSearchIndex, query: string, maxExcerpts = 3): SessionHistoryMatch | null {\n return sessionHistoryFromMatches(searchSessionIndex(index, query, index.turns.length), maxExcerpts)\n}\n\nexport async function searchSessionHistoryIndexAsync(\n index: SessionSearchIndex,\n query: string,\n maxExcerpts = 3,\n onProgress?: (searched: number, total: number) => void,\n signal?: AbortSignal,\n): Promise<SessionHistoryMatch | null> {\n const matches = await searchSessionIndexAsync(index, query, {\n limit: index.turns.length,\n onProgress,\n signal,\n })\n return sessionHistoryFromMatches(matches, maxExcerpts)\n}\n\nfunction sessionHistoryFromMatches(matches: readonly SearchTurnMatch[], maxExcerpts: number): SessionHistoryMatch | null {\n if (matches.length === 0)\n return null\n const excerpts: SessionSearchExcerpt[] = []\n for (const match of matches) {\n for (const excerpt of match.excerpts) {\n excerpts.push({ ...excerpt, turnId: match.turn.id, role: match.turn.role })\n if (excerpts.length >= maxExcerpts)\n break\n }\n if (excerpts.length >= maxExcerpts)\n break\n }\n return {\n score: matches[0]?.score ?? 0,\n matchedTurnIds: matches.map(match => match.turn.id),\n excerpts,\n }\n}\n\n/**\n * `contentMatches` are keyed by `keyOf(meta)`: the bare id by default, a\n * (host, id) session key for a list across hosts (twins are two rows).\n */\nexport function filterSessionSearchCatalog(\n sessions: readonly SessionMeta[],\n query: string,\n contentMatches: ReadonlyMap<string, SessionHistoryMatch>,\n keyOf: (meta: SessionMeta) => string = meta => meta.id,\n): SessionMeta[] {\n const terms = query.trim().toLocaleLowerCase().split(/\\s+/u).filter(Boolean)\n if (terms.length === 0)\n return [...sessions]\n return sessions\n .flatMap((meta) => {\n const projectBasename = meta.projectRoot?.split(/[\\\\/]/).pop() ?? ''\n const corpus = `${meta.title} ${meta.id} ${projectBasename} ${meta.projectRoot ?? ''}`.toLocaleLowerCase()\n const direct = terms.every(term => corpus.includes(term))\n const fuzzy = !direct && terms.every(term => findFuzzyWordRange(corpus, term) !== null)\n const metadataRank = direct ? 2 : fuzzy ? 1 : 0\n const contentMatch = contentMatches.get(keyOf(meta))\n return metadataRank > 0 || contentMatch ? [{ meta, metadataRank, contentMatch }] : []\n })\n .sort((a, b) => b.metadataRank - a.metadataRank\n || (b.contentMatch?.score ?? 0) - (a.contentMatch?.score ?? 0)\n || b.meta.updatedAt - a.meta.updatedAt)\n .map(row => row.meta)\n}\n\nexport function searchHighlightRanges(text: string, query: string): HighlightRange[] {\n const parsed = parseQuery(query.trim())\n if (parsed.tokens.length === 0)\n return []\n const lowerText = lower(text)\n const phrase = findTermRanges(lowerText, parsed.phraseLower)\n if (phrase.length > 0)\n return mergeRanges(phrase, text.length)\n const exact = parsed.tokens.flatMap(token => findTermRanges(lowerText, token.lower))\n if (exact.length > 0)\n return mergeRanges(exact, text.length)\n return mergeRanges(\n parsed.tokens.flatMap(token => findFuzzyWordRange(lowerText, token.lower) ?? []),\n text.length,\n )\n}\n\nexport function highlightSegments(text: string, ranges: readonly HighlightRange[]): HighlightSegment[] {\n const normalized = mergeRanges(ranges, text.length)\n if (!normalized.length)\n return [{ text, highlighted: false }]\n const segments: HighlightSegment[] = []\n let cursor = 0\n for (const range of normalized) {\n if (range.start > cursor)\n segments.push({ text: text.slice(cursor, range.start), highlighted: false })\n if (range.end > range.start)\n segments.push({ text: text.slice(range.start, range.end), highlighted: true })\n cursor = range.end\n }\n if (cursor < text.length)\n segments.push({ text: text.slice(cursor), highlighted: false })\n return segments.filter(segment => segment.text.length > 0)\n}\n\nfunction matchTurn(turn: SessionTurn, text: string, lowerText: string, query: ParsedQuery): Omit<SearchTurnMatch, 'turn'> | null {\n const phraseRanges = findTermRanges(lowerText, query.phraseLower)\n if (phraseRanges.length)\n return buildResult(turn, text, phraseRanges, 'exact-phrase', 3000 + phraseRanges.length)\n\n const termRanges: HighlightRange[] = []\n let exactTerms = 0\n for (const token of query.tokens) {\n const exact = findTermRanges(lowerText, token.lower)\n if (exact.length) {\n exactTerms += 1\n termRanges.push(...exact)\n continue\n }\n const fuzzy = findFuzzyWordRange(lowerText, token.lower)\n if (!fuzzy)\n return null\n termRanges.push(...fuzzy)\n }\n\n const merged = mergeRanges(termRanges, text.length)\n if (!merged.length)\n return null\n const allExact = exactTerms === query.tokens.length\n // Within the fuzzy band, more exact tokens = cleaner match = higher rank.\n return buildResult(turn, text, merged, allExact ? 'exact-terms' : 'fuzzy', allExact ? 2000 : 1000 + exactTerms)\n}\n\nfunction buildResult(turn: SessionTurn, text: string, highlighted: HighlightRange[], matchKind: MatchKind, score: number): Omit<SearchTurnMatch, 'turn'> {\n return {\n text,\n highlighted,\n excerpts: buildExcerpts(text, highlighted),\n matchKind,\n score,\n }\n}\n\nfunction buildExcerpts(text: string, ranges: readonly HighlightRange[]): SearchExcerpt[] {\n const lines = splitLines(text)\n const matches = rangesToLineMatches(text, lines, ranges)\n return matches.slice(0, 3).map((match) => {\n const lineText = lines[match.lineIndex] ?? ''\n const clipped = clipLine(lineText, match.ranges, EXCERPT_WIDTH, EXCERPT_MARGIN)\n return clipped\n })\n}\n\nfunction clipLine(text: string, ranges: readonly HighlightRange[], width: number, margin: number): SearchExcerpt {\n if (text.length <= width)\n return { text, highlighted: mergeRanges(ranges, text.length) }\n\n const merged = mergeRanges(ranges, text.length)\n if (!merged.length)\n return { text: text.slice(0, width), highlighted: [] }\n\n const focusStart = merged[0].start\n const focusEnd = merged[merged.length - 1].end\n let start = Math.max(0, Math.min(focusStart - margin, text.length - width))\n let end = Math.min(text.length, Math.max(focusEnd + margin, start + width))\n if (end - start > width) {\n const over = end - start - width\n start += Math.floor(over / 2)\n end = start + width\n }\n const clippedText = text.slice(start, end)\n return {\n text: clippedText,\n highlighted: merged.map(range => ({ start: Math.max(0, range.start - start), end: Math.min(clippedText.length, range.end - start) })).filter(range => range.end > range.start),\n }\n}\n\nfunction rangesToLineMatches(text: string, lines: string[], ranges: readonly HighlightRange[]): LineMatch[] {\n const matches: LineMatch[] = []\n let offset = 0\n for (let index = 0; index < lines.length; index++) {\n const line = lines[index]\n const lineStart = offset\n const lineEnd = offset + line.length\n const lineRanges = ranges\n .map(range => intersectRange(range, lineStart, lineEnd))\n .filter((range): range is HighlightRange => Boolean(range))\n .map(range => ({ start: range.start - lineStart, end: range.end - lineStart }))\n if (lineRanges.length)\n matches.push({ lineIndex: index, lineStart, lineEnd, ranges: lineRanges })\n offset = lineEnd + 1\n }\n return matches\n}\n\nfunction splitLines(text: string): string[] {\n return text.split('\\n')\n}\n\nconst MAX_SEARCHABLE_TEXT_CHARS = 512_000\nconst MAX_SEARCHABLE_TOOL_CHARS = 128_000\nconst BINARY_KEY_RE = /(?:^|_)(?:data|base64|bytes|blob|attachment|image|audio|video|binary|file_content)(?:$|_)/i\nconst BASE64_RUN_RE = /[a-z0-9+/]{256,}={0,2}/gi\n\n/**\n * Search-specific serializer. Unlike `turnAsText`, it never serializes media,\n * document attachments, encrypted reasoning, or base64-looking payloads.\n */\nexport function searchableTurnText(turn: SessionTurn): string {\n const parts: string[] = []\n for (const block of turn.content) {\n if (block.type === 'text') {\n pushSearchText(parts, block.text, MAX_SEARCHABLE_TEXT_CHARS)\n }\n else if (block.type === 'thinking') {\n pushSearchText(parts, `[thinking]\\n${block.text}`, MAX_SEARCHABLE_TEXT_CHARS)\n }\n else if (block.type === 'compact-summary') {\n pushSearchText(parts, `[compaction summary]\\n${block.summary}`, MAX_SEARCHABLE_TEXT_CHARS)\n }\n else if (block.type === 'tool_call') {\n const args = searchableJson(block.input)\n parts.push(`[tool call · ${block.name}]${args ? `\\n${args}` : ''}`)\n }\n else if (block.type === 'tool_result') {\n const output = searchableToolResult(block.output)\n if (output)\n parts.push(`[tool result]\\n${output}`)\n }\n else if (block.type === 'server_tool_use') {\n const input = searchableJson(block.input)\n parts.push(`[server tool · ${block.name}]${input ? `\\n${input}` : ''}`)\n }\n else if (block.type === 'server_tool_result') {\n const content = searchableJson(block.content)\n if (content)\n parts.push(`[server tool result · ${block.toolName}]\\n${content}`)\n }\n // image/audio/video/document/redacted/provider-reasoning blocks are\n // intentionally absent: names and payloads belong to attachments/wire.\n }\n return parts.join('\\n\\n')\n}\n\nfunction searchableToolResult(output: string | ToolResultContent[]): string {\n if (typeof output === 'string')\n return safeSearchString(output, MAX_SEARCHABLE_TOOL_CHARS)\n return output.flatMap((part) => {\n if (part.type === 'text') {\n const text = safeSearchString(part.text, MAX_SEARCHABLE_TOOL_CHARS)\n return text ? [text] : []\n }\n // Structured image/audio/video/document content is an attachment.\n return []\n }).join('\\n')\n}\n\nfunction pushSearchText(parts: string[], text: string, max: number): void {\n const safe = safeSearchString(text, max)\n if (safe)\n parts.push(safe)\n}\n\nfunction safeSearchString(value: string, max: number): string {\n const trimmed = value.trim()\n if (!trimmed || isLikelyBase64(trimmed))\n return ''\n const withoutPayloads = trimmed.replace(BASE64_RUN_RE, '').trim()\n if (!withoutPayloads)\n return ''\n return withoutPayloads.length <= max ? withoutPayloads : `${withoutPayloads.slice(0, max)}\\n… [search text truncated]`\n}\n\nfunction isLikelyBase64(value: string): boolean {\n if (/^data:[^;,]+;base64,/i.test(value))\n return true\n if (value.length < 256 || value.length % 4 !== 0 || /\\s/.test(value))\n return false\n return /^[a-z0-9+/]+={0,2}$/i.test(value)\n}\n\nfunction searchableJson(value: unknown): string {\n const sanitized = sanitizeSearchValue(value, 0)\n if (sanitized === undefined)\n return ''\n try {\n return safeSearchString(JSON.stringify(sanitized, null, 2), MAX_SEARCHABLE_TOOL_CHARS)\n }\n catch {\n return ''\n }\n}\n\nfunction sanitizeSearchValue(value: unknown, depth: number): unknown {\n if (depth > 6 || value === null || typeof value === 'number' || typeof value === 'boolean')\n return value\n if (typeof value === 'string') {\n const safe = safeSearchString(value, MAX_SEARCHABLE_TOOL_CHARS)\n return safe || undefined\n }\n if (Array.isArray(value))\n return value.slice(0, 200).flatMap(item => sanitizeSearchValue(item, depth + 1) ?? [])\n if (typeof value !== 'object')\n return undefined\n const out: Record<string, unknown> = {}\n for (const [key, child] of Object.entries(value as Record<string, unknown>)) {\n if (BINARY_KEY_RE.test(key))\n continue\n const safe = sanitizeSearchValue(child, depth + 1)\n if (safe !== undefined)\n out[key] = safe\n }\n return Object.keys(out).length ? out : undefined\n}\n\nfunction compareMatches(a: SearchTurnMatch, b: SearchTurnMatch): number {\n return b.score - a.score || b.turn.createdAt - a.turn.createdAt || a.turn.id.localeCompare(b.turn.id)\n}\n\nfunction yieldToEventLoop(): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, 0))\n}\n\nfunction parseQuery(query: string): ParsedQuery {\n const tokens = tokenize(query)\n const phrase = tokens.map(token => token.text).join(' ')\n return {\n tokens: tokens.map(token => ({ ...token, lower: lower(token.text) })),\n phraseLower: lower(phrase),\n }\n}\n\nfunction tokenize(query: string): QueryToken[] {\n const tokens: QueryToken[] = []\n let i = 0\n while (i < query.length) {\n while (i < query.length && /\\s/u.test(query[i]!))\n i += 1\n if (i >= query.length)\n break\n if (query[i] === '\"') {\n const start = i + 1\n i += 1\n let value = ''\n while (i < query.length && query[i] !== '\"') {\n value += query[i]\n i += 1\n }\n tokens.push({ text: value, start, end: i })\n if (query[i] === '\"')\n i += 1\n continue\n }\n const start = i\n while (i < query.length && !/\\s/u.test(query[i]!))\n i += 1\n tokens.push({ text: query.slice(start, i), start, end: i })\n }\n return tokens.filter(token => token.text.length > 0)\n}\n\nfunction findTermRanges(text: string, termLower: string): HighlightRange[] {\n if (!termLower)\n return []\n const ranges: HighlightRange[] = []\n let from = 0\n while (from <= text.length) {\n const index = text.indexOf(termLower, from)\n if (index === -1)\n break\n ranges.push({ start: index, end: index + termLower.length })\n from = index + Math.max(1, termLower.length)\n }\n return ranges\n}\n\n/** Word-local typo matching: one word within a bounded edit distance of the term. */\nfunction findFuzzyWordRange(text: string, termLower: string): HighlightRange[] | null {\n // Short fuzzy tokens are overwhelmingly noisy (`api` matching `app`, for\n // example). Exact substring matching already handles useful prefixes.\n if (termLower.length < 4)\n return null\n const maxEdits = termLower.length >= 9 ? 2 : 1\n const words = text.matchAll(/[\\p{L}\\p{N}_-]+/gu)\n let best: { start: number, end: number, distance: number } | null = null\n for (const match of words) {\n const candidate = match[0]!.toLocaleLowerCase()\n if (Math.abs(candidate.length - termLower.length) > maxEdits)\n continue\n const distance = boundedEditDistance(candidate, termLower, maxEdits)\n if (distance === null)\n continue\n const similarity = 1 - distance / Math.max(candidate.length, termLower.length)\n if (similarity < 0.8)\n continue\n if (!best || distance < best.distance || (distance === best.distance && candidate.length < best.end - best.start)) {\n const start = match.index ?? 0\n best = { start, end: start + match[0]!.length, distance }\n }\n }\n return best ? [{ start: best.start, end: best.end }] : null\n}\n\nfunction boundedEditDistance(left: string, right: string, limit: number): number | null {\n let previous = Array.from({ length: right.length + 1 }, (_, i) => i)\n for (let i = 1; i <= left.length; i++) {\n const current = [i]\n let rowMin = i\n for (let j = 1; j <= right.length; j++) {\n const value = Math.min(\n current[j - 1]! + 1,\n previous[j]! + 1,\n previous[j - 1]! + (left[i - 1] === right[j - 1] ? 0 : 1),\n )\n current.push(value)\n rowMin = Math.min(rowMin, value)\n }\n if (rowMin > limit)\n return null\n previous = current\n }\n const distance = previous[right.length]!\n return distance <= limit ? distance : null\n}\n\nfunction mergeRanges(ranges: readonly HighlightRange[], max: number): HighlightRange[] {\n const sorted = ranges\n .map(range => ({ start: clamp(range.start, 0, max), end: clamp(range.end, 0, max) }))\n .filter(range => range.end > range.start)\n .sort((a, b) => a.start - b.start || a.end - b.end)\n const merged: HighlightRange[] = []\n for (const range of sorted) {\n const last = merged[merged.length - 1]\n if (!last || range.start > last.end) {\n merged.push({ ...range })\n continue\n }\n last.end = Math.max(last.end, range.end)\n }\n return merged\n}\n\nfunction intersectRange(range: HighlightRange, start: number, end: number): HighlightRange | null {\n const s = Math.max(range.start, start)\n const e = Math.min(range.end, end)\n return e > s ? { start: s, end: e } : null\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value))\n}\n\nfunction lower(value: string): string {\n return value.toLocaleLowerCase()\n}\n\ninterface ParsedQuery {\n tokens: (QueryToken & { lower: string })[]\n phraseLower: string\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- export { };
1
+ export {}
@@ -1,4 +1,4 @@
1
- import { c as searchSessionHistoryIndexAsync, n as buildSessionSearchIndexAsync, u as searchSessionIndexAsync } from "./history-search-C4bk1Wz_.js";
1
+ import { c as searchSessionHistoryIndexAsync, n as buildSessionSearchIndexAsync, u as searchSessionIndexAsync } from "./history-search-CcYzF8-0.js";
2
2
  //#region src/tui/history-search-worker.ts
3
3
  const indexes = /* @__PURE__ */ new Map();
4
4
  const controllers = /* @__PURE__ */ new Map();
@@ -0,0 +1,378 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-BhDjJH2R.js";
2
+ import { p as toCodemodeIdentifier } from "./source-mPExaUm8.js";
3
+ import { t as loadQuickJSWasm } from "./wasm-BVT-j5cl.js";
4
+ import { n as isWorkerToHostMessage } from "./protocol-DnhqqSmE.js";
5
+ import { Worker } from "node:worker_threads";
6
+ //#region src/codemode/runtime/host.ts
7
+ var host_exports = /* @__PURE__ */ __exportAll({ CodemodeSandbox: () => CodemodeSandbox });
8
+ const DEFAULT_TIMEOUT_MS = 3e5;
9
+ const IDENTIFIER = /^[A-Z_$][\w$]*$/i;
10
+ const RESERVED_GLOBALS = /* @__PURE__ */ new Set([
11
+ "tools",
12
+ "ALL_TOOLS",
13
+ "console",
14
+ "text",
15
+ "image",
16
+ "exit",
17
+ "globalThis",
18
+ "store",
19
+ "load"
20
+ ]);
21
+ function errorMessage(error) {
22
+ return error instanceof Error ? error.message : String(error);
23
+ }
24
+ function serializeStore(store) {
25
+ const serialized = {};
26
+ for (const [key, value] of Object.entries(store ?? {})) {
27
+ const json = JSON.stringify(value);
28
+ if (json !== void 0) serialized[key] = json;
29
+ }
30
+ return serialized;
31
+ }
32
+ /**
33
+ * The prelude that serializes values for the host runs in the same VM as the script, so a script
34
+ * that patches built-ins (for example `Array.prototype.toJSON`) can make it send malformed data.
35
+ * Payloads that do not decode throw this error, and the execution fails as a sandbox error.
36
+ */
37
+ var BridgeError = class extends Error {};
38
+ function parseBridgeJson(json, what) {
39
+ try {
40
+ return JSON.parse(json);
41
+ } catch {
42
+ throw new BridgeError(`${what} is not valid JSON`);
43
+ }
44
+ }
45
+ function parseStoreWrites(json) {
46
+ const entries = parseBridgeJson(json, "store writes");
47
+ if (!Array.isArray(entries)) throw new BridgeError("store writes are not an array");
48
+ const writes = {
49
+ set: {},
50
+ delete: []
51
+ };
52
+ for (const entry of entries) {
53
+ if (!Array.isArray(entry) || typeof entry[0] !== "string" || (entry.length === 2 ? typeof entry[1] !== "string" : entry.length !== 1)) throw new BridgeError("store writes contain a malformed entry");
54
+ const [key, value] = entry;
55
+ if (value === void 0) writes.delete.push(key);
56
+ else writes.set[key] = parseBridgeJson(value, `store value for ${JSON.stringify(key)}`);
57
+ }
58
+ return writes;
59
+ }
60
+ function parseScriptError(json) {
61
+ const parsed = parseBridgeJson(json, "script error");
62
+ if (typeof parsed !== "object" || parsed === null) throw new BridgeError("script error is not an object");
63
+ const { name, message, stack } = parsed;
64
+ if (typeof message !== "string" || name !== void 0 && typeof name !== "string" || stack !== void 0 && typeof stack !== "string") throw new BridgeError("script error is malformed");
65
+ return {
66
+ kind: "script",
67
+ name,
68
+ message,
69
+ stack
70
+ };
71
+ }
72
+ function defaultWorkerUrl() {
73
+ return new URL(import.meta.url.endsWith(".ts") ? "./worker.ts" : "./codemode-worker.js", import.meta.url);
74
+ }
75
+ /**
76
+ * One script run in its own worker and QuickJS VM. A fresh worker per run keeps
77
+ * termination simple: a runaway script, including one that only spins the
78
+ * microtask queue, is killed with `terminate()` and cannot poison a later run.
79
+ */
80
+ var Execution = class {
81
+ promise;
82
+ resolveResult;
83
+ worker;
84
+ interrupt = new SharedArrayBuffer(4);
85
+ tools;
86
+ globals;
87
+ signal;
88
+ timer;
89
+ output = [];
90
+ calls = [];
91
+ pending = /* @__PURE__ */ new Map();
92
+ finished = false;
93
+ constructor(options) {
94
+ this.promise = new Promise((resolve) => {
95
+ this.resolveResult = resolve;
96
+ });
97
+ this.tools = options.tools;
98
+ this.globals = options.globals;
99
+ this.signal = options.signal;
100
+ if (Number.isFinite(options.timeoutMs)) this.timer = setTimeout(() => {
101
+ this.finish({
102
+ kind: "timeout",
103
+ message: `Execution timed out after ${options.timeoutMs} ms`
104
+ });
105
+ }, options.timeoutMs);
106
+ if (options.signal) {
107
+ if (options.signal.aborted) this.onAbort();
108
+ else options.signal.addEventListener("abort", this.onAbort, { once: true });
109
+ }
110
+ options.wasm.then((wasm) => this.start(options, wasm), (error) => {
111
+ this.finish({
112
+ kind: "sandbox",
113
+ message: `Failed to load QuickJS: ${errorMessage(error)}`
114
+ });
115
+ });
116
+ }
117
+ abort(message) {
118
+ this.finish({
119
+ kind: "aborted",
120
+ message
121
+ });
122
+ return this.promise;
123
+ }
124
+ start(options, wasm) {
125
+ if (this.finished) return;
126
+ const workerData = {
127
+ code: options.code,
128
+ tools: [...options.tools.values()].map((tool) => ({
129
+ name: tool.name,
130
+ jsName: toCodemodeIdentifier(tool.name),
131
+ description: tool.description ?? ""
132
+ })),
133
+ globals: [...options.globals.values()].map((global) => ({
134
+ name: global.name,
135
+ spread: global.spread === true
136
+ })),
137
+ wasm,
138
+ memoryLimitBytes: options.memoryLimitBytes,
139
+ store: options.store,
140
+ interrupt: this.interrupt,
141
+ determinism: options.determinism
142
+ };
143
+ let worker;
144
+ try {
145
+ worker = new Worker(options.workerUrl, { workerData });
146
+ } catch (error) {
147
+ this.finish({
148
+ kind: "sandbox",
149
+ message: `Failed to start worker: ${errorMessage(error)}`
150
+ });
151
+ return;
152
+ }
153
+ this.worker = worker;
154
+ worker.on("message", (message) => {
155
+ try {
156
+ this.handleMessage(message);
157
+ } catch (error) {
158
+ this.finish({
159
+ kind: "sandbox",
160
+ message: error instanceof BridgeError ? `Sandbox bridge broken: ${error.message}. The script may have modified built-ins such as a prototype's toJSON.` : `Sandbox host failed: ${errorMessage(error)}`
161
+ });
162
+ }
163
+ });
164
+ worker.on("error", (error) => {
165
+ this.finish({
166
+ kind: "sandbox",
167
+ name: error instanceof Error ? error.name : void 0,
168
+ message: errorMessage(error)
169
+ });
170
+ });
171
+ worker.on("exit", (code) => {
172
+ this.finish({
173
+ kind: "sandbox",
174
+ message: `Worker exited with code ${code} before the script settled`
175
+ });
176
+ });
177
+ }
178
+ onAbort = () => {
179
+ const reason = this.signal?.reason;
180
+ this.finish({
181
+ kind: "aborted",
182
+ message: reason instanceof Error ? reason.message : "Execution aborted"
183
+ });
184
+ };
185
+ post(message) {
186
+ this.worker?.postMessage(message);
187
+ }
188
+ handleMessage(message) {
189
+ if (this.finished) return;
190
+ if (!isWorkerToHostMessage(message)) throw new BridgeError("unknown message from the worker");
191
+ switch (message.type) {
192
+ case "output":
193
+ this.output.push(message.item);
194
+ break;
195
+ case "call":
196
+ if (this.pending.has(message.id)) throw new BridgeError(`duplicate call id ${message.id}`);
197
+ this.handleCall(message);
198
+ break;
199
+ case "done":
200
+ this.handleDone(message);
201
+ break;
202
+ case "crash": this.finish({
203
+ kind: "sandbox",
204
+ message: message.message
205
+ });
206
+ }
207
+ }
208
+ handleDone(message) {
209
+ if (!message.ok) {
210
+ this.finish(parseScriptError(message.error));
211
+ return;
212
+ }
213
+ const value = message.value === void 0 ? void 0 : parseBridgeJson(message.value, "return value");
214
+ this.finish(void 0, value, parseStoreWrites(message.writes));
215
+ }
216
+ async handleCall(message) {
217
+ const { id, name } = message;
218
+ const isTool = message.target === "tool";
219
+ const record = isTool ? {
220
+ name,
221
+ seq: id,
222
+ status: "cancelled",
223
+ durationMs: 0
224
+ } : void 0;
225
+ if (record) this.calls.push(record);
226
+ const pending = {
227
+ record,
228
+ startedAt: performance.now(),
229
+ controller: new AbortController()
230
+ };
231
+ this.pending.set(id, pending);
232
+ let status;
233
+ let reply;
234
+ try {
235
+ const tool = (isTool ? this.tools : this.globals).get(name);
236
+ if (!tool) throw new Error(`Unknown ${isTool ? "tool" : "global"} "${name}"`);
237
+ const args = message.args === void 0 ? void 0 : JSON.parse(message.args);
238
+ const value = await tool.execute(args, {
239
+ signal: pending.controller.signal,
240
+ seq: id
241
+ });
242
+ reply = {
243
+ type: "result",
244
+ id,
245
+ ok: true,
246
+ payload: value === void 0 ? void 0 : JSON.stringify(value)
247
+ };
248
+ status = "ok";
249
+ } catch (error) {
250
+ reply = {
251
+ type: "result",
252
+ id,
253
+ ok: false,
254
+ payload: errorMessage(error)
255
+ };
256
+ status = "error";
257
+ }
258
+ if (!this.pending.delete(id)) return;
259
+ if (record) {
260
+ record.status = status;
261
+ record.durationMs = performance.now() - pending.startedAt;
262
+ }
263
+ this.post(reply);
264
+ }
265
+ finish(error, value, writes) {
266
+ if (this.finished) return;
267
+ this.finished = true;
268
+ clearTimeout(this.timer);
269
+ this.signal?.removeEventListener("abort", this.onAbort);
270
+ const now = performance.now();
271
+ for (const pending of this.pending.values()) {
272
+ if (pending.record) pending.record.durationMs = now - pending.startedAt;
273
+ pending.controller.abort();
274
+ }
275
+ this.pending.clear();
276
+ const result = error ? {
277
+ ok: false,
278
+ error,
279
+ output: this.output,
280
+ calls: this.calls
281
+ } : {
282
+ ok: true,
283
+ value,
284
+ output: this.output,
285
+ calls: this.calls,
286
+ storeWrites: writes ?? {
287
+ set: {},
288
+ delete: []
289
+ }
290
+ };
291
+ if (!this.worker) {
292
+ this.resolveResult(result);
293
+ return;
294
+ }
295
+ Atomics.store(new Int32Array(this.interrupt), 0, 1);
296
+ this.worker.terminate().catch(() => void 0).then(() => this.resolveResult(result));
297
+ }
298
+ };
299
+ /**
300
+ * Runs JavaScript in a QuickJS VM (a separate wasm instance) inside a worker
301
+ * thread. The script sees `tools.<name>(args)` for every registered tool, `ALL_TOOLS`,
302
+ * the output helpers `text`, `image`, `exit`, and `console.*`, `store`/`load`, and the
303
+ * configured globals; nothing else (no timers, `fetch`, `process`, `require`, modules).
304
+ *
305
+ * Each `execute()` gets its own worker and VM; the sandbox only holds the tool
306
+ * table and defaults. `close()` aborts in-flight executions.
307
+ */
308
+ var CodemodeSandbox = class {
309
+ toolsByName = /* @__PURE__ */ new Map();
310
+ globalsByName = /* @__PURE__ */ new Map();
311
+ timeoutMs;
312
+ memoryLimitBytes;
313
+ wasm;
314
+ workerUrl;
315
+ running = /* @__PURE__ */ new Set();
316
+ closed = false;
317
+ constructor(options = {}) {
318
+ this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
319
+ this.memoryLimitBytes = options.memoryLimitBytes;
320
+ this.wasm = options.wasm;
321
+ this.workerUrl = options.workerUrl ?? defaultWorkerUrl();
322
+ for (const tool of options.tools ?? []) this.registerTool(tool);
323
+ const namespaces = /* @__PURE__ */ new Set();
324
+ for (const global of options.globals ?? []) {
325
+ const parts = global.name.split(".");
326
+ if (parts.length > 2 || !parts.every((part) => IDENTIFIER.test(part)) || RESERVED_GLOBALS.has(parts[0])) throw new Error(`Invalid global name "${global.name}"`);
327
+ if (this.globalsByName.has(global.name)) throw new Error(`Global "${global.name}" is already registered`);
328
+ if (parts.length === 2) namespaces.add(parts[0]);
329
+ this.globalsByName.set(global.name, global);
330
+ }
331
+ for (const name of namespaces) if (this.globalsByName.has(name)) throw new Error(`Global "${name}" conflicts with the namespace "${name}"`);
332
+ }
333
+ /** Throws if a tool with the same name is already registered. */
334
+ registerTool(tool) {
335
+ if (this.toolsByName.has(tool.name)) throw new Error(`Tool "${tool.name}" is already registered`);
336
+ this.toolsByName.set(tool.name, tool);
337
+ }
338
+ unregisterTool(name) {
339
+ return this.toolsByName.delete(name);
340
+ }
341
+ get tools() {
342
+ return [...this.toolsByName.values()];
343
+ }
344
+ get globals() {
345
+ return [...this.globalsByName.values()];
346
+ }
347
+ /**
348
+ * `code` is an async function body: `return` and top-level `await` work.
349
+ * Never rejects for script failures; those come back as `{ ok: false }`.
350
+ * The script can use `store(key, value)` and `load(key)` on `options.store`.
351
+ */
352
+ execute(code, options = {}) {
353
+ if (this.closed) return Promise.reject(/* @__PURE__ */ new Error("Sandbox is closed"));
354
+ const execution = new Execution({
355
+ code,
356
+ tools: new Map(this.toolsByName),
357
+ globals: this.globalsByName,
358
+ timeoutMs: options.timeoutMs ?? this.timeoutMs,
359
+ signal: options.signal,
360
+ memoryLimitBytes: this.memoryLimitBytes,
361
+ store: serializeStore(options.store),
362
+ wasm: this.wasm === void 0 ? loadQuickJSWasm() : Promise.resolve(this.wasm),
363
+ workerUrl: this.workerUrl,
364
+ determinism: options.determinism
365
+ });
366
+ this.running.add(execution);
367
+ return execution.promise.finally(() => this.running.delete(execution));
368
+ }
369
+ /** Aborts in-flight executions (they resolve with `kind: "aborted"`) and rejects new ones. */
370
+ async close() {
371
+ this.closed = true;
372
+ await Promise.all([...this.running].map((execution) => execution.abort("Sandbox closed")));
373
+ }
374
+ };
375
+ //#endregion
376
+ export { host_exports as n, CodemodeSandbox as t };
377
+
378
+ //# sourceMappingURL=host-D7NrI03V.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-D7NrI03V.js","names":[],"sources":["../src/codemode/runtime/host.ts"],"sourcesContent":["import type {\n CodemodeCall,\n CodemodeCallStatus,\n CodemodeDeterminism,\n CodemodeError,\n CodemodeExecuteOptions,\n CodemodeOutputItem,\n CodemodeResult,\n CodemodeSandboxOptions,\n CodemodeStoreWrites,\n CodemodeTool,\n} from '../types'\nimport type { CodemodeWasmModule } from '../wasm'\nimport type { HostToWorkerMessage, WorkerData, WorkerToHostMessage } from './protocol'\nimport { Worker } from 'node:worker_threads'\nimport { toCodemodeIdentifier } from '../identifier'\nimport { loadQuickJSWasm } from '../wasm'\nimport { isWorkerToHostMessage } from './protocol'\n\nconst DEFAULT_TIMEOUT_MS = 300_000\nconst IDENTIFIER = /^[A-Z_$][\\w$]*$/i\nconst RESERVED_GLOBALS: ReadonlySet<string> = new Set([\n 'tools',\n 'ALL_TOOLS',\n 'console',\n 'text',\n 'image',\n 'exit',\n 'globalThis',\n 'store',\n 'load',\n])\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n\nfunction serializeStore(store: Readonly<Record<string, unknown>> | undefined): Record<string, string> {\n const serialized: Record<string, string> = {}\n for (const [key, value] of Object.entries(store ?? {})) {\n const json = JSON.stringify(value)\n if (json !== undefined)\n serialized[key] = json\n }\n return serialized\n}\n\n/**\n * The prelude that serializes values for the host runs in the same VM as the script, so a script\n * that patches built-ins (for example `Array.prototype.toJSON`) can make it send malformed data.\n * Payloads that do not decode throw this error, and the execution fails as a sandbox error.\n */\nclass BridgeError extends Error {}\n\nfunction parseBridgeJson(json: string, what: string): unknown {\n try {\n return JSON.parse(json)\n }\n catch {\n throw new BridgeError(`${what} is not valid JSON`)\n }\n}\n\nfunction parseStoreWrites(json: string): CodemodeStoreWrites {\n const entries = parseBridgeJson(json, 'store writes')\n if (!Array.isArray(entries))\n throw new BridgeError('store writes are not an array')\n const writes: CodemodeStoreWrites = { set: {}, delete: [] }\n for (const entry of entries) {\n if (\n !Array.isArray(entry)\n || typeof entry[0] !== 'string'\n || (entry.length === 2 ? typeof entry[1] !== 'string' : entry.length !== 1)\n ) {\n throw new BridgeError('store writes contain a malformed entry')\n }\n const [key, value] = entry as [string, string?]\n if (value === undefined)\n writes.delete.push(key)\n else\n writes.set[key] = parseBridgeJson(value, `store value for ${JSON.stringify(key)}`)\n }\n return writes\n}\n\nfunction parseScriptError(json: string): CodemodeError {\n const parsed = parseBridgeJson(json, 'script error')\n if (typeof parsed !== 'object' || parsed === null)\n throw new BridgeError('script error is not an object')\n const { name, message, stack } = parsed as Record<string, unknown>\n if (\n typeof message !== 'string'\n || (name !== undefined && typeof name !== 'string')\n || (stack !== undefined && typeof stack !== 'string')\n ) {\n throw new BridgeError('script error is malformed')\n }\n return { kind: 'script', name, message, stack }\n}\n\nfunction defaultWorkerUrl(): URL {\n // Source (tests, `bun run`) sits next to `worker.ts`; the published dist ships it as the\n // sibling entry `codemode-worker.js`.\n return new URL(import.meta.url.endsWith('.ts') ? './worker.ts' : './codemode-worker.js', import.meta.url)\n}\n\ninterface PendingCall {\n record: CodemodeCall | undefined\n startedAt: number\n controller: AbortController\n}\n\ninterface ExecutionOptions {\n code: string\n tools: ReadonlyMap<string, CodemodeTool>\n globals: ReadonlyMap<string, CodemodeTool>\n timeoutMs: number\n signal: AbortSignal | undefined\n memoryLimitBytes: number | undefined\n store: Record<string, string>\n wasm: Promise<CodemodeWasmModule>\n workerUrl: string | URL\n determinism: CodemodeDeterminism | undefined\n}\n\n/**\n * One script run in its own worker and QuickJS VM. A fresh worker per run keeps\n * termination simple: a runaway script, including one that only spins the\n * microtask queue, is killed with `terminate()` and cannot poison a later run.\n */\nclass Execution {\n readonly promise: Promise<CodemodeResult>\n private resolveResult!: (result: CodemodeResult) => void\n private worker: Worker | undefined\n private readonly interrupt = new SharedArrayBuffer(4)\n private readonly tools: ReadonlyMap<string, CodemodeTool>\n private readonly globals: ReadonlyMap<string, CodemodeTool>\n private readonly signal: AbortSignal | undefined\n private readonly timer: ReturnType<typeof setTimeout> | undefined\n private readonly output: CodemodeOutputItem[] = []\n private readonly calls: CodemodeCall[] = []\n private readonly pending = new Map<number, PendingCall>()\n private finished = false\n\n constructor(options: ExecutionOptions) {\n this.promise = new Promise<CodemodeResult>((resolve) => {\n this.resolveResult = resolve\n })\n this.tools = options.tools\n this.globals = options.globals\n this.signal = options.signal\n\n if (Number.isFinite(options.timeoutMs)) {\n this.timer = setTimeout(() => {\n this.finish({ kind: 'timeout', message: `Execution timed out after ${options.timeoutMs} ms` })\n }, options.timeoutMs)\n }\n\n if (options.signal) {\n if (options.signal.aborted)\n this.onAbort()\n else\n options.signal.addEventListener('abort', this.onAbort, { once: true })\n }\n\n options.wasm.then(\n wasm => this.start(options, wasm),\n (error: unknown) => {\n this.finish({ kind: 'sandbox', message: `Failed to load QuickJS: ${errorMessage(error)}` })\n },\n )\n }\n\n abort(message: string): Promise<CodemodeResult> {\n this.finish({ kind: 'aborted', message })\n return this.promise\n }\n\n private start(options: ExecutionOptions, wasm: CodemodeWasmModule): void {\n if (this.finished)\n return\n const workerData: WorkerData = {\n code: options.code,\n tools: [...options.tools.values()].map(tool => ({\n name: tool.name,\n jsName: toCodemodeIdentifier(tool.name),\n description: tool.description ?? '',\n })),\n globals: [...options.globals.values()].map(global => ({\n name: global.name,\n spread: global.spread === true,\n })),\n wasm,\n memoryLimitBytes: options.memoryLimitBytes,\n store: options.store,\n interrupt: this.interrupt,\n determinism: options.determinism,\n }\n let worker: Worker\n try {\n worker = new Worker(options.workerUrl, { workerData })\n }\n catch (error) {\n this.finish({ kind: 'sandbox', message: `Failed to start worker: ${errorMessage(error)}` })\n return\n }\n this.worker = worker\n worker.on('message', (message: unknown) => {\n // An exception here would be uncaught in the host process and leave the execution unsettled.\n try {\n this.handleMessage(message)\n }\n catch (error) {\n this.finish({\n kind: 'sandbox',\n message:\n error instanceof BridgeError\n ? `Sandbox bridge broken: ${error.message}. The script may have modified built-ins such as a prototype's toJSON.`\n : `Sandbox host failed: ${errorMessage(error)}`,\n })\n }\n })\n worker.on('error', (error: unknown) => {\n this.finish({\n kind: 'sandbox',\n name: error instanceof Error ? error.name : undefined,\n message: errorMessage(error),\n })\n })\n worker.on('exit', (code) => {\n this.finish({ kind: 'sandbox', message: `Worker exited with code ${code} before the script settled` })\n })\n }\n\n private readonly onAbort = (): void => {\n const reason: unknown = this.signal?.reason\n this.finish({ kind: 'aborted', message: reason instanceof Error ? reason.message : 'Execution aborted' })\n }\n\n private post(message: HostToWorkerMessage): void {\n this.worker?.postMessage(message)\n }\n\n private handleMessage(message: unknown): void {\n if (this.finished)\n return\n if (!isWorkerToHostMessage(message))\n throw new BridgeError('unknown message from the worker')\n switch (message.type) {\n case 'output':\n this.output.push(message.item)\n break\n case 'call':\n if (this.pending.has(message.id))\n throw new BridgeError(`duplicate call id ${message.id}`)\n void this.handleCall(message)\n break\n case 'done':\n this.handleDone(message)\n break\n case 'crash':\n this.finish({ kind: 'sandbox', message: message.message })\n break\n }\n }\n\n private handleDone(message: Extract<WorkerToHostMessage, { type: 'done' }>): void {\n // Decode everything before finish(), which must not throw once it starts.\n if (!message.ok) {\n this.finish(parseScriptError(message.error))\n return\n }\n const value = message.value === undefined ? undefined : parseBridgeJson(message.value, 'return value')\n this.finish(undefined, value, parseStoreWrites(message.writes))\n }\n\n private async handleCall(message: Extract<WorkerToHostMessage, { type: 'call' }>): Promise<void> {\n const { id, name } = message\n const isTool = message.target === 'tool'\n const record: CodemodeCall | undefined = isTool ? { name, seq: id, status: 'cancelled', durationMs: 0 } : undefined\n if (record)\n this.calls.push(record)\n const pending: PendingCall = { record, startedAt: performance.now(), controller: new AbortController() }\n this.pending.set(id, pending)\n\n let status: CodemodeCallStatus\n let reply: HostToWorkerMessage\n try {\n const tool = (isTool ? this.tools : this.globals).get(name)\n if (!tool)\n throw new Error(`Unknown ${isTool ? 'tool' : 'global'} \"${name}\"`)\n const args: unknown = message.args === undefined ? undefined : JSON.parse(message.args)\n const value = await tool.execute(args, { signal: pending.controller.signal, seq: id })\n reply = { type: 'result', id, ok: true, payload: value === undefined ? undefined : JSON.stringify(value) }\n status = 'ok'\n }\n catch (error) {\n reply = { type: 'result', id, ok: false, payload: errorMessage(error) }\n status = 'error'\n }\n\n // Already cancelled by finish(): the record keeps \"cancelled\" and the\n // worker is gone or going.\n if (!this.pending.delete(id))\n return\n if (record) {\n record.status = status\n record.durationMs = performance.now() - pending.startedAt\n }\n this.post(reply)\n }\n\n private finish(error: CodemodeError | undefined, value?: unknown, writes?: CodemodeStoreWrites): void {\n if (this.finished)\n return\n this.finished = true\n clearTimeout(this.timer)\n this.signal?.removeEventListener('abort', this.onAbort)\n\n const now = performance.now()\n for (const pending of this.pending.values()) {\n if (pending.record)\n pending.record.durationMs = now - pending.startedAt\n pending.controller.abort()\n }\n this.pending.clear()\n\n const result: CodemodeResult = error\n ? { ok: false, error, output: this.output, calls: this.calls }\n : {\n ok: true,\n value,\n output: this.output,\n calls: this.calls,\n storeWrites: writes ?? { set: {}, delete: [] },\n }\n if (!this.worker) {\n this.resolveResult(result)\n return\n }\n Atomics.store(new Int32Array(this.interrupt), 0, 1)\n this.worker\n .terminate()\n .catch(() => undefined)\n .then(() => this.resolveResult(result))\n }\n}\n\n/**\n * Runs JavaScript in a QuickJS VM (a separate wasm instance) inside a worker\n * thread. The script sees `tools.<name>(args)` for every registered tool, `ALL_TOOLS`,\n * the output helpers `text`, `image`, `exit`, and `console.*`, `store`/`load`, and the\n * configured globals; nothing else (no timers, `fetch`, `process`, `require`, modules).\n *\n * Each `execute()` gets its own worker and VM; the sandbox only holds the tool\n * table and defaults. `close()` aborts in-flight executions.\n */\nexport class CodemodeSandbox {\n private readonly toolsByName = new Map<string, CodemodeTool>()\n private readonly globalsByName = new Map<string, CodemodeTool>()\n private readonly timeoutMs: number\n private readonly memoryLimitBytes: number | undefined\n private readonly wasm: CodemodeWasmModule | Promise<CodemodeWasmModule> | undefined\n private readonly workerUrl: string | URL\n private readonly running = new Set<Execution>()\n private closed = false\n\n constructor(options: CodemodeSandboxOptions = {}) {\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS\n this.memoryLimitBytes = options.memoryLimitBytes\n this.wasm = options.wasm\n this.workerUrl = options.workerUrl ?? defaultWorkerUrl()\n for (const tool of options.tools ?? [])\n this.registerTool(tool)\n const namespaces = new Set<string>()\n for (const global of options.globals ?? []) {\n const parts = global.name.split('.')\n if (parts.length > 2 || !parts.every(part => IDENTIFIER.test(part)) || RESERVED_GLOBALS.has(parts[0]!))\n throw new Error(`Invalid global name \"${global.name}\"`)\n if (this.globalsByName.has(global.name))\n throw new Error(`Global \"${global.name}\" is already registered`)\n if (parts.length === 2)\n namespaces.add(parts[0]!)\n this.globalsByName.set(global.name, global)\n }\n for (const name of namespaces) {\n if (this.globalsByName.has(name))\n throw new Error(`Global \"${name}\" conflicts with the namespace \"${name}\"`)\n }\n }\n\n /** Throws if a tool with the same name is already registered. */\n registerTool(tool: CodemodeTool): void {\n if (this.toolsByName.has(tool.name))\n throw new Error(`Tool \"${tool.name}\" is already registered`)\n this.toolsByName.set(tool.name, tool)\n }\n\n unregisterTool(name: string): boolean {\n return this.toolsByName.delete(name)\n }\n\n get tools(): CodemodeTool[] {\n return [...this.toolsByName.values()]\n }\n\n get globals(): CodemodeTool[] {\n return [...this.globalsByName.values()]\n }\n\n /**\n * `code` is an async function body: `return` and top-level `await` work.\n * Never rejects for script failures; those come back as `{ ok: false }`.\n * The script can use `store(key, value)` and `load(key)` on `options.store`.\n */\n execute(code: string, options: CodemodeExecuteOptions = {}): Promise<CodemodeResult> {\n if (this.closed)\n return Promise.reject(new Error('Sandbox is closed'))\n const execution = new Execution({\n code,\n tools: new Map(this.toolsByName),\n globals: this.globalsByName,\n timeoutMs: options.timeoutMs ?? this.timeoutMs,\n signal: options.signal,\n memoryLimitBytes: this.memoryLimitBytes,\n store: serializeStore(options.store),\n wasm: this.wasm === undefined ? loadQuickJSWasm() : Promise.resolve(this.wasm),\n workerUrl: this.workerUrl,\n determinism: options.determinism,\n })\n this.running.add(execution)\n return execution.promise.finally(() => this.running.delete(execution))\n }\n\n /** Aborts in-flight executions (they resolve with `kind: \"aborted\"`) and rejects new ones. */\n async close(): Promise<void> {\n this.closed = true\n await Promise.all([...this.running].map(execution => execution.abort('Sandbox closed')))\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,118 @@
1
+ import { t as JsonRpcConnectionClosedError } from "./json-rpc--HXQti1E.js";
2
+ import { E as ensureDaemonRunning, T as defaultSocketPath, k as selfDaemonSpawnCommand } from "./settings-keys-Ckf29NeM.js";
3
+ import { d as connectIpcClient, f as connectOrSpawnDaemon } from "./dispatcher-BMlu2BmZ.js";
4
+ //#region src/tui/runtime/transport.ts
5
+ /** The shared daemon over its socket; spawns one when none is listening. */
6
+ function socketTransport(options = {}) {
7
+ const socketPath = { socketPath: options.socketPath ?? defaultSocketPath() };
8
+ return { async connect(connectOptions = {}) {
9
+ const spawnCommand = options.spawnCommand ?? selfDaemonSpawnCommand();
10
+ const common = {
11
+ ...connectOptions.appVersion ? { appVersion: connectOptions.appVersion } : {},
12
+ ...connectOptions.onClose ? { onClose: connectOptions.onClose } : {}
13
+ };
14
+ if (connectOptions.passive) {
15
+ const path = await ensureDaemonRunning({
16
+ ...socketPath,
17
+ spawnCommand
18
+ });
19
+ connectOptions.signal?.throwIfAborted();
20
+ return connectIpcClient({
21
+ ...common,
22
+ socketPath: path,
23
+ drainOnMismatch: false
24
+ });
25
+ }
26
+ connectOptions.signal?.throwIfAborted();
27
+ return connectOrSpawnDaemon({
28
+ ...common,
29
+ ...socketPath,
30
+ spawnCommand
31
+ });
32
+ } };
33
+ }
34
+ /**
35
+ * A remote host over a WebSocket (`zidane-server`). Nothing to spawn and
36
+ * nothing to drain: `passive` changes nothing, a version mismatch is the
37
+ * server's to resolve. The WebSocket client loads on the first connect, so
38
+ * a window that never goes remote never loads it.
39
+ */
40
+ function wsTransport(options) {
41
+ return { async connect(connectOptions = {}) {
42
+ connectOptions.signal?.throwIfAborted();
43
+ const { connectWsClient } = await import("./ws-client-N7NxzvQp.js").then((n) => n.r);
44
+ connectOptions.signal?.throwIfAborted();
45
+ return connectWsClient({
46
+ url: options.url,
47
+ ...options.token ? { token: options.token } : {},
48
+ ...options.expectHostId ? { expectHostId: options.expectHostId } : {},
49
+ ...connectOptions.appVersion ? { appVersion: connectOptions.appVersion } : {},
50
+ ...connectOptions.onClose ? { onClose: connectOptions.onClose } : {},
51
+ ...connectOptions.signal ? { signal: connectOptions.signal } : {}
52
+ });
53
+ } };
54
+ }
55
+ /** A host in this process (see `startInProcessHost`). */
56
+ function inProcessTransport(host) {
57
+ return { async connect(options = {}) {
58
+ options.signal?.throwIfAborted();
59
+ return host.connect({
60
+ ...options.appVersion ? { appVersion: options.appVersion } : {},
61
+ ...options.onClose ? { onClose: options.onClose } : {}
62
+ });
63
+ } };
64
+ }
65
+ /**
66
+ * A host in this process, started by the first connect (a window that never
67
+ * opens a session never builds one). A failed start is retried by the next.
68
+ */
69
+ function lazyInProcessTransport(start) {
70
+ let starting = null;
71
+ let host = null;
72
+ let closed = false;
73
+ const ensure = () => {
74
+ starting ??= start().then((started) => {
75
+ host = started;
76
+ return started;
77
+ }, (err) => {
78
+ starting = null;
79
+ throw err;
80
+ });
81
+ return starting;
82
+ };
83
+ return {
84
+ async connect(options = {}) {
85
+ if (closed) throw new JsonRpcConnectionClosedError();
86
+ const started = await ensure();
87
+ if (closed) throw new JsonRpcConnectionClosedError();
88
+ return inProcessTransport(started).connect(options);
89
+ },
90
+ started: () => host,
91
+ async close() {
92
+ closed = true;
93
+ const pending = starting;
94
+ if (!pending) return;
95
+ await (await pending.catch(() => null))?.close();
96
+ }
97
+ };
98
+ }
99
+ //#endregion
100
+ //#region src/tui/host/host-signals.ts
101
+ function hostSignalHandlers(sinks) {
102
+ const { onPresence, onConnected, onSessionsChanged } = sinks;
103
+ return {
104
+ onSignal: (key, signal) => {
105
+ if (signal.kind === "presence:changed") onPresence?.(key, signal.sessions);
106
+ else if (signal.kind === "sessions:changed") onSessionsChanged?.(key);
107
+ },
108
+ onConnected: (key, client) => {
109
+ onConnected?.(key);
110
+ if (onPresence) client.request("presence.list", {}).then((rows) => onPresence(key, rows), () => void 0);
111
+ },
112
+ onDisconnected: (key) => onPresence?.(key, [])
113
+ };
114
+ }
115
+ //#endregion
116
+ export { wsTransport as i, lazyInProcessTransport as n, socketTransport as r, hostSignalHandlers as t };
117
+
118
+ //# sourceMappingURL=host-signals-BcP5QKUD.js.map