zidane 7.2.4 → 8.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (376) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +34 -6
  3. package/dist/{acp-D-tVyUjw.js → acp-DQDhi2dj.js} +230 -77
  4. package/dist/acp-DQDhi2dj.js.map +1 -0
  5. package/dist/acp-cli.d.ts +1 -1
  6. package/dist/acp-cli.js +9 -66
  7. package/dist/acp-cli.js.map +1 -1
  8. package/dist/acp.d.ts +10 -590
  9. package/dist/acp.d.ts.map +1 -1
  10. package/dist/acp.js +3 -3
  11. package/dist/{agent-D0zZnGbt.js → agent-DSLNmBp0.js} +14401 -13214
  12. package/dist/agent-DSLNmBp0.js.map +1 -0
  13. package/dist/agent.d.ts +1 -1
  14. package/dist/agent.js +3 -2
  15. package/dist/aliasing-lVFbm81n.js +217 -0
  16. package/dist/aliasing-lVFbm81n.js.map +1 -0
  17. package/dist/{anthropic-C2aole0G.js → anthropic-CD00LhUP.js} +1442 -1264
  18. package/dist/anthropic-CD00LhUP.js.map +1 -0
  19. package/dist/artifacts-CV2hUKnL.js.map +1 -1
  20. package/dist/{atomic-write-B7zr1ddF.js → atomic-write-Ijgf2Mhc.js} +13 -3
  21. package/dist/atomic-write-Ijgf2Mhc.js.map +1 -0
  22. package/dist/call-tool-dHlbGOIY.js +70 -0
  23. package/dist/call-tool-dHlbGOIY.js.map +1 -0
  24. package/dist/chat/pure.d.ts +372 -6
  25. package/dist/chat/pure.d.ts.map +1 -1
  26. package/dist/chat/pure.js +35 -244
  27. package/dist/chat/pure.js.map +1 -1
  28. package/dist/{approvals-DKaJZYlm.js → chat-JPJJ8uu5.js} +15879 -14631
  29. package/dist/chat-JPJJ8uu5.js.map +1 -0
  30. package/dist/chat.d.ts +4 -6
  31. package/dist/chat.js +23 -12
  32. package/dist/cli-shared-C-YCaglL.js +159 -0
  33. package/dist/cli-shared-C-YCaglL.js.map +1 -0
  34. package/dist/client-core-BQSyDALT.d.ts +2115 -0
  35. package/dist/client-core-BQSyDALT.d.ts.map +1 -0
  36. package/dist/codemode-worker.d.ts +1 -0
  37. package/dist/codemode-worker.js +155 -0
  38. package/dist/codemode-worker.js.map +1 -0
  39. package/dist/codemode.d.ts +352 -0
  40. package/dist/codemode.d.ts.map +1 -0
  41. package/dist/codemode.js +5 -0
  42. package/dist/connection-Dr-Js4yZ.d.ts +28 -0
  43. package/dist/connection-Dr-Js4yZ.d.ts.map +1 -0
  44. package/dist/connection-loop-gdh22LTI.js +112 -0
  45. package/dist/connection-loop-gdh22LTI.js.map +1 -0
  46. package/dist/context-segments-BHKlagL6.js +1016 -0
  47. package/dist/context-segments-BHKlagL6.js.map +1 -0
  48. package/dist/{context-transport-T_6AYIvy.js → context-transport-DSMTUsK1.js} +3 -3
  49. package/dist/{context-transport-T_6AYIvy.js.map → context-transport-DSMTUsK1.js.map} +1 -1
  50. package/dist/contexts/daytona.d.ts +19 -8
  51. package/dist/contexts/daytona.d.ts.map +1 -1
  52. package/dist/contexts/daytona.js +1 -440
  53. package/dist/contexts/docker.d.ts +36 -7
  54. package/dist/contexts/docker.d.ts.map +1 -1
  55. package/dist/contexts/docker.js +1 -456
  56. package/dist/contexts/e2b.d.ts +68 -13
  57. package/dist/contexts/e2b.d.ts.map +1 -1
  58. package/dist/contexts/e2b.js +1 -382
  59. package/dist/contexts/sandbox.d.ts +1 -1
  60. package/dist/contexts/sandbox.js +5 -0
  61. package/dist/contexts/sandbox.js.map +1 -1
  62. package/dist/{contexts-CRE9pw07.js → contexts-d7UolYot.js} +1059 -524
  63. package/dist/contexts-d7UolYot.js.map +1 -0
  64. package/dist/contexts.d.ts +3 -3
  65. package/dist/contexts.js +1 -1
  66. package/dist/cred-keys-GpBg71cP.js +105 -0
  67. package/dist/cred-keys-GpBg71cP.js.map +1 -0
  68. package/dist/{auth-BG2rVKSt.js → credentials-JttEuRON.js} +55 -206
  69. package/dist/credentials-JttEuRON.js.map +1 -0
  70. package/dist/{cursor-iojRXHF9.js → cursor-CdjaQTBW.js} +3 -3
  71. package/dist/{cursor-iojRXHF9.js.map → cursor-CdjaQTBW.js.map} +1 -1
  72. package/dist/daemon-cli.d.ts +1 -1
  73. package/dist/daemon-cli.js +3 -2
  74. package/dist/daemon-cli.js.map +1 -1
  75. package/dist/daytona-DG3omipZ.js +513 -0
  76. package/dist/daytona-DG3omipZ.js.map +1 -0
  77. package/dist/defaults-Cx3zvDOV.js +23 -0
  78. package/dist/defaults-Cx3zvDOV.js.map +1 -0
  79. package/dist/dispatcher-BMlu2BmZ.js +4941 -0
  80. package/dist/dispatcher-BMlu2BmZ.js.map +1 -0
  81. package/dist/docker-BZhMMJUp.js +727 -0
  82. package/dist/docker-BZhMMJUp.js.map +1 -0
  83. package/dist/e2b-CEVOdRib.js +480 -0
  84. package/dist/e2b-CEVOdRib.js.map +1 -0
  85. package/dist/edit-utils-EGosADZq.js +234 -0
  86. package/dist/edit-utils-EGosADZq.js.map +1 -0
  87. package/dist/environment-8wsKE2Ln.js +214 -0
  88. package/dist/environment-8wsKE2Ln.js.map +1 -0
  89. package/dist/eval-BNcvle_J.js +1595 -0
  90. package/dist/eval-BNcvle_J.js.map +1 -0
  91. package/dist/eval.d.ts +2 -2
  92. package/dist/eval.js +1 -1489
  93. package/dist/executor-Cx5-8yqi.js +621 -0
  94. package/dist/executor-Cx5-8yqi.js.map +1 -0
  95. package/dist/extension-authoring-DyGGmq9V.js +385 -0
  96. package/dist/extension-authoring-DyGGmq9V.js.map +1 -0
  97. package/dist/extensions.d.ts +2 -2
  98. package/dist/extensions.js +3 -3
  99. package/dist/{fetch-url-DX75gpL0.js → fetch-url-Ct2TjDWt.js} +4 -4
  100. package/dist/{fetch-url-DX75gpL0.js.map → fetch-url-Ct2TjDWt.js.map} +1 -1
  101. package/dist/{format-BF745pLL.js → format-C2NQEVUH.js} +39 -2
  102. package/dist/format-C2NQEVUH.js.map +1 -0
  103. package/dist/format-bytes-C7tfc3Zm.js +55 -0
  104. package/dist/format-bytes-C7tfc3Zm.js.map +1 -0
  105. package/dist/headless-C_rNUuYC.js +960 -0
  106. package/dist/headless-C_rNUuYC.js.map +1 -0
  107. package/dist/headless.d.ts +1 -1
  108. package/dist/headless.js +1 -413
  109. package/dist/{history-search-C4bk1Wz_.js → history-search-CcYzF8-0.js} +7 -3
  110. package/dist/history-search-CcYzF8-0.js.map +1 -0
  111. package/dist/history-search-worker.d.ts +1 -1
  112. package/dist/history-search-worker.js +1 -1
  113. package/dist/host-D7NrI03V.js +378 -0
  114. package/dist/host-D7NrI03V.js.map +1 -0
  115. package/dist/host-signals-BcP5QKUD.js +118 -0
  116. package/dist/host-signals-BcP5QKUD.js.map +1 -0
  117. package/dist/identity-CwfO8K-t.js +26 -0
  118. package/dist/identity-CwfO8K-t.js.map +1 -0
  119. package/dist/{index-BgN1T3lk.d.ts → index-BGe1fQT7.d.ts} +10987 -9320
  120. package/dist/index-BGe1fQT7.d.ts.map +1 -0
  121. package/dist/index-BVQsIKGn.d.ts +448 -0
  122. package/dist/index-BVQsIKGn.d.ts.map +1 -0
  123. package/dist/{index-C6NEd5y_.d.ts → index-CHABJd-L.d.ts} +3386 -502
  124. package/dist/index-CHABJd-L.d.ts.map +1 -0
  125. package/dist/{index-C37_ppWv.d.ts → index-D6a7qXpg.d.ts} +2 -3
  126. package/dist/index-D6a7qXpg.d.ts.map +1 -0
  127. package/dist/index.d.ts +6 -6
  128. package/dist/index.js +27 -23
  129. package/dist/{completion-core-BRo86R_L.js → inline-ghost-BVRQeGoL.js} +50 -2
  130. package/dist/inline-ghost-BVRQeGoL.js.map +1 -0
  131. package/dist/ipc/remote.d.ts +313 -0
  132. package/dist/ipc/remote.d.ts.map +1 -0
  133. package/dist/ipc/remote.js +4 -0
  134. package/dist/ipc.d.ts +6 -964
  135. package/dist/ipc.js +403 -4
  136. package/dist/ipc.js.map +1 -0
  137. package/dist/{isolation-Kfoof0MM.d.ts → isolation-D9L650W5.d.ts} +100 -15
  138. package/dist/isolation-D9L650W5.d.ts.map +1 -0
  139. package/dist/json-rpc--HXQti1E.js +350 -0
  140. package/dist/json-rpc--HXQti1E.js.map +1 -0
  141. package/dist/links-j8rED1sR.js +603 -0
  142. package/dist/links-j8rED1sR.js.map +1 -0
  143. package/dist/local-terminal-D8QThwo_.js +252 -0
  144. package/dist/local-terminal-D8QThwo_.js.map +1 -0
  145. package/dist/{logger--C1VQjwJ.js → logger-Gtqlayx8.js} +199 -173
  146. package/dist/logger-Gtqlayx8.js.map +1 -0
  147. package/dist/logs-view-CWG8aUAG.js.map +1 -1
  148. package/dist/{mcp-CgNd-f3F.js → mcp-_wecH9Qe.js} +608 -562
  149. package/dist/mcp-_wecH9Qe.js.map +1 -0
  150. package/dist/mcp.d.ts +2 -2
  151. package/dist/mcp.js +2 -2
  152. package/dist/media-sniff-UKijEaiQ.js.map +1 -1
  153. package/dist/{messages-2jcOA_5R.js → messages-BqiwcD2Q.js} +1017 -1014
  154. package/dist/messages-BqiwcD2Q.js.map +1 -0
  155. package/dist/{oauth-DxHO17JE.js → oauth-Px_pBB9W.js} +5 -5
  156. package/dist/{oauth-DxHO17JE.js.map → oauth-Px_pBB9W.js.map} +1 -1
  157. package/dist/{openai-compat-Dy56weK8.js → openai-compat-CFrpH7uq.js} +432 -589
  158. package/dist/openai-compat-CFrpH7uq.js.map +1 -0
  159. package/dist/orchestration-BCGmB8Ps.js +511 -0
  160. package/dist/orchestration-BCGmB8Ps.js.map +1 -0
  161. package/dist/output/stream-json.d.ts +1 -2
  162. package/dist/output/stream-json.d.ts.map +1 -1
  163. package/dist/output/stream-json.js +1 -1
  164. package/dist/output/terminal.d.ts +1 -2
  165. package/dist/output/terminal.d.ts.map +1 -1
  166. package/dist/output/terminal.js +13 -7
  167. package/dist/output/terminal.js.map +1 -1
  168. package/dist/{plugins-gbI7SBA6.js → plugins-DS7mahzZ.js} +20 -101
  169. package/dist/plugins-DS7mahzZ.js.map +1 -0
  170. package/dist/plugins.d.ts +1 -1
  171. package/dist/plugins.js +1 -2
  172. package/dist/prelude-Cxo4t74B.js +517 -0
  173. package/dist/prelude-Cxo4t74B.js.map +1 -0
  174. package/dist/presets.d.ts +1 -1
  175. package/dist/presets.js +1 -2
  176. package/dist/project-root-B8zADr4o.js +167 -0
  177. package/dist/project-root-B8zADr4o.js.map +1 -0
  178. package/dist/project-user-paths-BSgtrRxl.js +58 -0
  179. package/dist/project-user-paths-BSgtrRxl.js.map +1 -0
  180. package/dist/{prompts-Pqc3JdW_.d.ts → prompts-DYcvqShf.d.ts} +14 -11
  181. package/dist/prompts-DYcvqShf.d.ts.map +1 -0
  182. package/dist/protocol-DnhqqSmE.js +13 -0
  183. package/dist/protocol-DnhqqSmE.js.map +1 -0
  184. package/dist/providers/anthropic.d.ts +2 -2
  185. package/dist/providers/anthropic.js +1 -2
  186. package/dist/providers/arcee.d.ts +1 -1
  187. package/dist/providers/arcee.js +1 -1
  188. package/dist/providers/baseten.d.ts +1 -1
  189. package/dist/providers/baseten.js +1 -1
  190. package/dist/providers/cerebras.d.ts +1 -1
  191. package/dist/providers/cerebras.js +3 -2
  192. package/dist/providers/cerebras.js.map +1 -1
  193. package/dist/providers/local.d.ts +1 -1
  194. package/dist/providers/local.js +1 -1
  195. package/dist/providers/openai-compat.d.ts +1 -1
  196. package/dist/providers/openai-compat.js +1 -2
  197. package/dist/providers/openai.d.ts +1 -1
  198. package/dist/providers/openai.js +15 -12
  199. package/dist/providers/openai.js.map +1 -1
  200. package/dist/providers/openrouter.d.ts +1 -1
  201. package/dist/providers/openrouter.js +3 -2
  202. package/dist/providers/openrouter.js.map +1 -1
  203. package/dist/providers/xai.d.ts +1 -1
  204. package/dist/providers/xai.js +3 -3
  205. package/dist/{providers-BVhnFyiY.js → providers-XUR7F4Hi.js} +4 -4
  206. package/dist/{providers-BVhnFyiY.js.map → providers-XUR7F4Hi.js.map} +1 -1
  207. package/dist/providers.d.ts +1 -1
  208. package/dist/providers.js +4 -4
  209. package/dist/registry-D6ShBWJU.js +5234 -0
  210. package/dist/registry-D6ShBWJU.js.map +1 -0
  211. package/dist/remote-hosts-BtA_9ZGp.js +97 -0
  212. package/dist/remote-hosts-BtA_9ZGp.js.map +1 -0
  213. package/dist/restate.d.ts +2 -3
  214. package/dist/restate.d.ts.map +1 -1
  215. package/dist/restate.js +631 -572
  216. package/dist/restate.js.map +1 -1
  217. package/dist/run-summary-CklLiZ4y.js +288 -0
  218. package/dist/run-summary-CklLiZ4y.js.map +1 -0
  219. package/dist/{sandbox-BH0WQkXn.d.ts → sandbox-C5dR5DwQ.d.ts} +6 -3
  220. package/dist/sandbox-C5dR5DwQ.d.ts.map +1 -0
  221. package/dist/session/sqlite.d.ts +1 -2
  222. package/dist/session/sqlite.d.ts.map +1 -1
  223. package/dist/session/sqlite.js +1 -616
  224. package/dist/session-factory-BUGY5P40.js +1576 -0
  225. package/dist/session-factory-BUGY5P40.js.map +1 -0
  226. package/dist/{session-BqRP1hS7.js → session-xh9JXu6i.js} +94 -52
  227. package/dist/session-xh9JXu6i.js.map +1 -0
  228. package/dist/session.d.ts +1 -1
  229. package/dist/session.js +2 -2
  230. package/dist/settings-keys-Ckf29NeM.js +677 -0
  231. package/dist/settings-keys-Ckf29NeM.js.map +1 -0
  232. package/dist/shell-path-Dqaoow2J.js +412 -0
  233. package/dist/shell-path-Dqaoow2J.js.map +1 -0
  234. package/dist/{skills-BC3dodWp.js → skills-DKqZJm4X.js} +430 -470
  235. package/dist/skills-DKqZJm4X.js.map +1 -0
  236. package/dist/skills.d.ts +2 -2
  237. package/dist/skills.js +1 -2
  238. package/dist/source-mPExaUm8.js +381 -0
  239. package/dist/source-mPExaUm8.js.map +1 -0
  240. package/dist/sqlite-DV1DQzN2.js +698 -0
  241. package/dist/sqlite-DV1DQzN2.js.map +1 -0
  242. package/dist/{src-CkNQKFKr.js → src-BRMYRJib.js} +903 -1121
  243. package/dist/src-BRMYRJib.js.map +1 -0
  244. package/dist/{stdio-DPpBDPx5.js → stdio-C6YyoW3I.js} +4 -4
  245. package/dist/{stdio-DPpBDPx5.js.map → stdio-C6YyoW3I.js.map} +1 -1
  246. package/dist/{stdio-loader-Bbx19dMZ.js → stdio-loader-C830Vg-Z.js} +4 -4
  247. package/dist/{stdio-loader-Bbx19dMZ.js.map → stdio-loader-C830Vg-Z.js.map} +1 -1
  248. package/dist/system-prompt-MNVHatSD.d.ts.map +1 -1
  249. package/dist/timeout-DEaqslLO.d.ts.map +1 -1
  250. package/dist/todo-edits-Dn251YUP.js +1790 -0
  251. package/dist/todo-edits-Dn251YUP.js.map +1 -0
  252. package/dist/{turn-operations-DrbJlpq9.js → tool-formatters-IQFDrdrs.js} +1456 -2120
  253. package/dist/tool-formatters-IQFDrdrs.js.map +1 -0
  254. package/dist/tool-state-Dku6YqAB.js +989 -0
  255. package/dist/tool-state-Dku6YqAB.js.map +1 -0
  256. package/dist/tools/fetch-url.d.ts +1 -2
  257. package/dist/tools/fetch-url.d.ts.map +1 -1
  258. package/dist/tools/fetch-url.js +1 -2
  259. package/dist/tools/prompts.d.ts +1 -1
  260. package/dist/tools/prompts.js +7 -7
  261. package/dist/tools/prompts.js.map +1 -1
  262. package/dist/tools/web-search.d.ts +1 -2
  263. package/dist/tools/web-search.d.ts.map +1 -1
  264. package/dist/tools/web-search.js +2 -2
  265. package/dist/tools/web-search.js.map +1 -1
  266. package/dist/tools-_DnT3AGM.js +578 -0
  267. package/dist/tools-_DnT3AGM.js.map +1 -0
  268. package/dist/tools.d.ts +3 -3
  269. package/dist/tools.js +4 -2
  270. package/dist/tui.d.ts +534 -517
  271. package/dist/tui.d.ts.map +1 -1
  272. package/dist/tui.js +34933 -27242
  273. package/dist/tui.js.map +1 -1
  274. package/dist/turn-operations-B8sokwi5.js +333 -0
  275. package/dist/turn-operations-B8sokwi5.js.map +1 -0
  276. package/dist/turn-operations-DQX5ZZni.d.ts +3089 -0
  277. package/dist/turn-operations-DQX5ZZni.d.ts.map +1 -0
  278. package/dist/types-C7ZFOztE.d.ts +132 -0
  279. package/dist/types-C7ZFOztE.d.ts.map +1 -0
  280. package/dist/types-CH5XpIHw.js +114 -0
  281. package/dist/types-CH5XpIHw.js.map +1 -0
  282. package/dist/{types-CWgENVLY.js → types-Cu0ZGDu9.js} +10 -6
  283. package/dist/types-Cu0ZGDu9.js.map +1 -0
  284. package/dist/types-IqegbJEE.d.ts +624 -0
  285. package/dist/types-IqegbJEE.d.ts.map +1 -0
  286. package/dist/types.d.ts +4 -4
  287. package/dist/types.js +1 -1
  288. package/dist/url-D8HCl65b.js +1259 -0
  289. package/dist/url-D8HCl65b.js.map +1 -0
  290. package/dist/wasm-BVT-j5cl.js +33 -0
  291. package/dist/wasm-BVT-j5cl.js.map +1 -0
  292. package/dist/workspace-exec-stream-SV2R9d5S.js +355 -0
  293. package/dist/workspace-exec-stream-SV2R9d5S.js.map +1 -0
  294. package/dist/ws-CIHMvlSh.js +952 -0
  295. package/dist/ws-CIHMvlSh.js.map +1 -0
  296. package/dist/ws-client-N7NxzvQp.js +230 -0
  297. package/dist/ws-client-N7NxzvQp.js.map +1 -0
  298. package/dist/{xai-CazjStOK.js → xai-CvJTeLrI.js} +165 -5
  299. package/dist/xai-CvJTeLrI.js.map +1 -0
  300. package/dist/xdg-zweed0-t.js +117 -0
  301. package/dist/xdg-zweed0-t.js.map +1 -0
  302. package/docs/ACP.md +52 -0
  303. package/docs/ARCHITECTURE.md +103 -6
  304. package/docs/ARTIFACTS.md +8 -4
  305. package/docs/CHAT.md +165 -14
  306. package/docs/EXECUTION_CONTEXT.md +8 -0
  307. package/docs/EXTENSIONS.md +123 -2
  308. package/docs/HEADLESS.md +2 -0
  309. package/docs/IPC.md +775 -64
  310. package/docs/MACHINES.md +456 -0
  311. package/docs/PANELS.md +3 -0
  312. package/docs/README.md +4 -0
  313. package/docs/RESTATE.md +3 -2
  314. package/docs/RUN_IN_BACKGROUND.md +10 -2
  315. package/docs/SERVER.md +1085 -0
  316. package/docs/SKILL.md +6 -1
  317. package/docs/TERMINAL.md +75 -0
  318. package/docs/TUI.md +65 -14
  319. package/package.json +58 -26
  320. package/scripts/eval.ts +4 -0
  321. package/dist/acp-D-tVyUjw.js.map +0 -1
  322. package/dist/agent-D0zZnGbt.js.map +0 -1
  323. package/dist/anthropic-C2aole0G.js.map +0 -1
  324. package/dist/approvals-DKaJZYlm.js.map +0 -1
  325. package/dist/atomic-write-B7zr1ddF.js.map +0 -1
  326. package/dist/auth-BG2rVKSt.js.map +0 -1
  327. package/dist/completion-core-BRo86R_L.js.map +0 -1
  328. package/dist/contexts/daytona.js.map +0 -1
  329. package/dist/contexts/docker.js.map +0 -1
  330. package/dist/contexts/e2b.js.map +0 -1
  331. package/dist/contexts-CRE9pw07.js.map +0 -1
  332. package/dist/eval.js.map +0 -1
  333. package/dist/format-BF745pLL.js.map +0 -1
  334. package/dist/glob-DluQFSw1.js +0 -270
  335. package/dist/glob-DluQFSw1.js.map +0 -1
  336. package/dist/headless.js.map +0 -1
  337. package/dist/history-search-C4bk1Wz_.js.map +0 -1
  338. package/dist/index-BgN1T3lk.d.ts.map +0 -1
  339. package/dist/index-C37_ppWv.d.ts.map +0 -1
  340. package/dist/index-C6NEd5y_.d.ts.map +0 -1
  341. package/dist/ipc-zVSyo6K1.js +0 -331
  342. package/dist/ipc-zVSyo6K1.js.map +0 -1
  343. package/dist/ipc.d.ts.map +0 -1
  344. package/dist/isolation-Kfoof0MM.d.ts.map +0 -1
  345. package/dist/json-rpc-rSWMUh9b.js +0 -192
  346. package/dist/json-rpc-rSWMUh9b.js.map +0 -1
  347. package/dist/logger--C1VQjwJ.js.map +0 -1
  348. package/dist/mcp-CgNd-f3F.js.map +0 -1
  349. package/dist/messages-2jcOA_5R.js.map +0 -1
  350. package/dist/openai-compat-Dy56weK8.js.map +0 -1
  351. package/dist/output-cap-C9zukcCj.js +0 -100
  352. package/dist/output-cap-C9zukcCj.js.map +0 -1
  353. package/dist/panels-B6gRk4bf.js +0 -789
  354. package/dist/panels-B6gRk4bf.js.map +0 -1
  355. package/dist/plugins-gbI7SBA6.js.map +0 -1
  356. package/dist/prompts-Pqc3JdW_.d.ts.map +0 -1
  357. package/dist/run-summary-BU_NgwUT.js +0 -269
  358. package/dist/run-summary-BU_NgwUT.js.map +0 -1
  359. package/dist/sandbox-BH0WQkXn.d.ts.map +0 -1
  360. package/dist/session/sqlite.js.map +0 -1
  361. package/dist/session-BqRP1hS7.js.map +0 -1
  362. package/dist/shell-path-h5czzllR.js +0 -1549
  363. package/dist/shell-path-h5czzllR.js.map +0 -1
  364. package/dist/skills-BC3dodWp.js.map +0 -1
  365. package/dist/src-CkNQKFKr.js.map +0 -1
  366. package/dist/todo-edits-UOwgxGKu.js +0 -528
  367. package/dist/todo-edits-UOwgxGKu.js.map +0 -1
  368. package/dist/tool-formatters-DoRLnfuD.d.ts +0 -759
  369. package/dist/tool-formatters-DoRLnfuD.d.ts.map +0 -1
  370. package/dist/transcript-anchors-BeudMbXx.d.ts +0 -1762
  371. package/dist/transcript-anchors-BeudMbXx.d.ts.map +0 -1
  372. package/dist/turn-operations-C8bMBDl_.d.ts +0 -1258
  373. package/dist/turn-operations-C8bMBDl_.d.ts.map +0 -1
  374. package/dist/turn-operations-DrbJlpq9.js.map +0 -1
  375. package/dist/types-CWgENVLY.js.map +0 -1
  376. package/dist/xai-CazjStOK.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatcher-BMlu2BmZ.js","names":["NAME_RE","process"],"sources":["../src/ipc/transports/paced-writer.ts","../src/ipc/client.ts","../src/ipc/daemon/environment.ts","../src/ipc/daemon/handlers/params.ts","../src/ipc/daemon/handlers/machine-links.ts","../src/ipc/daemon/handlers/machines.ts","../src/ipc/daemon/handlers/transcript-page.ts","../src/ipc/daemon/handlers/artifacts.ts","../src/ipc/daemon/handlers/auth.ts","../src/ipc/daemon/handlers/browser.ts","../src/ipc/daemon/handlers/catalog-install.ts","../src/ipc/daemon/redact.ts","../src/ipc/daemon/catalog-entries.ts","../src/ipc/daemon/handlers/catalogs.ts","../src/ipc/daemon/handlers/chat.ts","../src/ipc/daemon/handlers/context.ts","../src/ipc/daemon/handlers/daemon.ts","../src/ipc/daemon/handlers/drafts.ts","../src/ipc/daemon/handlers/sessions.ts","../src/ipc/daemon/handlers/environments.ts","../src/ipc/daemon/handlers/extensions.ts","../src/ipc/daemon/handlers/fs.ts","../src/ipc/daemon/handlers/history.ts","../src/ipc/daemon/handlers/hitl.ts","../src/ipc/daemon/handlers/launch-overrides.ts","../src/ipc/daemon/handlers/machine-serve.ts","../src/ipc/daemon/handlers/oauth-flows.ts","../src/ipc/daemon/handlers/orchestration.ts","../src/ipc/daemon/handlers/presence.ts","../src/ipc/daemon/handlers/queue.ts","../src/ipc/daemon/handlers/resume.ts","../src/ipc/daemon/handlers/session-reads.ts","../src/ipc/daemon/handlers/settings.ts","../src/ipc/daemon/handlers/suggest.ts","../src/ipc/daemon/sync-apply.ts","../src/ipc/daemon/sync-store.ts","../src/ipc/daemon/handlers/sync.ts","../src/ipc/daemon/handlers/terminal.ts","../src/ipc/daemon/handlers/titles.ts","../src/ipc/daemon/handlers/todos.ts","../src/ipc/daemon/handlers/transcript.ts","../src/ipc/daemon/handlers/transcript-cache.ts","../src/ipc/daemon/handlers/workspace.ts","../src/ipc/daemon/handlers/workspace-exec-stream.ts","../src/ipc/daemon/handshake.ts","../src/ipc/daemon/identity.ts","../src/ipc/daemon/peers.ts","../src/ipc/daemon/signal-log.ts","../src/ipc/daemon/workspace-roots.ts","../src/ipc/daemon/dispatcher.ts"],"sourcesContent":["/**\n * Writes to a socket with backpressure: slices go out while the socket takes\n * them (`write` returns true), the rest waits for `drain`. Messages keep\n * their order, and `buffered` counts what is queued here plus what the\n * socket still holds, so a send budget measuring it sees the whole backlog.\n *\n * Handing a socket one large buffer at once is what this avoids: Bun's\n * `node:net` re-copies the unsent remainder after each partial write, so a\n * 100 MB reply took ~12 s to cross a unix socket, against ~70 ms when paced\n * (Node is fast either way).\n */\nimport type { Writable } from 'node:stream'\nimport { Buffer } from 'node:buffer'\n\n/** Largest slice handed to the socket at once. */\nconst SLICE_BYTES = 64 * 1024\n\nexport interface PacedWriter {\n write: (text: string) => void\n /** Bytes not yet handed to the OS: queued here, plus the socket's own buffer. */\n buffered: () => number\n}\n\nexport function createPacedWriter(stream: Writable): PacedWriter {\n const queue: Buffer[] = []\n let queuedBytes = 0\n let waiting = false\n\n const pump = (): void => {\n waiting = false\n while (queue.length > 0) {\n if (stream.destroyed || stream.writableEnded) {\n queue.length = 0\n queuedBytes = 0\n return\n }\n const head = queue[0]!\n const slice = head.length > SLICE_BYTES ? head.subarray(0, SLICE_BYTES) : head\n if (slice === head)\n queue.shift()\n else\n queue[0] = head.subarray(SLICE_BYTES)\n queuedBytes -= slice.length\n if (!stream.write(slice)) {\n waiting = true\n stream.once('drain', pump)\n return\n }\n }\n }\n\n return {\n write(text) {\n const bytes = Buffer.from(text)\n queue.push(bytes)\n queuedBytes += bytes.length\n if (!waiting)\n pump()\n },\n buffered: () => queuedBytes + stream.writableLength,\n }\n}\n","/**\n * Typed daemon client — the only thing a zidane window (TUI, attach CLI,\n * future GUI-proxy mode) needs to talk to a shared chat host.\n *\n * `request` is checked against the `IpcMethods` contract, `onSignal`\n * delivers every `HostSignal` fan-out, and `connectIpcClient` handles the\n * handshake including the protocol-version dance: a mismatched daemon is\n * asked to drain (`daemon.shutdown`) so the caller can respawn a fresh one.\n * The transport-independent half (handshake, deadlines, signals) is shared\n * with the WebSocket client in `./transports/client-core`.\n */\nimport type { Socket } from 'node:net'\nimport type { EnsureDaemonOptions } from './daemon/lifecycle'\nimport type { IpcClient } from './transports/client-core'\nimport { connect } from 'node:net'\nimport { createJsonRpcConnection, errorResponse } from '../acp/json-rpc'\nimport { METHOD_NOT_FOUND } from '../chat/hosts/connection'\nimport { ensureDaemonRunning, probeSocket } from './daemon/lifecycle'\nimport { createSignalListeners, IpcVersionMismatchError, openIpcClient } from './transports/client-core'\nimport { createPacedWriter } from './transports/paced-writer'\n\nexport { type IpcClient, IpcVersionMismatchError } from './transports/client-core'\n\nexport interface IpcClientOptions {\n socketPath: string\n /** Client zidane version, surfaced in daemon diagnostics. */\n appVersion?: string\n /** Called when the daemon connection drops (socket close/error). */\n onClose?: () => void\n /**\n * On a version/build mismatch, ask the stale daemon to drain before\n * throwing (default). PASSIVE clients (the presence watcher) must set\n * this false: they retry on a timer, and an old-build window left open\n * across a protocol bump would otherwise drain the NEW daemon in a\n * loop, aborting every other window's runs.\n */\n drainOnMismatch?: boolean\n}\n\nexport async function connectIpcClient(options: IpcClientOptions): Promise<IpcClient> {\n const socket: Socket = await new Promise((resolvePromise, reject) => {\n const s = connect(options.socketPath)\n s.once('connect', () => {\n s.off('error', reject)\n resolvePromise(s)\n })\n s.once('error', reject)\n })\n\n const signals = createSignalListeners()\n let closed = false\n\n // A large request (turns with images) goes out paced, as the daemon's replies do.\n const writer = createPacedWriter(socket)\n const connection = createJsonRpcConnection({\n input: socket,\n output: socket,\n send: json => writer.write(`${json}\\n`),\n // The daemon never sends requests to clients — only notifications.\n onRequest: message => errorResponse(message.id, METHOD_NOT_FOUND, 'Clients do not accept requests.'),\n onNotification: signals.onNotification,\n })\n connection.start()\n\n const close = (): void => {\n if (closed)\n return\n closed = true\n connection.close()\n socket.destroy()\n }\n\n socket.on('close', () => {\n if (closed)\n return\n closed = true\n connection.close()\n options.onClose?.()\n })\n socket.on('error', () => {\n // 'close' follows; swallow so an unhandled 'error' doesn't crash us.\n })\n\n const passive = options.drainOnMismatch === false\n return openIpcClient(\n // `abort` destroys the socket (not `close()`), so its 'close' handler fires `onClose`.\n { rpc: connection, close, abort: () => socket.destroy(), where: options.socketPath },\n signals.listeners,\n {\n ...(options.appVersion ? { appVersion: options.appVersion } : {}),\n drain: passive ? 'stale-only' : 'always',\n buildFence: !passive,\n },\n )\n}\n\n/**\n * One-call convenience for windows: make sure a daemon is up (spawning if\n * needed), connect, and — when the running daemon speaks an older protocol\n * — drain it and spawn a fresh one before retrying once.\n */\nexport async function connectOrSpawnDaemon(\n options: Omit<IpcClientOptions, 'socketPath'> & EnsureDaemonOptions = {},\n): Promise<IpcClient> {\n const socketPath = await ensureDaemonRunning(options)\n try {\n return await connectIpcClient({ ...options, socketPath })\n }\n catch (err) {\n if (!(err instanceof IpcVersionMismatchError))\n throw err\n /*\n * The stale daemon was told to drain by `connectIpcClient`, but\n * `daemon.shutdown` replies BEFORE the socket actually closes (the\n * drain runs on `setImmediate`). Poll until the socket stops\n * accepting connections (bounded) before respawning, so\n * `ensureDaemonRunning` doesn't re-probe the still-listening stale\n * daemon and hit a second mismatch.\n */\n const drainDeadline = Date.now() + 2000\n while (await probeSocket(socketPath)) {\n if (Date.now() > drainDeadline)\n break\n await new Promise(r => setTimeout(r, 100))\n }\n const retryPath = await ensureDaemonRunning(options)\n return connectIpcClient({ ...options, socketPath: retryPath })\n }\n}\n","import type { ChatHostEnvironment, PendingApprovalsStore } from '../../chat/host/environment'\n/**\n * Disk-backed `ChatHostEnvironment` for the zidane daemon.\n *\n * Mirrors the TUI's storage layout so the daemon is a drop-in peer of the\n * terminal process: sessions in `sessions.db` (canonical sqlite store),\n * settings in `state.json`'s `settings` slot, credentials/safelist under the\n * shared user dir, extensions discovered per-cwd with the same allowlist +\n * trust contract every other surface uses.\n */\nimport type { ResolvedConfig } from '../../chat/index'\nimport type { ExtensionBus, ExtensionHostRuntimeBridge } from '../../extensions/index'\nimport type { SessionStore } from '../../session/index'\nimport type { HostSettings, HostSignal, WireApprovalRequest } from '../protocol'\nimport { existsSync, readFileSync, unlinkSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { OWNER_ONLY, writeJsonFileAtomic } from '../../atomic-write'\nimport { createMemoryApprovalsStore } from '../../chat/host/approvals'\nimport { applyApiKeyEnv, BUILTIN_PROVIDERS, createExtensionMcpHost, createFileMcpCredentialStore, credentialsPath, DEFAULT_SETTINGS, enforceSettingsInvariants, resolveConfig, SETTINGS_TOGGLES } from '../../chat/index'\nimport { createExtensionBus, createExtensionHostRuntimeBridge, createExtensionHud, discoverAndBuildExtensionRegistry } from '../../extensions/index'\n\nexport interface DaemonEnvironment extends ChatHostEnvironment {\n writeSettings: (patch: Partial<HostSettings>) => HostSettings\n /** Drop the per-cwd runtime-config memo (settings changed) and dispose the registries it held. */\n invalidateRuntime: () => void\n /**\n * Drop the memo WITHOUT disposing: the next `runtimeConfig` builds fresh\n * registries while agents still running on the old ones keep working.\n * Returns the disposer for what was dropped; call it once no agent\n * holds those registries (`runtime.reload` after every session rebuilt).\n */\n forgetRuntime: () => () => void\n /** Base config resolved at daemon boot (paths, store, state). */\n config: ResolvedConfig\n /**\n * Shared extension bus for daemon-side registries (`ctx.bus`). The\n * server delivers validated `extension.emit` notifications into it;\n * daemon-side emits leave through its `onEmit` → `broadcast`. Optional:\n * test environments without extensions omit it.\n */\n extensionBus?: ExtensionBus\n}\n\n/**\n * File-backed pending-approvals persistence (`pending-approvals.json` next\n * to `state.json`). Small, rewritten atomically enough for its purpose —\n * the queue holds at most a handful of rows.\n */\nexport function createFileApprovalsStore(path: string): PendingApprovalsStore {\n function read(): WireApprovalRequest[] {\n if (!existsSync(path))\n return []\n try {\n const parsed = JSON.parse(readFileSync(path, 'utf8'))\n return Array.isArray(parsed) ? (parsed as WireApprovalRequest[]) : []\n }\n catch {\n return []\n }\n }\n\n function write(rows: WireApprovalRequest[]): void {\n if (rows.length === 0) {\n try {\n unlinkSync(path)\n }\n catch {\n // absent already — fine\n }\n return\n }\n // Atomic: this file exists to survive a crash — a torn write would\n // corrupt the very queue we're persisting to recover. Owner-only: rows\n // carry tool inputs (commands, file contents).\n writeJsonFileAtomic(path, rows, OWNER_ONLY)\n }\n\n return {\n insert(request) {\n const rows = read().filter(r => r.id !== request.id)\n rows.push(request)\n write(rows)\n },\n delete(id) {\n write(read().filter(r => r.id !== id))\n },\n clear() {\n write([])\n },\n list() {\n return read()\n },\n }\n}\n\nexport interface HostEnvironmentOptions {\n broadcast: (signal: HostSignal) => void\n debugStream?: boolean\n /** Daemon only: base cwd for its own boot-time config resolution. Default: `process.cwd()`. */\n cwd?: string\n /**\n * Share the embedding window's setup instead of resolving the daemon's\n * own: a host in the window's process. Absent: the daemon (own config,\n * per-cwd extension discovery, multi-process).\n */\n shared?: SharedHostSetup\n}\n\n/** What a host in the window's own process takes from the window. */\nexport interface SharedHostSetup {\n /**\n * The window's boot config (paths, store, state file): one store and one\n * writer to `state.json` in the process.\n */\n config: ResolvedConfig\n /**\n * The window's per-cwd session config. Discovering extensions here instead\n * would run every extension's `setup` a second time in the same process.\n * `invalidate` / `forget` back `DaemonEnvironment.invalidateRuntime` /\n * `forgetRuntime` (settings changes, `runtime.reload`).\n */\n runtimeConfig: {\n resolve: (cwd: string) => Promise<ResolvedConfig>\n invalidate?: () => void\n forget?: () => () => void\n }\n /** Host-runtime bridge the window's registries were built with (`ChatHostEnvironment.hostRuntime`). */\n hostRuntime?: ExtensionHostRuntimeBridge\n /** The window's extension bus, so `extension.emit` from other clients reaches its extensions. */\n extensionBus?: ExtensionBus\n /** Whether another process also drives these sessions. Default `false` (single writer). */\n multiProcess?: boolean\n /** The window's instrumentation for every agent the host builds (`ChatHostEnvironment.instrumentAgent`). */\n instrumentAgent?: ChatHostEnvironment['instrumentAgent']\n /** Whether the window can show terminals (`ChatHostEnvironment.terminals`). */\n terminals?: boolean\n}\n\n/** The daemon's environment: its own config, per-cwd extension discovery, multi-process. */\nexport function createDaemonEnvironment(options: Omit<HostEnvironmentOptions, 'shared'>): Promise<DaemonEnvironment> {\n return createHostEnvironment(options)\n}\n\n/**\n * Disk-backed host environment: the daemon's, or (with `shared`) a host\n * sharing the window's process and setup.\n */\nexport async function createHostEnvironment(options: HostEnvironmentOptions): Promise<DaemonEnvironment> {\n const { shared } = options\n const config = shared?.config ?? await resolveOwnConfig(options.cwd)\n const store: SessionStore = config.store\n\n /*\n * Project-DB mode resolves storage to a PER-REPO `.zidane/sessions.db`\n * from the boot cwd. A single daemon serving windows opened in different\n * projects would then read/write every session against ONE project's DB.\n * The daemon is a single-store process, so warn loudly rather than\n * silently mixing projects; a project-scoped daemon (own socket) is the\n * supported way to use project-DB mode with the daemon.\n */\n if (!shared && config.paths.projectDir) {\n process.stderr.write(\n `[zidane-daemon] warning: project-DB mode is on, so this daemon uses ${config.paths.db}. `\n + `Windows opened in other projects will share this project's sessions. `\n + `Run a per-project daemon (ZIDANE_DAEMON_SOCKET) to isolate them.\\n`,\n )\n }\n\n /*\n * `config.initialSettings` is `resolveConfig`'s migrated snapshot of the\n * on-disk settings (it ran `migrateLegacySettings`, which is private to\n * `config.ts`). Layering it under the live raw read means a user with\n * legacy-shaped settings gets the SAME effective settings in the daemon\n * as in the TUI, while mid-session writes (live `stateStore`) still win.\n */\n const readSettings = (): HostSettings => ({\n ...DEFAULT_SETTINGS,\n ...config.initialSettings,\n ...(config.stateStore.load().settings ?? {}),\n })\n\n /**\n * Fields the invariant forced (only ever `false`), so the stored file records\n * them too — otherwise a later read of `state.settings` would resurrect the\n * value the invariant just rejected.\n */\n const pickInvariantFields = (merged: HostSettings, patch: Partial<HostSettings>): Partial<HostSettings> => {\n const out: Partial<HostSettings> = {}\n for (const row of SETTINGS_TOGGLES) {\n if (row.requires && merged[row.key] === false && patch[row.key] !== false)\n out[row.key] = false\n }\n return out\n }\n\n const writeSettings = (patch: Partial<HostSettings>): HostSettings => {\n /*\n * Read-modify-write of the whole `state.json`, synchronous, through the\n * state store. A host in the window's process shares the window's store\n * (`config`), so the two writers interleave whole writes and each keeps\n * the other's fields. Across processes (the daemon and a local-mode\n * window on the same file) nothing locks; in daemon mode the window\n * leaves settings to the daemon and persists only its window-local\n * keys (`WINDOW_LOCAL_SETTINGS`: `useDaemon`, `remoteHosts`).\n */\n const state = config.stateStore.load()\n // Same invariants every writer applies (`orchestration` needs `useDaemon`,\n // …) — enforced on the MERGED view, since a patch can flip a requirement\n // off while the dependent stays true in the stored fields.\n const merged = enforceSettingsInvariants({ ...DEFAULT_SETTINGS, ...config.initialSettings, ...(state.settings ?? {}), ...patch })\n const next = { ...(state.settings ?? {}), ...patch, ...pickInvariantFields(merged, patch) }\n config.stateStore.save({ ...state, settings: next })\n return merged\n }\n\n const userDataDir = (): string => config.paths.userDir\n\n const applyAuthEnv = (): void => {\n const dir = userDataDir()\n process.env.ZIDANE_CREDENTIALS_PATH = credentialsPath(dir)\n // The window's own registry when sharing its config (custom providers);\n // the daemon keeps the built-ins it has always used.\n applyApiKeyEnv(dir, shared ? config.providers : BUILTIN_PROVIDERS)\n }\n\n const base = {\n // The daemon serves explicitly-invoked clients (`zidane attach`)\n // even when `useDaemon` is off: a multi-writer surface by\n // construction, so the run guard + heartbeat are not setting-gated.\n // A shared host is single-writer unless told otherwise.\n multiProcess: shared ? shared.multiProcess === true : true,\n broadcast: options.broadcast,\n store,\n readSettings,\n writeSettings,\n userDataDir,\n applyAuthEnv,\n mcpCredentialStore: () => createFileMcpCredentialStore(userDataDir()),\n /*\n * The daemon persists parked approvals so a restart can re-offer them. A\n * host in the window's process dies with its runs, so it keeps them in\n * memory: the file is the daemon's (same state dir), not its to load or\n * clear.\n */\n approvalsPersistence: shared\n ? createMemoryApprovalsStore()\n : createFileApprovalsStore(join(dirname(config.paths.state), 'pending-approvals.json')),\n ...(options.debugStream !== undefined ? { debugStream: options.debugStream } : {}),\n config,\n }\n\n // The window's per-cwd config: no discovery, HUD or bus of our own;\n // the window's registries own those.\n if (shared) {\n const { resolve, invalidate, forget } = shared.runtimeConfig\n return {\n ...base,\n // Session artifacts where the window's local agent kept them.\n cacheDir: () => config.paths.cacheDir,\n runtimeConfig: resolve,\n ...(shared.hostRuntime ? { hostRuntime: shared.hostRuntime } : {}),\n ...(shared.extensionBus ? { extensionBus: shared.extensionBus } : {}),\n ...(shared.instrumentAgent ? { instrumentAgent: shared.instrumentAgent } : {}),\n ...(shared.terminals !== undefined ? { terminals: shared.terminals } : {}),\n invalidateRuntime: () => invalidate?.(),\n // Same contract as the daemon's: drop now, dispose when the returned\n // disposer runs (once no agent holds the old registries).\n forgetRuntime: () => forget?.() ?? (() => undefined),\n }\n }\n\n /*\n * Per-(cwd + allowlist + trust) runtime-config memo — same invalidation\n * axes the GUI's extension registry cache uses. Dropped wholesale on\n * settings writes that touch extension keys (see the server's\n * `settings.set` handler calling `invalidate`).\n */\n /*\n * Daemon-side extension HUD: extension hooks run HERE in daemon mode, so\n * their `ctx.tui` writes need a live bus (headless hosts otherwise no-op\n * them). Every change is forwarded to the windows as `hud:state` /\n * `hud:notify` signals; the TUI overlays them under its local HUD.\n */\n const hud = createExtensionHud()\n hud.subscribe(() => {\n const state = hud.getState()\n options.broadcast({\n kind: 'hud:state',\n statuses: Object.fromEntries(\n Object.entries(state.statuses).map(([name, s]) => [name, { text: s.text, loader: s.loader }]),\n ),\n banners: Object.fromEntries(\n Object.entries(state.banners).map(([name, lines]) => [name, [...lines]]),\n ),\n })\n })\n hud.onNotify((n) => {\n options.broadcast({ kind: 'hud:notify', extension: n.extension, text: n.text, tone: n.tone })\n })\n\n /*\n * Daemon-side extension bus: one bus shared by every per-cwd registry\n * (channels are private per extension id, so sharing is safe — and it\n * lets the server deliver a validated `extension.emit` no matter which\n * cwd's registry claimed the id). Emits from daemon-side extensions\n * already delivered loopback inside the bus; the hook fans the envelope\n * out to every window as `extension:signal`.\n */\n const extensionBus = createExtensionBus()\n extensionBus.onEmit((envelope) => {\n options.broadcast({ kind: 'extension:signal', ...envelope })\n })\n\n /*\n * LRU-bounded: a service-style daemon (`--idle-exit 0`) serving many\n * project folders would otherwise accumulate a full ResolvedConfig +\n * extension registry per (cwd × allowlist) key forever — this was the\n * last unbounded collection in the daemon. Map iteration order is\n * insertion order; a cache hit re-inserts to mark recency.\n */\n const RUNTIME_CACHE_MAX = 16\n const runtimeCache = new Map<string, Promise<ResolvedConfig>>()\n\n // One bridge for every registry this daemon builds; the engine scopes the\n // invoking session onto it per command (see `ChatHostEnvironment.hostRuntime`).\n const hostRuntime = createExtensionHostRuntimeBridge()\n\n // `ctx.mcp` (`'mcp:call'` permission): one connection pool for every per-cwd registry.\n const mcpHost = createExtensionMcpHost({\n prefix: config.prefix,\n readSettings,\n credentialStore: () => createFileMcpCredentialStore(userDataDir()),\n })\n\n /**\n * Best-effort release of an evicted entry's extension registry\n * (teardown hooks, HUD writers — `registry.dispose()` is idempotent).\n * Fire-and-forget: eviction must never block or throw on a broken\n * extension teardown, and a rejected resolve has nothing to release.\n */\n const disposeRuntime = (promise: Promise<ResolvedConfig>): void => {\n void promise\n .then(config => config.extensions.dispose())\n .catch(() => undefined)\n }\n\n const runtimeConfig = (cwd: string): Promise<ResolvedConfig> => {\n const settings = readSettings()\n const key = [\n cwd,\n JSON.stringify(settings.enabledExtensions ?? null),\n String(settings.loadProjectExtensions === true),\n ].join('\\u0000')\n\n const existing = runtimeCache.get(key)\n if (existing) {\n // Refresh recency.\n runtimeCache.delete(key)\n runtimeCache.set(key, existing)\n return existing\n }\n\n const promise = (async () => {\n const extensionRegistry = await discoverAndBuildExtensionRegistry({\n cwd,\n hud,\n bus: extensionBus,\n hostRuntime,\n mcp: mcpHost,\n prefix: config.prefix,\n ...(settings.enabledExtensions !== undefined ? { enabledAllowlist: [...settings.enabledExtensions] } : {}),\n trustProjectExtensions: settings.loadProjectExtensions === true,\n readSettings,\n })\n return resolveConfig({\n cwd,\n extensionRegistry,\n store: () => store,\n })\n })()\n\n runtimeCache.set(key, promise)\n while (runtimeCache.size > RUNTIME_CACHE_MAX) {\n const oldest = runtimeCache.keys().next().value\n if (oldest === undefined)\n break\n const evicted = runtimeCache.get(oldest)\n runtimeCache.delete(oldest)\n if (evicted)\n disposeRuntime(evicted)\n }\n promise.catch(() => {\n if (runtimeCache.get(key) === promise)\n runtimeCache.delete(key)\n })\n return promise\n }\n\n return {\n ...base,\n runtimeConfig,\n hostRuntime,\n invalidateRuntime: () => {\n for (const entry of runtimeCache.values())\n disposeRuntime(entry)\n runtimeCache.clear()\n },\n forgetRuntime: () => {\n const dropped = [...runtimeCache.values()]\n runtimeCache.clear()\n return () => {\n for (const entry of dropped)\n disposeRuntime(entry)\n }\n },\n extensionBus,\n }\n}\n\n/** The daemon's own boot config: paths + store + state, from `cwd`. */\nasync function resolveOwnConfig(cwd: string | undefined): Promise<ResolvedConfig> {\n /*\n * `bun:sqlite` is loaded LAZILY so `zidane/ipc` stays importable under\n * plain Node (the Electron GUI main process imports this barrel for\n * `createChatHost`; the sqlite chunk must never be evaluated there).\n * Same invariant the tsdown config maintains for `zidane/session/sqlite`.\n */\n const { createTuiStore } = await import('../../session/sqlite')\n /*\n * Session-facing runtime config is re-resolved per cwd (project\n * extensions differ per folder); this one only carries paths, store, state.\n */\n return resolveConfig({\n ...(cwd !== undefined ? { cwd } : {}),\n store: resolved => createTuiStore(resolved.db),\n })\n}\n","/**\n * Shape checks for request params: they arrive as untrusted JSON (the\n * `IpcMethods` types are not a runtime guarantee). The dispatcher runs\n * {@link checkParams} on every request and notification before its handler;\n * handlers use the field checks for what they require. A failed check is an\n * {@link InvalidParamsError}, answered as JSON-RPC \"invalid params\".\n */\n\nexport class InvalidParamsError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'InvalidParamsError'\n }\n}\n\n/** Longest session id accepted (minted ids are under 64 characters). */\nconst MAX_SESSION_ID_LENGTH = 1024\n\n/**\n * A session id: a non-empty string that is one plain path segment. Ids name\n * directories on disk (`<data dir>/sessions/<id>/`, removed recursively on\n * delete), so `..`, separators and NUL are refused.\n */\nexport function checkSessionId(value: unknown, name = 'sessionId'): string {\n if (typeof value !== 'string' || value.length === 0 || value.length > MAX_SESSION_ID_LENGTH)\n throw new InvalidParamsError(`${name} must be a non-empty string of at most ${MAX_SESSION_ID_LENGTH} characters.`)\n if (value === '.' || value === '..' || /[/\\\\\\0]/.test(value))\n throw new InvalidParamsError(`${name} must not be a path (no \"/\", \"\\\\\", \".\" or \"..\").`)\n return value\n}\n\n/** The required `sessionId` of `params`. */\nexport function sessionIdOf(params: { sessionId?: unknown } | null | undefined): string {\n return checkSessionId(params?.sessionId)\n}\n\n/** An optional non-negative integer; `undefined` when absent. */\nexport function nonNegativeInt(value: unknown, name: string): number | undefined {\n if (value === undefined)\n return undefined\n if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < 0)\n throw new InvalidParamsError(`${name} must be a non-negative integer.`)\n return value\n}\n\n/** An optional string; `undefined` when absent. */\nexport function optionalString(value: unknown, name: string): string | undefined {\n if (value !== undefined && typeof value !== 'string')\n throw new InvalidParamsError(`${name} must be a string.`)\n return value\n}\n\n/**\n * What every method's params must be: absent, `null`, or an object (never an\n * array or a scalar), whose `sessionId` / `sessionIds`, when present, name\n * sessions ({@link checkSessionId}).\n */\nexport function checkParams(params: unknown): void {\n if (params === undefined || params === null)\n return\n if (typeof params !== 'object' || Array.isArray(params))\n throw new InvalidParamsError('params must be an object.')\n const { sessionId, sessionIds } = params as { sessionId?: unknown, sessionIds?: unknown }\n if (sessionId !== undefined)\n checkSessionId(sessionId)\n if (sessionIds !== undefined) {\n if (!Array.isArray(sessionIds))\n throw new InvalidParamsError('sessionIds must be an array.')\n for (const id of sessionIds)\n checkSessionId(id, 'sessionIds[]')\n }\n}\n","/**\n * A local host's machine links for its clients (`machines.share.*`,\n * `machines.useServer`, `machines.links.status`; `docs/MACHINES.md` § Client\n * UI). Opt-in down to the module graph: the controller (`../../machine/links`,\n * which dials servers) is imported only while remote hosts are on, so with\n * the setting off nothing is loaded, no token read, nothing dialed. Turning\n * remote hosts off stops every link (the wanted links stay saved).\n */\nimport type { ChatHost } from '../../../chat/host/engine'\nimport type { MachineLinksStatus } from '../../../chat/machine-protocol'\nimport type { MachineLinks } from '../../machine/links'\nimport type { HostSignal } from '../../protocol'\nimport type { DaemonEnvironment } from '../environment'\nimport type { Handlers } from './types'\nimport { existsSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { remoteHostsGate } from '../../../chat/feature-gate'\nimport { InvalidParamsError } from './params'\n\nconst GATE_POLL_MS = 2000\nconst EMPTY: MachineLinksStatus = { shares: [], uses: [] }\n\nexport interface MachineLinksHandlerOptions {\n host: ChatHost\n env: Pick<DaemonEnvironment, 'readSettings' | 'userDataDir'>\n broadcast: (signal: HostSignal) => void\n hostId: string | undefined\n /** A zidane-server: it has no links (a server is shared from, never shares from here); every method is refused. */\n server?: boolean\n appVersion: string\n /** Connection pacing for the links (tests shrink it). */\n pacing?: { minDelayMs?: number, maxDelayMs?: number, heartbeatMs?: number, pollMs?: number }\n}\n\ntype Methods = 'machines.share.start' | 'machines.share.stop' | 'machines.useServer' | 'machines.links.status'\n\n/** A server's: no links, nothing loaded or resumed. */\nfunction serverLinkHandlers(): Handlers<Methods> {\n const refuse = (): never => {\n throw new Error('A zidane-server has no machine links: share a computer with it from that computer (zidane machine share, or its Hosts page).')\n }\n return { 'machines.share.start': refuse, 'machines.share.stop': refuse, 'machines.useServer': refuse, 'machines.links.status': refuse }\n}\n\nexport function createMachineLinkHandlers(options: MachineLinksHandlerOptions): Handlers<Methods> {\n if (options.server)\n return serverLinkHandlers()\n const { host, env, broadcast } = options\n let links: Promise<MachineLinks> | undefined\n let gateTimer: ReturnType<typeof setInterval> | undefined\n\n const gateOn = (): boolean => remoteHostsGate.isEnabled(env.readSettings())\n\n const stop = (): void => {\n const current = links\n links = undefined\n clearInterval(gateTimer)\n gateTimer = undefined\n void current?.then(l => l.close()).catch(() => undefined)\n broadcast({ kind: 'machine:links', links: EMPTY })\n }\n\n const load = (): Promise<MachineLinks> => {\n links ??= import('../../machine/links').then(({ startMachineLinks }) => startMachineLinks({\n dataDir: env.userDataDir(),\n machines: host.machines,\n hostId: options.hostId,\n appVersion: options.appVersion,\n settings: () => env.readSettings(),\n onChange: status => broadcast({ kind: 'machine:links', links: status }),\n ...options.pacing,\n }))\n // Remote hosts turned off (here or in another window): every link stops.\n gateTimer ??= setInterval(() => {\n if (!gateOn())\n stop()\n }, options.pacing?.pollMs ?? GATE_POLL_MS)\n gateTimer.unref?.()\n return links\n }\n\n const required = (): Promise<MachineLinks> => {\n if (!gateOn())\n throw new Error(`Remote hosts are off${remoteHostsGate.isKilled() ? ` (${remoteHostsGate.killSwitchEnv}=1)` : ''}: machines are part of them.`)\n return load()\n }\n\n const str = (value: unknown, name: string): string => {\n if (typeof value !== 'string' || value === '')\n throw new InvalidParamsError(`\"${name}\" must be a non-empty string.`)\n return value\n }\n\n // Links saved by an earlier run resume with the host, only while remote hosts are on.\n if (gateOn() && existsSync(join(env.userDataDir(), 'machine-links.json')))\n void load().catch(() => undefined)\n host.machines.onClose(() => {\n const current = links\n links = undefined\n clearInterval(gateTimer)\n void current?.then(l => l.close()).catch(() => undefined)\n })\n\n return {\n 'machines.share.start': async (p) => {\n if (!Array.isArray(p.roots))\n throw new InvalidParamsError('\"roots\" must be a list of folders.')\n // A confined host lends only its own workspace (local hosts are not confined).\n if (host.workspace.confined) {\n for (const root of p.roots)\n host.workspace.resolveFolder(String(root))\n }\n return (await required()).startShare({ hostId: str(p.hostId, 'hostId'), name: str(p.name, 'name'), roots: p.roots, ...(typeof p.token === 'string' ? { token: p.token } : {}) })\n },\n 'machines.share.stop': async p => (await required()).stopShare(str(p.hostId, 'hostId')),\n 'machines.useServer': async (p) => {\n if (typeof p.enabled !== 'boolean')\n throw new InvalidParamsError('\"enabled\" must be a boolean.')\n return (await required()).setUse(str(p.hostId, 'hostId'), p.enabled)\n },\n 'machines.links.status': async () => (gateOn() ? (await load()).status() : EMPTY),\n }\n}\n","/** Machines this host knows, for clients (`docs/MACHINES.md`): list them, forget one, browse one's folders. */\nimport type { ChatHost } from '../../../chat/host/engine'\nimport type { HostSignal } from '../../protocol'\nimport type { Handlers } from './types'\nimport { posix } from 'node:path'\nimport { insideDeclaredRoots } from '../../../chat/host/machines'\nimport { InvalidParamsError } from './params'\n\n/** Folders listed per call at most. */\nconst MAX_DIRS = 2000\n\nexport function createMachineHandlers({ host, broadcast }: { host: ChatHost, broadcast: (signal: HostSignal) => void }): Handlers<'machines.list' | 'machines.forget' | 'machines.listDirs'> {\n return {\n 'machines.list': () => host.machines.list(),\n 'machines.forget': (p) => {\n if (typeof p.machineId !== 'string')\n throw new InvalidParamsError('machines.forget: \"machineId\" must be a string.')\n const machine = host.machines.get(p.machineId)\n const forgotten = host.machines.forget(p.machineId)\n if (forgotten && machine)\n broadcast({ kind: 'machine:status', machineId: machine.id, name: machine.name, status: 'offline' })\n return { forgotten }\n },\n 'machines.listDirs': async (p) => {\n if (typeof p.machineId !== 'string')\n throw new InvalidParamsError('machines.listDirs: \"machineId\" must be a string.')\n const machine = host.machines.get(p.machineId)\n const link = host.machines.link(p.machineId)\n if (!machine || !link)\n throw new Error(`Unknown machine \"${p.machineId}\".`)\n const roots = machine.roots.map(root => root.path)\n // No path: the first root.\n const asked = p.path === undefined || p.path === '' ? roots[0]! : p.path\n if (typeof asked !== 'string' || !insideDeclaredRoots(machine.roots, asked))\n throw new Error(`${String(asked)} is outside ${machine.name}'s roots.`)\n const path = posix.normalize(asked)\n const root = roots.find(r => insideDeclaredRoots([{ path: r }], path))!\n // The machine confines the listing again on its filesystem (real paths); never waits for an offline one.\n const { entries } = await link.call('fs.list', { handle: { id: 'host-list-dirs', cwd: root }, path }, { wait: false })\n const dirs = entries\n .map(entry => (typeof entry === 'string' ? entry : entry.path))\n .filter(name => name.endsWith('/'))\n .map(name => posix.join(path, name.slice(0, -1)))\n .sort()\n .slice(0, MAX_DIRS)\n return { path, dirs, roots }\n },\n }\n}\n","/**\n * One page of a transcript for `sessions.loadEvents` paging, in whole runs:\n * everything from a user message to the turn before the next one. The run\n * the page ends in is always whole, and the runs before it join while the\n * page stays within `limit` turns, so scrolling back brings the previous\n * run (or a few small ones) at a time, never part of one. A run longer than\n * {@link WHOLE_RUN_PAGES} pages on its own is the one exception: it comes in\n * pieces of that size, each starting on a turn that keeps a tool call with\n * its result. The GUI's local pager cuts with the same rule.\n */\nimport type { SessionRun } from '../../../session/index'\nimport type { SessionTurn } from '../../../types'\nimport type { LoadEventsPaging } from '../../protocol'\nimport { LOAD_EVENTS_MAX_PAGE_TURNS, LOAD_EVENTS_PAGE_TURNS } from '../../protocol'\nimport { nonNegativeInt } from './params'\n\n/**\n * A run longer than this many pages is split (by `limit`, so the client's\n * halving retry on a reply too large still converges).\n */\nexport const WHOLE_RUN_PAGES = 5\n\nexport function isPagedLoad(p: LoadEventsPaging | undefined): boolean {\n return p?.before !== undefined || p?.limit !== undefined\n}\n\n/** Per turn: does a run start there (a parent-run user turn carrying no tool result)? */\nexport function exchangeBoundaries(turns: readonly SessionTurn[], runs: readonly SessionRun[]): boolean[] {\n const childRuns = new Set(runs.filter(run => (run.depth ?? 0) > 0 || run.parentRunId !== undefined).map(run => run.id))\n return turns.map(turn => turn.role === 'user'\n && !(turn.runId !== undefined && childRuns.has(turn.runId))\n && !turn.content.some(block => block.type === 'tool_result'))\n}\n\n/** Per turn: can a page start there without leaving a tool call's result behind (not a tool-result turn)? */\nexport function turnCutPoints(turns: readonly SessionTurn[]): boolean[] {\n return turns.map(turn => !(turn.role === 'user' && turn.content.some(block => block.type === 'tool_result')))\n}\n\n/**\n * `[from, to)` of the page, and the cursor of the one before it, over the\n * turns' {@link exchangeBoundaries} (run starts) and {@link turnCutPoints}\n * (where a run too long to send whole may be split; run starts when absent).\n */\nexport function transcriptPage(\n boundaries: readonly boolean[],\n paging: LoadEventsPaging,\n cuts: readonly boolean[] = boundaries,\n): { from: number, to: number, cursor?: number } {\n const before = nonNegativeInt(paging.before, 'before')\n const limit = Math.min(Math.max(nonNegativeInt(paging.limit, 'limit') ?? LOAD_EVENTS_PAGE_TURNS, 1), LOAD_EVENTS_MAX_PAGE_TURNS)\n const to = Math.min(before ?? boundaries.length, boundaries.length)\n if (to === 0)\n return { from: 0, to: 0 }\n /** Where the run holding turn `end - 1` starts (0 when no run start precedes it). */\n const runStart = (end: number): number => {\n let i = end - 1\n while (i > 0 && !boundaries[i])\n i--\n return i\n }\n let from = runStart(to)\n const ceiling = limit * WHOLE_RUN_PAGES\n if (to - from > ceiling) {\n // One run too long to send whole: its last `ceiling` turns, from a turn\n // that keeps a tool call with its result.\n from = to - ceiling\n while (from < to - 1 && !cuts[from])\n from++\n }\n else {\n // The runs before it too, whole, while the page stays within `limit`.\n while (from > 0) {\n const previous = runStart(from)\n if (to - previous > limit)\n break\n from = previous\n }\n }\n return { from, to, ...(from > 0 ? { cursor: from } : {}) }\n}\n","/** Session artifacts: list, delete, upsert, with change fan-out. */\nimport type { SessionStore } from '../../../session/index'\nimport type { HostSignal } from '../../protocol'\nimport type { Handlers } from './types'\nimport { normalizeArtifactInput } from '../../../session/artifacts'\n\n/** Wire-supplied limit → sane positive integer capped at 1000, else `undefined` (no limit). */\nfunction boundedLimit(raw: unknown): number | undefined {\n return Number.isInteger(raw) && (raw as number) > 0 ? Math.min(raw as number, 1000) : undefined\n}\n\nexport function createArtifactHandlers({ store, broadcast }: {\n store: SessionStore\n broadcast: (signal: HostSignal) => void\n}): Handlers<'sessions.artifacts' | 'artifacts.list' | 'artifacts.delete' | 'artifacts.upsert'> {\n return {\n 'sessions.artifacts': async (p) => {\n if (!store.listArtifacts)\n return []\n return store.listArtifacts({\n sessionId: p.sessionId,\n ...(typeof p.kind === 'string' ? { kind: p.kind } : {}),\n ...(boundedLimit(p.limit) !== undefined ? { limit: boundedLimit(p.limit) } : {}),\n })\n },\n 'artifacts.list': async (p) => {\n if (!store.listArtifacts)\n return []\n return store.listArtifacts({\n // Tri-state: `null` selects untagged sessions, omitted ignores the axis.\n ...(p.projectRoot === null || typeof p.projectRoot === 'string' ? { projectRoot: p.projectRoot } : {}),\n ...(typeof p.kind === 'string' ? { kind: p.kind } : {}),\n ...(typeof p.uri === 'string' ? { uri: p.uri } : {}),\n ...(typeof p.since === 'number' && Number.isFinite(p.since) ? { since: p.since } : {}),\n ...(boundedLimit(p.limit) !== undefined ? { limit: boundedLimit(p.limit) } : {}),\n })\n },\n 'artifacts.delete': async (p) => {\n if (!store.deleteArtifact)\n return false\n await store.deleteArtifact(p.sessionId, p.artifactId)\n broadcast({ kind: 'artifact:changed', sessionId: p.sessionId, op: 'delete', artifactId: p.artifactId })\n return true\n },\n 'artifacts.upsert': async (p) => {\n if (!store.upsertArtifact)\n return null\n // Wire input: re-normalize the presentation fields (bounds, kind\n // shape) before trusting them; identity fields pass through since\n // the store merges onto the existing row anyway.\n const normalized = normalizeArtifactInput(p.artifact)\n if (!normalized || typeof p.artifact?.sessionId !== 'string' || typeof p.artifact?.id !== 'string')\n return null\n const now = Date.now()\n const stored = await store.upsertArtifact({\n ...normalized,\n id: p.artifact.id,\n sessionId: p.artifact.sessionId,\n ...(typeof p.artifact.runId === 'string' ? { runId: p.artifact.runId } : {}),\n ...(typeof p.artifact.turnId === 'string' ? { turnId: p.artifact.turnId } : {}),\n createdAt: typeof p.artifact.createdAt === 'number' ? p.artifact.createdAt : now,\n updatedAt: now,\n })\n if (stored)\n broadcast({ kind: 'artifact:changed', sessionId: stored.sessionId, op: 'upsert', artifactId: stored.id, artifact: stored })\n return stored\n },\n }\n}\n","/**\n * The host's provider credentials, managed by a client (Settings on a\n * window attached to a zidane-server): status, set an API key, remove.\n * Secrets go in, never out: statuses carry sources, labels and env var\n * names only, and nothing here logs a key.\n */\nimport type { ChatHost } from '../../../chat/host/engine'\nimport type { ProviderDescriptor } from '../../../chat/providers'\nimport type { HostProviderAuth } from '../../protocol'\nimport type { DaemonEnvironment } from '../environment'\nimport type { Handlers } from './types'\nimport { detectAuth } from '../../../chat/auth'\nimport { applyApiKeyEnv, readProviderCredentials, removeProviderCredential, removeStoredCredential, setProviderCredential } from '../../../chat/credentials'\n\n/** Longest API key accepted (keys are well under 1 KiB; this bounds a mistaken paste). */\nconst MAX_KEY_LENGTH = 8192\n\nexport type ProviderAuth = ReturnType<typeof createProviderAuth>\n\n/** The host's providers and their credentials: lookups, statuses, and applying a change. */\nexport function createProviderAuth({ host, env }: { host: Pick<ChatHost, 'rebuildAllAgents'>, env: DaemonEnvironment }) {\n const registry = (): Readonly<Record<string, ProviderDescriptor>> => env.config.providers\n const dataDir = (): string => env.userDataDir()\n\n const descriptorOf = (provider: unknown): ProviderDescriptor => {\n const descriptor = typeof provider === 'string' ? registry()[provider] : undefined\n if (!descriptor)\n throw new Error(`Unknown provider \"${String(provider)}\".`)\n return descriptor\n }\n\n const statusOf = (key: string): HostProviderAuth => {\n const auth = detectAuth(dataDir(), { [key]: registry()[key]! })[0]!\n return {\n key: auth.key,\n label: auth.label,\n configured: auth.available,\n oauth: registry()[key]?.oauthProvider !== undefined,\n ...(auth.envKey ? { envKey: auth.envKey } : {}),\n methods: auth.methods.map(m => ({\n source: m.source,\n active: m.active === true,\n ...(m.key !== undefined ? { key: m.key } : {}),\n ...(m.label !== undefined ? { label: m.label } : {}),\n detail: m.detail,\n })),\n }\n }\n\n /** The stored API key values of a provider (to clear them from the environment once removed). */\n const storedKeys = (descriptor: ProviderDescriptor): string[] =>\n readProviderCredentials(dataDir(), descriptor).flatMap(s => s.credential.kind === 'apikey' && s.credential.value ? [s.credential.value] : [])\n\n /** Make the change take effect: env re-applied, a removed key out of it, agents rebuilt. */\n const applied = (descriptor: ProviderDescriptor, removedKeys: readonly string[] = []): void => {\n if (env.applyAuthEnv)\n env.applyAuthEnv()\n else\n applyApiKeyEnv(dataDir(), registry(), { log: () => undefined })\n // `applyApiKeyEnv` leaves the env alone when nothing is stored; a key it\n // put there earlier must not outlive its removal.\n const envKey = descriptor.envKey\n if (envKey && removedKeys.includes(process.env[envKey] ?? '') && !storedKeys(descriptor).includes(process.env[envKey]!))\n delete process.env[envKey]\n void host.rebuildAllAgents().catch(() => undefined)\n }\n\n return { registry, dataDir, descriptorOf, statusOf, storedKeys, applied }\n}\n\nexport function createAuthHandlers({ auth }: { auth: ProviderAuth }): Handlers<'auth.status' | 'auth.setApiKey' | 'auth.remove'> {\n const { registry, dataDir, descriptorOf, statusOf, storedKeys, applied } = auth\n return {\n 'auth.status': () => ({ providers: Object.keys(registry()).map(statusOf) }),\n 'auth.setApiKey': (p) => {\n const descriptor = descriptorOf(p.provider)\n const key = typeof p.key === 'string' ? p.key.trim() : ''\n if (!key)\n throw new Error('The API key is empty.')\n if (key.length > MAX_KEY_LENGTH)\n throw new Error(`The API key is longer than ${MAX_KEY_LENGTH} characters.`)\n setProviderCredential(dataDir(), descriptor, { kind: 'apikey', value: key })\n applied(descriptor)\n return statusOf(descriptor.key)\n },\n 'auth.remove': (p) => {\n const descriptor = descriptorOf(p.provider)\n const before = storedKeys(descriptor)\n let removed: boolean\n if (typeof p.account === 'string') {\n removed = removeStoredCredential(dataDir(), descriptor, p.account)\n }\n else {\n removed = readProviderCredentials(dataDir(), descriptor).length > 0\n removeProviderCredential(dataDir(), descriptor)\n }\n if (removed)\n applied(descriptor, before.filter(k => !storedKeys(descriptor).includes(k)))\n return { removed, provider: statusOf(descriptor.key) }\n },\n }\n}\n","/** Browser hosts a client registers to serve the agent's browser tool. */\nimport type { ChatHost } from '../../../chat/host/engine'\nimport type { HostPeer } from '../peers'\nimport type { Handlers } from './types'\n\nexport function createBrowserHandlers({ host }: { host: ChatHost }): {\n methods: Handlers<'browser.registerHost' | 'browser.unregisterHost' | 'browser.respond'>\n /** The peer dropped: release the browser hosts it registered. */\n releasePeer: (peer: HostPeer) => void\n} {\n return {\n methods: {\n 'browser.registerHost': (p, peer) => {\n ;(peer.browserHosts ??= new Set()).add(p.hostId)\n host.browser.registerHost(p.hostId)\n return { ok: true }\n },\n 'browser.unregisterHost': (p, peer) => {\n peer.browserHosts?.delete(p.hostId)\n host.browser.unregisterHost(p.hostId)\n return { ok: true }\n },\n 'browser.respond': (p, peer) => host.browser.respond(p.requestId, p.response, peer.browserHosts ?? new Set()),\n },\n releasePeer(peer) {\n for (const hostId of peer.browserHosts ?? [])\n host.browser.unregisterHost(hostId)\n },\n }\n}\n","/**\n * Installs and removals from a client (`catalog.install` / `remove` /\n * `update`, `mcp.upsert` / `remove`): the local Settings actions, run on\n * the host for a window attached to a zidane-server.\n *\n * Scope: the host user's only (`~/.agents/*`, `~/.<prefix>/*`). A\n * project's skills, extensions and MCP servers are files in its folder,\n * which the agent and the files panel already edit; installing into one\n * from a client would run a package manager inside a workspace for no gain.\n *\n * Installs fetch code and may run package managers ON THE HOST, so a\n * zidane-server gates them (`allowRemoteInstalls`, on by default: a client\n * token already runs commands there) and audits every attempt, refused or\n * failed ones too, with the token. Specs are GitHub or npm only (a path is\n * refused), work is bounded in time, progress lines come back with the\n * result. MCP `env` / `headers` values go into the host's `mcps.json` and\n * never come back. After a change the host rebuilds what reads it and\n * every window gets `catalog:changed`.\n */\nimport type { ChatHost } from '../../../chat/host/engine'\nimport type { HostSettings } from '../../../chat/host/signals'\nimport type { InstallIo } from '../../../install/source'\nimport type { McpServerConfig } from '../../../types'\nimport type { HostCatalogName, HostSignal } from '../../protocol'\nimport type { DaemonEnvironment } from '../environment'\nimport type { HostPeer } from '../peers'\nimport type { Handlers } from './types'\nimport { existsSync, rmSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { enabledMcpsWith, enabledMcpsWithout } from '../../../chat/mcp-allowlist'\nimport { mcpsWritePath, removeMcpServer, upsertMcpServer } from '../../../chat/mcps-write'\nimport { projectUserPaths } from '../../../chat/project-user-paths'\nimport { ExtensionInstallError, installExtensionFromSpec, removeInstalledExtension, updateInstalledExtension } from '../../../extensions/install'\nimport { abortableInstallIo } from '../../../install/source'\nimport { installSkillFromSpec } from '../../../skills/install'\nimport { InvalidParamsError } from './params'\n\nexport interface RemoteInstallsOptions {\n /** `allowRemoteInstalls`, read at each call. */\n allowed: () => boolean\n /** One audit line per attempt (the server adds the connection's token). */\n audit?: (peer: HostPeer, entry: Record<string, unknown>) => void\n /** Test seam: the installers' fetch / exec / which. */\n io?: InstallIo\n /** Bound on one install or update. Default 5 minutes. */\n timeoutMs?: number\n}\n\ntype InstallMethod = 'catalog.install' | 'catalog.remove' | 'catalog.update' | 'mcp.upsert' | 'mcp.remove'\n\nconst DEFAULT_TIMEOUT_MS = 5 * 60_000\nconst MAX_SPEC_LENGTH = 500\nconst MAX_MCP_CONFIG_BYTES = 64 * 1024\nconst NAME_RE = /^[\\w@.-]{1,100}$/\nconst MCP_TRANSPORTS = new Set(['stdio', 'sse', 'streamable-http'])\n\nconst OFF_MESSAGE = 'Installs from clients are off on this server (allowRemoteInstalls is off).'\n\n/** A spec a server may fetch: GitHub or npm. Anything path-like is refused before the parsers see it. */\nfunction checkSpec(spec: unknown): string {\n if (typeof spec !== 'string' || spec.trim() === '')\n throw new InvalidParamsError('spec must be a non-empty string.')\n const value = spec.trim()\n if (value.length > MAX_SPEC_LENGTH)\n throw new InvalidParamsError(`spec is longer than ${MAX_SPEC_LENGTH} characters.`)\n const segments = value.split(/[/:#@]/)\n if (/^(?:[./~\\\\]|file:)/i.test(value) || value.includes('\\\\') || segments.includes('.') || segments.includes('..'))\n throw new InvalidParamsError(`\"${value}\" is a path: a server installs from GitHub (owner/repo, a GitHub URL) or npm only.`)\n return value\n}\n\nfunction checkName(name: unknown, what: string): string {\n if (typeof name !== 'string' || !NAME_RE.test(name) || name === '.' || name === '..')\n throw new InvalidParamsError(`${what} must be a plain name (letters, digits, ., _, -, @).`)\n return name\n}\n\nfunction checkKind(kind: unknown): 'skill' | 'extension' {\n if (kind !== 'skill' && kind !== 'extension')\n throw new InvalidParamsError('kind must be \"skill\" or \"extension\".')\n return kind\n}\n\nfunction isStringRecord(value: unknown): value is Record<string, string> {\n return typeof value === 'object' && value !== null && !Array.isArray(value) && Object.values(value).every(v => typeof v === 'string')\n}\n\nfunction checkMcpConfig(config: unknown): McpServerConfig {\n if (typeof config !== 'object' || config === null || Array.isArray(config))\n throw new InvalidParamsError('config must be an MCP server object.')\n if (JSON.stringify(config).length > MAX_MCP_CONFIG_BYTES)\n throw new InvalidParamsError(`config is larger than ${MAX_MCP_CONFIG_BYTES} bytes.`)\n const c = config as Record<string, unknown>\n checkName(c.name, 'name')\n if (c.transport !== undefined && !MCP_TRANSPORTS.has(c.transport as string))\n throw new InvalidParamsError('transport must be stdio, sse or streamable-http.')\n const hasCommand = typeof c.command === 'string' && c.command.trim() !== ''\n let hasUrl = false\n if (typeof c.url === 'string') {\n try {\n hasUrl = ['http:', 'https:'].includes(new URL(c.url).protocol)\n }\n catch {}\n if (!hasUrl)\n throw new InvalidParamsError('url must be an http(s) URL.')\n }\n if (!hasCommand && !hasUrl)\n throw new InvalidParamsError('An MCP server needs a command (stdio) or a url.')\n if (c.args !== undefined && (!Array.isArray(c.args) || !c.args.every(a => typeof a === 'string')))\n throw new InvalidParamsError('args must be strings.')\n for (const key of ['env', 'headers'] as const) {\n if (c[key] !== undefined && !isStringRecord(c[key]))\n throw new InvalidParamsError(`${key} must map names to strings.`)\n }\n return c as unknown as McpServerConfig\n}\n\n/** How long a stopped install may take to roll back before the refusal is answered anyway. */\nconst ROLLBACK_GRACE_MS = 10_000\n\n/**\n * `run` bounded by `ms`: past it, its signal fires (children killed, no next\n * step: `abortableInstallIo`) and the refusal waits for the installer's own\n * rollback (staging dir, transactional target), up to {@link ROLLBACK_GRACE_MS}.\n */\nasync function bounded<T>(run: (signal: AbortSignal) => Promise<T>, ms: number, what: string): Promise<T> {\n const controller = new AbortController()\n const work = run(controller.signal)\n let timer: ReturnType<typeof setTimeout> | undefined\n try {\n return await Promise.race([work, new Promise<never>((_, reject) => {\n timer = setTimeout(() => {\n controller.abort()\n reject(new Error(`${what} took longer than ${Math.round(ms / 1000)}s and was stopped.`))\n }, ms)\n })])\n }\n catch (err) {\n if (controller.signal.aborted) {\n let grace: ReturnType<typeof setTimeout> | undefined\n await Promise.race([work.catch(() => undefined), new Promise((resolve) => {\n grace = setTimeout(resolve, ROLLBACK_GRACE_MS)\n })])\n clearTimeout(grace)\n }\n throw err\n }\n finally {\n clearTimeout(timer)\n }\n}\n\nexport function createCatalogInstallHandlers({ host, env, broadcast, setSettings, options }: {\n host: Pick<ChatHost, 'rebuildAllAgents'>\n env: DaemonEnvironment\n broadcast: (signal: HostSignal) => void\n /** `settings.set`: writes, rebuilds what the change needs, tells every window. */\n setSettings: (patch: Partial<HostSettings>) => unknown\n options?: RemoteInstallsOptions\n}): Handlers<InstallMethod> {\n const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS\n const io = options?.io\n const prefix = (): string => env.config.prefix\n /** The host user's roots for `subPath` (`~/.agents/<sub>`, `~/.<prefix>/<sub>`), read at call time. */\n const userRoots = (subPath: string): string[] =>\n projectUserPaths({ subPath, cwd: homedir(), home: homedir(), prefix: prefix() }).filter(p => p.source === 'user').map(p => p.path)\n\n /** Gate, run, audit: every attempt leaves one line, refusals and failures included. */\n async function guarded<T>(peer: HostPeer, event: string, fields: Record<string, unknown>, run: () => Promise<T> | T): Promise<T> {\n if (!options) {\n throw new Error('This host takes no installs from clients (a zidane-server does, with allowRemoteInstalls on).')\n }\n if (!options.allowed()) {\n options.audit?.(peer, { event, ...fields, ok: false, refused: 'allowRemoteInstalls is off' })\n throw new Error(OFF_MESSAGE)\n }\n try {\n const result = await run()\n options.audit?.(peer, { event, ...fields, ok: true })\n return result\n }\n catch (err) {\n options.audit?.(peer, { event, ...fields, ok: false, error: err instanceof Error ? err.message : String(err) })\n throw err\n }\n }\n\n const changed = (catalog: HostCatalogName): void => broadcast({ kind: 'catalog:changed', catalog })\n\n /** Skills and MCP servers are read when an agent is built. */\n const rebuild = (): void => {\n void host.rebuildAllAgents({ rediscover: true }).catch(() => undefined)\n }\n\n /** Extensions live in the runtime registry: forget it, rebuild, dispose the old one once idle (as `runtime.reload`). */\n const reloadExtensions = (): void => {\n const disposeOld = env.forgetRuntime()\n void host.rebuildAllAgents({ rediscover: true }).then(disposeOld, disposeOld)\n }\n\n /** `name` dropped from (or added to) an explicit allowlist; an absent list means \"all\", left alone. */\n const allowlist = (key: 'enabledExtensions' | 'enabledSkills', name: string, present: boolean): boolean => {\n const list = env.readSettings()[key]\n if (list === undefined || list.includes(name) === present)\n return false\n setSettings({ [key]: present ? [...list, name] : list.filter(n => n !== name) })\n return true\n }\n\n /** The user-scope install directory named `name` under `subPath`, if any. */\n const userDir = (subPath: string, name: string, marker?: string): string | undefined =>\n userRoots(subPath).map(root => join(root, name)).find(dir => existsSync(marker ? join(dir, marker) : dir))\n\n return {\n 'catalog.install': (p, peer) => guarded(peer, 'catalog.install', { kind: p.kind, spec: typeof p.spec === 'string' ? p.spec.slice(0, MAX_SPEC_LENGTH) : undefined }, async () => {\n const kind = checkKind(p.kind)\n const spec = checkSpec(p.spec)\n if (p.scope !== undefined && p.scope !== 'user')\n throw new InvalidParamsError('A server installs in its user scope only (scope: \"user\").')\n const progress: string[] = []\n const onProgress = (line: string): void => {\n if (progress.length < 200)\n progress.push(line)\n }\n const home = homedir()\n if (kind === 'skill') {\n const result = await bounded(signal => installSkillFromSpec({\n source: spec,\n scope: 'user',\n cwd: home,\n home,\n prefix: prefix(),\n onProgress,\n io: abortableInstallIo(io, signal),\n ...(Array.isArray(p.skills) ? { skills: p.skills.filter(s => typeof s === 'string') } : {}),\n ...(p.all === true ? { all: true } : {}),\n ...(p.overwrite === true ? { overwrite: true } : {}),\n }), timeoutMs, `Installing ${spec}`)\n rebuild()\n changed('skills')\n const skipped = result.skipped?.length ? `. Skipped existing: ${result.skipped.join(', ')}` : ''\n return { installed: [...result.installed], message: `installed ${result.installed.join(', ')} (${result.provenance ?? result.engine})${skipped}`, progress }\n }\n let result\n try {\n result = await bounded(signal => installExtensionFromSpec({\n source: spec,\n scope: 'user',\n cwd: home,\n home,\n prefix: prefix(),\n onProgress,\n io: abortableInstallIo(io, signal),\n ...(typeof p.extension === 'string' ? { extension: p.extension } : {}),\n ...(p.overwrite === true ? { overwrite: true } : {}),\n }), timeoutMs, `Installing ${spec}`)\n }\n catch (err) {\n if (err instanceof ExtensionInstallError && err.code === 'exists')\n throw new Error('already installed on the server: update or remove it first.')\n throw err\n }\n // Enabled in an explicit allowlist (that write reloads the registry); else reload here.\n if (!allowlist('enabledExtensions', result.name, true))\n reloadExtensions()\n changed('extensions')\n const warn = result.warnings.length > 0 ? `. ${result.warnings.join('. ')}` : ''\n return { installed: [result.name], message: `installed \"${result.name}\" (${result.provenance})${warn}`, progress }\n }),\n\n 'catalog.remove': (p, peer) => guarded(peer, 'catalog.remove', { kind: p.kind, name: p.name }, async () => {\n const kind = checkKind(p.kind)\n const name = checkName(p.name, 'name')\n if (kind === 'skill') {\n const dir = userDir('skills', name, 'SKILL.md')\n if (!dir)\n throw new Error(`No user-scope skill \"${name}\" on this server (project skills are files in their folder).`)\n rmSync(dir, { recursive: true, force: true })\n allowlist('enabledSkills', name, false)\n rebuild()\n changed('skills')\n return { removed: name, message: `deleted \"${name}\"` }\n }\n const dir = userDir('extensions', name)\n if (!dir)\n throw new Error(`No user-scope extension \"${name}\" on this server.`)\n removeInstalledExtension({ dir, cwd: homedir(), home: homedir(), prefix: prefix() })\n if (!allowlist('enabledExtensions', name, false))\n reloadExtensions()\n changed('extensions')\n return { removed: name, message: `removed \"${name}\"` }\n }),\n\n 'catalog.update': (p, peer) => guarded(peer, 'catalog.update', { kind: p.kind, name: p.name }, async () => {\n const kind = checkKind(p.kind)\n const name = checkName(p.name, 'name')\n if (kind === 'skill')\n throw new Error('Skills are not updated in place: install again with overwrite.')\n const dir = userDir('extensions', name)\n if (!dir)\n throw new Error(`No user-scope extension \"${name}\" on this server.`)\n const result = await bounded(signal => updateInstalledExtension({ dir, cwd: homedir(), home: homedir(), prefix: prefix(), io: abortableInstallIo(io, signal) }), timeoutMs, `Updating ${name}`)\n if (result.upToDate)\n return { updated: result.name, upToDate: true, message: `\"${result.name}\" is already up to date${result.commit ? ` (${result.commit.slice(0, 7)})` : ''}` }\n reloadExtensions()\n changed('extensions')\n return { updated: result.name, upToDate: false, message: `updated \"${result.name}\" → ${result.provenance}` }\n }),\n\n 'mcp.upsert': (p, peer) => guarded(peer, 'mcp.upsert', { name: (p.config as { name?: unknown } | undefined)?.name }, () => {\n const config = checkMcpConfig(p.config)\n const result = upsertMcpServer(mcpsWritePath('user', { home: homedir(), cwd: homedir(), prefix: prefix() }), config)\n // Added from a client: on, like a server added in local Settings. An edit keeps its toggle.\n const enabled = result.action === 'added' ? enabledMcpsWith(env.readSettings().enabledMcps, config.name) : undefined\n if (enabled)\n setSettings({ enabledMcps: enabled })\n rebuild()\n changed('mcps')\n return { name: config.name, created: result.action === 'added' }\n }),\n\n 'mcp.remove': (p, peer) => guarded(peer, 'mcp.remove', { name: p.name }, () => {\n const name = checkName(p.name, 'name')\n const path = mcpsWritePath('user', { home: homedir(), cwd: homedir(), prefix: prefix() })\n try {\n removeMcpServer(path, name)\n }\n catch (err) {\n // No file, or no entry of that name: nothing to remove. A malformed file is an error.\n if (!existsSync(path) || /no entry named/.test(err instanceof Error ? err.message : ''))\n return { removed: false }\n throw err\n }\n const enabled = enabledMcpsWithout(env.readSettings().enabledMcps, name)\n if (enabled)\n setSettings({ enabledMcps: enabled })\n rebuild()\n changed('mcps')\n return { removed: true }\n }),\n }\n}\n\n/** For `ipc.hello`: installs are offered when the server allows them. */\nexport function remoteInstallsAllowed(options: RemoteInstallsOptions | undefined): boolean {\n return options?.allowed() === true\n}\n","/**\n * Secret redaction for what a host shows about its MCP servers\n * (`catalog.mcps`): command-line arguments and URLs, which config files\n * routinely fill with tokens. Over-redacting an ordinary argument is a\n * cosmetic loss; under-redacting leaks a credential to every client, so the\n * rules lean wide, but stay off file paths, package names and plain words.\n *\n * - URLs (`scheme://…`, as an argument or inside one): userinfo, query values,\n * fragment values, and secret-looking path segments.\n * - Values of secret-looking flags (`--token x`, `--api-key=x`), of header\n * flags (`-H \"Name: value\"`, `--header=Name: value`), of secret-looking\n * headers anywhere (`Authorization: Bearer …`), and of secret-looking\n * `KEY=VALUE` pairs (`-e GITHUB_TOKEN=…`, `env API_KEY=…`, `--pass x`).\n * - JSON arguments (`--config '{\"apiKey\":\"…\"}'`): the value of every\n * secret-named key at any depth; the other strings as values.\n * - Connection strings and form bodies (`Server=x;Password=…`,\n * `a=1&token=…`): each secret-named pair's value.\n * - Known token shapes anywhere in an argument (`sk-…`, `ghp_…`, `xoxb-…`,\n * `AKIA…`, `glpat-…`, `zds_…`), and whole high-entropy arguments.\n *\n * What counts as secret-looking is shared (`src/chat/secret-shapes`): the\n * remote host URL check refuses the same shapes in a URL's path.\n */\nimport { isSecretName, isSecretPathSegment, KNOWN_TOKEN, looksLikeSecret } from '../../chat/secret-shapes'\nimport { REDACTED } from '../protocol'\n\nconst HEADER_FLAGS = new Set(['-H', '--header', '--headers'])\nconst URL_SHAPED = /^[a-z][a-z0-9+.-]*:\\/\\//i\nconst HEADER = /^([\\w-]+):(\\s*)\\S.*$/s\nconst KEY_VALUE = /^([A-Z_][\\w.-]*)=(.*)$/is\n/** `k=v` pairs joined by `;` or `&` (a connection string, a form body): `Server=x;Password=y`, `a=1&token=x`. */\nconst DELIMITED_PAIRS = /^[a-z_][\\w .-]*=[^;&]*(?:[;&][a-z_][\\w .-]*=[^;&]*)+[;&]?$/i\n/** A JSON object or array argument (`--config '{\"apiKey\":\"…\"}'`). */\nconst JSON_SHAPED = /^\\s*[{[][\\s\\S]*[}\\]]\\s*$/\n\nconst scrubKnownTokens = (value: string): string => value.replace(KNOWN_TOKEN, REDACTED)\n\nfunction redactPairs(text: string): string {\n return text.split('&').map((pair) => {\n const eq = pair.indexOf('=')\n return eq < 0 ? pair : `${pair.slice(0, eq)}=${REDACTED}`\n }).join('&')\n}\n\n/**\n * `https://user:pw@host/p/<key>/sse?k=v#t=x` → `https://<redacted>@host/p/<redacted>/sse?k=<redacted>#t=<redacted>`;\n * an unparsable URL is redacted whole.\n */\nexport function redactUrl(raw: string): string {\n let url: URL\n try {\n url = new URL(raw)\n }\n catch {\n return REDACTED\n }\n const credentials = url.username !== '' || url.password !== '' ? `${REDACTED}@` : ''\n const path = url.pathname.split('/').map(segment => isSecretPathSegment(segment) ? REDACTED : segment).join('/')\n const keys = [...url.searchParams.keys()]\n const query = keys.length > 0 ? `?${keys.map(key => `${encodeURIComponent(key)}=${REDACTED}`).join('&')}` : ''\n const fragment = url.hash.slice(1)\n const hash = fragment === '' ? '' : fragment.includes('=') ? `#${redactPairs(fragment)}` : looksLikeSecret(fragment) ? `#${REDACTED}` : `#${fragment}`\n const authority = url.host !== '' || raw.includes('//') ? `//${credentials}${url.host}` : ''\n return scrubKnownTokens(`${url.protocol}${authority}${path}${query}${hash}`)\n}\n\nfunction redactHeader(value: string): string {\n const match = HEADER.exec(value)\n return match ? `${match[1]}:${match[2]}${REDACTED}` : REDACTED\n}\n\n/** One value standing on its own (a positional argument, or what follows `--flag=`). */\nfunction redactValue(value: string): string {\n if (URL_SHAPED.test(value))\n return redactUrl(value)\n const header = HEADER.exec(value)\n if (header && isSecretName(header[1]!))\n return redactHeader(value)\n const json = JSON_SHAPED.test(value) ? redactJson(value) : null\n if (json !== null)\n return json\n if (DELIMITED_PAIRS.test(value))\n return redactDelimitedPairs(value)\n const pair = KEY_VALUE.exec(value)\n if (pair)\n return `${pair[1]}=${isSecretName(pair[1]!) ? REDACTED : redactValue(pair[2]!)}`\n if (looksLikeSecret(value))\n return REDACTED\n return scrubKnownTokens(value)\n}\n\n/** `Server=x;Password=y` → `Server=x;Password=<redacted>`: each secret-named pair's value, the others' as values. */\nfunction redactDelimitedPairs(value: string): string {\n return value.split(/([;&])/).map((part) => {\n const eq = part.indexOf('=')\n if (eq < 0)\n return part\n const name = part.slice(0, eq)\n return `${name}=${isSecretName(name.trim()) ? REDACTED : redactValue(part.slice(eq + 1))}`\n }).join('')\n}\n\n/** A JSON argument with every secret-named key's value redacted (any depth), the other strings as values; `null` when not JSON. */\nfunction redactJson(value: string): string | null {\n let parsed: unknown\n try {\n parsed = JSON.parse(value)\n }\n catch {\n return null\n }\n if (parsed === null || typeof parsed !== 'object')\n return null\n const walk = (node: unknown): unknown => {\n if (typeof node === 'string')\n return redactValue(node)\n if (Array.isArray(node))\n return node.map(walk)\n if (node !== null && typeof node === 'object')\n return Object.fromEntries(Object.entries(node).map(([key, child]) => [key, isSecretName(key) ? REDACTED : walk(child)]))\n return node\n }\n return JSON.stringify(walk(parsed))\n}\n\n/** An MCP server's arguments with every secret-looking value replaced by {@link REDACTED}. */\nexport function redactArgs(args: readonly string[]): string[] {\n const out: string[] = []\n for (let i = 0; i < args.length; i++) {\n const arg = args[i]!\n if (!arg.startsWith('-')) {\n out.push(redactValue(arg))\n continue\n }\n const eq = arg.indexOf('=')\n const flag = eq > 0 ? arg.slice(0, eq) : arg\n if (eq > 0) {\n const value = arg.slice(eq + 1)\n out.push(`${flag}=${HEADER_FLAGS.has(flag) ? redactHeader(value) : isSecretName(flag) ? REDACTED : redactValue(value)}`)\n continue\n }\n out.push(scrubKnownTokens(arg))\n const next = args[i + 1]\n if (next === undefined || next.startsWith('-'))\n continue\n if (HEADER_FLAGS.has(flag)) {\n out.push(redactHeader(next))\n i++\n }\n else if (isSecretName(flag)) {\n out.push(REDACTED)\n i++\n }\n }\n return out\n}\n","/**\n * What a host discovered, as the settings tabs list it (`catalog.*`): the\n * same scans and gates the host's agents use (`composeSessionSkills`,\n * `discoverSessionMcpServers`, the plugin gates), each entry with whether\n * the host's settings enable it. Wire-safe and secret-free: an MCP server's\n * `env` / `headers` values never leave the host, and its URL and arguments\n * go through `./redact` (credentials, query / fragment values, header and\n * secret-flag values, secret `KEY=VALUE` pairs, token-shaped values).\n */\nimport type { DiscoveredMcp, DiscoveryError } from '../../chat/mcps-discovery'\nimport type { DiscoveredPlugin } from '../../chat/plugins-discovery'\nimport type { LoadedExtension, LoadedPluginRecord } from '../../extensions/index'\nimport type { SkillConfig } from '../../skills/index'\nimport type { HostCatalogError, HostCatalogExtension, HostCatalogMcp, HostCatalogPlugin, HostCatalogSkill, HostSettings } from '../protocol'\nimport { REDACTED } from '../protocol'\nimport { redactArgs, redactUrl } from './redact'\n\nconst allows = (list: readonly string[] | undefined, name: string): boolean => list === undefined || list.includes(name)\n\n/**\n * Disk skills (gated by `enabledSkills`), then plugin and extension skills\n * (gated by their plugin / extension, so always on here), later ones winning\n * a name like the agent's own merge (`mergeSkillCatalog`).\n */\nexport function skillEntries(input: { disk: readonly SkillConfig[], plugin: readonly SkillConfig[], extension: readonly SkillConfig[], settings: HostSettings }): HostCatalogSkill[] {\n const byName = new Map<string, HostCatalogSkill>()\n const add = (skill: SkillConfig, origin: HostCatalogSkill['origin']): void => {\n const contributedBy = origin === 'plugin' ? skill.metadata?.['zidane.plugin'] : origin === 'extension' ? skill.metadata?.['zidane.extension'] : undefined\n byName.set(skill.name, {\n name: skill.name,\n description: skill.description,\n ...(skill.source ? { source: skill.source } : {}),\n ...(skill.location ? { location: skill.location } : {}),\n origin,\n ...(contributedBy ? { contributedBy } : {}),\n enabled: origin === 'disk' ? allows(input.settings.enabledSkills, skill.name) : true,\n toggleable: origin === 'disk',\n })\n }\n for (const skill of input.disk)\n add(skill, 'disk')\n for (const skill of input.plugin)\n add(skill, 'plugin')\n for (const skill of input.extension)\n add(skill, 'extension')\n return [...byName.values()].sort((a, b) => a.name.localeCompare(b.name))\n}\n\nfunction redactValues(record: Readonly<Record<string, string>> | undefined): Record<string, string> | undefined {\n if (!record)\n return undefined\n return Object.fromEntries(Object.keys(record).map(key => [key, REDACTED]))\n}\n\nexport function mcpEntries(servers: readonly DiscoveredMcp[], errors: readonly DiscoveryError[], settings: HostSettings): { servers: HostCatalogMcp[], errors: HostCatalogError[] } {\n return {\n servers: servers.map(({ config, source, path }) => {\n const env = redactValues(config.env)\n const headers = redactValues(config.headers)\n return {\n name: config.name,\n transport: config.transport,\n source,\n path,\n enabled: allows(settings.enabledMcps, config.name),\n toggleable: true,\n ...(config.command !== undefined ? { command: config.command } : {}),\n ...(config.args ? { args: redactArgs(config.args) } : {}),\n ...(config.url !== undefined ? { url: redactUrl(config.url) } : {}),\n ...(config.cwd !== undefined ? { cwd: config.cwd } : {}),\n ...(config.scope !== undefined ? { scope: config.scope } : {}),\n ...(config.auth !== undefined ? { auth: config.auth } : {}),\n ...(env ? { env } : {}),\n ...(headers ? { headers } : {}),\n }\n }),\n errors: errors.map(e => ({ path: e.path, source: e.source, message: e.message, ...(e.informational ? { informational: true } : {}) })),\n }\n}\n\nfunction capabilities(contributions: NonNullable<LoadedExtension['contributions']>): string[] {\n const labels: string[] = []\n const add = (label: string, present: boolean): void => {\n if (present)\n labels.push(label)\n }\n add('agents', Object.keys(contributions.agents).length > 0)\n add('providers', Object.keys(contributions.providers).length > 0)\n add('tools', Object.keys(contributions.tools).length > 0)\n add('hooks', Object.values(contributions.hooks).some(handlers => handlers !== undefined && handlers.length > 0))\n add('mcps', contributions.mcpServers.length > 0)\n add('skills', contributions.skills.length > 0)\n add('commands', contributions.commands.length > 0)\n add('completions', contributions.completionProviders.length > 0)\n add('themes', Object.keys(contributions.themes).length > 0)\n add('system', contributions.systemFragments.length > 0)\n return labels\n}\n\n/** Loaded, then inactive (disabled or broken), first one of a name wins. */\nexport function extensionEntries(loaded: readonly LoadedExtension[], inactive: readonly LoadedExtension[], settings: HostSettings): HostCatalogExtension[] {\n const rows = new Map<string, HostCatalogExtension>()\n for (const ext of [...loaded, ...inactive]) {\n if (rows.has(ext.name))\n continue\n rows.set(ext.name, {\n name: ext.name,\n source: ext.source,\n enabled: !ext.error && allows(settings.enabledExtensions, ext.name),\n toggleable: !ext.error,\n ...(ext.definition?.version ? { version: ext.definition.version } : {}),\n ...(ext.definition?.description ? { description: ext.definition.description } : {}),\n ...(ext.dir ? { dir: ext.dir } : {}),\n ...(ext.error ? { error: ext.error } : {}),\n ...(ext.contributions ? { capabilities: capabilities(ext.contributions) } : {}),\n })\n }\n return [...rows.values()].sort((a, b) => a.name.localeCompare(b.name))\n}\n\ninterface PluginSource { plugin: DiscoveredPlugin['plugin'], name: string, origin: HostCatalogPlugin['origin'] }\n\n/** Disk plugins, then the ones extensions loaded (a name on disk wins, as the agent's gate decides). */\nexport function pluginEntries(disk: readonly DiscoveredPlugin[], fromExtensions: readonly LoadedPluginRecord[], settings: HostSettings): HostCatalogPlugin[] {\n const sources: PluginSource[] = [\n ...disk.map(p => ({ plugin: p.plugin, name: p.name, origin: { kind: 'disk' as const, scope: p.source, dir: p.path } })),\n ...fromExtensions.map(r => ({ plugin: r.plugin, name: r.name, origin: { kind: 'extension' as const, extensionName: r.extensionName, dir: r.dir } })),\n ]\n const rows = new Map<string, HostCatalogPlugin>()\n for (const { plugin, name, origin } of sources) {\n if (rows.has(name))\n continue\n const error = plugin.ok ? undefined : plugin.diagnostics.find(d => d.severity === 'error')?.message\n rows.set(name, {\n name,\n origin,\n ok: plugin.ok,\n enabled: plugin.ok && allows(settings.enabledPlugins, name),\n toggleable: plugin.ok,\n ...(plugin.manifest?.version !== undefined ? { version: plugin.manifest.version } : {}),\n ...(plugin.manifest?.description !== undefined ? { description: plugin.manifest.description } : {}),\n skills: plugin.skills.map(s => s.name),\n mcpServers: plugin.mcpServers.map(s => s.name),\n ...(error ? { error } : {}),\n })\n }\n return [...rows.values()].sort((a, b) => a.name.localeCompare(b.name))\n}\n","/**\n * What the host discovered for its settings tabs (`catalog.*`) and the\n * models its credentials can run (`models.list`), so a window editing a\n * server lists the server's skills, MCP servers, extensions, plugins and\n * providers, not its own.\n */\nimport type { ResolvedConfig } from '../../../chat/config'\nimport type { ChatHost } from '../../../chat/host/engine'\nimport type { MachineProject } from '../../../chat/host/machines'\nimport type { DiscoveredPlugin } from '../../../chat/plugins-discovery'\nimport type { HostModelProvider } from '../../protocol'\nimport type { DaemonEnvironment } from '../environment'\nimport type { Handlers } from './types'\nimport { detectAuth } from '../../../chat/auth'\nimport { machineDiscoveryCwd } from '../../../chat/host/machines'\nimport { discoverProjectMcps } from '../../../chat/mcps-discovery'\nimport { buildPluginContributions, discoverProjectPlugins } from '../../../chat/plugins-discovery'\nimport { scopeCwd } from '../../../chat/session-cwd'\nimport { discoverProjectSkills } from '../../../chat/skills-discovery'\nimport { filterRegistryPlugins } from '../../../extensions/index'\nimport { extensionEntries, mcpEntries, pluginEntries, skillEntries } from '../catalog-entries'\n\ntype CatalogMethod = 'catalog.skills' | 'catalog.mcps' | 'catalog.extensions' | 'catalog.plugins' | 'models.list'\n\nconst kindOf = (kind: unknown): string | undefined => (typeof kind === 'string' ? kind : undefined)\n\n/**\n * The folder a catalog scans: `cwd` (inside the roots on a server), else the\n * host user's home. A machine's folder (`docs/MACHINES.md` § Folders) is\n * never read here: a folder of this host's stands in for the user scope.\n */\nexport function catalogFolder({ env, host }: { env: Pick<DaemonEnvironment, 'userDataDir'>, host: Pick<ChatHost, 'resolveFolder'> }, cwd: unknown, kind?: unknown): string {\n if (cwd !== undefined && typeof cwd !== 'string')\n throw new Error('cwd must be a string.')\n if (!cwd)\n return scopeCwd('')\n const folder = host.resolveFolder(cwd, kindOf(kind))\n return folder.machine ? machineDiscoveryCwd(env.userDataDir()) : scopeCwd(folder.cwd)\n}\n\nexport function createCatalogHandlers({ env, host }: { env: DaemonEnvironment, host: Pick<ChatHost, 'resolveFolder' | 'folderCatalog'> }): Handlers<CatalogMethod> {\n const folderOf = (cwd: unknown, kind?: unknown): string => catalogFolder({ env, host }, cwd, kind)\n /** User scope here, project scope read on the machine for a machine's folder. */\n const catalogOf = async (cwd: unknown, kind: unknown, prefix: string): Promise<{ dir: string, project?: MachineProject }> => {\n if (typeof cwd !== 'string' || !cwd || !host.resolveFolder(cwd, kindOf(kind)).machine)\n return { dir: folderOf(cwd, kind) }\n const { discoveryCwd, project } = await host.folderCatalog(cwd, kindOf(kind), prefix)\n return { dir: discoveryCwd, ...(project ? { project } : {}) }\n }\n const scanFlags = () => {\n const settings = env.readSettings()\n return { settings, foreignAgents: settings.importForeignConfigs === true, ruler: settings.importRulerConfigs !== false }\n }\n const plugins = async (dir: string, config: ResolvedConfig): Promise<DiscoveredPlugin[]> => {\n const { plugins: found } = await discoverProjectPlugins({\n cwd: dir,\n prefix: config.prefix,\n ...(config.pluginScanPaths.length > 0 ? { extraRoots: config.pluginScanPaths } : {}),\n })\n return found\n }\n\n return {\n 'catalog.skills': async (p) => {\n const { dir, project } = await catalogOf(p?.cwd, p?.kind, env.config.prefix)\n const config = await env.runtimeConfig(dir)\n const { settings, foreignAgents, ruler } = scanFlags()\n const [found, discovered] = await Promise.all([\n discoverProjectSkills({ cwd: dir, prefix: config.prefix, foreignAgents, ruler }),\n plugins(dir, config),\n ])\n // A machine's project skills first: project beats user, as in its sessions.\n const machineNames = new Set((project?.skills ?? []).map(skill => skill.name))\n const disk = [...(project?.skills ?? []), ...found.filter(skill => !machineNames.has(skill.name))]\n const pluginSkills = buildPluginContributions({ discovered, ...(settings.enabledPlugins !== undefined ? { enabled: settings.enabledPlugins } : {}) }).skills\n const live = filterRegistryPlugins(config.extensions, settings.enabledPlugins, new Set(discovered.map(d => d.name)))\n return { skills: skillEntries({ disk, plugin: pluginSkills, extension: live.skills, settings }) }\n },\n 'catalog.mcps': async (p) => {\n const { dir, project } = await catalogOf(p?.cwd, p?.kind, env.config.prefix)\n const config = await env.runtimeConfig(dir)\n const { settings, foreignAgents, ruler } = scanFlags()\n const { servers: found, errors } = discoverProjectMcps({ cwd: dir, prefix: config.prefix, foreignAgents, ruler })\n const machineNames = new Set((project?.mcps ?? []).map(server => server.config.name))\n const servers = [...(project?.mcps ?? []), ...found.filter(server => !machineNames.has(server.config.name))]\n return mcpEntries(servers, errors, settings)\n },\n 'catalog.extensions': async (p) => {\n const config = await env.runtimeConfig(folderOf(p?.cwd, p?.kind))\n return { extensions: extensionEntries(config.extensions.loaded, config.extensions.inactive, env.readSettings()) }\n },\n 'catalog.plugins': async (p) => {\n const dir = folderOf(p?.cwd, p?.kind)\n const config = await env.runtimeConfig(dir)\n return { plugins: pluginEntries(await plugins(dir, config), config.extensions.plugins, env.readSettings()) }\n },\n 'models.list': async (p) => {\n const config = p?.cwd ? await env.runtimeConfig(folderOf(p.cwd, p.kind)) : env.config\n const providers: HostModelProvider[] = detectAuth(env.userDataDir(), config.providers)\n .filter(auth => auth.available)\n .map(auth => ({\n key: auth.key,\n label: config.providers[auth.key]?.label ?? auth.label,\n // JSON copies: `ModelInfo` is data, but a provider may hand out frozen or shared arrays.\n models: JSON.parse(JSON.stringify(config.modelsFor(auth.key))) as HostModelProvider['models'],\n }))\n return { providers }\n },\n }\n}\n","/** Runs: send, interrupt, steer, follow-up, running work, and slash-command discovery. */\nimport type { ChatHost } from '../../../chat/host/engine'\nimport type { SendOptions } from '../../protocol'\nimport type { HostPeer } from '../peers'\nimport type { Handlers } from './types'\n\ntype ChatMethod\n = | 'chat.send' | 'chat.interrupt' | 'chat.steer' | 'chat.followUp' | 'chat.pushQueued'\n | 'chat.isRunning' | 'chat.rebuildAgent' | 'chat.listWork' | 'chat.cancelWork'\n | 'commands.list' | 'commands.completeArgs'\n\nexport function createChatHandlers({ host, clearDraft }: {\n host: ChatHost\n clearDraft: (sessionId: string, origin: HostPeer | null) => void\n}): Handlers<ChatMethod> {\n return {\n 'chat.send': async (p, peer) => {\n // `wake` is host-internal: a wire peer must not run a session with\n // the `user-prompt` broadcast suppressed (params are unchecked JSON\n // — the Omit<> in the method type is not a runtime guarantee).\n const { wake: _stripped, keepDraft, ...params } = p as SendOptions\n const result = await host.sendPrompt(params)\n // A composer submit consumed the shared draft — clear it everywhere\n // else (the sender's input is already empty; excluding it means a user\n // already typing their NEXT message is never clobbered). A prompt sent\n // from elsewhere (Continue, Retry, the palette) did not.\n if (!keepDraft)\n clearDraft(p.sessionId, peer)\n return result\n },\n 'chat.interrupt': p => host.interrupt(p.sessionId),\n 'chat.steer': p => host.steer(p.sessionId, p.message),\n 'chat.followUp': p => host.followUp(p.sessionId, p.message),\n 'chat.pushQueued': async (p, peer) => {\n const result = await host.pushQueued(p.sessionId, p.message, p.activatedSkills)\n if (!p.keepDraft)\n clearDraft(p.sessionId, peer)\n return result\n },\n 'chat.isRunning': p => host.isSessionRunning(p.sessionId),\n 'chat.rebuildAgent': p => host.disposeAgentForRebuild(p.sessionId),\n 'chat.listWork': p => host.listRunningWork(p.sessionId),\n 'chat.cancelWork': p => host.cancelRunningWork(p.sessionId, p.id, p.reason),\n\n 'commands.list': p => host.listCommands(p.cwd, typeof p.kind === 'string' ? p.kind : undefined),\n 'commands.completeArgs': p => host.completeCommandArgs(p.cwd, p.name, p.argsPrefix, typeof p.kind === 'string' ? p.kind : undefined),\n }\n}\n","/** What a session's model sees: context breakdown and segments, and the session's system prompt override. */\nimport type { ChatHost } from '../../../chat/host/engine'\nimport type { Handlers } from './types'\n\nexport function createContextHandlers({ host }: { host: ChatHost }): Handlers<'sessions.contextBreakdown' | 'sessions.contextSegments' | 'sessions.createSystemOverride' | 'sessions.systemMd'> {\n return {\n 'sessions.systemMd': p => host.sessionSystemMd(p.sessionId),\n 'sessions.contextSegments': p => host.getContextSegments(p.sessionId),\n 'sessions.createSystemOverride': p => host.createSystemOverride(p.sessionId),\n 'sessions.contextBreakdown': p => host.getContextBreakdown(p.sessionId),\n }\n}\n","/** The daemon process itself: identity and shutdown. */\nimport type { ChatHost } from '../../../chat/host/engine'\nimport type { HelloResult } from '../../protocol'\nimport type { Handlers } from './types'\nimport { IPC_PROTOCOL_VERSION } from '../../protocol'\n\nexport function createDaemonHandlers({ host, appVersion, startedAt, lifecycle, identity }: {\n host: ChatHost\n appVersion: string\n startedAt: number\n lifecycle: { shutdown: () => void, retireWhenIdle: () => void }\n /** The host identity fields `ipc.hello` reports. */\n identity: Pick<HelloResult, 'hostId' | 'hostKind' | 'hostName'>\n}): Handlers<'daemon.info' | 'daemon.shutdown'> {\n return {\n 'daemon.info': (): HelloResult => ({\n protocolVersion: IPC_PROTOCOL_VERSION,\n appVersion,\n pid: process.pid,\n startedAt,\n ...identity,\n }),\n 'daemon.shutdown': async (p) => {\n // Version-skew retirement never aborts live work: exit once idle.\n if (p?.whenIdle === true && host.hasActiveWork()) {\n lifecycle.retireWhenIdle()\n return { deferred: true }\n }\n // Reply first (return), then drain on the next tick.\n setImmediate(lifecycle.shutdown)\n },\n }\n}\n","/**\n * Shared per-session composer state: prompt drafts, draft attachments, and\n * transcript-search state, synced across windows. Ephemeral by design —\n * in-memory only, cleared when any window submits, gone on daemon restart.\n */\nimport type { HostSignal, PromptAttachment } from '../../protocol'\nimport type { HostPeer } from '../peers'\nimport type { Handlers } from './types'\n\ninterface DraftEntry { text?: string, shell?: boolean, attachments?: PromptAttachment[], search?: { active: boolean, query: string } }\n\n/**\n * Bound a peer-supplied attachment list: shape-guarded entries only,\n * 24 MiB of base64 per list. Shared by `queue.add` and\n * `drafts.setAttachments`.\n */\nexport function boundAttachments(list: unknown[]): PromptAttachment[] {\n let budget = 24 * 1024 * 1024\n const out: PromptAttachment[] = []\n for (const entry of list) {\n const a = entry as Partial<PromptAttachment>\n if (typeof a?.mediaType !== 'string' || typeof a?.data !== 'string')\n continue\n budget -= a.data.length\n if (budget < 0)\n break\n // Names render in every window's UI — cap them so a hostile peer\n // can't pin megabytes of \"name\" per attachment.\n out.push({ mediaType: a.mediaType, data: a.data, ...(typeof a.name === 'string' ? { name: a.name.slice(0, 256) } : {}) })\n }\n return out\n}\n\nexport function createDraftHandlers({ broadcastExcept }: {\n broadcastExcept: (origin: HostPeer | null, signal: HostSignal) => void\n}): {\n methods: Handlers<'drafts.get' | 'drafts.set' | 'drafts.setAttachments' | 'search.set'>\n /** Consume the draft after a submit — every window except the sender clears. */\n clearDraft: (sessionId: string, origin: HostPeer | null) => void\n /** The session was deleted: drop its draft silently. */\n forget: (sessionId: string) => void\n} {\n /**\n * Shared per-session prompt drafts. Ephemeral by design — in-memory\n * only, cleared when any window submits, gone on daemon restart.\n */\n const drafts = new Map<string, DraftEntry>()\n\n /** Total base64 bytes currently pinned by ALL draft attachments. */\n function draftAttachmentBytes(): number {\n let total = 0\n for (const entry of drafts.values()) {\n for (const attachment of entry.attachments ?? [])\n total += attachment.data.length\n }\n return total\n }\n\n function clearDraft(sessionId: string, origin: HostPeer | null): void {\n const entry = drafts.get(sessionId)\n if (!entry)\n return\n drafts.delete(sessionId)\n if (entry.text)\n broadcastExcept(origin, { kind: 'draft:changed', sessionId, text: '' })\n if (entry.attachments?.length)\n broadcastExcept(origin, { kind: 'draft:attachments', sessionId, attachments: [] })\n }\n\n /** Drop empty draft entries so the map only holds live composing state. */\n function compactDraft(sessionId: string, entry: DraftEntry): void {\n if (!entry.text && !entry.shell && !entry.attachments?.length && !entry.search?.active)\n drafts.delete(sessionId)\n else\n drafts.set(sessionId, entry)\n }\n\n const methods: Handlers<'drafts.get' | 'drafts.set' | 'drafts.setAttachments' | 'search.set'> = {\n 'drafts.get': (p) => {\n const entry = drafts.get(p.sessionId)\n return {\n text: entry?.text ?? '',\n ...(entry?.shell ? { shell: true } : {}),\n ...(entry?.attachments?.length ? { attachments: entry.attachments } : {}),\n ...(entry?.search?.active ? { search: entry.search } : {}),\n }\n },\n 'drafts.set': (p, peer) => {\n // Bound the ephemeral draft store: a buggy/looping client must not\n // grow daemon memory without limit (drafts only evict on submit or\n // session delete). 64 KiB is far above any real prompt.\n const text = typeof p.text === 'string' ? p.text.slice(0, 64 * 1024) : ''\n // When the cap actually truncated, INCLUDE the origin in the fan-out\n // so its local buffer converges to the stored truth — otherwise the\n // origin silently diverges from what every other window (and a\n // remote submit) sees.\n const truncated = typeof p.text === 'string' && p.text.length > text.length\n // Also bound the KEY count: drafts only evict on submit / session\n // delete, so a client writing under many bogus session ids could\n // otherwise grow the map unbounded. 256 concurrent drafts is far\n // beyond any real multi-window session set.\n if (!drafts.has(p.sessionId) && drafts.size >= 256)\n return\n const entry = drafts.get(p.sessionId) ?? {}\n entry.text = text.length > 0 ? text : undefined\n // Shell mode rides out of band — never sniffed from the text.\n entry.shell = p.shell === true ? true : undefined\n compactDraft(p.sessionId, entry)\n broadcastExcept(truncated ? null : peer, { kind: 'draft:changed', sessionId: p.sessionId, text, ...(p.shell === true ? { shell: true } : {}) })\n },\n 'search.set': (p, peer) => {\n // Shared transcript-search state — same lifecycle + caps as drafts.\n const active = p.active === true\n const query = typeof p.query === 'string' ? p.query.slice(0, 4 * 1024) : ''\n if (!drafts.has(p.sessionId) && drafts.size >= 256)\n return\n const entry = drafts.get(p.sessionId) ?? {}\n entry.search = active || query.length > 0 ? { active, query } : undefined\n compactDraft(p.sessionId, entry)\n broadcastExcept(peer, { kind: 'search:changed', sessionId: p.sessionId, active, query })\n },\n 'drafts.setAttachments': (p, peer) => {\n /*\n * Composing attachments (payloads included, so a remote window can\n * submit the shared draft attachments-and-all). Bounded three ways:\n * shape-guarded entries, 24 MiB of base64 per session, and a 96 MiB\n * GLOBAL budget across every draft — the per-session cap times the\n * 256-key cap would otherwise let a looping client pin gigabytes.\n */\n const bounded = Array.isArray(p.attachments) ? boundAttachments(p.attachments) : []\n if (!drafts.has(p.sessionId) && drafts.size >= 256)\n return\n const current = drafts.get(p.sessionId)?.attachments ?? []\n const currentBytes = current.reduce((sum, a) => sum + a.data.length, 0)\n const incomingBytes = bounded.reduce((sum, a) => sum + a.data.length, 0)\n if (draftAttachmentBytes() - currentBytes + incomingBytes > 96 * 1024 * 1024)\n return\n const entry = drafts.get(p.sessionId) ?? {}\n entry.attachments = bounded.length > 0 ? bounded : undefined\n compactDraft(p.sessionId, entry)\n broadcastExcept(peer, { kind: 'draft:attachments', sessionId: p.sessionId, attachments: bounded })\n },\n }\n\n return {\n methods,\n clearDraft,\n forget: (sessionId) => {\n drafts.delete(sessionId)\n },\n }\n}\n","/** Session rows: list, create, delete, and metadata edits (title, archive, agent, model, folder). */\nimport type { ChatHost } from '../../../chat/host/engine'\nimport type { SessionData, SessionStore } from '../../../session/index'\nimport type { CreateSessionParams, HostSignal, IpcParams, SessionRow } from '../../protocol'\nimport type { WorkspaceRoots } from '../workspace-roots'\nimport type { Handlers } from './types'\nimport { STALE_RUN_MARKER_MS } from '../../../chat/host/engine'\nimport { deriveSessionTitle, sessionEnvironmentSummary, sessionModelFallbacks } from '../../../chat/index'\nimport { isMainSession } from '../../../chat/orchestration'\nimport { PINNED_SKILLS_META_KEY, pinnedSkillsValue, readPinnedSkills } from '../../../chat/pinned-skills'\n\ntype SessionMethod\n = | 'sessions.list' | 'sessions.create' | 'sessions.delete' | 'sessions.setTitle' | 'sessions.setArchived'\n | 'sessions.setAgentId' | 'sessions.setEffort' | 'sessions.setModel' | 'sessions.setModelOptions' | 'sessions.setFolder'\n\nexport async function loadOrThrow(store: SessionStore, sessionId: string): Promise<SessionData> {\n const data = await store.load(sessionId)\n if (!data)\n throw new Error(`Session \"${sessionId}\" not found.`)\n return data\n}\n\nexport function createSessionHandlers({ host, store, broadcast, forgetSession, hostId, workspace }: {\n host: ChatHost\n store: SessionStore\n broadcast: (signal: HostSignal) => void\n /** Drop the per-session wire state other handlers keep, before the host deletes the session. */\n forgetSession: (sessionId: string) => void\n /** Stamped on every returned row (`SessionRow.hostId`). */\n hostId: string | undefined\n /** Where session folders may be (a server confines them to its workspace roots). */\n workspace?: WorkspaceRoots\n}): Handlers<SessionMethod> {\n const stamp = (row: SessionRow): SessionRow => hostId ? { ...row, hostId } : row\n /**\n * Apply a metadata-only patch. Prefers the host's live-session path (safe\n * mid-run — routes through the in-memory `Session` whose turns are the\n * source of truth); only falls back to a store-level full-document\n * `save()` when the session is idle, where no run is appending turns so\n * `load → mutate → save` can't drop concurrently-persisted turns.\n *\n * `bumpUpdatedAt: false` skips the recency bump so a rename doesn't yank\n * the row to the top of recency-sorted lists (mirrors the GUI).\n */\n async function patchSessionMeta(\n sessionId: string,\n patch: Record<string, unknown>,\n opts: { bumpUpdatedAt?: boolean } = {},\n ): Promise<void> {\n /*\n * Live path: route through the in-memory `Session` so the full-document\n * save() re-persists the CURRENT turns. `session.save()` bumps\n * `updatedAt` unconditionally, so the rare \"rename during a live run\"\n * case bumps recency — accepted, since avoiding turn loss matters more\n * than recency-order purity on that narrow window.\n */\n await host.patchSessionMeta(sessionId, patch, opts)\n broadcast({ kind: 'sessions:changed', op: 'update', sessionId })\n }\n\n async function patchSession(\n sessionId: string,\n mutate: (data: SessionData) => void,\n ): Promise<void> {\n const data = await loadOrThrow(store, sessionId)\n mutate(data)\n data.updatedAt = Date.now()\n await store.save(data)\n broadcast({ kind: 'sessions:changed', op: 'update', sessionId })\n }\n\n async function createSessionRow(params: CreateSessionParams): Promise<SessionRow> {\n // Creation lives in the host now (shared with the embedded GUI host and\n // orchestration); this adds only the wire row + the change broadcast.\n // Forward the wire fields by name: the host factory also accepts an\n // explicit `id` and raw `metadata`, which a wire client must not set\n // (only the validated keys below).\n const metadata = creationMetadata(params)\n // A machine's folder (`local@<machine>`) is not on this host: the host checks it against the machine's roots instead.\n const onMachine = params.environment?.kind ? host.environments.get(params.environment.kind)?.checkFolder !== undefined : false\n const cwd = workspace?.describe().confined && !onMachine ? workspace.sessionFolder(params.cwd ?? '') : params.cwd\n const id = await host.createSession({\n cwd,\n ...(metadata ? { metadata } : {}),\n ...(params.title ? { title: params.title } : {}),\n ...(params.agentId ? { agentId: params.agentId } : {}),\n ...(params.providerKey && params.modelId ? { providerKey: params.providerKey, modelId: params.modelId } : {}),\n ...(params.fallbacks ? { fallbacks: params.fallbacks } : {}),\n ...(params.extensionEdit ? { extensionEdit: true } : {}),\n ...(params.skillEdit?.name ? { skillEdit: { name: params.skillEdit.name } } : {}),\n ...(params.environment?.kind\n ? {\n environment: {\n kind: params.environment.kind,\n ...(params.environment.branch ? { branch: params.environment.branch } : {}),\n ...(params.environment.base ? { base: params.environment.base } : {}),\n },\n }\n : {}),\n })\n const data = await loadOrThrow(store, id)\n broadcast({ kind: 'sessions:changed', op: 'create', sessionId: id })\n return stamp(toRow(host, data))\n }\n\n return {\n 'sessions.list': async p => (await listSessionRows(host, store, p)).map(stamp),\n 'sessions.create': p => createSessionRow(p),\n 'sessions.delete': async (p) => {\n forgetSession(p.sessionId)\n // Agent retirement + environment + row + on-disk artifacts: the shared host delete.\n const { environment } = await host.deleteSession(p.sessionId)\n broadcast({ kind: 'sessions:changed', op: 'delete', sessionId: p.sessionId })\n return environment.removed && !environment.reason ? {} : { environment }\n },\n // Rename skips the recency bump so it doesn't yank the row to the top\n // of recency-sorted lists (mirrors the GUI).\n 'sessions.setTitle': p => patchSessionMeta(p.sessionId, { title: p.title }, { bumpUpdatedAt: false }),\n 'sessions.setArchived': p => patchSessionMeta(p.sessionId, { archived: p.archived }),\n 'sessions.setAgentId': async (p) => {\n /*\n * `agentId` is a top-level field (not metadata) and rebuilds the\n * agent. Patch the LIVE document when the host holds one — a bare\n * store patch loads a stale copy whose full save would clobber\n * mid-run turn appends, and the untouched live doc would revert the\n * label on its next save. Idle sessions take the store patch (no\n * concurrent writer). Then retire the agent (deferred to run end\n * while running) so a swap doesn't abort a shared run mid-stream.\n */\n if (await host.setLiveSessionAgentId(p.sessionId, p.agentId)) {\n broadcast({ kind: 'sessions:changed', op: 'update', sessionId: p.sessionId })\n }\n else {\n await patchSession(p.sessionId, (d) => {\n d.agentId = p.agentId\n })\n }\n host.disposeAgentForRebuild(p.sessionId)\n },\n 'sessions.setEffort': p => patchSessionMeta(p.sessionId, { effort: p.effort }),\n 'sessions.setModel': async (p) => {\n // The one model-swap contract (`ChatHost.setSessionModel`): patch\n // race-free, replace the chain, reset effort/options, retire the agent\n // (run-end deferred mid-run). Documented in protocol.ts.\n await host.setSessionModel(p.sessionId, {\n providerKey: p.providerKey,\n modelId: p.modelId,\n ...(p.fallbacks ? { fallbacks: p.fallbacks } : {}),\n ...(p.effort ? { effort: p.effort } : {}),\n ...(p.modelOptions ? { modelOptions: p.modelOptions } : {}),\n })\n broadcast({ kind: 'sessions:changed', op: 'update', sessionId: p.sessionId })\n },\n 'sessions.setModelOptions': p => patchSessionMeta(p.sessionId, { modelOptions: p.options }),\n 'sessions.setFolder': (p) => {\n const cwd = typeof p.cwd === 'string' ? p.cwd : ''\n // The host checks it: against this host's roots, or a machine session's machine's (`docs/MACHINES.md` § Folders).\n return host.setSessionFolder(p.sessionId, cwd)\n },\n }\n}\n\n/** The creation-time metadata a client may stamp: the pick's effort and options, pinned skills. */\nfunction creationMetadata(params: CreateSessionParams): Record<string, unknown> | undefined {\n const metadata: Record<string, unknown> = {}\n if (typeof params.effort === 'string')\n metadata.effort = params.effort\n if (params.modelOptions && typeof params.modelOptions === 'object') {\n const options = Object.fromEntries(Object.entries(params.modelOptions).filter(([, on]) => typeof on === 'boolean'))\n if (Object.keys(options).length > 0)\n metadata.modelOptions = options\n }\n if (Array.isArray(params.pinnedSkills)) {\n const pins = readPinnedSkills(params.pinnedSkills.slice(0, 64))\n if (pins.size > 0)\n metadata[PINNED_SKILLS_META_KEY] = pinnedSkillsValue(pins)\n }\n return Object.keys(metadata).length > 0 ? metadata : undefined\n}\n\nasync function listSessionRows(host: ChatHost, store: SessionStore, p: IpcParams<'sessions.list'>): Promise<SessionRow[]> {\n const filter\n = p?.projectRoot !== undefined ? { projectRoot: p.projectRoot as string | null } : undefined\n\n const applyArchive = (rows: SessionRow[]): SessionRow[] => {\n const filtered = rows.filter((row) => {\n if (p?.archive === 'active')\n return !row.archived\n if (p?.archive === 'archived')\n return row.archived\n return true\n })\n filtered.sort((a, b) => b.updatedAt - a.updatedAt)\n return filtered\n }\n\n /*\n * Fast path: `listMeta` returns header rows without materializing\n * turn arrays — O(sessions), not O(total turns). Falls back to the\n * load-per-id path for stores that don't implement it.\n */\n if (store.listMeta) {\n const metas = await store.listMeta(filter)\n return applyArchive(metas.map((meta) => {\n const md = meta.metadata\n // Canonical derivation — the same helper the TUI list uses, so\n // daemon-fed rows can't render a different title for the same\n // session (the hand-rolled fallback had its own truncation).\n const title = deriveSessionTitle(meta.firstUserTurn ? [meta.firstUserTurn] : [], md)\n return {\n id: meta.id,\n title,\n projectRoot: meta.projectRoot ?? null,\n cwd: typeof md.cwd === 'string' ? md.cwd : (meta.projectRoot ?? ''),\n ...(meta.agentId ? { agentId: meta.agentId } : {}),\n // A crashed process's leftover 'running' marker must not render\n // forever — apply the same freshness bound the run guard uses.\n status: host.isSessionRunning(meta.id)\n ? 'running' as const\n : meta.status === 'running' && Date.now() - meta.updatedAt >= STALE_RUN_MARKER_MS\n ? 'idle' as const\n : (meta.status ?? 'idle'),\n createdAt: meta.createdAt ?? 0,\n updatedAt: meta.updatedAt,\n archived: md.archived === true,\n ...(() => {\n const environment = sessionEnvironmentSummary(md)\n return environment ? { environment } : {}\n })(),\n ...(typeof md.providerKey === 'string' ? { providerKey: md.providerKey } : {}),\n ...(typeof md.modelId === 'string' ? { modelId: md.modelId } : {}),\n ...(typeof md.effort === 'string' ? { effort: md.effort as SessionRow['effort'] } : {}),\n ...(md.modelOptions && typeof md.modelOptions === 'object'\n ? { modelOptions: md.modelOptions as Record<string, boolean> }\n : {}),\n ...(() => {\n const fallbacks = sessionModelFallbacks(md)\n return fallbacks ? { modelFallbacks: fallbacks } : {}\n })(),\n }\n }))\n }\n\n const ids = await store.list(filter)\n const rows: SessionRow[] = []\n for (const id of ids) {\n const data = await store.load(id)\n if (!data)\n continue\n rows.push(toRow(host, data))\n }\n return applyArchive(rows)\n}\n\nfunction toRow(host: ChatHost, data: SessionData): SessionRow {\n const meta = data.metadata ?? {}\n // Canonical derivation — same helper as the TUI list (see the\n // listMeta fast path above).\n const title = deriveSessionTitle(data.turns, meta)\n\n return {\n id: data.id,\n title,\n ...(isMainSession(meta) ? { isMain: true } : {}),\n projectRoot: data.projectRoot ?? null,\n cwd: typeof meta.cwd === 'string' ? meta.cwd : (data.projectRoot ?? ''),\n ...(typeof data.agentId === 'string' ? { agentId: data.agentId } : {}),\n status: host.isSessionRunning(data.id)\n ? 'running'\n : data.status === 'running' && Date.now() - data.updatedAt >= STALE_RUN_MARKER_MS\n ? 'idle'\n : data.status,\n createdAt: data.createdAt,\n updatedAt: data.updatedAt,\n archived: meta.archived === true,\n ...(() => {\n const environment = sessionEnvironmentSummary(meta)\n return environment ? { environment } : {}\n })(),\n ...(typeof meta.providerKey === 'string' ? { providerKey: meta.providerKey } : {}),\n ...(typeof meta.modelId === 'string' ? { modelId: meta.modelId } : {}),\n ...(typeof meta.effort === 'string' ? { effort: meta.effort as SessionRow['effort'] } : {}),\n ...(meta.modelOptions && typeof meta.modelOptions === 'object'\n ? { modelOptions: meta.modelOptions as Record<string, boolean> }\n : {}),\n ...(() => {\n const fallbacks = sessionModelFallbacks(meta)\n return fallbacks ? { modelFallbacks: fallbacks } : {}\n })(),\n }\n}\n","/** Execution environments: the catalog, verification, settings, and a session's provisioning and actions. */\nimport type { ChatHost } from '../../../chat/host/engine'\nimport type { HostSettings } from '../../../chat/index'\nimport type { DaemonEnvironment } from '../environment'\nimport type { Handler, Handlers } from './types'\nimport { applyEnvironmentSettingsChange } from '../../../chat/index'\nimport { loadOrThrow } from './sessions'\n\ntype EnvironmentMethod\n = | 'environments.list' | 'environments.verify' | 'environments.update'\n | 'sessions.retryEnvironment' | 'sessions.environmentActions' | 'sessions.runEnvironmentAction'\n\nexport function createEnvironmentHandlers({ host, env, setSettings }: {\n host: ChatHost\n env: DaemonEnvironment\n /** The `settings.set` handler, so an environment edit fans out like any settings edit. */\n setSettings: Handler<'settings.set'>\n}): Handlers<EnvironmentMethod> {\n return {\n 'sessions.retryEnvironment': async (p) => {\n await loadOrThrow(env.store, p.sessionId)\n // Provisioning can take minutes (a sandbox, a clone): respond once the\n // row shows `provisioning` (a poller must not read the old failure) and\n // let `prepare` run in the background, announced as `sessions:changed`.\n await host.retryEnvironment(p.sessionId, { background: true })\n },\n 'sessions.environmentActions': p => host.listEnvironmentActions(p.sessionId),\n 'sessions.runEnvironmentAction': p => host.runEnvironmentAction(p.sessionId, p.actionId),\n 'environments.list': p => host.listEnvironments(p.cwd ?? '', typeof p.kind === 'string' ? p.kind : undefined),\n 'environments.verify': p => host.verifyEnvironment(p.kind),\n 'environments.update': async (p, peer) => {\n const write = applyEnvironmentSettingsChange(host.environments, env.readSettings(), p)\n for (const secret of write.secrets)\n host.environmentSecrets.set(p.kind, secret.key, secret.value)\n // Through `settings.set` so the change fans out (and tears down what a\n // bound key like `sandbox` requires) exactly like any settings edit.\n await setSettings({ patch: write.settingsPatch as Partial<HostSettings> }, peer)\n },\n }\n}\n","/** Extension bus emits from clients whose extensions run client-side. */\nimport type { HostSignal } from '../../protocol'\nimport type { DaemonEnvironment } from '../environment'\nimport type { HostPeer } from '../peers'\nimport type { Handlers } from './types'\nimport { EXTENSION_BUS_MAX_PAYLOAD_BYTES, serializedPayloadBytes } from '../../../extensions/index'\nimport { loadOrThrow } from './sessions'\n\nexport function createExtensionHandlers({ env, broadcastExcept }: {\n env: DaemonEnvironment\n broadcastExcept: (origin: HostPeer | null, signal: HostSignal) => void\n}): Handlers<'extension.emit'> {\n return {\n 'extension.emit': async (p, peer) => {\n /*\n * Extension bus emit from a client whose extensions run client-side\n * (TUI daemon mode). Trust boundary: params are unchecked JSON —\n * same cheap shape guards as `drafts.set`, the payload cap\n * re-enforced daemon-side, and the extension id validated against\n * the session cwd's registry (spoof-resistance: a hand-rolled peer\n * can't ride an id that isn't a loaded, `'ipc'`-permitted extension).\n */\n const extensionId = typeof p.extensionId === 'string' ? p.extensionId : ''\n if (extensionId.length === 0 || extensionId.length > 256)\n return\n if (typeof p.seq !== 'number' || !Number.isFinite(p.seq))\n return\n const sessionId = typeof p.sessionId === 'string' ? p.sessionId : undefined\n const bytes = serializedPayloadBytes(p.payload)\n if (bytes === null || bytes > EXTENSION_BUS_MAX_PAYLOAD_BYTES)\n return\n // Registry for the session's cwd (same derivation as `suggest.resolve`);\n // sessionless emits validate against the boot-config registry.\n let registry = env.config.extensions\n if (sessionId !== undefined) {\n try {\n const data = await loadOrThrow(env.store, sessionId)\n const meta = data.metadata ?? {}\n const cwd = typeof meta.cwd === 'string' ? meta.cwd : (data.projectRoot ?? '')\n registry = (await env.runtimeConfig(cwd)).extensions\n }\n catch {\n return // Unknown session — nothing to validate against, drop.\n }\n }\n const known = registry.loaded.some(ext =>\n !ext.error && ext.name === extensionId && ext.definition?.permissions?.includes('ipc') === true)\n if (!known)\n return\n const nonce = typeof p.nonce === 'string' ? p.nonce : undefined\n const envelope = { extensionId, ...(sessionId !== undefined ? { sessionId } : {}), payload: p.payload, seq: p.seq, ...(nonce !== undefined ? { nonce } : {}) }\n // Daemon-side subscribers first (loopback for extensions living in\n // per-cwd daemon registries), then every OTHER window — the origin\n // already delivered to its local subscribers at emit.\n env.extensionBus?.deliver(envelope)\n broadcastExcept(peer, { kind: 'extension:signal', ...envelope })\n },\n }\n}\n","/** Folder browsing on the host's machine (`fs.roots`, `fs.listDirs`), within its workspace roots. */\nimport type { WorkspaceRoots } from '../workspace-roots'\nimport type { Handlers } from './types'\nimport { optionalString } from './params'\n\nexport function createFsHandlers({ workspace }: { workspace: WorkspaceRoots }): Handlers<'fs.roots' | 'fs.listDirs'> {\n return {\n 'fs.roots': () => workspace.describe(),\n 'fs.listDirs': p => workspace.list(optionalString(p?.path, 'path')),\n }\n}\n","/** Transcript history search, per session and across sessions, over one shared index cache. */\nimport type { ChatHost } from '../../../chat/host/engine'\nimport type { SessionHistoryMatch, SessionSearchIndex } from '../../../chat/index'\nimport type { SessionStore } from '../../../session/index'\nimport type { SessionTurn } from '../../../types'\nimport type { HostPeer } from '../peers'\nimport type { Handlers } from './types'\nimport { buildSessionSearchIndexAsync, searchSessionHistoryIndexAsync, searchSessionIndexAsync } from '../../../chat/index'\n\n/*\n * Daemon-side history search — one index cache shared by EVERY window,\n * so repeat queries (and other windows' queries) pay match cost only.\n * Off the UI thread by construction (this process has no renderer), so\n * no Worker indirection is needed. Live sessions index the host's\n * in-memory turns (fresh mid-run); idle sessions index store turns.\n * LRU-bounded — full-text indexes can reach 512k chars per turn.\n */\nconst SEARCH_INDEX_CACHE_MAX = 64\n\nexport function createHistoryHandlers({ host, store }: {\n host: ChatHost\n store: SessionStore\n}): Handlers<'history.searchSession' | 'history.searchAll'> {\n /** Latest `history.searchAll` generation per peer — see the handler. */\n const searchGenerations = new WeakMap<HostPeer, number>()\n const searchIndexCache = new Map<string, { key: string, index: SessionSearchIndex }>()\n\n async function sessionSearchIndex(sessionId: string): Promise<SessionSearchIndex | null> {\n const liveTurns = host.getLiveTurns(sessionId)\n let turns: readonly SessionTurn[]\n let key: string\n if (liveTurns) {\n /*\n * SNAPSHOT before the async index build — the agent may append\n * mid-build and the builder yields between turns. The cache key\n * folds in the last turn id so a same-count content change (e.g.\n * compaction replacing turns) can't serve a stale index.\n */\n turns = [...liveTurns]\n key = `live:${turns.length}:${turns.at(-1)?.id ?? ''}`\n }\n else {\n const data = await store.load(sessionId)\n if (!data)\n return null\n turns = data.turns\n key = `store:${data.updatedAt}:${data.turns.length}`\n }\n\n const cached = searchIndexCache.get(sessionId)\n if (cached?.key === key) {\n // Refresh LRU recency (Map preserves insertion order).\n searchIndexCache.delete(sessionId)\n searchIndexCache.set(sessionId, cached)\n return cached.index\n }\n\n const index = await buildSessionSearchIndexAsync(turns)\n searchIndexCache.set(sessionId, { key, index })\n while (searchIndexCache.size > SEARCH_INDEX_CACHE_MAX) {\n const oldest = searchIndexCache.keys().next().value\n if (oldest === undefined)\n break\n searchIndexCache.delete(oldest)\n }\n return index\n }\n\n return {\n 'history.searchSession': async (p) => {\n const index = await sessionSearchIndex(p.sessionId)\n if (!index)\n return []\n // Wire-supplied limit: unchecked JSON — coerce to a sane positive\n // integer bounded by the corpus (same policy as queue/draft bounds).\n const limit = Number.isInteger(p.limit) && (p.limit as number) > 0\n ? Math.min(p.limit as number, index.turns.length)\n : index.turns.length\n const matches = await searchSessionIndexAsync(index, p.query, { limit })\n // Turn order, not relevance — search is a transcript filter, and\n // sorting here spares clients from re-fetching the turn list.\n const order = new Map(index.turns.map((entry, i) => [entry.turn.id, i]))\n matches.sort((a, b) => (order.get(a.turn.id) ?? 0) - (order.get(b.turn.id) ?? 0))\n return matches\n },\n 'history.searchAll': async (p, peer) => {\n /*\n * Per-peer supersession: search fires per debounced keystroke and\n * the client discards stale responses, but without this the daemon\n * would still run every superseded full-corpus pass to completion —\n * stacked CPU that delays signal fan-out for every window. A newer\n * query from the same peer makes older loops bail at the next\n * session boundary (partial result; the client ignores it anyway).\n */\n const generation = (searchGenerations.get(peer) ?? 0) + 1\n searchGenerations.set(peer, generation)\n\n const results: Record<string, SessionHistoryMatch> = {}\n // Bound the per-request corpus: `store.load` materializes full turn\n // arrays, and supersession only cancels SAME-peer re-queries — one\n // oversized request must not run the shared daemon to completion.\n const ids = Array.isArray(p.sessionIds) ? p.sessionIds.slice(0, 500) : []\n for (const sessionId of ids) {\n if (searchGenerations.get(peer) !== generation)\n break\n try {\n const index = await sessionSearchIndex(sessionId)\n if (!index)\n continue\n const match = await searchSessionHistoryIndexAsync(index, p.query, p.excerptLimit ?? 3)\n if (match)\n results[sessionId] = match\n }\n catch {\n // One bad session must not sink the whole cross-session search.\n }\n }\n return results\n },\n }\n}\n","/** Human-in-the-loop: tool approvals and interactions (questions, plans) awaiting an answer. */\nimport type { ChatHost } from '../../../chat/host/engine'\nimport type { Handlers } from './types'\n\ntype HitlMethod\n = | 'interactions.list' | 'interactions.respond' | 'interactions.cancel' | 'interactions.rehydrate'\n | 'approvals.resolve' | 'approvals.denyAll' | 'approvals.listPending'\n\nexport function createHitlHandlers({ host }: { host: ChatHost }): Handlers<HitlMethod> {\n return {\n 'interactions.list': p => host.interactions.list(p?.sessionId),\n 'interactions.respond': p => host.interactions.respond(p.requestId, p.response),\n 'interactions.cancel': p => host.interactions.cancel(p.requestId, p.reason),\n 'interactions.rehydrate': p => host.interactions.rehydrate(p.sessionId),\n\n 'approvals.resolve': p => host.approvals.resolve(p.requestId, p.decision),\n 'approvals.denyAll': p => host.approvals.denyAll(p?.sessionId),\n 'approvals.listPending': () => host.approvals.listPending(),\n }\n}\n","/** Per-client launch overrides: each window's own, the latest connected setter's applied. */\nimport type { ChatHost } from '../../../chat/host/engine'\nimport type { SessionLaunchOverrides } from '../../../chat/host/launch-overrides'\nimport type { HostPeer } from '../peers'\nimport type { Handlers } from './types'\nimport { normalizeLaunchOverrides } from '../../../chat/host/launch-overrides'\n\n/**\n * A confined host (a server) drops a `cwd` outside its workspace roots\n * itself (`ChatHost.setLaunchOverrides`): a window's own folder is a path on\n * ITS machine, which the session must not move to.\n */\nexport function createLaunchOverrideHandlers({ host }: { host: ChatHost }): {\n methods: Handlers<'sessions.setLaunchOverrides'>\n /** The peer dropped: forget its overrides, so the previous setter's apply again. */\n releasePeer: (peer: HostPeer) => void\n /** The session was deleted: forget every setter's overrides. */\n forget: (sessionId: string) => void\n} {\n /**\n * Each client's launch overrides per session, oldest setter first. The\n * session runs the most recent connected setter's; a client clearing, or\n * disconnecting, drops only its own, and the previous setter's apply again.\n */\n const launchOverridesByPeer = new Map<string, Map<HostPeer, SessionLaunchOverrides>>()\n\n /** Run the latest connected setter's overrides (see `launchOverridesByPeer`). */\n const applyLaunchOverrides = (sessionId: string): void => {\n const setters = launchOverridesByPeer.get(sessionId)\n const latest = setters ? [...setters.values()].at(-1) : undefined\n if (!latest)\n launchOverridesByPeer.delete(sessionId)\n host.setLaunchOverrides(sessionId, latest ?? null)\n }\n\n return {\n methods: {\n 'sessions.setLaunchOverrides': (p, peer) => {\n const { sessionId, ...rest } = p\n const next = normalizeLaunchOverrides(rest)\n const setters = launchOverridesByPeer.get(sessionId) ?? new Map<HostPeer, SessionLaunchOverrides>()\n // Re-inserted, so a client setting again becomes the latest setter.\n setters.delete(peer)\n if (next)\n setters.set(peer, next)\n launchOverridesByPeer.set(sessionId, setters)\n applyLaunchOverrides(sessionId)\n },\n },\n releasePeer(peer) {\n for (const [sessionId, setters] of launchOverridesByPeer) {\n if (setters.delete(peer))\n applyLaunchOverrides(sessionId)\n }\n },\n forget(sessionId) {\n launchOverridesByPeer.delete(sessionId)\n },\n }\n}\n","/**\n * Reverse direction (`docs/MACHINES.md` § Reverse direction): this server\n * lends itself as a machine to a client's host over that client's own\n * connection, because a local host (a laptop) has no listener to be dialed.\n * The client sends `machine.attach`, then one `machine.call` per\n * host→machine request; the server's confined executor\n * (`../../machine/executor`, loaded on first attach) answers them inside the\n * server's workspace roots. Machine notifications go back to that connection\n * only, as `machine:notification` signals.\n *\n * Off unless the server allows it (`allowAsMachine`). It does not widen what a\n * client token can do: `sessions.workspaceExec` and terminals already run\n * commands in the same roots with the same token.\n */\nimport type { ChatHost } from '../../../chat/host/engine'\nimport type { MachineRegisterParams } from '../../../chat/machine-protocol'\nimport type { LooseSandboxSettings } from '../../../chat/sandbox-settings'\nimport type { JsonValue } from '../../../types'\nimport type { MachineExecutor } from '../../machine/executor'\nimport type { HostPeer } from '../peers'\nimport type { Handlers } from './types'\nimport { join } from 'node:path'\nimport { MACHINE_PROTOCOL_VERSION, MachineErrorCode, toMachineName } from '../../../chat/machine-protocol'\nimport { ZIDANE_VERSION } from '../../../version'\n\n/**\n * Executors kept between their connections (tasks, terminals), keyed by the\n * token that attached them and the host id it named: a host id is the\n * client's word, so another token naming it gets an executor of its own,\n * never the first one's tasks, terminals or exits. Each token holds at most\n * {@link MAX_PER_PRINCIPAL} and evicts only its own idle ones.\n */\nconst MAX_PER_PRINCIPAL = 4\nconst MAX_ATTACHED_HOSTS = 32\n\nexport interface MachineServeOptions {\n /** `allowAsMachine`: read per attach, so a restart is not needed to turn it off for new links. */\n allowed: () => boolean\n}\n\nclass MachineServeError extends Error {\n readonly code: number = MachineErrorCode.MethodNotAllowed\n}\n\n/** A capacity limit: the client retries later (`../../machine/reverse.ts`). */\nclass MachineServeBusyError extends MachineServeError {\n override readonly code: number = MachineErrorCode.Busy\n}\n\ninterface Served {\n executor: MachineExecutor\n peer: HostPeer | null\n principal: string\n}\n\n/** Who attached: the token's id (`''` on a host without auth, a loopback test server). */\nconst principalOf = (peer: HostPeer): string => peer.principal ?? ''\n\nexport function createMachineServeHandlers(input: {\n host: ChatHost\n dataDir: () => string\n hostName: string\n settings: () => LooseSandboxSettings\n options?: MachineServeOptions\n isConnected: (peer: HostPeer) => boolean\n}): { methods: Handlers<'machine.attach' | 'machine.call' | 'machine.detach'>, releasePeer: (peer: HostPeer) => void, allowed: () => boolean } {\n const { host } = input\n const allowed = (): boolean => input.options?.allowed() === true\n const served = new Map<string, Served>()\n const byPeer = new Map<HostPeer, string>()\n\n const roots = (): string[] => {\n const { roots: list, confined } = host.workspace\n if (!confined || list.length === 0)\n throw new MachineServeError('This host has no workspace roots to lend.')\n return [...list]\n }\n\n /** Make room for one more of `principal`'s: its own idle executor goes, never another token's. */\n const makeRoom = (principal: string): void => {\n const own = [...served].filter(([, entry]) => entry.principal === principal)\n if (own.length < MAX_PER_PRINCIPAL && served.size < MAX_ATTACHED_HOSTS)\n return\n const idle = own.find(([, entry]) => entry.peer === null)\n if (!idle)\n throw new MachineServeBusyError(own.length >= MAX_PER_PRINCIPAL ? `This token already has ${MAX_PER_PRINCIPAL} hosts attached here.` : `This server already lends itself to ${MAX_ATTACHED_HOSTS} hosts.`)\n served.delete(idle[0])\n void idle[1].executor.close()\n }\n\n async function executorFor(hostId: string, peer: HostPeer): Promise<MachineExecutor> {\n const principal = principalOf(peer)\n const key = `${principal}:${hostId}`\n const existing = served.get(key)\n if (existing) {\n const previous = existing.peer\n if (previous && previous !== peer)\n byPeer.delete(previous)\n existing.peer = peer\n return existing.executor\n }\n makeRoom(principal)\n const { createMachineExecutor } = await import('../../machine/executor')\n const entry: Served = { peer, principal, executor: undefined as unknown as MachineExecutor }\n entry.executor = createMachineExecutor({\n roots: roots().map(path => ({ path })),\n dataDir: join(input.dataDir(), 'machine-self'),\n // The server's own sandbox settings apply to what it runs as a machine, as to its own sessions.\n sandbox: input.settings(),\n credentialsDataDir: input.dataDir(),\n notify: (method, params) => {\n const target = entry.peer\n if (!target || !input.isConnected(target))\n return false\n target.send({ kind: 'machine:notification', method, params: params as JsonValue })\n return true\n },\n })\n served.set(key, entry)\n return entry.executor\n }\n\n const attachedOf = (peer: HostPeer): Served => {\n const key = byPeer.get(peer)\n const entry = key ? served.get(key) : undefined\n if (!entry || entry.peer !== peer)\n throw new MachineServeError('Send machine.attach first on this connection.')\n return entry\n }\n\n return {\n allowed,\n methods: {\n 'machine.attach': async (p, peer) => {\n if (!allowed())\n throw new MachineServeError('This server does not lend itself as a machine (allowAsMachine is off).')\n if (typeof p.hostId !== 'string' || !/^[\\w-]{1,64}$/.test(p.hostId))\n throw new MachineServeError('machine.attach: \"hostId\" must be 1 to 64 letters, digits, \"-\" or \"_\".')\n const executor = await executorFor(p.hostId, peer)\n byPeer.set(peer, `${principalOf(peer)}:${p.hostId}`)\n executor.linkUp()\n const { machineIdentity } = await import('../../machine/identity')\n const result: MachineRegisterParams = {\n machineId: machineIdentity(join(input.dataDir(), 'machine-self')),\n name: toMachineName(input.hostName),\n roots: roots().map(path => ({ path })),\n capabilities: { shell: true, terminals: typeof (globalThis as { Bun?: unknown }).Bun !== 'undefined', background: true, worktrees: true, stream: true, sandboxed: executor.sandbox.on },\n version: ZIDANE_VERSION,\n protocolVersion: MACHINE_PROTOCOL_VERSION,\n }\n return result\n },\n 'machine.call': async (p, peer) => {\n if (!allowed())\n throw new MachineServeError('This server does not lend itself as a machine (allowAsMachine is off).')\n if (typeof p.method !== 'string')\n throw new MachineServeError('machine.call: \"method\" must be a string.')\n return (await attachedOf(peer).executor.handle(p.method, p.params ?? {})) as JsonValue\n },\n 'machine.detach': (_p, peer) => {\n const key = byPeer.get(peer)\n if (!key)\n return { detached: false }\n byPeer.delete(peer)\n const entry = served.get(key)\n if (entry?.peer === peer) {\n entry.peer = null\n entry.executor.linkLost()\n }\n return { detached: true }\n },\n },\n releasePeer(peer) {\n const key = byPeer.get(peer)\n if (!key)\n return\n byPeer.delete(peer)\n const entry = served.get(key)\n if (entry?.peer === peer) {\n entry.peer = null\n entry.executor.linkLost()\n }\n },\n }\n}\n","/**\n * OAuth sign-in over the wire (`auth.oauth.*`): the browser on the client,\n * the tokens on the host.\n *\n * `begin` runs the login HERE (a provider's `runOAuthLogin`, an MCP server's\n * `loginMcpServer`), so the PKCE verifier, `state` and the token exchange\n * never leave the host, and answers with the authorization URL as soon as\n * the login produces it. The redirect lands on the client's loopback (a\n * provider's fixed `redirect_uri`, or the loopback URI the client chose for\n * an MCP server); the client sends the code back with `complete`, which\n * checks `state` here and hands the code to the waiting login: zidane's\n * providers read it through their manual-input path (`callbackServer:\n * false`: nothing listens on this machine), an MCP login through an\n * injected callback. Paste-back and device-code flows ride the same calls.\n *\n * A provider's questions (a choice between flows, a free-text prompt) are\n * the client's to answer, never picked here: `begin` answers with a `step`\n * when one comes before the URL, `complete` when one comes after, and\n * `respond` delivers the answer. A provider that would listen on this\n * machine for the redirect (one that ignores `callbackServer: false`) is\n * refused: the client's browser could never reach that port.\n *\n * A flow is bound to the connection that began it, takes one code, and\n * expires; a dropped connection abandons its flows. Codes and tokens are\n * never logged nor returned.\n */\nimport type { ChatHost } from '../../../chat/host/engine'\nimport type { McpServerConfig } from '../../../types'\nimport type { HostOAuthBegin, HostOAuthComplete, HostOAuthStep } from '../../protocol'\nimport type { DaemonEnvironment } from '../environment'\nimport type { HostPeer } from '../peers'\nimport type { ProviderAuth } from './auth'\nimport type { Handlers } from './types'\nimport { randomBytes } from 'node:crypto'\nimport { setProviderCredential } from '../../../chat/credentials'\nimport { createFileMcpCredentialStore } from '../../../chat/mcp-credentials'\nimport { discoverProjectMcps } from '../../../chat/mcps-discovery'\nimport { runOAuthLogin } from '../../../chat/oauth'\nimport { canSignInRemotely } from '../../../chat/oauth-page/server'\nimport { loginMcpServer } from '../../../mcp/login'\nimport { catalogFolder } from './catalogs'\nimport { InvalidParamsError } from './params'\n\n/** How long a flow waits for its code. */\nexport const OAUTH_FLOW_TTL_MS = 10 * 60_000\n/** Open flows per connection. */\nconst MAX_FLOWS_PER_PEER = 4\n/** How long a login may take to produce its URL. */\nconst BEGIN_TIMEOUT_MS = 30_000\n\ntype Delivery = { code: string, state?: string } | { input: string }\n\ninterface Flow {\n id: string\n peer: HostPeer\n expiresAt: number\n /** The `state` the authorization URL carries; a code must come back with it. */\n expectedState?: string\n /** Where the browser is sent back (rebuilds a callback URL from a code + state). */\n redirectUri?: string\n delivered: boolean\n deliver: (delivery: Delivery) => void\n result: Promise<HostOAuthComplete>\n abort: AbortController\n timer: ReturnType<typeof setTimeout>\n /** The provider's questions (absent: an MCP sign-in, which asks none). */\n steps?: StepChannel\n /** Where the flow stands for `respond`: its URL once known. */\n started?: Promise<Omit<HostOAuthBegin, 'flowId' | 'expiresAt'>>\n /** Set once the URL was handed out: later questions come through `complete`. */\n begun?: Omit<HostOAuthBegin, 'flowId' | 'expiresAt'>\n}\n\ntype StepInput = { kind: 'select', message: string, options: Array<{ id: string, label: string }> } | { kind: 'prompt', message: string, placeholder?: string, allowEmpty?: boolean }\n\n/** A provider's questions, one at a time: asked by its login, answered by the client. */\ninterface StepChannel {\n ask: (step: StepInput) => Promise<string | undefined>\n /** The question waiting for its answer. */\n pending: () => HostOAuthStep | undefined\n /** The next question (the pending one, if any). */\n next: () => Promise<HostOAuthStep>\n answer: (stepId: string, value: string | undefined) => void\n}\n\nfunction stepChannel(signal: AbortSignal): StepChannel {\n let current: { step: HostOAuthStep, resolve: (value: string | undefined) => void } | undefined\n const waiters: Array<(step: HostOAuthStep) => void> = []\n return {\n ask: step => new Promise((resolve, reject) => {\n if (signal.aborted)\n return reject(new Error('The sign-in was cancelled.'))\n const full = { ...step, id: randomBytes(9).toString('base64url') } as HostOAuthStep\n current = { step: full, resolve }\n signal.addEventListener('abort', () => reject(new Error('The sign-in was cancelled.')), { once: true })\n for (const waiter of waiters.splice(0))\n waiter(full)\n }),\n pending: () => current?.step,\n next: () => (current ? Promise.resolve(current.step) : new Promise(resolve => waiters.push(resolve))),\n answer(stepId, value) {\n const step = current?.step\n if (!step || step.id !== stepId)\n throw new Error('That sign-in is not waiting on this question (answered already, or another one).')\n if (step.kind === 'select' && value !== undefined && !step.options.some(option => option.id === value))\n throw new InvalidParamsError(`\"${value}\" is not one of the choices.`)\n if (step.kind === 'prompt' && (value === undefined || (value.trim() === '' && !step.allowEmpty)))\n throw new InvalidParamsError('That question needs an answer.')\n const { resolve } = current!\n current = undefined\n resolve(value)\n },\n }\n}\n\ninterface Deferred<T> {\n promise: Promise<T>\n resolve: (value: T) => void\n}\n\nfunction deferred<T>(): Deferred<T> {\n let resolve!: (value: T) => void\n const promise = new Promise<T>((r) => {\n resolve = r\n })\n return { promise, resolve }\n}\n\nconst LOOPBACK_HOSTS = new Set(['127.0.0.1', 'localhost', '[::1]', '::1'])\n\n/** `http://<loopback>:<port>/<path>`, nothing else: where an MCP sign-in may send the browser. */\nfunction loopbackRedirect(raw: unknown): string {\n let url: URL | undefined\n try {\n url = typeof raw === 'string' ? new URL(raw) : undefined\n }\n catch {}\n if (!url || url.protocol !== 'http:' || !LOOPBACK_HOSTS.has(url.hostname) || !url.port || url.username || url.password || url.search || url.hash)\n throw new InvalidParamsError('redirectUri must be a loopback URL on the client (http://127.0.0.1:<port>/callback).')\n return url.toString()\n}\n\n/** `state` in what a user pasted: a callback URL, a `code=…&state=…` query, or Anthropic's `code#state`. */\nfunction stateIn(input: string): string | undefined {\n const value = input.trim()\n try {\n return new URL(value).searchParams.get('state') ?? undefined\n }\n catch {}\n if (value.includes('#'))\n return value.split('#', 2)[1]\n if (value.includes('state='))\n return new URLSearchParams(value).get('state') ?? undefined\n return undefined\n}\n\n/** The code in a pasted callback URL / query / `code#state`. */\nfunction codeIn(input: string): string | undefined {\n const value = input.trim()\n try {\n return new URL(value).searchParams.get('code') ?? undefined\n }\n catch {}\n if (value.includes('#'))\n return value.split('#', 2)[0]\n if (value.includes('code='))\n return new URLSearchParams(value).get('code') ?? undefined\n return value || undefined\n}\n\nfunction isLoopbackUrl(raw: string | null): raw is string {\n if (!raw)\n return false\n try {\n const url = new URL(raw)\n return url.protocol === 'http:' && LOOPBACK_HOSTS.has(url.hostname)\n }\n catch {\n return false\n }\n}\n\n/** What a provider's manual-input path reads: the pasted text, or the callback URL rebuilt from a code + state. */\nfunction manualInput(delivery: Delivery, redirectUri: string | undefined): string {\n if ('input' in delivery)\n return delivery.input\n const query = new URLSearchParams({ code: delivery.code, ...(delivery.state !== undefined ? { state: delivery.state } : {}) }).toString()\n return redirectUri ? `${redirectUri}?${query}` : query\n}\n\n/** First of: what the login produced, its early end, a timeout, the abort. */\nasync function firstOf<T>(started: Promise<T>, login: Promise<unknown>, signal: AbortSignal): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined\n try {\n return await Promise.race([\n started,\n login.then(() => {\n throw new Error('The sign-in finished without a browser step (already signed in?).')\n }),\n new Promise<never>((_, reject) => {\n timer = setTimeout(reject, BEGIN_TIMEOUT_MS, new Error(`The sign-in did not produce an authorization URL within ${BEGIN_TIMEOUT_MS / 1000}s.`))\n signal.addEventListener('abort', () => reject(new Error('The sign-in was cancelled.')), { once: true })\n }),\n ])\n }\n finally {\n clearTimeout(timer)\n }\n}\n\n/**\n * A provider's login, running here for a client: its URL (once known), its\n * questions, the code the client delivers, its stored result. Refused for a\n * provider that would listen on this machine (see the module header).\n */\nfunction startProviderLogin(auth: ProviderAuth, provider: unknown) {\n const descriptor = auth.descriptorOf(provider)\n if (!descriptor.oauthProvider)\n throw new Error(`OAuth not supported for ${descriptor.label} (${descriptor.key}). Use an API key instead.`)\n if (!canSignInRemotely(descriptor.oauthProvider))\n throw new Error(`${descriptor.label}'s sign-in can't run from another computer: it waits for the browser on a port of the server's own machine. Sign in on the server machine or use an API key.`)\n const abort = new AbortController()\n const code = deferred<string>()\n const steps = stepChannel(abort.signal)\n const url = deferred<{ url: string, instructions?: string, userCode?: string, device?: true }>()\n const login = runOAuthLogin(descriptor, {\n onUrl: (u, instructions) => url.resolve({ url: u, ...(instructions ? { instructions } : {}) }),\n onDeviceCode: info => url.resolve({ url: info.verificationUri, userCode: info.userCode, device: true }),\n // The loopback's callback URL, or what the user pasted.\n onManualCodeInput: () => code.promise,\n // The provider's own questions go to the client (never answered here).\n onPrompt: prompt => steps.ask({ kind: 'prompt', message: prompt.message, ...(prompt.placeholder ? { placeholder: prompt.placeholder } : {}), ...(prompt.allowEmpty ? { allowEmpty: true } : {}) }).then(value => value ?? ''),\n onSelect: prompt => steps.ask({ kind: 'select', message: prompt.message, options: prompt.options.map(option => ({ id: option.id, label: option.label })) }),\n signal: abort.signal,\n callbackServer: false,\n openBrowser: false,\n })\n login.catch(() => undefined)\n // Where the flow stands once it has its URL (the loopback redirect the code is rebuilt for).\n let redirectUri: string | undefined\n const started = url.promise.then((first): Omit<HostOAuthBegin, 'flowId' | 'expiresAt'> => {\n if (!first.device) {\n const redirect = new URL(first.url).searchParams.get('redirect_uri')\n if (isLoopbackUrl(redirect))\n redirectUri = redirect\n }\n return {\n url: first.url,\n mode: first.device ? 'device' : redirectUri ? 'loopback' : 'browser',\n ...(redirectUri ? { redirectUri } : {}),\n ...(first.userCode ? { userCode: first.userCode } : {}),\n ...(first.instructions ? { instructions: first.instructions } : {}),\n }\n })\n started.catch(() => undefined)\n const result = login.then((credentials): HostOAuthComplete => {\n setProviderCredential(auth.dataDir(), descriptor, { kind: 'oauth', ...credentials })\n auth.applied(descriptor)\n return { provider: auth.statusOf(descriptor.key) }\n })\n return { login, abort, result, steps, started, deliver: (delivery: Delivery) => code.resolve(manualInput(delivery, redirectUri)) }\n}\n\n/** The flow `flowId` names, if it exists and belongs to this connection. */\nfunction flowOf(flows: ReadonlyMap<string, Flow>, flowId: unknown, peer: HostPeer): Flow {\n const flow = typeof flowId === 'string' ? flows.get(flowId) : undefined\n if (!flow)\n throw new Error('No sign-in with that id: it finished, expired or was cancelled. Start it again.')\n if (flow.peer !== peer)\n throw new Error('That sign-in belongs to another connection.')\n return flow\n}\n\n/** Hand the flow its code (from the client's loopback) or pasted input, once, after checking its `state`. */\nfunction deliverCode(flow: Flow, p: { code?: unknown, state?: unknown, input?: unknown }, end: (flow: Flow, reason: string) => void): void {\n const code = typeof p.code === 'string' && p.code !== '' ? p.code : undefined\n const input = typeof p.input === 'string' && p.input.trim() !== '' ? p.input : undefined\n if (code === undefined && input === undefined)\n return\n if (flow.delivered)\n throw new Error('That sign-in already received its code.')\n const state = code !== undefined ? (typeof p.state === 'string' ? p.state : undefined) : stateIn(input!)\n // A code from the loopback must carry the flow's state; a pasted bare code (Anthropic's page) may omit it.\n if (flow.expectedState !== undefined && (state !== undefined || code !== undefined) && state !== flow.expectedState) {\n end(flow, 'OAuth state mismatch.')\n throw new Error('OAuth state mismatch: the sign-in was refused. Start it again.')\n }\n flow.delivered = true\n flow.deliver(code !== undefined ? { code, ...(state !== undefined ? { state } : {}) } : { input: input! })\n}\n\nexport function createOAuthFlowHandlers({ host, env, auth, isConnected, ttlMs = OAUTH_FLOW_TTL_MS }: {\n host: Pick<ChatHost, 'resolveFolder' | 'rebuildAllAgents'>\n env: DaemonEnvironment\n auth: ProviderAuth\n isConnected: (peer: HostPeer) => boolean\n ttlMs?: number\n}): {\n methods: Handlers<'auth.oauth.begin' | 'auth.oauth.complete' | 'auth.oauth.respond' | 'auth.oauth.cancel'>\n releasePeer: (peer: HostPeer) => void\n} {\n const flows = new Map<string, Flow>()\n\n const end = (flow: Flow, reason: string): void => {\n clearTimeout(flow.timer)\n flows.delete(flow.id)\n if (!flow.abort.signal.aborted)\n flow.abort.abort(new Error(reason))\n }\n\n /** Register a flow whose login is already running; it ends at expiry, on cancel, or once settled and collected. */\n function register(peer: HostPeer, parts: { abort: AbortController, deliver: Flow['deliver'], result: Promise<HostOAuthComplete>, expectedState?: string, redirectUri?: string, steps?: StepChannel, started?: Flow['started'] }): Flow {\n const id = randomBytes(24).toString('base64url')\n const flow: Flow = {\n id,\n peer,\n expiresAt: Date.now() + ttlMs,\n delivered: false,\n ...parts,\n timer: undefined as unknown as ReturnType<typeof setTimeout>,\n }\n flow.timer = setTimeout(end, ttlMs, flow, 'The sign-in expired.')\n flow.timer.unref?.()\n // Nobody may be waiting on it (expired, abandoned): never an unhandled rejection.\n flow.result.catch(() => undefined)\n flows.set(id, flow)\n return flow\n }\n\n const ownFlows = (peer: HostPeer): Flow[] => [...flows.values()].filter(flow => flow.peer === peer)\n /** MCP begins in flight per connection: counted against the cap before their flow registers. */\n const startingMcp = new Map<HostPeer, number>()\n\n async function beginProvider(peer: HostPeer, provider: unknown): Promise<HostOAuthBegin> {\n const { login, ...parts } = startProviderLogin(auth, provider)\n const flow = register(peer, parts)\n try {\n return await stateOf(flow, login)\n }\n catch (err) {\n end(flow, 'The sign-in did not start.')\n throw err\n }\n }\n\n /** The flow's URL, or the question it waits on first; its `state` and redirect recorded once the URL is known. */\n async function stateOf(flow: Flow, login: Promise<unknown>): Promise<HostOAuthBegin> {\n const steps = flow.steps!\n const next = await firstOf<{ step: HostOAuthStep } | { begin: Omit<HostOAuthBegin, 'flowId' | 'expiresAt'> }>(\n Promise.race([flow.started!.then(begin => ({ begin })), steps.next().then(step => ({ step }))]),\n login,\n flow.abort.signal,\n )\n if ('step' in next)\n return { flowId: flow.id, url: '', mode: 'step', step: next.step, expiresAt: flow.expiresAt }\n const begin = next.begin\n flow.begun = begin\n if (begin.mode !== 'device') {\n const authorize = new URL(begin.url)\n flow.expectedState = authorize.searchParams.get('state') ?? undefined\n if (begin.redirectUri)\n flow.redirectUri = begin.redirectUri\n }\n return { flowId: flow.id, ...begin, expiresAt: flow.expiresAt }\n }\n\n async function beginMcp(peer: HostPeer, p: { mcpServer: string, cwd?: string, kind?: string, redirectUri?: string }): Promise<HostOAuthBegin> {\n const redirectUri = loopbackRedirect(p.redirectUri)\n const dir = catalogFolder({ env, host }, p.cwd, p.kind)\n const config = await env.runtimeConfig(dir)\n const settings = env.readSettings()\n const { servers } = discoverProjectMcps({ cwd: dir, prefix: config.prefix, foreignAgents: settings.importForeignConfigs === true, ruler: settings.importRulerConfigs !== false })\n const entry: McpServerConfig | undefined = servers.find(server => server.config.name === p.mcpServer)?.config\n if (!entry)\n throw new Error(`No MCP server \"${p.mcpServer}\" in that folder's catalog.`)\n const abort = new AbortController()\n const state = randomBytes(24).toString('base64url')\n const callbackCode = deferred<{ code: string, state?: string }>()\n const started = deferred<{ url: string }>()\n const login = loginMcpServer(entry, {\n store: env.mcpCredentialStore?.() ?? createFileMcpCredentialStore(env.userDataDir()),\n signal: abort.signal,\n state,\n timeoutMs: ttlMs,\n // The client's loopback; the code comes back through `complete`.\n callback: { redirectUri, promise: callbackCode.promise, close: async () => undefined },\n onAuthorizationUrl: url => started.resolve({ url: url.toString() }),\n })\n login.catch(() => undefined)\n const first = await firstOf(started.promise, login, abort.signal).catch((err) => {\n abort.abort()\n throw err\n })\n const result = login.then(() => {\n void host.rebuildAllAgents({ rediscover: true }).catch(() => undefined)\n return { mcpServer: entry.name }\n })\n const flow = register(peer, {\n abort,\n result,\n expectedState: state,\n redirectUri,\n deliver: (delivery) => {\n if ('input' in delivery) {\n const code = codeIn(delivery.input)\n const pastedState = stateIn(delivery.input)\n if (code)\n callbackCode.resolve({ code, ...(pastedState !== undefined ? { state: pastedState } : {}) })\n return\n }\n callbackCode.resolve(delivery)\n },\n })\n return { flowId: flow.id, url: first.url, mode: 'loopback', redirectUri, expiresAt: flow.expiresAt }\n }\n\n return {\n methods: {\n 'auth.oauth.begin': async (p, peer) => {\n const target = [p.provider, p.mcpServer].filter(value => value !== undefined)\n if (target.length !== 1 || typeof target[0] !== 'string' || target[0] === '')\n throw new InvalidParamsError('auth.oauth.begin needs exactly one of \"provider\" or \"mcpServer\".')\n if (ownFlows(peer).length + (startingMcp.get(peer) ?? 0) >= MAX_FLOWS_PER_PEER)\n throw new Error(`This connection already has ${MAX_FLOWS_PER_PEER} sign-ins open: finish or cancel one first.`)\n let begun: HostOAuthBegin\n if (p.provider !== undefined) {\n begun = await beginProvider(peer, p.provider)\n }\n else {\n // An MCP flow registers only once its URL is known; hold its slot meanwhile.\n startingMcp.set(peer, (startingMcp.get(peer) ?? 0) + 1)\n try {\n begun = await beginMcp(peer, { mcpServer: p.mcpServer!, ...(p.cwd !== undefined ? { cwd: p.cwd } : {}), ...(p.kind !== undefined ? { kind: p.kind } : {}), ...(p.redirectUri !== undefined ? { redirectUri: p.redirectUri } : {}) })\n }\n finally {\n const left = (startingMcp.get(peer) ?? 1) - 1\n if (left > 0)\n startingMcp.set(peer, left)\n else\n startingMcp.delete(peer)\n }\n }\n // Dropped while it started: nobody will finish it.\n if (!isConnected(peer)) {\n const flow = flows.get(begun.flowId)\n if (flow)\n end(flow, 'The connection closed.')\n }\n return begun\n },\n\n 'auth.oauth.complete': async (p, peer) => {\n const flow = flowOf(flows, p.flowId, peer)\n deliverCode(flow, p, end)\n let asking = false\n try {\n // The login may ask something first: the client answers (`respond`), then calls again.\n const outcome = await (flow.steps\n ? Promise.race([flow.result, flow.steps.next().then(step => ({ step }))])\n : flow.result)\n asking = outcome.step !== undefined\n return outcome\n }\n catch (err) {\n throw new Error(flow.abort.signal.aborted && flow.abort.signal.reason instanceof Error ? flow.abort.signal.reason.message : err instanceof Error ? err.message : String(err))\n }\n finally {\n if (!asking)\n end(flow, 'The sign-in finished.')\n }\n },\n\n 'auth.oauth.respond': async (p, peer) => {\n const flow = flowOf(flows, p.flowId, peer)\n if (!flow.steps || typeof p.stepId !== 'string')\n throw new InvalidParamsError('auth.oauth.respond needs the flow\\'s \"stepId\".')\n if (p.value !== undefined && typeof p.value !== 'string')\n throw new InvalidParamsError('\"value\" must be a string.')\n const cancelled = p.value === undefined && flow.steps.pending()?.kind === 'select'\n flow.steps.answer(p.stepId, p.value)\n if (cancelled) {\n end(flow, 'The sign-in was cancelled.')\n throw new Error('The sign-in was cancelled (no choice made).')\n }\n // After the URL: where it stands (`complete` again waits for the rest).\n return flow.begun ? { flowId: flow.id, ...flow.begun, expiresAt: flow.expiresAt } : stateOf(flow, flow.result)\n },\n\n 'auth.oauth.cancel': (p, peer) => {\n const flow = typeof p.flowId === 'string' ? flows.get(p.flowId) : undefined\n if (!flow || flow.peer !== peer)\n return { cancelled: false }\n end(flow, 'The sign-in was cancelled.')\n return { cancelled: true }\n },\n },\n releasePeer(peer) {\n for (const flow of ownFlows(peer))\n end(flow, 'The connection closed.')\n },\n }\n}\n","/** The main session driving worker sessions. */\nimport type { ChatHost } from '../../../chat/host/engine'\nimport type { Handlers } from './types'\n\ntype OrchestrationMethod\n = | 'orchestration.main' | 'orchestration.createWorker' | 'orchestration.list' | 'orchestration.read'\n | 'orchestration.send' | 'orchestration.steer' | 'orchestration.cancel' | 'orchestration.transcript'\n\nexport function createOrchestrationHandlers({ host }: { host: ChatHost }): Handlers<OrchestrationMethod> {\n return {\n 'orchestration.main': () => host.orchestration.ensureMain(),\n 'orchestration.createWorker': ({ mainId, ...params }) => host.orchestration.createWorker(mainId, params),\n 'orchestration.list': p => host.orchestration.list(p.mainId, p.limit),\n 'orchestration.read': async p =>\n (await host.orchestration.canOrchestrate(p.mainId, p.sessionId)) ? host.orchestration.read(p.sessionId) : null,\n 'orchestration.send': p => host.orchestration.send(p.mainId, p.sessionId, p.prompt, p.wake),\n 'orchestration.steer': p => host.orchestration.steer(p.mainId, p.sessionId, p.message),\n 'orchestration.cancel': p => host.orchestration.cancel(p.mainId, p.sessionId),\n 'orchestration.transcript': p => host.orchestration.transcript(p.mainId, p.sessionId, p.limit),\n }\n}\n","/** Which sessions have windows attached, and which one this window watches. */\nimport type { DaemonEnvironment } from '../environment'\nimport type { PeerRegistry } from '../peers'\nimport type { Handlers } from './types'\n\nexport function createPresenceHandlers({ env, peers }: {\n env: DaemonEnvironment\n peers: Pick<PeerRegistry, 'computePresence' | 'broadcastPresence'>\n}): Handlers<'presence.list' | 'presence.watch'> {\n return {\n 'presence.list': () => peers.computePresence(),\n 'presence.watch': (p, peer) => {\n peer.watching = p.sessionId\n peers.broadcastPresence()\n // Warm the per-cwd runtime config off the keystroke path: the first\n // suggest.resolve on a cold cwd would otherwise pay full extension\n // discovery inside the typist's wait (the 150ms provider deadline\n // starts only AFTER the registry exists). Fire-and-forget; the\n // 16-entry LRU keeps recently watched cwds hot.\n void env.store.load(p.sessionId).then((data) => {\n if (!data)\n return\n const meta = data.metadata ?? {}\n const cwd = typeof meta.cwd === 'string' ? meta.cwd : (data.projectRoot ?? '')\n return env.runtimeConfig(cwd)\n }).catch(() => undefined)\n },\n }\n}\n","/** The host-owned type-ahead queue every window shares. */\nimport type { ChatHost } from '../../../chat/host/engine'\nimport type { HostPeer } from '../peers'\nimport type { Handlers } from './types'\nimport { boundAttachments } from './drafts'\nimport { InvalidParamsError } from './params'\n\nexport function createQueueHandlers({ host, clearDraft }: {\n host: ChatHost\n clearDraft: (sessionId: string, origin: HostPeer | null) => void\n}): Handlers<'queue.list' | 'queue.add' | 'queue.remove' | 'queue.update' | 'queue.attachments' | 'queue.pushNow'> {\n return {\n 'queue.list': p => host.queueList(p.sessionId),\n 'queue.add': async (p, peer) => {\n // Same cheap shape guards as `drafts.set` — a malformed peer payload\n // must not propagate a non-string into every window's queue box.\n const text = typeof p.text === 'string' ? p.text.slice(0, 64 * 1024) : ''\n const activatedSkills = Array.isArray(p.activatedSkills)\n ? p.activatedSkills.filter((name): name is string => typeof name === 'string')\n : undefined\n const attachments = Array.isArray(p.attachments)\n ? boundAttachments(p.attachments)\n : undefined\n const asCommand = typeof p.asCommand === 'string' ? p.asCommand.slice(0, 128) : undefined\n const result = await host.queueAdd(p.sessionId, text, activatedSkills, attachments, asCommand)\n // Queuing/sending consumed the shared draft, same as a direct send\n // (not for a prompt sent from outside the composer).\n if (p.keepDraft !== true)\n clearDraft(p.sessionId, peer)\n return result\n },\n 'queue.remove': p => host.queueRemove(p.sessionId, p.id),\n 'queue.update': p => host.queueUpdate(\n p.sessionId,\n p.id,\n typeof p.text === 'string' ? p.text.slice(0, 64 * 1024) : '',\n updatedAttachments(p.attachments),\n ),\n 'queue.attachments': p => host.queueAttachments(p.sessionId, p.id),\n 'queue.pushNow': p => host.queuePushNow(p.sessionId, p.id),\n }\n}\n\n/**\n * The list `queue.update` stores in place of an entry's attachments. An entry\n * that is malformed or over the budget is refused, not dropped: the list\n * REPLACES what is stored, so a quietly shorter list would delete the rest.\n */\nfunction updatedAttachments(list: unknown): ReturnType<typeof boundAttachments> | undefined {\n if (!Array.isArray(list))\n return undefined\n const bounded = boundAttachments(list)\n if (bounded.length !== list.length)\n throw new InvalidParamsError('attachments: an entry is malformed, or the list is over 24 MiB.')\n return bounded\n}\n","/** Reattach without a reload: replay a session's numbered signals from the host's log (`../signal-log`). */\nimport type { SignalLog } from '../signal-log'\nimport type { Handlers } from './types'\n\nexport function createResumeHandlers({ log }: { log: Pick<SignalLog, 'epoch' | 'replay'> }): Handlers<'sessions.resume'> {\n return {\n 'sessions.resume': (p) => {\n if (p.epoch !== log.epoch)\n return { ok: false, reason: 'epoch' }\n const signals = typeof p.afterSeq === 'number' ? log.replay(p.sessionId, p.afterSeq) : null\n return signals ? { ok: true, signals } : { ok: false, reason: 'gap' }\n },\n }\n}\n","/**\n * Session data a client reads (and the extension state it writes) instead of\n * its own store: the list rows, one row, the whole document (or it a page of\n * turns at a time), one tool result's text. A window on\n * another machine (zidane-server) has no other way to see the host's\n * sessions.\n */\nimport type { ChatHost } from '../../../chat/host/engine'\nimport type { SessionData, SessionStore } from '../../../session/index'\nimport type { TranscriptReplayCache } from './transcript-cache'\nimport type { Handlers } from './types'\nimport { getSessionHeader, getSessionMeta, headerFromData, lastContextSizeFromTurns, listSessionMeta, sumRunCosts, toolResultText } from '../../../chat/store'\nimport { deleteExtensionSessionState, loadSession, setExtensionSessionState } from '../../../session/index'\nimport { SESSION_TURNS_MAX_PAGE, SESSION_TURNS_PAGE } from '../../protocol'\nimport { InvalidParamsError, nonNegativeInt, sessionIdOf } from './params'\n\ntype SessionReadMethod = 'sessions.listMeta' | 'sessions.getMeta' | 'sessions.get' | 'sessions.getTurns' | 'sessions.getToolResult' | 'sessions.getHeader' | 'sessions.setExtensionState'\n\nfunction pageBound(value: unknown, name: string, fallback: number, max: number): number {\n return Math.min(nonNegativeInt(value, name) ?? fallback, max)\n}\n\nexport function createSessionReadHandlers({ host, store, snapshots }: { host: ChatHost, store: SessionStore, snapshots: Pick<TranscriptReplayCache, 'document'> }): Handlers<SessionReadMethod> {\n /** The document as the host holds it: the live copy (ahead of the store mid-run, and holding the todos), else the stored one. */\n const documentOf = async (sessionId: string): Promise<SessionData | null> => {\n const live = host.getLiveSession(sessionId)\n if (live)\n return live.toJSON()\n // A reader: a load-time pairing heal stays in memory, the host's own\n // agent persists the document.\n const loaded = await loadSession(store, sessionId, { persistHeal: false })\n return loaded ? loaded.toJSON() : null\n }\n return {\n 'sessions.listMeta': (p) => {\n const projectRoot = p?.projectRoot\n if (projectRoot !== undefined && projectRoot !== null && typeof projectRoot !== 'string')\n throw new InvalidParamsError('projectRoot must be a string or null.')\n return listSessionMeta(store, projectRoot !== undefined ? { projectRoot } : undefined)\n },\n 'sessions.getMeta': p => getSessionMeta(store, sessionIdOf(p)),\n 'sessions.get': async (p) => {\n const sessionId = sessionIdOf(p)\n if (p.turns !== false)\n return documentOf(sessionId)\n // `turns: false`: the rest of the document, its turns read a page at a time\n // (`sessions.getTurns`), from the same snapshot, named by its version.\n const snapshot = await snapshots.document(store, sessionId, host.getLiveSession(sessionId))\n return snapshot && { ...snapshot.data, turns: [], version: snapshot.version }\n },\n 'sessions.getTurns': async (p) => {\n // One snapshot per content version serves every page (not a load, heal and copy per page).\n const sessionId = sessionIdOf(p)\n const snapshot = await snapshots.document(store, sessionId, host.getLiveSession(sessionId))\n if (!snapshot)\n return null\n const from = pageBound(p.from, 'from', 0, Number.MAX_SAFE_INTEGER)\n const limit = Math.max(1, pageBound(p.limit, 'limit', SESSION_TURNS_PAGE, SESSION_TURNS_MAX_PAGE))\n const { turns } = snapshot.data\n return { turns: turns.slice(from, from + limit), total: turns.length, version: snapshot.version }\n },\n 'sessions.getToolResult': async (p) => {\n const sessionId = sessionIdOf(p)\n if (typeof p.callId !== 'string' || p.callId.length === 0)\n throw new InvalidParamsError('callId must be a non-empty string.')\n const data = await documentOf(sessionId)\n if (!data)\n return null\n // The named turn first, then the rest (newest first: results sit near their call).\n const named = typeof p.turnId === 'string' ? data.turns.filter(turn => turn.id === p.turnId) : []\n for (const turn of [...named, ...[...data.turns].reverse()]) {\n for (const block of turn.content) {\n if (block.type === 'tool_result' && block.callId === p.callId)\n return toolResultText(block.output)\n }\n }\n return null\n },\n 'sessions.getHeader': async (p) => {\n const sessionId = sessionIdOf(p)\n const live = host.getLiveSession(sessionId)\n if (p.usage !== true)\n return live ? headerFromData(live.toJSON()) : getSessionHeader(store, sessionId)\n // The footer's numbers need the turns: read here, two numbers go out.\n const data = live ? live.toJSON() : await store.load(sessionId)\n if (!data)\n return null\n const header = live ? headerFromData(data) : (await getSessionHeader(store, sessionId)) ?? headerFromData({ ...data, id: sessionId })\n return { ...header, contextTokens: lastContextSizeFromTurns(data.turns, data.runs), costUsd: sumRunCosts(data.runs) }\n },\n 'sessions.setExtensionState': async (p) => {\n const sessionId = sessionIdOf(p)\n if (typeof p.extension !== 'string' || typeof p.key !== 'string')\n throw new InvalidParamsError('extension and key must be strings.')\n // The live copy when an agent holds the session (its save is\n // header-only, safe mid-run), else the stored one.\n const session = host.getLiveSession(sessionId) ?? await loadSession(store, sessionId, { persistHeal: false })\n if (!session)\n throw new Error(`Session \"${sessionId}\" not found.`)\n // Key checks and size bounds are the shared helpers' own.\n if (p.value === undefined)\n await deleteExtensionSessionState(session, p.extension, p.key)\n else\n await setExtensionSessionState(session, p.extension, p.key, p.value)\n },\n }\n}\n","/** Host settings and the runtime registry: read, write (rebuilding what a change requires), reload. */\nimport type { ChatHost } from '../../../chat/host/engine'\nimport type { HostSignal } from '../../protocol'\nimport type { DaemonEnvironment } from '../environment'\nimport type { Handlers } from './types'\nimport { InvalidParamsError } from './params'\n\n/**\n * Settings the host reads when it BUILDS an agent (not per call): changing\n * one rebuilds the live agents. `enabledPlugins` applies the plugin gate;\n * a live agent would otherwise keep a disabled plugin's skills and stdio MCP\n * servers until something unrelated rebuilt it.\n */\nconst AGENT_BUILD_KEYS = ['enabledMcps', 'disabledMcpTools', 'enabledSkills', 'enabledPlugins', 'importForeignConfigs', 'importRulerConfigs', 'artifacts'] as const\n\nexport function createSettingsHandlers({ host, env, broadcast }: {\n host: ChatHost\n env: DaemonEnvironment\n broadcast: (signal: HostSignal) => void\n}): Handlers<'settings.get' | 'settings.set' | 'runtime.reload'> {\n return {\n 'runtime.reload': () => {\n // Forget first so every rebuild (now for idle sessions, at run end for\n // busy ones) resolves a fresh registry; dispose the old registries only\n // once no agent runs on them. Disposing up front would tear down hooks\n // and HUD writers a busy run is still using.\n const disposeOld = env.forgetRuntime()\n void host.rebuildAllAgents().then(disposeOld, disposeOld)\n },\n\n 'settings.get': () => env.readSettings(),\n 'settings.set': (p) => {\n const patch: unknown = p?.patch\n if (typeof patch !== 'object' || patch === null || Array.isArray(patch))\n throw new InvalidParamsError('patch must be an object of settings.')\n const before = env.readSettings()\n const next = env.writeSettings(p.patch)\n\n /*\n * Only runtime-shaping keys tear down live agents — same policy as\n * the GUI's `settings:set` (gui/src/main/chat/ipc.ts). Toggling a\n * display/behavior key (e.g. `safeMode`) must NOT abort every live\n * run in every window; those keys are read at gate/invocation time.\n */\n const changed = (key: keyof typeof next): boolean =>\n JSON.stringify(before[key]) !== JSON.stringify(next[key])\n\n /*\n * Agent-shaping keys rebuild every live agent, deferred to run end for\n * a busy session (no run aborted, its approvals and queue kept), the\n * same as the TUI's local agent. The host applies these at agent BUILD\n * time (`buildActiveRun`: the plugin gate, MCP and skill catalogs, the\n * artifacts tool), so a rebuild is enough; `rediscover` re-walks the\n * disk instead of serving a catalog that predates the toggle.\n * Extension toggles also swap the registry: forget the runtime config\n * first so the rebuilds resolve a fresh one, and dispose the old\n * registries only once no agent runs on them (as `runtime.reload`).\n */\n if (changed('enabledExtensions') || changed('loadProjectExtensions')) {\n const disposeOld = env.forgetRuntime()\n void host.rebuildAllAgents({ rediscover: true }).then(disposeOld, disposeOld)\n }\n else if (AGENT_BUILD_KEYS.some(changed)) {\n // Best-effort, as the extension branch: a failed rebuild must not reject unobserved.\n void host.rebuildAllAgents({ rediscover: true }).catch(() => undefined)\n }\n\n // Flipping to skip answers the modals already on screen — otherwise an\n // interaction raised under `ask` waits forever for an answer the new mode\n // says nobody will give. Resolved host-side so every window converges.\n if (changed('interactionMode') && next.interactionMode === 'skip')\n host.interactions.resolveAutomatically()\n\n // Agent-shaping settings (terminals, subagent models, interactions off): rebuild agents (no run aborted), close terminals when turned off.\n host.applyAgentSettings(before, next)\n\n // Converge every window's settings UI on the new state live.\n broadcast({ kind: 'settings:changed', settings: next })\n\n return next\n },\n }\n}\n","/** Inline autocomplete, resolved daemon-side and fanned out to every window on the session. */\nimport type { HostSignal } from '../../protocol'\nimport type { DaemonEnvironment } from '../environment'\nimport type { HostPeer } from '../peers'\nimport type { Handlers } from './types'\nimport { createPathAutocompleteProvider, resolveInlineSuggestion } from '../../../chat/index'\nimport { loadOrThrow } from './sessions'\n\nexport function createSuggestHandlers({ env, broadcastExcept }: {\n env: DaemonEnvironment\n broadcastExcept: (origin: HostPeer | null, signal: HostSignal) => void\n}): {\n methods: Handlers<'suggest.resolve'>\n /** The session was deleted: abort its in-flight compute and forget its sequence. */\n forget: (sessionId: string) => void\n} {\n /**\n * Shared inline-autocomplete state — per-session latest-wins\n * coalescing for `suggest.resolve`. `seq` is the newest sequence seen\n * (stale requests return without computing); `controller` aborts an\n * in-flight compute when a newer request supersedes it (the GUI's\n * controller-map pattern, daemon-side). Entries outlive their compute\n * (the seq high-water mark), so the map is an LRU of 256 sessions:\n * refusing new keys at the cap instead would switch suggestions off for\n * every session past the 256th until the daemon restarts.\n */\n const suggests = new Map<string, { seq: number, controller: AbortController | null }>()\n\n const methods: Handlers<'suggest.resolve'> = {\n 'suggest.resolve': async (p, peer) => {\n const sessionId = String(p.sessionId)\n const seq = typeof p.seq === 'number' ? p.seq : 0\n // Same cheap shape guards + 64 KiB text cap as `drafts.set`.\n const text = typeof p.text === 'string' ? p.text.slice(0, 64 * 1024) : ''\n const caret = typeof p.caret === 'number'\n ? Math.max(0, Math.min(Math.floor(p.caret), text.length))\n : text.length\n\n const prev = suggests.get(sessionId)\n // Latest-wins: a stale seq answers immediately without computing —\n // the requester's own NEWER request (already in flight or about to\n // land) carries the authoritative result.\n if (prev && seq < prev.seq)\n return { suggestion: null, seq }\n // Supersede: abort the in-flight compute for this session, if any.\n prev?.controller?.abort()\n\n const controller = new AbortController()\n const entry = { seq, controller: controller as AbortController | null }\n suggests.delete(sessionId)\n suggests.set(sessionId, entry)\n if (suggests.size > 256) {\n const [oldest, evicted] = suggests.entries().next().value!\n evicted.controller?.abort()\n suggests.delete(oldest)\n }\n\n try {\n // Session cwd from metadata (same derivation as `toRow`) — the\n // per-cwd runtime config is the SAME registry the GUI main uses\n // locally, resolved through the existing daemon environment.\n const data = await loadOrThrow(env.store, sessionId)\n const meta = data.metadata ?? {}\n const cwd = typeof meta.cwd === 'string' ? meta.cwd : (data.projectRoot ?? '')\n const config = await env.runtimeConfig(cwd)\n // Canonical provider assembly (built-in path provider first, then\n // extension providers) and canonical deadlines —\n // `resolveInlineSuggestion` races each provider against its own\n // budget exactly as the GUI main / TUI do.\n const providers = [\n createPathAutocompleteProvider({ cwd: () => cwd }),\n ...config.extensions.inlineAutocompleteProviders,\n ]\n const result = await resolveInlineSuggestion(providers, { text, cursor: caret, cwd, signal: controller.signal })\n // Superseded mid-compute — the newer request owns the fan-out.\n if (controller.signal.aborted || suggests.get(sessionId) !== entry)\n return { suggestion: null, seq }\n // Full ordered candidate list rides along (additive field) so\n // clients keep ↑/↓ rotation; `suggestion` stays candidates[0] for\n // older clients that only read the single field.\n const candidates = result ? [...result.suffixes] : []\n const suggestion = candidates[0] ?? null\n // Fan out to every OTHER window on the session — the requester\n // already has the result from this RPC reply (drafts'\n // broadcastExcept pattern).\n broadcastExcept(peer, { kind: 'suggest:changed', sessionId, seq, basis: text, caret, suggestion, ...(candidates.length > 0 ? { candidates } : {}) })\n return { suggestion, seq, ...(candidates.length > 0 ? { candidates } : {}) }\n }\n finally {\n // Keep the seq high-water mark for stale checks; drop only the\n // controller so a finished compute can't be \"aborted\" later.\n if (suggests.get(sessionId) === entry)\n entry.controller = null\n }\n },\n }\n\n return {\n methods,\n forget: (sessionId) => {\n suggests.get(sessionId)?.controller?.abort()\n suggests.delete(sessionId)\n },\n }\n}\n","/**\n * Applying one `sync.push` category on a zidane-server (`./handlers/sync`\n * owns the record, the source check and the audit): each writes through the\n * host's own setters or the user-scope files, skipping overrides (a field\n * whose value here no longer matches what sync wrote becomes one), and\n * reports every field as applied, unchanged or skipped (with why).\n */\nimport type { SyncCategory, SyncFile, SyncPayloads, SyncPushResult } from '../../chat/sync/types'\nimport type { McpServerConfig } from '../../types'\nimport type { DaemonEnvironment } from './environment'\nimport type { ProviderAuth } from './handlers/auth'\nimport type { SyncSetters } from './handlers/sync'\nimport type { HostPeer } from './peers'\nimport type { SyncFieldRecord, SyncRecord } from './sync-store'\nimport { Buffer } from 'node:buffer'\nimport { createHash } from 'node:crypto'\nimport { accessSync, constants, existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from 'node:fs'\nimport { basename, delimiter, dirname, isAbsolute, join, relative, resolve, sep } from 'node:path'\nimport process from 'node:process'\nimport { writeFileAtomic } from '../../atomic-write'\nimport { isWindowOnlySetting } from '../../chat/host-scoped-settings'\nimport { parseMcpsFile } from '../../chat/mcps-discovery'\nimport { mcpsWritePath } from '../../chat/mcps-write'\nimport { projectUserPaths } from '../../chat/project-user-paths'\nimport { readProjects, safelistProjectKey, writeProjects } from '../../chat/safe-mode'\nimport { DEFAULT_SETTINGS } from '../../chat/settings-context'\nimport { hashValue, isRecord } from '../../chat/sync/hash'\nimport { isSyncableSetting } from '../../chat/sync/settings-keys'\nimport { settingField, SYSTEM_MD_FIELD } from '../../chat/sync/types'\nimport { userSystemMdPath } from '../../chat/system-md'\nimport { InvalidParamsError } from './handlers/params'\n\n/** What applying a push reads and writes through. */\nexport interface SyncApplyContext {\n env: DaemonEnvironment\n setters: SyncSetters\n auth: Pick<ProviderAuth, 'descriptorOf' | 'storedKeys'>\n home: () => string\n prefix: () => string\n}\n\nconst MAX_SETTINGS_BYTES = 256 * 1024\n\nconst MAX_SYSTEM_MD_BYTES = 256 * 1024\n\nconst MAX_FILE_BYTES = 1024 * 1024\n\nconst MAX_SKILL_BYTES = 4 * 1024 * 1024\n\nconst MAX_FILES_BYTES = 16 * 1024 * 1024\n\nconst MAX_SKILL_FILES = 200\n\nconst MAX_SKILLS = 500\n\nconst MAX_PATH_DEPTH = 8\n\nconst MAX_SAFELIST_ENTRIES = 1000\n\nconst MAX_ENTRY_LENGTH = 1000\n\nconst NAME_RE = /^\\w[\\w@.-]{0,99}$/\n\nconst SEGMENT_RE = /^[^/\\\\\\0]{1,255}$/\n\n/** A skill file's relative path: plain segments, no `..`, bounded depth. */\nfunction checkRelativePath(path: unknown): string | null {\n if (typeof path !== 'string' || path === '' || isAbsolute(path) || path.includes('\\\\'))\n return null\n const segments = path.split('/')\n if (segments.length > MAX_PATH_DEPTH || segments.some(s => s === '.' || s === '..' || !SEGMENT_RE.test(s)))\n return null\n return segments.join('/')\n}\n\n/** Is `command` runnable here (an absolute path, or found on PATH)? Looks, never runs. */\nfunction commandAvailable(command: string): boolean {\n const executable = (path: string): boolean => {\n try {\n accessSync(path, constants.X_OK)\n return statSync(path).isFile()\n }\n catch {\n return false\n }\n }\n if (command.includes('/'))\n return isAbsolute(command) && executable(command)\n return (process.env.PATH ?? '').split(delimiter).filter(Boolean).some(dir => executable(join(dir, command)))\n}\n\n/** A folder's files, sorted, as one hash (symlinks hashed by target, never followed). Null when absent. */\nfunction hashDir(dir: string): string | null {\n let stat\n try {\n stat = lstatSync(dir)\n }\n catch {\n return null\n }\n if (!stat.isDirectory())\n return `not-a-folder:${stat.mode}`\n const hash = createHash('sha256')\n const walk = (at: string, depth: number): void => {\n if (depth > MAX_PATH_DEPTH + 1)\n return\n for (const name of readdirSync(at).sort()) {\n const path = join(at, name)\n const rel = relative(dir, path).split(sep).join('/')\n const s = lstatSync(path)\n if (s.isDirectory()) {\n walk(path, depth + 1)\n }\n else if (s.isFile()) {\n hash.update(`f:${rel}\\0`)\n hash.update(readFileSync(path))\n hash.update('\\0')\n }\n else {\n hash.update(`o:${rel}:${s.mode}\\0`)\n }\n }\n }\n walk(dir, 0)\n return hash.digest('hex')\n}\n\n/** The hash `hashDir` gives the folder these files make. */\nfunction hashFiles(files: readonly { path: string, bytes: Buffer }[]): string {\n const hash = createHash('sha256')\n // `hashDir` walks in sorted order level by level: replay that order.\n const sorted = [...files].sort((a, b) => compareWalkOrder(a.path, b.path))\n for (const file of sorted) {\n hash.update(`f:${file.path}\\0`)\n hash.update(file.bytes)\n hash.update('\\0')\n }\n return hash.digest('hex')\n}\n\n/** The order a sorted depth-first walk visits two relative paths. */\nfunction compareWalkOrder(a: string, b: string): number {\n const as = a.split('/')\n const bs = b.split('/')\n for (let i = 0; i < Math.min(as.length, bs.length); i++) {\n if (as[i] !== bs[i]) {\n // Same level: readdir order (code units), whether file or folder.\n return as[i]! < bs[i]! ? -1 : 1\n }\n }\n return as.length - bs.length\n}\n\nfunction userSkillsRoot(ctx: SyncApplyContext): string {\n const root = projectUserPaths({ subPath: 'skills', cwd: ctx.home(), home: ctx.home(), prefix: ctx.prefix() })\n .find(p => p.source === 'user' && p.path.includes(`.${ctx.prefix().replace(/^\\./, '')}`))\n return root!.path\n}\nfunction userMcpsPath(ctx: SyncApplyContext): string {\n return mcpsWritePath('user', { home: ctx.home(), cwd: ctx.home(), prefix: ctx.prefix() })\n}\nfunction userExtensionDirs(ctx: SyncApplyContext, name: string): string[] {\n return projectUserPaths({ subPath: 'extensions', cwd: ctx.home(), home: ctx.home(), prefix: ctx.prefix() }).filter(p => p.source === 'user').map(p => join(p.path, name))\n}\n\n/** Is `field` free to write? An override (now or found by a changed value) is not. */\nfunction writable(record: SyncRecord, field: string, currentHash: string | null, result: SyncPushResult): boolean {\n if (record.overrides[field]) {\n result.skipped.push({ field, reason: 'override' })\n return false\n }\n const known = record.fields[field]\n if (known?.hash !== undefined && known.hash !== (currentHash ?? 'absent')) {\n record.overrides[field] = { at: Date.now() }\n result.skipped.push({ field, reason: 'override' })\n return false\n }\n return true\n}\n\nfunction mark(record: SyncRecord, field: string, category: SyncCategory, fields: Omit<SyncFieldRecord, 'category' | 'syncedAt'>): void {\n record.fields[field] = { category, syncedAt: Date.now(), ...fields }\n}\n\n// ---- settings ----------------------------------------------------------\nexport function pushSettings(ctx: SyncApplyContext, record: SyncRecord, payload: SyncPayloads['settings'], result: SyncPushResult): void {\n if (!isRecord(payload?.values))\n throw new InvalidParamsError('settings: payload.values must be an object.')\n if (JSON.stringify(payload.values).length > MAX_SETTINGS_BYTES)\n throw new InvalidParamsError(`settings: larger than ${MAX_SETTINGS_BYTES} bytes.`)\n const current = ctx.env.readSettings() as unknown as Record<string, unknown>\n const patch: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(payload.values)) {\n const field = settingField(key)\n if (!Object.hasOwn(DEFAULT_SETTINGS, key)) {\n result.skipped.push({ field, reason: 'not a setting' })\n continue\n }\n if (!isSyncableSetting(key)) {\n result.skipped.push({ field, reason: isWindowOnlySetting(key) ? 'window-only setting' : 'not synced' })\n continue\n }\n const currentHash = hashValue(current[key])\n if (!writable(record, field, currentHash, result))\n continue\n if (hashValue(value) === currentHash) {\n mark(record, field, 'settings', { hash: currentHash, sent: currentHash })\n result.unchanged.push(field)\n continue\n }\n patch[key] = value\n }\n if (Object.keys(patch).length === 0)\n return\n const next = ctx.setters.setSettings(patch)\n for (const key of Object.keys(patch)) {\n mark(record, settingField(key), 'settings', { hash: hashValue(next[key]), sent: hashValue(patch[key]) })\n result.applied.push(settingField(key))\n }\n}\n\n// ---- safe-mode allowlists ----------------------------------------------\n/** The project here a client's path names: the same folder inside a workspace root, else one folder of that name in a root. */\nfunction projectHere(ctx: SyncApplyContext, clientPath: string): string | null {\n const roots = (ctx.env.workspaceRoots ?? []).map((root) => {\n try {\n return realpathSync(root)\n }\n catch {\n return null\n }\n }).filter((r): r is string => r !== null)\n const inRoot = (path: string): boolean => roots.some(root => path === root || path.startsWith(root + sep))\n const isDir = (path: string): boolean => statSync(path, { throwIfNoEntry: false })?.isDirectory() === true\n if (isAbsolute(clientPath) && isDir(clientPath)) {\n const real = realpathSync(clientPath)\n if (inRoot(real))\n return safelistProjectKey(real)\n }\n const name = basename(clientPath)\n if (!name || name === '.' || name === '..')\n return null\n const found = [...new Set(roots.map(root => join(root, name)).filter(isDir).map(path => realpathSync(path)))]\n return found.length === 1 ? safelistProjectKey(found[0]!) : null\n}\n\nexport function pushSafelists(ctx: SyncApplyContext, record: SyncRecord, payload: SyncPayloads['safelists'], result: SyncPushResult): void {\n if (!isRecord(payload?.projects))\n throw new InvalidParamsError('safelists: payload.projects must map paths to entries.')\n const dataDir = ctx.env.userDataDir()\n const file = readProjects(dataDir)\n let dirty = false\n for (const [clientPath, entries] of Object.entries(payload.projects)) {\n const field = `safelist:${clientPath}`\n if (!Array.isArray(entries) || entries.length > MAX_SAFELIST_ENTRIES || !entries.every(e => typeof e === 'string' && e.length <= MAX_ENTRY_LENGTH)) {\n result.skipped.push({ field, reason: 'invalid entries' })\n continue\n }\n const target = projectHere(ctx, clientPath)\n if (!target) {\n result.skipped.push({ field, reason: 'no project of that path or name on this server' })\n continue\n }\n // The server's own entries stay; the ones this device put there and dropped since go.\n const previous = record.fields[field]?.target === target ? (record.fields[field]?.entries ?? []) : []\n const current = file[target]?.safelist ?? []\n const next = current.filter(entry => !previous.includes(entry) || entries.includes(entry))\n for (const entry of entries) {\n if (!next.includes(entry))\n next.push(entry)\n }\n mark(record, field, 'safelists', { target, entries: [...entries] })\n if (JSON.stringify(next) === JSON.stringify(current)) {\n result.unchanged.push(field)\n continue\n }\n file[target] = { ...file[target], safelist: next }\n dirty = true\n result.applied.push(field)\n }\n if (dirty)\n writeProjects(dataDir, file)\n}\n\n// ---- SYSTEM.md and skills ----------------------------------------------\n/** A skill as checked bytes, or why it is refused. */\nfunction checkSkill(skill: unknown): { name: string, files: { path: string, bytes: Buffer }[] } | { field: string, reason: string } {\n const name = isRecord(skill) && typeof skill.name === 'string' ? skill.name : ''\n const field = `skill:${name}`\n if (!NAME_RE.test(name))\n return { field, reason: 'not a plain skill name' }\n const files = isRecord(skill) && Array.isArray(skill.files) ? skill.files as SyncFile[] : null\n if (!files || files.length === 0 || files.length > MAX_SKILL_FILES)\n return { field, reason: `needs 1 to ${MAX_SKILL_FILES} files` }\n const out: { path: string, bytes: Buffer }[] = []\n let total = 0\n for (const file of files) {\n const path = checkRelativePath(isRecord(file) ? file.path : undefined)\n if (!path)\n return { field, reason: 'a file path is not a plain relative path' }\n if (typeof file.data !== 'string')\n return { field, reason: `${path}: no data` }\n const bytes = Buffer.from(file.data, 'base64')\n if (bytes.length > MAX_FILE_BYTES)\n return { field, reason: `${path} is larger than ${MAX_FILE_BYTES} bytes` }\n total += bytes.length\n if (out.some(f => f.path === path || f.path.startsWith(`${path}/`) || path.startsWith(`${f.path}/`)))\n return { field, reason: `${path} appears twice` }\n out.push({ path, bytes })\n }\n if (total > MAX_SKILL_BYTES)\n return { field, reason: `larger than ${MAX_SKILL_BYTES} bytes` }\n return { name, files: out }\n}\n\n/** Replace `dir` with exactly these files: staged next to it, then swapped in. */\nfunction writeSkillDir(root: string, name: string, files: readonly { path: string, bytes: Buffer }[]): void {\n mkdirSync(root, { recursive: true })\n const dir = join(root, name)\n const stage = join(root, `.${name}.sync-${process.pid}-${Date.now()}`)\n mkdirSync(stage)\n try {\n for (const file of files) {\n const target = resolve(stage, file.path)\n if (!target.startsWith(stage + sep))\n throw new Error(`${file.path} is outside the skill folder.`)\n mkdirSync(dirname(target), { recursive: true })\n writeFileSync(target, file.bytes)\n }\n const backup = existsSync(dir) ? `${stage}.old` : null\n if (backup)\n renameSync(dir, backup)\n renameSync(stage, dir)\n if (backup)\n rmSync(backup, { recursive: true, force: true })\n }\n finally {\n rmSync(stage, { recursive: true, force: true })\n }\n}\n\nexport function pushFiles(ctx: SyncApplyContext, record: SyncRecord, payload: SyncPayloads['files'], result: SyncPushResult): boolean {\n if (!isRecord(payload) || !Array.isArray(payload.skills) || payload.skills.length > MAX_SKILLS || (payload.systemMd !== null && typeof payload.systemMd !== 'string'))\n throw new InvalidParamsError('files: payload must be { systemMd: string | null, skills: [...] }.')\n let touched = false\n let total = 0\n\n // SYSTEM.md (user scope).\n const mdPath = userSystemMdPath({ home: ctx.home(), prefix: ctx.prefix() })\n const currentMd = existsSync(mdPath) ? readFileSync(mdPath, 'utf8') : null\n const currentMdHash = currentMd === null ? null : hashValue(currentMd)\n if (payload.systemMd !== null && Buffer.byteLength(payload.systemMd) > MAX_SYSTEM_MD_BYTES) {\n result.skipped.push({ field: SYSTEM_MD_FIELD, reason: `larger than ${MAX_SYSTEM_MD_BYTES} bytes` })\n }\n else if (payload.systemMd !== null || record.fields[SYSTEM_MD_FIELD]) {\n if (writable(record, SYSTEM_MD_FIELD, currentMdHash, result)) {\n if (payload.systemMd === null) {\n // This computer has none any more: drop the one sync wrote.\n rmSync(mdPath, { force: true })\n delete record.fields[SYSTEM_MD_FIELD]\n result.applied.push(SYSTEM_MD_FIELD)\n touched = true\n }\n else if (hashValue(payload.systemMd) === currentMdHash) {\n mark(record, SYSTEM_MD_FIELD, 'files', { hash: currentMdHash })\n result.unchanged.push(SYSTEM_MD_FIELD)\n }\n else {\n total += Buffer.byteLength(payload.systemMd)\n writeFileAtomic(mdPath, payload.systemMd, { ensureDir: true })\n mark(record, SYSTEM_MD_FIELD, 'files', { hash: hashValue(payload.systemMd) })\n result.applied.push(SYSTEM_MD_FIELD)\n touched = true\n }\n }\n }\n\n // Skills (user scope, `~/.<prefix>/skills/<name>`).\n const root = userSkillsRoot(ctx)\n const sent = new Set<string>()\n for (const raw of payload.skills) {\n const skill = checkSkill(raw)\n if ('reason' in skill) {\n result.skipped.push(skill)\n continue\n }\n const field = `skill:${skill.name}`\n sent.add(field)\n const bytes = skill.files.reduce((n, f) => n + f.bytes.length, 0)\n if (total + bytes > MAX_FILES_BYTES) {\n result.skipped.push({ field, reason: `over the ${MAX_FILES_BYTES}-byte bound of one push` })\n continue\n }\n const dir = join(root, skill.name)\n if (existsSync(dir) && lstatSync(dir).isSymbolicLink()) {\n result.skipped.push({ field, reason: 'a link on this server, left alone' })\n continue\n }\n const currentHash = hashDir(dir)\n if (!writable(record, field, currentHash, result))\n continue\n const wanted = hashFiles(skill.files)\n if (wanted === currentHash) {\n mark(record, field, 'files', { hash: wanted })\n result.unchanged.push(field)\n continue\n }\n total += bytes\n writeSkillDir(root, skill.name, skill.files)\n mark(record, field, 'files', { hash: hashDir(dir) ?? wanted })\n result.applied.push(field)\n touched = true\n }\n // Skills this device synced and no longer has.\n for (const [field, known] of Object.entries(record.fields)) {\n if (known.category !== 'files' || !field.startsWith('skill:') || sent.has(field))\n continue\n const dir = join(root, field.slice('skill:'.length))\n if (!writable(record, field, hashDir(dir), result))\n continue\n rmSync(dir, { recursive: true, force: true })\n delete record.fields[field]\n result.applied.push(field)\n touched = true\n }\n return touched\n}\n\n// ---- MCP servers ---------------------------------------------------------\nfunction readUserMcps(ctx: SyncApplyContext): McpServerConfig[] {\n const path = userMcpsPath(ctx)\n if (!existsSync(path))\n return []\n try {\n return parseMcpsFile(readFileSync(path, 'utf8'))\n }\n catch {\n return []\n }\n}\n\nexport async function pushMcps(ctx: SyncApplyContext, record: SyncRecord, payload: SyncPayloads['mcps'], peer: HostPeer, result: SyncPushResult): Promise<void> {\n if (!isRecord(payload) || !Array.isArray(payload.servers))\n throw new InvalidParamsError('mcps: payload.servers must be a list.')\n const hashOf = (name: string): string | null => {\n const found = readUserMcps(ctx).find(s => s.name === name)\n return found ? hashValue(found) : null\n }\n const sent = new Set<string>()\n for (const config of payload.servers) {\n const name = isRecord(config) && typeof config.name === 'string' ? config.name : ''\n const field = `mcp:${name}`\n if (!NAME_RE.test(name)) {\n result.skipped.push({ field, reason: 'not a plain server name' })\n continue\n }\n sent.add(field)\n const currentHash = hashOf(name)\n if (!writable(record, field, currentHash, result))\n continue\n const wanted = hashValue(config)\n if (record.fields[field]?.sent === wanted && currentHash !== null) {\n result.unchanged.push(field)\n continue\n }\n try {\n await ctx.setters.mcpUpsert({ config: config as unknown as McpServerConfig }, peer)\n }\n catch (err) {\n result.skipped.push({ field, reason: err instanceof Error ? err.message : String(err) })\n continue\n }\n mark(record, field, 'mcps', { hash: hashOf(name) ?? wanted, sent: wanted })\n result.applied.push(field)\n if (typeof config.command === 'string' && config.command.trim() !== '' && !commandAvailable(config.command.trim()))\n result.warnings.push({ field, message: `\"${config.command}\" is not on this server's PATH: the server may not run there.` })\n }\n for (const [field, known] of Object.entries(record.fields)) {\n if (known.category !== 'mcps' || sent.has(field))\n continue\n const name = field.slice('mcp:'.length)\n if (!writable(record, field, hashOf(name), result))\n continue\n try {\n await ctx.setters.mcpRemove({ name }, peer)\n }\n catch (err) {\n result.skipped.push({ field, reason: err instanceof Error ? err.message : String(err) })\n continue\n }\n delete record.fields[field]\n result.applied.push(field)\n }\n}\n\n// ---- extensions ----------------------------------------------------------\nexport async function pushExtensions(ctx: SyncApplyContext, record: SyncRecord, payload: SyncPayloads['extensions'], peer: HostPeer, result: SyncPushResult): Promise<void> {\n if (!isRecord(payload) || !Array.isArray(payload.extensions))\n throw new InvalidParamsError('extensions: payload.extensions must be a list.')\n for (const entry of payload.extensions) {\n const name = isRecord(entry) && typeof entry.name === 'string' ? entry.name : ''\n const field = `extension:${name}`\n if (!NAME_RE.test(name) || typeof entry.spec !== 'string') {\n result.skipped.push({ field, reason: 'needs a plain name and a source spec' })\n continue\n }\n if (record.overrides[field]) {\n result.skipped.push({ field, reason: 'override' })\n continue\n }\n // Installed already (by sync or by hand): left as it is, never updated or removed by sync.\n if (userExtensionDirs(ctx, name).some(dir => existsSync(dir))) {\n if (!record.fields[field])\n mark(record, field, 'extensions', {})\n result.unchanged.push(field)\n continue\n }\n try {\n await ctx.setters.install({ kind: 'extension', spec: entry.spec, scope: 'user', ...(typeof entry.extension === 'string' ? { extension: entry.extension } : {}) }, peer)\n }\n catch (err) {\n result.skipped.push({ field, reason: err instanceof Error ? err.message : String(err) })\n continue\n }\n mark(record, field, 'extensions', {})\n result.applied.push(field)\n }\n}\n\n// ---- provider API keys ---------------------------------------------------\nexport function pushKeys(ctx: SyncApplyContext, record: SyncRecord, payload: SyncPayloads['keys'], result: SyncPushResult): void {\n if (!isRecord(payload) || !Array.isArray(payload.keys))\n throw new InvalidParamsError('keys: payload.keys must be a list.')\n for (const entry of payload.keys) {\n const provider = isRecord(entry) && typeof entry.provider === 'string' ? entry.provider : ''\n const field = `key:${provider}`\n if (!record.keys.includes(provider)) {\n result.skipped.push({ field, reason: 'not opted in for this key' })\n continue\n }\n if (record.overrides[field]) {\n result.skipped.push({ field, reason: 'override' })\n continue\n }\n try {\n if (typeof entry.key !== 'string' || entry.key.trim() === '')\n throw new Error('empty key')\n if (ctx.auth.storedKeys(ctx.auth.descriptorOf(provider)).includes(entry.key.trim())) {\n if (!record.fields[field])\n mark(record, field, 'keys', {})\n result.unchanged.push(field)\n continue\n }\n ctx.setters.setApiKey({ provider, key: entry.key })\n }\n catch (err) {\n result.skipped.push({ field, reason: err instanceof Error ? err.message : String(err) })\n continue\n }\n mark(record, field, 'keys', {})\n result.applied.push(field)\n }\n}\n","/**\n * A zidane-server's settings-sync record (`<dataDir>/sync.json`, 0600,\n * written atomically): the source device, the categories and API keys it\n * opted in, the fields it set (with a hash of what the server held after\n * each write, to tell a server-side edit) and the fields edited here since\n * (overrides). No secret is stored: an API key field has no hash.\n */\nimport type { SyncCategory, SyncSource, SyncStatus } from '../../chat/sync/types'\nimport { existsSync, readFileSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { OWNER_ONLY, writeJsonFileAtomic } from '../../atomic-write'\nimport { isRecord } from '../../chat/sync/hash'\nimport { SYNC_CATEGORIES } from '../../chat/sync/types'\n\nexport interface SyncFieldRecord {\n category: SyncCategory\n syncedAt: number\n /** Hash of the server's value right after the last write: anything else there now is an edit made here. */\n hash?: string\n /** Hash of the value the source sent last: the same again is `unchanged`. */\n sent?: string\n /** A safelist: the project key it maps to here, and the entries the source put there. */\n target?: string\n entries?: string[]\n}\n\nexport interface SyncRecord {\n version: 1\n source: SyncSource | null\n categories: SyncCategory[]\n keys: string[]\n fields: Record<string, SyncFieldRecord>\n overrides: Record<string, { at: number }>\n lastPushAt?: number\n}\n\nexport const SYNC_FILE = 'sync.json'\n\nexport function emptySyncRecord(): SyncRecord {\n return { version: 1, source: null, categories: [], keys: [], fields: {}, overrides: {} }\n}\n\nexport interface SyncStore {\n file: string\n read: () => SyncRecord\n write: (record: SyncRecord) => void\n}\n\nexport function createSyncStore(dataDir: string): SyncStore {\n const file = join(dataDir, SYNC_FILE)\n return {\n file,\n read: () => {\n if (!existsSync(file))\n return emptySyncRecord()\n try {\n const raw: unknown = JSON.parse(readFileSync(file, 'utf8'))\n if (!isRecord(raw))\n return emptySyncRecord()\n const source = isRecord(raw.source) && typeof raw.source.deviceId === 'string' && typeof raw.source.deviceName === 'string'\n ? raw.source as unknown as SyncSource\n : null\n return {\n version: 1,\n source,\n categories: Array.isArray(raw.categories) ? raw.categories.filter((c): c is SyncCategory => SYNC_CATEGORIES.includes(c as SyncCategory)) : [],\n keys: Array.isArray(raw.keys) ? raw.keys.filter((k): k is string => typeof k === 'string') : [],\n fields: isRecord(raw.fields) ? raw.fields as Record<string, SyncFieldRecord> : {},\n overrides: isRecord(raw.overrides) ? raw.overrides as Record<string, { at: number }> : {},\n ...(typeof raw.lastPushAt === 'number' ? { lastPushAt: raw.lastPushAt } : {}),\n }\n }\n catch {\n // Unreadable: start over (the next write replaces it).\n return emptySyncRecord()\n }\n },\n write: record => writeJsonFileAtomic(file, record, OWNER_ONLY),\n }\n}\n\n/** What `sync.status` says: the record without hashes or safelist entries. */\nexport function syncStatusOf(record: SyncRecord): SyncStatus {\n return {\n source: record.source,\n categories: [...record.categories],\n keys: [...record.keys],\n fields: Object.fromEntries(Object.entries(record.fields).map(([field, f]) => [field, { category: f.category, syncedAt: f.syncedAt }])),\n overrides: { ...record.overrides },\n ...(record.lastPushAt !== undefined ? { lastPushAt: record.lastPushAt } : {}),\n }\n}\n","/**\n * Settings sync from a client's computer (`sync.*`, `docs/SERVER.md`\n * § Settings sync): a zidane-server takes one device's settings, files,\n * MCP servers, extensions and opted-in API keys, through the same setters a\n * window uses (`settings.set`, `mcp.upsert` / `remove`, `catalog.install`,\n * `auth.setApiKey`, the user-scope files), and keeps a record of what came\n * from where (`../sync-store`).\n *\n * - One source per server: `sync.claim` by another device is refused unless\n * it takes over (which drops the previous source's marks, not its values).\n * The source is the device AND the token it claimed with: a device id is a\n * client's word, so the same id from another token is another source\n * (coordination between a user's devices, bound to who authenticated).\n * - A field edited on the server since it was synced (through a window, or\n * on disk: its value no longer matches what sync wrote) is an override:\n * pushes skip it until `sync.reset`.\n * - Window-only settings never apply; skills are written by plain names and\n * relative paths inside the skills folder, size-bounded; extensions and\n * MCP servers go through the install gate (`allowRemoteInstalls`) and its\n * audit; API keys only for providers the source opted in.\n * - Every call is audited with the connection's token; no value is logged.\n */\nimport type { ChatHost } from '../../../chat/host/engine'\nimport type { SyncCategory, SyncPayloads, SyncPushResult, SyncStatus } from '../../../chat/sync/types'\nimport type { HostSignal, IpcParams } from '../../protocol'\nimport type { DaemonEnvironment } from '../environment'\nimport type { HostPeer } from '../peers'\nimport type { SyncApplyContext } from '../sync-apply'\nimport type { SyncRecord } from '../sync-store'\nimport type { ProviderAuth } from './auth'\nimport type { Handlers } from './types'\nimport { homedir } from 'node:os'\nimport { isRecord } from '../../../chat/sync/hash'\nimport { settingField, SYNC_CATEGORIES } from '../../../chat/sync/types'\nimport { pushExtensions, pushFiles, pushKeys, pushMcps, pushSafelists, pushSettings } from '../sync-apply'\nimport { createSyncStore, syncStatusOf } from '../sync-store'\nimport { InvalidParamsError } from './params'\n\nexport interface SyncOptions {\n /** One audit line per call (the server adds the connection's token). */\n audit?: (peer: HostPeer, entry: Record<string, unknown>) => void\n}\n\ntype SyncMethod = 'sync.status' | 'sync.claim' | 'sync.push' | 'sync.reset' | 'sync.release'\n\n/** The host's own setters, as a window calls them (installs gated and audited there). */\nexport interface SyncSetters {\n setSettings: (patch: Record<string, unknown>) => Record<string, unknown>\n install: (params: IpcParams<'catalog.install'>, peer: HostPeer) => Promise<unknown> | unknown\n mcpUpsert: (params: IpcParams<'mcp.upsert'>, peer: HostPeer) => Promise<unknown> | unknown\n mcpRemove: (params: IpcParams<'mcp.remove'>, peer: HostPeer) => Promise<unknown> | unknown\n setApiKey: (params: IpcParams<'auth.setApiKey'>) => unknown\n}\n\nconst MAX_DEVICE_FIELD = 200\n\nconst NOT_A_SERVER = 'This host takes no settings sync (a zidane-server does).'\n\nfunction checkDevice(p: { deviceId?: unknown, deviceName?: unknown }, withName: boolean): { deviceId: string, deviceName: string } {\n if (typeof p.deviceId !== 'string' || p.deviceId.trim() === '' || p.deviceId.length > MAX_DEVICE_FIELD)\n throw new InvalidParamsError('deviceId must be a non-empty string.')\n if (withName && (typeof p.deviceName !== 'string' || p.deviceName.trim() === '' || p.deviceName.length > MAX_DEVICE_FIELD))\n throw new InvalidParamsError('deviceName must be a non-empty string.')\n return { deviceId: p.deviceId, deviceName: typeof p.deviceName === 'string' ? p.deviceName.trim() : '' }\n}\n\nfunction checkCategories(value: unknown): SyncCategory[] | undefined {\n if (value === undefined)\n return undefined\n if (!Array.isArray(value) || !value.every(c => SYNC_CATEGORIES.includes(c as SyncCategory)))\n throw new InvalidParamsError(`categories must be some of: ${SYNC_CATEGORIES.join(', ')}.`)\n return SYNC_CATEGORIES.filter(c => value.includes(c))\n}\n\nexport function createSyncHandlers({ host, env, broadcast, setters, auth, options }: {\n host: Pick<ChatHost, 'rebuildAllAgents'>\n env: DaemonEnvironment\n broadcast: (signal: HostSignal) => void\n setters: SyncSetters\n auth: Pick<ProviderAuth, 'descriptorOf' | 'storedKeys'>\n options?: SyncOptions\n}): Handlers<SyncMethod> & { markOverrides: (fields: readonly string[]) => Promise<void> } {\n const store = createSyncStore(env.userDataDir())\n const ctx: SyncApplyContext = { env, setters, auth, home: () => homedir(), prefix: () => env.config.prefix }\n\n /** Sync calls (and override marks) one at a time: each reads the record, works, writes it. */\n let queue: Promise<unknown> = Promise.resolve()\n const exclusive = <T>(work: () => Promise<T> | T): Promise<T> => {\n const next = queue.then(work, work)\n queue = next.catch(() => undefined)\n return next\n }\n\n const changed = (): void => broadcast({ kind: 'sync:changed' })\n const audit = (peer: HostPeer, entry: Record<string, unknown>): void => options?.audit?.(peer, entry)\n\n function requireOptions(): void {\n if (!options)\n throw new Error(NOT_A_SERVER)\n }\n\n /** Mark fields the source set as edited here; nothing for fields nobody synced. */\n const markOverrides = (fields: readonly string[]): Promise<void> => {\n if (!options || fields.length === 0)\n return Promise.resolve()\n return exclusive(() => {\n const record = store.read()\n const marked = fields.filter(field => record.fields[field] && !record.overrides[field])\n if (marked.length === 0)\n return\n const at = Date.now()\n for (const field of marked)\n record.overrides[field] = { at }\n store.write(record)\n changed()\n })\n }\n\n /** Whether `deviceId` over `peer`'s token is the recorded source. */\n const isSource = (record: SyncRecord, deviceId: string, peer: HostPeer): boolean =>\n record.source !== null && record.source.deviceId === deviceId && record.source.tokenId === peer.principal\n\n /** The source's own call, or a refusal naming the device that syncs. */\n function requireSource(record: SyncRecord, deviceId: string, peer: HostPeer): void {\n if (!record.source)\n throw new Error('No device syncs to this server: claim it first (sync.claim).')\n if (!isSource(record, deviceId, peer))\n throw new Error(`This server is synced from ${record.source.deviceName}${record.source.deviceId === deviceId ? ' with another token' : ''}: take over from that device first.`)\n }\n\n const rebuild = (): void => {\n void host.rebuildAllAgents({ rediscover: true }).catch(() => undefined)\n }\n\n return {\n markOverrides,\n\n 'sync.status': (): SyncStatus => {\n requireOptions()\n return syncStatusOf(store.read())\n },\n\n 'sync.claim': (p, peer) => exclusive(() => {\n requireOptions()\n const { deviceId, deviceName } = checkDevice(p, true)\n const categories = checkCategories(p.categories)\n if (p.keys !== undefined && (!Array.isArray(p.keys) || !p.keys.every(k => typeof k === 'string')))\n throw new InvalidParamsError('keys must be provider names.')\n const takeover = p.takeover === true\n const record = store.read()\n const other = record.source !== null && !isSource(record, deviceId, peer)\n if (other && !takeover) {\n audit(peer, { event: 'sync.claim', deviceId, deviceName, takeover, claimed: false, ok: true })\n return { claimed: false, status: syncStatusOf(record) }\n }\n const next: SyncRecord = other\n ? { version: 1, source: null, categories: [], keys: [], fields: {}, overrides: {} }\n : record\n next.source = {\n deviceId,\n deviceName,\n claimedAt: other || !record.source ? Date.now() : record.source.claimedAt,\n ...(peer.principal ? { tokenId: peer.principal } : {}),\n }\n if (categories)\n next.categories = categories\n if (p.keys !== undefined)\n next.keys = [...new Set(p.keys)]\n store.write(next)\n changed()\n audit(peer, { event: 'sync.claim', deviceId, deviceName, takeover, claimed: true, categories: next.categories, keys: next.keys, ok: true })\n return { claimed: true, status: syncStatusOf(next) }\n }),\n\n 'sync.push': (p, peer) => exclusive(async () => {\n requireOptions()\n const { deviceId } = checkDevice(p, false)\n const category = p.category\n const fields = { event: 'sync.push', category, deviceId }\n try {\n if (!SYNC_CATEGORIES.includes(category))\n throw new InvalidParamsError(`category must be one of: ${SYNC_CATEGORIES.join(', ')}.`)\n const record = store.read()\n requireSource(record, deviceId, peer)\n if (!record.categories.includes(category))\n throw new Error(`\"${category}\" is not synced to this server (claim it with that category).`)\n const result: SyncPushResult = { applied: [], unchanged: [], skipped: [], warnings: [] }\n const payload = p.payload as unknown\n if (category === 'settings') {\n pushSettings(ctx, record, payload as SyncPayloads['settings'], result)\n }\n else if (category === 'safelists') {\n pushSafelists(ctx, record, payload as SyncPayloads['safelists'], result)\n }\n else if (category === 'files') {\n if (pushFiles(ctx, record, payload as SyncPayloads['files'], result)) {\n rebuild()\n broadcast({ kind: 'catalog:changed', catalog: 'skills' })\n }\n }\n else if (category === 'mcps') {\n await pushMcps(ctx, record, payload as SyncPayloads['mcps'], peer, result)\n }\n else if (category === 'extensions') {\n await pushExtensions(ctx, record, payload as SyncPayloads['extensions'], peer, result)\n }\n else {\n pushKeys(ctx, record, payload as SyncPayloads['keys'], result)\n }\n record.lastPushAt = Date.now()\n store.write(record)\n changed()\n audit(peer, { ...fields, applied: result.applied.length, unchanged: result.unchanged.length, skipped: result.skipped.length, ok: true })\n return result\n }\n catch (err) {\n audit(peer, { ...fields, ok: false, error: err instanceof Error ? err.message : String(err) })\n throw err\n }\n }),\n\n 'sync.reset': (p, peer) => exclusive(() => {\n requireOptions()\n if (typeof p.field !== 'string' || p.field === '')\n throw new InvalidParamsError('field must be a sync field name.')\n const record = store.read()\n const reset = Boolean(record.overrides[p.field])\n if (reset) {\n delete record.overrides[p.field]\n // Forget the server value it was compared against: the next push writes over it.\n const known = record.fields[p.field]\n if (known) {\n delete known.hash\n delete known.sent\n }\n store.write(record)\n changed()\n }\n audit(peer, { event: 'sync.reset', field: p.field, reset, ok: true })\n return { reset }\n }),\n\n 'sync.release': (p, peer) => exclusive(() => {\n requireOptions()\n const { deviceId } = checkDevice(p, false)\n const record = store.read()\n if (!record.source)\n return { released: false }\n requireSource(record, deviceId, peer)\n // What it set stays; the marks go.\n store.write({ version: 1, source: null, categories: [], keys: [], fields: {}, overrides: {} })\n changed()\n audit(peer, { event: 'sync.release', deviceId, ok: true })\n return { released: true }\n }),\n }\n}\n\ntype OverrideWrapped = 'settings.set' | 'mcp.upsert' | 'mcp.remove' | 'catalog.remove' | 'catalog.update' | 'auth.setApiKey' | 'auth.remove'\n\n/**\n * The window-facing setters, marking what they change as an override when\n * the field came from sync (the sync handlers call the unwrapped ones).\n */\nexport function withSyncOverrides(\n handlers: Handlers<OverrideWrapped>,\n { readSettings, markOverrides }: { readSettings: () => object, markOverrides: (fields: readonly string[]) => Promise<void> },\n): Handlers<OverrideWrapped> {\n const after = async <T>(work: () => Promise<T> | T, fields: (result: T) => string[]): Promise<T> => {\n const result = await work()\n await markOverrides(fields(result))\n return result\n }\n return {\n 'settings.set': async (p, peer) => {\n const before = readSettings() as Record<string, unknown>\n return after(() => handlers['settings.set'](p, peer), next => Object.keys(isRecord(p?.patch) ? p.patch : {})\n .filter(key => JSON.stringify(before[key]) !== JSON.stringify((next as unknown as Record<string, unknown>)[key]))\n .map(settingField))\n },\n 'mcp.upsert': (p, peer) => after(() => handlers['mcp.upsert'](p, peer), r => [`mcp:${r.name}`]),\n 'mcp.remove': (p, peer) => after(() => handlers['mcp.remove'](p, peer), r => (r.removed ? [`mcp:${p.name}`] : [])),\n 'catalog.remove': (p, peer) => after(() => handlers['catalog.remove'](p, peer), () => [`${p.kind}:${p.name}`]),\n 'catalog.update': (p, peer) => after(() => handlers['catalog.update'](p, peer), () => [`${p.kind}:${p.name}`]),\n 'auth.setApiKey': (p, peer) => after(() => handlers['auth.setApiKey'](p, peer), () => [`key:${p.provider}`]),\n 'auth.remove': (p, peer) => after(() => handlers['auth.remove'](p, peer), r => (r.removed ? [`key:${p.provider}`] : [])),\n }\n}\n","/** Shared terminals: lifecycle, I/O, and the views and viewers each client attaches. */\nimport type { ChatHost } from '../../../chat/host/engine'\nimport type { HostPeer } from '../peers'\nimport type { Handlers } from './types'\n\ntype TerminalMethod\n = | 'terminal.state' | 'terminal.open' | 'terminal.attach' | 'terminal.detach' | 'terminal.write'\n | 'terminal.resize' | 'terminal.ack' | 'terminal.restart' | 'terminal.close' | 'terminal.setHidden'\n | 'terminal.registerViewer' | 'terminal.unregisterViewer'\n\nexport function createTerminalHandlers({ host, isConnected }: {\n host: ChatHost\n isConnected: (peer: HostPeer) => boolean\n}): {\n methods: Handlers<TerminalMethod>\n /** The peer dropped: release its viewers, then detach its views. */\n releasePeer: (peer: HostPeer) => void\n} {\n return {\n methods: {\n 'terminal.state': p => host.terminals.state(p.sessionId),\n 'terminal.open': p => host.terminals.open(p),\n 'terminal.attach': async (p, peer) => {\n const result = await host.terminals.attach(p.terminalId, p.clientId)\n // The peer dropped during the attach (a remote reconnect can take seconds):\n // its cleanup already ran, so a client left behind would never ack and stall every view.\n if (!isConnected(peer)) {\n host.terminals.detach(p.terminalId, p.clientId)\n return result\n }\n const views = (peer.terminalViews ??= new Map())\n views.set(p.terminalId, (views.get(p.terminalId) ?? new Set()).add(p.clientId))\n return result\n },\n 'terminal.detach': (p, peer) => {\n const views = peer.terminalViews?.get(p.terminalId)\n views?.delete(p.clientId)\n if (views?.size === 0)\n peer.terminalViews?.delete(p.terminalId)\n host.terminals.detach(p.terminalId, p.clientId)\n },\n 'terminal.write': p => host.terminals.write(p.terminalId, p.data, p.clientId ? { clientId: p.clientId, ...(p.response ? { response: true } : {}) } : undefined),\n 'terminal.resize': p => host.terminals.resize(p.terminalId, p.clientId, p.cols, p.rows, p.claim),\n 'terminal.ack': p => host.terminals.ack(p.terminalId, p.clientId, p.offset),\n 'terminal.restart': p => host.terminals.restart(p.terminalId),\n 'terminal.close': p => host.terminals.close(p.terminalId),\n 'terminal.setHidden': p => host.terminals.setHidden(p.terminalId, p.hidden),\n 'terminal.registerViewer': (p, peer) => {\n ;(peer.terminalViewers ??= new Set()).add(p.viewerId)\n host.terminals.registerViewer(p.viewerId)\n return { ok: true }\n },\n 'terminal.unregisterViewer': (p, peer) => {\n peer.terminalViewers?.delete(p.viewerId)\n host.terminals.unregisterViewer(p.viewerId)\n return { ok: true }\n },\n },\n releasePeer(peer) {\n for (const viewerId of peer.terminalViewers ?? [])\n host.terminals.unregisterViewer(viewerId)\n for (const [terminalId, clients] of peer.terminalViews ?? []) {\n for (const clientId of clients)\n host.terminals.detach(terminalId, clientId)\n }\n },\n }\n}\n","/** `sessions.generateTitle`: the host titles a session with its own providers and credentials (`ChatHost.generateSessionTitle`). */\nimport type { ChatHost } from '../../../chat/host/engine'\nimport type { HostSignal } from '../../protocol'\nimport type { Handlers } from './types'\nimport { optionalString, sessionIdOf } from './params'\n\nexport function createTitleHandlers({ host, broadcast }: {\n host: ChatHost\n broadcast: (signal: HostSignal) => void\n}): Handlers<'sessions.generateTitle'> {\n return {\n 'sessions.generateTitle': async (p) => {\n const sessionId = sessionIdOf(p)\n const providerKey = optionalString(p.providerKey, 'providerKey')\n const model = optionalString(p.model, 'model')\n const title = await host.generateSessionTitle(sessionId, {\n ...(providerKey !== undefined ? { providerKey } : {}),\n ...(model !== undefined ? { model } : {}),\n })\n // As `sessions.setTitle`: every window told.\n broadcast({ kind: 'sessions:changed', op: 'update', sessionId })\n return { title }\n },\n }\n}\n","/** A session's todo list. */\nimport type { ChatHost } from '../../../chat/host/engine'\nimport type { TodoItem } from '../../../chat/todos'\nimport type { SessionStore } from '../../../session/index'\nimport type { TodosSnapshot } from '../../protocol'\nimport type { Handlers } from './types'\nimport { toTodosSnapshot } from '../../../chat/host/signals'\nimport { selectActiveTodos, setTodosForRun } from '../../../chat/todos'\nimport { loadSession } from '../../../session/index'\n\nexport function createTodoHandlers({ host, store }: { host: ChatHost, store: SessionStore }): Handlers<'todos.get' | 'todos.set'> {\n return {\n 'todos.get': (p): TodosSnapshot | null => {\n const state = host.getTodosSnapshot(p.sessionId)\n return state ? toTodosSnapshot(state) : null\n },\n\n /*\n * The host fans the resulting `todos:snapshot` out to every window,\n * including this caller — the returned snapshot is a confirmation, so the\n * sender can tell \"applied\" from \"no live agent\" (null) rather than\n * assuming success. `persistIdle` turns \"no live agent\" into a write to\n * the stored session (nothing else is writing it), for a client that has\n * no store of its own.\n */\n 'todos.set': async (p): Promise<TodosSnapshot | null> => {\n const state = await host.setTodos(p.sessionId, p.items)\n if (state)\n return toTodosSnapshot(state)\n if (p.persistIdle !== true || host.getLiveSession(p.sessionId))\n return null\n return persistIdleTodos(store, p.sessionId, Array.isArray(p.items) ? p.items : [])\n },\n }\n}\n\n/** The idle-session todo edit, as a window applied it to its own copy: the active run's list, archive cleared. */\nasync function persistIdleTodos(store: SessionStore, sessionId: string, items: readonly TodoItem[]): Promise<TodosSnapshot | null> {\n const session = await loadSession(store, sessionId, { persistHeal: false })\n const runId = session ? selectActiveTodos(session).runId : null\n if (!session || !runId)\n return null\n setTodosForRun(session, runId, items, { clearArchive: true })\n await session.save()\n return toTodosSnapshot(selectActiveTodos(session))\n}\n","/** A session's turns: replay, fork, edits, out-of-band appends, and compaction. */\nimport type { ChatHost } from '../../../chat/host/engine'\nimport type { StreamEvent } from '../../../chat/index'\nimport type { SessionStore } from '../../../session/index'\nimport type { HostSignal, LoadEventsPaging } from '../../protocol'\nimport type { TranscriptReplayCache } from './transcript-cache'\nimport type { Handlers } from './types'\nimport { describeForkFailure, eventsFromTurns } from '../../../chat/index'\nimport { loadOrThrow } from './sessions'\nimport { isPagedLoad } from './transcript-page'\n\ntype TranscriptMethod\n = | 'sessions.loadEvents' | 'sessions.getTurn' | 'sessions.touch' | 'sessions.fork' | 'sessions.deleteTurn'\n | 'sessions.editTurnText' | 'sessions.appendTurns' | 'sessions.appendNote' | 'sessions.compact'\n\nexport function createTranscriptHandlers({ host, store, broadcast, replays }: {\n host: ChatHost\n store: SessionStore\n broadcast: (signal: HostSignal) => void\n /** The whole replays pages are sliced from (one replay per scroll-back, not per page). */\n replays: TranscriptReplayCache\n}): Handlers<TranscriptMethod> {\n return {\n 'sessions.loadEvents': async (p) => {\n const paging = p as typeof p & LoadEventsPaging\n if (isPagedLoad(paging)) {\n // A slice of the whole replay: pages concatenate to exactly one whole load.\n // The paged shape (`loadEventsPage`); the method is typed by its unpaged call.\n return await replays.page(store, p.sessionId, paging) as unknown as StreamEvent[]\n }\n const data = await loadOrThrow(store, p.sessionId)\n // Pass `runs` so replay reconstructs subagent depth / ancestry /\n // spawn rendering — matching the GUI + TUI local replay paths.\n return eventsFromTurns(data.turns, data.runs)\n },\n 'sessions.getTurn': async (p) => {\n const data = await store.load(p.sessionId)\n return data?.turns.find(t => t.id === p.turnId) ?? null\n },\n // Out-of-band transcript append (local command / bash output) — tell\n // every window to re-converge on the store's canonical replay.\n 'sessions.touch': (p) => {\n broadcast({ kind: 'sessions:changed', op: 'update', sessionId: p.sessionId })\n },\n 'sessions.fork': async (p) => {\n const result = await host.forkSession({\n source: p.sessionId,\n turnId: p.turnId,\n ...(typeof p.title === 'string' && p.title ? { title: p.title.slice(0, 256) } : {}),\n })\n if (!result.ok)\n throw new Error(describeForkFailure(result.reason, p.sessionId, p.turnId))\n broadcast({ kind: 'sessions:changed', op: 'create', sessionId: result.id })\n return { id: result.id }\n },\n 'sessions.deleteTurn': p => host.deleteTurn(p.sessionId, p.turnId),\n // Same 64 KiB text cap as the composer paths.\n 'sessions.editTurnText': p => host.editTurnText(p.sessionId, p.turnId, typeof p.text === 'string' ? p.text.slice(0, 64 * 1024) : ''),\n 'sessions.appendTurns': p => host.appendTurns(p.sessionId, Array.isArray(p.turns) ? p.turns : []),\n 'sessions.appendNote': p => host.appendNote(\n p.sessionId,\n Array.isArray(p.blocks) ? p.blocks.filter(block => typeof block?.text === 'string') : [],\n ),\n 'sessions.compact': p => host.compactSessionNow(p.sessionId),\n }\n}\n","/**\n * Whole-session reads a client pages through, kept per session content\n * version so N pages cost one read of the session, not N:\n *\n * - the replay behind `sessions.loadEvents` pages (each page is a slice of\n * the WHOLE replay: see `replayTurns`);\n * - the document behind `sessions.getTurns` pages and the `sessions.get`\n * `turns: false` head (`document`): loaded, healed and copied once.\n * Every page carries its version, so a client that sees it change\n * mid-load starts over instead of mixing two versions\n * (`loadSessionDocument`).\n *\n * The version: a store with `getMeta` answers it without parsing turns\n * (its change counter `rev`, `updatedAt`, the turn and run counts; a hit\n * then skips the load too). `rev` grows on every write, so a version never\n * comes back after a change, whatever `updatedAt` a writer stamps (another\n * process on the same sessions.db included, which no host signal covers).\n * The version is read again after a miss's load: when it moved meanwhile,\n * what was loaded is of no known version, so it is served under a label no\n * other read gets, and not kept. A store without `rev` keeps the older\n * rule: a version stamped in the millisecond the read started is served\n * but not kept. Any other store's loaded document is fingerprinted (turn\n * ids, roles, block shapes and text lengths, the runs), and so is a live\n * session's in-memory copy (plus its metadata and status). The host's own\n * writes also drop entries by their signals (`observe`), which covers the\n * edits a version cannot see.\n *\n * Bounded: a few sessions per kind, least recently used first out, and a\n * byte budget (an entry over it is served, not kept). Besides the entries,\n * a session is tracked only while a read of it is in flight (so a drop\n * meanwhile stops that read's result from being kept): a session that is\n * dropped, forgotten or signalled leaves nothing behind.\n */\nimport type { StreamEvent } from '../../../chat/index'\nimport type { Session, SessionData, SessionRun, SessionStore } from '../../../session/index'\nimport type { SessionTurn } from '../../../types'\nimport type { HostSignal, LoadEventsPaging, SessionEventsPage } from '../../protocol'\nimport { replayTurns } from '../../../chat/store'\nimport { loadSession } from '../../../session/index'\nimport { loadOrThrow } from './sessions'\nimport { exchangeBoundaries, transcriptPage, turnCutPoints } from './transcript-page'\n\nconst DEFAULT_MAX_SESSIONS = 4\nconst DEFAULT_MAX_BYTES = 64 * 1024 * 1024\n\n/** Signals that follow a change to a session's turns or runs. */\nconst CHANGE_SIGNALS = new Set<HostSignal['kind']>(['sessions:changed', 'run:start', 'run:end', 'turn:end', 'compacting:end', 'prompt-turns'])\n\ninterface Versioned {\n version: string\n bytes: number\n}\n\ninterface Replay extends Versioned {\n events: StreamEvent[]\n /** Where each turn's events start (`[turns]` = the end). */\n turnStarts: number[]\n boundaries: boolean[]\n /** Where a run too long for one page may be split (`turnCutPoints`). */\n cuts: boolean[]\n}\n\n/** One version of a session's document, as `sessions.get` would send it. */\nexport interface DocumentSnapshot extends Versioned {\n data: SessionData\n}\n\nexport interface TranscriptReplayCache {\n page: (store: SessionStore, sessionId: string, paging: LoadEventsPaging) => Promise<SessionEventsPage>\n /** The document (the live copy when `live` is given, else the stored one, healed in memory), and its version; `null` when unknown. */\n document: (store: SessionStore, sessionId: string, live: Session | null) => Promise<DocumentSnapshot | null>\n /** A host signal: one that follows a change to a session drops its entries. */\n observe: (signal: HostSignal) => void\n forget: (sessionId: string) => void\n /** Entries kept and sessions with a read in flight, across both kinds: what the cache holds. */\n sizes: () => { entries: number, inFlight: number }\n}\n\n/** A read in flight: a drop of its session meanwhile marks it, and its result is then served but not kept. */\ninterface InFlightRead { dropped: boolean }\n\n/** One kind of entry (replays, documents): LRU by insertion order, bounded by count and bytes. */\nfunction createLru<T extends Versioned>(maxSessions: number, maxBytes: number) {\n const entries = new Map<string, T>()\n let totalBytes = 0\n const drop = (sessionId: string): void => {\n const entry = entries.get(sessionId)\n if (entry) {\n totalBytes -= entry.bytes\n entries.delete(sessionId)\n }\n }\n return {\n size: () => entries.size,\n hit(sessionId: string, version: string): T | undefined {\n const entry = entries.get(sessionId)\n if (!entry || entry.version !== version)\n return undefined\n entries.delete(sessionId)\n entries.set(sessionId, entry)\n return entry\n },\n drop,\n keep(sessionId: string, entry: T): void {\n if (entry.bytes > maxBytes)\n return\n drop(sessionId)\n entries.set(sessionId, entry)\n totalBytes += entry.bytes\n for (const [id, oldest] of entries) {\n if (entries.size <= maxSessions && totalBytes <= maxBytes)\n break\n entries.delete(id)\n totalBytes -= oldest.bytes\n }\n },\n }\n}\n\nexport function createTranscriptReplayCache(options: {\n maxSessions?: number\n maxBytes?: number\n /** The replay (a seam for counting it). */\n replay?: typeof replayTurns\n} = {}): TranscriptReplayCache {\n const maxSessions = options.maxSessions ?? DEFAULT_MAX_SESSIONS\n const maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES\n const replay = options.replay ?? replayTurns\n const replays = createLru<Replay>(maxSessions, maxBytes)\n const documents = createLru<DocumentSnapshot>(maxSessions, maxBytes)\n const inFlight = new Map<string, Set<InFlightRead>>()\n /** Labels a read of no known version: never equal to another read's. */\n let unversioned = 0\n\n function drop(sessionId: string): void {\n for (const read of inFlight.get(sessionId) ?? [])\n read.dropped = true\n replays.drop(sessionId)\n documents.drop(sessionId)\n }\n\n /** Run `fn` as an in-flight read of `sessionId`, tracked only while it runs. */\n async function tracked<R>(sessionId: string, fn: (read: InFlightRead) => Promise<R>): Promise<R> {\n const read: InFlightRead = { dropped: false }\n const reads = inFlight.get(sessionId) ?? new Set<InFlightRead>()\n inFlight.set(sessionId, reads.add(read))\n try {\n return await fn(read)\n }\n finally {\n reads.delete(read)\n if (reads.size === 0 && inFlight.get(sessionId) === reads)\n inFlight.delete(sessionId)\n }\n }\n\n /**\n * A stored session's entry of `lru`, built from `load` on a miss. The\n * version comes from `getMeta` when the store has it (see the header),\n * else from the loaded data (`fingerprintOf`).\n */\n function stored<T extends Versioned, D>(\n lru: ReturnType<typeof createLru<T>>,\n store: SessionStore,\n sessionId: string,\n load: () => Promise<D | null>,\n build: (data: D, version: string) => T,\n fingerprintOf: (data: D) => string,\n ): Promise<T | null> {\n return tracked(sessionId, async (read) => {\n if (store.getMeta) {\n const readAt = Date.now()\n const meta = await store.getMeta(sessionId)\n if (!meta)\n return null\n const version = storeVersion(meta)\n const cached = lru.hit(sessionId, version)\n if (cached)\n return cached\n const data = await load()\n if (data === null)\n return null\n let settled: boolean\n if (meta.rev !== undefined) {\n const after = await store.getMeta(sessionId)\n settled = after !== null && storeVersion(after) === version\n }\n else {\n settled = meta.updatedAt < readAt\n }\n const entry = build(data, settled ? version : `${version}~${++unversioned}`)\n if (settled && !read.dropped)\n lru.keep(sessionId, entry)\n return entry\n }\n const data = await load()\n if (data === null)\n return null\n const version = fingerprintOf(data)\n const cached = lru.hit(sessionId, version)\n if (cached)\n return cached\n const entry = build(data, version)\n if (!read.dropped)\n lru.keep(sessionId, entry)\n return entry\n })\n }\n\n function buildReplay(data: SessionData, version: string): Replay {\n const { events, turnStarts } = replay(data.turns, data.runs)\n return { version, events, turnStarts, boundaries: exchangeBoundaries(data.turns, data.runs), cuts: turnCutPoints(data.turns), bytes: JSON.stringify(events).length }\n }\n\n const snapshotOf = (data: SessionData, version: string): DocumentSnapshot => ({ version, data, bytes: JSON.stringify(data).length })\n\n return {\n async page(store, sessionId, paging) {\n const entry = await stored(replays, store, sessionId, () => loadOrThrow(store, sessionId), buildReplay, data => fingerprint(data.updatedAt, data.turns, data.runs))\n if (!entry)\n throw new Error(`Session \"${sessionId}\" not found.`)\n const { from, to, cursor } = transcriptPage(entry.boundaries, paging, entry.cuts)\n const events = entry.events.slice(entry.turnStarts[from], entry.turnStarts[to])\n return { events, exact: true, start: entry.turnStarts[from]!, ...(cursor !== undefined ? { cursor } : {}) }\n },\n async document(store, sessionId, live) {\n if (live) {\n // The live copy: ahead of the store mid-run, and holding the todos.\n const version = `live:${fingerprint(0, live.turns, live.runs)}:${hashText(JSON.stringify([live.status, live.metadata]))}`\n return tracked(sessionId, async (read) => {\n const cached = documents.hit(sessionId, version)\n if (cached)\n return cached\n const entry = snapshotOf(live.toJSON(), version)\n if (!read.dropped)\n documents.keep(sessionId, entry)\n return entry\n })\n }\n // A reader: a load-time pairing heal stays in memory, the host's own agent persists the document.\n const load = async (): Promise<SessionData | null> => (await loadSession(store, sessionId, { persistHeal: false }))?.toJSON() ?? null\n return stored(documents, store, sessionId, load, snapshotOf, data => fingerprint(data.updatedAt, data.turns, data.runs))\n },\n observe(signal) {\n if (CHANGE_SIGNALS.has(signal.kind) && 'sessionId' in signal && typeof signal.sessionId === 'string')\n drop(signal.sessionId)\n },\n forget: drop,\n sizes: () => ({ entries: replays.size() + documents.size(), inFlight: inFlight.size }),\n }\n}\n\nfunction storeVersion(meta: { rev?: number, updatedAt: number, turnCount: number, runCount: number }): string {\n return `meta:${meta.rev ?? '-'}:${meta.updatedAt}:${meta.turnCount}:${meta.runCount}`\n}\n\n/** A 32-bit FNV-1a: `mix` values in, `digest` (base 36) out. */\nfunction fnv1a() {\n let hash = 0x811C9DC5\n const add = (text: string): void => {\n for (let i = 0; i < text.length; i++)\n hash = Math.imul(hash ^ text.charCodeAt(i), 0x01000193)\n }\n return {\n add,\n /** One value, then a separator: `ab` + `c` never hashes as `a` + `bc`. */\n mix: (value: string | number | undefined): void => {\n add(String(value))\n hash = Math.imul(hash ^ 0x1F, 0x01000193)\n },\n digest: (): string => (hash >>> 0).toString(36),\n }\n}\n\nfunction hashText(text: string): string {\n const hash = fnv1a()\n hash.add(text)\n return hash.digest()\n}\n\n/** FNV-1a over the document's shape: what changes when a turn or run is added, removed, or rewritten. */\nfunction fingerprint(updatedAt: number, turns: readonly SessionTurn[], runs: readonly SessionRun[]): string {\n const { mix, digest } = fnv1a()\n for (const turn of turns) {\n mix(turn.id)\n mix(turn.role)\n mix(turn.runId)\n mix(typeof turn.display === 'string' ? turn.display : '')\n mix(turn.content.length)\n for (const block of turn.content) {\n mix(block.type)\n const fields = block as { text?: unknown, output?: unknown, summary?: unknown }\n for (const field of [fields.text, fields.output, fields.summary])\n mix(typeof field === 'string' ? field.length : Array.isArray(field) ? field.length : '')\n }\n }\n mix(JSON.stringify(runs))\n return `doc:${updatedAt}:${turns.length}:${runs.length}:${digest()}`\n}\n","/** Commands and file access inside a session's workspace (its execution environment). */\nimport type { ChatHost } from '../../../chat/host/engine'\nimport type { Handlers } from './types'\n\ntype WorkspaceMethod\n = | 'sessions.workspaceExec' | 'sessions.workspaceReadFile' | 'sessions.workspaceWriteFile'\n | 'sessions.workspaceListFiles' | 'sessions.workspaceFileSize'\n\nexport function createWorkspaceHandlers({ host }: { host: ChatHost }): Handlers<WorkspaceMethod> {\n return {\n 'sessions.workspaceExec': p => host.workspaceExec(p.sessionId, p.command, {\n ...(p.cwd !== undefined ? { cwd: p.cwd } : {}),\n ...(p.env !== undefined ? { env: p.env } : {}),\n ...(p.timeoutSeconds !== undefined ? { timeoutSeconds: p.timeoutSeconds } : {}),\n }),\n 'sessions.workspaceReadFile': p => host.workspaceReadFile(p.sessionId, p.path),\n 'sessions.workspaceWriteFile': p => host.workspaceWriteFile(p.sessionId, p.path, p.content),\n 'sessions.workspaceListFiles': p => host.workspaceListFiles(p.sessionId, p.path, p.options),\n 'sessions.workspaceFileSize': p => host.workspaceFileSize(p.sessionId, p.path),\n }\n}\n","import type { ChatHost } from '../../../chat/host/engine'\n/**\n * Streamed workspace commands (`sessions.workspaceExecStream` /\n * `sessions.workspaceExecCancel`): `!` on a remote host, live. The process\n * is the session context's `execStream` (a machine's too); its output goes\n * to the connection that started it only, as `workspace:exec:data` signals,\n * then one `workspace:exec:exit`. Bounded per connection: concurrent\n * commands, chunk size, total output (past it the process group is stopped\n * and the exit says `truncated`). Cancel and a dropped connection kill the\n * process group. A context that can't stream runs the buffered exec and\n * reports it the same way (its cancel stops reporting, not the command).\n */\nimport type { StreamHandle } from '../../../contexts/types'\nimport type { HostSignal } from '../../protocol'\nimport type { HostPeer } from '../peers'\nimport type { Handlers } from './types'\nimport { Buffer } from 'node:buffer'\nimport { randomUUID } from 'node:crypto'\nimport { InvalidParamsError } from './params'\n\nexport const WORKSPACE_EXEC_STREAM_LIMITS = {\n /** Streamed commands one connection may run at once. */\n maxConcurrent: 4,\n /** Largest `chunk` of one data signal, in bytes. */\n chunkBytes: 64 * 1024,\n /** Output past this (stdout + stderr, bytes) stops the process: the same ceiling as a local `!`. */\n maxOutputBytes: 1024 * 1024,\n /** Longest command text. */\n maxCommandLength: 64 * 1024,\n /** The buffered fallback's bound (seconds), as the buffered `!` had. */\n fallbackTimeoutSeconds: 600,\n}\n\ntype ExitSignal = Extract<HostSignal, { kind: 'workspace:exec:exit' }>\n\ninterface RunningExec {\n peer: HostPeer\n /** Ends the process group (the fallback: stops reporting). */\n kill: () => void\n cancelled: boolean\n /** A kill was sent before the process's exit was known: the exit is the kill's. */\n killedLive?: boolean\n}\n\n/** Cut `text` into pieces of at most `max` UTF-8 bytes, never inside a code point. */\nfunction utf8Pieces(text: string, max: number): string[] {\n if (Buffer.byteLength(text) <= max)\n return [text]\n const pieces: string[] = []\n let current = ''\n let bytes = 0\n for (const char of text) {\n const size = Buffer.byteLength(char)\n if (bytes + size > max) {\n pieces.push(current)\n current = ''\n bytes = 0\n }\n current += char\n bytes += size\n }\n if (current)\n pieces.push(current)\n return pieces\n}\n\n/** The longest prefix of `text` within `max` UTF-8 bytes. */\nfunction utf8Prefix(text: string, max: number): string {\n let bytes = 0\n let end = 0\n for (const char of text) {\n const size = Buffer.byteLength(char)\n if (bytes + size > max)\n break\n bytes += size\n end += char.length\n }\n return text.slice(0, end)\n}\n\nexport function createWorkspaceExecStreamHandlers({ host, isConnected, limits = WORKSPACE_EXEC_STREAM_LIMITS }: {\n host: Pick<ChatHost, 'workspaceExecStream' | 'workspaceExec'>\n isConnected: (peer: HostPeer) => boolean\n limits?: typeof WORKSPACE_EXEC_STREAM_LIMITS\n}): {\n methods: Handlers<'sessions.workspaceExecStream' | 'sessions.workspaceExecCancel'>\n /** The peer dropped: kill what it started. */\n releasePeer: (peer: HostPeer) => void\n} {\n const running = new Map<string, RunningExec>()\n const perPeer = new WeakMap<HostPeer, Set<string>>()\n\n const send = (peer: HostPeer, signal: HostSignal): void => {\n if (isConnected(peer))\n peer.send(signal)\n }\n\n /** Output accounting for one exec: emits what fits, reports when the cap is reached. */\n function outputSink(execId: string, peer: HostPeer, onCap: () => void) {\n let total = 0\n let capped = false\n return {\n capped: () => capped,\n emit(stream: 'stdout' | 'stderr', text: string): void {\n if (capped || text === '')\n return\n let piece = text\n if (total + Buffer.byteLength(piece) > limits.maxOutputBytes) {\n piece = utf8Prefix(piece, limits.maxOutputBytes - total)\n capped = true\n }\n total += Buffer.byteLength(piece)\n for (const chunk of piece ? utf8Pieces(piece, limits.chunkBytes) : [])\n send(peer, { kind: 'workspace:exec:data', execId, stream, chunk })\n if (capped)\n onCap()\n },\n }\n }\n\n async function pump(execId: string, peer: HostPeer, stream: StreamHandle, entry: RunningExec): Promise<void> {\n const sink = outputSink(execId, peer, () => entry.kill())\n const drain = async (source: AsyncIterable<Uint8Array> | undefined, name: 'stdout' | 'stderr'): Promise<void> => {\n if (!source)\n return\n const decoder = new TextDecoder()\n try {\n for await (const bytes of source)\n sink.emit(name, decoder.decode(bytes, { stream: true }))\n sink.emit(name, decoder.decode())\n }\n catch {\n // The stream ended badly (a dropped machine link): the exit says how.\n }\n }\n const [code] = await Promise.all([stream.exited, drain(stream.stdout, 'stdout'), drain(stream.stderr, 'stderr')])\n // A cancel or cap that landed after the process exited on its own leaves its real exit.\n const killed = entry.killedLive === true\n const exit: ExitSignal = {\n kind: 'workspace:exec:exit',\n execId,\n code: killed ? null : code,\n signal: killed ? 'SIGTERM' : null,\n ...(sink.capped() ? { truncated: true as const } : {}),\n ...(entry.cancelled && killed ? { cancelled: true as const } : {}),\n }\n send(peer, exit)\n }\n\n /** A context without `execStream`: the buffered exec, reported as one stdout and one stderr chunk. */\n async function buffered(execId: string, peer: HostPeer, entry: RunningExec, run: () => Promise<{ stdout: string, stderr: string, exitCode: number }>): Promise<void> {\n let stopped = false\n entry.kill = () => {\n stopped = true\n }\n const sink = outputSink(execId, peer, () => undefined)\n try {\n const result = await run()\n if (!stopped) {\n sink.emit('stdout', result.stdout)\n sink.emit('stderr', result.stderr)\n }\n send(peer, {\n kind: 'workspace:exec:exit',\n execId,\n code: stopped ? null : result.exitCode,\n signal: stopped ? 'SIGTERM' : null,\n ...(sink.capped() ? { truncated: true as const } : {}),\n ...(entry.cancelled ? { cancelled: true as const } : {}),\n })\n }\n catch (err) {\n sink.emit('stderr', err instanceof Error ? err.message : String(err))\n send(peer, { kind: 'workspace:exec:exit', execId, code: null, signal: null, ...(entry.cancelled ? { cancelled: true as const } : {}) })\n }\n }\n\n return {\n methods: {\n 'sessions.workspaceExecStream': async (p, peer) => {\n if (typeof p.sessionId !== 'string' || p.sessionId === '')\n throw new InvalidParamsError('sessionId must be a non-empty string.')\n if (typeof p.command !== 'string' || p.command.trim() === '')\n throw new InvalidParamsError('command must be a non-empty string.')\n if (p.command.length > limits.maxCommandLength)\n throw new InvalidParamsError(`command is longer than ${limits.maxCommandLength} characters.`)\n if (p.cwd !== undefined && typeof p.cwd !== 'string')\n throw new InvalidParamsError('cwd must be a string.')\n const own = perPeer.get(peer) ?? new Set<string>()\n perPeer.set(peer, own)\n if (own.size >= limits.maxConcurrent)\n throw new Error(`This connection already runs ${own.size} shell commands (at most ${limits.maxConcurrent}): stop one first.`)\n const execId = randomUUID()\n // Reserved before the await: concurrent requests count against the bound too.\n own.add(execId)\n const entry: RunningExec = { peer, kill: () => undefined, cancelled: false }\n running.set(execId, entry)\n const done = (): void => {\n own.delete(execId)\n running.delete(execId)\n }\n const options = p.cwd !== undefined ? { cwd: p.cwd } : {}\n let stream: StreamHandle | null\n try {\n stream = await host.workspaceExecStream(p.sessionId, p.command, options)\n }\n catch (err) {\n done()\n throw err\n }\n if (stream) {\n const live = stream\n let exited = false\n void live.exited.then(() => {\n exited = true\n }, () => {\n exited = true\n })\n entry.kill = () => {\n if (!exited)\n entry.killedLive = true\n void live.kill()\n }\n // Dropped while it started: nobody will read it.\n if (!isConnected(peer))\n entry.kill()\n void pump(execId, peer, live, entry).finally(done)\n }\n else {\n void buffered(execId, peer, entry, () => host.workspaceExec(p.sessionId, p.command, { ...options, timeoutSeconds: limits.fallbackTimeoutSeconds })).finally(done)\n }\n return { execId }\n },\n 'sessions.workspaceExecCancel': (p, peer) => {\n const entry = typeof p.execId === 'string' ? running.get(p.execId) : undefined\n if (!entry || entry.peer !== peer)\n return { cancelled: false }\n entry.cancelled = true\n entry.kill()\n return { cancelled: true }\n },\n },\n releasePeer(peer) {\n for (const execId of perPeer.get(peer) ?? []) {\n const entry = running.get(execId)\n if (entry) {\n entry.cancelled = true\n entry.kill()\n }\n }\n },\n }\n}\n","/**\n * `ipc.hello` verdict: can this client attach to this host process?\n *\n * Pure (no I/O, no state) so every transport applies the same three fences:\n * protocol version, build fingerprint, release. Kept apart from the\n * dispatcher because the rules are subtle and the direction of each fence\n * (only a strictly NEWER client retires the host) matters more than the code.\n *\n * A network server (`hostKind: 'server'`) keeps only the protocol fence: it\n * outlives any one client's upgrade and no client may retire it, so a newer\n * release or build attaches and degrades like an older one does.\n */\nimport type { HelloParams, HostKind } from '../protocol'\nimport { compareVersions } from '../../version'\nimport { IPC_PROTOCOL_VERSION } from '../protocol'\n\nexport type HelloVerdict\n /** `retire`: attach, but the host must exit at its first idle point. */\n = | { accept: true, retire: boolean }\n | { accept: false, message: string }\n\nexport interface HelloContext {\n /** This host's build fingerprint (`IPC_BUILD_ID`; `'unknown'` in compiled binaries). */\n buildId: string\n /** This host's release (`ZIDANE_VERSION`). */\n codeVersion: string\n /** Runs, queues or interactions in flight that a drain would abort. */\n hasActiveWork: boolean\n /** What this host is. Default: a local daemon's fences. */\n hostKind?: HostKind\n}\n\nfunction evaluateServerHello(params: Partial<HelloParams>): HelloVerdict {\n if (params.protocolVersion === IPC_PROTOCOL_VERSION)\n return { accept: true, retire: false }\n const client = typeof params.protocolVersion === 'number' ? params.protocolVersion : undefined\n const upgrade = client !== undefined && client > IPC_PROTOCOL_VERSION ? 'server' : 'client'\n return {\n accept: false,\n message: `Protocol version mismatch: the server speaks v${IPC_PROTOCOL_VERSION}, the client v${client ?? '?'}. Upgrade the ${upgrade}.`,\n }\n}\n\nexport function evaluateHello(params: Partial<HelloParams>, ctx: HelloContext): HelloVerdict {\n if (ctx.hostKind === 'server')\n return evaluateServerHello(params)\n /*\n * Build-fingerprint drain is DIRECTIONAL: only a strictly NEWER\n * client retires this (older) daemon. An older client accepts a\n * newer daemon — its unknown methods degrade via `optional()`.\n * Without the direction check, two concurrently-running clients\n * from different builds would each reject the other's daemon and\n * drain-respawn in a loop, aborting live runs each cycle.\n */\n const clientBuild = Number(params.buildId)\n const daemonBuild = Number(ctx.buildId)\n const staleBuild\n = params.buildId !== undefined\n && params.buildId !== 'unknown'\n && ctx.buildId !== 'unknown'\n && Number.isFinite(clientBuild)\n && Number.isFinite(daemonBuild)\n && clientBuild > daemonBuild\n /*\n * Release fence: the same protocol version can span several\n * releases, and a daemon outlives the upgrade that replaced its\n * binary — a client running strictly NEWER code must not execute on\n * the old process. Same direction rule as the build fence: only a\n * newer client retires the daemon; older clients attach and degrade.\n */\n const staleRelease\n = typeof params.codeVersion === 'string'\n && compareVersions(params.codeVersion, ctx.codeVersion) > 0\n /*\n * Same protocol, older code, live work: attach instead of asking\n * for a drain that would abort it. The client can speak to this\n * daemon; it only must not stay on it, so the daemon retires at\n * its first idle point and the client's reconnect lands on a\n * fresh one. A protocol mismatch can't attach and stays refused.\n */\n const protocolMatches = params.protocolVersion === IPC_PROTOCOL_VERSION\n if (protocolMatches && (staleBuild || staleRelease) && ctx.hasActiveWork)\n return { accept: true, retire: true }\n if (!protocolMatches || staleBuild || staleRelease) {\n return {\n accept: false,\n message: staleRelease\n ? `Stale daemon: it runs zidane ${ctx.codeVersion} but the client runs ${params.codeVersion}. Draining for respawn.`\n : staleBuild\n ? `Build mismatch: the daemon was started from an older build (daemon ${ctx.buildId}, client ${params.buildId}). Draining for respawn.`\n : `Protocol version mismatch: daemon speaks v${IPC_PROTOCOL_VERSION}, client sent v${params.protocolVersion ?? '?'}.`,\n }\n }\n return { accept: true, retire: false }\n}\n","/**\n * Host identity: which host a client is talking to, stable across restarts.\n *\n * The id is a UUID written once to `<dataDir>/host-id` and read back on every\n * start. The data dir is the host's `userDataDir` (the user's zidane dir), so\n * the local daemon and a window's in-process host share one id: they serve\n * the same store on the same computer. A remote `zidane-server` has its own\n * data dir, hence its own id.\n */\nimport type { HostKind } from '../protocol'\nimport { randomUUID } from 'node:crypto'\nimport { mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { hostname } from 'node:os'\nimport { join } from 'node:path'\n\nexport interface HostIdentityOptions {\n kind: HostKind\n /** Display name. Default: the machine's hostname. */\n name?: string\n}\n\nexport interface HostIdentity {\n /** `undefined` when the data dir can't hold the id: the host still serves, without identity. */\n id: string | undefined\n kind: HostKind\n name: string\n}\n\nconst UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i\nconst FILE = 'host-id'\n\nfunction readId(path: string): string | undefined {\n try {\n const id = readFileSync(path, 'utf8').trim()\n return UUID.test(id) ? id : undefined\n }\n catch {\n return undefined\n }\n}\n\n/**\n * The id persisted in `dataDir`, created on first use. Two processes starting\n * at once agree: the file is created exclusively (`wx`) and the loser reads\n * the winner's id. A missing or corrupt file gets a fresh id.\n */\nfunction readOrCreateHostId(dataDir: string): string | undefined {\n const path = join(dataDir, FILE)\n const existing = readId(path)\n if (existing)\n return existing\n const id = randomUUID()\n try {\n mkdirSync(dataDir, { recursive: true })\n writeFileSync(path, `${id}\\n`, { flag: 'wx', mode: 0o600 })\n return id\n }\n catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'EEXIST') {\n // Another process won the race, or the file is corrupt: theirs if valid, else replace it.\n const raced = readId(path)\n if (raced)\n return raced\n try {\n writeFileSync(path, `${id}\\n`, { mode: 0o600 })\n // Re-read: a concurrent replacer may have written last.\n return readId(path) ?? id\n }\n catch {\n return undefined\n }\n }\n return undefined\n }\n}\n\nexport function resolveHostIdentity(dataDir: string, options: HostIdentityOptions): HostIdentity {\n return {\n id: readOrCreateHostId(dataDir),\n kind: options.kind,\n name: options.name ?? hostname(),\n }\n}\n","/**\n * Connected peers: the set, signal fan-out, live presence, and the cleanup a\n * dropped peer triggers. Presence piggybacks on fan-out, so the two live\n * together.\n */\nimport type { ChatHost } from '../../chat/host/engine'\nimport type { HostSignal, SessionPresence } from '../protocol'\n\n/** One connected client, as the dispatcher sees it. The transport creates it and supplies `send`. */\nexport interface HostPeer {\n /**\n * Delivers one host signal to this client, with its number in its session\n * when it has one (`./signal-log`; the wire carries it as\n * `SIGNAL_SEQ_FIELD`). Must never throw.\n */\n send: (signal: HostSignal, seq?: number) => void\n /** Set once `ipc.hello` succeeded; only ready peers receive signals. */\n ready: boolean\n /** Session this peer's window is attached to (`presence.watch`). */\n watching: string | null\n /** Browser hosts this peer registered (`browser.registerHost`), released when it drops. */\n browserHosts?: Set<string>\n /** Terminal views attached through this peer: terminal id → client ids. Detached when it drops. */\n terminalViews?: Map<string, Set<string>>\n /** Terminal viewers this peer registered (`terminal.registerViewer`), released when it drops. */\n terminalViewers?: Set<string>\n /** What authenticated the connection (a zidane-server's token id), for its audit lines. */\n principal?: string\n}\n\nexport interface PeerRegistry {\n add: (peer: HostPeer) => void\n /** Whether the peer is still connected (a handler may outlive its peer across an await). */\n has: (peer: HostPeer) => boolean\n /** The peer's connection ended: run every `onClose` cleanup in registration order, then refresh presence. */\n remove: (peer: HostPeer) => void\n /** Release what a peer registered when it drops; runs in registration order. */\n onClose: (cleanup: (peer: HostPeer) => void) => void\n /** Forget every peer WITHOUT per-peer cleanup (the host is shutting down). */\n clear: () => void\n size: () => number\n /** Fan a host signal out to every ready peer (terminal output only to its viewers), refreshing presence on the signals that change it. */\n broadcast: (signal: HostSignal) => void\n /**\n * Fan out to every handshaken peer except `origin`. Draft signals use\n * this so a window's own keystrokes never bounce back and fight its\n * cursor — echo-safety by construction, no client-side dedupe.\n */\n broadcastExcept: (origin: HostPeer | null, signal: HostSignal) => void\n computePresence: () => SessionPresence[]\n broadcastPresence: () => void\n /**\n * Late-bound: the broadcast sink exists before the host (the environment\n * the host is built on needs it), and presence reads the host only once a\n * signal arrives.\n */\n bindHost: (host: PresenceSource) => void\n}\n\ntype PresenceSource = Pick<ChatHost, 'approvals' | 'interactions' | 'listLiveSessions'>\n\nexport interface PeerRegistryOptions {\n /** Numbers a signal on its way to every peer (`SignalLog.record`). */\n sequence?: (signal: HostSignal) => number | undefined\n}\n\nexport function createPeerRegistry(options: PeerRegistryOptions = {}): PeerRegistry {\n const peers = new Set<HostPeer>()\n let boundHost: PresenceSource | null = null\n const closeCleanups: Array<(peer: HostPeer) => void> = []\n\n /** Sessions with a run in flight, tracked from the run signals themselves. */\n const runningSessions = new Set<string>()\n\n const broadcast = (signal: HostSignal): void => {\n // Terminal output only goes where the terminal is shown.\n if (signal.kind === 'terminal:output' || signal.kind === 'terminal:reset') {\n for (const peer of peers) {\n if (peer.ready && peer.terminalViews?.has(signal.terminalId))\n peer.send(signal)\n }\n return\n }\n // Numbered only here: what every peer gets is what a reattaching one can be replayed.\n fanOut(null, signal, options.sequence?.(signal))\n /*\n * Presence piggybacks on the signals that change it — run state and\n * HITL queues — so the snapshot stays fresh without instrumenting the\n * host. `presence:changed` itself is emitted via `broadcastExcept`\n * directly, so this cannot recurse.\n */\n switch (signal.kind) {\n case 'run:start':\n // Signal-tracked rather than read off `agent.isRunning`: the host\n // broadcasts `run:start` BEFORE invoking `agent.run()`, so the\n // flag lags the signal by a tick.\n runningSessions.add(signal.sessionId)\n broadcastPresence()\n break\n case 'run:end':\n runningSessions.delete(signal.sessionId)\n broadcastPresence()\n break\n case 'approval:request':\n case 'approval:resolved':\n case 'interaction:request':\n case 'interaction:resolved':\n broadcastPresence()\n break\n default:\n break\n }\n }\n\n function fanOut(origin: HostPeer | null, signal: HostSignal, seq: number | undefined): void {\n for (const peer of peers) {\n if (!peer.ready || peer === origin)\n continue\n peer.send(signal, seq)\n }\n }\n\n function broadcastExcept(origin: HostPeer | null, signal: HostSignal): void {\n fanOut(origin, signal, undefined)\n }\n\n /**\n * Live presence: which sessions have attached windows, and their\n * run / awaiting-input state. Union of watched, live-agent, and\n * pending-HITL sessions — small by construction.\n */\n function computePresence(): SessionPresence[] {\n const host = boundHost\n if (!host)\n throw new Error('Presence read before the host was bound.')\n const windowCounts = new Map<string, number>()\n for (const peer of peers) {\n if (peer.ready && peer.watching)\n windowCounts.set(peer.watching, (windowCounts.get(peer.watching) ?? 0) + 1)\n }\n\n const attention = new Set<string>()\n for (const request of host.approvals.listPending())\n attention.add(request.sessionId)\n for (const pending of host.interactions.list())\n attention.add(pending.sessionId)\n\n // Union of signal-tracked runs (fresh) and the agent flag (covers a\n // window attaching to a daemon whose run started before it connected).\n const live = new Map(host.listLiveSessions().map(entry => [entry.sessionId, entry.running]))\n\n const ids = new Set<string>([...windowCounts.keys(), ...attention, ...live.keys(), ...runningSessions])\n return [...ids].map(sessionId => ({\n sessionId,\n windows: windowCounts.get(sessionId) ?? 0,\n running: runningSessions.has(sessionId) || live.get(sessionId) === true,\n attention: attention.has(sessionId),\n }))\n }\n\n function broadcastPresence(): void {\n broadcastExcept(null, { kind: 'presence:changed', sessions: computePresence() })\n }\n\n return {\n add(peer) {\n peers.add(peer)\n },\n has: peer => peers.has(peer),\n remove(peer) {\n if (!peers.delete(peer))\n return\n for (const cleanup of closeCleanups)\n cleanup(peer)\n // The window detached: its session may have left the \"active\" set.\n if (peer.watching)\n broadcastPresence()\n },\n onClose(cleanup) {\n closeCleanups.push(cleanup)\n },\n clear() {\n peers.clear()\n },\n size: () => peers.size,\n broadcast,\n broadcastExcept,\n computePresence,\n broadcastPresence,\n bindHost(host) {\n boundHost = host\n },\n }\n}\n","/**\n * Per-session signal numbering and the bounded replay log behind\n * `sessions.resume`.\n *\n * Every session-scoped signal the host fans out to all peers gets the next\n * number of its session (from 1), and the last ones are kept as JSON, so a\n * client that dropped and reattached can be sent exactly what it missed\n * instead of reloading the whole transcript. Signals with no session, and\n * the origin-excluded or viewer-only ones that never go through the full\n * fan-out (drafts, search, suggestions, terminal output), are not numbered.\n *\n * Bounds: per session the last `maxSignals` signals and at most `maxBytes`\n * of them; across sessions `maxTotalBytes`, past which the least recently\n * written session loses its log. Sizes are UTF-8 bytes of the JSON. A\n * position the log no longer covers (or that is not a non-negative integer)\n * is a gap: the client falls back to `sessions.loadEvents`.\n *\n * Numbering survives eviction and `forget`, so a stale position can never\n * pass for a fresh one. A forgotten session keeps only its next number, in\n * a map bounded by `maxForgotten` (least recently forgotten go first); an\n * evicted counter raises a floor every new log starts from, so a number is\n * never given out twice in one epoch, at the cost of new sessions'\n * numbering not starting at 1 once that happened.\n *\n * `epoch` names this log: numbers mean nothing to another host process.\n */\nimport type { HostSignal, SequencedSignal } from '../protocol'\nimport { Buffer } from 'node:buffer'\nimport { randomUUID } from 'node:crypto'\n\nexport interface SignalLogOptions {\n /** Default 2000. */\n maxSignals?: number\n /** Default 4 MiB. */\n maxBytes?: number\n /** Default 32 MiB. */\n maxTotalBytes?: number\n /** Forgotten sessions whose counters are kept. Default 10 000. */\n maxForgotten?: number\n}\n\nexport interface SignalLog {\n readonly epoch: string\n /** The signal's number in its session, or `undefined` when it is not session-scoped. */\n record: (signal: HostSignal) => number | undefined\n /** Every signal of `sessionId` after `afterSeq`, in order; `null` when the log does not cover them all. */\n replay: (sessionId: string, afterSeq: number) => SequencedSignal[] | null\n /** The session is gone: drop its log (its numbering stays). */\n forget: (sessionId: string) => void\n /** Sessions tracked (live logs and forgotten counters): bounded by `maxForgotten` plus live sessions. */\n sessionCount: () => number\n}\n\ninterface Entry {\n seq: number\n json: string\n bytes: number\n}\n\ninterface SessionLog {\n /** Number the next signal gets. */\n next: number\n entries: Entry[]\n /** Index of the oldest kept entry. */\n head: number\n bytes: number\n}\n\nfunction sessionOf(signal: HostSignal): string | undefined {\n const id = (signal as { sessionId?: unknown }).sessionId\n return typeof id === 'string' ? id : undefined\n}\n\nexport function createSignalLog(options: SignalLogOptions = {}): SignalLog {\n const maxSignals = options.maxSignals ?? 2000\n const maxBytes = options.maxBytes ?? 4 * 1024 * 1024\n const maxTotalBytes = options.maxTotalBytes ?? 32 * 1024 * 1024\n const maxForgotten = options.maxForgotten ?? 10_000\n const epoch = randomUUID()\n /** Insertion order = least recently written first. */\n const logs = new Map<string, SessionLog>()\n /** Next number of forgotten sessions; insertion order = least recently forgotten first. */\n const forgotten = new Map<string, number>()\n /** Every number below this may have been given out by a session whose counter is gone. */\n let floor = 1\n let totalBytes = 0\n\n const dropOldest = (log: SessionLog): void => {\n totalBytes -= log.entries[log.head]!.bytes\n log.bytes -= log.entries[log.head]!.bytes\n log.head++\n if (log.head > 1024 && log.head * 2 > log.entries.length) {\n log.entries = log.entries.slice(log.head)\n log.head = 0\n }\n }\n\n const clear = (log: SessionLog): void => {\n totalBytes -= log.bytes\n log.entries = []\n log.head = 0\n log.bytes = 0\n }\n\n return {\n epoch,\n record(signal) {\n const sessionId = sessionOf(signal)\n if (sessionId === undefined)\n return undefined\n let log = logs.get(sessionId)\n if (log) {\n logs.delete(sessionId)\n }\n else {\n log = { next: forgotten.get(sessionId) ?? floor, entries: [], head: 0, bytes: 0 }\n forgotten.delete(sessionId)\n }\n logs.set(sessionId, log)\n\n const seq = log.next++\n let json: string\n try {\n json = JSON.stringify(signal)\n }\n catch {\n // Not JSON-able, so no peer can receive it either: a hole the log cannot replay.\n clear(log)\n return seq\n }\n const bytes = Buffer.byteLength(json)\n log.entries.push({ seq, json, bytes })\n log.bytes += bytes\n totalBytes += bytes\n while (log.entries.length - log.head > maxSignals || (log.bytes > maxBytes && log.entries.length - log.head > 0))\n dropOldest(log)\n for (const [id, other] of logs) {\n if (totalBytes <= maxTotalBytes || id === sessionId)\n break\n clear(other)\n }\n return seq\n },\n replay(sessionId, afterSeq) {\n const log = logs.get(sessionId)\n if (!log || !Number.isSafeInteger(afterSeq) || afterSeq < 0)\n return null\n const last = log.next - 1\n if (afterSeq > last || afterSeq < 0)\n return null\n if (afterSeq === last)\n return []\n const first = log.entries[log.head]?.seq\n if (first === undefined || first > afterSeq + 1)\n return null\n const out: SequencedSignal[] = []\n for (let i = log.head; i < log.entries.length; i++) {\n const entry = log.entries[i]!\n if (entry.seq > afterSeq)\n out.push({ seq: entry.seq, signal: JSON.parse(entry.json) as HostSignal })\n }\n return out\n },\n forget(sessionId) {\n const log = logs.get(sessionId)\n if (!log)\n return\n clear(log)\n logs.delete(sessionId)\n forgotten.set(sessionId, log.next)\n while (forgotten.size > maxForgotten) {\n const [oldest, next] = forgotten.entries().next().value!\n forgotten.delete(oldest)\n floor = Math.max(floor, next)\n }\n },\n sessionCount: () => logs.size + forgotten.size,\n }\n}\n","import type { WorkspaceConfinement } from '../../chat/workspace-confinement'\nimport type { FsDirEntry, FsDirListing, FsRoots } from '../protocol'\n/**\n * The folders a host lets sessions use, as `fs.*` lists them: the host's own\n * confinement (`ChatHost.workspace`, `src/chat/workspace-confinement.ts`,\n * which the host enforces at its entry points), plus the folder listing. A\n * server is confined to its workspace roots; a local host is not, and its\n * listing root is the user's home, like the window's own folder picker.\n */\nimport { existsSync, readdirSync, realpathSync, statSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { isInside } from '../../chat/workspace-confinement'\n\n/** Most folders one listing returns. */\nconst MAX_DIR_ENTRIES = 2000\n\nexport interface WorkspaceRoots {\n describe: () => FsRoots\n /** The real path of `path` when it is a folder inside the roots; throws otherwise. */\n resolveFolder: (path: string) => string\n /** A new session's folder: `cwd` checked when confined, the first root when confined and empty. */\n sessionFolder: (cwd: string) => string\n /** A folder a running session moves to (`setFolder`, launch override): checked when confined; `''` passes. */\n checkFolder: (cwd: string) => string\n list: (path?: string) => FsDirListing\n}\n\nexport function createWorkspaceRoots(confinement: WorkspaceConfinement): WorkspaceRoots {\n const { confined, roots, resolveFolder } = confinement\n return {\n describe: () => ({ roots: [...roots], confined }),\n resolveFolder,\n checkFolder: confinement.checkFolder,\n sessionFolder: confinement.sessionFolder,\n list(path) {\n const dir = resolveFolder(path ?? roots[0]!)\n const entries: FsDirEntry[] = []\n let truncated = false\n const names = readdirSync(dir, { withFileTypes: true })\n .filter(e => !e.name.startsWith('.') && (e.isDirectory() || e.isSymbolicLink()))\n .map(e => e.name)\n .sort((a, b) => a.localeCompare(b))\n for (const name of names) {\n let real: string\n try {\n // Canonical, as the confinement's roots are (`../../chat/workspace-confinement`).\n real = realpathSync.native(join(dir, name))\n if (!statSync(real).isDirectory())\n continue\n }\n catch {\n continue\n }\n // A symlink out of the roots is not offered (it would be refused anyway).\n if (!roots.some(root => isInside(root, real)))\n continue\n if (entries.length >= MAX_DIR_ENTRIES) {\n truncated = true\n break\n }\n entries.push({ name, path: real, isGitRepo: existsSync(join(real, '.git')) })\n }\n const atRoot = roots.includes(dir)\n return { roots: [...roots], path: dir, parent: atRoot ? null : dirname(dir), entries, ...(truncated ? { truncated } : {}) }\n },\n }\n}\n","/**\n * Transport-free JSON-RPC dispatch around a `ChatHost`.\n *\n * Owns everything a host connection needs that is NOT the wire: the typed\n * method table, per-peer state (presence, terminal views, browser hosts,\n * terminal viewers), signal fan-out, the shared draft / search / suggest\n * state, and the `ipc.hello` handshake. A transport (the unix-socket server\n * in `server.ts`, the WebSocket server in `../transports/ws-server.ts`, the\n * in-memory one in `../memory.ts`) only frames messages and hands each\n * connection over as a {@link HostPeer} whose `send` delivers signals.\n *\n * Lifecycle that belongs to the process (draining, retiring once idle) stays\n * with the transport and reaches in through {@link DispatcherLifecycle}.\n *\n * This module is the composition root: peers and fan-out live in\n * `./peers`, each feature's methods (and the per-session or per-peer state\n * only they touch) in `./handlers/<feature>`.\n */\nimport type { ChatHost } from '../../chat/host/engine'\nimport type { HelloParams, HelloResult, HostSignal } from '../protocol'\nimport type { DaemonEnvironment } from './environment'\nimport type { RemoteInstallsOptions } from './handlers/catalog-install'\nimport type { MachineLinksHandlerOptions } from './handlers/machine-links'\nimport type { MachineServeOptions } from './handlers/machine-serve'\nimport type { SyncOptions } from './handlers/sync'\nimport type { MethodTable } from './handlers/types'\nimport type { HostIdentityOptions } from './identity'\nimport type { HostPeer } from './peers'\nimport type { SignalLogOptions } from './signal-log'\nimport { AcpErrorCode } from '../../acp/types'\nimport { createChatHost } from '../../chat/host/engine'\nimport { ZIDANE_VERSION } from '../../version'\nimport { IPC_PROTOCOL_VERSION, IpcErrorCode, MachineErrorCode, PING_METHOD } from '../protocol'\nimport { createDaemonEnvironment } from './environment'\nimport { createArtifactHandlers } from './handlers/artifacts'\nimport { createAuthHandlers, createProviderAuth } from './handlers/auth'\nimport { createBrowserHandlers } from './handlers/browser'\nimport { createCatalogInstallHandlers, remoteInstallsAllowed } from './handlers/catalog-install'\nimport { createCatalogHandlers } from './handlers/catalogs'\nimport { createChatHandlers } from './handlers/chat'\nimport { createContextHandlers } from './handlers/context'\nimport { createDaemonHandlers } from './handlers/daemon'\nimport { createDraftHandlers } from './handlers/drafts'\nimport { createEnvironmentHandlers } from './handlers/environments'\nimport { createExtensionHandlers } from './handlers/extensions'\nimport { createFsHandlers } from './handlers/fs'\nimport { createHistoryHandlers } from './handlers/history'\nimport { createHitlHandlers } from './handlers/hitl'\nimport { createLaunchOverrideHandlers } from './handlers/launch-overrides'\nimport { createMachineLinkHandlers } from './handlers/machine-links'\nimport { createMachineServeHandlers } from './handlers/machine-serve'\nimport { createMachineHandlers } from './handlers/machines'\nimport { createOAuthFlowHandlers } from './handlers/oauth-flows'\nimport { createOrchestrationHandlers } from './handlers/orchestration'\nimport { checkParams, InvalidParamsError } from './handlers/params'\nimport { createPresenceHandlers } from './handlers/presence'\nimport { createQueueHandlers } from './handlers/queue'\nimport { createResumeHandlers } from './handlers/resume'\nimport { createSessionReadHandlers } from './handlers/session-reads'\nimport { createSessionHandlers } from './handlers/sessions'\nimport { createSettingsHandlers } from './handlers/settings'\nimport { createSuggestHandlers } from './handlers/suggest'\nimport { createSyncHandlers, withSyncOverrides } from './handlers/sync'\nimport { createTerminalHandlers } from './handlers/terminal'\nimport { createTitleHandlers } from './handlers/titles'\nimport { createTodoHandlers } from './handlers/todos'\nimport { createTranscriptHandlers } from './handlers/transcript'\nimport { createTranscriptReplayCache } from './handlers/transcript-cache'\nimport { createWorkspaceHandlers } from './handlers/workspace'\nimport { createWorkspaceExecStreamHandlers } from './handlers/workspace-exec-stream'\nimport { evaluateHello } from './handshake'\nimport { resolveHostIdentity } from './identity'\nimport { IPC_BUILD_ID } from './lifecycle'\nimport { createPeerRegistry } from './peers'\nimport { createSignalLog } from './signal-log'\nimport { createWorkspaceRoots } from './workspace-roots'\n\n/** Codes a machine error keeps over the wire (`MachineErrorCode`). */\nconst MACHINE_ERROR_CODES: ReadonlySet<number> = new Set(Object.values(MachineErrorCode))\n\nexport type { HostPeer } from './peers'\n\n/** Process lifecycle the transport owns; the dispatcher only asks for it. */\nexport interface DispatcherLifecycle {\n /** `daemon.shutdown`: drain and exit once the reply is out. */\n shutdown: () => void\n /** A newer client found this host mid-work: keep serving, exit at the first idle point. */\n retireWhenIdle: () => void\n isRetiring: () => boolean\n}\n\nexport interface HostDispatcherOptions {\n /**\n * Environment factory: the production daemon uses the disk-backed\n * `createDaemonEnvironment`; tests inject an in-memory one. Receives the\n * broadcast sink wired to peer fan-out.\n */\n createEnvironment?: (broadcast: (signal: HostSignal) => void) => DaemonEnvironment | Promise<DaemonEnvironment>\n appVersion: string\n startedAt: number\n lifecycle: DispatcherLifecycle\n /**\n * What this host reports itself as in `ipc.hello` / `daemon.info`; the id\n * comes from the environment's data dir. Default: a `daemon` named after\n * the machine.\n */\n identity?: HostIdentityOptions\n /** Bounds of the per-session replay log `sessions.resume` reads (`./signal-log`). */\n replay?: SignalLogOptions\n /**\n * Lend this host as a machine to its clients' hosts (`machine.attach`,\n * `docs/MACHINES.md` § Reverse direction). A zidane-server's\n * `allowAsMachine`; absent: refused.\n */\n machineServe?: MachineServeOptions\n /** Mint machine tokens for clients (`tokens.createMachineToken`): a zidane-server's token store. Absent: refused. */\n tokens?: { createMachineToken: (name: string, by: string | undefined) => { id: string, name: string, token: string } }\n /** Pacing of this host's machine links (tests shrink it). */\n machineLinks?: MachineLinksHandlerOptions['pacing']\n /** How long an `auth.oauth.*` sign-in waits for its code. Default 10 minutes. */\n oauthFlowTtlMs?: number\n /**\n * Installs and removals from clients (`catalog.install` / `remove` /\n * `update`, `mcp.upsert` / `remove`): a zidane-server's `allowRemoteInstalls`\n * and its audit log. Absent: refused.\n */\n remoteInstalls?: RemoteInstallsOptions\n /**\n * Settings sync from a client's computer (`sync.*`): a zidane-server's\n * sync record and audit. Absent: refused.\n */\n sync?: SyncOptions\n}\n\n/** A request's outcome, ready for the transport to frame as a JSON-RPC response. */\nexport type DispatchOutcome\n = | { ok: true, result: unknown }\n | { ok: false, code: number, message: string, data?: unknown }\n\nexport interface HostDispatcher {\n host: ChatHost\n addPeer: (peer: HostPeer) => void\n /** The peer's connection ended: release what it registered and refresh presence. */\n removePeer: (peer: HostPeer) => void\n /** Forget every peer WITHOUT per-peer cleanup (the host is shutting down). */\n detachAll: () => void\n peerCount: () => number\n handleRequest: (method: string, params: unknown, peer: HostPeer) => Promise<DispatchOutcome>\n /** Fire-and-forget: no response, errors swallowed, ignored before the handshake. */\n handleNotification: (method: string, params: unknown, peer: HostPeer) => Promise<void>\n}\n\nexport async function createHostDispatcher(options: HostDispatcherOptions): Promise<HostDispatcher> {\n const { appVersion, startedAt, lifecycle } = options\n\n const signalLog = createSignalLog(options.replay)\n const replays = createTranscriptReplayCache()\n // Every numbered signal passes here: the ones following a session change drop its cached replay.\n const peers = createPeerRegistry({ sequence: (signal) => {\n replays.observe(signal)\n return signalLog.record(signal)\n } })\n const { broadcast, broadcastExcept } = peers\n\n const env = await (options.createEnvironment\n ? options.createEnvironment(broadcast)\n : createDaemonEnvironment({ broadcast }))\n const host = createChatHost(env)\n peers.bindHost(host)\n host.approvals.rehydrate()\n\n const store = env.store\n const identity = resolveHostIdentity(env.userDataDir(), options.identity ?? { kind: 'daemon' })\n const identityFields = {\n ...(identity.id ? { hostId: identity.id } : {}),\n hostKind: identity.kind,\n hostName: identity.name,\n }\n\n // The host's own confinement (it checks it at its entry points); `fs.*` lists with it.\n const workspace = createWorkspaceRoots(host.workspace)\n const drafts = createDraftHandlers({ broadcastExcept })\n const suggest = createSuggestHandlers({ env, broadcastExcept })\n const launchOverrides = createLaunchOverrideHandlers({ host })\n const browser = createBrowserHandlers({ host })\n const terminal = createTerminalHandlers({ host, isConnected: peers.has })\n const execStreams = createWorkspaceExecStreamHandlers({ host, isConnected: peers.has })\n const auth = createProviderAuth({ host, env })\n const oauth = createOAuthFlowHandlers({ host, env, auth, isConnected: peers.has, ...(options.oauthFlowTtlMs !== undefined ? { ttlMs: options.oauthFlowTtlMs } : {}) })\n const settings = createSettingsHandlers({ host, env, broadcast })\n const installs = createCatalogInstallHandlers({ host, env, broadcast, setSettings: patch => settings['settings.set']({ patch }, null as unknown as HostPeer), ...(options.remoteInstalls ? { options: options.remoteInstalls } : {}) })\n const authHandlers = createAuthHandlers({ auth })\n const sync = createSyncHandlers({\n host,\n env,\n broadcast,\n auth,\n setters: {\n setSettings: patch => settings['settings.set']({ patch }, null as unknown as HostPeer) as unknown as Record<string, unknown>,\n install: (p, peer) => installs['catalog.install'](p, peer),\n mcpUpsert: (p, peer) => installs['mcp.upsert'](p, peer),\n mcpRemove: (p, peer) => installs['mcp.remove'](p, peer),\n setApiKey: p => authHandlers['auth.setApiKey'](p, null as unknown as HostPeer),\n },\n ...(options.sync ? { options: options.sync } : {}),\n })\n const { markOverrides, ...syncMethods } = sync\n const machineServe = createMachineServeHandlers({ host, dataDir: () => env.userDataDir(), hostName: identity.name, settings: () => env.readSettings(), isConnected: peers.has, ...(options.machineServe ? { options: options.machineServe } : {}) })\n\n // Peer-close cleanup, in this order: browser hosts, terminal viewers and views, launch overrides, a lent machine.\n peers.onClose(browser.releasePeer)\n peers.onClose(terminal.releasePeer)\n peers.onClose(launchOverrides.releasePeer)\n peers.onClose(machineServe.releasePeer)\n peers.onClose(execStreams.releasePeer)\n peers.onClose(oauth.releasePeer)\n\n const forgetSession = (sessionId: string): void => {\n drafts.forget(sessionId)\n launchOverrides.forget(sessionId)\n suggest.forget(sessionId)\n signalLog.forget(sessionId)\n replays.forget(sessionId)\n }\n\n /*\n * Exhaustive by `satisfies`: every `IpcMethodName` MUST have a handler\n * (compile error otherwise), each pinned to its `IpcMethods` signature\n * by the slice it comes from (see `./handlers/types`).\n */\n const methods = {\n ...createChatHandlers({ host, clearDraft: drafts.clearDraft }),\n ...createQueueHandlers({ host, clearDraft: drafts.clearDraft }),\n ...drafts.methods,\n ...suggest.methods,\n ...createExtensionHandlers({ env, broadcastExcept }),\n ...launchOverrides.methods,\n ...createSessionHandlers({ host, store, broadcast, forgetSession, hostId: identity.id, workspace }),\n ...createTitleHandlers({ host, broadcast }),\n ...createSessionReadHandlers({ host, store, snapshots: replays }),\n ...createTranscriptHandlers({ host, store, broadcast, replays }),\n ...createResumeHandlers({ log: signalLog }),\n ...createContextHandlers({ host }),\n ...createEnvironmentHandlers({ host, env, setSettings: settings['settings.set'] }),\n ...createWorkspaceHandlers({ host }),\n ...execStreams.methods,\n ...createFsHandlers({ workspace }),\n ...authHandlers,\n ...oauth.methods,\n ...installs,\n ...createCatalogHandlers({ env, host }),\n ...createArtifactHandlers({ store, broadcast }),\n ...createHistoryHandlers({ host, store }),\n ...createTodoHandlers({ host, store }),\n ...createOrchestrationHandlers({ host }),\n ...createHitlHandlers({ host }),\n ...browser.methods,\n ...terminal.methods,\n ...settings,\n ...createPresenceHandlers({ env, peers }),\n ...createMachineHandlers({ host, broadcast }),\n ...machineServe.methods,\n ...createMachineLinkHandlers({ host, env, broadcast, hostId: identity.id, server: identity.kind === 'server', appVersion, ...(options.machineLinks ? { pacing: options.machineLinks } : {}) }),\n 'tokens.createMachineToken': (p, peer) => {\n if (!options.tokens)\n throw new Error('This host has no tokens to mint (only a zidane-server does).')\n if (typeof p.name !== 'string' || p.name.trim() === '')\n throw new InvalidParamsError('tokens.createMachineToken: \"name\" must be a non-empty string.')\n // Counted against, and audited with, the token that asks.\n return options.tokens.createMachineToken(p.name.trim().slice(0, 100), peer.principal)\n },\n ...createDaemonHandlers({ host, appVersion, startedAt, lifecycle, identity: identityFields }),\n ...syncMethods,\n // A window's edit of a field the sync source set makes it a server override.\n ...(options.sync\n ? withSyncOverrides({\n 'settings.set': settings['settings.set'],\n 'mcp.upsert': installs['mcp.upsert'],\n 'mcp.remove': installs['mcp.remove'],\n 'catalog.remove': installs['catalog.remove'],\n 'catalog.update': installs['catalog.update'],\n 'auth.setApiKey': authHandlers['auth.setApiKey'],\n 'auth.remove': authHandlers['auth.remove'],\n }, { readSettings: () => env.readSettings(), markOverrides })\n : {}),\n } satisfies MethodTable\n\n /**\n * Widened view for the string-keyed lookup: the table is typed exhaustively\n * above; unknown wire methods fall out here. Own keys only: a wire method\n * named `constructor` / `__proto__` / `toString` is unknown, not a call into\n * `Object.prototype`.\n */\n const handlerFor = (method: string): ((params: unknown, peer: HostPeer) => unknown) | undefined =>\n Object.hasOwn(methods, method)\n ? (methods as Partial<Record<string, (params: unknown, peer: HostPeer) => unknown>>)[method]\n : undefined\n\n function hello(params: Partial<HelloParams>, peer: HostPeer): DispatchOutcome {\n const verdict = evaluateHello(params, { buildId: IPC_BUILD_ID, codeVersion: ZIDANE_VERSION, hasActiveWork: host.hasActiveWork(), hostKind: identity.kind })\n if (!verdict.accept) {\n return {\n ok: false,\n code: IpcErrorCode.VersionMismatch,\n message: verdict.message,\n data: { daemon: { protocolVersion: IPC_PROTOCOL_VERSION, appVersion, pid: process.pid, startedAt, buildId: IPC_BUILD_ID, codeVersion: ZIDANE_VERSION, ...identityFields } },\n }\n }\n if (verdict.retire)\n lifecycle.retireWhenIdle()\n peer.ready = true\n const result: HelloResult = {\n protocolVersion: IPC_PROTOCOL_VERSION,\n appVersion,\n pid: process.pid,\n startedAt,\n buildId: IPC_BUILD_ID,\n codeVersion: ZIDANE_VERSION,\n ...identityFields,\n signalEpoch: signalLog.epoch,\n ...(lifecycle.isRetiring() ? { retiring: true } : {}),\n ...(machineServe.allowed() ? { machineServe: true } : {}),\n ...(remoteInstallsAllowed(options.remoteInstalls) ? { remoteInstalls: true } : {}),\n ...(options.sync ? { sync: true } : {}),\n }\n return { ok: true, result }\n }\n\n return {\n host,\n addPeer: peers.add,\n removePeer: peers.remove,\n detachAll: peers.clear,\n peerCount: peers.size,\n\n async handleRequest(method, params, peer) {\n // Transport liveness (`../transports/client-core` heartbeat): answered by any host, handshake or not.\n if (method === PING_METHOD)\n return { ok: true, result: {} }\n if (method === 'ipc.hello')\n return hello((params ?? {}) as Partial<HelloParams>, peer)\n\n /*\n * `daemon.shutdown` / `daemon.info` are allowed pre-handshake: a\n * client that just got a VERSION_MISMATCH on `ipc.hello` (so it\n * never became `ready`) still needs to drain this stale daemon\n * before respawning a matching one.\n */\n if (!peer.ready && method !== 'daemon.shutdown' && method !== 'daemon.info')\n return { ok: false, code: IpcErrorCode.NotHandshaken, message: 'Handshake required: send ipc.hello first.' }\n\n const handler = handlerFor(method)\n if (!handler && method.startsWith('machine.'))\n return { ok: false, code: MachineErrorCode.MethodNotAllowed, message: `\"${method}\" needs a machine connection (a machine-scoped token); this is a client connection.` }\n if (!handler)\n return { ok: false, code: AcpErrorCode.MethodNotFound, message: `Unknown method \"${method}\".` }\n\n try {\n checkParams(params)\n return { ok: true, result: (await handler(params, peer)) ?? null }\n }\n catch (err) {\n if (err instanceof InvalidParamsError)\n return { ok: false, code: AcpErrorCode.InvalidParams, message: err.message }\n // A machine error keeps its code: a client tells \"busy, retry\" from \"refused\" by it.\n const code = (err as { code?: unknown } | null)?.code\n if (typeof code === 'number' && MACHINE_ERROR_CODES.has(code))\n return { ok: false, code, message: (err as Error).message }\n return { ok: false, code: IpcErrorCode.HandlerFailed, message: err instanceof Error ? err.message : String(err) }\n }\n },\n\n /*\n * Notification fast path: fire-and-forget writes with no response\n * bookkeeping. Used for per-keystroke draft sync, where a\n * request/response round-trip per key would be pure overhead.\n * Routed through the SAME handler table as requests; errors are\n * swallowed (there is nowhere to send them) and pre-handshake\n * notifications are ignored.\n */\n async handleNotification(method, params, peer) {\n if (!peer.ready)\n return\n const handler = handlerFor(method)\n if (!handler)\n return\n try {\n checkParams(params)\n await handler(params, peer)\n }\n catch {\n // fire-and-forget by contract\n }\n },\n }\n}\n"],"mappings":"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"}