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
package/docs/SKILL.md CHANGED
@@ -419,6 +419,7 @@ Every event in `AgentHooks` (`src/agent.ts`), one row each. `child:*` bubble eve
419
419
  | `context:transform` | Before each LLM call | **yes** (`messages`) | `messages` |
420
420
  | `system:transform` | Per-request system-prompt mutation (after `context:transform`) | **yes** (`system`) | `system, messages (readonly), turn, turnId, session?` |
421
421
  | `steer:inject` | Steering/follow-up injected | — | `message` |
422
+ | `spawn:queued` | A top-level spawn call waits for a slot (`maxConcurrent` reached) | — | `task, callId?, depth, waitingFor: { active, max }` |
422
423
  | `spawn:before`, `spawn:complete`, `spawn:error` | Sub-agent lifecycle | — | `id, task, callId?, stats?, error?` (`callId` = the spawn call's own id, i.e. the child's `parentCallId`) |
423
424
  | `mcp:connect` | Server's client is live (bootstrap, or first `tools/call` for `lazyConnect`) | — | `name, transport, tools, lazy?` |
424
425
  | `mcp:error` | Fatal MCP connection failure | — | `name, error` |
@@ -483,11 +484,15 @@ child:stream:server_tool_use / child:stream:server_tool_result / child:stream:er
483
484
  child:tool:gate / child:mcp:tool:gate ← mutable: block/reason/result propagate to the child
484
485
  child:tool:transform ← mutable: parent can rewrite the child's tool_result
485
486
  child:tool:before / child:tool:dispatched / child:tool:after / child:tool:error / child:tool:cancelled
487
+ child:validation:reject / child:repeat-guard:exceeded
486
488
  child:background:start / child:background:exit / child:background:reassign
487
489
  child:turn:after
488
490
  child:artifact:recorded
491
+ child:spawn:before / child:spawn:complete / child:spawn:error ← a spawn run BY a subagent
489
492
  ```
490
493
 
494
+ `child:spawn:*` carry the spawned agent's record (`id` / `depth` / `task` / `callId`, plus `stats` / `status` or `error`) and `parentChildId` (its spawner) — no `childId`, no `tracingContext`. Deeper levels chain through verbatim.
495
+
491
496
  Render nested activity without listening on the child instance. The `child:*:gate` and `child:tool:transform` events share the same `ctx` reference the child's loop awaits on (`BUBBLED_MUTABLE_EVENTS` in `src/tools/spawn.ts`), so a parent gate handler can refuse / substitute / annotate a child's tool call without registering on the child agent. `child:background:reassign` fires when a grandchild's background tasks get promoted to the child's handle on the grandchild's destroy — the chain runs at each spawn boundary until the top-level parent owns every task.
492
497
 
493
498
  ### Hook recipes
@@ -612,7 +617,7 @@ definePreset({
612
617
  tools: {
613
618
  ...basicTools,
614
619
  spawn: createSpawnTool({
615
- maxConcurrent: 5,
620
+ maxConcurrent: 5, // a 6th top-level call waits for a slot; a subagent's is refused
616
621
  model: 'claude-haiku-4-5-20251001',
617
622
  preset: { tools: {} }, // restrict children
618
623
  }),
@@ -0,0 +1,75 @@
1
+ # Terminals
2
+
3
+ Each session can open terminals that run **where the session runs**: on this machine, in its Docker container, or in its E2B / Daytona sandbox. The GUI shows them in a bottom drawer under the transcript and in a **Terminal** tab of the side panel. The agent can list and read them, type into them with approval, and its background `shell` tasks run in terminals of their own.
4
+
5
+ ## Where they run
6
+
7
+ The host (the daemon) owns every terminal, so terminals keep running while no window shows them, and every view (the drawer, the panel tab, a second window) shows the same one. The execution context opens the PTY through `ExecutionContext.openTerminal`:
8
+
9
+ | Context | How | Survives a daemon restart |
10
+ | --------- | --------------------------------------------------------------------------------------- | ------------------------- |
11
+ | `process` | `Bun.spawn(..., { terminal })`: a login shell in the session directory | no |
12
+ | `docker` | `docker exec -it` inside a local PTY; `kill` hangs up the in-container shell's group | no |
13
+ | `e2b` | `sandbox.pty` (`create` / `sendInput` / `resize` / `kill`) | yes, `pty.connect(pid)` |
14
+ | `daytona` | `process.createPty` / `resizePtySession` / `killPtySession` | yes, `connectPty(id)` |
15
+
16
+ Local PTYs need Bun, so terminals are **daemon-only**: the GUI's in-process host runs under Node and reports terminals as unavailable. Turn on the shared daemon to use them (Settings › Terminal shows the switch and whether the daemon is connected).
17
+
18
+ In a Docker or sandbox session, **New terminal on this Mac** opens a shell on the host in the project directory instead.
19
+
20
+ Terminals get the environment the agent's commands get in that context, plus `TERM=xterm-256color`, `COLORTERM=truecolor`, `TERM_PROGRAM=zidane`. Host plumbing (`PORT`, `ELECTRON_*`, `ZIDANE_DAEMON_SOCKET`, …) is removed.
21
+
22
+ ## Settings
23
+
24
+ Settings › Terminal (shared `state.json`, so every surface sees them):
25
+
26
+ | Key | Default | Off means |
27
+ | -------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
28
+ | `terminal` | on | No drawer, panel tab, header toggle, palette entries or shortcuts; the host refuses to open terminals and closes the ones the user opened. |
29
+ | `terminalAgent` | on | The agent gets no `terminal_*` tools. Requires `terminal`. |
30
+ | `terminalAgentTasks` | on | Background `shell` tasks run on pipes, without an agent tab. Requires `terminal`. |
31
+
32
+ Off is enforced by the host, not just hidden: `ChatHost.applyTerminalSettings` runs on every settings write (daemon `settings.set` and the GUI's in-process path), rebuilds agents (idle ones now, busy ones at run end, no run aborted) and, when `terminal` goes off, closes user terminals. Running agent tasks keep their terminals until they end. The page also shows the "Shared daemon runtime" switch and the daemon's connection state, since terminals only run there.
33
+
34
+ ## Host side (`src/chat/host/terminal/`)
35
+
36
+ - **History**: the last 4 M characters of raw output per terminal, replayed to a view when it attaches.
37
+ - **Pacing**: output is batched every 16 ms and sent as `terminal:output { offset, data }`. Views drop what they already have and `terminal.ack` what they wrote. Once the slowest view is 256 K characters behind, sending stops; when it catches up, every view gets `terminal:reset` from history. The daemon sends output only to connections that attached that terminal.
38
+ - **Size**: a PTY has one size; the view the user last focused or typed into sets it (`terminal.resize` with `claim: true`).
39
+ - **Labels**: the title a program sets (OSC 0/2), and for local shells the foreground program (`ps -o tpgid`).
40
+ - **Agent text**: a second, plain-text copy (escape sequences stripped, carriage-return redraws collapsed, `src/contexts/ansi-strip.ts`), 5 000 lines, for `terminal_read`.
41
+ - **Persistence**: remote terminals are saved in session metadata (`terminals`) and come back as `paused` after a restart; attaching reconnects. Local ones end with the daemon.
42
+ - **Idle suspension**: terminal input or output counts as session activity, and a session with recent terminal activity (or a running agent task terminal) is not suspended. When a sandbox does pause, its terminals are let go and reconnect on next use.
43
+ - **Limits**: 12 open terminals per session.
44
+
45
+ ## IPC
46
+
47
+ `terminal.state | open | attach | detach | write | resize | ack | restart | close | setHidden` (`src/ipc/protocol.ts`); signals `terminal:changed` (the session's full list), `terminal:output`, `terminal:reset` (`src/chat/host/signals.ts`). Shapes live in `src/chat/terminal/protocol.ts`, re-exported from `zidane/chat/pure`.
48
+
49
+ ## Agent tools (`src/chat/terminal/tools.ts`)
50
+
51
+ | Tool | What | Safe mode |
52
+ | ---------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------- |
53
+ | `terminal_list` | The session's terminals: status, owner, program, cwd | never asks |
54
+ | `terminal_read` | Recent plain-text output, up to 16 KB, with a `since` cursor | never asks |
55
+ | `terminal_write` | Types `text` then `keys` (`Enter`, `C-c`, `Up`, …), waits for output to settle | asks; on a terminal the user opened, asks every time |
56
+
57
+ A terminal marked **Hide from agent** is left out of all three.
58
+
59
+ ## Agent background tasks
60
+
61
+ In the chat host, `shell({ run_in_background: true })` runs the command in a PTY when the context supports it (`execBackground`'s `terminal` option; the `process` context today). The task shows up as an agent tab the user can watch, scroll, type into, or close (which kills the task). The model's side stays the same: the log at `output_path` receives the output as plain text (a prompt left waiting for input is written out too), and `wait_task`, `shell_kill` and `<task-notification>` work as before. One difference: stdin is now a terminal instead of `/dev/null`, so the user can answer prompts. Pagers and git's credential prompt are turned off (`PAGER=cat`, `GIT_TERMINAL_PROMPT=0`), but other tools that check for a TTY behave as they would in a shell: `vitest` starts in watch mode, `sudo` and `ssh` ask for a password. Pass their non-interactive flag (`vitest run`, `sudo -n`). Other contexts, and the headless CLI, keep running tasks on pipes.
62
+
63
+ ## GUI (`gui/src/renderer/src/terminal/`)
64
+
65
+ Rendered with [`@tahul/ghostty-web`](https://github.com/Tahul/ghostty-web) (our fork of `ghostty-web`: Ghostty's VT parser in WebAssembly, xterm.js-compatible API); `TerminalSurface.tsx` is the only file that imports it. Theme from the `--zg-*` tokens. Selecting output and choosing **Add to chat** attaches it to the prompt as a chip (`Terminal 1 · lines 12–18`). `Ctrl+`` toggles the drawer, `Ctrl+Shift+`` opens a new terminal.
66
+
67
+ - **Links**: the library finds OSC 8 hyperlinks (`ls --hyperlink`, compilers, `gh`) and URLs with a scheme, soft-wrapped ones included, and hands every click to our `linkHandler` (`linkTarget` in `links.ts`): web pages open in the Browser tab (⌘/Ctrl-click: the system browser), `file://` links in the Files panel (with `:line:col` or `#L12`), `mailto:` in the system on ⌘/Ctrl-click only, every other scheme (`javascript:`, `data:`, `vscode:`, …) never. Our own provider adds what the library can't know: file paths with a position and scheme-less local servers (`localhost:5173`).
68
+ - **Keys**: macOS editing keys send what Terminal.app and iTerm2 send, so shells handle them by default: ⌘⌫ / ⌘⌦ delete to the line start / end, ⌘← / ⌘→ go to the line start / end, ⌥⌫ / ⌥⌦ delete a word, ⌥← / ⌥→ move by word (`keys.ts`). ⌘C copies a selection, ⌘V pastes (bracketed when asked). ⌘K stays the app's command palette; **Clear** is in the right-click menu.
69
+ - **Tabs and sizing**: a terminal shown in a view stays mounted while another tab is active, so switching back is instant. A view's grid always has the PTY's size, never its own, so output is always drawn in the grid it was laid out for (no reflow, no garbled prompts). Views only ask for the size their container fits; the one being looked at (shown, focused, typed into) gets it, and when it leaves, the view still showing the terminal takes over with its last request. A view narrower than the grid clips the right edge, as tmux does. Sizes carry a `sizeSeq`, so a view keeps the newest one whether it came with the attach reply or the terminals list.
70
+ - **Opening size**: the terminal area measures the grid it fits before opening (`grid-size.ts`, the library's own fit formula), so a new PTY starts at its real size. Started at 80×24 and resized, zsh would leave its `%` partial-line mark behind and the prompt would render twice.
71
+ - **First frame**: a view stays transparent until it has its history and the size it asked for (capped at 400 ms), so a half-drawn terminal is never on screen. A grid that already has content is never resized in place (the library's reflow overlaps lines): the view clears it, resizes the empty grid and redraws what it has shown, in the same frame.
72
+ - **Late mouse reports**: the host follows the program's mouse modes from its output (`src/contexts/terminal-mouse.ts`) and drops mouse reports that arrive after tracking went off (a view decides from its own copy of the screen, a few ms behind), so a shell never prints `80;41;31M` after a program quits.
73
+ - **Emulator replies**: queries in the output (cursor position `ESC[6n`, device attributes), which prompts like starship send, are answered by the view's emulator. Replies produced while replaying history are dropped, and live ones are sent tagged (`terminal.write` with `response`); the host keeps only the size owner's, so a shell never reads extra `;1R` as typed text.
74
+ - **Mouse**: while a program tracks the mouse (vim, htop, `less --mouse`), clicks, drags and the wheel are reported to it (one report per wheel notch) and don't select text or scroll; hold **Shift** to select, scroll the scrollback, or open our right-click menu instead.
75
+ - **Known issue**: after an OSC 8 link has been clicked, the next terminal created can loop inside the WASM (`ghostty_render_state_update`, during its first fit), freezing the window. Tracked by a `test.fixme` in `gui/test/visual/terminal.test.ts`.
package/docs/TUI.md CHANGED
@@ -16,13 +16,13 @@ await runTui({ providers: { ...BUILTIN_PROVIDERS } }) // custom registry
16
16
  await runTui({ projectDb: true }) // per-repo <git-root>/.zidane/sessions.db
17
17
  ```
18
18
 
19
- Contents: [Quick start](#quick-start) · [Composition](#composition) · [Public exports](#public-exports) · [Screens](#screens) · [Keyboard](#keyboard) · [Modals](#modals) · [Theme + code highlighting](#theme--code-highlighting) · [Transcript rendering](#transcript-rendering) · [Settings modal](#settings-modal) · [Completion + slash-commands](#completion--slash-commands) · [MCP servers + OAuth](#mcp-servers--oauth) · [Auth wizard](#auth-wizard-ai-providers) · [Execution runtimes](#execution-runtimes-in-process-vs-daemon) · [Embedding](#embedding) · [Auto-update](#auto-update) · [File layout](#file-layout)
19
+ Contents: [Quick start](#quick-start) · [Composition](#composition) · [Public exports](#public-exports) · [Screens](#screens) · [Keyboard](#keyboard) · [Modals](#modals) · [Theme + code highlighting](#theme--code-highlighting) · [Transcript rendering](#transcript-rendering) · [Settings modal](#settings-modal) · [Completion + slash-commands](#completion--slash-commands) · [MCP servers + OAuth](#mcp-servers--oauth) · [Auth wizard](#auth-wizard-ai-providers) · [Execution runtimes](#execution-runtimes-in-process-vs-daemon) · [Several hosts](#several-hosts-remote-hosts) · [Embedding](#embedding) · [Auto-update](#auto-update) · [File layout](#file-layout)
20
20
 
21
21
  ## Quick start
22
22
 
23
23
  `runTui` is a one-shot launcher: boots OpenTUI, registers Tree-sitter grammars, resolves config, mounts `<App>`, then `process.exit(0)`s on dismiss (Ctrl+C, or Esc on the auth screen). Calling it twice throws.
24
24
 
25
- Env overrides: `ZIDANE_STORAGE_DIR`, `ZIDANE_PREFIX`, `ZIDANE_PROJECT_DB`, `ZIDANE_NO_UPDATE`, `ZIDANE_NO_DAEMON` / `--no-daemon`, `ZIDANE_DEBUG` (renderer `gatherStats`, fps/frametime to stderr on exit).
25
+ Env overrides: `ZIDANE_STORAGE_DIR`, `ZIDANE_PREFIX`, `ZIDANE_PROJECT_DB`, `ZIDANE_NO_UPDATE`, `ZIDANE_NO_DAEMON` / `--no-daemon`, `ZIDANE_HOST_URL` + `ZIDANE_HOST_TOKEN` / `--host` + `--token` (remote host), `ZIDANE_NO_REMOTE` / `--no-remote`, `ZIDANE_DEBUG` (renderer `gatherStats`, fps/frametime to stderr on exit).
26
26
 
27
27
  Renderer fps is `Settings.targetFps` (30/60/120): seeds the renderer at boot, live flips apply via `renderer.targetFps`/`maxFps`.
28
28
 
@@ -230,7 +230,7 @@ Theme switching is real-time: every `useColors()`/`useSelectStyle()`/`useSurface
230
230
 
231
231
  Fenced code blocks highlight via Tree-sitter (`src/tui/tree-sitter.ts`). Registered grammars: `python`, `bash`(`sh`/`shell`/`zsh`), `json`, `rust`(`rs`), `go`(`golang`), `yaml`(`yml`), `html`(`htm`), `css`, `haskell`(`hs`), `c`, `cpp`(`c++`/`cxx`/`cc`), `csharp`(`cs`/`c#`), `elixir`(`ex`/`exs`), `ruby`(`rb`), `diff`(`patch`), `scala`(`sbt`/`sc`), `julia`(`jl`), `ocaml`(`ml`), `r`, `perl`(`pl`/`pm`), `swift`, `kotlin`(`kt`/`kts`), `fsharp`(`fs`/`fsx`/`fsi`), `sql`(`psql`/`mysql`/`sqlite`/`plsql` — vendored into the TUI binary via `ZIDANE_LOCAL_TREE_SITTER_SQL_WASM`), plus whatever OpenTUI ships by default (TS/JS/JSX/TSX). `registerTreeSitterParsers()` runs synchronously at boot; `initTreeSitterWorker()` warms the worker off the critical path. Wasms download lazily and cache under OpenTUI's data path; failures fall back to plain text.
232
232
 
233
- `Settings.toolCallDisplay` picks the `'tool'` event rendering (`'hidden'` / `'formatted'` (default) / `'full'`); `Settings.showEditDiffs` renders `edit`/`multi_edit`/`write_file` as a unified diff via `EditDiffBlock` regardless of that mode, with per-hunk applied/denied/skipped/failed badges when outcomes are present. Both are engine-shaped contracts documented in [CHAT.md § Tool call display](./CHAT.md#tool-call-display) and [§ Edit-diff rendering](./CHAT.md#edit-diff-rendering) — this doc only owns the OpenTUI rendering (`<EventLine>` dispatch in `components.tsx`, diff colors from `theme.surfaces.diff`).
233
+ `Settings.toolCallDisplay` picks the `'tool'` event rendering (`'hidden'` / `'formatted'` (default) / `'full'`); `Settings.showEditDiffs` renders `edit`/`multi_edit`/`write_file` as a unified diff via `EditDiffBlock` regardless of that mode, with per-hunk applied/denied/skipped/failed badges when outcomes are present. Both are engine-shaped contracts documented in [CHAT.md § Tool call display](./CHAT.md#tool-call-display) and [§ Edit-diff rendering](./CHAT.md#edit-diff-rendering) — this doc only owns the OpenTUI rendering (`<EventLine>` dispatch in `transcript/event-line.tsx`, diff colors from `theme.surfaces.diff`).
234
234
 
235
235
  ## Transcript rendering
236
236
 
@@ -249,16 +249,20 @@ Fenced code blocks highlight via Tree-sitter (`src/tui/tree-sitter.ts`). Registe
249
249
  Tabbed: **Agent**, **UI** (always present) + **Keybindings**, **Authentication**, **Instructions** (present when the host wires the matching data props) + **Skills**, **MCP servers** (always) + **Extensions** (present when extensions are discoverable). One shared search input filters the active tab; `←`/`→` cycle tabs, `↑`/`↓` navigate, `↵` toggle/cycle/pick/edit.
250
250
 
251
251
  - **Agent / UI** rows are toggle/choice/action, sourced from `SETTINGS_TOGGLES`/`SETTINGS_CHOICES`/`SettingsActions` in `src/chat/settings-context.tsx` — current keys, labels, categories: [CHAT.md § Settings](./CHAT.md#settings).
252
+ - **Agent → Environments** opens `EnvironmentsSettingsModal` (`src/tui/environments-settings.tsx`): the default environment for new sessions, each kind's on/off and options, secrets (`ctrl+x` resets / clears). Same descriptors and schema check as the GUI's Environments tab — [CHAT.md § Session environments](./CHAT.md#session-environments). A kind with a connection to check gets a **test connection** row. With more than Local enabled, `newSession` opens `EnvironmentPickerModal` first (the focused kind's note says what it will clone). The session details modal shows the session's environment and runs its commands (push branch, open pull request) with `1`–`9`.
252
253
  - **Keybindings** embeds the `KEYBINDING_DEFS` catalog (shared with the standalone `KeybindingsModal` via `groupBindings`); `↵` opens `keybindings.json`.
253
254
  - **Authentication** shows the active + detected providers; `↵` pops the full-screen `AuthScreen`.
254
- - **Instructions** answers "what's in my context, and where from" — one row per `ContextSegment` (base prompt, each `AGENTS.md`/`CLAUDE.md`, skills catalog, MCP instructions, subagent defs), labelled by origin (`built-in`/`file`/`generated`/`mcp server`). `tab` expands inline, `↵` opens file-backed rows in `$EDITOR`. The `SYSTEM.md` row's `↵` **creates** the override file (seeded from the doctrine-only prompt) when none exists — the one Instructions action that writes. Full contract: [CHAT.md § `SYSTEM.md`](./CHAT.md#systemmd--overriding-the-built-in-prompt) and [§ Context segments](./CHAT.md#context-segments).
255
+ - **Instructions** answers "what's in my context, and where from" — one row per `ContextSegment` (base prompt, each `AGENTS.md`/`CLAUDE.md`, skills catalog, MCP instructions, searchable-tools catalog), labelled by origin (`built-in`/`file`/`generated`/`mcp server`). `tab` expands inline, `↵` opens file-backed rows in `$EDITOR`. The `SYSTEM.md` row's `↵` **creates** the override file (seeded from the doctrine-only prompt) when none exists — the one Instructions action that writes. Full contract: [CHAT.md § `SYSTEM.md`](./CHAT.md#systemmd--overriding-the-built-in-prompt) and [§ Context segments](./CHAT.md#context-segments).
256
+ - **Hosts** (only with Settings → Remote hosts on, and `ZIDANE_NO_REMOTE` unset): This computer and the saved servers, each with its status (connected / reconnecting / offline / token refused / different server: another server answers at its URL, not retried) and the server's name and version. `↵` on `+ add a server` asks for the URL, then the token (typed or pasted, shown as dots), and saves nothing unless the server answers to it; a refusal says why (bad URL, token refused, unreachable, TLS, not a zidane-server, a different server at that URL). `↵`/`ctrl+t` tests the focused server, `ctrl+b` opens its machines (share this computer with it, use it as a machine, its machines: [MACHINES.md § Client UI](./MACHINES.md#client-ui)), `ctrl+e` renames it, `ctrl+x` removes it and its token (asks first). This computer and a `--host` server are not removable. See [Several hosts](#several-hosts-remote-hosts).
255
257
  - **Skills / MCP servers / Extensions** render the discovered catalogs as enable/disable checklists (`enabledSkills`/`enabledMcps` default to "everything enabled"; toggling seeds an explicit allowlist so newly-discovered entries don't silently opt in). Extension semantics: [EXTENSIONS.md](./EXTENSIONS.md).
256
258
 
257
- Reachable from every screen but `auth`; with no live agent yet (home/sessions/model-picker), the Instructions tab composes a preview of the *next* session (`live: false`) via the same `composeHostContext` helper `buildAgent` uses.
259
+ **On a server's session** (remote hosts on), the modal edits that server: its title is `settings · <server>`, and the settings the server owns (safe mode, sandbox, limits, compaction, the enabled skills / MCP servers / extensions, …) are read with `settings.get` and written with `settings.set` there, never into this computer's `state.json`. This window's own settings (the UI tab, theme, fps, icons, editor and keyboard habits, `useDaemon`, `remoteHosts`: `isWindowOnlySetting` in `src/chat/host-scoped-settings.ts`, shared with the GUI) stay local. The tabs that read this computer's files change: **Authentication** lists the server's providers (`auth.status`); `↵` stores an API key there (`auth.setApiKey`, typed masked), `o` signs an OAuth provider in with the browser on this computer and the tokens on the server (`auth.oauth.*`, `src/tui/settings/server-oauth.tsx`: the URL / device code shown, `p` pastes a code or the address the browser landed on, esc cancels on the server), `ctrl+x` removes the stored ones (`auth.remove`). **Skills / MCP servers / Extensions** list the server's catalogs for the session's folder there (`catalog.skills` / `catalog.mcps` / `catalog.extensions` + `catalog.plugins`, `src/tui/settings/server-catalog-panel.tsx`), each with the server's enabled state; `↵` turns an entry off or on, written to the server's enabled list (the first toggle seeds an explicit list, like this computer's tabs). MCP secrets arrive redacted. `o` signs an HTTP MCP server in the same way (a loopback on this computer, the tokens on the server). When the server takes installs (`ipc.hello`'s `remoteInstalls`, its `allowRemoteInstalls`): `i` installs a skill / extension from a GitHub or npm spec into the server user's scope (`catalog.install`), `ctrl+x` then `y` removes a user-scope one (`catalog.remove` / `mcp.remove`), `ctrl+u` updates an extension (`catalog.update`), `a` adds an MCP server (`<name> <url>` then an optional masked Authorization header, or `<name> <command> [args]`; `mcp.upsert`); a `catalog:changed` from any window re-reads the tab. `!` in a server session streams from the server (`sessions.workspaceExecStream`; esc kills it there); so does `!` in a machine session (`local@` / `worktree@<machine>`) on any host, This computer's included: it runs on the machine, never in this window's shell. A server too old for the catalogs gets its enabled lists only (the previous panel). **Instructions** is hidden (it composes this computer's context). The rule is keyed on the active session's host being a server, saved or `--host`, remote hosts on or off (`isActiveOnServer`, `src/tui/live-settings.ts`), never on "another server than the default": a setting flipped outside the modal (the command palette, an extension, the modal of a `--host` window with remote hosts off) publishes only the server's keys (`src/tui/settings/use-settings-publish.ts`); a server's `settings:changed` is applied for its host-scoped keys only (another window's theme, `remoteHosts` or `useDaemon` never reach this one); and only window-only keys are written to this computer's `state.json` while on a server. Back on a This computer session, the window takes this computer's host-scoped values again from its `state.json`.
260
+
261
+ Reachable from every screen but `auth`; with no live agent yet (home/sessions/model-picker), the Instructions tab composes a preview of the *next* session (`live: false`) via the same `composeHostContext` helper the host uses to build agents.
258
262
 
259
263
  ## Completion + slash-commands
260
264
 
261
- Two built-in providers: **skills** (`/`, substring match on name+description, prefix sorts first) and **files** (`@`, exact-name → prefix → substring → path-substring; `git ls-files --cached --others --exclude-standard` when in a repo, else a depth-walked scan capped at 10,000 files). Commit inserts `<trigger><value> `. On submit, `App` walks the buffer via each provider's `parseReferences(text)`; skill refs call `agent.activateSkill(name)` before `agent.run()` (slash text stays visible to the model).
265
+ Two built-in providers: **skills** (`/`, substring match on name+description, prefix sorts first) and **files** (`@`, exact-name → prefix → substring → path-substring; `git ls-files --cached --others --exclude-standard` when in a repo, else a depth-walked scan capped at 10,000 files). Commit inserts `<trigger><value> `. `↵` and `tab` both commit (the `chats` popup's `tab` toggles scope instead). On submit, `App` walks the buffer via each provider's `parseReferences(text)`; skill refs ride the send (`activatedSkills`) and the host activates them before the run (slash text stays visible to the model).
262
266
 
263
267
  References highlight in two places: the live textarea (`useChipHighlights`) and the submitted echo (`UserPromptBlock` via `splitPromptSegments`), both keyed off `theme.surfaces.chips[providerId]` (fallback `chips.default`). Adding a third provider: implement `CompletionProvider<TItem>` in `zidane/chat`, pass it in `completionProviders` — the popup picks it up automatically.
264
268
 
@@ -280,11 +284,48 @@ Discovered servers (`mcps.json` + `mcp.json` under `.{prefix}/` or `.agents/`, p
280
284
 
281
285
  `AuthScreen`/`SetupWizard`: pick provider → pick method (API key or OAuth, gated on `supportsOAuth`) → enter key (`setProviderCredential`) or run OAuth (`runOAuthLogin`, surfaced via `<OAuthAuthBlock>` with browser-open, copy, and paste-back). A first OAuth login is stored as the `Default` account; when the provider already holds OAuth accounts, picking OAuth first asks whether to re-authenticate one of them or add another, then for the new account's name (required). Settings → Authentication lists every stored account under its provider; `↵` on one makes it active, `ctrl+e` renames it (footer editor, empty = `Default`), `ctrl+x` (twice) removes it. A pre-existing user picker (when ≥1 provider is authed) lists current credentials plus `+ add or re-configure`. Esc bails to the picker, or exits the TUI on true first launch.
282
286
 
283
- ## Execution runtimes (in-process vs daemon)
284
-
285
- `activateSession` (`src/tui/app.tsx`) is the single fork point: **in-process** (default) builds the agent loop in this window's process; **daemon** (`Settings.useDaemon`, experimental) connects to a shared daemon (`src/tui/runtime/daemon.ts`) so multiple windows converge on the same live stream, queue, drafts, approvals, and presence. An activation populates exactly one of `agentRef`/`daemonRef` — never both — and both branches feed the same React state, so every screen/modal/keybinding works unmodified in either mode.
286
-
287
- Coexistence: the store (`sessions.db`/`state.json`) is neutral ground both runtimes read/write; a cross-process run guard (`status: 'running'`, 5-minute freshness bound) stops two runtimes stacking `agent.run()` on one session; while a controller is connected the daemon owns `state.json` settings writes. Turning it off always works: every daemon touchpoint gates on the live controller, `--no-daemon`/`ZIDANE_NO_DAEMON=1` beat the setting, and a connect failure fails soft to `buildAgent` with a visible notice. Full protocol, lifecycle, and the daemon-mode asymmetries (`/` commands needing a local agent, `!`/`/` executing in the issuing window): [IPC.md](./IPC.md).
287
+ ## Execution runtimes (in-process, daemon, remote)
288
+
289
+ Sessions always run in a chat host; `activateSession` (`src/tui/host/use-session-activation.ts`) connects the window to it with `connectHostSession` (`src/tui/runtime/host-session.ts`) and only the transport differs (`src/tui/runtime/transport.ts`). **In-process** (default): a host inside this window's process, started on first use and built from the window's own config, extension registry and bridges; a run lives with its window (switching sessions mid-run is refused, leaving a session disposes it, quitting drains the host). **Daemon** (`Settings.useDaemon`, experimental): the shared daemon over its socket, so multiple windows converge on the same live stream, queue, drafts, approvals, and presence, and runs outlive their window. **Remote** (`zidane --host <wss-url> --token-file <path>`, or `ZIDANE_HOST_URL` / `ZIDANE_HOST_TOKEN`; experimental): every session of the window runs on a zidane-server over WebSocket, with daemon semantics (multi-process: runs outlive the window, switching mid-run is allowed, presence, the health dot plus `host: <name>` in the footer). Which one a window uses is decided in one place, `resolveHostTarget` (`src/tui/host-target.ts`); `isMultiProcess` and the window's transport (`src/tui/host/use-local-host.ts`) read it. `ZIDANE_NO_REMOTE=1` (`--no-remote`) refuses `--host` with a message, ignores `ZIDANE_HOST_URL` from the environment with a warning (the window runs locally), and greys out Settings → Remote hosts. Headless runs (`zidane run --json`, `--json-schema`) are local-only: they refuse `--host` and ignore the environment's host. In remote mode `!` commands run on the server, in the session's folder, through its workspace exec. The window reads and writes session data (the list, the open session, titles, artifacts, out-of-band turns) only through its host (`src/tui/runtime/session-data.ts`), holding a store-less snapshot of the open session (`src/tui/runtime/session-snapshot.ts`), so a remote window shows the server's sessions. Details: [IPC.md § TUI local mode](./IPC.md#tui-local-mode), [IPC.md § Remote server](./IPC.md#remote-server-zidane-server).
290
+
291
+ ### Several hosts (remote hosts)
292
+
293
+ Opt-in: Settings → Remote hosts (experimental, off by default), and `ZIDANE_NO_REMOTE=1` beats it. Off, the window is exactly the single-host window above: no Hosts tab, no grouping, no host step, and the saved-hosts code (`src/tui/host/remote-hosts.ts`, the WebSocket client, the registry) is never loaded, so `hosts.json` is never read and nothing is dialed (`test/tui/remote-lazy-graph.test.ts` checks the static import graph, `test/tui/app-remote-containment.test.tsx` the running app).
294
+
295
+ On, the window keeps one app-lifetime connection per host in its **host directory** (`src/tui/host/host-directory.ts`: key → transport, client, status): This computer (the in-process host or the shared daemon), each server saved on the Hosts page, and a `--host` server as an unsaved entry. The registry ↔ directory sync and the connection loop (backoff 1 s → 30 s, a refused token not retried, the statuses) are shared with the GUI (`src/ipc/hosts`, `zidane/ipc/remote`); the TUI keeps its glue (`remote-hosts.ts`: a WebSocket transport per entry; `host-signals.ts`: presence and session changes). The default host (where a new session goes) is `--host` when given, else This computer; the active host is the one of the session on screen.
296
+
297
+ - **Routing by session**: every call about one session (out-of-band turns, `!` on a server, extension state, artifacts, environment actions) goes to that session's host (`src/tui/runtime/routed-session-data.ts`), not to whatever host is on screen when it finishes: a `!` or a notice that completes after a switch lands on its own session. A session's host is learned from what the hosts say: their lists, a create, an activation, a lookup the active host answered. A session is a (host, id) pair: two hosts may list the same id, so a row of the several-host list carries its host (`SessionMeta.hostKey`) into opening it and its details actions, the open session's pair is recorded at activation, and an id several hosts list is refused without its host (`AmbiguousHostIdError`). A write to a session no host named is refused (`UnknownHostIdError`), never sent to This computer; the hosts also refuse `sessions.appendTurns` for a session they don't have (no header-less ghost row).
298
+ - **Saving a saved server again** (a new token, a new URL) reconnects it in place: an open session on it stays there.
299
+ - **Removing the server of the open session** (Hosts page, another window, or turning Remote hosts off) closes that session in the window: its controller goes, pending questions are cancelled with the reason, and the window lands on the sessions list with `<server> was removed` (`src/tui/host/use-host-removal.ts`). Its ids answer `HostRemovedError` from then on.
300
+
301
+ - **Sessions list**: grouped by host, This computer first, then each server with its status. A server that is offline shows the sessions of its last good list (in memory only), marked as such; opening one says the server is offline. The project scope applies to This computer; a server's group lists all its sessions (its folders are not this machine's). Search, the scope toggle and presence glyphs work across groups. With no saved server the list has no headers.
302
+ - **Opening** a session uses its host. Switching follows the semantics of the host the current session runs on: an in-process run blocks the switch (as above), a daemon or server run keeps going. A row whose session another window deleted meanwhile is never recreated: opening it says `This session no longer exists on <host>.` (`SessionGoneError`, `src/tui/runtime/session-data.ts`) and the list re-reads.
303
+ - **Notices** on the sessions list are one line, gone when you leave the screen; one about a server's status ("<server> is offline") also goes as soon as that server connects again (`src/tui/sessions/use-sessions-notice.ts`).
304
+ - **New session** (`ctrl+n`, `+ new session`) asks the host first (default focused), then that host's environments (a server's from `environments.list`), then for a server a folder on it (`fs.roots` / `fs.listDirs`, starting at its first workspace root; `↵` on a folder opens it, on `use <path>` creates there). This computer keeps the window's folder and environment picker. A window never sends its own folder to a server: a new session on a `--host` server starts in the server's first root unless one is picked.
305
+ - **Chat title / footer**: a server session's title bar shows `<folder> (on <server>)` and the footer `host: <server>`; This computer shows neither.
306
+ - **Machines** (`src/tui/machines/`, [MACHINES.md](./MACHINES.md)): Settings → Hosts → `ctrl+b` on a saved server: share this computer with it (name, then folders: `+ add a folder`, `ctrl+x` removes one, `start sharing`; the machine agent runs in This computer's host and its token is minted on the server, or pasted when the server can't), use it as a machine (only when it lends itself), its machines (status, folders, last seen; `ctrl+x` forgets, asks first). New session: a host's machine kinds after its own, grouped by machine with its status (offline: listed, not pickable), then a folder on the machine (`machines.listDirs`); This computer's picker adds its own machine kinds (a server it uses). The chat title shows `local@laptop` / `worktree@laptop ⎇ <branch>`, and `waiting for laptop…` while a run is paused on that machine.
307
+ - **Live lists**: every connected host's group re-reads when that host announces a session change (`sessions:changed`, which a host sends every connection, watching a session or not), at most every 250 ms: a session another window (or the GUI) creates, renames or deletes on a server shows up without reopening the list.
308
+ - **Resume on launch** remembers the host: the window's `state.json` keeps `lastSessionHostKey` (a saved server's host key, its id; absent for This computer; read from the older `lastSessionHostId` too) beside `lastSessionId`. A `--host` session writes neither (the pointer stays on the last session of This computer or a saved server), and a `--host` launch resumes nothing. With remote hosts on, launch waits for that server's first connect (up to 20 s) and reopens the session there; offline, refused or no longer saved, it lands on the sessions list saying why. With remote hosts off, a server's session is not resumed (the window resumes only its own).
309
+ - **Model picker** on a server session lists the server's credentialed providers and models (`models.list`, `src/tui/model/use-host-model-catalog.ts`): a provider only the server has is pickable, one only this window has is not. A pick there is remembered for the next launch only when this computer is signed in to its provider, without the fallbacks it can't run (`rememberableChain`, the GUI's rule too).
310
+ - **`/` commands** on a server session are the server's (`commands.list` for the session's folder there, `src/tui/prompt/use-host-commands.ts`): completion lists them, argument completion asks the server, and sending one queues it to the server. The window's built-ins (`/help`, `/reload`, …) stay its own.
311
+ - **Transcripts** load a page of turns per reply, from the end, only as far as the window shows (`loadDisplayedTranscript` → `loadEventsTail`, in every mode): pages stop once the display cap (`capTranscriptEvents`) is covered, behind its hidden-count marker, so a long session opens on a few pages, not all of them. No single reply carries a long session; a page refused as too large is asked again at half the turns. Each page is a slice of the host's whole replay (with `start`, its place in it), so the tail is exactly what capping the whole replay shows. An older host's pages say nothing of where they start: those load whole.
312
+ - **Claude Code import** always imports into this computer; on a server session it says so.
313
+ - **Settings** edits the server of the active session: see [Settings modal](#settings-modal). A write the server refuses shows one line under the tabs (`<server> refused <key>: <why>`, `SettingsStatusLine`) until the next change.
314
+
315
+ Coexistence: the store (`sessions.db`/`state.json`) is neutral ground both hosts read/write; a cross-process run guard (`status: 'running'`, 5-minute freshness bound) stops two processes stacking runs on one session; while a daemon controller is connected the daemon owns `state.json` settings writes. Turning it off always works: `--no-daemon`/`ZIDANE_NO_DAEMON=1` beat the setting, and a daemon connect failure leaves the window reconnecting with a visible notice. Full protocol, lifecycle, and the asymmetries (`!`/the TUI's own `/` commands executing in the issuing window): [IPC.md](./IPC.md).
316
+
317
+ **Settings sync** (Settings → Hosts → a saved server → `ctrl+s`;
318
+ [SERVER.md § Settings sync](./SERVER.md#settings-sync)): the mode (↵
319
+ cycles Off · Import once · Keep in sync), the categories (↵ toggles), with
320
+ API keys one row per stored key (↵ asks first: it copies the secret), *push
321
+ everything now*, *take over* when another device syncs there (asks first),
322
+ and the server's overrides (↵ resets one); below, the connection, the last
323
+ push, what waits, the last error and what the server skipped or warned
324
+ about. While the modal edits a server synced from a computer, a synced
325
+ setting's row reads `· synced from <device>`, an override's `· edited
326
+ here, not synced (ctrl+r: sync from <device>)`, and `ctrl+r` on it resets
327
+ it. `src/tui/settings/server-sync-page.tsx`, `host-settings-scope.tsx`; the
328
+ engine (`src/chat/sync`) starts with the saved hosts (`remote-hosts.ts`).
288
329
 
289
330
  ## Embedding
290
331
 
@@ -339,9 +380,10 @@ A GUI (or any host whose `process.execPath` is not the package's bin) uses `upgr
339
380
  ```
340
381
  src/tui/
341
382
  index.tsx runTui + public exports
342
- app.tsx App + AppShell + ThemedShell — provider stack + agent lifecycle
343
- screens.tsx AuthScreen, SessionsScreen, ChatScreen, PromptBlock, ApprovalBlock, QueuedMessagesBlock
344
- components.tsx Transcript, EventLine, MarkdownBlock, SubagentBlock, Footer, Spinner, StatusSpinner, TitleOverlay, EditDiffBlock, NoticeRow, TaskNotificationBlock
383
+ app.tsx App + AppShell + ThemedShell — provider stack; AppShell composes the feature hooks (shell/, host/, …)
384
+ screens.tsx Re-exports AuthScreen, SessionsScreen, ChatScreen, PromptBlock, … from auth/, sessions/, chat/, prompt/, queue/
385
+ components.tsx Footer, TitleOverlay; re-exports Transcript, Spinner, StatusSpinner, … from transcript/ and status-spinner.tsx
386
+ <feature>/ shell/, host/, sessions/, prompt/, chat/, transcript/, settings/, mcp/, … — each feature's hooks and components together (see ARCHITECTURE.md)
345
387
  modal.tsx ModalRoot + Modal (+ rightTitle slot) + useModalAwareFocus
346
388
  model-picker.tsx Cross-provider searchable model list modal
347
389
  model-options-picker.tsx Reasoning-effort + feature-toggle modal (ctrl+l) — supersedes effort-picker.tsx in-app
@@ -358,6 +400,15 @@ src/tui/
358
400
  extension-hud.tsx Extension-contributed HUD overlay
359
401
  create-extension-modal.tsx Scaffold-a-new-extension flow
360
402
  claude-import-modal.tsx Import sessions / MCP servers / skills from Claude Code
403
+ host/host-directory.ts The window's hosts (This computer, --host, saved servers): transport, client, status; default + active host
404
+ host/remote-hosts.ts Saved servers in the directory (loaded only with remote hosts on)
405
+ sessions/hosted-sessions.ts The sessions list across hosts (grouping, last known rows of an offline server)
406
+ settings/hosts-panel.tsx Settings → Hosts
407
+ machines/ A server's machines page (share, use, list), the machine folder step, the online-machines mirror
408
+ settings/host-settings-scope.tsx The Settings modal editing a server's settings
409
+ settings/server-catalog-panel.tsx A server's Skills / MCP servers / Extensions tabs (catalog.*)
410
+ model/use-host-model-catalog.ts The model pickers' providers: the session's server's (models.list)
411
+ prompt/use-host-commands.ts A server session's `/` commands (commands.list)
361
412
  cwd-picker.tsx Directory picker (ctrl+h)
362
413
  session-details-modal.tsx Stats + delete / export / title / compact (ctrl+shift+x)
363
414
  turn-details-modal.tsx Fork / delete / copy / edit (opened from select-turn mode)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zidane",
3
- "version": "7.2.4",
3
+ "version": "8.0.4",
4
4
  "description": "an agent that goes straight to the goal",
5
5
  "type": "module",
6
6
  "private": false,
@@ -191,6 +191,11 @@
191
191
  "import": "./dist/restate.js",
192
192
  "default": "./dist/restate.js"
193
193
  },
194
+ "./codemode": {
195
+ "types": "./dist/codemode.d.ts",
196
+ "import": "./dist/codemode.js",
197
+ "default": "./dist/codemode.js"
198
+ },
194
199
  "./chat": {
195
200
  "types": "./dist/chat.d.ts",
196
201
  "import": "./dist/chat.js",
@@ -221,6 +226,11 @@
221
226
  "import": "./dist/ipc.js",
222
227
  "default": "./dist/ipc.js"
223
228
  },
229
+ "./ipc/remote": {
230
+ "types": "./dist/ipc/remote.d.ts",
231
+ "import": "./dist/ipc/remote.js",
232
+ "default": "./dist/ipc/remote.js"
233
+ },
224
234
  "./eval": {
225
235
  "types": "./dist/eval.d.ts",
226
236
  "import": "./dist/eval.js",
@@ -242,6 +252,7 @@
242
252
  "workspaces": [
243
253
  "tui",
244
254
  "tui/npm/*",
255
+ "server",
245
256
  "extensions/*"
246
257
  ],
247
258
  "engines": {
@@ -257,38 +268,54 @@
257
268
  "tui:install:cross": "bun install --cpu='*' --os='*'",
258
269
  "tui:build": "bun run scripts/build-executables.ts",
259
270
  "tui:build:current": "bun run scripts/build-executables.ts --current",
271
+ "server": "bun run src/server/main.ts",
272
+ "server:build": "bun run scripts/build-server.ts",
273
+ "server:smoke": "bun run server/scripts/smoke-binary.ts",
274
+ "server:docker": "docker build -f server/Dockerfile -t zidane-server:dev .",
275
+ "server:smoke:image": "bun run server/scripts/smoke-image.ts",
276
+ "server:release:package": "bun run scripts/package-server-release.ts",
260
277
  "build": "tsdown",
261
278
  "lint": "eslint .",
262
279
  "lint:fix": "eslint . --fix",
263
280
  "smoke:package": "bun run scripts/smoke-package-exports.ts",
264
281
  "smoke:bundle": "bun run scripts/smoke-bundle-size.ts",
265
- "test": "bun test",
266
- "test:extensions": "bun test ./extensions",
267
- "test:all": "bun test && bun test ./extensions",
282
+ "test": "bun run scripts/test.ts",
283
+ "test:extensions": "bun run scripts/test.ts ./extensions",
284
+ "test:all": "bun run scripts/test.ts && bun run scripts/test.ts ./extensions",
268
285
  "typecheck:extensions": "for d in extensions/*/; do tsc --noEmit -p \"$d\" || exit 1; done",
269
286
  "test:inference": "cd test-inference && bun test",
270
287
  "test:eval": "bun run scripts/eval.ts",
271
288
  "bench:memory": "bun run benchmarks/memory/run.ts",
272
289
  "evals": "bun run scripts/eval.ts",
290
+ "evals:codemode": "bun run scripts/eval.ts --setups build,codemode -g vite-todolist-react --repeat 3 --timeout 600000",
273
291
  "restate:fixture:up": "docker compose -f test/fixtures/restate-docker/docker-compose.yml up --build -d",
274
292
  "restate:fixture:down": "docker compose -f test/fixtures/restate-docker/docker-compose.yml down -v",
275
293
  "restate:fixture:service": "PORT=19080 bun run test/fixtures/restate-docker/service.ts",
276
294
  "restate:fixture:smoke": "bun run test/fixtures/restate-docker/smoke.ts",
277
295
  "restate:fixture:test": "bun run test/fixtures/restate-docker/run.ts",
278
- "release": "bumpp package.json tui/package.json tui/npm/*/package.json gui/package.json --execute \"bun install --cpu='*' --os='*'\" --all",
296
+ "release": "bumpp package.json tui/package.json tui/npm/*/package.json server/package.json gui/package.json --execute \"bun install --cpu='*' --os='*'\" --all",
279
297
  "typecheck": "tsc --noEmit"
280
298
  },
281
299
  "dependencies": {
282
- "@earendil-works/pi-ai": "0.87.1",
300
+ "@earendil-works/pi-ai": "1.0.4",
283
301
  "chalk": "^5.6.2",
284
302
  "fzf": "^0.5.2",
285
- "hookable": "^6.1.1",
303
+ "hookable": "^6.1.2",
286
304
  "marked": "18.0.9"
287
305
  },
288
306
  "overrides": {
289
307
  "@types/react": "19.2.18",
290
308
  "@types/react-dom": "19.2.3",
291
- "tslib": "^2.8.1"
309
+ "tslib": "^2.8.1",
310
+ "@typescript-eslint/parser": "8.62.1",
311
+ "@typescript-eslint/scope-manager": "8.62.1",
312
+ "@typescript-eslint/utils": "8.62.1",
313
+ "@typescript-eslint/types": "8.62.1",
314
+ "@typescript-eslint/typescript-estree": "8.62.1",
315
+ "@typescript-eslint/visitor-keys": "8.62.1",
316
+ "@typescript-eslint/eslint-plugin": "8.62.1",
317
+ "@typescript-eslint/type-utils": "8.62.1",
318
+ "typescript-eslint": "8.62.1"
292
319
  },
293
320
  "peerDependencies": {
294
321
  "@anthropic-ai/bedrock-sdk": ">=0.32.0",
@@ -300,6 +327,7 @@
300
327
  "@restatedev/restate-sdk": "^1.11.0",
301
328
  "dockerode": "^5.0.0",
302
329
  "e2b": "^2.0.0",
330
+ "quickjs-wasi": "^3.6.2",
303
331
  "react": "^18.0.0 || ^19.0.0",
304
332
  "tar-stream": "^3.0.0",
305
333
  "zod": ">=4.0.0"
@@ -332,6 +360,9 @@
332
360
  "e2b": {
333
361
  "optional": true
334
362
  },
363
+ "quickjs-wasi": {
364
+ "optional": true
365
+ },
335
366
  "react": {
336
367
  "optional": true
337
368
  },
@@ -343,29 +374,30 @@
343
374
  }
344
375
  },
345
376
  "devDependencies": {
346
- "@antfu/eslint-config": "^8.2.0",
377
+ "@antfu/eslint-config": "^8.3.0",
347
378
  "@anthropic-ai/bedrock-sdk": "^0.32.4",
348
379
  "@anthropic-ai/sdk": "^0.104.2",
349
380
  "@daytona/sdk": "^0.187.0",
350
- "@modelcontextprotocol/sdk": "^1.30.0",
351
- "@opentui/core": "^0.5.3",
352
- "@opentui/core-darwin-x64": "^0.5.3",
353
- "@opentui/core-linux-arm64": "^0.5.3",
354
- "@opentui/core-linux-x64": "^0.5.3",
355
- "@opentui/react": "^0.5.3",
356
- "@restatedev/restate-sdk": "^1.16.5",
357
- "@types/bun": "^1.4.0",
381
+ "@modelcontextprotocol/sdk": "^1.32.1",
382
+ "@opentui/core": "^0.5.16",
383
+ "@opentui/core-darwin-x64": "^0.5.16",
384
+ "@opentui/core-linux-arm64": "^0.5.16",
385
+ "@opentui/core-linux-x64": "^0.5.16",
386
+ "@opentui/react": "^0.5.16",
387
+ "@restatedev/restate-sdk": "^1.17.2",
388
+ "@types/bun": "^1.4.2",
358
389
  "@types/dockerode": "^4.0.1",
359
390
  "@types/react": "19.2.18",
360
- "@types/tar-stream": "^3.1.4",
361
- "bumpp": "^11.0.1",
362
- "dockerode": "^5.0.0",
363
- "e2b": "^2.39.0",
364
- "eslint": "^10.8.1",
365
- "jiti": "^2.6.1",
366
- "react": "^19.2.8",
367
- "tar-stream": "^3.2.1",
368
- "tsdown": "^0.22.0",
391
+ "@types/tar-stream": "^3.1.5",
392
+ "bumpp": "^11.1.0",
393
+ "dockerode": "^5.0.1",
394
+ "e2b": "^2.53.1",
395
+ "eslint": "^10.12.0",
396
+ "jiti": "^2.7.0",
397
+ "quickjs-wasi": "3.6.2",
398
+ "react": "^19.3.0",
399
+ "tar-stream": "^3.2.2",
400
+ "tsdown": "^0.22.14",
369
401
  "typescript": "~6.0.3",
370
402
  "unrun": "^0.3.1"
371
403
  }
package/scripts/eval.ts CHANGED
@@ -9,6 +9,7 @@
9
9
  * bun run test:eval --provider openai --model gpt-5 --filter vite --repeat 3
10
10
  * bun run test:eval --provider all # every provider with an API key in env/.env
11
11
  * bun run test:eval --provider baseten --models zai-org/GLM-5.1,moonshotai/Kimi-K2.6
12
+ * bun run test:eval --setups build,codemode -g vite-todolist-react --repeat 3 # Build vs Codemode
12
13
  *
13
14
  * Flags:
14
15
  * --provider <name> agent provider (anthropic|openai|openrouter|cerebras|arcee|baseten|local).
@@ -26,6 +27,8 @@
26
27
  * (default path: benchmarks/evals/baseline.json)
27
28
  * --extensions <names> enable repo extensions for the run, comma-separated
28
29
  * (e.g. pxpipe,headroom — see benchmarks/evals/_extensions.ts)
30
+ * --setups <names> run every eval once per agent setup and compare them
31
+ * (e.g. build,codemode — see benchmarks/evals/_setups.ts)
29
32
  * --timeout <ms> per-test timeout (default 180000)
30
33
  */
31
34
 
@@ -52,6 +55,7 @@ const FLAG_TO_ENV: Record<string, string> = {
52
55
  'artifact-dir': 'ZIDANE_EVAL_ARTIFACT_DIR',
53
56
  'baseline': 'ZIDANE_EVAL_BASELINE',
54
57
  'extensions': 'ZIDANE_EVAL_EXTENSIONS',
58
+ 'setups': 'ZIDANE_EVAL_SETUPS',
55
59
  }
56
60
 
57
61
  /** Flags whose value may be omitted, falling back to a default. */