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
@@ -1,1762 +0,0 @@
1
- import { Bv as SkillConfig, Dd as EditOutcome, Fd as SessionMeta, Hf as ModelInfo, Id as Settings, Jv as SessionData, Ld as StreamEvent, Lf as ProviderAuth, Nd as Picked, Qo as ExtensionRegistry, Rf as ProviderKey, Tc as SubagentRegistry, U_ as SessionTurn, Uc as LoadedPlugin, Wf as ProviderDescriptor, Wl as StorageMode, Xv as SessionRun, Z_ as ThinkingLevel, Zv as SessionStore, ac as StoredExtensionConfigItem, bf as ModelChainEntry, nv as ToolResultContent, qs as ExtensionConfigCategory, t as Preset, wc as SubagentOverride, y_ as McpServerConfig, ym as AgentRegistry, z_ as SessionContentBlock } from "./index-BgN1T3lk.js";
2
- //#region src/chat/hints.d.ts
3
- /**
4
- * Single hint entry — `<key> <label>`, optionally followed by an inline
5
- * secondary chord (`<key><extra.key> <label> <extra.label>`) for compound
6
- * shortcuts like `ctrl+m/n model effort`.
7
- *
8
- * Colour fields are advisory hex strings (resolved against the active
9
- * theme by the renderer); leaving them undefined lets the renderer pick
10
- * its conventional fallback (e.g. `warn` for keys, `dim` for labels,
11
- * `mute` for secondary).
12
- */
13
- interface Hint {
14
- key: string;
15
- label: string;
16
- /** Optional override for the key color. Renderer default: warn. */
17
- keyColor?: string;
18
- /** Optional override for the label color. Renderer default: dim. */
19
- labelColor?: string;
20
- /**
21
- * Optional secondary chord + value rendered inline after the primary
22
- * pair: `<key><extra.key> <label> <extra.label>`. Lets one hint advertise
23
- * a compound shortcut (e.g. `ctrl+m/n model effort`) without forcing
24
- * callers into a parallel struct or a custom renderer.
25
- */
26
- extra?: {
27
- key: string;
28
- label: string;
29
- /**
30
- * Dispatchable binding spec behind `extra.key` when the displayed
31
- * chord is an abbreviation (`/l` for `ctrl+l` — see `shortChord`).
32
- * The abbreviation itself doesn't parse as a keypress, so a renderer
33
- * that makes the secondary chord independently clickable needs the
34
- * full spec. Defaults to `extra.key` when omitted.
35
- */
36
- keySpec?: string; /** Defaults to mute on the renderer side. */
37
- keyColor?: string; /** Defaults to dim on the renderer side. */
38
- labelColor?: string;
39
- };
40
- }
41
- /**
42
- * Truncate `text` to at most `max` characters, replacing the trailing
43
- * overflow with `…`. Edge cases:
44
- * - `max <= 0` → empty string (no room to render at all).
45
- * - `max === 1` → just the ellipsis glyph.
46
- * - `text.length <= max` → unchanged.
47
- *
48
- * Trailing-style truncation matches the natural read order of titles:
49
- * the prefix carries enough signal to identify the surface.
50
- */
51
- declare function truncateTrailing(text: string, max: number): string;
52
- /**
53
- * Plain-text width estimate for a list of {@link Hint}s rendered as
54
- * `<key> <label> · <key> <label> · …`. Exported so prompt-box overlays
55
- * can run the same responsive math as the bottom-bar footer when
56
- * deciding whether trigger hints fit. Pure / total.
57
- */
58
- declare function hintsLength(hints: readonly Hint[]): number;
59
- /**
60
- * Stable empty list so callers can compare by reference. Exported so
61
- * any consumer that needs to feed "no primary hints" into the same
62
- * `clipHintsToWidth` / `renderHintSpans` pipeline (e.g. the TUI's
63
- * minimal UI mode, where the prompt overlay shows only `@` / `/`
64
- * triggers) reuses the same frozen array instead of allocating a new
65
- * one each render.
66
- */
67
- declare const EMPTY_HINTS: readonly Hint[];
68
- /**
69
- * Return the longest prefix of `hints` whose rendered width fits within
70
- * `budget`. Used to degrade hint rows gracefully at narrow terminal
71
- * widths instead of letting an absolutely-positioned hint row wrap
72
- * mid-segment (which paints the overflow over surrounding borders and
73
- * looks like garbled glyphs in a TUI).
74
- *
75
- * Prefix-only (no reordering, no last-hint priority) so the survivors
76
- * keep their authored order — the user's muscle memory for "leftmost
77
- * hint = primary action" stays intact as the terminal shrinks.
78
- */
79
- declare function clipHintsToWidth(hints: readonly Hint[], budget: number): readonly Hint[];
80
- //#endregion
81
- //#region src/start/shared-options.d.ts
82
- declare const startProviderNames: readonly ["anthropic", "openai", "openrouter", "cerebras", "xai", "arcee", "baseten", "local", "openai-compat"];
83
- type StartProviderName = typeof startProviderNames[number];
84
- declare const startPresetNames: readonly ["basic"];
85
- type StartPresetName = typeof startPresetNames[number];
86
- declare const startFormatNames: readonly ["zidane", "provider"];
87
- type StartFormatName = typeof startFormatNames[number];
88
- interface StartLocalOptions {
89
- system?: string;
90
- prompt: string;
91
- model?: string;
92
- baseURL?: string;
93
- apiKeyEnv?: string;
94
- headersEnv?: string;
95
- extraHeaders?: Record<string, string>;
96
- vision?: boolean;
97
- imageInToolResult?: boolean;
98
- temperature?: number;
99
- seed?: number;
100
- preset: StartPresetName;
101
- thinking: ThinkingLevel;
102
- provider: StartProviderName;
103
- context: string;
104
- image?: string;
105
- cwd?: string;
106
- env?: Record<string, string>;
107
- pregame?: {
108
- name: string;
109
- content: string;
110
- };
111
- sandboxId?: string;
112
- sandboxOnDestroy?: 'kill' | 'pause' | 'leave';
113
- mcp?: McpServerConfig[];
114
- sessionDb?: string;
115
- sessionId?: string;
116
- schema?: Record<string, unknown>;
117
- json: boolean;
118
- streamJson: boolean;
119
- format: StartFormatName;
120
- }
121
- //#endregion
122
- //#region src/chat/keybindings.d.ts
123
- /**
124
- * Keybindings — a single source of truth for the app's global shortcuts.
125
- *
126
- * Every customizable action is declared once in {@link KEYBINDING_DEFS}
127
- * with its default trigger, label, and description. The TUI imports
128
- * `DEFAULT_KEYBINDINGS` for the baked-in defaults; on launch we load
129
- * `<userDir>/keybindings.json` (when present) and merge user overrides
130
- * on top so the user can rebind any action without recompiling.
131
- *
132
- * Scope (deliberate):
133
- *
134
- * - We expose only the **global, action-opening** shortcuts here —
135
- * "open the Settings modal", "cycle agent profile", "enter
136
- * select-turn mode", etc. Modal-internal letter shortcuts (`f`
137
- * fork, `d` delete, `c` copy on the turn-details modal) and
138
- * universal navigation (`↑/↓/↵/⎋`) stay hardcoded — they live
139
- * too close to a renderable's input contract to remap safely.
140
- *
141
- * - Storage lives at the **user level** (`<userDir>/keybindings.json`),
142
- * never inside a project's `.{prefix}/`. Shortcut muscle memory is
143
- * a per-user concern, not a per-repo one.
144
- *
145
- * Format on disk: JSON with `//` and `/* … *\/` comments allowed
146
- * (parsed via a small JSONC stripper). Each entry maps an action id
147
- * to a binding spec string. Specs are parsed by {@link parseBindingSpec};
148
- * unknown / malformed entries fall back to the default for that action
149
- * (with a debug log under `ZIDANE_DEBUG`) so a syntax slip never bricks
150
- * the TUI.
151
- */
152
- /**
153
- * Every action the keybindings system can drive. Adding a new action
154
- * here forces every consumer (TUI keyboard handler, hint rows, settings
155
- * UI) to handle it, and ships a default that the user can override.
156
- */
157
- type KeyAction = 'openSettings' | 'openSessionDetails' | 'newSession' | 'openModelPicker' | 'openEffortPicker' | 'openTodos' | 'openArtifacts' | 'panelNext' | 'panelPrev' | 'openContextPanel' | 'openMainSession' | 'openUsagePanel' | 'openKeybindings' | 'openPalette' | 'cycleAgent' | 'enterSelectTurnMode' | 'cancelToolCall' | 'abortRun' | 'changeCwd' | 'attachClipboardImage' | 'openExternalEditor' | 'enterQueueSelection' | 'pushQueuedMessage' | 'dropQueuedMessage' | 'turnFork' | 'turnDelete' | 'turnCopy' | 'turnEdit' | 'sessionDelete' | 'sessionCopyId' | 'sessionGenerateTitle' | 'sessionExportMarkdown' | 'sessionExportJson' | 'sessionCompact';
158
- /** Resolved keybindings — every action has a current spec string. */
159
- type KeyBindings = Record<KeyAction, string>;
160
- /**
161
- * Resolved spec string for one extension-contributed keybinding. Same
162
- * shape as a built-in {@link KeyBindings} entry but the `id` is
163
- * extension-owned (no `KeyAction` union member). The TUI dispatcher
164
- * iterates these alongside the built-ins; user overrides flow through
165
- * the same `keybindings.json` file by matching on `id`.
166
- */
167
- interface ResolvedExtensionKeybinding {
168
- /** Extension-owned id (matches `ExtensionKeybinding.id`). */
169
- id: string;
170
- /** Active spec string — user override when present, default otherwise. May be empty (= unbound). */
171
- spec: string;
172
- }
173
- /**
174
- * Logical grouping for one action — used by the keybindings panel to
175
- * render section headers. Stable strings (not an enum) so future
176
- * groups can be added without churning every existing entry.
177
- */
178
- type KeyBindingGroup = 'Global' | 'Message queue' | 'Turn details' | 'Session details';
179
- /** Static metadata for one action — used by the loader, hint rows, settings UI. */
180
- interface KeyBindingDef {
181
- /** Stable identifier — JSON key + TS union member. */
182
- action: KeyAction;
183
- /** Default trigger spec (e.g. `'ctrl+o'`). */
184
- default: string;
185
- /** Short label used in shortcut hint rows. */
186
- label: string;
187
- /** Longer description for the settings UI and the annotated JSON file. */
188
- description: string;
189
- /**
190
- * Group label rendered as a section header in the keybindings panel.
191
- * Items are listed in {@link KEYBINDING_DEFS} order; the panel just
192
- * inserts a header whenever this field changes between adjacent
193
- * entries — so groups stay contiguous and the order here is the
194
- * order on screen.
195
- */
196
- group: KeyBindingGroup;
197
- }
198
- /**
199
- * The canonical action catalog. Order is the source of truth for the
200
- * generated keybindings file and the settings UI.
201
- */
202
- declare const KEYBINDING_DEFS: readonly KeyBindingDef[];
203
- /** Index by action for O(1) lookup of label / description / default. */
204
- declare const KEYBINDING_DEF_BY_ACTION: Readonly<Record<KeyAction, KeyBindingDef>>;
205
- /** Defaults, derived from {@link KEYBINDING_DEFS} so the two never drift. */
206
- declare const DEFAULT_KEYBINDINGS: KeyBindings;
207
- /** Parsed shape of a `"ctrl+shift+o"` spec. */
208
- interface ParsedBinding {
209
- ctrl: boolean;
210
- shift: boolean;
211
- alt: boolean;
212
- meta: boolean;
213
- /** The key name (e.g. `'o'`, `'tab'`, `'escape'`). Always lowercase. */
214
- name: string;
215
- }
216
- /**
217
- * Parse a `'ctrl+shift+o'`-style spec into structured fields. Returns
218
- * `null` for empty / malformed inputs; the caller falls back to the
219
- * default for that action.
220
- *
221
- * Tolerant by design:
222
- * - Case-insensitive (`Ctrl+O` → same as `ctrl+o`).
223
- * - Modifier order doesn't matter (`shift+ctrl+o` works).
224
- * - Mixed `+` and `-` separators allowed (`ctrl-o`, `ctrl+o`).
225
- * - Trailing / leading whitespace is stripped.
226
- * - Duplicate modifiers collapse silently.
227
- */
228
- declare function parseBindingSpec(spec: string | undefined | null): ParsedBinding | null;
229
- /**
230
- * Test a KeyEvent against a parsed-or-string binding. Accepts either
231
- * form so callers can pre-parse (hot path) or pass the raw spec for
232
- * one-off checks.
233
- *
234
- * Modifier semantics: ALL declared modifiers must be pressed AND no
235
- * extra modifiers may be pressed. So `'o'` does NOT match `ctrl+o`,
236
- * and `'ctrl+o'` does NOT match `ctrl+shift+o`. This avoids surprises
237
- * where a binding that should be specific accidentally fires for a
238
- * superset of key combinations.
239
- */
240
- declare function matchesBinding(event: {
241
- name?: string;
242
- ctrl?: boolean;
243
- shift?: boolean;
244
- meta?: boolean;
245
- option?: boolean;
246
- alt?: boolean;
247
- }, spec: string | ParsedBinding): boolean;
248
- /**
249
- * Render a binding spec (`"ctrl+return"`, `"backspace"`, `"delete"`) as a
250
- * compact display string the user recognizes at a glance. Substitutes
251
- * arrow / enter / backspace glyphs for their verbose names so the hint
252
- * row stays narrow; modifier names + plain keys pass through unchanged.
253
- *
254
- * Empty / missing specs return an empty string — callers decide whether
255
- * to render a placeholder (e.g. `'—'` for an unbound action in the
256
- * keybindings panel) or hide the surface entirely (e.g. hint rows that
257
- * fall back to a different chord when the binding is empty).
258
- */
259
- declare function formatBindingForDisplay(spec: string | null | undefined): string;
260
- /**
261
- * Merge a partial map of user overrides into the defaults. Unknown
262
- * action keys are dropped (a future TUI version may have retired the
263
- * action); invalid spec strings (parse fails) fall back to the default
264
- * for that action.
265
- */
266
- declare function mergeKeybindings(overrides: Readonly<Record<string, unknown>> | null | undefined): KeyBindings;
267
- /** Path of the user-level keybindings file. */
268
- declare function keybindingsPath(userDir: string): string;
269
- /**
270
- * One contiguous section of the catalog — every action in a single
271
- * `group` rendered together with the section header inserted once.
272
- * Adjacent sections with the same group are NOT merged: catalog order
273
- * wins so the on-screen story matches the on-disk file.
274
- *
275
- * `rows` may carry built-in `KeyBindingDef`s (the common case) or
276
- * extension-owned ones (when an extension contributes a keybinding).
277
- * Both share label / description / spec — see {@link KeyBindingRow}.
278
- */
279
- interface KeyBindingSection {
280
- group: string;
281
- rows: ReadonlyArray<KeyBindingRow>;
282
- }
283
- /**
284
- * One row in the keybindings catalog. Either a built-in action (with
285
- * its `def`) or an extension-contributed one (with `id` instead). The
286
- * renderer reads `label` / `description` / `spec` uniformly and only
287
- * needs the `kind` discriminator when offering action-specific UI
288
- * (e.g. "edit in keybindings.json" by action name).
289
- */
290
- type KeyBindingRow = {
291
- kind: 'builtin';
292
- def: KeyBindingDef;
293
- spec: string;
294
- } | {
295
- kind: 'extension';
296
- id: string;
297
- label: string;
298
- description: string;
299
- spec: string;
300
- };
301
- /**
302
- * Walk {@link KEYBINDING_DEFS} in order and bucket rows into contiguous
303
- * sections by `group`. Shared between the standalone `KeybindingsModal`
304
- * and the `Keybindings` tab inside `SettingsModal` so both surfaces
305
- * render the same catalog with the same ordering rules.
306
- *
307
- * Pass `extensionRows` (resolved extension keybindings paired with
308
- * their definitions) to append an "Extensions" section at the end so
309
- * extension-contributed shortcuts are discoverable in the same UI.
310
- */
311
- declare function groupBindings(bindings: KeyBindings, extensionRows?: readonly {
312
- id: string;
313
- label: string;
314
- description: string;
315
- spec: string;
316
- }[]): readonly KeyBindingSection[];
317
- /**
318
- * Width (in cells) of the fixed key column used by every binding-row
319
- * renderer. Derived once from {@link KEYBINDING_DEFS} so a new action
320
- * with a wider default spec (`ctrl+shift+x`, …) automatically grows
321
- * the column instead of truncating the label.
322
- */
323
- declare const KEYBINDING_KEY_COL_WIDTH: number;
324
- /**
325
- * Load + merge the user's keybindings file (when present). Always
326
- * returns a fully-resolved {@link KeyBindings} — defaults fill in for
327
- * any missing / invalid entries so consumers can treat the result as
328
- * total.
329
- *
330
- * Failure modes (all tolerated, all fall back to defaults):
331
- * - File missing
332
- * - File not valid JSON / JSONC (after comment stripping)
333
- * - Top-level is not an object
334
- * - Individual entries have invalid spec strings
335
- */
336
- declare function readKeybindings(userDir: string): KeyBindings;
337
- /**
338
- * Create the user-level `keybindings.json` if it doesn't exist,
339
- * prefilled with every default. Returns the absolute file path either
340
- * way so the caller can open it in `$EDITOR`. Idempotent: an existing
341
- * user file is NEVER overwritten — the user's customizations are
342
- * sacred.
343
- */
344
- declare function ensureKeybindingsFile(userDir: string): string;
345
- /**
346
- * Read the raw on-disk JSON object from `keybindings.json` after the
347
- * JSONC stripper. Used by extension-keybinding resolution so the
348
- * user's overrides for extension-owned ids flow through the same file
349
- * the built-in actions use.
350
- *
351
- * Returns an empty object on missing / malformed / non-object files
352
- * — same fault-tolerance contract as {@link readKeybindings}.
353
- */
354
- declare function readKeybindingsRaw(userDir: string): Readonly<Record<string, unknown>>;
355
- /**
356
- * Resolve the live spec string for each extension-contributed
357
- * keybinding. The user's `keybindings.json` is consulted for an
358
- * override on the binding's `id`; absent / invalid entries fall back
359
- * to the binding's `default`.
360
- *
361
- * Pass the raw object (from {@link readKeybindingsRaw}) — passing
362
- * `KeyBindings` here wouldn't help because the typed map only carries
363
- * built-in `KeyAction` entries.
364
- *
365
- * Returns one entry per input binding, in source order. Empty `spec`
366
- * (binding declared `default: ''` and the user didn't bind it) is a
367
- * legitimate "unbound" state — the dispatcher never matches an empty
368
- * spec, so the action stays accessible via re-binding through
369
- * `keybindings.json`.
370
- */
371
- declare function resolveExtensionKeybindings(bindings: readonly {
372
- id: string;
373
- default: string;
374
- }[], raw: Readonly<Record<string, unknown>>): ResolvedExtensionKeybinding[];
375
- /**
376
- * Strip `//` line comments and `/* … *\/` block comments from a JSONC
377
- * source string. Stays out of string literals so a `"foo // bar"` value
378
- * keeps its slashes. Exported for unit-tests; the only runtime caller
379
- * is {@link readKeybindings}.
380
- *
381
- * Trade-off: this is a tiny state-machine, not a full JSONC parser. It
382
- * doesn't understand `\\` outside strings (irrelevant for JSON) and
383
- * doesn't track line numbers in error messages. Good enough for a
384
- * config file — corruption in production gracefully falls back to the
385
- * defaults via the try/catch in `readKeybindings`.
386
- */
387
- declare function stripJsonComments(input: string): string;
388
- //#endregion
389
- //#region src/chat/store.d.ts
390
- interface TuiState {
391
- lastProvider?: ProviderKey;
392
- lastSessionId?: string;
393
- /** Per-provider last-used model id. */
394
- lastModelByProvider?: Partial<Record<ProviderKey, string>>;
395
- /**
396
- * Last-applied model fallback chain (entry 0 = primary, mirroring
397
- * `lastProvider` + `lastModelByProvider`; entries 1+ = fallbacks).
398
- * Additive — absent for single-model users and older state files.
399
- * Restored on launch only when entry 0 still matches the resolved
400
- * primary; entries are re-validated against the live registry.
401
- */
402
- lastModelChain?: ModelChainEntry[];
403
- /**
404
- * Per-model last-picked reasoning effort. Keyed by model id (not provider)
405
- * so switching the same model across providers preserves the user's
406
- * intent. Models without reasoning support are absent from the map.
407
- */
408
- lastEffortByModel?: Record<string, ThinkingLevel>;
409
- /**
410
- * Per-model last-picked custom options (e.g. `{ fast: true }`). Keyed by
411
- * model id like {@link lastEffortByModel}, so a toggle follows the model
412
- * across providers. Models with no options are absent from the map.
413
- */
414
- lastModelOptionsByModel?: Record<string, Record<string, boolean>>;
415
- /**
416
- * Last-active agent profile id (see {@link AgentRegistry}). Resumed on
417
- * launch so a returning user lands back in the same mode (Build / Plan /
418
- * a host profile). Falls back to the host's `defaultAgent` then the first
419
- * registry key if the id is no longer registered.
420
- */
421
- /**
422
- * @deprecated No longer read: the agent profile is per-session and fresh
423
- * sessions always start in the default. Kept so older state files parse.
424
- */
425
- lastAgent?: string;
426
- /** User-toggled transcript filters. Persisted so they outlive a launch. */
427
- settings?: Partial<Settings>;
428
- }
429
- interface StateStoreApi {
430
- load: () => TuiState;
431
- save: (state: TuiState) => void;
432
- }
433
- declare function createStateStore(path: string): StateStoreApi;
434
- declare function loadState(path: string): TuiState;
435
- declare function saveState(path: string, state: TuiState): void;
436
- /**
437
- * Load every session and project it to the compact `SessionMeta` shape used by
438
- * the picker. Sorted by recency via the underlying store's `list()` contract
439
- * (sqlite store returns by `updated_at DESC`).
440
- *
441
- * Robust to per-row failures: `Promise.allSettled` so a single corrupt or
442
- * unreadable row (malformed JSON, partial write, transient I/O error)
443
- * doesn't take down the entire picker. Failed rows are silently skipped;
444
- * a stderr line is emitted under `ZIDANE_DEBUG` for diagnosis.
445
- */
446
- declare function listSessionMeta(store: SessionStore, filter?: {
447
- /**
448
- * Restrict to sessions belonging to this project. Omit to ignore
449
- * the axis; pass `null` to ask for untagged (legacy) sessions
450
- * specifically. The TUI defaults to passing the current git root /
451
- * cwd here so each project sees only its own conversations.
452
- */
453
- projectRoot?: string | null;
454
- }): Promise<SessionMeta[]>;
455
- /** Derive a short title from the first user message — returns null when empty. */
456
- declare function titleFromTurns(turns: SessionTurn[]): string | null;
457
- /**
458
- * Display title for a session — preferred sources, in order:
459
- *
460
- * 1. `metadata.title` if it's a non-empty string (typically set by
461
- * the session-details modal's "generate title" action).
462
- * 2. {@link titleFromTurns} — the first user message, one-line + clipped.
463
- * 3. {@link DEFAULT_SESSION_TITLE} (`'New session'`).
464
- *
465
- * Total / pure / defensive on non-string metadata values.
466
- */
467
- declare function deriveSessionTitle(turns: SessionTurn[], metadata?: Record<string, unknown>): string;
468
- /**
469
- * Replay persisted turns as a viewable transcript. Mirrors the event shape
470
- * produced live by the agent hooks so loaded and streaming history render
471
- * identically — including subagent ancestry when `runs` is supplied.
472
- *
473
- * Subagent reconstruction:
474
- * - Every turn carries a `runId`. We look that up in `runs` to get the
475
- * run's `depth` and tag the resulting events with `{ depth, childId }`
476
- * — the same shape the live `child:*` bubble hooks produce.
477
- * - We synthesize `spawn-start` / `spawn-end` markers at each child-run
478
- * boundary so the transcript reads the same as a live run did
479
- * (`🌱 [run-id] task` … child events … `🌳 [run-id] done · tokens`).
480
- * - For child runs (`depth > 0`), the user-role "task" text is suppressed
481
- * because `spawn-start` already shows it.
482
- *
483
- * Without `runs` (legacy callers / tests), the function falls back to the
484
- * old behavior: depth-0 events with no subagent grouping.
485
- */
486
- /**
487
- * Map a `compact-summary` content block to its `compact-summary` StreamEvent —
488
- * the single source of truth for the compaction boundary card. Used by
489
- * {@link eventsFromTurns} (reload / TUI live repaint) AND by chat hosts that
490
- * surface the boundary live without a full reload (the GUI broadcasts this
491
- * from the loop's `compact:end` hook), so the live card and the reloaded card
492
- * are byte-identical regardless of who created the marker (manual, the old
493
- * host trigger, or loop-native auto-compaction — all share this block shape).
494
- */
495
- declare function compactSummaryEvent(block: Extract<SessionContentBlock, {
496
- type: 'compact-summary';
497
- }>, turnId?: string): StreamEvent;
498
- declare function eventsFromTurns(turns: SessionTurn[], runs?: readonly SessionRun[]): StreamEvent[];
499
- declare function toolCallPreview(name: string, input: Record<string, unknown>): string;
500
- /**
501
- * Update the trailing `'tool'` event matching `callId` so its
502
- * `edit.outcomes` reflects the canonical merged outcomes the chat
503
- * layer's `tool:transform` hook just computed. Without this, the live
504
- * diff badges stay frozen at whatever the gate set (approval-side
505
- * outcomes) and never reflect body-side failures from `multi_edit`'s
506
- * best-effort run — only a session reload re-attaches the merged
507
- * outcomes via {@link eventsFromTurns}.
508
- *
509
- * Walks back-to-front because the matching event is overwhelmingly the
510
- * most recent (we're updating right after the body returned). Returns
511
- * the same reference when no match is found (or the event already
512
- * carries the target outcomes), so React skips the re-render.
513
- */
514
- declare function updateToolEventOutcomes(events: readonly StreamEvent[], callId: string, outcomes: readonly EditOutcome[]): StreamEvent[];
515
- /** Render tool output as plain text, whether it's a string or structured content. */
516
- declare function toolResultText(output: string | ToolResultContent[]): string;
517
- /**
518
- * Strip the `Tokens: …` line from a spawn tool-result. The spawn-end marker
519
- * displayed right above already shows the same stats; keeping the line in the
520
- * rendered tool-result body just produces a visible duplicate (and, on
521
- * reloaded pre-fix sessions, an *inconsistent* duplicate — the persisted line
522
- * uses the old `13 in / 4075 out` shape while the freshly synthesized
523
- * spawn-end uses the cache-aware `in 92615 (cache 92602) / 4075 out` shape).
524
- *
525
- * Display-only: the persisted tool_result content is untouched, so the LLM
526
- * still sees the full string in its context window. Anchored to start-of-line
527
- * and matches both `Tokens: 13 in / 4075 out` (legacy) and `Tokens: in 13 …`
528
- * (post-`formatTokenUsage`) shapes.
529
- */
530
- declare function stripSpawnTokensLine(text: string): string;
531
- /**
532
- * Resolve the top margin (in rows) for an event given the one rendered
533
- * just before it. Context-aware rules:
534
- *
535
- * - A `tool` / `tool-result` event right after another
536
- * `tool` / `tool-result` collapses to a tight list — call→result
537
- * pairs and back-to-back calls read as one logical block.
538
- * - Consecutive `task-notification` banners stack tight — a burst of
539
- * background-task completions reads as one log column rather than
540
- * scattered banners.
541
- *
542
- * NB: parent-level events (`depth === 0`) following a subagent block
543
- * (`depth > 0`) get their normal default margin. An earlier revision
544
- * collapsed this transition to 0 on the assumption that the subagent's
545
- * `🌳` end-marker provided enough visual separation — it didn't. A
546
- * 2-cell emoji on the same row as the close marker doesn't create a
547
- * vertical break, and in hide-subagent-output mode the SubagentBlock
548
- * box isn't rendered either, so the parent's follow-up markdown was
549
- * glued directly against the close line. Subagents should READ like
550
- * tool calls: open with breathing room, close tight inside, and open
551
- * a clean gap before the parent's next thought — that's the contract
552
- * the tool-call → markdown transition uses, mirrored here.
553
- *
554
- * Renderer-agnostic — TUI uses it as Yoga `marginTop`; a CSS host can
555
- * use the same number as the row's top margin in `em` / `rem`.
556
- */
557
- declare function marginTopFor(event: StreamEvent, previous: StreamEvent | undefined): number;
558
- /** Effective context size of the most recent assistant turn — drives the footer indicator. */
559
- /**
560
- * Walk from the end of `turns` and return the cache-aware input-token total
561
- * of the most recent **parent** (depth-0) assistant turn. Subagent turns
562
- * are skipped because their context window is the child's, not the parent's
563
- * — surfacing a subagent's `usage.input` as the footer's "context used"
564
- * after a session ends mid-spawn would be misleading. The next prompt
565
- * feeds the parent, so the parent's last view is what matters.
566
- *
567
- * Zero-context placeholder turns are also skipped. `executeTurn`
568
- * synthesizes an assistant turn with `usage: { input: 0, output: 0 }`
569
- * when the provider stream throws / aborts before any usage is reported
570
- * (see `src/loop.ts`'s catch path) — that turn is purely a shape
571
- * contract for resume, not a real context-window measurement. Without
572
- * the skip, an abort mid-stream shadows the prior real turn and the
573
- * footer reads `ctx 0` on the next session load even though earlier
574
- * turns accumulated meaningful context (and `run.cost`).
575
- *
576
- * `runs` is optional for backwards compatibility (older call sites and
577
- * tests that don't have ancestry info). Without it, this falls back to the
578
- * pre-fix behavior — depth is unknown so every assistant turn qualifies.
579
- */
580
- declare function lastContextSizeFromTurns(turns: SessionTurn[], runs?: readonly SessionRun[]): number;
581
- /**
582
- * Sum provider-reported USD cost across every run in a session. Used to
583
- * seed the live cost indicator on session activation. Returns 0 when no
584
- * run carries a `cost` (most providers — only OpenRouter reports today).
585
- */
586
- declare function sumRunCosts(runs: readonly SessionRun[]): number;
587
- /** Per-model token/spend totals across a session — see {@link usageByModel}. */
588
- interface ModelUsageSummary {
589
- /** Provider-echoed model id, or `"unknown"` for turns that never recorded one. */
590
- modelId: string;
591
- turns: number;
592
- /** Fresh (uncached) input tokens. */
593
- input: number;
594
- output: number;
595
- cacheRead: number;
596
- cacheCreation: number;
597
- /** Summed USD cost across turns that carried one (provider-reported or estimated). */
598
- cost: number;
599
- /**
600
- * `false` when at least one turn had no cost figure (no published rate
601
- * for the model) — `cost` is then a floor, not a total.
602
- */
603
- costComplete: boolean;
604
- }
605
- /**
606
- * Aggregate per-model token + spend totals across every run in a session.
607
- * Parent and subagent runs alike: each turn carries its own `modelId`, so
608
- * cost-tiered delegation (cheap spawn workers) shows up as separate rows
609
- * priced at their own rates. Sorted by cost (desc), then total tokens, so
610
- * the biggest spender reads first.
611
- */
612
- declare function usageByModel(runs: readonly SessionRun[]): ModelUsageSummary[];
613
- //#endregion
614
- //#region src/chat/config.d.ts
615
- /**
616
- * Provider registry — a map keyed by `descriptor.key`. Passed verbatim to the
617
- * chat engine; there is no implicit merge with built-ins. Hosts that want the
618
- * four default providers spread {@link BUILTIN_PROVIDERS}; hosts that only
619
- * want their own pass exactly their own.
620
- */
621
- type ProviderRegistry = Readonly<Record<string, ProviderDescriptor>>;
622
- /**
623
- * Options accepted by `resolveConfig()` (and, transitively, by `runTui()` and
624
- * any future GUI launcher). Every field is optional — defaults boot a working
625
- * chat against the built-in providers with sessions stored under `~/.zidane/`.
626
- */
627
- interface ChatOptions {
628
- /**
629
- * Directory name used under `storageDir` for sessions + state.
630
- * Default: `'.zidane'` → `~/.zidane/sessions.db` + `~/.zidane/state.json`.
631
- * Pass e.g. `'.myapp'` for `~/.myapp/...`, or `'myapp'` for a visible dir.
632
- */
633
- prefix?: string;
634
- /**
635
- * Storage root. Defaults to the user's home directory. Combined with
636
- * `prefix` to form the data directory.
637
- */
638
- storageDir?: string;
639
- /**
640
- * Provider registry. Each value is a {@link ProviderDescriptor} carrying
641
- * label + factory + credential metadata. **No automatic merge** — hosts
642
- * pass exactly what they want.
643
- *
644
- * - Omitted → {@link BUILTIN_PROVIDERS} (anthropic + openai + openrouter + cerebras).
645
- * - `providers: BUILTIN_PROVIDERS` → same as omitted, but explicit.
646
- * - `providers: { anthropic: anthropicDescriptor }` → only Anthropic.
647
- * - `providers: { ...BUILTIN_PROVIDERS, mine: customDescriptor }` → built-ins + custom.
648
- * - `providers: { mine: customDescriptor }` → custom-only, **no built-ins**.
649
- */
650
- providers?: ProviderRegistry;
651
- /**
652
- * Legacy single-agent preset (tools, system prompt, behavior). When set
653
- * **without** {@link ChatOptions.agents}, the resolver wraps this preset
654
- * into a one-entry {@link AgentRegistry} keyed `default` so existing
655
- * callers keep working and the picker is effectively hidden.
656
- *
657
- * Prefer `agents` for any multi-profile setup. Passing both throws.
658
- */
659
- preset?: Preset;
660
- /**
661
- * Agent profile registry — keyed by `profile.id`. Each profile bundles a
662
- * preset with display metadata (label, description, accent). The TUI
663
- * shows a picker (Ctrl+A) when more than one profile is registered.
664
- *
665
- * - Omitted (and `preset` omitted) → {@link BUILTIN_AGENTS} (Build + Plan).
666
- * - Omitted but `preset` provided → single-entry registry around the preset.
667
- * - Provided → host owns the registry; pass exactly what you want.
668
- *
669
- * Hosts mixing built-ins with their own typically spread:
670
- * `agents: { ...BUILTIN_AGENTS, debug: myDebugProfile }`.
671
- */
672
- agents?: AgentRegistry;
673
- /**
674
- * Id of the profile every fresh session (and the initial launch) starts
675
- * in. Resolved against `agents`; unknown ids fall through to
676
- * `DEFAULT_AGENT_ID`, then the registry's first key. Sessions remember
677
- * the profile they were created with; this is never overridden by a
678
- * previously picked profile.
679
- */
680
- defaultAgent?: string;
681
- /**
682
- * Session store — either an instance or a factory called with the
683
- * resolved storage paths. **Required** at the chat layer so this module
684
- * stays platform-agnostic (no `bun:sqlite` baked in). Terminal hosts use
685
- * `createTuiStore` from `zidane/session/sqlite`; a future GUI host can
686
- * supply a different adapter (IndexedDB, remote API, in-memory) without
687
- * touching this layer.
688
- *
689
- * ```ts
690
- * import { createTuiStore } from 'zidane/session/sqlite'
691
- *
692
- * // Either pass a factory…
693
- * resolveConfig({ store: paths => createTuiStore(paths.db) })
694
- *
695
- * // …or an instance built ahead of time.
696
- * const store = createTuiStore('/path/to/sessions.db')
697
- * resolveConfig({ store })
698
- * ```
699
- */
700
- store: SessionStore | ((paths: ResolvedPaths) => SessionStore);
701
- /**
702
- * Project-scoped session storage. Off by default; when it resolves
703
- * to `true` and the launch happens inside a git repo, zidane
704
- * auto-creates `<git-root>/.{prefix}/` and stores `sessions.db` +
705
- * `state.json` there — so sessions, mcps.json, and skills all live
706
- * alongside the project they belong to. Credentials and the
707
- * cross-project safelist stay at `~/.{prefix}/` regardless.
708
- *
709
- * Precedence (most → least specific): `options.projectDb` >
710
- * `ZIDANE_PROJECT_DB` env var (`0`/`false`/`off`/`no` → off,
711
- * `1`/`true`/`on`/`yes` → on) > `~/.{prefix}/config.json`
712
- * `projectDb` > `false`. Note the host option beats the env var —
713
- * setting `ZIDANE_PROJECT_DB` has no effect when the host passes an
714
- * explicit `projectDb`.
715
- *
716
- * When it resolves to `false`, OR when not inside a git repo,
717
- * everything lives at `~/.{prefix}/` — the classic single-store
718
- * layout.
719
- */
720
- projectDb?: boolean;
721
- /**
722
- * Override for the project root. Defaults to `process.cwd()`. Hosts
723
- * embedding the TUI from a non-CLI context (tests, daemons) can pin
724
- * the cwd here so the git-root walk produces a stable result. Has no
725
- * effect when `projectDb` resolves to `false`.
726
- */
727
- cwd?: string;
728
- /**
729
- * Optional one-shot launch request used by CLI shells such as `zidane run`.
730
- * The TUI opens/creates the requested session and submits the prompt after
731
- * the first provider/session activation, while keeping the normal renderer
732
- * and persistence behavior.
733
- */
734
- launch?: StartLocalOptions;
735
- /**
736
- * Auto-update wiring. When set, the App quietly checks the npm registry
737
- * for a newer release of `packageName` (matching the host's package),
738
- * caches the result for a day under `userDir/`, and surfaces a passive
739
- * `↑ vX.Y.Z` chip in the footer when one is available.
740
- *
741
- * Consumers wrapping `runTui` for their own CLI inline their own
742
- * `package.json` version at build time and pass it here. The bundled
743
- * `zidane-tui` binary wires this automatically in `tui/src/cli.ts`.
744
- *
745
- * Defaults to `null` — no auto-update plumbing, no network calls,
746
- * no chip.
747
- */
748
- autoUpdate?: AutoUpdateConfig | null;
749
- /**
750
- * Pre-built {@link ExtensionRegistry}. The `resolveConfig` surface is
751
- * synchronous; extension `setup()` can be async, so the host must
752
- * build the registry ahead of time and pass it here verbatim.
753
- *
754
- * Typical wiring (matches `runTui`):
755
- *
756
- * ```ts
757
- * import {
758
- * buildExtensionRegistry,
759
- * discoverExtensions,
760
- * inlineLoadedExtension,
761
- * resolveConfig,
762
- * } from 'zidane'
763
- *
764
- * const registry = await buildExtensionRegistry([
765
- * // Project-scoped extensions run arbitrary local code — they stay
766
- * // off unless the host establishes trust explicitly (or the user
767
- * // sets ZIDANE_TRUST_PROJECT_EXTENSIONS=1).
768
- * ...await discoverExtensions({ cwd, prefix, trustProjectExtensions: hostTrustsProject }),
769
- * ...inlineDefinitions.map(inlineLoadedExtension),
770
- * ])
771
- * const config = resolveConfig({ ...opts, extensionRegistry: registry })
772
- * ```
773
- *
774
- * Omitted → empty registry (no contributions).
775
- */
776
- extensionRegistry?: ExtensionRegistry;
777
- /**
778
- * Extra extension scan roots the host used (or wants runtime re-discovery
779
- * to use). Each path is a root containing extension dirs/packages:
780
- * `<root>/<name>/index.ts`. `runTui` wires this from
781
- * `ZIDANE_EXTENSION_DIRS` when omitted.
782
- */
783
- extensionScanPaths?: readonly string[];
784
- /**
785
- * Extra Agent Plugin scan roots. Each path is a root containing plugin
786
- * directories: `<root>/<name>/plugin.json`. `runTui` wires this from
787
- * `ZIDANE_PLUGIN_DIRS` when omitted.
788
- *
789
- * Appended after the four default roots, so a project or user plugin still
790
- * wins a name collision against a dev root.
791
- */
792
- pluginScanPaths?: readonly string[];
793
- /**
794
- * Whether project-scoped extensions are trusted to run their (arbitrary,
795
- * local) code. Off by default unless the embedding host has established
796
- * project trust; falls back to `ZIDANE_TRUST_PROJECT_EXTENSIONS=1`.
797
- *
798
- * Surfaced on {@link ResolvedConfig.trustProjectExtensions} so a host
799
- * that re-discovers extensions at runtime (e.g. the TUI on a working-
800
- * directory change) reuses the same trust decision as boot.
801
- */
802
- trustProjectExtensions?: boolean;
803
- }
804
- /**
805
- * Host-supplied auto-update settings. The check itself is gated on
806
- * `Settings.checkForUpdates`; passing a config wires the React plumbing.
807
- *
808
- * Hosts that want to publish their own consumer-facing package can pass
809
- * different values without forking anything — the registry / channel /
810
- * platform-package-prefix are all knobs.
811
- */
812
- interface AutoUpdateConfig {
813
- /** Top-level npm package the user installs (`zidane-tui`, `my-app`, …). */
814
- packageName: string;
815
- /** Inlined at build time — usually `pkg.version`. */
816
- currentVersion: string;
817
- /** dist-tag. Defaults to `'latest'`. */
818
- channel?: string;
819
- /** Registry base URL. Defaults to `'https://registry.npmjs.org'`. */
820
- registry?: string;
821
- /**
822
- * Override the read-through cache lifetime in ms for the in-TUI hook.
823
- * Defaults to `0` — every TUI launch fetches fresh, so the chip
824
- * never lies. Pass a positive value (e.g. `3_600_000` for 1 h) to
825
- * throttle the registry-poll rate at the cost of staleness.
826
- *
827
- * The on-disk cache is always WRITTEN, regardless of this value, so
828
- * `zidane upgrade` and other tooling read paths benefit immediately.
829
- */
830
- cacheTtlMs?: number;
831
- /**
832
- * Platform-package prefix used by the in-place self-update flow when
833
- * resolving the per-arch tarball name. Defaults to `'<packageName>-'`
834
- * (i.e. `zidane-tui-darwin-arm64` when `packageName === 'zidane-tui'`).
835
- * Override only when your platform packages don't follow the `<name>-<key>`
836
- * convention.
837
- */
838
- platformPackagePrefix?: string;
839
- /**
840
- * Executable name on PATH for `packageName`, used to probe the version
841
- * installed on disk (the `↻ vX` "restart to update" chip). Defaults to
842
- * `packageName`; the TUI passes `'zidane'` for `zidane-tui`.
843
- */
844
- binName?: string;
845
- }
846
- /** Resolved on-disk layout produced by {@link resolveConfig}. */
847
- interface ResolvedPaths {
848
- /**
849
- * Effective data root — equals `userDir` (configDir) when project
850
- * mode is off, `projectDir` when it's on. Kept for callers that
851
- * wrote against the pre-project-db API; new code should reference
852
- * the explicit slots (`configDir` / `dataDir` / `cacheDir` /
853
- * `stateDir`) or `projectDir` / `db` / `state` instead.
854
- */
855
- dir: string;
856
- /**
857
- * User-scoped config root — credentials, mcp-credentials, keybindings,
858
- * `config.json`, `mcps.json`, skills. Legacy alias for `configDir`;
859
- * existing call sites still reference `userDir`. In XDG mode this
860
- * lands at `$XDG_CONFIG_HOME/zidane`; in legacy mode the four slots
861
- * (config / data / state / cache) collapse to a single
862
- * `<storageDir>/<prefix>` directory.
863
- */
864
- userDir: string;
865
- /**
866
- * Project-scoped data root. Set to `<git-root>/<prefix>` when project
867
- * mode resolved to ON and a git root was found. `null` otherwise.
868
- */
869
- projectDir: string | null;
870
- /** Resolved `sessions.db` path. Lives under `projectDir` when active, else `dataDir`. */
871
- db: string;
872
- /** Resolved `state.json` path. Lives under `projectDir` when active, else `stateDir`. */
873
- state: string;
874
- /**
875
- * XDG config slot — `$XDG_CONFIG_HOME/zidane` on a fresh Linux install,
876
- * `<storageDir>/<prefix>` (e.g. `~/.zidane/`) in legacy mode. Holds
877
- * user-editable surface (`credentials.json`, `mcps.json`, …).
878
- */
879
- configDir: string;
880
- /**
881
- * XDG data slot — `$XDG_DATA_HOME/zidane` on Linux, single-dir
882
- * elsewhere. Holds long-lived chat history (`sessions.db`).
883
- */
884
- dataDir: string;
885
- /**
886
- * XDG state slot — `$XDG_STATE_HOME/zidane` on Linux, single-dir
887
- * elsewhere. Holds per-machine UI bookkeeping (`state.json`).
888
- */
889
- stateDir: string;
890
- /**
891
- * XDG cache slot — `$XDG_CACHE_HOME/zidane` on Linux, single-dir
892
- * elsewhere. Holds regenerable data: persisted tool results,
893
- * background-task logs, auto-update registry cache.
894
- */
895
- cacheDir: string;
896
- /**
897
- * Which resolution branch produced the layout. `'xdg'` when split
898
- * across the four XDG dirs; one of `'legacy-explicit'`,
899
- * `'legacy-existing'`, or `'default'` when the slots collapse to a
900
- * single directory. Surfaced for diagnostics + tests.
901
- */
902
- storageMode: StorageMode;
903
- }
904
- interface ResolvedConfig {
905
- prefix: string;
906
- storageDir: string;
907
- paths: ResolvedPaths;
908
- providers: ProviderRegistry;
909
- /**
910
- * Resolved profile registry. Always non-empty; the resolver throws when
911
- * the host passes an empty `agents` map (same contract as `providers`).
912
- */
913
- agents: AgentRegistry;
914
- /** Id of the profile to activate on mount. Guaranteed to key into `agents`. */
915
- initialAgentId: string;
916
- store: SessionStore;
917
- stateStore: StateStoreApi;
918
- /** Lookup by `ProviderKey` returning the available models for the picker. */
919
- modelsFor: (key: ProviderKey) => readonly ModelInfo[];
920
- initialState: TuiState;
921
- initialSettings: Partial<Settings>;
922
- resumeProvider: ProviderAuth | null;
923
- initialPicked: Picked | null;
924
- /**
925
- * Effective keybindings — defaults merged with the user-level
926
- * `<userDir>/keybindings.json` (when present). Always fully-resolved
927
- * so consumers can treat the record as total. See `./keybindings.ts`
928
- * for the action catalog + spec format.
929
- */
930
- keybindings: KeyBindings;
931
- /**
932
- * Resolved extension-contributed keybindings. Each entry pairs the
933
- * extension's binding definition with the user's effective spec
934
- * (override from `keybindings.json` when present, default
935
- * otherwise). The TUI dispatcher iterates these alongside the
936
- * built-in action catalog; the GUI host can do the same.
937
- *
938
- * Empty when no extension contributed a keybinding.
939
- */
940
- extensionKeybindings: readonly ResolvedExtensionKeybinding[];
941
- /**
942
- * Resolved auto-update knobs (forwarded verbatim from `ChatOptions.autoUpdate`)
943
- * — `null` when the host didn't wire one. The TUI feeds this into
944
- * `useUpdateCheck` so the footer chip + the `zidane upgrade` subcommand
945
- * share a single source of truth.
946
- */
947
- autoUpdate: AutoUpdateConfig | null;
948
- /**
949
- * Merged extension contributions — the registry passed via
950
- * {@link ChatOptions.extensionRegistry}, returned verbatim, or
951
- * {@link EMPTY_EXTENSION_REGISTRY} when the host didn't pass one.
952
- * `resolveConfig` is synchronous, so it never runs `setup()` itself;
953
- * the host pre-builds the registry with `buildExtensionRegistry`.
954
- *
955
- * Renderer-side wiring reads `tuiContributions` / `guiContributions`
956
- * to mount keybindings / footer hints / modals / panels. The
957
- * `extensionPreset` field below carries the agent-side surface
958
- * (tools / hooks / mcpServers / skills) ready to spread.
959
- */
960
- extensions: ExtensionRegistry;
961
- /**
962
- * Extra extension scan roots used at boot. Runtime re-discovery (TUI cwd
963
- * changes, future hosts) feeds these back into the shared discovery helper so
964
- * local/dev package roots stay active after the initial launch.
965
- */
966
- extensionScanPaths: readonly string[];
967
- /**
968
- * Extra Agent Plugin scan roots used at boot. Threaded into the discovery
969
- * shell so a dev root stays active across project/cwd changes, same as
970
- * {@link ResolvedConfig.extensionScanPaths}.
971
- */
972
- pluginScanPaths: readonly string[];
973
- /**
974
- * Single {@link Preset} folded together from every extension's
975
- * agent-side contributions. Hosts spread it into `createAgent()`
976
- * alongside the active profile's preset:
977
- *
978
- * ```ts
979
- * const profile = composePresets(extensionPreset, agentProfile.preset)
980
- * const agent = createAgent({ ...profile, provider })
981
- * ```
982
- *
983
- * Extension hooks are bucketed per event so every handler fires;
984
- * tools and mcpServers compose with profile contributions via the
985
- * usual `composePresets` rules. System-prompt fragments land as a
986
- * trailing block on `preset.system` (host profiles that re-derive
987
- * `system` per session — Build / Plan — append the fragments via
988
- * the `system:transform` hook so the live system always carries
989
- * them).
990
- */
991
- extensionPreset: Preset;
992
- /**
993
- * System-prompt fragments contributed by extensions, in registration
994
- * order. Surfaced separately from {@link extensionPreset} so hosts
995
- * that re-derive `system` per session (Build / Plan in the TUI) can
996
- * append them on `system:transform` instead of trying to merge two
997
- * `preset.system` strings.
998
- */
999
- extensionSystemFragments: readonly string[];
1000
- /**
1001
- * Spawnable subagents (adds) contributed by extensions, keyed by name.
1002
- * Surfaced separately from {@link extensionPreset} (like
1003
- * {@link extensionSystemFragments}) because subagents don't ride the
1004
- * preset path — the host merges them onto the spawn tool's base
1005
- * registry via `spawn.withSubagents(...)` at agent build time.
1006
- */
1007
- extensionSubagents: SubagentRegistry;
1008
- /**
1009
- * Subagent edits contributed by extensions, keyed by target name and
1010
- * composed in registration order. Applied (after the adds above) by
1011
- * the host's `spawn.withSubagents(...)` call so extensions can edit or
1012
- * delete host- / extension-provided subagents by name.
1013
- */
1014
- extensionSubagentOverrides: Record<string, SubagentOverride>;
1015
- /**
1016
- * Merged extension-contributed config categories, keyed by category id.
1017
- * Surfaced (alongside {@link extensionConfigItems}) so the TUI can read
1018
- * the schema in-process — same way it reads `extensions.themes` — and
1019
- * the GUI's `extensions:configSchema` IPC can serialize it.
1020
- */
1021
- extensionConfigCategories: Readonly<Record<string, ExtensionConfigCategory>>;
1022
- /**
1023
- * Merged extension-contributed config items, namespaced
1024
- * `extName → itemKey → item`. Each item carries its resolved
1025
- * `category`; values are read default-first via the core resolver.
1026
- */
1027
- extensionConfigItems: Readonly<Record<string, Readonly<Record<string, StoredExtensionConfigItem>>>>;
1028
- /**
1029
- * Resolved project-extension trust decision (option + env fallback).
1030
- * Hosts that re-discover extensions at runtime feed this back into
1031
- * {@link discoverAndBuildExtensionRegistry} so the rebuild trusts the
1032
- * same scopes boot did.
1033
- */
1034
- trustProjectExtensions: boolean;
1035
- /**
1036
- * Raw user `keybindings.json` object (post-JSONC-strip). Surfaced so a
1037
- * host re-resolving {@link extensionKeybindings} at runtime (after an
1038
- * extension registry rebuild) can reuse the same override source
1039
- * without a second disk read.
1040
- */
1041
- rawKeybindings: Readonly<Record<string, unknown>>;
1042
- /** One-shot launch request forwarded from {@link ChatOptions.launch}. */
1043
- launch: StartLocalOptions | null;
1044
- }
1045
- /**
1046
- * Resolve user options into a fully-bound runtime config.
1047
- *
1048
- * NOT pure: besides disk reads, this mutates `process.env` so the harness
1049
- * providers pick up the chat engine's credential store — it sets
1050
- * `ZIDANE_CREDENTIALS_PATH` and reconciles stored API keys / OAuth entries
1051
- * into env via `applyApiKeyEnv` (which can overwrite or delete ambient keys
1052
- * like `ANTHROPIC_API_KEY`; see its JSDoc for the precedence rationale).
1053
- */
1054
- declare function resolveConfig(options: ChatOptions): ResolvedConfig;
1055
- /**
1056
- * Compute the on-disk layout for a single TUI session. Public so hosts
1057
- * (CLI tools, tests, scripted bootstraps) can ask "where will sessions
1058
- * land?" without going through `resolveConfig`'s full machinery.
1059
- *
1060
- * Storage-slot resolution (config / data / state / cache) is delegated
1061
- * to {@link resolveStorageDirs}. In legacy modes the four slots collapse
1062
- * to a single `<storageDir>/<prefix>` directory; in XDG mode they fan
1063
- * out into `$XDG_CONFIG_HOME/zidane`, `$XDG_DATA_HOME/zidane`,
1064
- * `$XDG_STATE_HOME/zidane`, `$XDG_CACHE_HOME/zidane`. See the module
1065
- * doc on `./xdg.ts` for the full precedence chain.
1066
- *
1067
- * Decision logic for project mode (least → most specific):
1068
- *
1069
- * 1. Default: OFF — sessions live in the user-scoped `dataDir`
1070
- * and get scoped per-project via the `SessionData.projectRoot` tag.
1071
- * 2. `<configDir>/config.json` `projectDb` flag (when present).
1072
- * 3. `ZIDANE_PROJECT_DB` env var (`'0'` / `'false'` / `'off'` → off,
1073
- * anything else true if set).
1074
- * 4. `options.projectDb` (host call site).
1075
- *
1076
- * Project mode activates only when the resolution above lands on
1077
- * `true` AND a git repo is found above `cwd`. Outside git or with the
1078
- * flag off, sessions + state stay at the user-scoped slots.
1079
- *
1080
- * Auto-creates the project `.{prefix}/` directory when mode resolves
1081
- * to ON (silent — mirrors `ensureStateDir`). User slots are created
1082
- * lazily by the state-store + credentials writers; we don't pre-touch
1083
- * them here so a read-only invocation stays read-only.
1084
- */
1085
- declare function resolveStoragePaths(opts: {
1086
- prefix: string; /** Explicit storage root. When set, forces legacy-explicit mode. */
1087
- storageDir?: string;
1088
- cwd: string; /** Host override for project mode. Beats the user-config + env-var sources. */
1089
- projectDb?: boolean;
1090
- }): ResolvedPaths;
1091
- //#endregion
1092
- //#region src/chat/credentials.d.ts
1093
- interface ApiKeyCredential {
1094
- kind: 'apikey';
1095
- /**
1096
- * Bearer API key. May be empty when the descriptor has no `envKey` and
1097
- * authenticates entirely via {@link customFields} (e.g. the `local`
1098
- * provider, where the auth signal is the configured base URL).
1099
- */
1100
- value: string;
1101
- /**
1102
- * Free-form fields collected by the wizard from the descriptor's
1103
- * `customFields` definitions. Keys match the descriptor field's `key`.
1104
- * Mirrored into `process.env[field.envVar]` by `applyApiKeyEnv` so the
1105
- * provider's factory can read them via the existing env-var convention.
1106
- */
1107
- customFields?: Record<string, string>;
1108
- }
1109
- interface OAuthCredential {
1110
- kind: 'oauth';
1111
- access: string;
1112
- refresh?: string;
1113
- expires?: number;
1114
- /**
1115
- * User-given account name ("work", "personal"). Optional — absent reads as
1116
- * `DEFAULT_OAUTH_ACCOUNT_LABEL` (see `oauthAccountLabel`). Survives token
1117
- * refresh because the refresh path spreads the stored entry into the rotated
1118
- * one (see `resolveOAuthApiKey`).
1119
- */
1120
- label?: string;
1121
- /** Provider-specific extras (e.g. OpenAI Codex `accountId`). */
1122
- [extra: string]: unknown;
1123
- }
1124
- type ProviderCredential = ApiKeyCredential | OAuthCredential;
1125
- /** One stored credential of a provider, addressed by the file key it lives at. */
1126
- interface StoredCredential {
1127
- /** File key — the selection identity for promote / remove / relabel. */
1128
- key: string;
1129
- credential: ProviderCredential;
1130
- /** True for the canonical slot, i.e. the credential readers resolve. */
1131
- active: boolean;
1132
- }
1133
- /** Top-level shape of `credentials.json` — keys are credential-file keys. */
1134
- type CredentialsFile = Record<string, ProviderCredential>;
1135
- /**
1136
- * Resolve the credentials file path given the resolved TUI data directory
1137
- * (typically `~/.zidane`, i.e. `config.paths.dir`).
1138
- *
1139
- * Matches the convention used elsewhere in the TUI (sessions.db, state.json)
1140
- * so a single `ZIDANE_STORAGE_DIR` override moves the entire data root.
1141
- */
1142
- declare function credentialsPath(dataDir: string): string;
1143
- /**
1144
- * Read credentials from disk.
1145
- *
1146
- * Returns `{}` when the file is missing or corrupt (last-ditch tolerance —
1147
- * a hand-edit gone wrong shouldn't lock the user out of re-authing). On first
1148
- * call with no file present, attempts a migration from `cwd/.credentials.json`
1149
- * (the legacy location used by `bun run auth`).
1150
- */
1151
- declare function readCredentials(dataDir: string): CredentialsFile;
1152
- /** Read a single provider's credential (translating via the descriptor). */
1153
- declare function readProviderCredential(dataDir: string, descriptor: ProviderDescriptor): ProviderCredential | undefined;
1154
- /**
1155
- * Both stored credentials for a provider: `active` is the one every reader
1156
- * resolves, `alternate` is the stored-but-not-preferred one (if any).
1157
- *
1158
- * Predates multi-account and only sees the `#alt` slot; use
1159
- * {@link readProviderCredentials} to list every stored account.
1160
- */
1161
- declare function readProviderCredentialPair(dataDir: string, descriptor: ProviderDescriptor): {
1162
- active?: ProviderCredential;
1163
- alternate?: ProviderCredential;
1164
- };
1165
- /**
1166
- * Every stored credential of a provider, active first.
1167
- *
1168
- * Tolerant of any kind in any slot: `#alt` is meant for the API key and
1169
- * `#account:N` for OAuth accounts, but a file written by an older build (which
1170
- * parked the OAuth alternate in `#alt`) must still list everything it holds.
1171
- */
1172
- declare function readProviderCredentials(dataDir: string, descriptor: ProviderDescriptor): StoredCredential[];
1173
- /** Pure form of {@link readProviderCredentials} over an already-read file. */
1174
- declare function storedCredentialsOf(all: CredentialsFile, fileKey: string): StoredCredential[];
1175
- /**
1176
- * Write credentials atomically (write-then-rename) with mode 0o600.
1177
- *
1178
- * Atomic on the same filesystem — readers either see the previous file or the
1179
- * new one, never a half-written intermediate. Creates the parent dir if needed
1180
- * (first launch on a fresh machine: `~/.zidane/` may not exist yet).
1181
- */
1182
- declare function writeCredentials(dataDir: string, creds: CredentialsFile): void;
1183
- interface SetProviderCredentialOptions {
1184
- /**
1185
- * File key of the stored credential this one REPLACES (a re-auth of a known
1186
- * account). The slot keeps its position — replacing the active one keeps it
1187
- * active. When the key is no longer stored (removed from another window
1188
- * mid-login), the credential is added as a new active account instead.
1189
- */
1190
- replaceKey?: string;
1191
- }
1192
- /**
1193
- * Store a credential as the provider's preferred one.
1194
- *
1195
- * The previous active credential is demoted, not destroyed: authenticating
1196
- * with OAuth used to silently delete a working API key (and vice versa), and a
1197
- * second OAuth login used to overwrite the first account. An API key moves to
1198
- * {@link alternateCredKey}; an OAuth grant moves to the next free account slot.
1199
- * Replacing an API key with an API key is a plain overwrite — there is only
1200
- * ever one — and so is an OAuth login that names its predecessor via
1201
- * `replaceKey`.
1202
- */
1203
- declare function setProviderCredential(dataDir: string, descriptor: ProviderDescriptor, cred: ProviderCredential, opts?: SetProviderCredentialOptions): void;
1204
- /**
1205
- * Outcome of {@link setPreferredCredential}.
1206
- *
1207
- * Three states rather than a boolean because the two non-promoting cases need
1208
- * opposite handling: `already-active` is a harmless idempotent call (the UI
1209
- * repaints and moves on), while `not-stored` means the caller asked for a
1210
- * credential that does not exist and should say so.
1211
- */
1212
- type PreferCredentialResult = 'promoted' | 'already-active' | 'not-stored';
1213
- /**
1214
- * What {@link setPreferredCredential} promotes: a stored credential by file
1215
- * key (from {@link readProviderCredentials} / `AuthMethod.key`), or the first
1216
- * stored credential of a kind — the pre-multi-account form, still right when
1217
- * the caller only knows "switch to the API key".
1218
- */
1219
- type PreferredCredentialTarget = ProviderCredential['kind'] | {
1220
- key: string;
1221
- };
1222
- /**
1223
- * Make one of the provider's stored credentials the preferred one.
1224
- *
1225
- * Swaps the target into the canonical slot and parks the previous active one
1226
- * (see {@link parkDemoted}). Returns which of the three outcomes happened so a
1227
- * caller cannot report a swap that provably did not occur — the write is
1228
- * silent either way, and a success-shaped `void` was a trap for any caller that
1229
- * trusted it instead of refetching.
1230
- */
1231
- declare function setPreferredCredential(dataDir: string, descriptor: ProviderDescriptor, target: PreferredCredentialTarget): PreferCredentialResult;
1232
- /**
1233
- * Drop ONE stored credential. Removing the active one promotes a survivor —
1234
- * another credential of the same kind when there is one (a second OAuth
1235
- * account), else whatever is left — so the provider does not go dark while it
1236
- * still holds a working credential. Returns false when `key` was not stored.
1237
- */
1238
- declare function removeStoredCredential(dataDir: string, descriptor: ProviderDescriptor, key: string): boolean;
1239
- /**
1240
- * Name a stored OAuth account. An empty label drops the field, which reads
1241
- * back as {@link DEFAULT_OAUTH_ACCOUNT_LABEL}. Returns false when `key` holds
1242
- * no OAuth credential.
1243
- */
1244
- declare function setCredentialLabel(dataDir: string, descriptor: ProviderDescriptor, key: string, label: string): boolean;
1245
- /**
1246
- * Sign a provider out — drops EVERY stored credential.
1247
- *
1248
- * "Signed out" has to mean the provider resolves nothing afterwards, which is
1249
- * what this has always guaranteed and what callers named it for; promoting a
1250
- * survivor instead would silently leave the provider authenticated through
1251
- * another source. Callers that want that behavior use
1252
- * {@link removeStoredCredential} on the one slot they mean.
1253
- */
1254
- declare function removeProviderCredential(dataDir: string, descriptor: ProviderDescriptor): void;
1255
- /**
1256
- * Reconcile `process.env` with the stored credentials so the harness providers
1257
- * pick up the wizard's output via their existing env-var resolution. Called
1258
- * once at TUI launch after the credentials file has been resolved.
1259
- *
1260
- * **Precedence: stored credential > ambient env.** When the user has run the
1261
- * auth wizard, that's an explicit, recent action — it MUST win over whatever
1262
- * ambient value is already in `process.env`. Otherwise an upgrade reliably
1263
- * breaks for anyone whose cwd happens to contain a stale `.env`: Bun
1264
- * auto-loads `.env` from cwd into `process.env` before our code runs, the
1265
- * legacy `bun run auth` used to upsert tokens into `cwd/.env`, and even a
1266
- * one-off `export ANTHROPIC_API_KEY=…` from months ago in the user's shell rc
1267
- * can outlive its usefulness. None of those should override a key the user
1268
- * just typed into the wizard.
1269
- *
1270
- * Three cases per registered provider with an `envKey`:
1271
- *
1272
- * 1. Stored `kind: 'apikey'` → overwrite env with the stored value. Wizard
1273
- * wins. A debug log fires when this clobbers a different ambient value.
1274
- * 2. Stored `kind: 'oauth'` → DELETE env, so {@link resolveOAuthApiKey}
1275
- * falls through to the file-read + refresh path. A stale OAuth token
1276
- * in env would otherwise short-circuit refresh and get rejected.
1277
- * 3. No stored entry → leave env alone. Env-only setups (no wizard run yet,
1278
- * hosts driving zidane purely from secrets management) keep working.
1279
- *
1280
- * To opt out and force ambient env to win again, the user signs the provider
1281
- * out via the wizard (which deletes the stored entry → case 3 above).
1282
- *
1283
- * Descriptors without an `envKey` (OAuth-only providers, custom providers
1284
- * that bypass env-var resolution) are skipped silently.
1285
- */
1286
- declare function applyApiKeyEnv(dataDir: string, registry: Readonly<Record<string, ProviderDescriptor>>, opts?: {
1287
- log?: (message: string) => void;
1288
- }): void;
1289
- //#endregion
1290
- //#region src/chat/mcps-discovery.d.ts
1291
- /**
1292
- * One entry in the discovered list. `path` is the source file (one of
1293
- * the `mcp(s).json` variants under `.agents/` or `.{prefix}/`) so a
1294
- * Settings picker can show "Defined in ~/.zidane/mcp.json" tooltips
1295
- * and the user can tell which file declared what.
1296
- */
1297
- interface DiscoveredMcp {
1298
- config: McpServerConfig;
1299
- source: 'project' | 'user';
1300
- path: string;
1301
- }
1302
- /**
1303
- * Search order for MCP config files — see {@link projectUserPaths}.
1304
- *
1305
- * Both `mcps.json` (zidane's canonical name) and `mcp.json` (Cursor /
1306
- * common ecosystem alias) are picked up from every search root. The
1307
- * canonical name wins within the same directory; across files the
1308
- * usual first-found-by-name dedup applies, so `mcp.json` effectively
1309
- * merges its non-overlapping entries on top of `mcps.json`.
1310
- *
1311
- * Order per scope (project beats user):
1312
- * 1. `{project}/.agents/mcps.json`
1313
- * 2. `{project}/.agents/mcp.json`
1314
- * 3. `{project}/.{prefix}/mcps.json`
1315
- * 4. `{project}/.{prefix}/mcp.json`
1316
- * 5. `~/.agents/mcps.json`
1317
- * 6. `~/.agents/mcp.json`
1318
- * 7. `~/.{prefix}/mcps.json`
1319
- * 8. `~/.{prefix}/mcp.json`
1320
- *
1321
- * Non-existent files are skipped without error.
1322
- */
1323
- declare function defaultMcpsConfigPaths(opts?: {
1324
- cwd?: string;
1325
- home?: string;
1326
- prefix?: string;
1327
- }): {
1328
- path: string;
1329
- source: 'project' | 'user';
1330
- }[];
1331
- /**
1332
- * Parse one `mcps.json` file. Canonical zidane shape is a flat array; the
1333
- * other shapes exist for copy-paste from neighboring tools:
1334
- *
1335
- * - `McpServerConfig[]` — flat array (recommended).
1336
- * - `{ name: {...} }` — name-keyed map.
1337
- * - `{ "mcpServers": { name: {...} } }` — Claude Desktop / Claude Code /
1338
- * Cursor wrapper. Unwrapped before normalization (otherwise
1339
- * `normalizeMcpServers` would treat the whole wrapper as a single server).
1340
- *
1341
- * Per-entry `enabled: false` (Cursor runtime state) drops the entry — same
1342
- * intent as the source tool. Use the TUI toggle list for "show but disabled".
1343
- *
1344
- * Tolerant to common copy-paste artifacts: when strict `JSON.parse` fails,
1345
- * retries after normalizing invisible whitespace that's valid Unicode but
1346
- * not valid JSON whitespace (BOM, NBSP, zero-width spaces, line/paragraph
1347
- * separators) — only OUTSIDE string literals, so user data isn't mutated.
1348
- * If the sanitized version still fails, throws the original error with a
1349
- * targeted hint when NBSPs are present.
1350
- *
1351
- * Validation flows through `normalizeMcpServers` so the result matches
1352
- * what `createAgent` accepts. Throws on truly malformed JSON; the caller
1353
- * decides whether to surface or swallow.
1354
- */
1355
- declare function parseMcpsFile(text: string): McpServerConfig[];
1356
- /**
1357
- * Per-file failure surfaced from {@link discoverProjectMcps}. The TUI shows
1358
- * these in the MCP settings empty / preamble state so a malformed
1359
- * `mcps.json` doesn't look identical to a missing one.
1360
- */
1361
- interface DiscoveryError {
1362
- path: string;
1363
- source: 'project' | 'user';
1364
- message: string;
1365
- /**
1366
- * A deliberate, documented behavior being reported (e.g. the ruler stdio
1367
- * security carve-out) rather than a failure. Hosts should style these as
1368
- * info, not error — crying wolf over a working default trains users to
1369
- * ignore the channel that also carries real parse failures.
1370
- */
1371
- informational?: boolean;
1372
- }
1373
- /**
1374
- * Result of {@link discoverProjectMcps}. `servers` is the per-source-priority
1375
- * merged list (project beats user, first-found wins on name collision).
1376
- * `errors` is one entry per file that existed but failed to parse, plus
1377
- * informational entries for servers a security gate skipped (ruler stdio
1378
- * without the foreign-agent opt-in) — empty on the happy path.
1379
- */
1380
- interface DiscoveryResult {
1381
- servers: DiscoveredMcp[];
1382
- errors: DiscoveryError[];
1383
- }
1384
- /**
1385
- * Walk the default config paths, parse every file that exists, and return
1386
- * `{ servers, errors }` in source-priority order. Project entries appear
1387
- * before user entries; first occurrence of a `name` wins (later
1388
- * duplicates dropped).
1389
- *
1390
- * Parse failures are captured into `errors` rather than thrown — the picker
1391
- * surfaces them while still showing whatever DID parse. A `ZIDANE_DEBUG`
1392
- * log line is also emitted for ops visibility.
1393
- */
1394
- declare function discoverProjectMcps(opts?: {
1395
- cwd?: string;
1396
- home?: string;
1397
- prefix?: string;
1398
- /**
1399
- * Also read MCP configs other agents maintain (Claude Code, Codex,
1400
- * Pi) — see `foreign-configs.ts`. Mirrors the `importForeignConfigs`
1401
- * setting; native locations always win name collisions, and project
1402
- * beats user within each group.
1403
- */
1404
- foreignAgents?: boolean;
1405
- /**
1406
- * Also read Ruler MCP configs (`.ruler/ruler.toml` + `mcp.json`,
1407
- * project and XDG-global) — see `ruler-configs.ts`. Mirrors the
1408
- * `importRulerConfigs` setting; same collision rules as above.
1409
- */
1410
- ruler?: boolean;
1411
- }): DiscoveryResult;
1412
- /**
1413
- * Map a user-toggled enable list onto the `mcpServers` array the agent
1414
- * receives. Conventions match `buildSkillsConfig`:
1415
- *
1416
- * - `enabled === undefined` → every discovered server enabled (default).
1417
- * - `enabled === []` → no servers (the agent runs MCP-less).
1418
- * - `enabled === [names]` → allowlist; servers not in the list are
1419
- * dropped.
1420
- *
1421
- * `disabledTools` is the per-server tool deny-list from
1422
- * `Settings.disabledMcpTools`. For each server that survives the
1423
- * server-level enable filter, the per-tool names are merged into
1424
- * `McpServerConfig.disabledTools` via **union** with anything the JSON
1425
- * file already pinned — a tool listed in either source is dropped.
1426
- * Union (not override) keeps JSON-side policy stable: a server file
1427
- * that pins `disabledTools: ['dangerous_tool']` can't be re-enabled
1428
- * via the UI by accident.
1429
- *
1430
- * `enabledTools` (JSON-side allowlist) takes precedence over the
1431
- * UI-side deny-list when both are set on the same server — the
1432
- * allowlist's "only these" semantics would be meaningless if a UI
1433
- * deny-list could subtract from it again. We don't emit `disabledTools`
1434
- * when `enabledTools` is present.
1435
- *
1436
- * Returns a fresh array — callers can mutate without affecting the
1437
- * underlying discovery list. Per-server config objects are also fresh
1438
- * copies (shallow), so the merged `disabledTools` doesn't leak back
1439
- * onto the discovery catalog.
1440
- */
1441
- declare function buildMcpServers(opts: {
1442
- discovered: readonly DiscoveredMcp[];
1443
- enabled?: readonly string[];
1444
- disabledTools?: Record<string, readonly string[]>;
1445
- }): McpServerConfig[];
1446
- /**
1447
- * Dedup a merged MCP-server list by `name`. First entry wins.
1448
- *
1449
- * Applied at agent build across every source that can contribute a server —
1450
- * `mcps.json`, Agent Plugins, launch options, extensions — so the earliest
1451
- * source in that order takes precedence.
1452
- *
1453
- * Drops are REPORTED rather than silent, via `onDropped`. A plugin shipping a
1454
- * `github` server loses to a `github` in `mcps.json`, and nothing downstream
1455
- * says so: the plugin's settings row still counts the server it shipped,
1456
- * because the row renders what the PACKAGE declares and only this merge knows
1457
- * what survived. That mirrors how the skills side reports the same class of
1458
- * event — `resolveSkills` emits `name-collision-shadowed` on the winner rather
1459
- * than annotating the loser.
1460
- *
1461
- * The reporter is injected rather than calling a logger directly so this stays
1462
- * a pure function of its input, testable without a logging shim. It lives here
1463
- * beside {@link buildMcpServers} rather than in the TUI because merge
1464
- * precedence is a config concern, not a rendering one.
1465
- */
1466
- declare function dedupMcpServersByName<T extends {
1467
- name: string;
1468
- }>(servers: readonly T[], onDropped?: (names: readonly string[]) => void): T[];
1469
- //#endregion
1470
- //#region src/chat/project-user-paths.d.ts
1471
- /**
1472
- * Shared search-path builder for project + user config discovery.
1473
- *
1474
- * Both Skills (`skills/<name>/SKILL.md`) and MCP servers (`mcps.json`)
1475
- * follow the same first-found-wins order:
1476
- *
1477
- * 1. `{project-root}/.agents/<sub>` — project, agnostic convention
1478
- * 2. `{project-root}/.{prefix}/<sub>` — project, zidane (`.zidane` default)
1479
- * 3. `~/.agents/<sub>` — user, agnostic
1480
- * 4. `~/.{prefix}/<sub>` — user, zidane
1481
- *
1482
- * `{project-root}` is the git root walked up from `cwd` when present,
1483
- * else `cwd` itself. This pairs with the project-scoped session
1484
- * storage (`resolveStoragePaths`) so all three project-aware surfaces
1485
- * — sessions, mcps, skills — anchor at the same `.{prefix}/`.
1486
- *
1487
- * Centralizing the pattern keeps the four paths in one place — a third
1488
- * discovery surface (hooks, rules, …) gets the same convention for free
1489
- * and stays in lock-step on a prefix bump.
1490
- */
1491
- /** A discovered path tagged with whether it lives in the project or the user dir. */
1492
- interface ProjectUserPath {
1493
- path: string;
1494
- source: 'project' | 'user';
1495
- }
1496
- /**
1497
- * Resolve the four search paths for a given subdirectory (`skills`,
1498
- * `mcps.json`, …). Returns absolute paths regardless of whether they
1499
- * exist — the caller chooses to `existsSync`-filter or feed straight
1500
- * into a tolerant discovery routine.
1501
- */
1502
- declare function projectUserPaths(opts: {
1503
- /** Subdirectory or filename relative to each search root. E.g. `'skills'`, `'mcps.json'`. */subPath: string; /** Discovery cwd. Default: `process.cwd()`. */
1504
- cwd?: string; /** User home directory. Default: `os.homedir()`. */
1505
- home?: string; /** Storage prefix. Leading dot tolerated. Default: `'.zidane'`. */
1506
- prefix?: string;
1507
- }): ProjectUserPath[];
1508
- //#endregion
1509
- //#region src/chat/plugins-discovery.d.ts
1510
- /** One plugin found on disk, loaded (successfully or not). */
1511
- interface DiscoveredPlugin {
1512
- /**
1513
- * Identity for dedup + the enabled allowlist. The manifest's `name` when
1514
- * the plugin loaded; the directory basename when it didn't, so a rejected
1515
- * plugin still has something stable to key a row and a toggle on.
1516
- */
1517
- name: string;
1518
- /** Load result. Check `ok` before trusting `manifest`. */
1519
- plugin: LoadedPlugin;
1520
- /** Which search root it came from. */
1521
- source: 'project' | 'user';
1522
- /** Plugin root directory, as discovered. */
1523
- path: string;
1524
- }
1525
- /**
1526
- * Load every plugin reachable from the default search roots.
1527
- *
1528
- * Each immediate child directory of a root is one plugin — the same
1529
- * depth-1 rule the spec applies inside `skills/`. A child that isn't a
1530
- * directory, or that holds no `plugin.json`, is silently skipped: dropping a
1531
- * README next to your plugins is not an error.
1532
- *
1533
- * Dedup is by plugin NAME, not directory name, because the manifest owns
1534
- * identity — two directories called `tools/` shipping different plugins are
1535
- * two plugins, and one plugin vendored at two scopes is one plugin.
1536
- */
1537
- declare function discoverProjectPlugins(opts?: {
1538
- cwd?: string;
1539
- home?: string;
1540
- prefix?: string;
1541
- /**
1542
- * Extra scan roots appended AFTER the four defaults — typically from
1543
- * {@link parsePluginScanPathEnv}. Ordered last so a real project or user
1544
- * plugin always wins a name collision against a dev/host-provided root.
1545
- *
1546
- * Scoped `'project'`: they're supplied by whoever launched the process, the
1547
- * same trust level as a plugin sitting in the working tree.
1548
- */
1549
- extraRoots?: readonly string[];
1550
- signal?: AbortSignal;
1551
- }): Promise<{
1552
- plugins: DiscoveredPlugin[];
1553
- errors: DiscoveryError[];
1554
- }>;
1555
- /**
1556
- * Map the user's enabled-plugin list onto the contributions a host merges
1557
- * into the agent.
1558
- *
1559
- * Conventions match `enabledSkills` / `enabledMcps`:
1560
- * - `undefined` → every discovered plugin is enabled (default)
1561
- * - `[]` → all off
1562
- * - `[names]` → allowlist
1563
- *
1564
- * A plugin that failed to load contributes nothing regardless of the
1565
- * allowlist — `ok: false` means components were never discovered.
1566
- */
1567
- declare function buildPluginContributions(opts: {
1568
- discovered: readonly DiscoveredPlugin[];
1569
- enabled?: readonly string[];
1570
- }): {
1571
- skills: SkillConfig[];
1572
- mcpServers: McpServerConfig[];
1573
- };
1574
- //#endregion
1575
- //#region src/chat/enabled-toggle-set.d.ts
1576
- /**
1577
- * Renderer-agnostic state machine for an "enabled allowlist" — the shape
1578
- * used by `settings.enabledSkills` / `settings.enabledMcps` (and any future
1579
- * `enabledX` toggle backed by a `Settings` field).
1580
- *
1581
- * Semantics, kept identical across all three call sites:
1582
- * - `undefined` → every catalog entry is enabled (default — user has
1583
- * never opened the picker; new entries flow in).
1584
- * - `[]` → the whole subsystem is off.
1585
- * - `[names]` → explicit allowlist; the persisted shape stays a
1586
- * concrete array once the user has toggled anything.
1587
- *
1588
- * The hook exposes a live `enabledSet` (Set<string>) + a `toggle(name)`
1589
- * callback that persists the result through `useSettings().setSetting`.
1590
- * The first toggle seeds the persisted allowlist from the current catalog
1591
- * so newly-added entries don't silently drop on the next launch.
1592
- *
1593
- * Renderer-neutral: works for the TUI's `<ToggleListModal>`, a GUI
1594
- * checkbox list, a CLI flag tool. Hook tests live alongside the chat
1595
- * suite; the rendering layer is tested where it lives.
1596
- */
1597
- /** Settings keys whose value type is `readonly string[] | undefined`. */
1598
- type EnabledAllowlistKey = 'enabledSkills' | 'enabledMcps' | 'enabledExtensions' | 'enabledPlugins';
1599
- interface EnabledToggleSet {
1600
- /** Live set of enabled names — `Set` for O(1) `has`. */
1601
- enabledSet: ReadonlySet<string>;
1602
- /** Toggle one name on/off; persists immediately via `setSetting`. */
1603
- toggle: (name: string) => void;
1604
- }
1605
- /**
1606
- * Bind an "enabled allowlist" setting to a discovered catalog.
1607
- *
1608
- * `keyOf` extracts the persisted identity from a catalog entry (skill name,
1609
- * MCP server name, …). Pass a stable, collision-free key — the persisted
1610
- * allowlist is keyed against it forever.
1611
- */
1612
- declare function useEnabledToggleSet<T>(opts: {
1613
- catalog: readonly T[];
1614
- keyOf: (entry: T) => string;
1615
- settingKey: EnabledAllowlistKey;
1616
- /**
1617
- * Names that survive the persisted-allowlist GC even when absent from
1618
- * `catalog`. Use when the catalog deliberately hides entries that are
1619
- * still known to exist — e.g. errored / untrusted extensions are kept
1620
- * out of the toggle list but must not be dropped from the allowlist
1621
- * by an unrelated toggle. Defaults to the catalog keys.
1622
- */
1623
- gcKeys?: readonly string[];
1624
- }): EnabledToggleSet;
1625
- //#endregion
1626
- //#region src/chat/session-export.d.ts
1627
- /** File format supported by the exporter. */
1628
- type SessionExportFormat = 'markdown' | 'json';
1629
- /**
1630
- * Anchor for the resolved destination directory:
1631
- * - `project` — the nearest enclosing git repository (`<repoRoot>/.{prefix}/sessions`)
1632
- * - `home` — fallback when no repo was found (`~/.{prefix}/sessions`)
1633
- */
1634
- type SessionExportAnchor = 'project' | 'home';
1635
- /** Resolved file destination for a session export. */
1636
- interface SessionExportTarget {
1637
- /** Absolute directory holding the file. May not exist yet — `writeSessionExport` creates it on demand. */
1638
- dir: string;
1639
- /** Absolute path of the file (`dir/{id}.{ext}`). */
1640
- filepath: string;
1641
- /** Where the destination was anchored. */
1642
- anchor: SessionExportAnchor;
1643
- }
1644
- /** Options shared by every resolve / write entry-point. */
1645
- interface ResolveOptions {
1646
- /** Discovery cwd. Defaults to `process.cwd()`. */
1647
- cwd?: string;
1648
- /** User home directory. Defaults to `os.homedir()`. */
1649
- home?: string;
1650
- /**
1651
- * Storage prefix. Leading dot tolerated (`zidane` and `.zidane` are
1652
- * equivalent). Defaults to `'.zidane'`.
1653
- */
1654
- prefix?: string;
1655
- }
1656
- /**
1657
- * Resolve the export target for a session id + format. Pure: no fs
1658
- * write happens here, the caller decides whether to `existsSync` the
1659
- * directory or hand the path to `writeSessionExport`.
1660
- *
1661
- * Anchor selection walks upward from `cwd` looking for a `.git` entry;
1662
- * the first hit anchors to that repo's root (`project`). When the walk
1663
- * exits without finding `.git`, the destination anchors to `home`.
1664
- *
1665
- * @throws RangeError when `sessionId` would resolve to an empty / `..`
1666
- * filename — defensive guard against malicious or buggy callers
1667
- * crossing into a sibling directory via the id.
1668
- */
1669
- declare function resolveSessionExportTarget(opts: {
1670
- sessionId: string;
1671
- format: SessionExportFormat;
1672
- } & ResolveOptions): SessionExportTarget;
1673
- /**
1674
- * Render a session into a string in the requested format.
1675
- *
1676
- * `markdown` produces a human-readable transcript: a YAML-free header
1677
- * block with the title and a one-line `id · created · turns` summary,
1678
- * a stats section (turns / runs / tokens / cost / status), then a
1679
- * `## Conversation` block where each turn renders as `### N. role ·
1680
- * run_X · ISO-date` with text, thinking, tool calls, and tool results
1681
- * formatted as appropriate fenced blocks. Useful for sharing a session
1682
- * with a teammate or pasting into an issue tracker.
1683
- *
1684
- * `json` returns a 2-space-indented, deterministic dump of the full
1685
- * `SessionData` blob. Useful for re-importing into the store or for
1686
- * post-hoc analysis tooling.
1687
- */
1688
- declare function renderSession(session: SessionData, format: SessionExportFormat): string;
1689
- /**
1690
- * Render `session` and write the resulting bytes to disk. Returns the
1691
- * resolved target so the caller can show the user where the file
1692
- * landed. The parent directory is created on demand (`recursive: true`)
1693
- * — first-time exports don't need any pre-flight setup.
1694
- */
1695
- declare function writeSessionExport(opts: {
1696
- session: SessionData;
1697
- format: SessionExportFormat;
1698
- } & ResolveOptions): Promise<SessionExportTarget>;
1699
- //#endregion
1700
- //#region src/chat/transcript-anchors.d.ts
1701
- /**
1702
- * One entry in the partitioned transcript-row list. Single events
1703
- * render as a normal row; a `child-run` groups ONE subagent's events
1704
- * from a consecutive run of subagent output into one bordered box
1705
- * (concurrent siblings get a `child-run` each, so their rows never
1706
- * braid together inside a shared frame); `tool-group`s
1707
- * collect ALL parent-owned tool/tool-result events of one exchange
1708
- * into a single collapsible summary row (`Settings.groupToolCalls`);
1709
- * an `exchange-fold` goes further (`Settings.transcriptDensity:
1710
- * 'compact'`) and takes every thinking, tool and worker event of the
1711
- * exchange, leaving only the prompt and the assistant's prose in place.
1712
- * `key` is stable across re-partitions of the same stream (derived
1713
- * from the first grouped event) so expand state survives appends.
1714
- *
1715
- * Currently produced by the TUI's `partitionTranscript`; a GUI shell
1716
- * grouping subagent runs the same way can produce the same shape.
1717
- */
1718
- type TranscriptItem = {
1719
- kind: 'event';
1720
- event: StreamEvent;
1721
- previous?: StreamEvent;
1722
- } | {
1723
- kind: 'child-run';
1724
- events: StreamEvent[];
1725
- previous?: StreamEvent;
1726
- } | {
1727
- kind: 'tool-group';
1728
- key: string;
1729
- events: StreamEvent[];
1730
- previous?: StreamEvent;
1731
- } | {
1732
- kind: 'exchange-fold';
1733
- key: string;
1734
- events: StreamEvent[];
1735
- previous?: StreamEvent;
1736
- };
1737
- /**
1738
- * Per-item anchor ids for auto-scroll. Walks `items` in render order
1739
- * and, for each event, returns either:
1740
- * - `'turn-anchor-<turnId>'` — the first event of this turn (the
1741
- * scroll target).
1742
- * - `undefined` — later event of an already-tagged turn (or a
1743
- * synthetic event with no `turnId`).
1744
- *
1745
- * `ids[i]` is a tuple per item: length 1 for plain events, length N
1746
- * for subagent runs (one entry per inner event). `idByTurn` is the
1747
- * inverse lookup used by the scroll effect. `lastTurnId` is the
1748
- * most-recently-rendered turn — the scroll effect special-cases it to
1749
- * snap to bottom rather than scroll the anchor into view (which would
1750
- * stop short of the actual tail).
1751
- *
1752
- * Exported so the anchor-tagging matrix can be unit-tested without
1753
- * rendering anything.
1754
- */
1755
- declare function computeTurnAnchors(items: readonly TranscriptItem[]): {
1756
- idByTurn: ReadonlyMap<string, string>;
1757
- ids: readonly (readonly (string | undefined)[])[];
1758
- lastTurnId: string | undefined;
1759
- };
1760
- //#endregion
1761
- export { ModelUsageSummary as $, ProviderCredential as A, groupBindings as At, removeStoredCredential as B, Hint as Bt, discoverProjectMcps as C, KeyBindingDef as Ct, OAuthCredential as D, ResolvedExtensionKeybinding as Dt, CredentialsFile as E, ParsedBinding as Et, readCredentials as F, readKeybindings as Ft, writeCredentials as G, setPreferredCredential as H, hintsLength as Ht, readProviderCredential as I, readKeybindingsRaw as It, ProviderRegistry as J, AutoUpdateConfig as K, readProviderCredentialPair as L, resolveExtensionKeybindings as Lt, StoredCredential as M, matchesBinding as Mt, applyApiKeyEnv as N, mergeKeybindings as Nt, PreferCredentialResult as O, ensureKeybindingsFile as Ot, credentialsPath as P, parseBindingSpec as Pt, resolveStoragePaths as Q, readProviderCredentials as R, stripJsonComments as Rt, defaultMcpsConfigPaths as S, KeyAction as St, ApiKeyCredential as T, KeyBindings as Tt, setProviderCredential as U, truncateTrailing as Ut, setCredentialLabel as V, clipHintsToWidth as Vt, storedCredentialsOf as W, ResolvedPaths as X, ResolvedConfig as Y, resolveConfig as Z, DiscoveredMcp as _, usageByModel as _t, SessionExportTarget as a, eventsFromTurns as at, buildMcpServers as b, KEYBINDING_DEF_BY_ACTION as bt, writeSessionExport as c, loadState as ct, useEnabledToggleSet as d, stripSpawnTokensLine as dt, StateStoreApi as et, DiscoveredPlugin as f, sumRunCosts as ft, projectUserPaths as g, updateToolEventOutcomes as gt, ProjectUserPath as h, toolResultText as ht, SessionExportFormat as i, deriveSessionTitle as it, SetProviderCredentialOptions as j, keybindingsPath as jt, PreferredCredentialTarget as k, formatBindingForDisplay as kt, EnabledAllowlistKey as l, marginTopFor as lt, discoverProjectPlugins as m, toolCallPreview as mt, computeTurnAnchors as n, compactSummaryEvent as nt, renderSession as o, lastContextSizeFromTurns as ot, buildPluginContributions as p, titleFromTurns as pt, ChatOptions as q, SessionExportAnchor as r, createStateStore as rt, resolveSessionExportTarget as s, listSessionMeta as st, TranscriptItem as t, TuiState as tt, EnabledToggleSet as u, saveState as ut, DiscoveryError as v, DEFAULT_KEYBINDINGS as vt, parseMcpsFile as w, KeyBindingSection as wt, dedupMcpServersByName as x, KEYBINDING_KEY_COL_WIDTH as xt, DiscoveryResult as y, KEYBINDING_DEFS as yt, removeProviderCredential as z, EMPTY_HINTS as zt };
1762
- //# sourceMappingURL=transcript-anchors-BeudMbXx.d.ts.map