zidane 7.2.4 → 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 -27242
  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-zVSyo6K1.js +0 -331
  342. package/dist/ipc-zVSyo6K1.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-h5czzllR.js +0 -1549
  363. package/dist/shell-path-h5czzllR.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,333 @@
1
+ //#region src/chat/model-chain.ts
2
+ /** Identity of a chain entry — the pair, not object identity. */
3
+ function chainEntryKey(entry) {
4
+ return `${entry.provider}\u0000${entry.model}`;
5
+ }
6
+ /** Toggle `entry`: absent → appended, present → removed. Pure. */
7
+ function toggleKeyed(chain, entry, keyOf) {
8
+ const key = keyOf(entry);
9
+ const idx = chain.findIndex((e) => keyOf(e) === key);
10
+ if (idx === -1) return [...chain, entry];
11
+ return [...chain.slice(0, idx), ...chain.slice(idx + 1)];
12
+ }
13
+ /**
14
+ * Make `entry` the primary (position 0), keeping the rest in order. Inserts
15
+ * when absent, promotes when present; no-op when it already leads.
16
+ *
17
+ * This is `↵` in the picker. It exists because toggling APPENDS: with a chain
18
+ * of `[current]`, toggling a new model produced `[current, new]` — the pick
19
+ * became a fallback and the active model never changed. "Highlight and ↵"
20
+ * means "use this one", so that gesture promotes; building a fallback list is
21
+ * the secondary gesture (`⇥`) and keeps toggle semantics.
22
+ */
23
+ function pickPrimaryKeyed(chain, entry, keyOf) {
24
+ const key = keyOf(entry);
25
+ return [entry, ...chain.filter((e) => keyOf(e) !== key)];
26
+ }
27
+ /** 1-based position of `key` in the chain, or `null` when absent. */
28
+ function positionKeyed(chain, key, keyOf) {
29
+ const idx = chain.findIndex((e) => keyOf(e) === key);
30
+ return idx === -1 ? null : idx + 1;
31
+ }
32
+ /** Same entries in the same order. */
33
+ function chainsEqualKeyed(a, b, keyOf) {
34
+ return a.length === b.length && a.every((e, i) => keyOf(e) === keyOf(b[i]));
35
+ }
36
+ /** Move the entry with `key` by one priority slot; boundary or missing = identity. */
37
+ function reorderKeyed(chain, key, delta, keyOf) {
38
+ const from = chain.findIndex((e) => keyOf(e) === key);
39
+ const to = from + delta;
40
+ if (from < 0 || to < 0 || to >= chain.length) return chain;
41
+ const next = [...chain];
42
+ const [entry] = next.splice(from, 1);
43
+ next.splice(to, 0, entry);
44
+ return next;
45
+ }
46
+ function toggleChainEntry(chain, entry) {
47
+ return toggleKeyed(chain, entry, chainEntryKey);
48
+ }
49
+ function pickChainPrimary(chain, entry) {
50
+ return pickPrimaryKeyed(chain, entry, chainEntryKey);
51
+ }
52
+ /** 1-based chain position of a provider+model pair, or `null` when not in the chain. */
53
+ function chainPositionOf(chain, provider, model) {
54
+ return positionKeyed(chain, chainEntryKey({
55
+ provider,
56
+ model
57
+ }), chainEntryKey);
58
+ }
59
+ function chainsEqual(a, b) {
60
+ return chainsEqualKeyed(a, b, chainEntryKey);
61
+ }
62
+ /**
63
+ * Did the SET of provider keys change between two chains? The agent is
64
+ * built with one provider instance per distinct chain key, so a set
65
+ * change requires a session re-activation (rebuild); a pure model /
66
+ * order change within the same providers does not.
67
+ */
68
+ function providerKeySetChanged(prev, next) {
69
+ const prevKeys = new Set(prev.map((e) => e.provider));
70
+ const nextKeys = new Set(next.map((e) => e.provider));
71
+ if (prevKeys.size !== nextKeys.size) return true;
72
+ for (const k of nextKeys) if (!prevKeys.has(k)) return true;
73
+ return false;
74
+ }
75
+ /**
76
+ * Assemble the `agent.run` `model` option from a chain.
77
+ *
78
+ * - Single-entry chain → the bare model id string (byte-identical to the
79
+ * pre-chain behavior).
80
+ * - Multi-entry chain → pinned `{ provider, model }` targets, where
81
+ * `provider` is the runtime `Provider.name` resolved via
82
+ * `providerNameFor` (chain entries carry chat-level `ProviderKey`s,
83
+ * which need not equal the instance names the agent loop matches on).
84
+ *
85
+ * Throws only on an empty chain — a programmer error, since chains
86
+ * always carry a primary. Stale or unresolvable entries degrade
87
+ * defensively instead (never throw, never produce an entry the agent
88
+ * would reject):
89
+ * - Entries whose key has no resolvable name (provider not constructed
90
+ * into the current agent) are dropped.
91
+ * - If the PRIMARY itself doesn't resolve, or fewer than two entries
92
+ * survive, fall back to the bare primary model string.
93
+ *
94
+ * `contextWindowFor` (optional) stamps each target with its model's
95
+ * context window from the host catalog, so the loop re-bases the
96
+ * auto-compact trigger when a fallback advances onto it (the host's
97
+ * explicit window is sized for the PRIMARY otherwise).
98
+ */
99
+ function buildRunModel(chain, providerNameFor, contextWindowFor) {
100
+ const primary = chain[0];
101
+ if (!primary) throw new Error("buildRunModel: chain must not be empty");
102
+ if (chain.length === 1 || providerNameFor(primary.provider) === void 0) return primary.model;
103
+ const resolved = [];
104
+ for (const entry of chain) {
105
+ const name = providerNameFor(entry.provider);
106
+ if (name === void 0) continue;
107
+ const contextWindow = contextWindowFor?.(entry);
108
+ resolved.push({
109
+ provider: name,
110
+ model: entry.model,
111
+ ...typeof contextWindow === "number" && contextWindow > 0 ? { contextWindow } : {}
112
+ });
113
+ }
114
+ return resolved.length > 1 ? resolved : primary.model;
115
+ }
116
+ /**
117
+ * Validate a persisted chain read back from `state.json`. The state file
118
+ * is user-editable JSON, so the value can be arbitrarily malformed —
119
+ * return only the well-shaped `{ provider, model }` entries (both
120
+ * non-empty strings), or `[]` for anything else. Never throws.
121
+ */
122
+ function sanitizeModelChain(value) {
123
+ if (!Array.isArray(value)) return [];
124
+ const entries = [];
125
+ for (const item of value) {
126
+ if (typeof item !== "object" || item === null || !("provider" in item) || !("model" in item)) continue;
127
+ const { provider, model } = item;
128
+ if (typeof provider === "string" && provider.length > 0 && typeof model === "string" && model.length > 0) entries.push({
129
+ provider,
130
+ model
131
+ });
132
+ }
133
+ return entries;
134
+ }
135
+ /**
136
+ * Restore the fallback tail of a persisted chain for a resolved primary
137
+ * pair. Returns entries 1+ only when the persisted chain's entry 0
138
+ * matches `primary` — a divergent chain belongs to a different selection
139
+ * (e.g. a `--model` launch override) and silently attaching it would
140
+ * surprise. Entries whose provider isn't registered, entries equal to
141
+ * the primary, and exact duplicates drop. Accepts the raw persisted
142
+ * value (`state.json` is user-editable) — shape validation included.
143
+ */
144
+ function restoreChainFallbacks(saved, primary, isRegistered) {
145
+ const chain = sanitizeModelChain(saved);
146
+ const head = chain[0];
147
+ if (chain.length < 2 || !head || head.provider !== primary.provider || head.model !== primary.model) return [];
148
+ return filterChainFallbacks(chain.slice(1), primary, isRegistered);
149
+ }
150
+ /**
151
+ * Filter candidate fallback entries against a primary pair, preserving
152
+ * picked order: entries whose provider `isAvailable` rejects, entries
153
+ * equal to the primary, and exact duplicates drop. Shared by the
154
+ * picker's apply path (live-auth availability) and persisted-chain
155
+ * restore (registry availability).
156
+ */
157
+ function filterChainFallbacks(entries, primary, isAvailable) {
158
+ const fallbacks = [];
159
+ for (const entry of entries) {
160
+ if (!isAvailable(entry.provider)) continue;
161
+ if (entry.provider === primary.provider && entry.model === primary.model) continue;
162
+ if (fallbacks.some((f) => f.provider === entry.provider && f.model === entry.model)) continue;
163
+ fallbacks.push({
164
+ provider: entry.provider,
165
+ model: entry.model
166
+ });
167
+ }
168
+ return fallbacks;
169
+ }
170
+ /**
171
+ * What of a model pick a window remembers as its default (`lastModelChain`:
172
+ * the next new session's model, the next launch's). One rule for the TUI and
173
+ * the GUI. A session on a server runs with the server's credentials, so its
174
+ * pickers list the server's providers: a pick there is remembered only when
175
+ * this computer can run its primary too (a provider only the server has
176
+ * would leave the next local session without a usable model), and the
177
+ * fallbacks this computer can't run are dropped. A pick on This computer is
178
+ * remembered as made. `null`: nothing to remember.
179
+ */
180
+ function rememberableChain(chain, providerOf, scope) {
181
+ const primary = chain[0];
182
+ if (primary === void 0) return null;
183
+ if (!scope.onServer) return [...chain];
184
+ if (!scope.canRunHere(providerOf(primary))) return null;
185
+ return chain.filter((entry) => scope.canRunHere(providerOf(entry)));
186
+ }
187
+ //#endregion
188
+ //#region src/chat/turn-operations.ts
189
+ /**
190
+ * Fork — keep every turn up to and including `turnId`, then strip any
191
+ * `tool_call` blocks left without a matching `tool_result` in the slice.
192
+ *
193
+ * Semantics:
194
+ * - Include the selected turn ("branch from HERE" mental model — the
195
+ * user wants the selected message to be the latest in the fork).
196
+ * - If the selected turn is an assistant turn with unresolved
197
+ * `tool_call` blocks (their `tool_result`s live in turns AFTER the
198
+ * slice), strip those calls. Otherwise the fork would post an
199
+ * assistant turn with no matching tool results, breaking the next
200
+ * provider call.
201
+ * - Drop turns that become empty (all blocks stripped).
202
+ *
203
+ * Returns `null` when `turnId` doesn't exist in `turns` — caller should
204
+ * surface a "turn not found" error rather than silently no-op.
205
+ */
206
+ function truncateTurnsAt(turns, turnId) {
207
+ const idx = turns.findIndex((t) => t.id === turnId);
208
+ if (idx === -1) return null;
209
+ return stripOrphanToolBlocks(turns.slice(0, idx + 1));
210
+ }
211
+ /**
212
+ * Delete — remove the turn with `turnId` and any tool blocks left
213
+ * orphaned by the removal. Returns `null` when `turnId` doesn't exist.
214
+ *
215
+ * Strategy:
216
+ * 1. Drop the target turn.
217
+ * 2. Scan the remaining turns for `tool_call`s without a matching
218
+ * `tool_result` (orphaned by removing the user turn that carried
219
+ * the result), and `tool_result`s without a matching `tool_call`
220
+ * (orphaned by removing the assistant turn that issued the call).
221
+ * Strip both sides.
222
+ * 3. Drop turns whose content is now empty.
223
+ *
224
+ * This guarantees the resulting history is protocol-clean — a follow-up
225
+ * `agent.run()` against the modified session can post turns without the
226
+ * provider rejecting the history.
227
+ */
228
+ function deleteTurnSafely(turns, turnId) {
229
+ const idx = turns.findIndex((t) => t.id === turnId);
230
+ if (idx === -1) return null;
231
+ return stripOrphanToolBlocks([...turns.slice(0, idx), ...turns.slice(idx + 1)]);
232
+ }
233
+ /**
234
+ * Walk a turn list and remove any tool blocks whose counterpart is
235
+ * missing. Drops turns left empty. Used by `truncateTurnsAt` (which can
236
+ * leave `tool_call`s orphaned when their results are past the cut) and
237
+ * `deleteTurnSafely` (which can orphan either side of a pair).
238
+ *
239
+ * Pure / total: returns a new array; never throws.
240
+ */
241
+ function stripOrphanToolBlocks(turns) {
242
+ const callIds = /* @__PURE__ */ new Set();
243
+ const resultIds = /* @__PURE__ */ new Set();
244
+ for (const turn of turns) for (const block of turn.content) if (block.type === "tool_call") callIds.add(block.id);
245
+ else if (block.type === "tool_result") resultIds.add(block.callId);
246
+ const result = [];
247
+ for (const turn of turns) {
248
+ const filtered = [];
249
+ for (const block of turn.content) {
250
+ if (block.type === "tool_call") {
251
+ if (!resultIds.has(block.id)) continue;
252
+ } else if (block.type === "tool_result") {
253
+ if (!callIds.has(block.callId)) continue;
254
+ }
255
+ filtered.push(block);
256
+ }
257
+ if (filtered.length === 0) continue;
258
+ result.push(filtered.length === turn.content.length ? turn : {
259
+ ...turn,
260
+ content: filtered
261
+ });
262
+ }
263
+ return result;
264
+ }
265
+ /**
266
+ * Replace a turn's text with `newText`, keeping every non-text block (tool
267
+ * calls, tool results, thinking, images) where it was. All text blocks
268
+ * collapse into one, placed where the first text block was; an empty or
269
+ * whitespace-only `newText` removes the text and keeps the rest.
270
+ *
271
+ * Returns `null` when the turn is missing or has no text to edit, so callers
272
+ * can report it. Untouched turns keep their identity (a store can rewrite
273
+ * only the edited row).
274
+ */
275
+ function replaceTurnTextBlocks(turns, turnId, newText) {
276
+ const idx = turns.findIndex((turn) => turn.id === turnId);
277
+ if (idx === -1) return null;
278
+ const turn = turns[idx];
279
+ const firstTextIdx = turn.content.findIndex((block) => block.type === "text");
280
+ if (firstTextIdx === -1) return null;
281
+ const content = turn.content.filter((block) => block.type !== "text");
282
+ if (newText.trim()) content.splice(Math.min(firstTextIdx, content.length), 0, {
283
+ type: "text",
284
+ text: newText
285
+ });
286
+ const next = turns.slice();
287
+ next[idx] = {
288
+ ...turn,
289
+ content
290
+ };
291
+ return next;
292
+ }
293
+ /**
294
+ * Serialize a turn's content to a clean text representation suited for
295
+ * the clipboard. Joins text + thinking blocks verbatim; tool calls and
296
+ * tool results get bracketed labels so the user can paste a readable
297
+ * record of what happened without losing structure.
298
+ *
299
+ * Empty turns return `''`.
300
+ */
301
+ function turnAsText(turn) {
302
+ const parts = [];
303
+ for (const block of turn.content) if (block.type === "text" && block.text.trim()) parts.push(block.text);
304
+ else if (block.type === "thinking" && block.text.trim()) parts.push(`[thinking]\n${block.text}`);
305
+ else if (block.type === "tool_call") parts.push(`[tool call · ${block.name}]\n${stringifyArgs(block.input)}`);
306
+ else if (block.type === "tool_result") parts.push(`[tool result]\n${typeof block.output === "string" ? block.output : JSON.stringify(block.output, null, 2)}`);
307
+ else if (block.type === "compact-summary") parts.push(`[compaction summary · ${block.replacesTurnIds.length} turn${block.replacesTurnIds.length === 1 ? "" : "s"}]\n${block.summary}`);
308
+ return parts.join("\n\n");
309
+ }
310
+ function stringifyArgs(input) {
311
+ try {
312
+ return JSON.stringify(input, null, 2);
313
+ } catch {
314
+ return String(input);
315
+ }
316
+ }
317
+ /**
318
+ * Count turns before / after the one identified by `turnId` in the
319
+ * given list. Returns `null` when the id is missing. Used to label the
320
+ * turn-details modal with `N before · M after`.
321
+ */
322
+ function countNeighbors(turnIds, turnId) {
323
+ const idx = turnIds.indexOf(turnId);
324
+ if (idx === -1) return null;
325
+ return {
326
+ before: idx,
327
+ after: turnIds.length - 1 - idx
328
+ };
329
+ }
330
+ //#endregion
331
+ export { reorderKeyed as _, turnAsText as a, toggleChainEntry as b, chainPositionOf as c, filterChainFallbacks as d, pickChainPrimary as f, rememberableChain as g, providerKeySetChanged as h, truncateTurnsAt as i, chainsEqual as l, positionKeyed as m, deleteTurnSafely as n, buildRunModel as o, pickPrimaryKeyed as p, replaceTurnTextBlocks as r, chainEntryKey as s, countNeighbors as t, chainsEqualKeyed as u, restoreChainFallbacks as v, toggleKeyed as x, sanitizeModelChain as y };
332
+
333
+ //# sourceMappingURL=turn-operations-B8sokwi5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turn-operations-B8sokwi5.js","names":[],"sources":["../src/chat/model-chain.ts","../src/chat/turn-operations.ts"],"sourcesContent":["/**\n * Model fallback chains — pure helpers for the ordered multi-model picker.\n *\n * A chain is an ordered list of provider+model pairs: entry 0 is the\n * PRIMARY (drives provider swap, effort, options, context-window display),\n * entries 1+ are run-level fallbacks forwarded to `agent.run` as pinned\n * `{ provider, model }` targets (see `AgentRunOptions.model`).\n *\n * Renderer-agnostic and side-effect free, mirroring `model-catalog.ts`:\n * the TUI picker drives toggling/numbering through these, and the chat\n * host uses them for persistence validation and run-option assembly.\n */\n\nimport type { ProviderKey } from './auth'\n\n/** One provider+model pair in a fallback chain. */\nexport interface ModelChainEntry {\n provider: ProviderKey\n model: string\n}\n\n/** Identity of a chain entry — the pair, not object identity. */\nexport function chainEntryKey(entry: ModelChainEntry): string {\n return `${entry.provider}\\u0000${entry.model}`\n}\n\n// ---------------------------------------------------------------------------\n// Keyed generics — the ONE implementation of each chain edit.\n//\n// Both clients hold chains, but in different shapes: the TUI in\n// `ModelChainEntry` (`provider`/`model`), the GUI in its wire\n// `ModelFallbackRef` (`providerKey`/`modelId`). Before this, the GUI carried\n// five hand-mirrored copies of these functions on its own shape, which is how\n// a picker gesture could diverge between surfaces. The generics take the key\n// function and know nothing about the shape; the `ModelChainEntry` wrappers\n// below keep the existing names for existing callers.\n// ---------------------------------------------------------------------------\n\n/** Toggle `entry`: absent → appended, present → removed. Pure. */\nexport function toggleKeyed<T>(chain: readonly T[], entry: T, keyOf: (e: T) => string): T[] {\n const key = keyOf(entry)\n const idx = chain.findIndex(e => keyOf(e) === key)\n if (idx === -1)\n return [...chain, entry]\n return [...chain.slice(0, idx), ...chain.slice(idx + 1)]\n}\n\n/**\n * Make `entry` the primary (position 0), keeping the rest in order. Inserts\n * when absent, promotes when present; no-op when it already leads.\n *\n * This is `↵` in the picker. It exists because toggling APPENDS: with a chain\n * of `[current]`, toggling a new model produced `[current, new]` — the pick\n * became a fallback and the active model never changed. \"Highlight and ↵\"\n * means \"use this one\", so that gesture promotes; building a fallback list is\n * the secondary gesture (`⇥`) and keeps toggle semantics.\n */\nexport function pickPrimaryKeyed<T>(chain: readonly T[], entry: T, keyOf: (e: T) => string): T[] {\n const key = keyOf(entry)\n return [entry, ...chain.filter(e => keyOf(e) !== key)]\n}\n\n/** 1-based position of `key` in the chain, or `null` when absent. */\nexport function positionKeyed<T>(chain: readonly T[], key: string, keyOf: (e: T) => string): number | null {\n const idx = chain.findIndex(e => keyOf(e) === key)\n return idx === -1 ? null : idx + 1\n}\n\n/** Same entries in the same order. */\nexport function chainsEqualKeyed<T>(a: readonly T[], b: readonly T[], keyOf: (e: T) => string): boolean {\n return a.length === b.length && a.every((e, i) => keyOf(e) === keyOf(b[i]!))\n}\n\n/** Move the entry with `key` by one priority slot; boundary or missing = identity. */\nexport function reorderKeyed<T>(chain: readonly T[], key: string, delta: -1 | 1, keyOf: (e: T) => string): readonly T[] {\n const from = chain.findIndex(e => keyOf(e) === key)\n const to = from + delta\n if (from < 0 || to < 0 || to >= chain.length)\n return chain\n const next = [...chain]\n const [entry] = next.splice(from, 1)\n next.splice(to, 0, entry as T)\n return next\n}\n\n// ---------------------------------------------------------------------------\n// `ModelChainEntry` wrappers — existing public names, unchanged contracts.\n// ---------------------------------------------------------------------------\n\nexport function toggleChainEntry(chain: readonly ModelChainEntry[], entry: ModelChainEntry): ModelChainEntry[] {\n return toggleKeyed(chain, entry, chainEntryKey)\n}\n\nexport function pickChainPrimary(chain: readonly ModelChainEntry[], entry: ModelChainEntry): ModelChainEntry[] {\n return pickPrimaryKeyed(chain, entry, chainEntryKey)\n}\n\n/** 1-based chain position of a provider+model pair, or `null` when not in the chain. */\nexport function chainPositionOf(chain: readonly ModelChainEntry[], provider: ProviderKey, model: string): number | null {\n return positionKeyed(chain, chainEntryKey({ provider, model }), chainEntryKey)\n}\n\nexport function chainsEqual(a: readonly ModelChainEntry[], b: readonly ModelChainEntry[]): boolean {\n return chainsEqualKeyed(a, b, chainEntryKey)\n}\n\n/**\n * Did the SET of provider keys change between two chains? The agent is\n * built with one provider instance per distinct chain key, so a set\n * change requires a session re-activation (rebuild); a pure model /\n * order change within the same providers does not.\n */\nexport function providerKeySetChanged(\n prev: readonly ModelChainEntry[],\n next: readonly ModelChainEntry[],\n): boolean {\n const prevKeys = new Set(prev.map(e => e.provider))\n const nextKeys = new Set(next.map(e => e.provider))\n if (prevKeys.size !== nextKeys.size)\n return true\n for (const k of nextKeys) {\n if (!prevKeys.has(k))\n return true\n }\n return false\n}\n\n/**\n * Assemble the `agent.run` `model` option from a chain.\n *\n * - Single-entry chain → the bare model id string (byte-identical to the\n * pre-chain behavior).\n * - Multi-entry chain → pinned `{ provider, model }` targets, where\n * `provider` is the runtime `Provider.name` resolved via\n * `providerNameFor` (chain entries carry chat-level `ProviderKey`s,\n * which need not equal the instance names the agent loop matches on).\n *\n * Throws only on an empty chain — a programmer error, since chains\n * always carry a primary. Stale or unresolvable entries degrade\n * defensively instead (never throw, never produce an entry the agent\n * would reject):\n * - Entries whose key has no resolvable name (provider not constructed\n * into the current agent) are dropped.\n * - If the PRIMARY itself doesn't resolve, or fewer than two entries\n * survive, fall back to the bare primary model string.\n *\n * `contextWindowFor` (optional) stamps each target with its model's\n * context window from the host catalog, so the loop re-bases the\n * auto-compact trigger when a fallback advances onto it (the host's\n * explicit window is sized for the PRIMARY otherwise).\n */\nexport function buildRunModel(\n chain: readonly ModelChainEntry[],\n providerNameFor: (key: ProviderKey) => string | undefined,\n contextWindowFor?: (entry: ModelChainEntry) => number | undefined,\n): string | Array<{ provider: string, model: string, contextWindow?: number }> {\n const primary = chain[0]\n if (!primary)\n throw new Error('buildRunModel: chain must not be empty')\n if (chain.length === 1 || providerNameFor(primary.provider) === undefined)\n return primary.model\n const resolved: Array<{ provider: string, model: string, contextWindow?: number }> = []\n for (const entry of chain) {\n const name = providerNameFor(entry.provider)\n if (name === undefined)\n continue\n const contextWindow = contextWindowFor?.(entry)\n resolved.push({\n provider: name,\n model: entry.model,\n ...(typeof contextWindow === 'number' && contextWindow > 0 ? { contextWindow } : {}),\n })\n }\n return resolved.length > 1 ? resolved : primary.model\n}\n\n/**\n * Validate a persisted chain read back from `state.json`. The state file\n * is user-editable JSON, so the value can be arbitrarily malformed —\n * return only the well-shaped `{ provider, model }` entries (both\n * non-empty strings), or `[]` for anything else. Never throws.\n */\nexport function sanitizeModelChain(value: unknown): ModelChainEntry[] {\n if (!Array.isArray(value))\n return []\n const entries: ModelChainEntry[] = []\n for (const item of value) {\n if (typeof item !== 'object' || item === null || !('provider' in item) || !('model' in item))\n continue\n const { provider, model } = item\n if (typeof provider === 'string' && provider.length > 0 && typeof model === 'string' && model.length > 0)\n entries.push({ provider, model })\n }\n return entries\n}\n\n/**\n * Restore the fallback tail of a persisted chain for a resolved primary\n * pair. Returns entries 1+ only when the persisted chain's entry 0\n * matches `primary` — a divergent chain belongs to a different selection\n * (e.g. a `--model` launch override) and silently attaching it would\n * surprise. Entries whose provider isn't registered, entries equal to\n * the primary, and exact duplicates drop. Accepts the raw persisted\n * value (`state.json` is user-editable) — shape validation included.\n */\nexport function restoreChainFallbacks(\n saved: unknown,\n primary: ModelChainEntry,\n isRegistered: (key: ProviderKey) => boolean,\n): ModelChainEntry[] {\n const chain = sanitizeModelChain(saved)\n const head = chain[0]\n if (chain.length < 2 || !head || head.provider !== primary.provider || head.model !== primary.model)\n return []\n return filterChainFallbacks(chain.slice(1), primary, isRegistered)\n}\n\n/**\n * Filter candidate fallback entries against a primary pair, preserving\n * picked order: entries whose provider `isAvailable` rejects, entries\n * equal to the primary, and exact duplicates drop. Shared by the\n * picker's apply path (live-auth availability) and persisted-chain\n * restore (registry availability).\n */\nexport function filterChainFallbacks(\n entries: readonly ModelChainEntry[],\n primary: ModelChainEntry,\n isAvailable: (key: ProviderKey) => boolean,\n): ModelChainEntry[] {\n const fallbacks: ModelChainEntry[] = []\n for (const entry of entries) {\n if (!isAvailable(entry.provider))\n continue\n if (entry.provider === primary.provider && entry.model === primary.model)\n continue\n if (fallbacks.some(f => f.provider === entry.provider && f.model === entry.model))\n continue\n fallbacks.push({ provider: entry.provider, model: entry.model })\n }\n return fallbacks\n}\n\n/**\n * What of a model pick a window remembers as its default (`lastModelChain`:\n * the next new session's model, the next launch's). One rule for the TUI and\n * the GUI. A session on a server runs with the server's credentials, so its\n * pickers list the server's providers: a pick there is remembered only when\n * this computer can run its primary too (a provider only the server has\n * would leave the next local session without a usable model), and the\n * fallbacks this computer can't run are dropped. A pick on This computer is\n * remembered as made. `null`: nothing to remember.\n */\nexport function rememberableChain<T>(\n chain: readonly T[],\n providerOf: (entry: T) => string,\n scope: { onServer: boolean, canRunHere: (providerKey: string) => boolean },\n): T[] | null {\n const primary = chain[0]\n if (primary === undefined)\n return null\n if (!scope.onServer)\n return [...chain]\n if (!scope.canRunHere(providerOf(primary)))\n return null\n return chain.filter(entry => scope.canRunHere(providerOf(entry)))\n}\n","/**\n * Pure transforms on `SessionTurn[]` used by the TUI's turn-selection\n * modal actions (fork / delete / copy). Each helper is renderer- and\n * store-agnostic so it composes the same in TUI, SDK, or test code.\n *\n * Tool-call protocol invariant the helpers preserve:\n *\n * Every `tool_call` block emitted by an assistant turn MUST be matched\n * by a `tool_result` block (same `callId`) in a later turn before the\n * next assistant turn. Providers reject histories that violate this —\n * so any operation that mutates the turn list must either keep pairs\n * intact or strip both sides.\n */\n\nimport type { SessionContentBlock, SessionTurn } from '../types'\n\n/**\n * Fork — keep every turn up to and including `turnId`, then strip any\n * `tool_call` blocks left without a matching `tool_result` in the slice.\n *\n * Semantics:\n * - Include the selected turn (\"branch from HERE\" mental model — the\n * user wants the selected message to be the latest in the fork).\n * - If the selected turn is an assistant turn with unresolved\n * `tool_call` blocks (their `tool_result`s live in turns AFTER the\n * slice), strip those calls. Otherwise the fork would post an\n * assistant turn with no matching tool results, breaking the next\n * provider call.\n * - Drop turns that become empty (all blocks stripped).\n *\n * Returns `null` when `turnId` doesn't exist in `turns` — caller should\n * surface a \"turn not found\" error rather than silently no-op.\n */\nexport function truncateTurnsAt(turns: readonly SessionTurn[], turnId: string): SessionTurn[] | null {\n const idx = turns.findIndex(t => t.id === turnId)\n if (idx === -1)\n return null\n const slice = turns.slice(0, idx + 1)\n return stripOrphanToolBlocks(slice)\n}\n\n/**\n * Delete — remove the turn with `turnId` and any tool blocks left\n * orphaned by the removal. Returns `null` when `turnId` doesn't exist.\n *\n * Strategy:\n * 1. Drop the target turn.\n * 2. Scan the remaining turns for `tool_call`s without a matching\n * `tool_result` (orphaned by removing the user turn that carried\n * the result), and `tool_result`s without a matching `tool_call`\n * (orphaned by removing the assistant turn that issued the call).\n * Strip both sides.\n * 3. Drop turns whose content is now empty.\n *\n * This guarantees the resulting history is protocol-clean — a follow-up\n * `agent.run()` against the modified session can post turns without the\n * provider rejecting the history.\n */\nexport function deleteTurnSafely(turns: readonly SessionTurn[], turnId: string): SessionTurn[] | null {\n const idx = turns.findIndex(t => t.id === turnId)\n if (idx === -1)\n return null\n const without = [...turns.slice(0, idx), ...turns.slice(idx + 1)]\n return stripOrphanToolBlocks(without)\n}\n\n/**\n * Walk a turn list and remove any tool blocks whose counterpart is\n * missing. Drops turns left empty. Used by `truncateTurnsAt` (which can\n * leave `tool_call`s orphaned when their results are past the cut) and\n * `deleteTurnSafely` (which can orphan either side of a pair).\n *\n * Pure / total: returns a new array; never throws.\n */\nfunction stripOrphanToolBlocks(turns: readonly SessionTurn[]): SessionTurn[] {\n const callIds = new Set<string>()\n const resultIds = new Set<string>()\n for (const turn of turns) {\n for (const block of turn.content) {\n if (block.type === 'tool_call')\n callIds.add(block.id)\n else if (block.type === 'tool_result')\n resultIds.add(block.callId)\n }\n }\n const result: SessionTurn[] = []\n for (const turn of turns) {\n const filtered: SessionContentBlock[] = []\n for (const block of turn.content) {\n if (block.type === 'tool_call') {\n if (!resultIds.has(block.id))\n continue // call lost its result\n }\n else if (block.type === 'tool_result') {\n if (!callIds.has(block.callId))\n continue // result lost its call\n }\n filtered.push(block)\n }\n if (filtered.length === 0)\n continue // turn is now empty — drop it\n result.push(filtered.length === turn.content.length ? turn : { ...turn, content: filtered })\n }\n return result\n}\n\n/**\n * Replace a turn's text with `newText`, keeping every non-text block (tool\n * calls, tool results, thinking, images) where it was. All text blocks\n * collapse into one, placed where the first text block was; an empty or\n * whitespace-only `newText` removes the text and keeps the rest.\n *\n * Returns `null` when the turn is missing or has no text to edit, so callers\n * can report it. Untouched turns keep their identity (a store can rewrite\n * only the edited row).\n */\nexport function replaceTurnTextBlocks(turns: readonly SessionTurn[], turnId: string, newText: string): SessionTurn[] | null {\n const idx = turns.findIndex(turn => turn.id === turnId)\n if (idx === -1)\n return null\n const turn = turns[idx]!\n const firstTextIdx = turn.content.findIndex(block => block.type === 'text')\n if (firstTextIdx === -1)\n return null\n const content: SessionContentBlock[] = turn.content.filter(block => block.type !== 'text')\n if (newText.trim())\n content.splice(Math.min(firstTextIdx, content.length), 0, { type: 'text', text: newText })\n const next = turns.slice()\n next[idx] = { ...turn, content }\n return next\n}\n\n/**\n * Serialize a turn's content to a clean text representation suited for\n * the clipboard. Joins text + thinking blocks verbatim; tool calls and\n * tool results get bracketed labels so the user can paste a readable\n * record of what happened without losing structure.\n *\n * Empty turns return `''`.\n */\nexport function turnAsText(turn: SessionTurn): string {\n const parts: string[] = []\n for (const block of turn.content) {\n if (block.type === 'text' && block.text.trim())\n parts.push(block.text)\n else if (block.type === 'thinking' && block.text.trim())\n parts.push(`[thinking]\\n${block.text}`)\n else if (block.type === 'tool_call')\n parts.push(`[tool call · ${block.name}]\\n${stringifyArgs(block.input)}`)\n else if (block.type === 'tool_result')\n parts.push(`[tool result]\\n${typeof block.output === 'string' ? block.output : JSON.stringify(block.output, null, 2)}`)\n else if (block.type === 'compact-summary')\n parts.push(`[compaction summary · ${block.replacesTurnIds.length} turn${block.replacesTurnIds.length === 1 ? '' : 's'}]\\n${block.summary}`)\n }\n return parts.join('\\n\\n')\n}\n\nfunction stringifyArgs(input: Record<string, unknown>): string {\n try {\n return JSON.stringify(input, null, 2)\n }\n catch {\n return String(input)\n }\n}\n\n/**\n * Count turns before / after the one identified by `turnId` in the\n * given list. Returns `null` when the id is missing. Used to label the\n * turn-details modal with `N before · M after`.\n */\nexport function countNeighbors(\n turnIds: readonly string[],\n turnId: string,\n): { before: number, after: number } | null {\n const idx = turnIds.indexOf(turnId)\n if (idx === -1)\n return null\n return { before: idx, after: turnIds.length - 1 - idx }\n}\n"],"mappings":"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"}