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
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022-present Yaël GUILLOUX
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -37,6 +37,12 @@ bun run auth # Anthropic + OpenAI Codex OAuth
37
37
  bun start --prompt "create a hello world app"
38
38
  ```
39
39
 
40
+ The chat host on a server (`zidane-server`; TUI and desktop windows attach over WebSocket): the image `ghcr.io/tahul/zidane-server` (`linux/amd64`, `linux/arm64`) or the binaries attached to each [GitHub release](https://github.com/Tahul/zidane/releases). See [SERVER.md](./docs/SERVER.md#install).
41
+
42
+ ```bash
43
+ docker run -d --name zidane -v zidane-data:/data -p 127.0.0.1:4280:4280 ghcr.io/tahul/zidane-server:7.2
44
+ ```
45
+
40
46
  ## Agent Setup
41
47
 
42
48
  ```ts
@@ -83,7 +89,9 @@ createAgent({
83
89
  compactStrategy: 'off', // 'off' | 'tail' (non-Anthropic compaction)
84
90
  compactThreshold: 131_072, // 128 KiB
85
91
  compactKeepTurns: 4,
86
- mediaKeepTurns: undefined, // age old image/document base64 off the wire; chat profiles use 8
92
+ mediaKeepTurns: undefined, // age image/document base64 off the wire after N messages; wins over mediaBudget
93
+ mediaBudget: undefined, // keep media inline until near the provider's caps; chat profiles use { maxItems: 80, maxBytes: 20 MiB }
94
+ maxImageEdge: undefined, // shrink oversize PNGs once, at entry; chat profiles use 2000
87
95
  autoCompact: false, // loop-native LLM summary at N% of the window; chat profiles enable it
88
96
  toolDisclosure: 'eager', // 'eager' | 'lazy' (hide MCP schemas behind tool_search)
89
97
  toolSearch: { tool: true, limit: 20, mode: 'unlock' }, // 'dispatch' = stable tool list via call_tool
@@ -181,6 +189,16 @@ Credentials come from Zidane's app credential store (`~/.zidane/credentials.json
181
189
 
182
190
  For Zed config, model selection, stdio framing details, session persistence, and in-process usage via `zidane/acp`, see [docs/ACP.md](./docs/ACP.md).
183
191
 
192
+ ### Vim / Neovim
193
+
194
+ `editors/vim` is a Vim 9 / Neovim 0.9+ plugin built on `zidane-acp`. It gives you a quick panel you can pop over any window (buffers, NERDTree, netrw, …), with editor tools so the agent can inspect your setup, read `:help`, and run commands once you approve them.
195
+
196
+ ```vim
197
+ Plug 'Tahul/zidane', { 'rtp': 'editors/vim' }
198
+ ```
199
+
200
+ `<Leader>z` or `:Zidane [prompt]` opens it; a visual selection is sent as context. See `:help zidane`.
201
+
184
202
  ## Providers
185
203
 
186
204
  All providers accept runtime credentials via params. Env vars are fallbacks.
@@ -405,7 +423,13 @@ agent.hooks.hook('context:transform', (ctx) => {
405
423
 
406
424
  `behavior.compactStrategy: 'tail'` elides older `tool_result` blocks once their combined size exceeds `compactThreshold` (default 128 KiB); the newest `compactKeepTurns` (default 4) stay intact. Anthropic users should prefer the server-side `context-management-2025-06-27` beta via `anthropic({ extraBetas, contextManagement })` — token-accurate.
407
425
 
408
- `behavior.mediaKeepTurns` is separate: it ages old inline image/document base64 off the provider wire while keeping bytes in `session.turns`. Aged media becomes an `attachment://<hash>` marker that `read_file path="attachment://..."` can re-inline. SDK default is off; built-in chat profiles set it to `8`. Proactive age-out only runs when `read_file` is registered.
426
+ Media has its own knobs. Aged media becomes an `attachment://<hash>` marker on the wire that `read_file path="attachment://..."` can re-inline; `session.turns` keeps the bytes.
427
+
428
+ - `behavior.mediaBudget` keeps inline images/documents on the wire until a request nears the provider's hard limits (`maxItems` blocks or `maxBytes` of base64), then ages out the oldest in steps of half the limit. Each age-out rewrites an earlier message and resets the prompt cache, so batching them is what keeps long image-heavy sessions cheap. `maxItems` drops to the provider's `capabilities.maxMediaPerRequest` when lower (Bedrock: 20). Built-in chat profiles, `runHeadless` and `restateBehavior()` use `{ maxItems: 80, maxBytes: 20 MiB }`.
429
+ - `behavior.maxImageEdge` shrinks PNGs larger than N px on their longest edge once, when they enter the session, with a built-in `node:zlib` codec (no native dependency). Those defaults use `2000`: past it, a request carrying more than 20 images is rejected.
430
+ - `behavior.mediaKeepTurns` is the older positional policy: media older than N messages ages out. It takes precedence over `mediaBudget` when set, and only runs when `read_file` is registered.
431
+
432
+ All three are off in the SDK by default.
409
433
 
410
434
  `behavior.autoCompact` is the heavy lever: loop-native auto-compaction. Once a turn's effective input crosses `threshold` (default `0.85`) of the context window, the loop runs a real LLM summary over the older turns, appends a `compact-summary` marker + file/skill restoration to the session, and continues — mid-run and at end-of-run. Window source is `autoCompact.contextWindow` → `provider.meta.contextWindow` (inert without one). Observe via the `compact:start` / `compact:end` hooks. SDK default off; chat profiles enable it. Distinct from `compactStrategy` (per-turn wire-only `tool_result` trim) and the always-on reactive `context_exceeded` recovery.
411
435
 
@@ -413,16 +437,18 @@ agent.hooks.hook('context:transform', (ctx) => {
413
437
 
414
438
  `behavior.elideStaleReads` decides what happens when an `edit` / `multi_edit` / `write_file` succeeds on a file the model read earlier in the run:
415
439
 
416
- - `'notice'` — append-only: a persisted `<system-reminder>` naming the stale path rides the mutating tool's own result. Never rewrites cached prefix bytes, so the prompt cache is untouched. The built-in chat profiles ship this.
440
+ - `'notice'` — append-only: a persisted `<system-reminder>` naming the stale path rides the mutating tool's own result. Never rewrites cached prefix bytes, so the prompt cache is untouched.
417
441
  - `'stub'` (or legacy `true`) — replace the stale read's output on the wire with a short stub. Reclaims the stale bytes from context, but each newly-stale read re-bills the conversation at the cache-write rate — only worth it under real context-window pressure.
418
- - `false` (default) — off. Detection is identical in both modes (success markers only; failed edits and no-op writes stale nothing), and dedup honesty around mutations holds in **every** mode — see below.
442
+ - `false` (default; also what the built-in chat profiles ship) — off. Detection is identical in both modes (success markers only; failed edits and no-op writes stale nothing), and dedup honesty around mutations holds in **every** mode — see below.
419
443
 
420
444
  See `docs/ARCHITECTURE.md` § *Cache-stable configuration* for the measured economics.
421
445
 
422
446
  ### Read dedup + read-before-edit guard
423
447
 
424
448
  - `behavior.dedupReads` (default **on**) — `read_file` returns `"unchanged since the previous read"` on identical re-reads. Per-session content-hash. Mutations are honest by construction: after an `edit`/`multi_edit`/`write_file` touches a file, the next re-read serves the full fresh body instead of the stub, then dedup resumes.
425
- - `behavior.requireReadBeforeEdit` (default **off** in the SDK core; **on** in the built-in `BUILD_AGENT` / `PLAN_AGENT` chat profiles) — `edit` / `multi_edit` reject when the file hasn't been read this session or has drifted. The refusal is a recoverable `tool_result` (tells the model to `read_file` first), and `write_file` seeds read-state so the write→edit flow needs no extra read.
449
+ - `behavior.requireReadBeforeEdit` (default **off**, including the built-in chat profiles) — `edit` / `multi_edit` reject when the file hasn't been read this session or has drifted. The refusal is a recoverable `tool_result` (tells the model to `read_file` first), and `write_file` seeds read-state so the write→edit flow needs no extra read.
450
+ - `behavior.trackShellReads` (default **off**) — with the gate on, plain shell reads (`cat`, `head`, `tail`, `nl`, `sed -n '<range>p'`) also count as reads, so the gate stops refusing files the model inspected through `shell`.
451
+ - `behavior.shellToolNudges` (default **off**; **on** in the chat profiles) — when a `shell` call does a pure read, a pure search, or a scripted file edit, append one line pointing at `read_file` / `grep` / `edit`, at most `maxPerKind` (2) times per kind per session.
426
452
  - `behavior.repeatGuard` (default **off** in the SDK core; **on** in the chat profiles) — breaks consecutive-identical tool streaks: blocks the Nth back-to-back identical call (default 4) with a pivot suggestion, aborts the run at the Mth (default 8) via the agent's `AbortController`. Defaults track the built-in `shell` + `read_file` tools; configurable via `RepeatGuardConfig`.
427
453
 
428
454
  Tracking and the dedup short-circuit are **independent** — turning `dedupReads` off does NOT disable `requireReadBeforeEdit`. Read-state keys are canonical absolute paths (resolved through `node:path`), so `read_file('src/x')` and `edit('./src/x', …)` resolve to the same entry. For subagent-shared tracking without shared turn history, use `createSpawnTool({ shareReadState: true })`.
@@ -938,6 +964,8 @@ Full index with a "where does X live" map: [docs/README.md](./docs/README.md).
938
964
  | Chat + surfaces | [CHAT.md](./docs/CHAT.md) | `zidane/chat`: renderer-agnostic engine — config, sessions, settings, safe mode, todos, commands, completion. |
939
965
  | Chat + surfaces | [TUI.md](./docs/TUI.md) | `zidane/tui`: terminal shell — screens, keybindings, modals, theming, file layout. |
940
966
  | Chat + surfaces | [IPC.md](./docs/IPC.md) | `zidane/ipc`: shared chat host + daemon; every RPC and signal; TUI/GUI parity. |
967
+ | Chat + surfaces | [SERVER.md](./docs/SERVER.md) | `zidane-server`: the chat host on a remote machine ([GHCR image, release binaries](./docs/SERVER.md#install), [Coolify](./docs/SERVER.md#deploy-on-coolify), TLS/proxy, tokens, security, operations). |
968
+ | Chat + surfaces | [MACHINES.md](./docs/MACHINES.md) | Machines: a computer lends a host its folders and shell (`local@laptop`, `zidane machine share`, "share this computer"), or a server lends itself to a local host (`local@server`); protocol, offline semantics, project files, sandbox, security. |
941
969
  | Chat + surfaces | [ARTIFACTS.md](./docs/ARTIFACTS.md) | Session artifacts: what a session produced (PRs, branches, commits, files) — model, producers, surfaces, IPC. |
942
970
  | Chat + surfaces | [EXTENSIONS.md](./docs/EXTENSIONS.md) | User extensions: `defineExtension`, the full `ctx` API, discovery, installing, authoring patterns. |
943
971
  | Integrations | [PLUGINS.md](./docs/PLUGINS.md) | `zidane/plugins`: Agent Plugins 1.0.0 loader (skills + MCP servers as portable packages). |
@@ -946,4 +974,4 @@ Full index with a "where does X live" map: [docs/README.md](./docs/README.md).
946
974
 
947
975
  ## License
948
976
 
949
- ISC
977
+ MIT
@@ -1,16 +1,20 @@
1
- import { P as defaultPromptMessage } from "./openai-compat-Dy56weK8.js";
2
- import { u as toolResultToText } from "./types-CWgENVLY.js";
3
- import { Ct as basic_default, or as readStateKey, rr as hashContent, sr as resolveReadStateMap, t as createAgent } from "./agent-D0zZnGbt.js";
4
- import { r as createProcessContext } from "./contexts-CRE9pw07.js";
1
+ import { At as basic_default, Kt as wholeReadRefusal, t as createAgent } from "./agent-DSLNmBp0.js";
5
2
  import { u as errorMessage } from "./errors-DKiMrOKq.js";
6
- import { o as loadSession, t as createSession } from "./session-BqRP1hS7.js";
3
+ import { d as toolResultToText, o as isThinkingLevel } from "./types-Cu0ZGDu9.js";
4
+ import { a as projectRootOf, t as findGitRoot } from "./project-root-B8zADr4o.js";
5
+ import { a as readFileTargets, r as readFileBatchHeader } from "./format-bytes-C7tfc3Zm.js";
6
+ import { D as resolveReadStateMap, E as readStateKey, x as hashContent } from "./tool-state-Dku6YqAB.js";
7
+ import { F as defaultPromptMessage } from "./openai-compat-CFrpH7uq.js";
8
+ import { o as loadSession } from "./session-xh9JXu6i.js";
7
9
  import { t as effectiveInputFromTurn } from "./stats-DAKBEKjc.js";
8
- import { a as successResponse, i as errorResponse, r as createJsonRpcConnection } from "./json-rpc-rSWMUh9b.js";
9
- import { r as fetchUrl } from "./fetch-url-DX75gpL0.js";
10
+ import { t as createProcessContext } from "./contexts-d7UolYot.js";
11
+ import { a as errorResponse, o as successResponse, r as createJsonRpcConnection } from "./json-rpc--HXQti1E.js";
12
+ import { r as fetchUrl } from "./fetch-url-Ct2TjDWt.js";
10
13
  import { webSearch } from "./tools/web-search.js";
11
- import { basename, resolve } from "node:path";
14
+ import { o as newSession } from "./session-factory-BUGY5P40.js";
12
15
  import { Buffer } from "node:buffer";
13
16
  import { readFileSync } from "node:fs";
17
+ import { basename, resolve } from "node:path";
14
18
  import { parseArgs } from "node:util";
15
19
  //#region src/start/shared-options.ts
16
20
  const validThinkingLevels = [
@@ -366,6 +370,109 @@ function parseHeaderArgs(raw, flag) {
366
370
  return headers;
367
371
  }
368
372
  //#endregion
373
+ //#region src/acp/client-declared-tools.ts
374
+ /** JSON-RPC method the agent sends to the client to run a client-declared tool. */
375
+ const CLIENT_TOOL_CALL_METHOD = "_zidane/tool_call";
376
+ /** Notification the agent sends when it abandons a pending {@link CLIENT_TOOL_CALL_METHOD}. */
377
+ const CLIENT_TOOL_CANCEL_METHOD = "_zidane/tool_call_cancel";
378
+ const TOOL_NAME_PATTERN = /^[a-z][\w-]{0,63}$/i;
379
+ /** Malformed or colliding `_meta.zidane.clientTools`. */
380
+ var ClientToolSpecError = class extends Error {
381
+ code = -32602;
382
+ };
383
+ /**
384
+ * Validate `_meta.zidane.clientTools`. Returns `undefined` when the key is
385
+ * absent (so resume can keep the existing set) and throws on malformed specs.
386
+ */
387
+ function parseClientToolSpecs(meta) {
388
+ const zidane = meta?.zidane;
389
+ if (zidane === void 0 || zidane === null) return void 0;
390
+ if (!isRecord$1(zidane)) throw new ClientToolSpecError("_meta.zidane must be an object.");
391
+ const raw = zidane.clientTools;
392
+ if (raw === void 0) return void 0;
393
+ if (!Array.isArray(raw)) throw new ClientToolSpecError("_meta.zidane.clientTools must be an array.");
394
+ const seen = /* @__PURE__ */ new Set();
395
+ return raw.map((entry, index) => {
396
+ if (!isRecord$1(entry)) throw new ClientToolSpecError(`clientTools[${index}] must be an object.`);
397
+ const { name, description, inputSchema, mutating } = entry;
398
+ if (typeof name !== "string" || !TOOL_NAME_PATTERN.test(name)) throw new ClientToolSpecError(`clientTools[${index}].name must match ${TOOL_NAME_PATTERN}.`);
399
+ if (seen.has(name)) throw new ClientToolSpecError(`Duplicate client tool: ${name}`);
400
+ seen.add(name);
401
+ if (typeof description !== "string" || description.length === 0) throw new ClientToolSpecError(`clientTools[${index}].description must be a non-empty string.`);
402
+ if (inputSchema !== void 0 && (!isRecord$1(inputSchema) || inputSchema.type !== "object")) throw new ClientToolSpecError(`clientTools[${index}].inputSchema must be a JSON Schema with type "object".`);
403
+ if (mutating !== void 0 && typeof mutating !== "boolean") throw new ClientToolSpecError(`clientTools[${index}].mutating must be a boolean.`);
404
+ return {
405
+ name,
406
+ description,
407
+ inputSchema: inputSchema ?? {
408
+ type: "object",
409
+ properties: {}
410
+ },
411
+ mutating: mutating ?? false
412
+ };
413
+ });
414
+ }
415
+ /** Client tools may add to the host tool set, never shadow it. */
416
+ function assertNoClientToolClash(hostTools, specs) {
417
+ const taken = /* @__PURE__ */ new Set();
418
+ for (const [key, tool] of Object.entries(hostTools ?? {})) {
419
+ taken.add(key);
420
+ taken.add(tool.spec.name);
421
+ }
422
+ const clash = specs.find((spec) => taken.has(spec.name));
423
+ if (clash) throw new ClientToolSpecError(`Client tool "${clash.name}" collides with a built-in tool.`);
424
+ }
425
+ function createClientDeclaredTools(specs, options) {
426
+ const tools = {};
427
+ for (const spec of specs) tools[spec.name] = {
428
+ spec: {
429
+ name: spec.name,
430
+ description: spec.description,
431
+ inputSchema: spec.inputSchema
432
+ },
433
+ async execute(input, ctx) {
434
+ const response = await raceAbort(options.client.sendRequest(CLIENT_TOOL_CALL_METHOD, {
435
+ sessionId: options.sessionId,
436
+ toolCallId: ctx.callId,
437
+ name: spec.name,
438
+ input
439
+ }), ctx.signal, () => notifyCancel(options, ctx.callId));
440
+ const content = typeof response?.content === "string" ? response.content : "";
441
+ if (response?.isError === true) throw new Error(content || `${spec.name} failed in the client.`);
442
+ return content;
443
+ }
444
+ };
445
+ return tools;
446
+ }
447
+ function notifyCancel(options, toolCallId) {
448
+ try {
449
+ Promise.resolve(options.client.sendNotification(CLIENT_TOOL_CANCEL_METHOD, {
450
+ sessionId: options.sessionId,
451
+ toolCallId
452
+ })).catch(() => {});
453
+ } catch {}
454
+ }
455
+ function raceAbort(promise, signal, onCancel) {
456
+ if (signal.aborted) return Promise.reject(signal.reason ?? /* @__PURE__ */ new Error("Aborted."));
457
+ return new Promise((resolve, reject) => {
458
+ const onAbort = () => {
459
+ onCancel();
460
+ reject(signal.reason ?? /* @__PURE__ */ new Error("Aborted."));
461
+ };
462
+ signal.addEventListener("abort", onAbort, { once: true });
463
+ promise.then((value) => {
464
+ signal.removeEventListener("abort", onAbort);
465
+ resolve(value);
466
+ }, (err) => {
467
+ signal.removeEventListener("abort", onAbort);
468
+ reject(err);
469
+ });
470
+ });
471
+ }
472
+ function isRecord$1(value) {
473
+ return typeof value === "object" && value !== null && !Array.isArray(value);
474
+ }
475
+ //#endregion
369
476
  //#region src/acp/mapping.ts
370
477
  function acpMcpServersToZidane(servers) {
371
478
  if (!servers) return [];
@@ -482,7 +589,6 @@ function acpPromptToPromptParts(prompt) {
482
589
  type: "text",
483
590
  text: JSON.stringify(block)
484
591
  });
485
- break;
486
592
  }
487
593
  return {
488
594
  prompt: parts,
@@ -694,24 +800,57 @@ function findToolEntry(tools, canonicalName) {
694
800
  return null;
695
801
  }
696
802
  function wrapReadFile(base, options) {
697
- return {
698
- ...base,
699
- async execute(input, ctx) {
700
- const path = typeof input.path === "string" ? input.path : "";
701
- if (!path) return "Read error: missing path.";
702
- const absPath = resolveAcpPath(ctx.handle.cwd, path);
703
- const line = lineOrDefault(input.offset);
704
- const limit = positiveNumberOrNull(input.limit);
803
+ const readOne = async (input, ctx) => {
804
+ const path = typeof input.path === "string" ? input.path : "";
805
+ if (!path) return "Read error: missing path.";
806
+ const absPath = resolveAcpPath(ctx.handle.cwd, path);
807
+ const limit = positiveNumberOrNull(input.limit);
808
+ const fromEnd = typeof input.offset === "number" && Number.isFinite(input.offset) && input.offset < 0;
809
+ let line = lineOrDefault(input.offset);
810
+ let content;
811
+ if (fromEnd) {
812
+ const refusal = await wholeReadRefusal(ctx.execution, ctx.handle, path, "read");
813
+ if (refusal) return refusal;
814
+ const response = await options.client.sendRequest("fs/read_text_file", {
815
+ sessionId: options.sessionId,
816
+ path: absPath
817
+ });
818
+ const whole = typeof response.content === "string" ? response.content : "";
819
+ const lines = whole.split("\n");
820
+ if (whole.endsWith("\n")) lines.pop();
821
+ line = Math.max(1, lines.length + Math.floor(input.offset) + 1);
822
+ content = lines.slice(line - 1, limit !== null ? line - 1 + limit : void 0).join("\n");
823
+ } else {
705
824
  const response = await options.client.sendRequest("fs/read_text_file", {
706
825
  sessionId: options.sessionId,
707
826
  path: absPath,
708
827
  line,
709
828
  ...limit !== null ? { limit } : {}
710
829
  });
711
- const content = typeof response.content === "string" ? response.content : "";
712
- seedReadState(ctx, absPath, content, line ?? 1, limit ?? Number.POSITIVE_INFINITY);
713
- if (input.lineNumbers === false) return content;
714
- return withLineNumbers(content, line ?? 1);
830
+ content = typeof response.content === "string" ? response.content : "";
831
+ }
832
+ seedReadState(ctx, absPath, content, line, limit ?? Number.POSITIVE_INFINITY);
833
+ if (input.lineNumbers === false) return content;
834
+ return withLineNumbers(content, line);
835
+ };
836
+ return {
837
+ ...base,
838
+ async execute(input, ctx) {
839
+ if (input.paths === void 0) return readOne(input, ctx);
840
+ if (Array.isArray(input.paths) && input.paths.length > 20) return `Read error: \`paths\` holds ${input.paths.length} entries; the limit is 20 per call. Split the batch.`;
841
+ const targets = readFileTargets(input);
842
+ if (targets.length === 0) return "Read error: `paths` must be a non-empty array of `{ path, offset?, limit? }` entries.";
843
+ const sections = [];
844
+ for (const target of targets) {
845
+ const body = await readOne({
846
+ path: target.path,
847
+ offset: target.offset,
848
+ limit: target.limit,
849
+ lineNumbers: input.lineNumbers
850
+ }, ctx);
851
+ sections.push(`${readFileBatchHeader(target.path)}\n${body}`);
852
+ }
853
+ return sections.join("\n\n");
715
854
  }
716
855
  };
717
856
  }
@@ -814,14 +953,6 @@ function seedReadState(ctx, path, content, offset, limit) {
814
953
  mtimeMs: Date.now()
815
954
  });
816
955
  }
817
- //#endregion
818
- //#region src/acp/server.ts
819
- const ACP_AGENT_VERSION = "1";
820
- const MODEL_CONFIG_ID = "model";
821
- const MODE_CONFIG_ID = "mode";
822
- const THINKING_CONFIG_ID = "thinking";
823
- const MODEL_OPTION_CONFIG_PREFIX = "model_option:";
824
- const PLAN_MODE_ID = "plan";
825
956
  const PLAN_READ_ONLY_TOOLS = /* @__PURE__ */ new Set([
826
957
  "read_file",
827
958
  "list_files",
@@ -831,6 +962,22 @@ const PLAN_READ_ONLY_TOOLS = /* @__PURE__ */ new Set([
831
962
  "fetch_url",
832
963
  "skills_read"
833
964
  ]);
965
+ /** Plan mode keeps the read-only built-ins plus client tools not marked `mutating`. */
966
+ function filterPlanTools(runtime) {
967
+ const filtered = {};
968
+ for (const [key, tool] of Object.entries(runtime.tools ?? {})) if (isPlanReadOnlyTool(tool.spec.name, runtime)) filtered[key] = tool;
969
+ return filtered;
970
+ }
971
+ function isPlanReadOnlyTool(name, runtime) {
972
+ return PLAN_READ_ONLY_TOOLS.has(name) || runtime.clientTools.some((tool) => tool.name === name && !tool.mutating);
973
+ }
974
+ //#endregion
975
+ //#region src/acp/server.ts
976
+ const ACP_AGENT_VERSION = "1";
977
+ const MODEL_CONFIG_ID = "model";
978
+ const MODE_CONFIG_ID = "mode";
979
+ const THINKING_CONFIG_ID = "thinking";
980
+ const MODEL_OPTION_CONFIG_PREFIX = "model_option:";
834
981
  /**
835
982
  * Search/fetch tools layered onto the DEFAULT ACP session (i.e. only when the
836
983
  * host passes no `preset` of its own). The `basic` preset ships neither — they
@@ -956,7 +1103,10 @@ var AcpServerImpl = class {
956
1103
  this.peer = peer;
957
1104
  }
958
1105
  async handleMessage(message) {
959
- if (!isObject(message) || typeof message.method !== "string") return errorResponse(normalizeId("id" in message ? message.id : null), -32600, "Invalid JSON-RPC request.");
1106
+ if (!isObject(message) || typeof message.method !== "string") {
1107
+ const id = "id" in message ? message.id : null;
1108
+ return errorResponse(normalizeId(id), -32600, "Invalid JSON-RPC request.");
1109
+ }
960
1110
  if (!("id" in message)) {
961
1111
  await this.handleNotification(message.method, message.params);
962
1112
  return null;
@@ -1000,10 +1150,7 @@ var AcpServerImpl = class {
1000
1150
  }
1001
1151
  async handleNotification(method, params) {
1002
1152
  switch (method) {
1003
- case "session/cancel":
1004
- this.cancel(asObject(params));
1005
- break;
1006
- default: break;
1153
+ case "session/cancel": this.cancel(asObject(params));
1007
1154
  }
1008
1155
  }
1009
1156
  initialize(params) {
@@ -1022,7 +1169,8 @@ var AcpServerImpl = class {
1022
1169
  close: {},
1023
1170
  additionalDirectories: {}
1024
1171
  },
1025
- auth: { ...this.options.logout ? { logout: {} } : {} }
1172
+ auth: { ...this.options.logout ? { logout: {} } : {} },
1173
+ _meta: { zidane: { clientTools: true } }
1026
1174
  },
1027
1175
  agentInfo: this.options.agentInfo ?? {
1028
1176
  name: "zidane",
@@ -1055,7 +1203,8 @@ var AcpServerImpl = class {
1055
1203
  const runtime = await this.createRuntime({
1056
1204
  cwd: params.cwd,
1057
1205
  additionalDirectories: params.additionalDirectories,
1058
- mcpServers: params.mcpServers ?? []
1206
+ mcpServers: params.mcpServers ?? [],
1207
+ _meta: params._meta
1059
1208
  }, params.sessionId, true);
1060
1209
  this.deferAvailableCommands(runtime.sessionId);
1061
1210
  return this.sessionStateResponse(runtime);
@@ -1092,15 +1241,23 @@ var AcpServerImpl = class {
1092
1241
  sessions: [...this.sessions.values()].filter((runtime) => !params.cwd || runtime.cwd === params.cwd).map((runtime) => sessionInfo(runtime)),
1093
1242
  nextCursor: null
1094
1243
  };
1095
- const ids = await store.list({
1244
+ const roots = params.cwd ? [.../* @__PURE__ */ new Set([
1245
+ projectRootOf(params.cwd),
1246
+ findGitRoot(params.cwd) ?? params.cwd,
1247
+ params.cwd
1248
+ ])] : [void 0];
1249
+ const idLists = await Promise.all(roots.map((root) => store.list({
1096
1250
  limit: 100,
1097
- ...params.cwd ? { projectRoot: params.cwd } : {}
1098
- });
1251
+ ...root ? { projectRoot: root } : {}
1252
+ })));
1253
+ const ids = [...new Set(idLists.flat())];
1099
1254
  const sessions = [];
1100
1255
  for (const id of ids) {
1101
1256
  const loaded = await store.load(id);
1102
1257
  if (!loaded) continue;
1103
- const cwd = loaded.projectRoot ?? params.cwd ?? this.sessions.get(loaded.id)?.cwd;
1258
+ const stampedCwd = typeof loaded.metadata.cwd === "string" && loaded.metadata.cwd ? loaded.metadata.cwd : void 0;
1259
+ if (params.cwd && (stampedCwd ?? loaded.projectRoot) !== params.cwd) continue;
1260
+ const cwd = stampedCwd ?? loaded.projectRoot ?? params.cwd ?? this.sessions.get(loaded.id)?.cwd;
1104
1261
  if (!cwd) continue;
1105
1262
  sessions.push({
1106
1263
  sessionId: loaded.id,
@@ -1243,8 +1400,8 @@ var AcpServerImpl = class {
1243
1400
  };
1244
1401
  }
1245
1402
  toolsForMode(runtime) {
1246
- if (runtime.modeId !== PLAN_MODE_ID) return {};
1247
- return { tools: filterPlanTools(runtime.tools) };
1403
+ if (runtime.modeId !== "plan") return {};
1404
+ return { tools: filterPlanTools(runtime) };
1248
1405
  }
1249
1406
  refreshModelDependentConfigOptions(runtime, choiceId) {
1250
1407
  const insertAfter = (option) => option.id === MODEL_CONFIG_ID;
@@ -1316,10 +1473,17 @@ var AcpServerImpl = class {
1316
1473
  const nextMcpServers = params.mcpServers === void 0 ? existing.mcpServers : acpMcpServersToZidane(params.mcpServers);
1317
1474
  if (!sameStringArray(existing.additionalDirectories, nextAdditionalDirectories)) throw new AcpProtocolError(-32602, `Session ${requestedSessionId} is already active with different additionalDirectories; close it before resuming with changed roots.`);
1318
1475
  if (!sameJson(existing.mcpServers, nextMcpServers)) throw new AcpProtocolError(-32602, `Session ${requestedSessionId} is already active with different MCP servers; close it before resuming with changed MCP configuration.`);
1476
+ const nextClientTools = parseClientToolSpecs(params._meta) ?? existing.clientTools;
1477
+ if (!sameJson(existing.clientTools, nextClientTools)) throw new AcpProtocolError(-32602, `Session ${requestedSessionId} is already active with different client tools; close it before resuming with changed tools.`);
1319
1478
  return existing;
1320
1479
  }
1321
1480
  }
1322
1481
  const mcpServers = acpMcpServersToZidane(params.mcpServers);
1482
+ const clientTools = parseClientToolSpecs(params._meta) ?? [];
1483
+ const base = this.options.preset ?? withAcpDefaultTools(basic_default);
1484
+ const agentOptions = this.options.agentOptions ?? {};
1485
+ const hostTools = mergeTools(base.tools, agentOptions.tools, this.options.tools);
1486
+ assertNoClientToolClash(hostTools, clientTools);
1323
1487
  const session = await this.resolveSession(requestedSessionId, params.cwd, mustExist);
1324
1488
  const execution = this.resolveExecution(params);
1325
1489
  const initialChoiceId = this.defaultModelChoiceId;
@@ -1327,9 +1491,13 @@ var AcpServerImpl = class {
1327
1491
  const provider = router ? router.provider : this.resolveProvider();
1328
1492
  const runModel = initialChoiceId !== void 0 ? this.modelChoices.find((choice) => choice.id === initialChoiceId).model : this.options.model;
1329
1493
  const sessionId = session.id;
1330
- const base = this.options.preset ?? withAcpDefaultTools(basic_default);
1331
- const agentOptions = this.options.agentOptions ?? {};
1332
- const wrappedTools = wrapToolsForAcpClient(mergeTools(base.tools, agentOptions.tools, this.options.tools), {
1494
+ const wrappedTools = wrapToolsForAcpClient(clientTools.length > 0 ? {
1495
+ ...hostTools,
1496
+ ...createClientDeclaredTools(clientTools, {
1497
+ client: this.requirePeer(),
1498
+ sessionId
1499
+ })
1500
+ } : hostTools, {
1333
1501
  client: this.requirePeer(),
1334
1502
  sessionId,
1335
1503
  capabilities: this.clientCapabilities,
@@ -1357,6 +1525,7 @@ var AcpServerImpl = class {
1357
1525
  cwd: params.cwd,
1358
1526
  additionalDirectories: params.additionalDirectories ?? [],
1359
1527
  mcpServers,
1528
+ clientTools,
1360
1529
  session,
1361
1530
  execution,
1362
1531
  agent,
@@ -1382,21 +1551,11 @@ var AcpServerImpl = class {
1382
1551
  const existing = await loadSession(store, sessionId);
1383
1552
  if (existing) return existing;
1384
1553
  if (mustExist) throw new AcpProtocolError(-32002, `Unknown session: ${sessionId}`);
1385
- const created = await createSession({
1386
- id: sessionId,
1387
- store,
1388
- projectRoot: cwd,
1389
- metadata: { title: "ACP session" }
1390
- });
1391
- await created.save();
1392
- return created;
1393
- }
1394
- if (sessionId && mustExist) throw new AcpProtocolError(-32002, `Unknown session: ${sessionId}`);
1395
- const created = await createSession({
1396
- ...sessionId ? { id: sessionId } : {},
1397
- ...store ? { store } : {},
1398
- projectRoot: cwd,
1399
- metadata: { title: "ACP session" }
1554
+ } else if (sessionId && mustExist) throw new AcpProtocolError(-32002, `Unknown session: ${sessionId}`);
1555
+ const created = await newSession(store, {
1556
+ cwd,
1557
+ title: "ACP session",
1558
+ ...sessionId ? { id: sessionId } : {}
1400
1559
  });
1401
1560
  if (store) await created.save();
1402
1561
  return created;
@@ -1414,12 +1573,12 @@ var AcpServerImpl = class {
1414
1573
  installHookAdapter(runtime) {
1415
1574
  const seenTools = /* @__PURE__ */ new Set();
1416
1575
  runtime.agent.hooks.hook("tool:gate", (ctx) => {
1417
- if (runtime.modeId !== PLAN_MODE_ID || isPlanReadOnlyTool(ctx.name)) return;
1576
+ if (runtime.modeId !== "plan" || isPlanReadOnlyTool(ctx.name, runtime)) return;
1418
1577
  ctx.block = true;
1419
1578
  ctx.reason = `Plan mode is read-only. Switch to Build mode before using \`${ctx.name}\`.`;
1420
1579
  });
1421
1580
  runtime.agent.hooks.hook("mcp:tool:gate", (ctx) => {
1422
- if (runtime.modeId !== PLAN_MODE_ID) return;
1581
+ if (runtime.modeId !== "plan") return;
1423
1582
  ctx.block = true;
1424
1583
  ctx.reason = `Plan mode is read-only. Switch to Build mode before using MCP tool \`${ctx.tool}\`.`;
1425
1584
  });
@@ -1444,7 +1603,7 @@ var AcpServerImpl = class {
1444
1603
  });
1445
1604
  });
1446
1605
  runtime.agent.hooks.hook("tool:gate", async (ctx) => {
1447
- if (!this.shouldRequestPermission(ctx.name, ctx.input)) return;
1606
+ if (!this.shouldRequestPermission(ctx.name, ctx.input, runtime)) return;
1448
1607
  const key = permissionKey(ctx.name, ctx.input);
1449
1608
  const cached = runtime.config.get(key);
1450
1609
  if (cached === "allow") return;
@@ -1549,9 +1708,10 @@ var AcpServerImpl = class {
1549
1708
  const fromMeta = runtime.provider.meta.contextWindow;
1550
1709
  if (typeof fromMeta === "number" && Number.isFinite(fromMeta) && fromMeta > 0) return fromMeta;
1551
1710
  }
1552
- shouldRequestPermission(name, input) {
1711
+ shouldRequestPermission(name, input, runtime) {
1553
1712
  const policy = this.options.permission;
1554
1713
  if (policy?.enabled !== true || !this.peer) return false;
1714
+ if (runtime.clientTools.some((tool) => tool.name === name && tool.mutating)) return true;
1555
1715
  if (policy.toolMatcher) return policy.toolMatcher(name, input);
1556
1716
  return name === "shell" || name === "write_file" || name === "edit" || name === "multi_edit";
1557
1717
  }
@@ -1645,14 +1805,6 @@ function mergeMcpServers(...sources) {
1645
1805
  for (const source of sources) for (const server of source ?? []) byName.set(server.name, server);
1646
1806
  return [...byName.values()];
1647
1807
  }
1648
- function filterPlanTools(tools) {
1649
- const filtered = {};
1650
- for (const [key, tool] of Object.entries(tools ?? {})) if (isPlanReadOnlyTool(tool.spec.name)) filtered[key] = tool;
1651
- return filtered;
1652
- }
1653
- function isPlanReadOnlyTool(name) {
1654
- return PLAN_READ_ONLY_TOOLS.has(name);
1655
- }
1656
1808
  function cloneConfigOptions(options) {
1657
1809
  return options.map((option) => ({
1658
1810
  ...option,
@@ -1674,9 +1826,6 @@ function configValue(options, id) {
1674
1826
  function isGeneratedModelOptionConfig(id) {
1675
1827
  return id.startsWith(MODEL_OPTION_CONFIG_PREFIX);
1676
1828
  }
1677
- function isThinkingLevel(value) {
1678
- return typeof value === "string" && validThinkingLevels.includes(value);
1679
- }
1680
1829
  function thinkingLabel(level) {
1681
1830
  return level === "xhigh" ? "Extra high" : level.charAt(0).toUpperCase() + level.slice(1);
1682
1831
  }
@@ -1702,6 +1851,10 @@ function toRpcError(err) {
1702
1851
  message: err.message,
1703
1852
  ...err.data !== void 0 ? { data: err.data } : {}
1704
1853
  };
1854
+ if (err instanceof ClientToolSpecError) return {
1855
+ code: err.code,
1856
+ message: err.message
1857
+ };
1705
1858
  return {
1706
1859
  code: -32603,
1707
1860
  message: err instanceof Error ? err.message : String(err)
@@ -1762,6 +1915,6 @@ function runAcpStdioServer(options) {
1762
1915
  };
1763
1916
  }
1764
1917
  //#endregion
1765
- export { wrapToolsForAcpClient as a, sessionBlocksToAcp as c, StartUsageError as d, buildStartLocalOptions as f, startProviderNames as h, withAcpDefaultTools as i, stopReasonFromRun as l, startLocalArgOptions as m, AcpProtocolError as n, acpMcpServersToZidane as o, parseStartArgValues as p, createAcpServer as r, acpPromptToPromptParts as s, runAcpStdioServer as t, toolResultToAcpContent as u };
1918
+ export { parseStartArgValues as _, wrapToolsForAcpClient as a, sessionBlocksToAcp as c, CLIENT_TOOL_CALL_METHOD as d, CLIENT_TOOL_CANCEL_METHOD as f, buildStartLocalOptions as g, StartUsageError as h, withAcpDefaultTools as i, stopReasonFromRun as l, parseClientToolSpecs as m, AcpProtocolError as n, acpMcpServersToZidane as o, createClientDeclaredTools as p, createAcpServer as r, acpPromptToPromptParts as s, runAcpStdioServer as t, toolResultToAcpContent as u, startLocalArgOptions as v, startProviderNames as y };
1766
1919
 
1767
- //# sourceMappingURL=acp-D-tVyUjw.js.map
1920
+ //# sourceMappingURL=acp-DQDhi2dj.js.map