remoteclaw 0.1.0-next.049f396 → 0.1.0-next.05abcca

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 (1199) hide show
  1. package/README.md +11 -9
  2. package/dist/accounts-79XhjwAj.js +32 -0
  3. package/dist/accounts-B1M3fOxL.js +272 -0
  4. package/dist/accounts-BwbvnKsW.js +205 -0
  5. package/dist/accounts-CIVjmTg9.js +270 -0
  6. package/dist/accounts-D1awQXKu.js +36 -0
  7. package/dist/accounts-DHkGVGUR.js +36 -0
  8. package/dist/accounts-P7cmIXUM.js +206 -0
  9. package/dist/accounts-XFgBY644.js +47 -0
  10. package/dist/accounts-_ZuNC5bz.js +47 -0
  11. package/dist/ack-reactions-BGJ9Vigf.js +621 -0
  12. package/dist/ack-reactions-Diu9O24z.js +621 -0
  13. package/dist/acp-cli-BwZ-va2P.js +1316 -0
  14. package/dist/acp-cli-eVKByz-j.js +1311 -0
  15. package/dist/active-listener--jrUO-8L.js +37 -0
  16. package/dist/active-listener-C7SyMcNY.js +37 -0
  17. package/dist/agent-BAxK2KQW.js +688 -0
  18. package/dist/agent-Dd5Yfhmq.js +687 -0
  19. package/dist/agent-helpers-5F0tdxud.js +400 -0
  20. package/dist/agent-helpers-Bs2nBXeI.js +400 -0
  21. package/dist/agent-scope-BA1HP4K6.js +114 -0
  22. package/dist/agent-scope-CAQLm3LP.js +116 -0
  23. package/dist/agents-D--9DD91.js +754 -0
  24. package/dist/agents.config-CmyzLYqW.js +116 -0
  25. package/dist/agents.config-DerBqRzk.js +116 -0
  26. package/dist/ansi-DtaiOnt1.js +107 -0
  27. package/dist/audio-ClIuKwkl.js +43 -0
  28. package/dist/audio-DqlIYYTb.js +43 -0
  29. package/dist/audit-Cn0cNCE4.js +3114 -0
  30. package/dist/audit-DXY4NHBC.js +3114 -0
  31. package/dist/auth-B-QK8JhI.js +315 -0
  32. package/dist/auth-C1zx1O24.js +314 -0
  33. package/dist/auth-DDmNYVMW.js +448 -0
  34. package/dist/auth-DH1wEw0w.js +448 -0
  35. package/dist/banner-CBWZhANO.js +294 -0
  36. package/dist/binaries-CYwLdubd.js +13 -0
  37. package/dist/bindings-DFAFatwT.js +69 -0
  38. package/dist/bindings-GUKIzFCp.js +69 -0
  39. package/dist/bonjour-discovery-AQMJqY4V.js +378 -0
  40. package/dist/bonjour-discovery-BLcPWHFJ.js +378 -0
  41. package/dist/boot/handler.js +41 -84
  42. package/dist/browser-cli-8Dv5ogFT.js +1690 -0
  43. package/dist/browser-cli-wNLo8SOy.js +1694 -0
  44. package/dist/build-info.json +3 -3
  45. package/dist/call-BTHzKFbN.js +518 -0
  46. package/dist/call-D_NchaCs.js +517 -0
  47. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  48. package/dist/catalog-DgpN5jxU.js +186 -0
  49. package/dist/catalog-k056Nh93.js +186 -0
  50. package/dist/channel-account-context-BHIy71Yh.js +133 -0
  51. package/dist/channel-account-context-DXU_-EkJ.js +133 -0
  52. package/dist/channel-activity-BatlvP_U.js +292 -0
  53. package/dist/channel-activity-BhT7NQ_v.js +94 -0
  54. package/dist/channel-activity-CvjEwpJz.js +94 -0
  55. package/dist/channel-options-BCccA2WC.js +32 -0
  56. package/dist/channel-options-VPR_pNyS.js +33 -0
  57. package/dist/channel-selection-AH6_y6RS.js +51 -0
  58. package/dist/channel-selection-ovohyJQZ.js +51 -0
  59. package/dist/channel-web-APDaQ_wp.js +2134 -0
  60. package/dist/channel-web-BW_YuNlT.js +2132 -0
  61. package/dist/channels-cli-DVsZyaU5.js +1436 -0
  62. package/dist/channels-cli-ubrg5vcL.js +1440 -0
  63. package/dist/channels-status-issues-BbYNzwLp.js +18 -0
  64. package/dist/channels-status-issues-DRybAijg.js +18 -0
  65. package/dist/chat-envelope-AJFUAuBM.js +248 -0
  66. package/dist/chat-envelope-BrfcPlDM.js +248 -0
  67. package/dist/chrome-Bv2UtAMQ.js +1732 -0
  68. package/dist/chrome-C6Vc_7su.js +1733 -0
  69. package/dist/chunk-BAMyFYtF.js +341 -0
  70. package/dist/chunk-BzVoFUZL.js +341 -0
  71. package/dist/clack-prompter-C6mBTOzE.js +122 -0
  72. package/dist/clack-prompter-DKcYqv3o.js +121 -0
  73. package/dist/cleanup-utils-Cb-leJcy.js +94 -0
  74. package/dist/cli/daemon-cli.js +1 -1
  75. package/dist/cli-Cs1n6-eD.js +135 -0
  76. package/dist/cli-Di3p1tLN.js +131 -0
  77. package/dist/client-B6h7bgbF.js +2311 -0
  78. package/dist/client-CMtdm9Ii.js +2311 -0
  79. package/dist/clipboard-A06eV_5C.js +31 -0
  80. package/dist/clipboard-DQBl3coj.js +31 -0
  81. package/dist/command-format-BiiNHkWG.js +18 -0
  82. package/dist/command-format-Dntg_tnC.js +32 -0
  83. package/dist/command-logger/handler.js +1 -1
  84. package/dist/command-registry-CCAvdWh2.js +215 -0
  85. package/dist/commands-D93TXYhv.js +41 -0
  86. package/dist/commands-UD7V7QC9.js +41 -0
  87. package/dist/commands-registry-CCbTtSSK.js +891 -0
  88. package/dist/commands-registry-De8JhZLG.js +890 -0
  89. package/dist/common-D4fL3S2m.js +156 -0
  90. package/dist/common-DXNisGxw.js +156 -0
  91. package/dist/completion-cli-CLo-r-UP.js +452 -0
  92. package/dist/completion-cli-D4ajG3yt.js +452 -0
  93. package/dist/config-BTH7fB_v.js +3345 -0
  94. package/dist/config-DwuBnd6D.js +3347 -0
  95. package/dist/config-cli-D0D1LSNt.js +243 -0
  96. package/dist/config-cli-tWsFNKQM.js +247 -0
  97. package/dist/config-guard-BcT7soTj.js +92 -0
  98. package/dist/config-guard-Bqak3bDc.js +75 -0
  99. package/dist/config-validation-CHEjSJ5K.js +18 -0
  100. package/dist/config-validation-CvgqLhyG.js +18 -0
  101. package/dist/configure-CK_0tFJG.js +889 -0
  102. package/dist/configure-D0z0kE-B.js +891 -0
  103. package/dist/constants-BBVTjb1j.js +75 -0
  104. package/dist/constants-PMRtHBHU.js +75 -0
  105. package/dist/control-auth-DrGYtMJM.js +397 -0
  106. package/dist/control-auth-KY4Qdr2I.js +397 -0
  107. package/dist/control-ui/assets/index-DdiU_ccM.css +1 -0
  108. package/dist/control-ui/assets/index-kVUYi64u.js +7723 -0
  109. package/dist/control-ui/assets/index-kVUYi64u.js.map +1 -0
  110. package/dist/control-ui/index.html +2 -2
  111. package/dist/control-ui-assets-DO1L6M0S.js +186 -0
  112. package/dist/control-ui-assets-S_TLo6Fs.js +186 -0
  113. package/dist/conversation-label-CDH4rKMG.js +36 -0
  114. package/dist/conversation-label-CMOfgCVl.js +36 -0
  115. package/dist/cron-cli-C7h_hLHu.js +495 -0
  116. package/dist/cron-cli-DTNg0Uvl.js +499 -0
  117. package/dist/daemon-cli-BlJS9zWM.js +737 -0
  118. package/dist/daemon-cli-Cfc1yszp.js +735 -0
  119. package/dist/daemon-cli.js +174 -1167
  120. package/dist/daemon-install-BbBLuLWg.js +60 -0
  121. package/dist/daemon-install-WEBvqVOj.js +56 -0
  122. package/dist/daemon-install-helpers-BVtPC2TK.js +504 -0
  123. package/dist/daemon-install-helpers-DVr51zvE.js +504 -0
  124. package/dist/deliver-EB272zWh.js +481 -0
  125. package/dist/deliver-iGD_woru.js +481 -0
  126. package/dist/delivery-queue-BDvalA10.js +244 -0
  127. package/dist/delivery-queue-BimvYz5E.js +244 -0
  128. package/dist/devices-cli-BXCOsNFc.js +323 -0
  129. package/dist/devices-cli-CHGdYfrz.js +319 -0
  130. package/dist/diagnostics-BzzhTQzK.js +35 -0
  131. package/dist/diagnostics-DILtxtcE.js +35 -0
  132. package/dist/directory-cli-COS40yI9.js +221 -0
  133. package/dist/directory-cli-Cb5j1JTC.js +225 -0
  134. package/dist/dispatcher-BUqxh_mA.js +174 -0
  135. package/dist/dispatcher-By-KZRWZ.js +173 -0
  136. package/dist/dm-policy-shared-BCp9_z3w.js +22 -0
  137. package/dist/dm-policy-shared-DgeKqjOu.js +22 -0
  138. package/dist/dns-cli-B8yyXB2N.js +203 -0
  139. package/dist/dns-cli-DAkTk-gM.js +199 -0
  140. package/dist/dock-B0bIIDS3.js +906 -0
  141. package/dist/dock-C3PzQ6CS.js +907 -0
  142. package/dist/doctor-completion-BXGEqLhU.js +92 -0
  143. package/dist/doctor-completion-D_mNzioP.js +92 -0
  144. package/dist/doctor-config-flow-BDDsR2J1.js +978 -0
  145. package/dist/doctor-config-flow-CwFFRUic.js +979 -0
  146. package/dist/enable-C3I9dWel.js +59 -0
  147. package/dist/enable-DnwKeWnR.js +59 -0
  148. package/dist/entry.js +75 -21
  149. package/dist/env-DyyqmxSM.js +60 -0
  150. package/dist/env-vars-CD2_baIP.js +43 -0
  151. package/dist/env-vars-a7S70ba7.js +43 -0
  152. package/dist/errors-0dfGxeYQ.js +35 -0
  153. package/dist/errors-C1kDByVU.js +35 -0
  154. package/dist/exec-CAk1dxq_.js +164 -0
  155. package/dist/exec-epNpA1aU.js +164 -0
  156. package/dist/export-html/template.css +0 -36
  157. package/dist/export-html/template.js +1 -32
  158. package/dist/extensionAPI.js +1765 -1590
  159. package/dist/fetch-BMQq41sB.js +281 -0
  160. package/dist/fetch-Cky99wYB.js +281 -0
  161. package/dist/fetch-D3tw4B4n.js +67 -0
  162. package/dist/fetch-DTsU2XnC.js +67 -0
  163. package/dist/fetch-Dgm9ZHFm.js +67 -0
  164. package/dist/file-lock-DWH0TfVu.js +107 -0
  165. package/dist/file-lock-DXW9h9ek.js +107 -0
  166. package/dist/fs-safe-BjSd07M4.js +115 -0
  167. package/dist/fs-safe-aWIhCWlb.js +125 -0
  168. package/dist/gateway-cli-C4y4H61g.js +24546 -0
  169. package/dist/gateway-cli-CtFr42NV.js +24550 -0
  170. package/dist/gateway-rpc-B92CH0D3.js +28 -0
  171. package/dist/gateway-rpc-DZNlWapO.js +28 -0
  172. package/dist/gmail-setup-utils-CKyh29_R.js +422 -0
  173. package/dist/gmail-setup-utils-DquflkMR.js +423 -0
  174. package/dist/health-BYl7T-4m.js +1417 -0
  175. package/dist/health-DdviISKg.js +1414 -0
  176. package/dist/health-format-BE5TK5bs.js +28 -0
  177. package/dist/heartbeat-visibility-BO3iRpB6.js +125 -0
  178. package/dist/heartbeat-visibility-Cwp4TrTv.js +125 -0
  179. package/dist/help-format-D3JhWp1E.js +17 -0
  180. package/dist/helpers-DAEoFkbn.js +10 -0
  181. package/dist/helpers-ndPQWl6m.js +10 -0
  182. package/dist/hook-runner-global-C1thol1d.js +527 -0
  183. package/dist/hooks-cli-BKS9uZ0H.js +1221 -0
  184. package/dist/hooks-cli-FLWcCr9q.js +1217 -0
  185. package/dist/host-env-security-BGibnCbS.js +106 -0
  186. package/dist/host-env-security-axRnIi8d.js +106 -0
  187. package/dist/image-ops-CX41n0v5.js +354 -0
  188. package/dist/image-ops-DSL3eFfQ.js +354 -0
  189. package/dist/import-BSFgt760.js +604 -0
  190. package/dist/import-Da1CHJJg.js +606 -0
  191. package/dist/inbound-context-BLy-G2Eq.js +68 -0
  192. package/dist/inbound-context-a5bzQvRt.js +68 -0
  193. package/dist/index.js +137 -108
  194. package/dist/inspect-BEpFbi0c.js +286 -0
  195. package/dist/inspect-BeNNpWna.js +286 -0
  196. package/dist/installs-CH7Qq_m_.js +319 -0
  197. package/dist/installs-CcM8H2YA.js +319 -0
  198. package/dist/ipv4-DNo9AFDu.js +46 -0
  199. package/dist/ipv4-VfoVR5uR.js +46 -0
  200. package/dist/ir-BPwP8hIc.js +972 -0
  201. package/dist/json-files-BI20PLIm.js +46 -0
  202. package/dist/lifecycle-core-5Zxqwa6V.js +476 -0
  203. package/dist/lifecycle-core-C1bGeLby.js +474 -0
  204. package/dist/links-CtGBIrG8.js +15 -0
  205. package/dist/loader-BoP3JA-r.js +22411 -0
  206. package/dist/loader-DXbpue-L.js +22414 -0
  207. package/dist/logger-ASsO5Nz-.js +49 -0
  208. package/dist/logging-Cd9y2AdQ.js +20 -0
  209. package/dist/logging-DRwtiLIS.js +1 -0
  210. package/dist/logging-fywhKCmE.js +1 -0
  211. package/dist/login-B2UXzgaB.js +61 -0
  212. package/dist/login-BEFL3xY9.js +62 -0
  213. package/dist/login-qr-C7wAz2fe.js +329 -0
  214. package/dist/login-qr-DWpUP1Ud.js +325 -0
  215. package/dist/logs-cli-CAcd-pXA.js +240 -0
  216. package/dist/logs-cli-D7Bzarht.js +236 -0
  217. package/dist/markdown-tables-BBNUZp4n.js +29 -0
  218. package/dist/markdown-tables-NgPcfXoF.js +29 -0
  219. package/dist/media-4-qOIjO-.js +971 -0
  220. package/dist/media-DTwJhAbE.js +9481 -0
  221. package/dist/message-action-names-BsNTjuBE.js +2520 -0
  222. package/dist/message-action-names-ocKcq8_3.js +2520 -0
  223. package/dist/message-channel-CtcVHawF.js +91 -0
  224. package/dist/message-channel-tuc9CdEw.js +91 -0
  225. package/dist/mime-CAqaK3kp.js +146 -0
  226. package/dist/mime-ViuhRuMM.js +146 -0
  227. package/dist/net-DSkFMHJ8.js +225 -0
  228. package/dist/net-DTqfFYzt.js +225 -0
  229. package/dist/node-cli-BeXU67eQ.js +1458 -0
  230. package/dist/node-cli-i2aCtnmM.js +1462 -0
  231. package/dist/node-service-RyMlWp8N.js +67 -0
  232. package/dist/node-service-TL9b6Qfz.js +67 -0
  233. package/dist/nodes-cli-CtqnXBMD.js +1346 -0
  234. package/dist/nodes-cli-DgQU3LrG.js +1350 -0
  235. package/dist/nodes-screen-B7HJugJ0.js +250 -0
  236. package/dist/nodes-screen-nCRd71Mk.js +250 -0
  237. package/dist/note-B6142LyJ.js +92 -0
  238. package/dist/note-D-EI0czq.js +92 -0
  239. package/dist/npm-registry-spec-PPyRXSpx.js +786 -0
  240. package/dist/npm-registry-spec-uUmDWe6v.js +786 -0
  241. package/dist/npm-resolution-BC1LqCm2.js +86 -0
  242. package/dist/npm-resolution-DhlhUmRF.js +86 -0
  243. package/dist/onboard-CGpC2ecw.js +647 -0
  244. package/dist/onboard-auth-cNtb3FTP.js +211 -0
  245. package/dist/onboard-auth-gwz-0mZ6.js +207 -0
  246. package/dist/onboard-channels-CXjJYzHC.js +2548 -0
  247. package/dist/onboard-channels-vtaIxYml.js +2549 -0
  248. package/dist/onboard-config-DOmXYEvJ.js +39 -0
  249. package/dist/onboard-config-JmR21VYa.js +39 -0
  250. package/dist/onboard-helpers-8afRV_Tm.js +364 -0
  251. package/dist/onboard-helpers-DTRrJLj-.js +363 -0
  252. package/dist/onboard-jLzfwoPx.js +649 -0
  253. package/dist/onboard-remote-CFkvVAYg.js +127 -0
  254. package/dist/onboard-remote-JfBnmK70.js +127 -0
  255. package/dist/onboarding-Dt0LKvZn.js +586 -0
  256. package/dist/onboarding-gMKlA2bP.js +588 -0
  257. package/dist/onboarding.finalize-BDML6Jx7.js +403 -0
  258. package/dist/onboarding.finalize-D850VgMA.js +405 -0
  259. package/dist/onboarding.gateway-config-DolBTXWT.js +196 -0
  260. package/dist/onboarding.gateway-config-rJkIamlG.js +202 -0
  261. package/dist/outbound-CPMaDtgC.js +220 -0
  262. package/dist/outbound-CYSuCMiW.js +221 -0
  263. package/dist/outbound-attachment-Ci02LXoq.js +18 -0
  264. package/dist/outbound-attachment-CqZ7Qc_o.js +18 -0
  265. package/dist/outbound-attachment-CuqWdsdV.js +18 -0
  266. package/dist/pairing-cli-B9JKvvST.js +126 -0
  267. package/dist/pairing-cli-C4HrfIHe.js +130 -0
  268. package/dist/pairing-labels-CBmGQ31P.js +9 -0
  269. package/dist/pairing-labels-D0xwC7Xb.js +9 -0
  270. package/dist/pairing-store-BoF0g-iN.js +459 -0
  271. package/dist/pairing-store-CseXj-5p.js +460 -0
  272. package/dist/path-env-CPZbb7me.js +89 -0
  273. package/dist/path-env-GTM4HXCN.js +89 -0
  274. package/dist/path-safety-BFE0XmGC.js +14 -0
  275. package/dist/path-safety-BJ8ge6Ho.js +14 -0
  276. package/dist/paths-DHuXVC00.js +229 -0
  277. package/dist/plugin-auto-enable-B_9J1XED.js +302 -0
  278. package/dist/plugin-auto-enable-DghjlFCL.js +301 -0
  279. package/dist/plugin-registry-68h2T8vi.js +33 -0
  280. package/dist/plugin-registry-BitdVPb4.js +33 -0
  281. package/dist/plugin-sdk/agents/agent-helpers.d.ts +0 -1
  282. package/dist/plugin-sdk/agents/agent-scope.d.ts +11 -0
  283. package/dist/plugin-sdk/agents/agent-types.d.ts +1 -6
  284. package/dist/plugin-sdk/agents/agent-utils.d.ts +0 -14
  285. package/dist/plugin-sdk/agents/provider-utils.d.ts +0 -1
  286. package/dist/plugin-sdk/agents/subagent-registry.store.d.ts +0 -1
  287. package/dist/plugin-sdk/agents/subagent-spawn.d.ts +0 -1
  288. package/dist/plugin-sdk/agents/tools/sessions-helpers.d.ts +0 -1
  289. package/dist/plugin-sdk/auth/constants.d.ts +15 -0
  290. package/dist/plugin-sdk/auth/display.d.ts +7 -0
  291. package/dist/plugin-sdk/auth/doctor.d.ts +8 -0
  292. package/dist/plugin-sdk/auth/env-injection.d.ts +38 -0
  293. package/dist/plugin-sdk/auth/index.d.ts +10 -0
  294. package/dist/plugin-sdk/auth/oauth.d.ts +13 -0
  295. package/dist/plugin-sdk/auth/order.d.ts +8 -0
  296. package/dist/plugin-sdk/auth/paths.d.ts +3 -0
  297. package/dist/plugin-sdk/auth/profiles.d.ts +11 -0
  298. package/dist/plugin-sdk/auth/provider-auth.d.ts +32 -0
  299. package/dist/plugin-sdk/auth/store.d.ts +7 -0
  300. package/dist/plugin-sdk/auth/types.d.ts +45 -0
  301. package/dist/plugin-sdk/auth/usage.d.ts +80 -0
  302. package/dist/plugin-sdk/auto-reply/reply/agent-runner-execution.d.ts +0 -1
  303. package/dist/plugin-sdk/auto-reply/reply/agent-runner-utils.d.ts +3 -36
  304. package/dist/plugin-sdk/auto-reply/reply/commands-status.d.ts +1 -7
  305. package/dist/plugin-sdk/auto-reply/reply/commands-subagents/shared.d.ts +1 -1
  306. package/dist/plugin-sdk/auto-reply/reply/commands-types.d.ts +1 -13
  307. package/dist/plugin-sdk/auto-reply/reply/directive-handling.levels.d.ts +1 -10
  308. package/dist/plugin-sdk/auto-reply/reply/directive-handling.params.d.ts +1 -11
  309. package/dist/plugin-sdk/auto-reply/reply/directive-handling.parse.d.ts +1 -29
  310. package/dist/plugin-sdk/auto-reply/reply/directive-handling.persist.d.ts +0 -3
  311. package/dist/plugin-sdk/auto-reply/reply/directive-handling.shared.d.ts +0 -25
  312. package/dist/plugin-sdk/auto-reply/reply/directives.d.ts +3 -42
  313. package/dist/plugin-sdk/auto-reply/reply/get-reply-directives-apply.d.ts +0 -9
  314. package/dist/plugin-sdk/auto-reply/reply/get-reply-directives-utils.d.ts +0 -1
  315. package/dist/plugin-sdk/auto-reply/reply/get-reply-directives.d.ts +1 -20
  316. package/dist/plugin-sdk/auto-reply/reply/get-reply-inline-actions.d.ts +1 -12
  317. package/dist/plugin-sdk/auto-reply/reply/get-reply-run.d.ts +1 -15
  318. package/dist/plugin-sdk/auto-reply/reply/queue/types.d.ts +1 -17
  319. package/dist/plugin-sdk/auto-reply/reply/response-prefix-template.d.ts +4 -6
  320. package/dist/plugin-sdk/auto-reply/reply/session-run-accounting.d.ts +0 -7
  321. package/dist/plugin-sdk/auto-reply/reply/session-updates.d.ts +0 -10
  322. package/dist/plugin-sdk/auto-reply/reply.d.ts +1 -1
  323. package/dist/plugin-sdk/auto-reply/status.d.ts +3 -12
  324. package/dist/plugin-sdk/auto-reply/templating.d.ts +0 -4
  325. package/dist/plugin-sdk/auto-reply/thinking.d.ts +0 -15
  326. package/dist/plugin-sdk/auto-reply/types.d.ts +1 -2
  327. package/dist/plugin-sdk/channels/dock.d.ts +1 -2
  328. package/dist/plugin-sdk/channels/plugins/types.adapters.d.ts +0 -6
  329. package/dist/plugin-sdk/channels/plugins/types.core.d.ts +1 -0
  330. package/dist/plugin-sdk/channels/plugins/types.d.ts +1 -1
  331. package/dist/plugin-sdk/channels/plugins/types.plugin.d.ts +1 -2
  332. package/dist/plugin-sdk/channels/voice-credentials.d.ts +26 -0
  333. package/dist/plugin-sdk/commands/agent/session.d.ts +1 -2
  334. package/dist/plugin-sdk/commands/onboard-helpers.d.ts +0 -1
  335. package/dist/plugin-sdk/commands/onboard-types.d.ts +2 -1
  336. package/dist/plugin-sdk/config/defaults.d.ts +0 -1
  337. package/dist/plugin-sdk/config/legacy.migrations.d.ts +2 -1
  338. package/dist/plugin-sdk/config/legacy.shared.d.ts +0 -9
  339. package/dist/plugin-sdk/config/sessions/types.d.ts +0 -17
  340. package/dist/plugin-sdk/config/types.agent-defaults.d.ts +28 -120
  341. package/dist/plugin-sdk/config/types.agents.d.ts +8 -0
  342. package/dist/plugin-sdk/config/types.base.d.ts +0 -1
  343. package/dist/plugin-sdk/config/types.messages.d.ts +1 -6
  344. package/dist/plugin-sdk/config/types.remoteclaw.d.ts +2 -2
  345. package/dist/plugin-sdk/config/types.tools.d.ts +1 -74
  346. package/dist/plugin-sdk/config/types.tts.d.ts +2 -1
  347. package/dist/plugin-sdk/config/zod-schema.agent-defaults.d.ts +9 -70
  348. package/dist/plugin-sdk/config/zod-schema.agent-runtime.d.ts +12 -210
  349. package/dist/plugin-sdk/config/zod-schema.agents.d.ts +14 -86
  350. package/dist/plugin-sdk/config/zod-schema.core.d.ts +6 -234
  351. package/dist/plugin-sdk/config/zod-schema.d.ts +111 -378
  352. package/dist/plugin-sdk/config/zod-schema.providers-core.d.ts +148 -160
  353. package/dist/plugin-sdk/config/zod-schema.providers-whatsapp.d.ts +12 -12
  354. package/dist/plugin-sdk/config/zod-schema.providers.d.ts +88 -96
  355. package/dist/plugin-sdk/config/zod-schema.session.d.ts +4 -10
  356. package/dist/plugin-sdk/daemon/constants.d.ts +2 -2
  357. package/dist/plugin-sdk/gateway/protocol/index.d.ts +10 -17
  358. package/dist/plugin-sdk/gateway/protocol/schema/sessions.d.ts +0 -7
  359. package/dist/plugin-sdk/gateway/server/ws-types.d.ts +2 -0
  360. package/dist/plugin-sdk/gateway/session-utils.types.d.ts +0 -3
  361. package/dist/plugin-sdk/index.js +722 -1283
  362. package/dist/plugin-sdk/infra/agent-events.d.ts +1 -1
  363. package/dist/plugin-sdk/infra/provider-usage.auth.d.ts +0 -1
  364. package/dist/plugin-sdk/infra/provider-usage.load.d.ts +0 -1
  365. package/dist/plugin-sdk/line/config-schema.d.ts +4 -4
  366. package/dist/plugin-sdk/logging/levels.d.ts +1 -1
  367. package/dist/plugin-sdk/middleware/auth-key-retry.d.ts +31 -0
  368. package/dist/plugin-sdk/middleware/channel-bridge.d.ts +4 -0
  369. package/dist/plugin-sdk/middleware/cli-runtime-base.d.ts +6 -0
  370. package/dist/plugin-sdk/middleware/error-classifier.d.ts +5 -0
  371. package/dist/plugin-sdk/middleware/media-capability.d.ts +21 -0
  372. package/dist/plugin-sdk/middleware/media-resolver.d.ts +12 -0
  373. package/dist/plugin-sdk/middleware/runtime-factory.d.ts +42 -0
  374. package/dist/plugin-sdk/middleware/runtimes/claude.d.ts +10 -0
  375. package/dist/plugin-sdk/middleware/runtimes/codex.d.ts +5 -0
  376. package/dist/plugin-sdk/middleware/runtimes/gemini.d.ts +11 -0
  377. package/dist/plugin-sdk/middleware/runtimes/opencode.d.ts +5 -0
  378. package/dist/plugin-sdk/middleware/types.d.ts +41 -1
  379. package/dist/plugin-sdk/plugin-sdk/index.d.ts +5 -1
  380. package/dist/plugin-sdk/plugins/manifest-registry.d.ts +2 -0
  381. package/dist/plugin-sdk/plugins/manifest.d.ts +4 -4
  382. package/dist/plugin-sdk/plugins/registry.d.ts +18 -0
  383. package/dist/plugin-sdk/plugins/types.d.ts +5 -1
  384. package/dist/plugin-sdk/stt/defaults.d.ts +2 -0
  385. package/dist/plugin-sdk/stt/preflight.d.ts +14 -0
  386. package/dist/plugin-sdk/stt/providers/deepgram/index.d.ts +2 -0
  387. package/dist/plugin-sdk/stt/providers/google/index.d.ts +2 -0
  388. package/dist/plugin-sdk/stt/providers/groq/index.d.ts +2 -0
  389. package/dist/plugin-sdk/stt/providers/index.d.ts +4 -0
  390. package/dist/plugin-sdk/stt/providers/mistral/index.d.ts +2 -0
  391. package/dist/plugin-sdk/stt/providers/openai/index.d.ts +2 -0
  392. package/dist/plugin-sdk/stt/stt.d.ts +27 -0
  393. package/dist/plugin-sdk/stt/types.d.ts +22 -0
  394. package/dist/plugin-sdk/terminal/palette.d.ts +2 -2
  395. package/dist/plugin-sdk/tts/providers/edge.d.ts +2 -0
  396. package/dist/plugin-sdk/tts/providers/elevenlabs.d.ts +2 -0
  397. package/dist/plugin-sdk/tts/providers/index.d.ts +4 -0
  398. package/dist/plugin-sdk/tts/providers/openai.d.ts +2 -0
  399. package/dist/plugin-sdk/tts/tts.d.ts +13 -5
  400. package/dist/plugin-sdk/tts/types.d.ts +21 -0
  401. package/dist/plugins-BviLFPLV.js +255 -0
  402. package/dist/plugins-CaudBUbl.js +254 -0
  403. package/dist/plugins-cli-CsLhphNr.js +803 -0
  404. package/dist/plugins-cli-CujSP9NS.js +807 -0
  405. package/dist/ports-BtuzUQHl.js +370 -0
  406. package/dist/ports-CMcHia07.js +96 -0
  407. package/dist/ports-DALdfBQy.js +96 -0
  408. package/dist/ports-gRBeuUtp.js +316 -0
  409. package/dist/preflight-Bq8rimP-.js +667 -0
  410. package/dist/preflight-DyYbEp9X.js +667 -0
  411. package/dist/program-D64vUv0b.js +250 -0
  412. package/dist/program-context-CTFkimUr.js +474 -0
  413. package/dist/progress-BcwxtM9Q.js +124 -0
  414. package/dist/prompt-DtWGd43j.js +21 -0
  415. package/dist/prompt-select-styled-GW2PexAK.js +1672 -0
  416. package/dist/prompt-select-styled-JOuWGHX7.js +1669 -0
  417. package/dist/prompt-style-BpUMhEHC.js +9 -0
  418. package/dist/provider-auth-B7QgxlKt.js +187 -0
  419. package/dist/provider-auth-j-EQvvIk.js +187 -0
  420. package/dist/provider-dispatcher-Bx6CaIoV.js +660 -0
  421. package/dist/provider-dispatcher-DhkvjhO5.js +659 -0
  422. package/dist/push-apns--nEiZmEN.js +711 -0
  423. package/dist/push-apns-BtS6B6lb.js +713 -0
  424. package/dist/pw-ai-BpCsXF-x.js +1908 -0
  425. package/dist/pw-ai-ud_Kbn5S.js +1911 -0
  426. package/dist/qr-cli-BCeVLGfz.js +353 -0
  427. package/dist/qr-cli-Crsqtw01.js +349 -0
  428. package/dist/redact-Ci96Gj0O.js +191 -0
  429. package/dist/redact-snapshot-B9nof-Pb.js +1952 -0
  430. package/dist/redact-snapshot-BKiS91Mj.js +1952 -0
  431. package/dist/register.agent-CcvOeVnL.js +292 -0
  432. package/dist/register.agent-azH_tdVX.js +1014 -0
  433. package/dist/register.configure-DAaZLjHs.js +130 -0
  434. package/dist/register.configure-lUl8O79m.js +135 -0
  435. package/dist/register.import-B83Dn36B.js +29 -0
  436. package/dist/register.import-wIYU2cVW.js +31 -0
  437. package/dist/register.maintenance-Bo-ooQDU.js +501 -0
  438. package/dist/register.maintenance-BwZ4OkK2.js +503 -0
  439. package/dist/register.message-BQhRoEQQ.js +687 -0
  440. package/dist/register.message-CvZKWeGb.js +691 -0
  441. package/dist/register.onboard---3EPh-O.js +98 -0
  442. package/dist/register.onboard-rsHSJUvQ.js +94 -0
  443. package/dist/register.setup-B0gc_lne.js +118 -0
  444. package/dist/register.setup-MWpb7jxL.js +114 -0
  445. package/dist/register.status-health-sessions-BZJ0wTSa.js +429 -0
  446. package/dist/register.status-health-sessions-CyrUwwtB.js +667 -0
  447. package/dist/register.subclis-i2d2ugaJ.js +267 -0
  448. package/dist/replies-BIx-MbQ7.js +136 -0
  449. package/dist/replies-DVU655H4.js +136 -0
  450. package/dist/reply-CL5VMSKN.js +12372 -0
  451. package/dist/reply-XKyfU3rS.js +12375 -0
  452. package/dist/reply-directives-DQfJ001O.js +182 -0
  453. package/dist/reply-directives-DfUITt7C.js +182 -0
  454. package/dist/reply-payloads-ZHo6kfTS.js +527 -0
  455. package/dist/reply-prefix-BSf3PC0x.js +37 -0
  456. package/dist/reply-prefix-DBTlMHLK.js +37 -0
  457. package/dist/resolve-route-B-_IgETc.js +249 -0
  458. package/dist/resolve-route-C8ZsgWDQ.js +249 -0
  459. package/dist/response-prefix-template-3LeqJx2X.js +134 -0
  460. package/dist/response-prefix-template-DBrUVx5V.js +134 -0
  461. package/dist/retry-CDrH81GP.js +77 -0
  462. package/dist/retry-Dar_7pCv.js +77 -0
  463. package/dist/run-main-rOudcbbs.js +308 -0
  464. package/dist/runtime-guard-CK80eucm.js +60 -0
  465. package/dist/runtime-status-CR9445g5.js +12 -0
  466. package/dist/runtime-status-hFVEC3wO.js +12 -0
  467. package/dist/secure-random-CLWSvf8A.js +44 -0
  468. package/dist/security-cli-B8lXw9ke.js +488 -0
  469. package/dist/security-cli-CRkS3VAf.js +483 -0
  470. package/dist/send-6g8QKfWj.js +374 -0
  471. package/dist/send-B5Hz1PIn.js +29 -0
  472. package/dist/send-B8eIlA1u.js +349 -0
  473. package/dist/send-BFZPQE4j.js +492 -0
  474. package/dist/send-BpTDvE0D.js +1779 -0
  475. package/dist/send-BxOrO1Wv.js +1776 -0
  476. package/dist/send-C6gPJu-Z.js +11 -0
  477. package/dist/send-C7MoKtkN.js +426 -0
  478. package/dist/send-CXzq2LI6.js +2245 -0
  479. package/dist/send-CYOZoObr.js +547 -0
  480. package/dist/send-CfQyIvcC.js +332 -0
  481. package/dist/send-DUtuuwhw.js +492 -0
  482. package/dist/send-DbafVwxp.js +2245 -0
  483. package/dist/send-DeZg8K7y.js +349 -0
  484. package/dist/send-DwkjxJlv.js +547 -0
  485. package/dist/send-iX9xbxlU.js +1178 -0
  486. package/dist/server-BKfCzEzd.js +206 -0
  487. package/dist/server-fmO4eo7K.js +202 -0
  488. package/dist/server-lifecycle-CgPpP10P.js +2437 -0
  489. package/dist/server-lifecycle-Cn8yY5MW.js +2437 -0
  490. package/dist/server-node-events-C-ZzSBYh.js +391 -0
  491. package/dist/server-node-events-DYlyfDHM.js +395 -0
  492. package/dist/service-C2j81L86.js +670 -0
  493. package/dist/service-C8a0SXHD.js +670 -0
  494. package/dist/session-AulYhqOb.js +170 -0
  495. package/dist/session-C6VKWvx6.js +170 -0
  496. package/dist/session-cost-usage-0Vs4hgMe.js +627 -0
  497. package/dist/session-cost-usage-C-DsaOfN.js +627 -0
  498. package/dist/session-dirs-CO1f2ArM.js +318 -0
  499. package/dist/session-dirs-DoboH7Oy.js +318 -0
  500. package/dist/session-utils-CRK8ToKG.js +621 -0
  501. package/dist/session-utils-DWlkmCX8.js +621 -0
  502. package/dist/sessions-DtqrmUJS.js +2553 -0
  503. package/dist/sessions-gT-4fcX-.js +245 -0
  504. package/dist/shell-env-DBS5su07.js +163 -0
  505. package/dist/shell-env-c3j5zcU9.js +163 -0
  506. package/dist/ssrf-8wNqPNzN.js +183 -0
  507. package/dist/ssrf-CJIdPXuS.js +183 -0
  508. package/dist/status-BI_-xpDt.js +1947 -0
  509. package/dist/status-PZVwjKjl.js +1943 -0
  510. package/dist/status.update-BmuDZ7E7.js +449 -0
  511. package/dist/status.update-Mf6HSRvU.js +449 -0
  512. package/dist/store-B7PGEdFf.js +2555 -0
  513. package/dist/store-CzhBjUCN.js +64 -0
  514. package/dist/store-YkSxKAey.js +53 -0
  515. package/dist/store-ZNeFv2Q7.js +64 -0
  516. package/dist/subagent-registry-R1DiAM4R.js +4839 -0
  517. package/dist/subagent-registry-xLRXC8Bg.js +4841 -0
  518. package/dist/subsystem-BAW_f3DI.js +1195 -0
  519. package/dist/subsystem-DGSHVL8I.js +1081 -0
  520. package/dist/system-cli-9SvRrT9D.js +77 -0
  521. package/dist/system-cli-yCa5Q1YM.js +73 -0
  522. package/dist/systemd-40Rij3QR.js +547 -0
  523. package/dist/systemd-5C97CSzd.js +547 -0
  524. package/dist/systemd-hints-3iQteJw-.js +278 -0
  525. package/dist/systemd-hints-CyQqHq1i.js +278 -0
  526. package/dist/systemd-linger-B2rPbnAi.js +75 -0
  527. package/dist/systemd-linger-DDvkfxH-.js +75 -0
  528. package/dist/table-DFx25vNb.js +279 -0
  529. package/dist/tables-C5fI0PmT.js +55 -0
  530. package/dist/tables-Cm9qvQ9D.js +55 -0
  531. package/dist/tables-fRe01eP1.js +55 -0
  532. package/dist/tailnet-Da-_9e8E.js +40 -0
  533. package/dist/tailnet-xt92Yaop.js +40 -0
  534. package/dist/tailscale-CnV0JWca.js +230 -0
  535. package/dist/tailscale-VkEC8dzj.js +230 -0
  536. package/dist/targets-C99szk_e.js +114 -0
  537. package/dist/targets-CPaTjbpp.js +2607 -0
  538. package/dist/targets-D-p4rJVS.js +650 -0
  539. package/dist/targets-D2OQt8-7.js +650 -0
  540. package/dist/targets-D94MtTiZ.js +2606 -0
  541. package/dist/targets-RajrXTl7.js +220 -0
  542. package/dist/targets-_UWmnyI9.js +53 -0
  543. package/dist/targets-tDrl_ioQ.js +46 -0
  544. package/dist/thinking-4nOZPunr.js +60 -0
  545. package/dist/thinking-ZfH2V9Os.js +60 -0
  546. package/dist/tokens-TtJJxzRr.js +21 -0
  547. package/dist/tool-display-Bxs_1jIn.js +785 -0
  548. package/dist/tool-display-D9p_Ttkq.js +785 -0
  549. package/dist/tool-images-9Ron321Q.js +263 -0
  550. package/dist/tool-images-BWhy6WRN.js +263 -0
  551. package/dist/trash-B5xyvBDf.js +125 -0
  552. package/dist/trash-BpB96kHe.js +125 -0
  553. package/dist/tui-Ba0uZDrg.js +3237 -0
  554. package/dist/tui-Biz0HqDj.js +3237 -0
  555. package/dist/tui-cli-C-UV6o2v.js +63 -0
  556. package/dist/tui-cli-Ds_bLT-h.js +67 -0
  557. package/dist/types.tools-BBb2rl3g.js +23 -0
  558. package/dist/types.tools-BDJw1yFx.js +23 -0
  559. package/dist/update-Barj5dsg.js +349 -0
  560. package/dist/update-D839Q8su.js +349 -0
  561. package/dist/update-cli-C0LnrpIt.js +1148 -0
  562. package/dist/update-cli-CUypa-T-.js +1150 -0
  563. package/dist/usage-BI9kergH.js +5465 -0
  564. package/dist/utils-DPoNpP7D.js +631 -0
  565. package/dist/version-3QUZW8EP.js +52 -0
  566. package/dist/version-CVMnqdzu.js +52 -0
  567. package/dist/voice-credentials-64XAMSJm.js +46 -0
  568. package/dist/voice-credentials-v-CQkTpD.js +46 -0
  569. package/dist/web-63IbbidQ.js +3051 -0
  570. package/dist/web-D9N764Da.js +80 -0
  571. package/dist/web-DUvNYLzr.js +75 -0
  572. package/dist/webhooks-cli-owhVNNkz.js +334 -0
  573. package/dist/webhooks-cli-zlvka6QD.js +330 -0
  574. package/dist/whatsapp-actions-8DejyRG5.js +126 -0
  575. package/dist/whatsapp-actions-DCzp5LKe.js +131 -0
  576. package/dist/widearea-dns-CQqZIeu8.js +127 -0
  577. package/dist/workspace-CB7pVojf.js +441 -0
  578. package/dist/workspace-DWEyzM0F.js +439 -0
  579. package/dist/zod-schema-CvFqwpNE.js +2719 -0
  580. package/dist/zod-schema-Y5SQgJLm.js +2719 -0
  581. package/extensions/matrix/src/matrix/monitor/replies.ts +0 -24
  582. package/extensions/mattermost/src/mattermost/monitor-helpers.ts +0 -1
  583. package/extensions/voice-call/index.ts +18 -1
  584. package/package.json +3 -4
  585. package/dist/accounts-7fm_KzPm.js +0 -32
  586. package/dist/accounts-BFy_Z3od.js +0 -272
  587. package/dist/accounts-BTXSfPWi.js +0 -270
  588. package/dist/accounts-BxGS70Do.js +0 -36
  589. package/dist/accounts-CNY1TGj1.js +0 -47
  590. package/dist/accounts-DqRQ75w3.js +0 -36
  591. package/dist/accounts-iODF3SK2.js +0 -47
  592. package/dist/ack-reactions-C1hk85VE.js +0 -446
  593. package/dist/ack-reactions-DRC2CiDQ.js +0 -446
  594. package/dist/acp-cli-DD-PD4NM.js +0 -1326
  595. package/dist/acp-cli-DIyRCOum.js +0 -1320
  596. package/dist/active-listener-VzhWW8W6.js +0 -37
  597. package/dist/active-listener-z0qVEcom.js +0 -37
  598. package/dist/agent-D2HeDFFR.js +0 -731
  599. package/dist/agent-Da_eZ5BP.js +0 -732
  600. package/dist/agent-helpers-B6VfZ9_u.js +0 -606
  601. package/dist/agent-helpers-CTx5KKJu.js +0 -606
  602. package/dist/agent-scope-BqPmD-Ax.js +0 -114
  603. package/dist/agent-scope-DgQzamQB.js +0 -116
  604. package/dist/agents-TB3QpHoo.js +0 -788
  605. package/dist/agents.config-BsAQTYe1.js +0 -116
  606. package/dist/agents.config-C9fyYfAh.js +0 -116
  607. package/dist/ansi-D04X81yq.js +0 -14
  608. package/dist/audio-DPOuhNq7.js +0 -43
  609. package/dist/audio-VBcVDa08.js +0 -43
  610. package/dist/audio-preflight-CK3EA3Dv.js +0 -69
  611. package/dist/audio-preflight-tdXtrutj.js +0 -64
  612. package/dist/audit-CJipUWDi.js +0 -3138
  613. package/dist/audit-COWzB9Y1.js +0 -3138
  614. package/dist/auth-CAczFgAO.js +0 -448
  615. package/dist/auth-Deh9i9Eg.js +0 -448
  616. package/dist/auth-profiles-BquJGKLC.js +0 -279
  617. package/dist/auth-profiles-D8vKiBPq.js +0 -281
  618. package/dist/banner-CUWBOR42.js +0 -294
  619. package/dist/binaries-DXW6oATV.js +0 -13
  620. package/dist/bindings-8YtSWb91.js +0 -69
  621. package/dist/bindings-l1R5LQQH.js +0 -69
  622. package/dist/bonjour-discovery-DdAk1VyO.js +0 -378
  623. package/dist/bonjour-discovery-DuhiIZZx.js +0 -378
  624. package/dist/browser-cli-5Q9lhGdd.js +0 -1687
  625. package/dist/browser-cli-D2qMeSx1.js +0 -1692
  626. package/dist/call-CZHVeMf1.js +0 -2828
  627. package/dist/call-CoMjY7ah.js +0 -2829
  628. package/dist/catalog-CYiAleBT.js +0 -185
  629. package/dist/catalog-pjPqB2hC.js +0 -185
  630. package/dist/channel-account-context-CvIDAtHS.js +0 -550
  631. package/dist/channel-account-context-q-o0pG1A.js +0 -550
  632. package/dist/channel-activity-BaCNOZpP.js +0 -94
  633. package/dist/channel-activity-Cd1JhIUj.js +0 -292
  634. package/dist/channel-activity-DTKGf3j5.js +0 -94
  635. package/dist/channel-options-8SjIcDDI.js +0 -33
  636. package/dist/channel-options-BtQGtMF4.js +0 -32
  637. package/dist/channel-selection-C4DzrynU.js +0 -51
  638. package/dist/channel-selection-DdfhwFuY.js +0 -51
  639. package/dist/channel-web-BKJSXnwf.js +0 -2136
  640. package/dist/channel-web-BUzvNE_A.js +0 -2134
  641. package/dist/channels-cli-CCXY796Z.js +0 -1421
  642. package/dist/channels-cli-DTfx1zFC.js +0 -1426
  643. package/dist/channels-status-issues-DnmuqPsi.js +0 -18
  644. package/dist/channels-status-issues-p1pCvTh8.js +0 -18
  645. package/dist/chat-envelope-DEZ-5RY8.js +0 -248
  646. package/dist/chat-envelope-el7Uo-Fe.js +0 -248
  647. package/dist/chrome-Dd4dv0Vh.js +0 -1732
  648. package/dist/chrome-DdNEInwI.js +0 -1733
  649. package/dist/chunk-CSQfUhgF.js +0 -341
  650. package/dist/chunk-D0Y_w4oX.js +0 -341
  651. package/dist/clack-prompter-B7tOxhJd.js +0 -122
  652. package/dist/clack-prompter-CCFnKP_1.js +0 -121
  653. package/dist/cleanup-utils-CqAVZz2b.js +0 -94
  654. package/dist/cli-BRwDPW0r.js +0 -125
  655. package/dist/cli-CV86F7iv.js +0 -130
  656. package/dist/clipboard-D7_SKHPK.js +0 -31
  657. package/dist/clipboard-Dzkx6Q2K.js +0 -31
  658. package/dist/command-format-CVfo8I5f.js +0 -18
  659. package/dist/command-format-DgXcqxBt.js +0 -32
  660. package/dist/command-registry-BvLC28b4.js +0 -215
  661. package/dist/commands-B49Lu-pa.js +0 -41
  662. package/dist/commands-DI1BCqnj.js +0 -41
  663. package/dist/commands-registry-Cr6SIR3n.js +0 -892
  664. package/dist/commands-registry-agiTEGDz.js +0 -893
  665. package/dist/common-CMI-qsF8.js +0 -156
  666. package/dist/common-DSVmydhm.js +0 -156
  667. package/dist/completion-cli-C7O4JU8t.js +0 -452
  668. package/dist/completion-cli-CQNXtEJ7.js +0 -452
  669. package/dist/config-ChYRSJQt.js +0 -6953
  670. package/dist/config-CwtWvygh.js +0 -6951
  671. package/dist/config-cli-Df5nJcfO.js +0 -241
  672. package/dist/config-cli-Dqe5O1pl.js +0 -246
  673. package/dist/config-guard-C6hyuH-z.js +0 -75
  674. package/dist/config-guard-kNMQS_tm.js +0 -97
  675. package/dist/config-validation-BZBaBH69.js +0 -18
  676. package/dist/config-validation-DkrbzCyL.js +0 -18
  677. package/dist/configure-CoJmCHqT.js +0 -891
  678. package/dist/configure-DJbojDRf.js +0 -889
  679. package/dist/constants-BmRFoHl0.js +0 -67
  680. package/dist/constants-C9WPAluB.js +0 -67
  681. package/dist/control-auth-7k6Cb2zH.js +0 -397
  682. package/dist/control-auth-DBxfkJ3g.js +0 -397
  683. package/dist/control-ui/assets/index-B4ZM1lW1.js +0 -7738
  684. package/dist/control-ui/assets/index-B4ZM1lW1.js.map +0 -1
  685. package/dist/control-ui/assets/index-PED72sKF.css +0 -1
  686. package/dist/control-ui-assets-Cx_mw4D0.js +0 -186
  687. package/dist/control-ui-assets-W1AUuGrO.js +0 -186
  688. package/dist/conversation-label-C4SDz4sT.js +0 -36
  689. package/dist/conversation-label-D1frnvYe.js +0 -36
  690. package/dist/cron-cli-BJXQKtR3.js +0 -495
  691. package/dist/cron-cli-CTIj0WPW.js +0 -490
  692. package/dist/daemon-cli-CZbHvkRG.js +0 -1197
  693. package/dist/daemon-cli-Cf_YKWvV.js +0 -1199
  694. package/dist/daemon-install-CcohRvKV.js +0 -55
  695. package/dist/daemon-install-DDshfT0J.js +0 -60
  696. package/dist/daemon-install-helpers-CFGAfRlj.js +0 -462
  697. package/dist/daemon-install-helpers-DIUzSFG1.js +0 -462
  698. package/dist/defaults-B5KStIBg.js +0 -7
  699. package/dist/defaults-xUAL2Z-F.js +0 -7
  700. package/dist/deliver-BDf2lIEK.js +0 -481
  701. package/dist/deliver-DvmkSwLt.js +0 -481
  702. package/dist/delivery-queue-Cfa9Wmxp.js +0 -244
  703. package/dist/delivery-queue-CxVRi4tw.js +0 -244
  704. package/dist/devices-cli-CRsW5WOw.js +0 -316
  705. package/dist/devices-cli-Crzrk5uf.js +0 -321
  706. package/dist/diagnostics-99iCgBUh.js +0 -46
  707. package/dist/diagnostics-VC0cz7kX.js +0 -46
  708. package/dist/directory-cli-BnoQqeOX.js +0 -222
  709. package/dist/directory-cli-DdBAX3AV.js +0 -217
  710. package/dist/dm-policy-shared-DNqPbnip.js +0 -22
  711. package/dist/dm-policy-shared-vCb_hnqo.js +0 -22
  712. package/dist/dns-cli-D410XQr9.js +0 -197
  713. package/dist/dns-cli-Fgg96Xkg.js +0 -202
  714. package/dist/dock-DXSgTbDw.js +0 -928
  715. package/dist/dock-FtQwUHXE.js +0 -929
  716. package/dist/doctor-completion-BWmtCiFR.js +0 -92
  717. package/dist/doctor-completion-DTM_wDxy.js +0 -92
  718. package/dist/doctor-config-flow-Ccna5fPs.js +0 -1934
  719. package/dist/doctor-config-flow-DqzrK_jh.js +0 -1933
  720. package/dist/enable-DcJnkzfz.js +0 -59
  721. package/dist/enable-ibNq4UWy.js +0 -59
  722. package/dist/env-DeF64iu0.js +0 -60
  723. package/dist/env-vars-7aZqKPhk.js +0 -93
  724. package/dist/env-vars-CLGbxdpL.js +0 -93
  725. package/dist/errors-8F-77i6m.js +0 -35
  726. package/dist/errors-DZ199hOo.js +0 -35
  727. package/dist/exec-DbKuYyM1.js +0 -164
  728. package/dist/exec-DkFE7lqU.js +0 -164
  729. package/dist/fetch-C6XKGA11.js +0 -67
  730. package/dist/fetch-CEDsOiql.js +0 -67
  731. package/dist/fetch-ePscvwi1.js +0 -67
  732. package/dist/file-lock-CIvloidc.js +0 -107
  733. package/dist/file-lock-CzBL_VIx.js +0 -107
  734. package/dist/fs-safe-DSwT85uK.js +0 -88
  735. package/dist/fs-safe-DkBhNAc3.js +0 -98
  736. package/dist/gateway-cli-BJooqlkO.js +0 -23747
  737. package/dist/gateway-cli-C2wPjxY4.js +0 -23742
  738. package/dist/gateway-rpc-BcT4FqJQ.js +0 -28
  739. package/dist/gateway-rpc-DhKAJ5EW.js +0 -28
  740. package/dist/gmail-setup-utils-Cnx8A5pW.js +0 -422
  741. package/dist/gmail-setup-utils-nkabbKOE.js +0 -423
  742. package/dist/health-BZX-PyP0.js +0 -1420
  743. package/dist/health-BgD0koJx.js +0 -1423
  744. package/dist/health-format-BG95OE6N.js +0 -28
  745. package/dist/heartbeat-visibility-DeW9EIeS.js +0 -125
  746. package/dist/heartbeat-visibility-DvogUlnZ.js +0 -125
  747. package/dist/help-format-DAxf0l_h.js +0 -17
  748. package/dist/helpers-R7bU5IBz.js +0 -10
  749. package/dist/helpers-kkeXif0Q.js +0 -10
  750. package/dist/hook-runner-global-cyaKukZP.js +0 -527
  751. package/dist/hooks-cli-DTygpzqS.js +0 -1217
  752. package/dist/hooks-cli-Dg853OdZ.js +0 -1222
  753. package/dist/host-env-security-Bms2_EMV.js +0 -92
  754. package/dist/host-env-security-szwfmhC4.js +0 -92
  755. package/dist/image-ops-Bi6JPSkD.js +0 -354
  756. package/dist/image-ops-DWytvdh_.js +0 -354
  757. package/dist/import-D8BBZQgl.js +0 -170
  758. package/dist/import-DQ6NI4Fz.js +0 -168
  759. package/dist/inbound-context-CPkkQW0i.js +0 -68
  760. package/dist/inbound-context-DS_kpIYI.js +0 -68
  761. package/dist/inbound-path-policy-Bg4gZBx-.js +0 -250
  762. package/dist/inbound-path-policy-sdr5Ji0k.js +0 -250
  763. package/dist/inspect-Dt8hogS3.js +0 -559
  764. package/dist/inspect-vYIL1oA0.js +0 -559
  765. package/dist/installs-ClX3qQmh.js +0 -325
  766. package/dist/installs-CxjOiLUM.js +0 -325
  767. package/dist/ipv4--2WXMVtE.js +0 -46
  768. package/dist/ipv4-CDQpx1A7.js +0 -46
  769. package/dist/ir-BvKdMuSP.js +0 -940
  770. package/dist/json-files-DzpTak5i.js +0 -46
  771. package/dist/links-C3soDNDH.js +0 -15
  772. package/dist/loader-BWZ_iRxI.js +0 -22624
  773. package/dist/loader-ClFP7wvS.js +0 -22621
  774. package/dist/local-roots-B6rSCu4U.js +0 -314
  775. package/dist/local-roots-v2HlOaG5.js +0 -313
  776. package/dist/logger-Bw3cFE5t.js +0 -49
  777. package/dist/logging-C-nxX2fn.js +0 -20
  778. package/dist/login-Cmpeb59f.js +0 -62
  779. package/dist/login-D1CV2eNF.js +0 -61
  780. package/dist/login-qr-B3tpFLRV.js +0 -327
  781. package/dist/login-qr-CSQzrtFX.js +0 -322
  782. package/dist/logs-cli-BSiUZwb2.js +0 -238
  783. package/dist/logs-cli-DDtoJ1Fr.js +0 -233
  784. package/dist/markdown-tables-PJUMrC4T.js +0 -29
  785. package/dist/markdown-tables-dDWBbtqd.js +0 -29
  786. package/dist/media-Dqv7Q0aS.js +0 -10492
  787. package/dist/media-DtN0R9A0.js +0 -940
  788. package/dist/message-action-names-Bs50Ia1g.js +0 -2521
  789. package/dist/message-action-names-Btd7cMvx.js +0 -2521
  790. package/dist/message-channel-DzJqHVZD.js +0 -91
  791. package/dist/message-channel-uWMAiywE.js +0 -91
  792. package/dist/mime-BS3jhcZE.js +0 -149
  793. package/dist/mime-Cxh_64P6.js +0 -149
  794. package/dist/net-Cg8AQeke.js +0 -225
  795. package/dist/net-D6D0wgcF.js +0 -225
  796. package/dist/node-cli-Q2-n3Fgv.js +0 -24
  797. package/dist/node-cli-Uf6lAntf.js +0 -24
  798. package/dist/nodes-cli-DVLvMgBV.js +0 -1343
  799. package/dist/nodes-cli-Dxf7vAKk.js +0 -1348
  800. package/dist/nodes-screen-BR9sYoPa.js +0 -250
  801. package/dist/nodes-screen-Cw7Hv7M2.js +0 -250
  802. package/dist/note-Dlv4NmlQ.js +0 -92
  803. package/dist/note-kvWV4xtw.js +0 -92
  804. package/dist/npm-registry-spec-0qiKawvv.js +0 -786
  805. package/dist/npm-registry-spec-COvUzy5J.js +0 -786
  806. package/dist/npm-resolution-DJnq5QBs.js +0 -86
  807. package/dist/npm-resolution-DVl2spoD.js +0 -86
  808. package/dist/onboard-BcQWYGY3.js +0 -405
  809. package/dist/onboard-RQ_FAMyg.js +0 -407
  810. package/dist/onboard-channels-CHh_BuxJ.js +0 -2547
  811. package/dist/onboard-channels-DXD-CK_M.js +0 -2548
  812. package/dist/onboard-config-BCTthQ7J.js +0 -24
  813. package/dist/onboard-config-y-2cgT0V.js +0 -24
  814. package/dist/onboard-helpers-BRMP8mup.js +0 -362
  815. package/dist/onboard-helpers-CUGbuZwH.js +0 -363
  816. package/dist/onboard-remote-D-qWujdL.js +0 -127
  817. package/dist/onboard-remote-o_OW-uzc.js +0 -127
  818. package/dist/onboarding-Bf9kVcef.js +0 -541
  819. package/dist/onboarding-CVlOLLp1.js +0 -543
  820. package/dist/onboarding.finalize-CQSt37fw.js +0 -398
  821. package/dist/onboarding.finalize-DggVL7Ay.js +0 -401
  822. package/dist/onboarding.gateway-config-BLca3Td2.js +0 -198
  823. package/dist/onboarding.gateway-config-C1mcOkRh.js +0 -191
  824. package/dist/outbound-DXXccLDS.js +0 -220
  825. package/dist/outbound-ZnVvUReT.js +0 -221
  826. package/dist/outbound-attachment-CfRb07J7.js +0 -18
  827. package/dist/outbound-attachment-DGXTtERK.js +0 -18
  828. package/dist/outbound-attachment-_jj74QBM.js +0 -18
  829. package/dist/pairing-cli-Bgm4fRA3.js +0 -127
  830. package/dist/pairing-cli-J0uGb1nU.js +0 -122
  831. package/dist/pairing-labels-CVm65Jkh.js +0 -9
  832. package/dist/pairing-labels-DD1mcvQG.js +0 -9
  833. package/dist/pairing-store-5qapT5-t.js +0 -460
  834. package/dist/pairing-store-MLceBEeL.js +0 -459
  835. package/dist/path-env-DR5vn3QL.js +0 -89
  836. package/dist/path-env-qRJbjJzj.js +0 -89
  837. package/dist/path-guards-CIx4hURU.js +0 -31
  838. package/dist/path-guards-CrQOUlsq.js +0 -31
  839. package/dist/path-safety-DkT9RmTG.js +0 -14
  840. package/dist/path-safety-juI2XbO1.js +0 -14
  841. package/dist/paths-BTaH3rLn.js +0 -232
  842. package/dist/plugin-auto-enable-BUSF117F.js +0 -301
  843. package/dist/plugin-auto-enable-CoDnqA0S.js +0 -302
  844. package/dist/plugin-registry-D2B6nbn1.js +0 -33
  845. package/dist/plugin-registry-fLaMC0ik.js +0 -33
  846. package/dist/plugin-sdk/agents/agent-helpers/thinking.d.ts +0 -5
  847. package/dist/plugin-sdk/agents/agent-paths.d.ts +0 -1
  848. package/dist/plugin-sdk/agents/auth-profiles/constants.d.ts +0 -16
  849. package/dist/plugin-sdk/agents/auth-profiles/display.d.ts +0 -7
  850. package/dist/plugin-sdk/agents/auth-profiles/doctor.d.ts +0 -8
  851. package/dist/plugin-sdk/agents/auth-profiles/oauth.d.ts +0 -14
  852. package/dist/plugin-sdk/agents/auth-profiles/paths.d.ts +0 -4
  853. package/dist/plugin-sdk/agents/auth-profiles/profiles.d.ts +0 -12
  854. package/dist/plugin-sdk/agents/auth-profiles/session-override.d.ts +0 -18
  855. package/dist/plugin-sdk/agents/auth-profiles/store.d.ts +0 -10
  856. package/dist/plugin-sdk/agents/auth-profiles/types.d.ts +0 -13
  857. package/dist/plugin-sdk/agents/auth-profiles.d.ts +0 -8
  858. package/dist/plugin-sdk/agents/defaults.d.ts +0 -3
  859. package/dist/plugin-sdk/agents/provider-auth.d.ts +0 -40
  860. package/dist/plugin-sdk/auto-reply/model-runtime.d.ts +0 -17
  861. package/dist/plugin-sdk/auto-reply/reply/directive-handling.auth.d.ts +0 -19
  862. package/dist/plugin-sdk/auto-reply/reply/elevated-allowlist-matcher.d.ts +0 -20
  863. package/dist/plugin-sdk/auto-reply/reply/elevated-unavailable.d.ts +0 -8
  864. package/dist/plugin-sdk/auto-reply/reply/reply-elevated.d.ts +0 -16
  865. package/dist/plugin-sdk/compat/legacy-names.d.ts +0 -8
  866. package/dist/plugin-sdk/config/legacy.migrations.part-1.d.ts +0 -2
  867. package/dist/plugin-sdk/config/legacy.migrations.part-2.d.ts +0 -2
  868. package/dist/plugin-sdk/config/legacy.migrations.part-3.d.ts +0 -2
  869. package/dist/plugin-sdk/config/model-input.d.ts +0 -9
  870. package/dist/plugin-sdk/config/zod-schema.agent-model.d.ts +0 -5
  871. package/dist/plugin-sdk/link-understanding/apply.d.ts +0 -10
  872. package/dist/plugin-sdk/link-understanding/defaults.d.ts +0 -2
  873. package/dist/plugin-sdk/link-understanding/detect.d.ts +0 -3
  874. package/dist/plugin-sdk/link-understanding/format.d.ts +0 -4
  875. package/dist/plugin-sdk/link-understanding/runner.d.ts +0 -11
  876. package/dist/plugin-sdk/media/input-files.d.ts +0 -95
  877. package/dist/plugin-sdk/media-understanding/apply.d.ts +0 -19
  878. package/dist/plugin-sdk/media-understanding/attachments.d.ts +0 -49
  879. package/dist/plugin-sdk/media-understanding/audio-preflight.d.ts +0 -16
  880. package/dist/plugin-sdk/media-understanding/concurrency.d.ts +0 -1
  881. package/dist/plugin-sdk/media-understanding/defaults.d.ts +0 -12
  882. package/dist/plugin-sdk/media-understanding/errors.d.ts +0 -6
  883. package/dist/plugin-sdk/media-understanding/format.d.ts +0 -7
  884. package/dist/plugin-sdk/media-understanding/fs.d.ts +0 -1
  885. package/dist/plugin-sdk/media-understanding/output-extract.d.ts +0 -2
  886. package/dist/plugin-sdk/media-understanding/providers/anthropic/index.d.ts +0 -2
  887. package/dist/plugin-sdk/media-understanding/providers/deepgram/index.d.ts +0 -2
  888. package/dist/plugin-sdk/media-understanding/providers/google/index.d.ts +0 -2
  889. package/dist/plugin-sdk/media-understanding/providers/google/video.d.ts +0 -3
  890. package/dist/plugin-sdk/media-understanding/providers/groq/index.d.ts +0 -2
  891. package/dist/plugin-sdk/media-understanding/providers/index.d.ts +0 -4
  892. package/dist/plugin-sdk/media-understanding/providers/minimax/index.d.ts +0 -2
  893. package/dist/plugin-sdk/media-understanding/providers/mistral/index.d.ts +0 -2
  894. package/dist/plugin-sdk/media-understanding/providers/moonshot/index.d.ts +0 -2
  895. package/dist/plugin-sdk/media-understanding/providers/moonshot/video.d.ts +0 -3
  896. package/dist/plugin-sdk/media-understanding/providers/openai/index.d.ts +0 -2
  897. package/dist/plugin-sdk/media-understanding/providers/zai/index.d.ts +0 -2
  898. package/dist/plugin-sdk/media-understanding/resolve.d.ts +0 -44
  899. package/dist/plugin-sdk/media-understanding/runner.d.ts +0 -34
  900. package/dist/plugin-sdk/media-understanding/runner.entries.d.ts +0 -33
  901. package/dist/plugin-sdk/media-understanding/scope.d.ts +0 -9
  902. package/dist/plugin-sdk/media-understanding/types.d.ts +0 -74
  903. package/dist/plugin-sdk/media-understanding/video.d.ts +0 -2
  904. package/dist/plugin-sdk/sessions/model-overrides.d.ts +0 -14
  905. package/dist/plugin-sdk/telegram/reasoning-lane-coordinator.d.ts +0 -18
  906. package/dist/plugin-sdk/utils/mask-api-key.d.ts +0 -1
  907. package/dist/plugin-sdk/utils/run-with-concurrency.d.ts +0 -11
  908. package/dist/plugins-CsYMlnVa.js +0 -455
  909. package/dist/plugins-Dhit-VHt.js +0 -453
  910. package/dist/plugins-cli-BwuvKtN-.js +0 -798
  911. package/dist/plugins-cli-D34k2VsI.js +0 -793
  912. package/dist/ports-DrruB2fK.js +0 -370
  913. package/dist/ports-GT1yV-Tg.js +0 -96
  914. package/dist/ports-NPqtlfp0.js +0 -316
  915. package/dist/ports-QMI4-F9m.js +0 -96
  916. package/dist/program-C5ukTU6N.js +0 -244
  917. package/dist/program-context-D55P0vBV.js +0 -474
  918. package/dist/progress-CBkSaM6z.js +0 -124
  919. package/dist/prompt-Bllj1dhc.js +0 -21
  920. package/dist/prompt-select-styled-WStiI-bz.js +0 -1647
  921. package/dist/prompt-select-styled-ram-aXWu.js +0 -1650
  922. package/dist/prompt-style-DVEm3BZW.js +0 -9
  923. package/dist/provider-dispatcher-epFKwpGK.js +0 -659
  924. package/dist/provider-dispatcher-vEBMmwZ0.js +0 -660
  925. package/dist/push-apns-C0LyG-WB.js +0 -713
  926. package/dist/push-apns-DuG95AKC.js +0 -711
  927. package/dist/pw-ai-TygsEDgY.js +0 -1906
  928. package/dist/pw-ai-eS0sIkZo.js +0 -1910
  929. package/dist/qr-cli-B8sYhugo.js +0 -352
  930. package/dist/qr-cli-yP8i4Iv1.js +0 -347
  931. package/dist/redact-eZq1uwNK.js +0 -191
  932. package/dist/redact-snapshot-gOLgfKp3.js +0 -2028
  933. package/dist/redact-snapshot-uT-CXbM8.js +0 -2028
  934. package/dist/register.agent-CSoigVGq.js +0 -1043
  935. package/dist/register.agent-GZLrbUPm.js +0 -286
  936. package/dist/register.configure-CXpiRohq.js +0 -124
  937. package/dist/register.configure-RaqiHe5L.js +0 -130
  938. package/dist/register.import-Bs-UkOs-.js +0 -27
  939. package/dist/register.import-DLng8g-e.js +0 -30
  940. package/dist/register.maintenance-B-ZLQ56Y.js +0 -494
  941. package/dist/register.maintenance-Bjr_SmG9.js +0 -497
  942. package/dist/register.message-BCQ8Vg4O.js +0 -686
  943. package/dist/register.message-ChhiSr7g.js +0 -681
  944. package/dist/register.onboard-DJCqNufv.js +0 -257
  945. package/dist/register.onboard-jlxjsrv6.js +0 -262
  946. package/dist/register.setup-C-sdixz5.js +0 -114
  947. package/dist/register.setup-Dwpe4ArC.js +0 -109
  948. package/dist/register.status-health-sessions-BWFRHBCZ.js +0 -669
  949. package/dist/register.status-health-sessions-D7noMz9y.js +0 -423
  950. package/dist/register.subclis-DFI5u4a6.js +0 -267
  951. package/dist/replies-Bzcj-R8d.js +0 -136
  952. package/dist/replies-uvTI-4lg.js +0 -136
  953. package/dist/reply-B9qz9Wwk.js +0 -13897
  954. package/dist/reply-CmGAXQKc.js +0 -13900
  955. package/dist/reply-directives-Be97YiyM.js +0 -182
  956. package/dist/reply-directives-DsLughUT.js +0 -182
  957. package/dist/reply-payloads-DW0YgT82.js +0 -527
  958. package/dist/reply-prefix-BzoT8h8o.js +0 -38
  959. package/dist/reply-prefix-CSaiVnkC.js +0 -38
  960. package/dist/resolve-route-2P40JKXk.js +0 -249
  961. package/dist/resolve-route-_CwEKLq6.js +0 -249
  962. package/dist/response-prefix-template-BAlvtSjL.js +0 -136
  963. package/dist/response-prefix-template-D-tls8tI.js +0 -136
  964. package/dist/retry-B042l5UJ.js +0 -77
  965. package/dist/retry-BhuXOEVR.js +0 -77
  966. package/dist/run-main-B-O5ZtbU.js +0 -320
  967. package/dist/runner-DGkTSlOS.js +0 -2294
  968. package/dist/runner-hs4uxAUP.js +0 -2294
  969. package/dist/runtime-DJNp29jv.js +0 -94
  970. package/dist/runtime-guard-DZ_xuCc4.js +0 -60
  971. package/dist/secure-random-DTcQnwrI.js +0 -44
  972. package/dist/security-cli-1iY1lW6F.js +0 -484
  973. package/dist/security-cli-BuiPPQYU.js +0 -478
  974. package/dist/send-3lgWtHHf.js +0 -349
  975. package/dist/send-6l2S1bcr.js +0 -11
  976. package/dist/send-9NV7sSlD.js +0 -2245
  977. package/dist/send-B0TcjZUD.js +0 -1778
  978. package/dist/send-Bb6K_10X.js +0 -2245
  979. package/dist/send-BzN7X1Om.js +0 -374
  980. package/dist/send-CLrRM0El.js +0 -426
  981. package/dist/send-Caz-txXK.js +0 -492
  982. package/dist/send-DJEr4rP6.js +0 -547
  983. package/dist/send-DJiDHXsu.js +0 -349
  984. package/dist/send-DOjg7kJj.js +0 -1775
  985. package/dist/send-DVXOiKT4.js +0 -1174
  986. package/dist/send-Dc_K995l.js +0 -547
  987. package/dist/send-Dh6d3CLl.js +0 -332
  988. package/dist/send-iPAfbiYM.js +0 -492
  989. package/dist/send-pwe9Gu8e.js +0 -29
  990. package/dist/server-B0IC-Osg.js +0 -205
  991. package/dist/server-MccRxMpb.js +0 -200
  992. package/dist/server-lifecycle-C_0CfoP7.js +0 -2437
  993. package/dist/server-lifecycle-IKdGw1kM.js +0 -2437
  994. package/dist/server-node-events-Czr2gXp_.js +0 -393
  995. package/dist/server-node-events-DFG6cXud.js +0 -398
  996. package/dist/service-Bjqii5nW.js +0 -670
  997. package/dist/service-fp29z5Ww.js +0 -670
  998. package/dist/session-DBL5nHDy.js +0 -170
  999. package/dist/session-cost-usage-DX09eTPU.js +0 -627
  1000. package/dist/session-cost-usage-yYi525j3.js +0 -627
  1001. package/dist/session-dirs-Cj5xi7zX.js +0 -947
  1002. package/dist/session-dirs-DdF6TDsE.js +0 -947
  1003. package/dist/session-utils-C7BtKlun.js +0 -625
  1004. package/dist/session-utils-CLe1dano.js +0 -625
  1005. package/dist/session-xKIW6gL2.js +0 -170
  1006. package/dist/sessions-C65iUuN9.js +0 -2593
  1007. package/dist/sessions-DjZ9IshB.js +0 -252
  1008. package/dist/ssrf-Ck9HDZpv.js +0 -183
  1009. package/dist/ssrf-m7kFIobZ.js +0 -183
  1010. package/dist/status-C6ghjxvX.js +0 -2072
  1011. package/dist/status-D-qTB8aZ.js +0 -2068
  1012. package/dist/status.update-C55QM2xs.js +0 -79
  1013. package/dist/status.update-CBmPXwYN.js +0 -79
  1014. package/dist/store-Bjk6rTC_.js +0 -53
  1015. package/dist/store-C3tOpizT.js +0 -64
  1016. package/dist/store-uRA67h-o.js +0 -2595
  1017. package/dist/store-v3P-OWhi.js +0 -64
  1018. package/dist/subagent-registry-BTG1aAZ8.js +0 -4860
  1019. package/dist/subagent-registry-CoclNL5c.js +0 -4858
  1020. package/dist/subsystem-COd61u0P.js +0 -1139
  1021. package/dist/subsystem-D9ZpRKFP.js +0 -1079
  1022. package/dist/system-cli-C__5QOMX.js +0 -70
  1023. package/dist/system-cli-Dr4XoVTq.js +0 -75
  1024. package/dist/systemd-DSnlM3jX.js +0 -547
  1025. package/dist/systemd-TfK8GuTx.js +0 -547
  1026. package/dist/systemd-linger-Axnc1xCb.js +0 -75
  1027. package/dist/systemd-linger-_0_-RY4v.js +0 -75
  1028. package/dist/table-DPTzZyhu.js +0 -279
  1029. package/dist/tables-BQ-CvUfT.js +0 -55
  1030. package/dist/tables-D3a9iSU1.js +0 -55
  1031. package/dist/tables-D3zdgEuK.js +0 -55
  1032. package/dist/tailnet-CEudzG0i.js +0 -40
  1033. package/dist/tailnet-PnMrjwGT.js +0 -40
  1034. package/dist/tailscale-DTATQxAG.js +0 -230
  1035. package/dist/tailscale-Dbyahx0J.js +0 -230
  1036. package/dist/targets-B_0Y1i-1.js +0 -2173
  1037. package/dist/targets-CMhBAn87.js +0 -120
  1038. package/dist/targets-CTmhieRB.js +0 -650
  1039. package/dist/targets-CcTME3bp.js +0 -46
  1040. package/dist/targets-DfaVEd_u.js +0 -220
  1041. package/dist/targets-DtiQgjEL.js +0 -2172
  1042. package/dist/targets-DyybKefq.js +0 -53
  1043. package/dist/targets-rDolm5YS.js +0 -650
  1044. package/dist/tokens-DzFOtLlW.js +0 -21
  1045. package/dist/tool-display-Br6mwaJc.js +0 -785
  1046. package/dist/tool-display-sgNwLOBj.js +0 -785
  1047. package/dist/tool-images-BNfIJ_Kj.js +0 -263
  1048. package/dist/tool-images-kloBqxqK.js +0 -263
  1049. package/dist/trash-DPi0aCCQ.js +0 -125
  1050. package/dist/trash-D_Jd_yQZ.js +0 -125
  1051. package/dist/tui-BSDCI2hh.js +0 -3392
  1052. package/dist/tui-DT7hLOBk.js +0 -3392
  1053. package/dist/tui-cli-DUWvLaoG.js +0 -58
  1054. package/dist/tui-cli-Dn2iXQTO.js +0 -63
  1055. package/dist/update-Bgl3Pk2N.js +0 -349
  1056. package/dist/update-CFPFib4P.js +0 -349
  1057. package/dist/update-cli-DSDSQ2Xi.js +0 -1373
  1058. package/dist/update-cli-DYR_7NLy.js +0 -1370
  1059. package/dist/usage-CS1zeIan.js +0 -5279
  1060. package/dist/utils-LBKvDoPx.js +0 -631
  1061. package/dist/web-BECD5Akw.js +0 -70
  1062. package/dist/web-D4oENnAL.js +0 -3065
  1063. package/dist/web-KP-TI2sO.js +0 -76
  1064. package/dist/webhooks-cli-BqoG_i-D.js +0 -328
  1065. package/dist/webhooks-cli-Ddu7dfdE.js +0 -333
  1066. package/dist/whatsapp-actions-BZLIjQ8J.js +0 -122
  1067. package/dist/whatsapp-actions-KCc1vHN5.js +0 -128
  1068. package/dist/widearea-dns-DSoaA-eH.js +0 -127
  1069. package/dist/workspace-4EaHHEWi.js +0 -447
  1070. package/dist/workspace-B_1t_yq3.js +0 -449
  1071. /package/dist/{account-lookup-0KDSp5Mj.js → account-lookup-C0ndrpt-.js} +0 -0
  1072. /package/dist/{account-lookup-zvANGr2x.js → account-lookup-CIY_RKhi.js} +0 -0
  1073. /package/dist/{api-BeQMq2iS.js → api-BE4ZCWWB.js} +0 -0
  1074. /package/dist/{api-CxX8-gGz.js → api-wsk9zRVi.js} +0 -0
  1075. /package/dist/{argv-Co-b9Zsc.js → argv-BY8EVMTP.js} +0 -0
  1076. /package/dist/{brew-DbSbN8sD.js → brew-CmTYeZk1.js} +0 -0
  1077. /package/dist/{brew-C4zKZsHX.js → brew-V4lMBeE3.js} +0 -0
  1078. /package/dist/{chat-type-CYPyHAj-.js → chat-type-BP9akbag.js} +0 -0
  1079. /package/dist/{chat-type-DKb2TlGZ.js → chat-type-CH3W-zKy.js} +0 -0
  1080. /package/dist/{cleanup-utils-CwQvD73q.js → cleanup-utils-ZC2zvntc.js} +0 -0
  1081. /package/dist/{cli-name-BicfmwQX.js → cli-name-BZsYSp9l.js} +0 -0
  1082. /package/dist/{cli-name-C6rJGl18.js → cli-name-CRe5Ow_t.js} +0 -0
  1083. /package/dist/{cli-utils-BhXbz2UF.js → cli-utils-BUOtyfnU.js} +0 -0
  1084. /package/dist/{cli-utils-DZe_rVkZ.js → cli-utils-CGB3cBZm.js} +0 -0
  1085. /package/dist/{client-C61M8zI3.js → client-9dK56xly.js} +0 -0
  1086. /package/dist/{client-DdpmATKq.js → client-D-R1YdRD.js} +0 -0
  1087. /package/dist/{command-options-C4paWSGf.js → command-options-CnHA4TzR.js} +0 -0
  1088. /package/dist/{command-options-CA30lfLK.js → command-options-D2nN4AXX.js} +0 -0
  1089. /package/dist/{config-eval-CjGZtLwx.js → config-eval-BQIR-wSg.js} +0 -0
  1090. /package/dist/{config-eval-H_wlEYIG.js → config-eval-Bh82JoXK.js} +0 -0
  1091. /package/dist/{constants-ChptG3d7.js → constants-C7j1VA2S.js} +0 -0
  1092. /package/dist/{constants-DY6b-_Wl.js → constants-DoYLsBmv.js} +0 -0
  1093. /package/dist/{credentials-BHWUBHMd.js → credentials-C_RoJFmK.js} +0 -0
  1094. /package/dist/{credentials-DFsi1_e8.js → credentials-DM_Dj0m8.js} +0 -0
  1095. /package/dist/{daemon-runtime-CMnbwryP.js → daemon-runtime-9oDBR7YW.js} +0 -0
  1096. /package/dist/{daemon-runtime-CvqE4ysg.js → daemon-runtime-CzFI2dPw.js} +0 -0
  1097. /package/dist/{dangerous-name-matching-BzmiLXmA.js → dangerous-name-matching-BlTBBZns.js} +0 -0
  1098. /package/dist/{dangerous-name-matching-DaVRgwer.js → dangerous-name-matching-CSq9sJDG.js} +0 -0
  1099. /package/dist/{dangerous-tools-BOLoCRv4.js → dangerous-tools-BRmbBvRf.js} +0 -0
  1100. /package/dist/{dangerous-tools-Baq7Q-i6.js → dangerous-tools-D4jtl72G.js} +0 -0
  1101. /package/dist/{fetch-timeout-DTIN7CGM.js → fetch-timeout-CytN1wiO.js} +0 -0
  1102. /package/dist/{fetch-timeout-DoySHqfO.js → fetch-timeout-DBRRPNBi.js} +0 -0
  1103. /package/dist/{file-identity-BxlKD8Ys.js → file-identity-CeRK5CJC.js} +0 -0
  1104. /package/dist/{format-duration-CqUERz51.js → format-duration-B-Uv5nOi.js} +0 -0
  1105. /package/dist/{format-duration-Ct-yiwkS.js → format-duration-D1M3Zxu6.js} +0 -0
  1106. /package/dist/{format-relative-79_Y1n2Y.js → format-relative-Czf5fUjn.js} +0 -0
  1107. /package/dist/{format-relative-CxLpEQOX.js → format-relative-zwkkXJvs.js} +0 -0
  1108. /package/dist/{health-format-B_QRD8Si.js → health-format-DF54wvUU.js} +0 -0
  1109. /package/dist/{heartbeat-wake-LGEgcXjs.js → heartbeat-wake-CvHncCjP.js} +0 -0
  1110. /package/dist/{heartbeat-wake-Y97geucO.js → heartbeat-wake-DLxQm6-U.js} +0 -0
  1111. /package/dist/{help-format-NNm_Ov4H.js → help-format-CJQ7APRn.js} +0 -0
  1112. /package/dist/{helpers-BAsMXprO.js → helpers-BER76F_2.js} +0 -0
  1113. /package/dist/{helpers-DLgbkcEn.js → helpers-n2CtWpm9.js} +0 -0
  1114. /package/dist/{input-provenance-Bn6thJNm.js → input-provenance-gIfDn1ki.js} +0 -0
  1115. /package/dist/{input-provenance-xUsSMOsz.js → input-provenance-wkso1o5V.js} +0 -0
  1116. /package/dist/{ip-C9q3Oq20.js → ip-D4VG5EJO.js} +0 -0
  1117. /package/dist/{ip-D0zgNmBV.js → ip-MwCwRA7c.js} +0 -0
  1118. /package/dist/{is-main-DN8-sNR5.js → is-main-BmHYGRhd.js} +0 -0
  1119. /package/dist/{json-file-B7l5-Xhr.js → json-file-BW22hGtf.js} +0 -0
  1120. /package/dist/{json-file-ChO_R9yh.js → json-file-DwRAfAAy.js} +0 -0
  1121. /package/dist/{json-files-CmpYSF4G.js → json-files-Dy52honG.js} +0 -0
  1122. /package/dist/{lanes-ByWMUgrz.js → lanes-1CBKdsiR.js} +0 -0
  1123. /package/dist/{lanes-cHJ5arWg.js → lanes-DqVYfPRG.js} +0 -0
  1124. /package/dist/{links-Bz4V7R_p.js → links-CwTlzaPe.js} +0 -0
  1125. /package/dist/{location-DBWCGNLq.js → location-50gaJF5Z.js} +0 -0
  1126. /package/dist/{location-GbZ0bBRU.js → location-Qo8Ii1zo.js} +0 -0
  1127. /package/dist/{logger-DyL5G2DO.js → logger-B8BE0PyS.js} +0 -0
  1128. /package/dist/{logger-BWMPnILd.js → logger-CPvz-aPM.js} +0 -0
  1129. /package/dist/{logger-GvipVDfh.js → logger-cL0D2DCr.js} +0 -0
  1130. /package/dist/{logging-D8-Kozjc.js → logging-DTEoeoa3.js} +0 -0
  1131. /package/dist/{mutable-allowlist-detectors-DiZDtmlZ.js → mutable-allowlist-detectors-BXE7Hr7F.js} +0 -0
  1132. /package/dist/{mutable-allowlist-detectors-U5ThQr9V.js → mutable-allowlist-detectors-CtKavajp.js} +0 -0
  1133. /package/dist/{parse-log-line-enq8pduH.js → parse-log-line-GisaZn5H.js} +0 -0
  1134. /package/dist/{parse-log-line-mz9TG6ig.js → parse-log-line-ZsbwG_u7.js} +0 -0
  1135. /package/dist/{parse-timeout-BMP8a0_a.js → parse-timeout-BpphuwYl.js} +0 -0
  1136. /package/dist/{parse-timeout-CDkco8kd.js → parse-timeout-CE6BjmGU.js} +0 -0
  1137. /package/dist/plugin-sdk/{agents → auth}/api-key-rotation.d.ts +0 -0
  1138. /package/dist/plugin-sdk/{media-understanding → stt}/providers/deepgram/audio.d.ts +0 -0
  1139. /package/dist/plugin-sdk/{media-understanding → stt}/providers/google/audio.d.ts +0 -0
  1140. /package/dist/plugin-sdk/{media-understanding → stt}/providers/google/inline-data.d.ts +0 -0
  1141. /package/dist/plugin-sdk/{media-understanding → stt}/providers/openai/audio.d.ts +0 -0
  1142. /package/dist/plugin-sdk/{media-understanding → stt}/providers/shared.d.ts +0 -0
  1143. /package/dist/{plugins-allowlist-BbTQ5Z2k.js → plugins-allowlist-A38nxBRG.js} +0 -0
  1144. /package/dist/{plugins-allowlist-C20oaESO.js → plugins-allowlist-D2tS9tcu.js} +0 -0
  1145. /package/dist/{polls-B0CCBDeR.js → polls-BLyT08ZI.js} +0 -0
  1146. /package/dist/{polls-CwwHzYBM.js → polls-BmymsJEe.js} +0 -0
  1147. /package/dist/{ports-lsof-Wteul3ju.js → ports-lsof-CDyv5GJd.js} +0 -0
  1148. /package/dist/{process-scoped-map-CV9kDvfG.js → process-scoped-map-BCJR56ZB.js} +0 -0
  1149. /package/dist/{process-scoped-map-PEvnG75N.js → process-scoped-map-Cb1EHPyN.js} +0 -0
  1150. /package/dist/{program-context-jqeI5alP.js → program-context-DlXnmuB7.js} +0 -0
  1151. /package/dist/{progress-C1kUfYL-.js → progress-DRLmcFiG.js} +0 -0
  1152. /package/dist/{prompt-Yn2yClg1.js → prompt-BRGfic91.js} +0 -0
  1153. /package/dist/{prompt-style-DjEYC_s-.js → prompt-style-CUuA6OCy.js} +0 -0
  1154. /package/dist/{provider-utils-3JTMJroG.js → provider-utils-C9kBVF1f.js} +0 -0
  1155. /package/dist/{provider-utils-FaBmofiq.js → provider-utils-DiLhkKQp.js} +0 -0
  1156. /package/dist/{proxy-DL3MD6-P.js → proxy-BMJL0Qog.js} +0 -0
  1157. /package/dist/{proxy-DpNv2cSV.js → proxy-D-qGA1vm.js} +0 -0
  1158. /package/dist/{pw-ai-state-CGfLv6nV.js → pw-ai-state--TxTVwRW.js} +0 -0
  1159. /package/dist/{pw-ai-state-Dynx20hr.js → pw-ai-state-CwXeO5d0.js} +0 -0
  1160. /package/dist/{redact-Dx1Fue21.js → redact-BW8tobyp.js} +0 -0
  1161. /package/dist/{redact-identifier-BTIWtaa-.js → redact-identifier-BJOQDEj0.js} +0 -0
  1162. /package/dist/{redact-identifier-CAagcfWA.js → redact-identifier-Bv5SUUw-.js} +0 -0
  1163. /package/dist/{remoteclaw-root-C2HV2VeC.js → remoteclaw-root-BfPjgewe.js} +0 -0
  1164. /package/dist/{remoteclaw-root-DybYl8PL.js → remoteclaw-root-E4-hmb4E.js} +0 -0
  1165. /package/dist/{render-CCLsW6Lz.js → render-BhKzKdV0.js} +0 -0
  1166. /package/dist/{render-uf6PvGMV.js → render-e7fENCYH.js} +0 -0
  1167. /package/dist/{retry-DnqPAqWp.js → retry-BWv_fy4u.js} +0 -0
  1168. /package/dist/{runtime-guard-U-ewY_QH.js → runtime-guard-Bhx-pb8_.js} +0 -0
  1169. /package/dist/{secret-equal-BbHdTtqY.js → secret-equal-D6AoXne1.js} +0 -0
  1170. /package/dist/{secret-equal-CXJEZiWb.js → secret-equal-DLnUuWM3.js} +0 -0
  1171. /package/dist/{secure-random-CS2mSdTn.js → secure-random-CJtykx_p.js} +0 -0
  1172. /package/dist/{secure-random-_dzDDlFo.js → secure-random-CRVHgtmO.js} +0 -0
  1173. /package/dist/{session-key-5YLnn_qf.js → session-key-BF-9YzxC.js} +0 -0
  1174. /package/dist/{session-key-C2n-VILA.js → session-key-CgKWfjoZ.js} +0 -0
  1175. /package/dist/{stagger-BXv_apuy.js → stagger--wvODnNe.js} +0 -0
  1176. /package/dist/{stagger-MI9gd2rQ.js → stagger-BLmTO4cK.js} +0 -0
  1177. /package/dist/{status-BmtCS3T1.js → status-1zVD-Clq.js} +0 -0
  1178. /package/dist/{status-BrwHRn2B.js → status-BtRY0nXQ.js} +0 -0
  1179. /package/dist/{strip-inbound-meta-DjKcSFaW.js → strip-inbound-meta-zmUXypSS.js} +0 -0
  1180. /package/dist/{strip-inbound-meta-jy3bkUab.js → strip-inbound-meta-zqtN9FTK.js} +0 -0
  1181. /package/dist/{table-C1rdyYl9.js → table-On3hkCqi.js} +0 -0
  1182. /package/dist/{target-errors-BDpPcwh5.js → target-errors-DJVRKFcU.js} +0 -0
  1183. /package/dist/{target-errors-DdIAPcMM.js → target-errors-GZXDqlUu.js} +0 -0
  1184. /package/dist/{targets-C-2xwh9f.js → targets-B46m7u5J.js} +0 -0
  1185. /package/dist/{targets-D-qLBpTA.js → targets-B_d_1z3N.js} +0 -0
  1186. /package/dist/{targets-UncQvCVs.js → targets-D01MJGnh.js} +0 -0
  1187. /package/dist/{targets-BMenhVHg.js → targets-D3r6Zgic.js} +0 -0
  1188. /package/dist/{text-format-BQ3z_OXA.js → text-format-DarxU3JH.js} +0 -0
  1189. /package/dist/{text-format-oWqzVmah.js → text-format-Ds92M9UT.js} +0 -0
  1190. /package/dist/{tokens-B-jmvNR9.js → tokens-Dw7ZdYwT.js} +0 -0
  1191. /package/dist/{usage-BdhBT0Vz.js → usage-BIzKZ5dT.js} +0 -0
  1192. /package/dist/{usage-BtQcAnf6.js → usage-BvZOzIC7.js} +0 -0
  1193. /package/dist/{usage-format-C3mNLfhI.js → usage-format-CmniSPCG.js} +0 -0
  1194. /package/dist/{usage-format-DAaPzr_z.js → usage-format-D_KQYQ-w.js} +0 -0
  1195. /package/dist/{widearea-dns-CsmBVbez.js → widearea-dns-D01FFYZ8.js} +0 -0
  1196. /package/dist/{workspace-BzPeZDew.js → workspace-BJCKO8Ns.js} +0 -0
  1197. /package/dist/{workspace-DkGLVfOl.js → workspace-BisvA9oA.js} +0 -0
  1198. /package/dist/{wsl-B_sPlzWw.js → wsl-PDLKeX04.js} +0 -0
  1199. /package/dist/{wsl-BCnYV9O0.js → wsl-kFaeW76c.js} +0 -0
@@ -13,16 +13,13 @@ import { execFileSync, spawn } from "node:child_process";
13
13
  import { fileURLToPath } from "node:url";
14
14
  import AjvPkg from "ajv";
15
15
  import { z } from "zod";
16
+ import { lookup } from "node:dns";
17
+ import { lookup as lookup$1 } from "node:dns/promises";
18
+ import { Agent } from "undici";
19
+ import ipaddr from "ipaddr.js";
20
+ import { fileTypeFromBuffer } from "file-type";
16
21
  import { createInterface } from "node:readline";
17
22
 
18
- //#region src/config/model-input.ts
19
- function resolveAgentModelPrimaryValue(model) {
20
- if (typeof model === "string") return model.trim() || void 0;
21
- if (!model || typeof model !== "object") return;
22
- return model.primary?.trim() || void 0;
23
- }
24
-
25
- //#endregion
26
23
  //#region src/infra/home-dir.ts
27
24
  function normalize(value) {
28
25
  const trimmed = value?.trim();
@@ -542,8 +539,8 @@ function pruneOldRollingLogs(dir) {
542
539
 
543
540
  //#endregion
544
541
  //#region src/terminal/palette.ts
545
- const LOBSTER_PALETTE = {
546
- accent: "#FF5A2D",
542
+ const PALETTE = {
543
+ accent: "#FF5A36",
547
544
  accentBright: "#FF7A3D",
548
545
  accentDim: "#D14A22",
549
546
  info: "#FF8A5B",
@@ -559,17 +556,17 @@ const hasForceColor = typeof process.env.FORCE_COLOR === "string" && process.env
559
556
  const baseChalk = process.env.NO_COLOR && !hasForceColor ? new Chalk({ level: 0 }) : chalk;
560
557
  const hex = (value) => baseChalk.hex(value);
561
558
  const theme = {
562
- accent: hex(LOBSTER_PALETTE.accent),
563
- accentBright: hex(LOBSTER_PALETTE.accentBright),
564
- accentDim: hex(LOBSTER_PALETTE.accentDim),
565
- info: hex(LOBSTER_PALETTE.info),
566
- success: hex(LOBSTER_PALETTE.success),
567
- warn: hex(LOBSTER_PALETTE.warn),
568
- error: hex(LOBSTER_PALETTE.error),
569
- muted: hex(LOBSTER_PALETTE.muted),
570
- heading: baseChalk.bold.hex(LOBSTER_PALETTE.accent),
571
- command: hex(LOBSTER_PALETTE.accentBright),
572
- option: hex(LOBSTER_PALETTE.warn)
559
+ accent: hex(PALETTE.accent),
560
+ accentBright: hex(PALETTE.accentBright),
561
+ accentDim: hex(PALETTE.accentDim),
562
+ info: hex(PALETTE.info),
563
+ success: hex(PALETTE.success),
564
+ warn: hex(PALETTE.warn),
565
+ error: hex(PALETTE.error),
566
+ muted: hex(PALETTE.muted),
567
+ heading: baseChalk.bold.hex(PALETTE.accent),
568
+ command: hex(PALETTE.accentBright),
569
+ option: hex(PALETTE.warn)
573
570
  };
574
571
 
575
572
  //#endregion
@@ -578,6 +575,10 @@ let globalVerbose = false;
578
575
  function isVerbose() {
579
576
  return globalVerbose;
580
577
  }
578
+ function logVerboseConsole(message) {
579
+ if (!globalVerbose) return;
580
+ console.log(theme.muted(message));
581
+ }
581
582
  const success = theme.success;
582
583
  const warn = theme.warn;
583
584
  const info = theme.info;
@@ -636,6 +637,8 @@ function createEmptyPluginRegistry() {
636
637
  typedHooks: [],
637
638
  channels: [],
638
639
  providers: [],
640
+ sttProviders: [],
641
+ ttsProviders: [],
639
642
  gatewayHandlers: {},
640
643
  httpHandlers: [],
641
644
  httpRoutes: [],
@@ -1087,7 +1090,8 @@ function resolveAgentConfig(cfg, agentId) {
1087
1090
  groupChat: entry.groupChat,
1088
1091
  subagents: typeof entry.subagents === "object" && entry.subagents ? entry.subagents : void 0,
1089
1092
  sandbox: entry.sandbox,
1090
- tools: entry.tools
1093
+ tools: entry.tools,
1094
+ auth: entry.auth
1091
1095
  };
1092
1096
  }
1093
1097
  function resolveAgentWorkspaceDir(cfg, agentId) {
@@ -1096,6 +1100,11 @@ function resolveAgentWorkspaceDir(cfg, agentId) {
1096
1100
  if (configured) return stripNullBytes(resolveUserPath(configured));
1097
1101
  throw new Error(`agent '${id}' has no workspace configured — set agents.list[].workspace in remoteclaw.json`);
1098
1102
  }
1103
+ function resolveAgentWorkspaceDirOrNull(cfg, agentId) {
1104
+ const configured = resolveAgentConfig(cfg, normalizeAgentId(agentId))?.workspace?.trim();
1105
+ if (configured) return stripNullBytes(resolveUserPath(configured));
1106
+ return null;
1107
+ }
1099
1108
  function resolveAgentDir(cfg, agentId) {
1100
1109
  const id = normalizeAgentId(agentId);
1101
1110
  const configured = resolveAgentConfig(cfg, id)?.agentDir?.trim();
@@ -1104,11 +1113,6 @@ function resolveAgentDir(cfg, agentId) {
1104
1113
  return path.join(root, "agents", id, "agent");
1105
1114
  }
1106
1115
 
1107
- //#endregion
1108
- //#region src/agents/defaults.ts
1109
- const DEFAULT_PROVIDER = "anthropic";
1110
- const DEFAULT_MODEL = "claude-opus-4-6";
1111
-
1112
1116
  //#endregion
1113
1117
  //#region src/agents/identity.ts
1114
1118
  function resolveAgentIdentity(cfg, agentId) {
@@ -1716,13 +1720,12 @@ function findDuplicateAgentDirs(cfg, deps) {
1716
1720
  function formatDuplicateAgentDirError(dups) {
1717
1721
  return [
1718
1722
  "Duplicate agentDir detected (multi-agent config).",
1719
- "Each agent must have a unique agentDir; sharing it causes auth/session state collisions and token invalidation.",
1723
+ "Each agent must have a unique agentDir; sharing it causes session state collisions.",
1720
1724
  "",
1721
1725
  "Conflicts:",
1722
1726
  ...dups.map((d) => `- ${d.agentDir}: ${d.agentIds.map((id) => `"${id}"`).join(", ")}`),
1723
1727
  "",
1724
- "Fix: remove the shared agents.list[].agentDir override (or give each agent its own directory).",
1725
- "If you want to share credentials, copy auth-profiles.json instead of sharing the entire agentDir."
1728
+ "Fix: remove the shared agents.list[].agentDir override (or give each agent its own directory)."
1726
1729
  ].join("\n");
1727
1730
  }
1728
1731
 
@@ -2168,7 +2171,9 @@ function applyContextPruningDefaults(cfg) {
2168
2171
  };
2169
2172
  modelsMutated = true;
2170
2173
  }
2171
- const primary = resolvePrimaryModelRef(resolveAgentModelPrimaryValue(defaults.model) ?? void 0);
2174
+ const rawModel = defaults.model;
2175
+ const rawPrimary = typeof rawModel === "string" ? rawModel : rawModel?.primary;
2176
+ const primary = resolvePrimaryModelRef(typeof rawPrimary === "string" ? rawPrimary : void 0);
2172
2177
  if (primary) {
2173
2178
  const parsedPrimary = parseModelRef(primary, "anthropic");
2174
2179
  if (isAnthropicCacheRetentionTarget(parsedPrimary)) {
@@ -2201,25 +2206,6 @@ function applyContextPruningDefaults(cfg) {
2201
2206
  }
2202
2207
  };
2203
2208
  }
2204
- function applyCompactionDefaults(cfg) {
2205
- const defaults = cfg.agents?.defaults;
2206
- if (!defaults) return cfg;
2207
- const compaction = defaults?.compaction;
2208
- if (compaction?.mode) return cfg;
2209
- return {
2210
- ...cfg,
2211
- agents: {
2212
- ...cfg.agents,
2213
- defaults: {
2214
- ...defaults,
2215
- compaction: {
2216
- ...compaction,
2217
- mode: "safeguard"
2218
- }
2219
- }
2220
- }
2221
- };
2222
- }
2223
2209
 
2224
2210
  //#endregion
2225
2211
  //#region src/config/env-preserve.ts
@@ -2648,1142 +2634,189 @@ function resolveConfigIncludes(obj, configPath, resolver = defaultResolver) {
2648
2634
  }
2649
2635
 
2650
2636
  //#endregion
2651
- //#region src/config/discord-preview-streaming.ts
2652
- function normalizeStreamingMode(value) {
2653
- if (typeof value !== "string") return null;
2654
- return value.trim().toLowerCase() || null;
2655
- }
2656
- function parseStreamingMode(value) {
2657
- const normalized = normalizeStreamingMode(value);
2658
- if (normalized === "off" || normalized === "partial" || normalized === "block" || normalized === "progress") return normalized;
2659
- return null;
2660
- }
2661
- function parseDiscordPreviewStreamMode(value) {
2662
- const parsed = parseStreamingMode(value);
2663
- if (!parsed) return null;
2664
- return parsed === "progress" ? "partial" : parsed;
2637
+ //#region src/config/legacy.rules.ts
2638
+ const LEGACY_CONFIG_RULES = [];
2639
+
2640
+ //#endregion
2641
+ //#region src/config/legacy.ts
2642
+ function findLegacyConfigIssues(raw) {
2643
+ if (!raw || typeof raw !== "object") return [];
2644
+ const root = raw;
2645
+ const issues = [];
2646
+ for (const rule of LEGACY_CONFIG_RULES) {
2647
+ let cursor = root;
2648
+ for (const key of rule.path) {
2649
+ if (!cursor || typeof cursor !== "object") {
2650
+ cursor = void 0;
2651
+ break;
2652
+ }
2653
+ cursor = cursor[key];
2654
+ }
2655
+ if (cursor !== void 0 && (!rule.match || rule.match(cursor, root))) issues.push({
2656
+ path: rule.path.join("."),
2657
+ message: rule.message
2658
+ });
2659
+ }
2660
+ return issues;
2665
2661
  }
2666
- function parseSlackLegacyDraftStreamMode(value) {
2667
- const normalized = normalizeStreamingMode(value);
2668
- if (normalized === "replace" || normalized === "status_final" || normalized === "append") return normalized;
2669
- return null;
2662
+
2663
+ //#endregion
2664
+ //#region src/config/merge-patch.ts
2665
+ function isObjectWithStringId(value) {
2666
+ if (!isPlainObject$2(value)) return false;
2667
+ return typeof value.id === "string" && value.id.length > 0;
2670
2668
  }
2671
- function mapSlackLegacyDraftStreamModeToStreaming(mode) {
2672
- if (mode === "append") return "block";
2673
- if (mode === "status_final") return "progress";
2674
- return "partial";
2669
+ /**
2670
+ * Merge arrays of object-like entries keyed by `id`.
2671
+ *
2672
+ * Contract:
2673
+ * - Base array must be fully id-keyed; otherwise return undefined (caller should replace).
2674
+ * - Patch entries with valid id merge by id (or append when the id is new).
2675
+ * - Patch entries without valid id append as-is, avoiding destructive full-array replacement.
2676
+ */
2677
+ function mergeObjectArraysById(base, patch, options) {
2678
+ if (!base.every(isObjectWithStringId)) return;
2679
+ const merged = [...base];
2680
+ const indexById = /* @__PURE__ */ new Map();
2681
+ for (const [index, entry] of merged.entries()) {
2682
+ if (!isObjectWithStringId(entry)) return;
2683
+ indexById.set(entry.id, index);
2684
+ }
2685
+ for (const patchEntry of patch) {
2686
+ if (!isObjectWithStringId(patchEntry)) {
2687
+ merged.push(structuredClone(patchEntry));
2688
+ continue;
2689
+ }
2690
+ const existingIndex = indexById.get(patchEntry.id);
2691
+ if (existingIndex === void 0) {
2692
+ merged.push(structuredClone(patchEntry));
2693
+ indexById.set(patchEntry.id, merged.length - 1);
2694
+ continue;
2695
+ }
2696
+ merged[existingIndex] = applyMergePatch(merged[existingIndex], patchEntry, options);
2697
+ }
2698
+ return merged;
2675
2699
  }
2676
- function resolveTelegramPreviewStreamMode(params = {}) {
2677
- const parsedStreaming = parseStreamingMode(params.streaming);
2678
- if (parsedStreaming) {
2679
- if (parsedStreaming === "progress") return "partial";
2680
- return parsedStreaming;
2700
+ function applyMergePatch(base, patch, options = {}) {
2701
+ if (!isPlainObject$2(patch)) return patch;
2702
+ const result = isPlainObject$2(base) ? { ...base } : {};
2703
+ for (const [key, value] of Object.entries(patch)) {
2704
+ if (isBlockedObjectKey(key)) continue;
2705
+ if (value === null) {
2706
+ delete result[key];
2707
+ continue;
2708
+ }
2709
+ if (options.mergeObjectArraysById && Array.isArray(result[key]) && Array.isArray(value)) {
2710
+ const mergedArray = mergeObjectArraysById(result[key], value, options);
2711
+ if (mergedArray) {
2712
+ result[key] = mergedArray;
2713
+ continue;
2714
+ }
2715
+ }
2716
+ if (isPlainObject$2(value)) {
2717
+ const baseValue = result[key];
2718
+ result[key] = applyMergePatch(isPlainObject$2(baseValue) ? baseValue : {}, value, options);
2719
+ continue;
2720
+ }
2721
+ result[key] = value;
2681
2722
  }
2682
- const legacy = parseDiscordPreviewStreamMode(params.streamMode);
2683
- if (legacy) return legacy;
2684
- if (typeof params.streaming === "boolean") return params.streaming ? "partial" : "off";
2685
- return "off";
2723
+ return result;
2686
2724
  }
2687
- function resolveDiscordPreviewStreamMode(params = {}) {
2688
- const parsedStreaming = parseDiscordPreviewStreamMode(params.streaming);
2689
- if (parsedStreaming) return parsedStreaming;
2690
- const legacy = parseDiscordPreviewStreamMode(params.streamMode);
2691
- if (legacy) return legacy;
2692
- if (typeof params.streaming === "boolean") return params.streaming ? "partial" : "off";
2693
- return "off";
2725
+
2726
+ //#endregion
2727
+ //#region src/config/normalize-paths.ts
2728
+ const PATH_VALUE_RE = /^~(?=$|[\\/])/;
2729
+ const PATH_KEY_RE = /(dir|path|paths|file|root|workspace)$/i;
2730
+ const PATH_LIST_KEYS = new Set(["paths", "pathPrepend"]);
2731
+ function normalizeStringValue(key, value) {
2732
+ if (!PATH_VALUE_RE.test(value.trim())) return value;
2733
+ if (!key) return value;
2734
+ if (PATH_KEY_RE.test(key) || PATH_LIST_KEYS.has(key)) return resolveUserPath(value);
2735
+ return value;
2694
2736
  }
2695
- function resolveSlackStreamingMode(params = {}) {
2696
- const parsedStreaming = parseStreamingMode(params.streaming);
2697
- if (parsedStreaming) return parsedStreaming;
2698
- const legacyStreamMode = parseSlackLegacyDraftStreamMode(params.streamMode);
2699
- if (legacyStreamMode) return mapSlackLegacyDraftStreamModeToStreaming(legacyStreamMode);
2700
- if (typeof params.streaming === "boolean") return "partial";
2701
- return "partial";
2737
+ function normalizeAny(key, value) {
2738
+ if (typeof value === "string") return normalizeStringValue(key, value);
2739
+ if (Array.isArray(value)) {
2740
+ const normalizeChildren = Boolean(key && PATH_LIST_KEYS.has(key));
2741
+ return value.map((entry) => {
2742
+ if (typeof entry === "string") return normalizeChildren ? normalizeStringValue(key, entry) : entry;
2743
+ if (Array.isArray(entry)) return normalizeAny(void 0, entry);
2744
+ if (isPlainObject$2(entry)) return normalizeAny(void 0, entry);
2745
+ return entry;
2746
+ });
2747
+ }
2748
+ if (!isPlainObject$2(value)) return value;
2749
+ for (const [childKey, childValue] of Object.entries(value)) {
2750
+ const next = normalizeAny(childKey, childValue);
2751
+ if (next !== childValue) value[childKey] = next;
2752
+ }
2753
+ return value;
2702
2754
  }
2703
- function resolveSlackNativeStreaming(params = {}) {
2704
- if (typeof params.nativeStreaming === "boolean") return params.nativeStreaming;
2705
- if (typeof params.streaming === "boolean") return params.streaming;
2706
- return true;
2755
+ /**
2756
+ * Normalize "~" paths in path-ish config fields.
2757
+ *
2758
+ * Goal: accept `~/...` consistently across config file + env overrides, while
2759
+ * keeping the surface area small and predictable.
2760
+ */
2761
+ function normalizeConfigPaths(cfg) {
2762
+ if (!cfg || typeof cfg !== "object") return cfg;
2763
+ normalizeAny(void 0, cfg);
2764
+ return cfg;
2707
2765
  }
2708
2766
 
2709
2767
  //#endregion
2710
- //#region src/infra/safe-executable-value.ts
2711
- const SHELL_METACHARS = /[;&|`$<>]/;
2712
- const CONTROL_CHARS = /[\r\n]/;
2713
- const QUOTE_CHARS = /["']/;
2714
- const BARE_NAME_PATTERN = /^[A-Za-z0-9._+-]+$/;
2715
- function isLikelyPath(value) {
2716
- if (value.startsWith(".") || value.startsWith("~")) return true;
2717
- if (value.includes("/") || value.includes("\\")) return true;
2718
- return /^[A-Za-z]:[\\/]/.test(value);
2768
+ //#region src/config/runtime-overrides.ts
2769
+ let overrides = {};
2770
+ function mergeOverrides(base, override) {
2771
+ if (!isPlainObject$2(base) || !isPlainObject$2(override)) return override;
2772
+ const next = { ...base };
2773
+ for (const [key, value] of Object.entries(override)) {
2774
+ if (value === void 0 || isBlockedObjectKey(key)) continue;
2775
+ next[key] = mergeOverrides(base[key], value);
2776
+ }
2777
+ return next;
2719
2778
  }
2720
- function isSafeExecutableValue(value) {
2721
- if (!value) return false;
2722
- const trimmed = value.trim();
2723
- if (!trimmed) return false;
2724
- if (trimmed.includes("\0")) return false;
2725
- if (CONTROL_CHARS.test(trimmed)) return false;
2726
- if (SHELL_METACHARS.test(trimmed)) return false;
2727
- if (QUOTE_CHARS.test(trimmed)) return false;
2728
- if (isLikelyPath(trimmed)) return true;
2729
- if (trimmed.startsWith("-")) return false;
2730
- return BARE_NAME_PATTERN.test(trimmed);
2779
+ function applyConfigOverrides(cfg) {
2780
+ if (!overrides || Object.keys(overrides).length === 0) return cfg;
2781
+ return mergeOverrides(cfg, overrides);
2731
2782
  }
2732
2783
 
2733
2784
  //#endregion
2734
- //#region src/config/legacy.shared.ts
2735
- const getRecord = (value) => isRecord(value) ? value : null;
2736
- const ensureRecord = (root, key) => {
2737
- const existing = root[key];
2738
- if (isRecord(existing)) return existing;
2739
- const next = {};
2740
- root[key] = next;
2741
- return next;
2785
+ //#region src/plugins/config-state.ts
2786
+ const BUNDLED_ENABLED_BY_DEFAULT = new Set([
2787
+ "device-pair",
2788
+ "phone-control",
2789
+ "talk-voice"
2790
+ ]);
2791
+ const normalizeList = (value) => {
2792
+ if (!Array.isArray(value)) return [];
2793
+ return value.map((entry) => typeof entry === "string" ? entry.trim() : "").filter(Boolean);
2742
2794
  };
2743
- const mergeMissing = (target, source) => {
2744
- for (const [key, value] of Object.entries(source)) {
2745
- if (value === void 0 || isBlockedObjectKey(key)) continue;
2746
- const existing = target[key];
2747
- if (existing === void 0) {
2748
- target[key] = value;
2795
+ const normalizePluginEntries = (entries) => {
2796
+ if (!entries || typeof entries !== "object" || Array.isArray(entries)) return {};
2797
+ const normalized = {};
2798
+ for (const [key, value] of Object.entries(entries)) {
2799
+ if (!key.trim()) continue;
2800
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
2801
+ normalized[key] = {};
2749
2802
  continue;
2750
2803
  }
2751
- if (isRecord(existing) && isRecord(value)) mergeMissing(existing, value);
2804
+ const entry = value;
2805
+ normalized[key] = {
2806
+ enabled: typeof entry.enabled === "boolean" ? entry.enabled : void 0,
2807
+ config: "config" in entry ? entry.config : void 0
2808
+ };
2752
2809
  }
2810
+ return normalized;
2753
2811
  };
2754
- const mapLegacyAudioTranscription = (value) => {
2755
- const transcriber = getRecord(value);
2756
- const command = Array.isArray(transcriber?.command) ? transcriber?.command : null;
2757
- if (!command || command.length === 0) return null;
2758
- if (typeof command[0] !== "string") return null;
2759
- if (!command.every((part) => typeof part === "string")) return null;
2760
- const rawExecutable = command[0].trim();
2761
- if (!rawExecutable) return null;
2762
- if (!isSafeExecutableValue(rawExecutable)) return null;
2763
- const args = command.slice(1);
2764
- const timeoutSeconds = typeof transcriber?.timeoutSeconds === "number" ? transcriber?.timeoutSeconds : void 0;
2765
- const result = {
2766
- command: rawExecutable,
2767
- type: "cli"
2768
- };
2769
- if (args.length > 0) result.args = args;
2770
- if (timeoutSeconds !== void 0) result.timeoutSeconds = timeoutSeconds;
2771
- return result;
2772
- };
2773
- const getAgentsList = (agents) => {
2774
- const list = agents?.list;
2775
- return Array.isArray(list) ? list : [];
2776
- };
2777
- const resolveDefaultAgentIdFromRaw = (raw) => {
2778
- const list = getAgentsList(getRecord(raw.agents));
2779
- const defaultEntry = list.find((entry) => isRecord(entry) && entry.default === true && typeof entry.id === "string" && entry.id.trim() !== "");
2780
- if (defaultEntry) return defaultEntry.id.trim();
2781
- const routing = getRecord(raw.routing);
2782
- const routingDefault = typeof routing?.defaultAgentId === "string" ? routing.defaultAgentId.trim() : "";
2783
- if (routingDefault) return routingDefault;
2784
- const firstEntry = list.find((entry) => isRecord(entry) && typeof entry.id === "string" && entry.id.trim() !== "");
2785
- if (firstEntry) return firstEntry.id.trim();
2786
- return "main";
2787
- };
2788
- const ensureAgentEntry = (list, id) => {
2789
- const normalized = id.trim();
2790
- const existing = list.find((entry) => isRecord(entry) && typeof entry.id === "string" && entry.id.trim() === normalized);
2791
- if (existing) return existing;
2792
- const created = { id: normalized };
2793
- list.push(created);
2794
- return created;
2795
- };
2796
-
2797
- //#endregion
2798
- //#region src/config/legacy.migrations.part-1.ts
2799
- function migrateBindings(raw, changes, changeNote, mutator) {
2800
- const bindings = Array.isArray(raw.bindings) ? raw.bindings : null;
2801
- if (!bindings) return;
2802
- let touched = false;
2803
- for (const entry of bindings) {
2804
- if (!isRecord(entry)) continue;
2805
- const match = getRecord(entry.match);
2806
- if (!match) continue;
2807
- if (!mutator(match)) continue;
2808
- entry.match = match;
2809
- touched = true;
2810
- }
2811
- if (touched) {
2812
- raw.bindings = bindings;
2813
- changes.push(changeNote);
2814
- }
2815
- }
2816
- function ensureDefaultGroupEntry(section) {
2817
- const groups = isRecord(section.groups) ? section.groups : {};
2818
- const defaultKey = "*";
2819
- return {
2820
- groups,
2821
- entry: isRecord(groups[defaultKey]) ? groups[defaultKey] : {}
2822
- };
2823
- }
2824
- const LEGACY_CONFIG_MIGRATIONS_PART_1 = [
2825
- {
2826
- id: "bindings.match.provider->bindings.match.channel",
2827
- describe: "Move bindings[].match.provider to bindings[].match.channel",
2828
- apply: (raw, changes) => {
2829
- migrateBindings(raw, changes, "Moved bindings[].match.provider → bindings[].match.channel.", (match) => {
2830
- if (typeof match.channel === "string" && match.channel.trim()) return false;
2831
- const provider = typeof match.provider === "string" ? match.provider.trim() : "";
2832
- if (!provider) return false;
2833
- match.channel = provider;
2834
- delete match.provider;
2835
- return true;
2836
- });
2837
- }
2838
- },
2839
- {
2840
- id: "bindings.match.accountID->bindings.match.accountId",
2841
- describe: "Move bindings[].match.accountID to bindings[].match.accountId",
2842
- apply: (raw, changes) => {
2843
- migrateBindings(raw, changes, "Moved bindings[].match.accountID → bindings[].match.accountId.", (match) => {
2844
- if (match.accountId !== void 0) return false;
2845
- const accountID = typeof match.accountID === "string" ? match.accountID.trim() : match.accountID;
2846
- if (!accountID) return false;
2847
- match.accountId = accountID;
2848
- delete match.accountID;
2849
- return true;
2850
- });
2851
- }
2852
- },
2853
- {
2854
- id: "session.sendPolicy.rules.match.provider->match.channel",
2855
- describe: "Move session.sendPolicy.rules[].match.provider to match.channel",
2856
- apply: (raw, changes) => {
2857
- const session = getRecord(raw.session);
2858
- if (!session) return;
2859
- const sendPolicy = getRecord(session.sendPolicy);
2860
- if (!sendPolicy) return;
2861
- const rules = Array.isArray(sendPolicy.rules) ? sendPolicy.rules : null;
2862
- if (!rules) return;
2863
- let touched = false;
2864
- for (const rule of rules) {
2865
- if (!isRecord(rule)) continue;
2866
- const match = getRecord(rule.match);
2867
- if (!match) continue;
2868
- if (typeof match.channel === "string" && match.channel.trim()) continue;
2869
- const provider = typeof match.provider === "string" ? match.provider.trim() : "";
2870
- if (!provider) continue;
2871
- match.channel = provider;
2872
- delete match.provider;
2873
- rule.match = match;
2874
- touched = true;
2875
- }
2876
- if (touched) {
2877
- sendPolicy.rules = rules;
2878
- session.sendPolicy = sendPolicy;
2879
- raw.session = session;
2880
- changes.push("Moved session.sendPolicy.rules[].match.provider → match.channel.");
2881
- }
2882
- }
2883
- },
2884
- {
2885
- id: "messages.queue.byProvider->byChannel",
2886
- describe: "Move messages.queue.byProvider to messages.queue.byChannel",
2887
- apply: (raw, changes) => {
2888
- const messages = getRecord(raw.messages);
2889
- if (!messages) return;
2890
- const queue = getRecord(messages.queue);
2891
- if (!queue) return;
2892
- if (queue.byProvider === void 0) return;
2893
- if (queue.byChannel === void 0) {
2894
- queue.byChannel = queue.byProvider;
2895
- changes.push("Moved messages.queue.byProvider → messages.queue.byChannel.");
2896
- } else changes.push("Removed messages.queue.byProvider (messages.queue.byChannel already set).");
2897
- delete queue.byProvider;
2898
- messages.queue = queue;
2899
- raw.messages = messages;
2900
- }
2901
- },
2902
- {
2903
- id: "providers->channels",
2904
- describe: "Move provider config sections to channels.*",
2905
- apply: (raw, changes) => {
2906
- const legacyEntries = [
2907
- "whatsapp",
2908
- "telegram",
2909
- "discord",
2910
- "slack",
2911
- "signal",
2912
- "imessage",
2913
- "msteams"
2914
- ].filter((key) => isRecord(raw[key]));
2915
- if (legacyEntries.length === 0) return;
2916
- const channels = ensureRecord(raw, "channels");
2917
- for (const key of legacyEntries) {
2918
- const legacy = getRecord(raw[key]);
2919
- if (!legacy) continue;
2920
- const channelEntry = ensureRecord(channels, key);
2921
- const hadEntries = Object.keys(channelEntry).length > 0;
2922
- mergeMissing(channelEntry, legacy);
2923
- channels[key] = channelEntry;
2924
- delete raw[key];
2925
- changes.push(hadEntries ? `Merged ${key} → channels.${key}.` : `Moved ${key} → channels.${key}.`);
2926
- }
2927
- raw.channels = channels;
2928
- }
2929
- },
2930
- {
2931
- id: "channels.streaming-keys->channels.streaming",
2932
- describe: "Normalize legacy streaming keys to channels.<provider>.streaming (Telegram/Discord/Slack)",
2933
- apply: (raw, changes) => {
2934
- const channels = getRecord(raw.channels);
2935
- if (!channels) return;
2936
- const migrateProviderEntry = (params) => {
2937
- const migrateCommonStreamingMode = (resolveMode) => {
2938
- const hasLegacyStreamMode = params.entry.streamMode !== void 0;
2939
- const legacyStreaming = params.entry.streaming;
2940
- if (!hasLegacyStreamMode && typeof legacyStreaming !== "boolean") return false;
2941
- const resolved = resolveMode(params.entry);
2942
- params.entry.streaming = resolved;
2943
- if (hasLegacyStreamMode) {
2944
- delete params.entry.streamMode;
2945
- changes.push(`Moved ${params.pathPrefix}.streamMode → ${params.pathPrefix}.streaming (${resolved}).`);
2946
- }
2947
- if (typeof legacyStreaming === "boolean") changes.push(`Normalized ${params.pathPrefix}.streaming boolean → enum (${resolved}).`);
2948
- return true;
2949
- };
2950
- const hasLegacyStreamMode = params.entry.streamMode !== void 0;
2951
- const legacyStreaming = params.entry.streaming;
2952
- const legacyNativeStreaming = params.entry.nativeStreaming;
2953
- if (params.provider === "telegram") {
2954
- migrateCommonStreamingMode(resolveTelegramPreviewStreamMode);
2955
- return;
2956
- }
2957
- if (params.provider === "discord") {
2958
- migrateCommonStreamingMode(resolveDiscordPreviewStreamMode);
2959
- return;
2960
- }
2961
- if (!hasLegacyStreamMode && typeof legacyStreaming !== "boolean") return;
2962
- const resolvedStreaming = resolveSlackStreamingMode(params.entry);
2963
- const resolvedNativeStreaming = resolveSlackNativeStreaming(params.entry);
2964
- params.entry.streaming = resolvedStreaming;
2965
- params.entry.nativeStreaming = resolvedNativeStreaming;
2966
- if (hasLegacyStreamMode) {
2967
- delete params.entry.streamMode;
2968
- changes.push(`Moved ${params.pathPrefix}.streamMode → ${params.pathPrefix}.streaming (${resolvedStreaming}).`);
2969
- }
2970
- if (typeof legacyStreaming === "boolean") changes.push(`Moved ${params.pathPrefix}.streaming (boolean) → ${params.pathPrefix}.nativeStreaming (${resolvedNativeStreaming}).`);
2971
- else if (typeof legacyNativeStreaming !== "boolean" && hasLegacyStreamMode) changes.push(`Set ${params.pathPrefix}.nativeStreaming → ${resolvedNativeStreaming}.`);
2972
- };
2973
- const migrateProvider = (provider) => {
2974
- const providerEntry = getRecord(channels[provider]);
2975
- if (!providerEntry) return;
2976
- migrateProviderEntry({
2977
- provider,
2978
- entry: providerEntry,
2979
- pathPrefix: `channels.${provider}`
2980
- });
2981
- const accounts = getRecord(providerEntry.accounts);
2982
- if (!accounts) return;
2983
- for (const [accountId, accountValue] of Object.entries(accounts)) {
2984
- const account = getRecord(accountValue);
2985
- if (!account) continue;
2986
- migrateProviderEntry({
2987
- provider,
2988
- entry: account,
2989
- pathPrefix: `channels.${provider}.accounts.${accountId}`
2990
- });
2991
- }
2992
- };
2993
- migrateProvider("telegram");
2994
- migrateProvider("discord");
2995
- migrateProvider("slack");
2996
- }
2997
- },
2998
- {
2999
- id: "routing.allowFrom->channels.whatsapp.allowFrom",
3000
- describe: "Move routing.allowFrom to channels.whatsapp.allowFrom",
3001
- apply: (raw, changes) => {
3002
- const routing = raw.routing;
3003
- if (!routing || typeof routing !== "object") return;
3004
- const allowFrom = routing.allowFrom;
3005
- if (allowFrom === void 0) return;
3006
- const channels = getRecord(raw.channels);
3007
- const whatsapp = channels ? getRecord(channels.whatsapp) : null;
3008
- if (!whatsapp) {
3009
- delete routing.allowFrom;
3010
- if (Object.keys(routing).length === 0) delete raw.routing;
3011
- changes.push("Removed routing.allowFrom (channels.whatsapp not configured).");
3012
- return;
3013
- }
3014
- if (whatsapp.allowFrom === void 0) {
3015
- whatsapp.allowFrom = allowFrom;
3016
- changes.push("Moved routing.allowFrom → channels.whatsapp.allowFrom.");
3017
- } else changes.push("Removed routing.allowFrom (channels.whatsapp.allowFrom already set).");
3018
- delete routing.allowFrom;
3019
- if (Object.keys(routing).length === 0) delete raw.routing;
3020
- channels.whatsapp = whatsapp;
3021
- raw.channels = channels;
3022
- }
3023
- },
3024
- {
3025
- id: "routing.groupChat.requireMention->groups.*.requireMention",
3026
- describe: "Move routing.groupChat.requireMention to channels.whatsapp/telegram/imessage groups",
3027
- apply: (raw, changes) => {
3028
- const routing = raw.routing;
3029
- if (!routing || typeof routing !== "object") return;
3030
- const groupChat = routing.groupChat && typeof routing.groupChat === "object" ? routing.groupChat : null;
3031
- if (!groupChat) return;
3032
- const requireMention = groupChat.requireMention;
3033
- if (requireMention === void 0) return;
3034
- const channels = ensureRecord(raw, "channels");
3035
- const applyTo = (key, options) => {
3036
- if (options?.requireExisting && !isRecord(channels[key])) return;
3037
- const section = channels[key] && typeof channels[key] === "object" ? channels[key] : {};
3038
- const { groups, entry } = ensureDefaultGroupEntry(section);
3039
- const defaultKey = "*";
3040
- if (entry.requireMention === void 0) {
3041
- entry.requireMention = requireMention;
3042
- groups[defaultKey] = entry;
3043
- section.groups = groups;
3044
- channels[key] = section;
3045
- changes.push(`Moved routing.groupChat.requireMention → channels.${key}.groups."*".requireMention.`);
3046
- } else changes.push(`Removed routing.groupChat.requireMention (channels.${key}.groups."*" already set).`);
3047
- };
3048
- applyTo("whatsapp", { requireExisting: true });
3049
- applyTo("telegram");
3050
- applyTo("imessage");
3051
- delete groupChat.requireMention;
3052
- if (Object.keys(groupChat).length === 0) delete routing.groupChat;
3053
- if (Object.keys(routing).length === 0) delete raw.routing;
3054
- raw.channels = channels;
3055
- }
3056
- },
3057
- {
3058
- id: "gateway.token->gateway.auth.token",
3059
- describe: "Move gateway.token to gateway.auth.token",
3060
- apply: (raw, changes) => {
3061
- const gateway = raw.gateway;
3062
- if (!gateway || typeof gateway !== "object") return;
3063
- const token = gateway.token;
3064
- if (token === void 0) return;
3065
- const gatewayObj = gateway;
3066
- const auth = gatewayObj.auth && typeof gatewayObj.auth === "object" ? gatewayObj.auth : {};
3067
- if (auth.token === void 0) {
3068
- auth.token = token;
3069
- if (!auth.mode) auth.mode = "token";
3070
- changes.push("Moved gateway.token → gateway.auth.token.");
3071
- } else changes.push("Removed gateway.token (gateway.auth.token already set).");
3072
- delete gatewayObj.token;
3073
- if (Object.keys(auth).length > 0) gatewayObj.auth = auth;
3074
- raw.gateway = gatewayObj;
3075
- }
3076
- },
3077
- {
3078
- id: "telegram.requireMention->channels.telegram.groups.*.requireMention",
3079
- describe: "Move telegram.requireMention to channels.telegram.groups.*.requireMention",
3080
- apply: (raw, changes) => {
3081
- const channels = ensureRecord(raw, "channels");
3082
- const telegram = channels.telegram;
3083
- if (!telegram || typeof telegram !== "object") return;
3084
- const requireMention = telegram.requireMention;
3085
- if (requireMention === void 0) return;
3086
- const { groups, entry } = ensureDefaultGroupEntry(telegram);
3087
- const defaultKey = "*";
3088
- if (entry.requireMention === void 0) {
3089
- entry.requireMention = requireMention;
3090
- groups[defaultKey] = entry;
3091
- telegram.groups = groups;
3092
- changes.push("Moved telegram.requireMention → channels.telegram.groups.\"*\".requireMention.");
3093
- } else changes.push("Removed telegram.requireMention (channels.telegram.groups.\"*\" already set).");
3094
- delete telegram.requireMention;
3095
- channels.telegram = telegram;
3096
- raw.channels = channels;
3097
- }
3098
- }
3099
- ];
3100
-
3101
- //#endregion
3102
- //#region src/config/legacy.migrations.part-2.ts
3103
- function applyLegacyAudioTranscriptionModel(params) {
3104
- const mapped = mapLegacyAudioTranscription(params.source);
3105
- if (!mapped) {
3106
- params.changes.push(params.invalidMessage);
3107
- return;
3108
- }
3109
- const mediaAudio = ensureRecord(ensureRecord(ensureRecord(params.raw, "tools"), "media"), "audio");
3110
- if ((Array.isArray(mediaAudio.models) ? mediaAudio.models : []).length === 0) {
3111
- mediaAudio.enabled = true;
3112
- mediaAudio.models = [mapped];
3113
- params.changes.push(params.movedMessage);
3114
- return;
3115
- }
3116
- params.changes.push(params.alreadySetMessage);
3117
- }
3118
- const LEGACY_CONFIG_MIGRATIONS_PART_2 = [
3119
- {
3120
- id: "agent.model-config-v2",
3121
- describe: "Migrate legacy agent.model/allowedModels/modelAliases/modelFallbacks/imageModelFallbacks to agent.models + model lists",
3122
- apply: (raw, changes) => {
3123
- const agentRoot = getRecord(raw.agent);
3124
- const defaults = getRecord(getRecord(raw.agents)?.defaults);
3125
- const agent = agentRoot ?? defaults;
3126
- if (!agent) return;
3127
- const label = agentRoot ? "agent" : "agents.defaults";
3128
- const legacyModel = typeof agent.model === "string" ? String(agent.model) : void 0;
3129
- const legacyImageModel = typeof agent.imageModel === "string" ? String(agent.imageModel) : void 0;
3130
- const legacyAllowed = Array.isArray(agent.allowedModels) ? agent.allowedModels.map(String) : [];
3131
- const legacyModelFallbacks = Array.isArray(agent.modelFallbacks) ? agent.modelFallbacks.map(String) : [];
3132
- const legacyImageModelFallbacks = Array.isArray(agent.imageModelFallbacks) ? agent.imageModelFallbacks.map(String) : [];
3133
- const legacyAliases = agent.modelAliases && typeof agent.modelAliases === "object" ? agent.modelAliases : {};
3134
- if (!(legacyModel || legacyImageModel || legacyAllowed.length > 0 || legacyModelFallbacks.length > 0 || legacyImageModelFallbacks.length > 0 || Object.keys(legacyAliases).length > 0)) return;
3135
- const models = agent.models && typeof agent.models === "object" ? agent.models : {};
3136
- const ensureModel = (rawKey) => {
3137
- if (typeof rawKey !== "string") return;
3138
- const key = rawKey.trim();
3139
- if (!key) return;
3140
- if (!models[key]) models[key] = {};
3141
- };
3142
- ensureModel(legacyModel);
3143
- ensureModel(legacyImageModel);
3144
- for (const key of legacyAllowed) ensureModel(key);
3145
- for (const key of legacyModelFallbacks) ensureModel(key);
3146
- for (const key of legacyImageModelFallbacks) ensureModel(key);
3147
- for (const target of Object.values(legacyAliases)) {
3148
- if (typeof target !== "string") continue;
3149
- ensureModel(target);
3150
- }
3151
- for (const [alias, targetRaw] of Object.entries(legacyAliases)) {
3152
- if (typeof targetRaw !== "string") continue;
3153
- const target = targetRaw.trim();
3154
- if (!target) continue;
3155
- const entry = models[target] && typeof models[target] === "object" ? models[target] : {};
3156
- if (!("alias" in entry)) {
3157
- entry.alias = alias;
3158
- models[target] = entry;
3159
- }
3160
- }
3161
- const currentModel = agent.model && typeof agent.model === "object" ? agent.model : null;
3162
- if (currentModel) {
3163
- if (!currentModel.primary && legacyModel) currentModel.primary = legacyModel;
3164
- if (legacyModelFallbacks.length > 0 && (!Array.isArray(currentModel.fallbacks) || currentModel.fallbacks.length === 0)) currentModel.fallbacks = legacyModelFallbacks;
3165
- agent.model = currentModel;
3166
- } else if (legacyModel || legacyModelFallbacks.length > 0) agent.model = {
3167
- primary: legacyModel,
3168
- fallbacks: legacyModelFallbacks.length ? legacyModelFallbacks : []
3169
- };
3170
- const currentImageModel = agent.imageModel && typeof agent.imageModel === "object" ? agent.imageModel : null;
3171
- if (currentImageModel) {
3172
- if (!currentImageModel.primary && legacyImageModel) currentImageModel.primary = legacyImageModel;
3173
- if (legacyImageModelFallbacks.length > 0 && (!Array.isArray(currentImageModel.fallbacks) || currentImageModel.fallbacks.length === 0)) currentImageModel.fallbacks = legacyImageModelFallbacks;
3174
- agent.imageModel = currentImageModel;
3175
- } else if (legacyImageModel || legacyImageModelFallbacks.length > 0) agent.imageModel = {
3176
- primary: legacyImageModel,
3177
- fallbacks: legacyImageModelFallbacks.length ? legacyImageModelFallbacks : []
3178
- };
3179
- agent.models = models;
3180
- if (legacyModel !== void 0) changes.push(`Migrated ${label}.model string → ${label}.model.primary.`);
3181
- if (legacyModelFallbacks.length > 0) changes.push(`Migrated ${label}.modelFallbacks → ${label}.model.fallbacks.`);
3182
- if (legacyImageModel !== void 0) changes.push(`Migrated ${label}.imageModel string → ${label}.imageModel.primary.`);
3183
- if (legacyImageModelFallbacks.length > 0) changes.push(`Migrated ${label}.imageModelFallbacks → ${label}.imageModel.fallbacks.`);
3184
- if (legacyAllowed.length > 0) changes.push(`Migrated ${label}.allowedModels → ${label}.models.`);
3185
- if (Object.keys(legacyAliases).length > 0) changes.push(`Migrated ${label}.modelAliases → ${label}.models.*.alias.`);
3186
- delete agent.allowedModels;
3187
- delete agent.modelAliases;
3188
- delete agent.modelFallbacks;
3189
- delete agent.imageModelFallbacks;
3190
- }
3191
- },
3192
- {
3193
- id: "routing.agents-v2",
3194
- describe: "Move routing.agents/defaultAgentId to agents.list",
3195
- apply: (raw, changes) => {
3196
- const routing = getRecord(raw.routing);
3197
- if (!routing) return;
3198
- const routingAgents = getRecord(routing.agents);
3199
- const agents = ensureRecord(raw, "agents");
3200
- const list = getAgentsList(agents);
3201
- if (routingAgents) {
3202
- for (const [rawId, entryRaw] of Object.entries(routingAgents)) {
3203
- const agentId = String(rawId ?? "").trim();
3204
- const entry = getRecord(entryRaw);
3205
- if (!agentId || !entry) continue;
3206
- const target = ensureAgentEntry(list, agentId);
3207
- const entryCopy = { ...entry };
3208
- if ("mentionPatterns" in entryCopy) {
3209
- const mentionPatterns = entryCopy.mentionPatterns;
3210
- const groupChat = ensureRecord(target, "groupChat");
3211
- if (groupChat.mentionPatterns === void 0) {
3212
- groupChat.mentionPatterns = mentionPatterns;
3213
- changes.push(`Moved routing.agents.${agentId}.mentionPatterns → agents.list (id "${agentId}").groupChat.mentionPatterns.`);
3214
- } else changes.push(`Removed routing.agents.${agentId}.mentionPatterns (agents.list groupChat mentionPatterns already set).`);
3215
- delete entryCopy.mentionPatterns;
3216
- }
3217
- const legacyGroupChat = getRecord(entryCopy.groupChat);
3218
- if (legacyGroupChat) {
3219
- mergeMissing(ensureRecord(target, "groupChat"), legacyGroupChat);
3220
- delete entryCopy.groupChat;
3221
- }
3222
- const legacySandbox = getRecord(entryCopy.sandbox);
3223
- if (legacySandbox) {
3224
- const sandboxTools = getRecord(legacySandbox.tools);
3225
- if (sandboxTools) {
3226
- mergeMissing(ensureRecord(ensureRecord(ensureRecord(target, "tools"), "sandbox"), "tools"), sandboxTools);
3227
- delete legacySandbox.tools;
3228
- changes.push(`Moved routing.agents.${agentId}.sandbox.tools → agents.list (id "${agentId}").tools.sandbox.tools.`);
3229
- }
3230
- entryCopy.sandbox = legacySandbox;
3231
- }
3232
- mergeMissing(target, entryCopy);
3233
- }
3234
- delete routing.agents;
3235
- changes.push("Moved routing.agents → agents.list.");
3236
- }
3237
- const defaultAgentId = typeof routing.defaultAgentId === "string" ? routing.defaultAgentId.trim() : "";
3238
- if (defaultAgentId) {
3239
- if (!list.some((entry) => isRecord(entry) && entry.default === true)) {
3240
- const entry = ensureAgentEntry(list, defaultAgentId);
3241
- entry.default = true;
3242
- changes.push(`Moved routing.defaultAgentId → agents.list (id "${defaultAgentId}").default.`);
3243
- } else changes.push("Removed routing.defaultAgentId (agents.list default already set).");
3244
- delete routing.defaultAgentId;
3245
- }
3246
- if (list.length > 0) agents.list = list;
3247
- if (Object.keys(routing).length === 0) delete raw.routing;
3248
- }
3249
- },
3250
- {
3251
- id: "routing.config-v2",
3252
- describe: "Move routing bindings/groupChat/queue/agentToAgent/transcribeAudio",
3253
- apply: (raw, changes) => {
3254
- const routing = getRecord(raw.routing);
3255
- if (!routing) return;
3256
- if (routing.bindings !== void 0) {
3257
- if (raw.bindings === void 0) {
3258
- raw.bindings = routing.bindings;
3259
- changes.push("Moved routing.bindings → bindings.");
3260
- } else changes.push("Removed routing.bindings (bindings already set).");
3261
- delete routing.bindings;
3262
- }
3263
- if (routing.agentToAgent !== void 0) {
3264
- const tools = ensureRecord(raw, "tools");
3265
- if (tools.agentToAgent === void 0) {
3266
- tools.agentToAgent = routing.agentToAgent;
3267
- changes.push("Moved routing.agentToAgent → tools.agentToAgent.");
3268
- } else changes.push("Removed routing.agentToAgent (tools.agentToAgent already set).");
3269
- delete routing.agentToAgent;
3270
- }
3271
- if (routing.queue !== void 0) {
3272
- const messages = ensureRecord(raw, "messages");
3273
- if (messages.queue === void 0) {
3274
- messages.queue = routing.queue;
3275
- changes.push("Moved routing.queue → messages.queue.");
3276
- } else changes.push("Removed routing.queue (messages.queue already set).");
3277
- delete routing.queue;
3278
- }
3279
- const groupChat = getRecord(routing.groupChat);
3280
- if (groupChat) {
3281
- const historyLimit = groupChat.historyLimit;
3282
- if (historyLimit !== void 0) {
3283
- const messagesGroup = ensureRecord(ensureRecord(raw, "messages"), "groupChat");
3284
- if (messagesGroup.historyLimit === void 0) {
3285
- messagesGroup.historyLimit = historyLimit;
3286
- changes.push("Moved routing.groupChat.historyLimit → messages.groupChat.historyLimit.");
3287
- } else changes.push("Removed routing.groupChat.historyLimit (messages.groupChat.historyLimit already set).");
3288
- delete groupChat.historyLimit;
3289
- }
3290
- const mentionPatterns = groupChat.mentionPatterns;
3291
- if (mentionPatterns !== void 0) {
3292
- const messagesGroup = ensureRecord(ensureRecord(raw, "messages"), "groupChat");
3293
- if (messagesGroup.mentionPatterns === void 0) {
3294
- messagesGroup.mentionPatterns = mentionPatterns;
3295
- changes.push("Moved routing.groupChat.mentionPatterns → messages.groupChat.mentionPatterns.");
3296
- } else changes.push("Removed routing.groupChat.mentionPatterns (messages.groupChat.mentionPatterns already set).");
3297
- delete groupChat.mentionPatterns;
3298
- }
3299
- if (Object.keys(groupChat).length === 0) delete routing.groupChat;
3300
- else routing.groupChat = groupChat;
3301
- }
3302
- if (routing.transcribeAudio !== void 0) {
3303
- applyLegacyAudioTranscriptionModel({
3304
- raw,
3305
- source: routing.transcribeAudio,
3306
- changes,
3307
- movedMessage: "Moved routing.transcribeAudio → tools.media.audio.models.",
3308
- alreadySetMessage: "Removed routing.transcribeAudio (tools.media.audio.models already set).",
3309
- invalidMessage: "Removed routing.transcribeAudio (invalid or empty command)."
3310
- });
3311
- delete routing.transcribeAudio;
3312
- }
3313
- if (Object.keys(routing).length === 0) delete raw.routing;
3314
- }
3315
- },
3316
- {
3317
- id: "audio.transcription-v2",
3318
- describe: "Move audio.transcription to tools.media.audio.models",
3319
- apply: (raw, changes) => {
3320
- const audio = getRecord(raw.audio);
3321
- if (audio?.transcription === void 0) return;
3322
- applyLegacyAudioTranscriptionModel({
3323
- raw,
3324
- source: audio.transcription,
3325
- changes,
3326
- movedMessage: "Moved audio.transcription → tools.media.audio.models.",
3327
- alreadySetMessage: "Removed audio.transcription (tools.media.audio.models already set).",
3328
- invalidMessage: "Removed audio.transcription (invalid or empty command)."
3329
- });
3330
- delete audio.transcription;
3331
- if (Object.keys(audio).length === 0) delete raw.audio;
3332
- else raw.audio = audio;
3333
- }
3334
- }
3335
- ];
3336
-
3337
- //#endregion
3338
- //#region src/config/legacy.migrations.part-3.ts
3339
- const LEGACY_CONFIG_MIGRATIONS_PART_3 = [
3340
- {
3341
- id: "auth.anthropic-claude-cli-mode-oauth",
3342
- describe: "Switch anthropic:claude-cli auth profile mode to oauth",
3343
- apply: (raw, changes) => {
3344
- const profiles = getRecord(getRecord(raw.auth)?.profiles);
3345
- if (!profiles) return;
3346
- const claudeCli = getRecord(profiles["anthropic:claude-cli"]);
3347
- if (!claudeCli) return;
3348
- if (claudeCli.mode !== "token") return;
3349
- claudeCli.mode = "oauth";
3350
- changes.push("Updated auth.profiles[\"anthropic:claude-cli\"].mode → \"oauth\".");
3351
- }
3352
- },
3353
- {
3354
- id: "tools.bash->tools.exec",
3355
- describe: "Move tools.bash to tools.exec",
3356
- apply: (raw, changes) => {
3357
- const tools = ensureRecord(raw, "tools");
3358
- const bash = getRecord(tools.bash);
3359
- if (!bash) return;
3360
- if (tools.exec === void 0) {
3361
- tools.exec = bash;
3362
- changes.push("Moved tools.bash → tools.exec.");
3363
- } else changes.push("Removed tools.bash (tools.exec already set).");
3364
- delete tools.bash;
3365
- }
3366
- },
3367
- {
3368
- id: "messages.tts.enabled->auto",
3369
- describe: "Move messages.tts.enabled to messages.tts.auto",
3370
- apply: (raw, changes) => {
3371
- const tts = getRecord(getRecord(raw.messages)?.tts);
3372
- if (!tts) return;
3373
- if (tts.auto !== void 0) {
3374
- if ("enabled" in tts) {
3375
- delete tts.enabled;
3376
- changes.push("Removed messages.tts.enabled (messages.tts.auto already set).");
3377
- }
3378
- return;
3379
- }
3380
- if (typeof tts.enabled !== "boolean") return;
3381
- tts.auto = tts.enabled ? "always" : "off";
3382
- delete tts.enabled;
3383
- changes.push(`Moved messages.tts.enabled → messages.tts.auto (${String(tts.auto)}).`);
3384
- }
3385
- },
3386
- {
3387
- id: "agent.defaults-v2",
3388
- describe: "Move agent config to agents.defaults and tools",
3389
- apply: (raw, changes) => {
3390
- const agent = getRecord(raw.agent);
3391
- if (!agent) return;
3392
- const agents = ensureRecord(raw, "agents");
3393
- const defaults = getRecord(agents.defaults) ?? {};
3394
- const tools = ensureRecord(raw, "tools");
3395
- const agentTools = getRecord(agent.tools);
3396
- if (agentTools) {
3397
- if (tools.allow === void 0 && agentTools.allow !== void 0) {
3398
- tools.allow = agentTools.allow;
3399
- changes.push("Moved agent.tools.allow → tools.allow.");
3400
- }
3401
- if (tools.deny === void 0 && agentTools.deny !== void 0) {
3402
- tools.deny = agentTools.deny;
3403
- changes.push("Moved agent.tools.deny → tools.deny.");
3404
- }
3405
- }
3406
- const elevated = getRecord(agent.elevated);
3407
- if (elevated) if (tools.elevated === void 0) {
3408
- tools.elevated = elevated;
3409
- changes.push("Moved agent.elevated → tools.elevated.");
3410
- } else changes.push("Removed agent.elevated (tools.elevated already set).");
3411
- const bash = getRecord(agent.bash);
3412
- if (bash) if (tools.exec === void 0) {
3413
- tools.exec = bash;
3414
- changes.push("Moved agent.bash → tools.exec.");
3415
- } else changes.push("Removed agent.bash (tools.exec already set).");
3416
- const sandbox = getRecord(agent.sandbox);
3417
- if (sandbox) {
3418
- const sandboxTools = getRecord(sandbox.tools);
3419
- if (sandboxTools) {
3420
- mergeMissing(ensureRecord(ensureRecord(tools, "sandbox"), "tools"), sandboxTools);
3421
- delete sandbox.tools;
3422
- changes.push("Moved agent.sandbox.tools → tools.sandbox.tools.");
3423
- }
3424
- }
3425
- const subagents = getRecord(agent.subagents);
3426
- if (subagents) {
3427
- const subagentTools = getRecord(subagents.tools);
3428
- if (subagentTools) {
3429
- mergeMissing(ensureRecord(ensureRecord(tools, "subagents"), "tools"), subagentTools);
3430
- delete subagents.tools;
3431
- changes.push("Moved agent.subagents.tools → tools.subagents.tools.");
3432
- }
3433
- }
3434
- const agentCopy = structuredClone(agent);
3435
- delete agentCopy.tools;
3436
- delete agentCopy.elevated;
3437
- delete agentCopy.bash;
3438
- if (isRecord(agentCopy.sandbox)) delete agentCopy.sandbox.tools;
3439
- if (isRecord(agentCopy.subagents)) delete agentCopy.subagents.tools;
3440
- mergeMissing(defaults, agentCopy);
3441
- agents.defaults = defaults;
3442
- raw.agents = agents;
3443
- delete raw.agent;
3444
- changes.push("Moved agent → agents.defaults.");
3445
- }
3446
- },
3447
- {
3448
- id: "identity->agents.list",
3449
- describe: "Move identity to agents.list[].identity",
3450
- apply: (raw, changes) => {
3451
- const identity = getRecord(raw.identity);
3452
- if (!identity) return;
3453
- const agents = ensureRecord(raw, "agents");
3454
- const list = getAgentsList(agents);
3455
- const defaultId = resolveDefaultAgentIdFromRaw(raw);
3456
- const entry = ensureAgentEntry(list, defaultId);
3457
- if (entry.identity === void 0) {
3458
- entry.identity = identity;
3459
- changes.push(`Moved identity → agents.list (id "${defaultId}").identity.`);
3460
- } else changes.push("Removed identity (agents.list identity already set).");
3461
- agents.list = list;
3462
- raw.agents = agents;
3463
- delete raw.identity;
3464
- }
3465
- }
3466
- ];
3467
-
3468
- //#endregion
3469
- //#region src/config/legacy.migrations.ts
3470
- const LEGACY_CONFIG_MIGRATIONS = [
3471
- ...LEGACY_CONFIG_MIGRATIONS_PART_1,
3472
- ...LEGACY_CONFIG_MIGRATIONS_PART_2,
3473
- ...LEGACY_CONFIG_MIGRATIONS_PART_3
3474
- ];
3475
-
3476
- //#endregion
3477
- //#region src/config/legacy.rules.ts
3478
- const LEGACY_CONFIG_RULES = [
3479
- {
3480
- path: ["whatsapp"],
3481
- message: "whatsapp config moved to channels.whatsapp (auto-migrated on load)."
3482
- },
3483
- {
3484
- path: ["telegram"],
3485
- message: "telegram config moved to channels.telegram (auto-migrated on load)."
3486
- },
3487
- {
3488
- path: ["discord"],
3489
- message: "discord config moved to channels.discord (auto-migrated on load)."
3490
- },
3491
- {
3492
- path: ["slack"],
3493
- message: "slack config moved to channels.slack (auto-migrated on load)."
3494
- },
3495
- {
3496
- path: ["signal"],
3497
- message: "signal config moved to channels.signal (auto-migrated on load)."
3498
- },
3499
- {
3500
- path: ["imessage"],
3501
- message: "imessage config moved to channels.imessage (auto-migrated on load)."
3502
- },
3503
- {
3504
- path: ["msteams"],
3505
- message: "msteams config moved to channels.msteams (auto-migrated on load)."
3506
- },
3507
- {
3508
- path: ["routing", "allowFrom"],
3509
- message: "routing.allowFrom was removed; use channels.whatsapp.allowFrom instead (auto-migrated on load)."
3510
- },
3511
- {
3512
- path: ["routing", "bindings"],
3513
- message: "routing.bindings was moved; use top-level bindings instead (auto-migrated on load)."
3514
- },
3515
- {
3516
- path: ["routing", "agents"],
3517
- message: "routing.agents was moved; use agents.list instead (auto-migrated on load)."
3518
- },
3519
- {
3520
- path: ["routing", "defaultAgentId"],
3521
- message: "routing.defaultAgentId was moved; use agents.list[].default instead (auto-migrated on load)."
3522
- },
3523
- {
3524
- path: ["routing", "agentToAgent"],
3525
- message: "routing.agentToAgent was moved; use tools.agentToAgent instead (auto-migrated on load)."
3526
- },
3527
- {
3528
- path: [
3529
- "routing",
3530
- "groupChat",
3531
- "requireMention"
3532
- ],
3533
- message: "routing.groupChat.requireMention was removed; use channels.whatsapp/telegram/imessage groups defaults (e.g. channels.whatsapp.groups.\"*\".requireMention) instead (auto-migrated on load)."
3534
- },
3535
- {
3536
- path: [
3537
- "routing",
3538
- "groupChat",
3539
- "mentionPatterns"
3540
- ],
3541
- message: "routing.groupChat.mentionPatterns was moved; use agents.list[].groupChat.mentionPatterns or messages.groupChat.mentionPatterns instead (auto-migrated on load)."
3542
- },
3543
- {
3544
- path: ["routing", "queue"],
3545
- message: "routing.queue was moved; use messages.queue instead (auto-migrated on load)."
3546
- },
3547
- {
3548
- path: ["routing", "transcribeAudio"],
3549
- message: "routing.transcribeAudio was moved; use tools.media.audio.models instead (auto-migrated on load)."
3550
- },
3551
- {
3552
- path: ["telegram", "requireMention"],
3553
- message: "telegram.requireMention was removed; use channels.telegram.groups.\"*\".requireMention instead (auto-migrated on load)."
3554
- },
3555
- {
3556
- path: ["identity"],
3557
- message: "identity was moved; use agents.list[].identity instead (auto-migrated on load)."
3558
- },
3559
- {
3560
- path: ["agent"],
3561
- message: "agent.* was moved; use agents.defaults (and tools.* for tool/elevated/exec settings) instead (auto-migrated on load)."
3562
- },
3563
- {
3564
- path: ["tools", "bash"],
3565
- message: "tools.bash was removed; use tools.exec instead (auto-migrated on load)."
3566
- },
3567
- {
3568
- path: ["agent", "model"],
3569
- message: "agent.model string was replaced by agents.defaults.model.primary/fallbacks and agents.defaults.models (auto-migrated on load).",
3570
- match: (value) => typeof value === "string"
3571
- },
3572
- {
3573
- path: ["agent", "imageModel"],
3574
- message: "agent.imageModel string was replaced by agents.defaults.imageModel.primary/fallbacks (auto-migrated on load).",
3575
- match: (value) => typeof value === "string"
3576
- },
3577
- {
3578
- path: ["agent", "allowedModels"],
3579
- message: "agent.allowedModels was replaced by agents.defaults.models (auto-migrated on load)."
3580
- },
3581
- {
3582
- path: ["agent", "modelAliases"],
3583
- message: "agent.modelAliases was replaced by agents.defaults.models.*.alias (auto-migrated on load)."
3584
- },
3585
- {
3586
- path: ["agent", "modelFallbacks"],
3587
- message: "agent.modelFallbacks was replaced by agents.defaults.model.fallbacks (auto-migrated on load)."
3588
- },
3589
- {
3590
- path: ["agent", "imageModelFallbacks"],
3591
- message: "agent.imageModelFallbacks was replaced by agents.defaults.imageModel.fallbacks (auto-migrated on load)."
3592
- },
3593
- {
3594
- path: [
3595
- "messages",
3596
- "tts",
3597
- "enabled"
3598
- ],
3599
- message: "messages.tts.enabled was replaced by messages.tts.auto (auto-migrated on load)."
3600
- },
3601
- {
3602
- path: ["gateway", "token"],
3603
- message: "gateway.token is ignored; use gateway.auth.token instead (auto-migrated on load)."
3604
- }
3605
- ];
3606
-
3607
- //#endregion
3608
- //#region src/config/legacy.ts
3609
- function findLegacyConfigIssues(raw) {
3610
- if (!raw || typeof raw !== "object") return [];
3611
- const root = raw;
3612
- const issues = [];
3613
- for (const rule of LEGACY_CONFIG_RULES) {
3614
- let cursor = root;
3615
- for (const key of rule.path) {
3616
- if (!cursor || typeof cursor !== "object") {
3617
- cursor = void 0;
3618
- break;
3619
- }
3620
- cursor = cursor[key];
3621
- }
3622
- if (cursor !== void 0 && (!rule.match || rule.match(cursor, root))) issues.push({
3623
- path: rule.path.join("."),
3624
- message: rule.message
3625
- });
3626
- }
3627
- return issues;
3628
- }
3629
-
3630
- //#endregion
3631
- //#region src/config/merge-patch.ts
3632
- function isObjectWithStringId(value) {
3633
- if (!isPlainObject$2(value)) return false;
3634
- return typeof value.id === "string" && value.id.length > 0;
3635
- }
3636
- /**
3637
- * Merge arrays of object-like entries keyed by `id`.
3638
- *
3639
- * Contract:
3640
- * - Base array must be fully id-keyed; otherwise return undefined (caller should replace).
3641
- * - Patch entries with valid id merge by id (or append when the id is new).
3642
- * - Patch entries without valid id append as-is, avoiding destructive full-array replacement.
3643
- */
3644
- function mergeObjectArraysById(base, patch, options) {
3645
- if (!base.every(isObjectWithStringId)) return;
3646
- const merged = [...base];
3647
- const indexById = /* @__PURE__ */ new Map();
3648
- for (const [index, entry] of merged.entries()) {
3649
- if (!isObjectWithStringId(entry)) return;
3650
- indexById.set(entry.id, index);
3651
- }
3652
- for (const patchEntry of patch) {
3653
- if (!isObjectWithStringId(patchEntry)) {
3654
- merged.push(structuredClone(patchEntry));
3655
- continue;
3656
- }
3657
- const existingIndex = indexById.get(patchEntry.id);
3658
- if (existingIndex === void 0) {
3659
- merged.push(structuredClone(patchEntry));
3660
- indexById.set(patchEntry.id, merged.length - 1);
3661
- continue;
3662
- }
3663
- merged[existingIndex] = applyMergePatch(merged[existingIndex], patchEntry, options);
3664
- }
3665
- return merged;
3666
- }
3667
- function applyMergePatch(base, patch, options = {}) {
3668
- if (!isPlainObject$2(patch)) return patch;
3669
- const result = isPlainObject$2(base) ? { ...base } : {};
3670
- for (const [key, value] of Object.entries(patch)) {
3671
- if (isBlockedObjectKey(key)) continue;
3672
- if (value === null) {
3673
- delete result[key];
3674
- continue;
3675
- }
3676
- if (options.mergeObjectArraysById && Array.isArray(result[key]) && Array.isArray(value)) {
3677
- const mergedArray = mergeObjectArraysById(result[key], value, options);
3678
- if (mergedArray) {
3679
- result[key] = mergedArray;
3680
- continue;
3681
- }
3682
- }
3683
- if (isPlainObject$2(value)) {
3684
- const baseValue = result[key];
3685
- result[key] = applyMergePatch(isPlainObject$2(baseValue) ? baseValue : {}, value, options);
3686
- continue;
3687
- }
3688
- result[key] = value;
3689
- }
3690
- return result;
3691
- }
3692
-
3693
- //#endregion
3694
- //#region src/config/normalize-paths.ts
3695
- const PATH_VALUE_RE = /^~(?=$|[\\/])/;
3696
- const PATH_KEY_RE = /(dir|path|paths|file|root|workspace)$/i;
3697
- const PATH_LIST_KEYS = new Set(["paths", "pathPrepend"]);
3698
- function normalizeStringValue(key, value) {
3699
- if (!PATH_VALUE_RE.test(value.trim())) return value;
3700
- if (!key) return value;
3701
- if (PATH_KEY_RE.test(key) || PATH_LIST_KEYS.has(key)) return resolveUserPath(value);
3702
- return value;
3703
- }
3704
- function normalizeAny(key, value) {
3705
- if (typeof value === "string") return normalizeStringValue(key, value);
3706
- if (Array.isArray(value)) {
3707
- const normalizeChildren = Boolean(key && PATH_LIST_KEYS.has(key));
3708
- return value.map((entry) => {
3709
- if (typeof entry === "string") return normalizeChildren ? normalizeStringValue(key, entry) : entry;
3710
- if (Array.isArray(entry)) return normalizeAny(void 0, entry);
3711
- if (isPlainObject$2(entry)) return normalizeAny(void 0, entry);
3712
- return entry;
3713
- });
3714
- }
3715
- if (!isPlainObject$2(value)) return value;
3716
- for (const [childKey, childValue] of Object.entries(value)) {
3717
- const next = normalizeAny(childKey, childValue);
3718
- if (next !== childValue) value[childKey] = next;
3719
- }
3720
- return value;
3721
- }
3722
- /**
3723
- * Normalize "~" paths in path-ish config fields.
3724
- *
3725
- * Goal: accept `~/...` consistently across config file + env overrides, while
3726
- * keeping the surface area small and predictable.
3727
- */
3728
- function normalizeConfigPaths(cfg) {
3729
- if (!cfg || typeof cfg !== "object") return cfg;
3730
- normalizeAny(void 0, cfg);
3731
- return cfg;
3732
- }
3733
-
3734
- //#endregion
3735
- //#region src/config/runtime-overrides.ts
3736
- let overrides = {};
3737
- function mergeOverrides(base, override) {
3738
- if (!isPlainObject$2(base) || !isPlainObject$2(override)) return override;
3739
- const next = { ...base };
3740
- for (const [key, value] of Object.entries(override)) {
3741
- if (value === void 0 || isBlockedObjectKey(key)) continue;
3742
- next[key] = mergeOverrides(base[key], value);
3743
- }
3744
- return next;
3745
- }
3746
- function applyConfigOverrides(cfg) {
3747
- if (!overrides || Object.keys(overrides).length === 0) return cfg;
3748
- return mergeOverrides(cfg, overrides);
3749
- }
3750
-
3751
- //#endregion
3752
- //#region src/plugins/config-state.ts
3753
- const BUNDLED_ENABLED_BY_DEFAULT = new Set([
3754
- "device-pair",
3755
- "phone-control",
3756
- "talk-voice"
3757
- ]);
3758
- const normalizeList = (value) => {
3759
- if (!Array.isArray(value)) return [];
3760
- return value.map((entry) => typeof entry === "string" ? entry.trim() : "").filter(Boolean);
3761
- };
3762
- const normalizePluginEntries = (entries) => {
3763
- if (!entries || typeof entries !== "object" || Array.isArray(entries)) return {};
3764
- const normalized = {};
3765
- for (const [key, value] of Object.entries(entries)) {
3766
- if (!key.trim()) continue;
3767
- if (!value || typeof value !== "object" || Array.isArray(value)) {
3768
- normalized[key] = {};
3769
- continue;
3770
- }
3771
- const entry = value;
3772
- normalized[key] = {
3773
- enabled: typeof entry.enabled === "boolean" ? entry.enabled : void 0,
3774
- config: "config" in entry ? entry.config : void 0
3775
- };
3776
- }
3777
- return normalized;
3778
- };
3779
- const normalizePluginsConfig = (config) => {
3780
- return {
3781
- enabled: config?.enabled !== false,
3782
- allow: normalizeList(config?.allow),
3783
- deny: normalizeList(config?.deny),
3784
- loadPaths: normalizeList(config?.load?.paths),
3785
- slots: {},
3786
- entries: normalizePluginEntries(config?.entries)
2812
+ const normalizePluginsConfig = (config) => {
2813
+ return {
2814
+ enabled: config?.enabled !== false,
2815
+ allow: normalizeList(config?.allow),
2816
+ deny: normalizeList(config?.deny),
2817
+ loadPaths: normalizeList(config?.load?.paths),
2818
+ slots: {},
2819
+ entries: normalizePluginEntries(config?.entries)
3787
2820
  };
3788
2821
  };
3789
2822
  function resolveEnableState(id, origin, config) {
@@ -3848,27 +2881,15 @@ function resolveBundledPluginsDir() {
3848
2881
  } catch {}
3849
2882
  }
3850
2883
 
3851
- //#endregion
3852
- //#region src/compat/legacy-names.ts
3853
- const PROJECT_NAME = "remoteclaw";
3854
- const LEGACY_PROJECT_NAMES = [];
3855
- const MANIFEST_KEY = PROJECT_NAME;
3856
- const LEGACY_MANIFEST_KEYS = LEGACY_PROJECT_NAMES;
3857
- const LEGACY_PLUGIN_MANIFEST_FILENAMES = [];
3858
-
3859
2884
  //#endregion
3860
2885
  //#region src/plugins/manifest.ts
2886
+ const MANIFEST_KEY = "remoteclaw";
3861
2887
  const PLUGIN_MANIFEST_FILENAME = "remoteclaw.plugin.json";
3862
- const PLUGIN_MANIFEST_FILENAMES = [PLUGIN_MANIFEST_FILENAME, ...LEGACY_PLUGIN_MANIFEST_FILENAMES];
3863
2888
  function normalizeStringList(value) {
3864
2889
  if (!Array.isArray(value)) return [];
3865
2890
  return value.map((entry) => typeof entry === "string" ? entry.trim() : "").filter(Boolean);
3866
2891
  }
3867
2892
  function resolvePluginManifestPath(rootDir) {
3868
- for (const filename of PLUGIN_MANIFEST_FILENAMES) {
3869
- const candidate = path.join(rootDir, filename);
3870
- if (fs.existsSync(candidate)) return candidate;
3871
- }
3872
2893
  return path.join(rootDir, PLUGIN_MANIFEST_FILENAME);
3873
2894
  }
3874
2895
  function loadPluginManifest(rootDir) {
@@ -3912,6 +2933,8 @@ function loadPluginManifest(rootDir) {
3912
2933
  const channels = normalizeStringList(raw.channels);
3913
2934
  const providers = normalizeStringList(raw.providers);
3914
2935
  const skills = normalizeStringList(raw.skills);
2936
+ const stt = normalizeStringList(raw.stt);
2937
+ const tts = normalizeStringList(raw.tts);
3915
2938
  let uiHints;
3916
2939
  if (isRecord(raw.uiHints)) uiHints = raw.uiHints;
3917
2940
  return {
@@ -3923,6 +2946,8 @@ function loadPluginManifest(rootDir) {
3923
2946
  channels,
3924
2947
  providers,
3925
2948
  skills,
2949
+ stt,
2950
+ tts,
3926
2951
  name,
3927
2952
  description,
3928
2953
  version,
@@ -3933,12 +2958,7 @@ function loadPluginManifest(rootDir) {
3933
2958
  }
3934
2959
  function getPackageManifestMetadata(manifest) {
3935
2960
  if (!manifest) return;
3936
- const current = manifest[MANIFEST_KEY];
3937
- if (current) return current;
3938
- for (const key of LEGACY_MANIFEST_KEYS) {
3939
- const legacy = manifest[key];
3940
- if (legacy) return legacy;
3941
- }
2961
+ return manifest[MANIFEST_KEY];
3942
2962
  }
3943
2963
 
3944
2964
  //#endregion
@@ -4428,6 +3448,8 @@ function buildRecord(params) {
4428
3448
  channels: params.manifest.channels ?? [],
4429
3449
  providers: params.manifest.providers ?? [],
4430
3450
  skills: params.manifest.skills ?? [],
3451
+ stt: params.manifest.stt ?? [],
3452
+ tts: params.manifest.tts ?? [],
4431
3453
  origin: params.candidate.origin,
4432
3454
  workspaceDir: params.candidate.workspaceDir,
4433
3455
  rootDir: params.candidate.rootDir,
@@ -4658,34 +3680,27 @@ function parseDurationMs(raw, opts) {
4658
3680
  }
4659
3681
 
4660
3682
  //#endregion
4661
- //#region src/config/zod-schema.agent-model.ts
4662
- const AgentModelSchema = z.union([z.string(), z.object({
4663
- primary: z.string().optional(),
4664
- fallbacks: z.array(z.string()).optional()
4665
- }).strict()]);
4666
-
4667
- //#endregion
4668
- //#region src/config/zod-schema.allowdeny.ts
4669
- const AllowDenyActionSchema = z.union([z.literal("allow"), z.literal("deny")]);
4670
- const AllowDenyChatTypeSchema = z.union([
4671
- z.literal("direct"),
4672
- z.literal("group"),
4673
- z.literal("channel"),
4674
- z.literal("dm")
4675
- ]).optional();
4676
- function createAllowDenyChannelRulesSchema() {
4677
- return z.object({
4678
- default: AllowDenyActionSchema.optional(),
4679
- rules: z.array(z.object({
4680
- action: AllowDenyActionSchema,
4681
- match: z.object({
4682
- channel: z.string().optional(),
4683
- chatType: AllowDenyChatTypeSchema,
4684
- keyPrefix: z.string().optional(),
4685
- rawKeyPrefix: z.string().optional()
4686
- }).strict().optional()
4687
- }).strict()).optional()
4688
- }).strict().optional();
3683
+ //#region src/infra/safe-executable-value.ts
3684
+ const SHELL_METACHARS = /[;&|`$<>]/;
3685
+ const CONTROL_CHARS = /[\r\n]/;
3686
+ const QUOTE_CHARS = /["']/;
3687
+ const BARE_NAME_PATTERN = /^[A-Za-z0-9._+-]+$/;
3688
+ function isLikelyPath(value) {
3689
+ if (value.startsWith(".") || value.startsWith("~")) return true;
3690
+ if (value.includes("/") || value.includes("\\")) return true;
3691
+ return /^[A-Za-z]:[\\/]/.test(value);
3692
+ }
3693
+ function isSafeExecutableValue(value) {
3694
+ if (!value) return false;
3695
+ const trimmed = value.trim();
3696
+ if (!trimmed) return false;
3697
+ if (trimmed.includes("\0")) return false;
3698
+ if (CONTROL_CHARS.test(trimmed)) return false;
3699
+ if (SHELL_METACHARS.test(trimmed)) return false;
3700
+ if (QUOTE_CHARS.test(trimmed)) return false;
3701
+ if (isLikelyPath(trimmed)) return true;
3702
+ if (trimmed.startsWith("-")) return false;
3703
+ return BARE_NAME_PATTERN.test(trimmed);
4689
3704
  }
4690
3705
 
4691
3706
  //#endregion
@@ -4772,11 +3787,7 @@ const MarkdownTableModeSchema = z.enum([
4772
3787
  "code"
4773
3788
  ]);
4774
3789
  const MarkdownConfigSchema = z.object({ tables: MarkdownTableModeSchema.optional() }).strict().optional();
4775
- const TtsProviderSchema = z.enum([
4776
- "elevenlabs",
4777
- "openai",
4778
- "edge"
4779
- ]);
3790
+ const TtsProviderSchema = z.string().min(1);
4780
3791
  const TtsModeSchema = z.enum(["final", "all"]);
4781
3792
  const TtsAutoSchema = z.enum([
4782
3793
  "off",
@@ -4954,22 +3965,6 @@ const TranscribeAudioSchema = z.object({
4954
3965
  }).strict().optional();
4955
3966
  const HexColorSchema = z.string().regex(/^#?[0-9a-fA-F]{6}$/, "expected hex color (RRGGBB)");
4956
3967
  const ExecutableTokenSchema = z.string().refine(isSafeExecutableValue, "expected safe executable name or path");
4957
- const MediaUnderstandingScopeSchema = createAllowDenyChannelRulesSchema();
4958
- const MediaUnderstandingCapabilitiesSchema = z.array(z.union([
4959
- z.literal("image"),
4960
- z.literal("audio"),
4961
- z.literal("video")
4962
- ])).optional();
4963
- const MediaUnderstandingAttachmentsSchema = z.object({
4964
- mode: z.union([z.literal("first"), z.literal("all")]).optional(),
4965
- maxAttachments: z.number().int().positive().optional(),
4966
- prefer: z.union([
4967
- z.literal("first"),
4968
- z.literal("last"),
4969
- z.literal("path"),
4970
- z.literal("url")
4971
- ]).optional()
4972
- }).strict().optional();
4973
3968
  const DeepgramAudioSchema = z.object({
4974
3969
  detectLanguage: z.boolean().optional(),
4975
3970
  punctuate: z.boolean().optional(),
@@ -4993,7 +3988,6 @@ const MediaUnderstandingRuntimeFields = {
4993
3988
  const MediaUnderstandingModelSchema = z.object({
4994
3989
  provider: z.string().optional(),
4995
3990
  model: z.string().optional(),
4996
- capabilities: MediaUnderstandingCapabilitiesSchema,
4997
3991
  type: z.union([z.literal("provider"), z.literal("cli")]).optional(),
4998
3992
  command: z.string().optional(),
4999
3993
  args: z.array(z.string()).optional(),
@@ -5005,38 +3999,23 @@ const MediaUnderstandingModelSchema = z.object({
5005
3999
  }).strict().optional();
5006
4000
  const ToolsMediaUnderstandingSchema = z.object({
5007
4001
  enabled: z.boolean().optional(),
5008
- scope: MediaUnderstandingScopeSchema,
5009
4002
  maxBytes: z.number().int().positive().optional(),
5010
4003
  maxChars: z.number().int().positive().optional(),
5011
4004
  ...MediaUnderstandingRuntimeFields,
5012
- attachments: MediaUnderstandingAttachmentsSchema,
5013
4005
  models: z.array(MediaUnderstandingModelSchema).optional()
5014
4006
  }).strict().optional();
5015
- const ToolsMediaSchema = z.object({
5016
- models: z.array(MediaUnderstandingModelSchema).optional(),
5017
- concurrency: z.number().int().positive().optional(),
5018
- image: ToolsMediaUnderstandingSchema.optional(),
5019
- audio: ToolsMediaUnderstandingSchema.optional(),
5020
- video: ToolsMediaUnderstandingSchema.optional()
5021
- }).strict().optional();
5022
- const LinkModelSchema = z.object({
5023
- type: z.literal("cli").optional(),
5024
- command: z.string().min(1),
5025
- args: z.array(z.string()).optional(),
5026
- timeoutSeconds: z.number().int().positive().optional()
5027
- }).strict();
5028
- const ToolsLinksSchema = z.object({
5029
- enabled: z.boolean().optional(),
5030
- scope: MediaUnderstandingScopeSchema,
5031
- maxLinks: z.number().int().positive().optional(),
5032
- timeoutSeconds: z.number().int().positive().optional(),
5033
- models: z.array(LinkModelSchema).optional()
5034
- }).strict().optional();
4007
+ const ToolsMediaSchema = z.object({ audio: ToolsMediaUnderstandingSchema.optional() }).strict().optional();
5035
4008
  const NativeCommandsSettingSchema = z.union([z.boolean(), z.literal("auto")]);
5036
4009
  const ProviderCommandsSchema = z.object({ native: NativeCommandsSettingSchema.optional() }).strict().optional();
5037
4010
 
5038
4011
  //#endregion
5039
4012
  //#region src/config/zod-schema.agent-runtime.ts
4013
+ /** Auth profile ref: `false` (skip), single string, or string array (rotation). */
4014
+ const AuthFieldSchema = z.union([
4015
+ z.literal(false),
4016
+ z.string(),
4017
+ z.array(z.string())
4018
+ ]).optional();
5040
4019
  const BootSchema = z.object({
5041
4020
  prompt: z.string().optional(),
5042
4021
  file: z.string().optional()
@@ -5050,7 +4029,6 @@ const HeartbeatSchema = z.object({
5050
4029
  }).strict().optional(),
5051
4030
  model: z.string().optional(),
5052
4031
  session: z.string().optional(),
5053
- includeReasoning: z.boolean().optional(),
5054
4032
  target: z.string().optional(),
5055
4033
  to: z.string().optional(),
5056
4034
  accountId: z.string().optional(),
@@ -5131,7 +4109,6 @@ const ToolPolicyWithProfileSchema = z.object({
5131
4109
  }).strict().superRefine((value, ctx) => {
5132
4110
  addAllowAlsoAllowConflictIssue(value, ctx, "tools.byProvider policy cannot set both allow and alsoAllow in the same scope (merge alsoAllow into allow, or remove allow and use profile + alsoAllow)");
5133
4111
  });
5134
- const ElevatedAllowFromSchema = z.record(z.string(), z.array(z.union([z.string(), z.number()]))).optional();
5135
4112
  const ToolExecSafeBinProfileSchema = z.object({
5136
4113
  minPositional: z.number().int().nonnegative().optional(),
5137
4114
  maxPositional: z.number().int().nonnegative().optional(),
@@ -5180,10 +4157,6 @@ const CommonToolPolicyFields = {
5180
4157
  };
5181
4158
  const AgentToolsSchema = z.object({
5182
4159
  ...CommonToolPolicyFields,
5183
- elevated: z.object({
5184
- enabled: z.boolean().optional(),
5185
- allowFrom: ElevatedAllowFromSchema
5186
- }).strict().optional(),
5187
4160
  exec: AgentToolExecSchema,
5188
4161
  fs: ToolFsSchema
5189
4162
  }).strict().superRefine((value, ctx) => {
@@ -5195,7 +4168,7 @@ const AgentEntrySchema = z.object({
5195
4168
  name: z.string().optional(),
5196
4169
  workspace: z.string().optional(),
5197
4170
  agentDir: z.string().optional(),
5198
- model: AgentModelSchema.optional(),
4171
+ model: z.unknown().optional(),
5199
4172
  skills: z.array(z.string()).optional(),
5200
4173
  humanDelay: HumanDelaySchema.optional(),
5201
4174
  heartbeat: HeartbeatSchema,
@@ -5204,19 +4177,15 @@ const AgentEntrySchema = z.object({
5204
4177
  groupChat: GroupChatSchema,
5205
4178
  subagents: z.object({
5206
4179
  allowAgents: z.array(z.string()).optional(),
5207
- model: z.union([z.string(), z.object({
5208
- primary: z.string().optional(),
5209
- fallbacks: z.array(z.string()).optional()
5210
- }).strict()]).optional(),
5211
- thinking: z.string().optional()
4180
+ model: z.unknown().optional()
5212
4181
  }).strict().optional(),
5213
4182
  editableFiles: z.array(z.string()).optional(),
5214
- tools: AgentToolsSchema
4183
+ tools: AgentToolsSchema,
4184
+ auth: AuthFieldSchema
5215
4185
  }).strict();
5216
4186
  const ToolsSchema = z.object({
5217
4187
  ...CommonToolPolicyFields,
5218
4188
  media: ToolsMediaSchema,
5219
- links: ToolsLinksSchema,
5220
4189
  sessions: z.object({ visibility: z.enum([
5221
4190
  "self",
5222
4191
  "tree",
@@ -5240,10 +4209,6 @@ const ToolsSchema = z.object({
5240
4209
  enabled: z.boolean().optional(),
5241
4210
  allow: z.array(z.string()).optional()
5242
4211
  }).strict().optional(),
5243
- elevated: z.object({
5244
- enabled: z.boolean().optional(),
5245
- allowFrom: ElevatedAllowFromSchema
5246
- }).strict().optional(),
5247
4212
  exec: ToolExecSchema,
5248
4213
  fs: ToolFsSchema,
5249
4214
  subagents: z.object({ tools: ToolPolicySchema }).strict().optional()
@@ -5254,17 +4219,11 @@ const ToolsSchema = z.object({
5254
4219
  //#endregion
5255
4220
  //#region src/config/zod-schema.agent-defaults.ts
5256
4221
  const AgentDefaultsSchema = z.object({
5257
- model: AgentModelSchema.optional(),
5258
- imageModel: AgentModelSchema.optional(),
5259
- models: z.record(z.string(), z.object({
5260
- alias: z.string().optional(),
5261
- params: z.record(z.string(), z.unknown()).optional(),
5262
- streaming: z.boolean().optional()
5263
- }).strict()).optional(),
4222
+ model: z.unknown().optional(),
4223
+ imageModel: z.unknown().optional(),
4224
+ models: z.unknown().optional(),
4225
+ workspace: z.string().optional(),
5264
4226
  repoRoot: z.string().optional(),
5265
- skipBootstrap: z.boolean().optional(),
5266
- bootstrapMaxChars: z.number().int().positive().optional(),
5267
- bootstrapTotalMaxChars: z.number().int().positive().optional(),
5268
4227
  userTimezone: z.string().optional(),
5269
4228
  timeFormat: z.union([
5270
4229
  z.literal("auto"),
@@ -5275,7 +4234,7 @@ const AgentDefaultsSchema = z.object({
5275
4234
  envelopeTimestamp: z.union([z.literal("on"), z.literal("off")]).optional(),
5276
4235
  envelopeElapsed: z.union([z.literal("on"), z.literal("off")]).optional(),
5277
4236
  contextTokens: z.number().int().positive().optional(),
5278
- cliBackends: z.record(z.string(), CliBackendSchema).optional(),
4237
+ cliBackends: z.unknown().optional(),
5279
4238
  contextPruning: z.object({
5280
4239
  mode: z.union([z.literal("off"), z.literal("cache-ttl")]).optional(),
5281
4240
  ttl: z.string().optional(),
@@ -5297,32 +4256,11 @@ const AgentDefaultsSchema = z.object({
5297
4256
  placeholder: z.string().optional()
5298
4257
  }).strict().optional()
5299
4258
  }).strict().optional(),
5300
- compaction: z.object({
5301
- mode: z.union([z.literal("default"), z.literal("safeguard")]).optional(),
5302
- reserveTokens: z.number().int().nonnegative().optional(),
5303
- keepRecentTokens: z.number().int().positive().optional(),
5304
- reserveTokensFloor: z.number().int().nonnegative().optional(),
5305
- maxHistoryShare: z.number().min(.1).max(.9).optional()
5306
- }).strict().optional(),
5307
- thinkingDefault: z.union([
5308
- z.literal("off"),
5309
- z.literal("minimal"),
5310
- z.literal("low"),
5311
- z.literal("medium"),
5312
- z.literal("high"),
5313
- z.literal("xhigh")
5314
- ]).optional(),
5315
4259
  verboseDefault: z.union([
5316
4260
  z.literal("off"),
5317
4261
  z.literal("on"),
5318
4262
  z.literal("full")
5319
4263
  ]).optional(),
5320
- elevatedDefault: z.union([
5321
- z.literal("off"),
5322
- z.literal("on"),
5323
- z.literal("ask"),
5324
- z.literal("full")
5325
- ]).optional(),
5326
4264
  blockStreamingDefault: z.union([z.literal("off"), z.literal("on")]).optional(),
5327
4265
  blockStreamingBreak: z.union([z.literal("text_end"), z.literal("message_end")]).optional(),
5328
4266
  blockStreamingChunk: BlockStreamingChunkSchema.optional(),
@@ -5341,8 +4279,7 @@ const AgentDefaultsSchema = z.object({
5341
4279
  maxSpawnDepth: z.number().int().min(1).max(5).optional().describe("Maximum nesting depth for sub-agent spawning. 1 = no nesting (default), 2 = sub-agents can spawn sub-sub-agents."),
5342
4280
  maxChildrenPerAgent: z.number().int().min(1).max(20).optional().describe("Maximum number of active children a single agent session can spawn (default: 5)."),
5343
4281
  archiveAfterMinutes: z.number().int().positive().optional(),
5344
- model: AgentModelSchema.optional(),
5345
- thinking: z.string().optional(),
4282
+ model: z.unknown().optional(),
5346
4283
  runTimeoutSeconds: z.number().int().min(0).optional(),
5347
4284
  announceTimeoutMs: z.number().int().positive().optional()
5348
4285
  }).strict().optional(),
@@ -5353,7 +4290,10 @@ const AgentDefaultsSchema = z.object({
5353
4290
  z.literal("gemini"),
5354
4291
  z.literal("codex"),
5355
4292
  z.literal("opencode")
5356
- ]).optional()
4293
+ ]).optional(),
4294
+ runtimeArgs: z.array(z.string()).optional(),
4295
+ runtimeEnv: z.record(z.string(), z.string()).optional(),
4296
+ auth: AuthFieldSchema
5357
4297
  }).strict().optional();
5358
4298
 
5359
4299
  //#endregion
@@ -5601,6 +4541,65 @@ function isValidInboundPathRootPattern(value) {
5601
4541
  return segments.every((segment) => segment === WILDCARD_SEGMENT || !segment.includes("*"));
5602
4542
  }
5603
4543
 
4544
+ //#endregion
4545
+ //#region src/config/discord-preview-streaming.ts
4546
+ function normalizeStreamingMode(value) {
4547
+ if (typeof value !== "string") return null;
4548
+ return value.trim().toLowerCase() || null;
4549
+ }
4550
+ function parseStreamingMode(value) {
4551
+ const normalized = normalizeStreamingMode(value);
4552
+ if (normalized === "off" || normalized === "partial" || normalized === "block" || normalized === "progress") return normalized;
4553
+ return null;
4554
+ }
4555
+ function parseDiscordPreviewStreamMode(value) {
4556
+ const parsed = parseStreamingMode(value);
4557
+ if (!parsed) return null;
4558
+ return parsed === "progress" ? "partial" : parsed;
4559
+ }
4560
+ function parseSlackLegacyDraftStreamMode(value) {
4561
+ const normalized = normalizeStreamingMode(value);
4562
+ if (normalized === "replace" || normalized === "status_final" || normalized === "append") return normalized;
4563
+ return null;
4564
+ }
4565
+ function mapSlackLegacyDraftStreamModeToStreaming(mode) {
4566
+ if (mode === "append") return "block";
4567
+ if (mode === "status_final") return "progress";
4568
+ return "partial";
4569
+ }
4570
+ function resolveTelegramPreviewStreamMode(params = {}) {
4571
+ const parsedStreaming = parseStreamingMode(params.streaming);
4572
+ if (parsedStreaming) {
4573
+ if (parsedStreaming === "progress") return "partial";
4574
+ return parsedStreaming;
4575
+ }
4576
+ const legacy = parseDiscordPreviewStreamMode(params.streamMode);
4577
+ if (legacy) return legacy;
4578
+ if (typeof params.streaming === "boolean") return params.streaming ? "partial" : "off";
4579
+ return "off";
4580
+ }
4581
+ function resolveDiscordPreviewStreamMode(params = {}) {
4582
+ const parsedStreaming = parseDiscordPreviewStreamMode(params.streaming);
4583
+ if (parsedStreaming) return parsedStreaming;
4584
+ const legacy = parseDiscordPreviewStreamMode(params.streamMode);
4585
+ if (legacy) return legacy;
4586
+ if (typeof params.streaming === "boolean") return params.streaming ? "partial" : "off";
4587
+ return "off";
4588
+ }
4589
+ function resolveSlackStreamingMode(params = {}) {
4590
+ const parsedStreaming = parseStreamingMode(params.streaming);
4591
+ if (parsedStreaming) return parsedStreaming;
4592
+ const legacyStreamMode = parseSlackLegacyDraftStreamMode(params.streamMode);
4593
+ if (legacyStreamMode) return mapSlackLegacyDraftStreamModeToStreaming(legacyStreamMode);
4594
+ if (typeof params.streaming === "boolean") return "partial";
4595
+ return "partial";
4596
+ }
4597
+ function resolveSlackNativeStreaming(params = {}) {
4598
+ if (typeof params.nativeStreaming === "boolean") return params.nativeStreaming;
4599
+ if (typeof params.streaming === "boolean") return params.streaming;
4600
+ return true;
4601
+ }
4602
+
5604
4603
  //#endregion
5605
4604
  //#region src/config/telegram-custom-commands.ts
5606
4605
  const TELEGRAM_COMMAND_NAME_PATTERN = /^[a-z0-9_]{1,32}$/;
@@ -6669,6 +5668,30 @@ const ChannelsSchema = z.object({
6669
5668
  msteams: MSTeamsConfigSchema.optional()
6670
5669
  }).passthrough().optional();
6671
5670
 
5671
+ //#endregion
5672
+ //#region src/config/zod-schema.allowdeny.ts
5673
+ const AllowDenyActionSchema = z.union([z.literal("allow"), z.literal("deny")]);
5674
+ const AllowDenyChatTypeSchema = z.union([
5675
+ z.literal("direct"),
5676
+ z.literal("group"),
5677
+ z.literal("channel"),
5678
+ z.literal("dm")
5679
+ ]).optional();
5680
+ function createAllowDenyChannelRulesSchema() {
5681
+ return z.object({
5682
+ default: AllowDenyActionSchema.optional(),
5683
+ rules: z.array(z.object({
5684
+ action: AllowDenyActionSchema,
5685
+ match: z.object({
5686
+ channel: z.string().optional(),
5687
+ chatType: AllowDenyChatTypeSchema,
5688
+ keyPrefix: z.string().optional(),
5689
+ rawKeyPrefix: z.string().optional()
5690
+ }).strict().optional()
5691
+ }).strict()).optional()
5692
+ }).strict().optional();
5693
+ }
5694
+
6672
5695
  //#endregion
6673
5696
  //#region src/config/zod-schema.session.ts
6674
5697
  const SessionResetConfigSchema = z.object({
@@ -6807,8 +5830,6 @@ const MessagesSchema = z.object({
6807
5830
  const CommandsSchema = z.object({
6808
5831
  native: NativeCommandsSettingSchema.optional().default("auto"),
6809
5832
  text: z.boolean().optional(),
6810
- bash: z.boolean().optional(),
6811
- bashForegroundMs: z.number().int().min(0).max(3e4).optional(),
6812
5833
  config: z.boolean().optional(),
6813
5834
  debug: z.boolean().optional(),
6814
5835
  restart: z.boolean().optional().default(true),
@@ -6816,7 +5837,7 @@ const CommandsSchema = z.object({
6816
5837
  ownerAllowFrom: z.array(z.union([z.string(), z.number()])).optional(),
6817
5838
  ownerDisplay: z.enum(["raw", "hash"]).optional().default("raw"),
6818
5839
  ownerDisplaySecret: z.string().optional().register(sensitive),
6819
- allowFrom: ElevatedAllowFromSchema.optional()
5840
+ allowFrom: z.record(z.string(), z.array(z.union([z.string(), z.number()]))).optional()
6820
5841
  }).strict().optional().default(() => ({
6821
5842
  native: "auto",
6822
5843
  restart: true,
@@ -6913,7 +5934,7 @@ const RemoteClawSchema = z.object({
6913
5934
  channel: z.union([
6914
5935
  z.literal("stable"),
6915
5936
  z.literal("beta"),
6916
- z.literal("dev")
5937
+ z.literal("next")
6917
5938
  ]).optional(),
6918
5939
  checkOnStart: z.boolean().optional(),
6919
5940
  auto: z.object({
@@ -7270,7 +6291,8 @@ function validateIdentityAvatar(config) {
7270
6291
  });
7271
6292
  continue;
7272
6293
  }
7273
- if (!isWorkspaceAvatarPath(avatar, resolveAgentWorkspaceDir(config, entry.id ?? resolveDefaultAgentId(config)))) issues.push({
6294
+ const workspaceDir = resolveAgentWorkspaceDirOrNull(config, entry.id ?? resolveDefaultAgentId(config));
6295
+ if (workspaceDir != null && !isWorkspaceAvatarPath(avatar, workspaceDir)) issues.push({
7274
6296
  path: `agents.list.${index}.identity.avatar`,
7275
6297
  message: "identity.avatar must stay within the agent workspace."
7276
6298
  });
@@ -7346,7 +6368,7 @@ function validateConfigObjectWithPluginsBase(raw, opts) {
7346
6368
  if (registryInfo) return registryInfo;
7347
6369
  const registry = loadPluginManifestRegistry({
7348
6370
  config,
7349
- workspaceDir: resolveAgentWorkspaceDir(config, resolveDefaultAgentId(config)) ?? void 0
6371
+ workspaceDir: resolveAgentWorkspaceDirOrNull(config, resolveDefaultAgentId(config)) ?? void 0
7350
6372
  });
7351
6373
  const knownIds = new Set(registry.plugins.map((record) => record.id));
7352
6374
  const normalizedPlugins = normalizePluginsConfig(config.plugins);
@@ -7949,7 +6971,7 @@ function createConfigIO(overrides = {}) {
7949
6971
  deps.logger.warn(`Config warnings:\\n${details}`);
7950
6972
  }
7951
6973
  warnIfConfigFromFuture(validated.config, deps.logger);
7952
- const cfg = applyTalkConfigNormalization(applyModelDefaults(applyCompactionDefaults(applyContextPruningDefaults(applyAgentDefaults(applySessionDefaults(applyLoggingDefaults(applyMessageDefaults(validated.config))))))));
6974
+ const cfg = applyTalkConfigNormalization(applyModelDefaults(applyContextPruningDefaults(applyAgentDefaults(applySessionDefaults(applyLoggingDefaults(applyMessageDefaults(validated.config)))))));
7953
6975
  normalizeConfigPaths(cfg);
7954
6976
  const duplicates = findDuplicateAgentDirs(cfg, {
7955
6977
  env: deps.env,
@@ -8009,7 +7031,7 @@ function createConfigIO(overrides = {}) {
8009
7031
  parsed: {},
8010
7032
  resolved: {},
8011
7033
  valid: true,
8012
- config: applyTalkApiKey(applyTalkConfigNormalization(applyModelDefaults(applyCompactionDefaults(applyContextPruningDefaults(applyAgentDefaults(applySessionDefaults(applyMessageDefaults({})))))))),
7034
+ config: applyTalkApiKey(applyTalkConfigNormalization(applyModelDefaults(applyContextPruningDefaults(applyAgentDefaults(applySessionDefaults(applyMessageDefaults({}))))))),
8013
7035
  hash,
8014
7036
  issues: [],
8015
7037
  warnings: [],
@@ -9363,22 +8385,6 @@ function loadSessionStore(storePath, opts = {}) {
9363
8385
  continue;
9364
8386
  }
9365
8387
  }
9366
- for (const entry of Object.values(store)) {
9367
- if (!entry || typeof entry !== "object") continue;
9368
- const rec = entry;
9369
- if (typeof rec.channel !== "string" && typeof rec.provider === "string") {
9370
- rec.channel = rec.provider;
9371
- delete rec.provider;
9372
- }
9373
- if (typeof rec.lastChannel !== "string" && typeof rec.lastProvider === "string") {
9374
- rec.lastChannel = rec.lastProvider;
9375
- delete rec.lastProvider;
9376
- }
9377
- if (typeof rec.groupChannel !== "string" && typeof rec.room === "string") {
9378
- rec.groupChannel = rec.room;
9379
- delete rec.room;
9380
- } else if ("room" in rec) delete rec.room;
9381
- }
9382
8388
  if (!opts.skipCache && isSessionStoreCacheEnabled()) SESSION_STORE_CACHE.set(storePath, {
9383
8389
  store: structuredClone(store),
9384
8390
  loadedAt: Date.now(),
@@ -9789,273 +8795,1160 @@ async function drainSessionStoreLockQueue(storePath) {
9789
8795
  drainSessionStoreLockQueue(storePath);
9790
8796
  });
9791
8797
  }
9792
- }
9793
- async function withSessionStoreLock(storePath, fn, opts = {}) {
9794
- if (!storePath || typeof storePath !== "string") throw new Error(`withSessionStoreLock: storePath must be a non-empty string, got ${JSON.stringify(storePath)}`);
9795
- const timeoutMs = opts.timeoutMs ?? 1e4;
9796
- const staleMs = opts.staleMs ?? 3e4;
9797
- opts.pollIntervalMs;
9798
- const hasTimeout = timeoutMs > 0 && Number.isFinite(timeoutMs);
9799
- const queue = getOrCreateLockQueue(storePath);
9800
- return await new Promise((resolve, reject) => {
9801
- const task = {
9802
- fn: async () => await fn(),
9803
- resolve: (value) => resolve(value),
9804
- reject,
9805
- timeoutMs: hasTimeout ? timeoutMs : void 0,
9806
- staleMs
8798
+ }
8799
+ async function withSessionStoreLock(storePath, fn, opts = {}) {
8800
+ if (!storePath || typeof storePath !== "string") throw new Error(`withSessionStoreLock: storePath must be a non-empty string, got ${JSON.stringify(storePath)}`);
8801
+ const timeoutMs = opts.timeoutMs ?? 1e4;
8802
+ const staleMs = opts.staleMs ?? 3e4;
8803
+ opts.pollIntervalMs;
8804
+ const hasTimeout = timeoutMs > 0 && Number.isFinite(timeoutMs);
8805
+ const queue = getOrCreateLockQueue(storePath);
8806
+ return await new Promise((resolve, reject) => {
8807
+ const task = {
8808
+ fn: async () => await fn(),
8809
+ resolve: (value) => resolve(value),
8810
+ reject,
8811
+ timeoutMs: hasTimeout ? timeoutMs : void 0,
8812
+ staleMs
8813
+ };
8814
+ queue.pending.push(task);
8815
+ drainSessionStoreLockQueue(storePath);
8816
+ });
8817
+ }
8818
+
8819
+ //#endregion
8820
+ //#region src/logger.ts
8821
+ const subsystemPrefixRe = /^([a-z][a-z0-9-]{1,20}):\s+(.*)$/i;
8822
+ function splitSubsystem(message) {
8823
+ const match = message.match(subsystemPrefixRe);
8824
+ if (!match) return null;
8825
+ const [, subsystem, rest] = match;
8826
+ return {
8827
+ subsystem,
8828
+ rest
8829
+ };
8830
+ }
8831
+ function logWarn(message, runtime = defaultRuntime) {
8832
+ const parsed = runtime === defaultRuntime ? splitSubsystem(message) : null;
8833
+ if (parsed) {
8834
+ createSubsystemLogger(parsed.subsystem).warn(parsed.rest);
8835
+ return;
8836
+ }
8837
+ runtime.log(warn(message));
8838
+ getLogger().warn(message);
8839
+ }
8840
+ function logDebug(message) {
8841
+ getLogger().debug(message);
8842
+ logVerboseConsole(message);
8843
+ }
8844
+
8845
+ //#endregion
8846
+ //#region src/plugins/hook-runner-global.ts
8847
+ /**
8848
+ * Global Plugin Hook Runner
8849
+ *
8850
+ * Singleton hook runner that's initialized when plugins are loaded
8851
+ * and can be called from anywhere in the codebase.
8852
+ */
8853
+ const log = createSubsystemLogger("plugins");
8854
+ let globalHookRunner = null;
8855
+ /**
8856
+ * Get the global hook runner.
8857
+ * Returns null if plugins haven't been loaded yet.
8858
+ */
8859
+ function getGlobalHookRunner() {
8860
+ return globalHookRunner;
8861
+ }
8862
+
8863
+ //#endregion
8864
+ //#region src/middleware/delivery-adapter.ts
8865
+ const DEFAULT_CHUNK_LIMIT = 4e3;
8866
+ /**
8867
+ * Converts AgentEvent async iterable into channel-deliverable ReplyPayload chunks.
8868
+ *
8869
+ * Handles:
8870
+ * - Text accumulation and chunking at channel limits
8871
+ * - Progressive streaming via BridgeCallbacks
8872
+ * - Tool result formatting
8873
+ * - Error event formatting
8874
+ */
8875
+ var DeliveryAdapter = class {
8876
+ constructor(options) {
8877
+ this.chunkLimit = options?.chunkLimit ?? DEFAULT_CHUNK_LIMIT;
8878
+ }
8879
+ /**
8880
+ * Process an event stream, invoking callbacks for real-time delivery
8881
+ * and returning final payloads for post-execution delivery.
8882
+ *
8883
+ * @param events - AgentEvent async iterable from runtime.execute()
8884
+ * @param callbacks - Optional streaming callbacks for real-time delivery
8885
+ * @returns Final ReplyPayload array for post-execution delivery
8886
+ */
8887
+ async process(events, callbacks) {
8888
+ let textBuffer = "";
8889
+ const payloads = [];
8890
+ /** Track media delivered via streaming events to avoid duplicates from result.media. */
8891
+ const deliveredMediaKeys = /* @__PURE__ */ new Set();
8892
+ let eventCount = 0;
8893
+ for await (const event of events) {
8894
+ eventCount++;
8895
+ switch (event.type) {
8896
+ case "text":
8897
+ if (event.text === "") break;
8898
+ textBuffer += event.text;
8899
+ while (textBuffer.length > this.chunkLimit) {
8900
+ const { chunk, rest } = splitAtBoundary(textBuffer, this.chunkLimit);
8901
+ textBuffer = rest;
8902
+ const payload = { text: chunk };
8903
+ payloads.push(payload);
8904
+ await callbacks?.onPartialReply?.(payload);
8905
+ }
8906
+ break;
8907
+ case "media": {
8908
+ const mediaUrl = event.media.filePath ?? event.media.sourceUrl;
8909
+ if (mediaUrl) {
8910
+ if (textBuffer.length > 0) {
8911
+ const textPayload = { text: textBuffer };
8912
+ payloads.push(textPayload);
8913
+ await callbacks?.onBlockReply?.(textPayload);
8914
+ textBuffer = "";
8915
+ }
8916
+ deliveredMediaKeys.add(mediaUrl);
8917
+ const payload = { mediaUrl };
8918
+ payloads.push(payload);
8919
+ await callbacks?.onBlockReply?.(payload);
8920
+ }
8921
+ break;
8922
+ }
8923
+ case "thinking":
8924
+ if (event.text) callbacks?.onThinking?.({ text: event.text });
8925
+ break;
8926
+ case "tool_use": break;
8927
+ case "tool_result": {
8928
+ const payload = { text: formatToolResult(event.toolId, event.output, event.isError) };
8929
+ await callbacks?.onToolResult?.(payload);
8930
+ break;
8931
+ }
8932
+ case "error": {
8933
+ const payload = {
8934
+ text: event.code ? `[${event.code}] ${event.message}` : event.message,
8935
+ isError: true
8936
+ };
8937
+ payloads.push(payload);
8938
+ await callbacks?.onBlockReply?.(payload);
8939
+ break;
8940
+ }
8941
+ case "done":
8942
+ if (textBuffer.length > 0) {
8943
+ const payload = { text: textBuffer };
8944
+ payloads.push(payload);
8945
+ await callbacks?.onBlockReply?.(payload);
8946
+ textBuffer = "";
8947
+ }
8948
+ if (event.result.media?.length) for (const media of event.result.media) {
8949
+ const url = media.filePath ?? media.sourceUrl;
8950
+ if (url && !deliveredMediaKeys.has(url)) {
8951
+ const payload = { mediaUrl: url };
8952
+ payloads.push(payload);
8953
+ await callbacks?.onBlockReply?.(payload);
8954
+ }
8955
+ }
8956
+ break;
8957
+ }
8958
+ }
8959
+ if (textBuffer.length > 0) {
8960
+ const payload = { text: textBuffer };
8961
+ payloads.push(payload);
8962
+ }
8963
+ logDebug(`[delivery-adapter] processed ${eventCount} events into ${payloads.length} payloads (chunkLimit=${this.chunkLimit})`);
8964
+ return payloads;
8965
+ }
8966
+ };
8967
+ /** Format a tool result for display. */
8968
+ function formatToolResult(toolId, output, isError) {
8969
+ return `${isError ? `Tool ${toolId} error` : `Tool ${toolId} result`}: ${output}`;
8970
+ }
8971
+ /**
8972
+ * Split text at the nearest safe boundary before the limit.
8973
+ *
8974
+ * Preference order:
8975
+ * 1. Paragraph break (\n\n)
8976
+ * 2. Line break (\n)
8977
+ * 3. Word boundary (space)
8978
+ * 4. Hard split at limit
8979
+ *
8980
+ * Markdown-aware: preserves code fence boundaries by closing/reopening
8981
+ * fences at split points when a split occurs inside a fenced code block.
8982
+ */
8983
+ function splitAtBoundary(text, limit) {
8984
+ const fenceInfo = findOpenCodeFence(text, limit);
8985
+ if (fenceInfo !== void 0) {
8986
+ const beforeFence = text.substring(0, fenceInfo.fenceStart);
8987
+ if (beforeFence.trimEnd().length > 0) {
8988
+ const trimmed = beforeFence.trimEnd();
8989
+ return {
8990
+ chunk: trimmed,
8991
+ rest: text.substring(trimmed.length).trimStart()
8992
+ };
8993
+ }
8994
+ const closingFence = `\n${fenceInfo.fence}`;
8995
+ const openingFence = `${fenceInfo.fence}\n`;
8996
+ const splitPoint = findSplitPoint(text, limit - closingFence.length);
8997
+ return {
8998
+ chunk: text.substring(0, splitPoint) + closingFence,
8999
+ rest: openingFence + text.substring(splitPoint)
9000
+ };
9001
+ }
9002
+ const splitPoint = findSplitPoint(text, limit);
9003
+ return {
9004
+ chunk: text.substring(0, splitPoint),
9005
+ rest: text.substring(splitPoint)
9006
+ };
9007
+ }
9008
+ /** Find the best split point within the text up to the given limit. */
9009
+ function findSplitPoint(text, limit) {
9010
+ if (limit <= 0) return Math.min(1, text.length);
9011
+ const searchRegion = text.substring(0, limit);
9012
+ const paragraphIdx = searchRegion.lastIndexOf("\n\n");
9013
+ if (paragraphIdx > 0) return paragraphIdx + 2;
9014
+ const lineIdx = searchRegion.lastIndexOf("\n");
9015
+ if (lineIdx > 0) return lineIdx + 1;
9016
+ const spaceIdx = searchRegion.lastIndexOf(" ");
9017
+ if (spaceIdx > 0) return spaceIdx + 1;
9018
+ return limit;
9019
+ }
9020
+ /**
9021
+ * Detect if the text has an unclosed code fence at or before the limit position.
9022
+ * Returns info about the open fence, or undefined if no open fence.
9023
+ */
9024
+ function findOpenCodeFence(text, limit) {
9025
+ const fenceRegex = /^(`{3,}|~{3,})/gm;
9026
+ let openFence;
9027
+ let match;
9028
+ while ((match = fenceRegex.exec(text)) !== null) {
9029
+ if (match.index >= limit) break;
9030
+ if (openFence === void 0) openFence = {
9031
+ fenceStart: match.index,
9032
+ fence: match[1]
9033
+ };
9034
+ else if (match[1].charAt(0) === openFence.fence.charAt(0) && match[1].length >= openFence.fence.length) openFence = void 0;
9035
+ }
9036
+ return openFence;
9037
+ }
9038
+
9039
+ //#endregion
9040
+ //#region src/middleware/error-classifier.ts
9041
+ const retryablePatterns = [
9042
+ /rate.?limit/i,
9043
+ /429/i,
9044
+ /503/i,
9045
+ /overloaded/i,
9046
+ /ETIMEDOUT/i,
9047
+ /ECONNRESET/i,
9048
+ /ECONNREFUSED/i,
9049
+ /network/i
9050
+ ];
9051
+ const contextOverflowPatterns = [
9052
+ /context.?length/i,
9053
+ /context.?window/i,
9054
+ /context.?overflow/i,
9055
+ /too many tokens/i,
9056
+ /maximum context/i,
9057
+ /token.?limit/i
9058
+ ];
9059
+ const fatalAuthPatterns = [
9060
+ /401/i,
9061
+ /403/i,
9062
+ /unauthorized/i,
9063
+ /forbidden/i,
9064
+ /invalid.?key/i,
9065
+ /authentication/i
9066
+ ];
9067
+ /**
9068
+ * Classify an error message string into an actionable category.
9069
+ *
9070
+ * Uses first-match-wins semantics across ordered pattern arrays:
9071
+ * 1. Retryable patterns checked first
9072
+ * 2. Context overflow patterns checked second
9073
+ * 3. Fatal auth patterns checked third
9074
+ * 4. Default: "fatal" for unmatched messages
9075
+ *
9076
+ * Case-insensitive matching throughout.
9077
+ */
9078
+ function classifyError(message) {
9079
+ for (const pattern of retryablePatterns) if (pattern.test(message)) {
9080
+ logDebug(`[error-classifier] classified as retryable: ${message.slice(0, 200)}`);
9081
+ return "retryable";
9082
+ }
9083
+ for (const pattern of contextOverflowPatterns) if (pattern.test(message)) {
9084
+ logDebug(`[error-classifier] classified as context_overflow: ${message.slice(0, 200)}`);
9085
+ return "context_overflow";
9086
+ }
9087
+ for (const pattern of fatalAuthPatterns) if (pattern.test(message)) {
9088
+ logDebug(`[error-classifier] classified as fatal (auth): ${message.slice(0, 200)}`);
9089
+ return "fatal";
9090
+ }
9091
+ logDebug(`[error-classifier] classified as fatal (unmatched): ${message.slice(0, 200)}`);
9092
+ return "fatal";
9093
+ }
9094
+
9095
+ //#endregion
9096
+ //#region src/middleware/mcp-side-effects.ts
9097
+ async function readMcpSideEffects(filePath) {
9098
+ const result = {
9099
+ sentTexts: [],
9100
+ sentMediaUrls: [],
9101
+ sentTargets: [],
9102
+ cronAdds: 0
9103
+ };
9104
+ let content;
9105
+ try {
9106
+ content = await readFile(filePath, "utf-8");
9107
+ } catch {
9108
+ return result;
9109
+ }
9110
+ const lines = content.split("\n").filter(Boolean);
9111
+ for (const line of lines) {
9112
+ let record;
9113
+ try {
9114
+ record = JSON.parse(line);
9115
+ } catch {
9116
+ continue;
9117
+ }
9118
+ if (record.type === "message_sent") {
9119
+ result.sentTexts.push(record.text);
9120
+ if (record.mediaUrl) result.sentMediaUrls.push(record.mediaUrl);
9121
+ const target = {
9122
+ tool: record.tool,
9123
+ provider: record.provider,
9124
+ ...record.accountId ? { accountId: record.accountId } : {},
9125
+ ...record.to ? { to: record.to } : {}
9126
+ };
9127
+ result.sentTargets.push(target);
9128
+ } else if (record.type === "cron_added") result.cronAdds += 1;
9129
+ else if (record.type === "heartbeat_report") result.heartbeatReport = {
9130
+ anythingDone: record.anythingDone,
9131
+ summary: record.summary
9807
9132
  };
9808
- queue.pending.push(task);
9809
- drainSessionStoreLockQueue(storePath);
9810
- });
9133
+ }
9134
+ return result;
9811
9135
  }
9812
9136
 
9813
9137
  //#endregion
9814
- //#region src/plugins/hook-runner-global.ts
9138
+ //#region src/middleware/media-capability.ts
9815
9139
  /**
9816
- * Global Plugin Hook Runner
9140
+ * Partition media attachments by whether the runtime accepts them.
9817
9141
  *
9818
- * Singleton hook runner that's initialized when plugins are loaded
9819
- * and can be called from anywhere in the codebase.
9142
+ * If the runtime does not declare `mediaCapabilities` at all, all media is
9143
+ * treated as supported (backwards-compatible — the runtime decides what to do).
9820
9144
  */
9821
- const log = createSubsystemLogger("plugins");
9822
- let globalHookRunner = null;
9145
+ function partitionMedia(runtime, media) {
9146
+ const prefixes = runtime.mediaCapabilities?.acceptsInbound;
9147
+ if (prefixes === void 0) return {
9148
+ supported: media,
9149
+ unsupported: []
9150
+ };
9151
+ const supported = [];
9152
+ const unsupported = [];
9153
+ for (const attachment of media) if (prefixes.some((prefix) => attachment.mimeType.startsWith(prefix))) supported.push(attachment);
9154
+ else unsupported.push(attachment);
9155
+ return {
9156
+ supported,
9157
+ unsupported
9158
+ };
9159
+ }
9823
9160
  /**
9824
- * Get the global hook runner.
9825
- * Returns null if plugins haven't been loaded yet.
9161
+ * Format a user-facing warning for media the runtime cannot handle.
9162
+ *
9163
+ * Returns `undefined` when there are no unsupported attachments.
9826
9164
  */
9827
- function getGlobalHookRunner() {
9828
- return globalHookRunner;
9165
+ function formatUnsupportedMediaWarning(unsupported, runtimeName) {
9166
+ if (unsupported.length === 0) return;
9167
+ const typeSummary = summarizeMediaTypes(unsupported);
9168
+ const runtimeLabel = runtimeName.toLowerCase();
9169
+ if (unsupported.length === 1) return `\u26a0\ufe0f Your ${typeSummary} was received but the current runtime (${runtimeLabel}) doesn't support ${typeSummary} input. Its content was not included in the conversation.`;
9170
+ return `\u26a0\ufe0f ${unsupported.length} media attachments were received but the current runtime (${runtimeLabel}) doesn't support them: ${typeSummary}. Their content was not included in the conversation.`;
9829
9171
  }
9830
-
9831
- //#endregion
9832
- //#region src/middleware/delivery-adapter.ts
9833
- const DEFAULT_CHUNK_LIMIT = 4e3;
9834
9172
  /**
9835
- * Converts AgentEvent async iterable into channel-deliverable ReplyPayload chunks.
9173
+ * Produce a human-readable summary of MIME type categories.
9836
9174
  *
9837
- * Handles:
9838
- * - Text accumulation and chunking at channel limits
9839
- * - Progressive streaming via BridgeCallbacks
9840
- * - Tool result formatting
9841
- * - Error event formatting
9175
+ * Groups by top-level type (image, audio, video) and deduplicates.
9176
+ * Falls back to "media" for unknown types.
9842
9177
  */
9843
- var DeliveryAdapter = class {
9844
- constructor(options) {
9845
- this.chunkLimit = options?.chunkLimit ?? DEFAULT_CHUNK_LIMIT;
9178
+ function summarizeMediaTypes(attachments) {
9179
+ const categories = /* @__PURE__ */ new Set();
9180
+ for (const a of attachments) switch (a.mimeType.split("/")[0]) {
9181
+ case "image":
9182
+ categories.add("image");
9183
+ break;
9184
+ case "audio":
9185
+ categories.add("audio");
9186
+ break;
9187
+ case "video":
9188
+ categories.add("video");
9189
+ break;
9190
+ default:
9191
+ categories.add("media");
9192
+ break;
9193
+ }
9194
+ return [...categories].toSorted().join("/");
9195
+ }
9196
+
9197
+ //#endregion
9198
+ //#region src/utils/fetch-timeout.ts
9199
+ /**
9200
+ * Relay abort without forwarding the Event argument as the abort reason.
9201
+ * Using .bind() avoids closure scope capture (memory leak prevention).
9202
+ */
9203
+ function relayAbort() {
9204
+ this.abort();
9205
+ }
9206
+ /** Returns a bound abort relay for use as an event listener. */
9207
+ function bindAbortRelay(controller) {
9208
+ return relayAbort.bind(controller);
9209
+ }
9210
+
9211
+ //#endregion
9212
+ //#region src/shared/net/ip.ts
9213
+ const BLOCKED_IPV4_SPECIAL_USE_RANGES = new Set([
9214
+ "unspecified",
9215
+ "broadcast",
9216
+ "multicast",
9217
+ "linkLocal",
9218
+ "loopback",
9219
+ "carrierGradeNat",
9220
+ "private",
9221
+ "reserved"
9222
+ ]);
9223
+ const PRIVATE_OR_LOOPBACK_IPV4_RANGES = new Set([
9224
+ "loopback",
9225
+ "private",
9226
+ "linkLocal",
9227
+ "carrierGradeNat"
9228
+ ]);
9229
+ const PRIVATE_OR_LOOPBACK_IPV6_RANGES = new Set([
9230
+ "unspecified",
9231
+ "loopback",
9232
+ "linkLocal",
9233
+ "uniqueLocal"
9234
+ ]);
9235
+ const RFC2544_BENCHMARK_PREFIX = [ipaddr.IPv4.parse("198.18.0.0"), 15];
9236
+ const EMBEDDED_IPV4_SENTINEL_RULES = [
9237
+ {
9238
+ matches: (parts) => parts[0] === 0 && parts[1] === 0 && parts[2] === 0 && parts[3] === 0 && parts[4] === 0 && parts[5] === 0,
9239
+ toHextets: (parts) => [parts[6], parts[7]]
9240
+ },
9241
+ {
9242
+ matches: (parts) => parts[0] === 100 && parts[1] === 65435 && parts[2] === 1 && parts[3] === 0 && parts[4] === 0 && parts[5] === 0,
9243
+ toHextets: (parts) => [parts[6], parts[7]]
9244
+ },
9245
+ {
9246
+ matches: (parts) => parts[0] === 8194,
9247
+ toHextets: (parts) => [parts[1], parts[2]]
9248
+ },
9249
+ {
9250
+ matches: (parts) => parts[0] === 8193 && parts[1] === 0,
9251
+ toHextets: (parts) => [parts[6] ^ 65535, parts[7] ^ 65535]
9252
+ },
9253
+ {
9254
+ matches: (parts) => (parts[4] & 64767) === 0 && parts[5] === 24318,
9255
+ toHextets: (parts) => [parts[6], parts[7]]
9846
9256
  }
9847
- /**
9848
- * Process an event stream, invoking callbacks for real-time delivery
9849
- * and returning final payloads for post-execution delivery.
9850
- *
9851
- * @param events - AgentEvent async iterable from runtime.execute()
9852
- * @param callbacks - Optional streaming callbacks for real-time delivery
9853
- * @returns Final ReplyPayload array for post-execution delivery
9854
- */
9855
- async process(events, callbacks) {
9856
- let textBuffer = "";
9857
- const payloads = [];
9858
- for await (const event of events) switch (event.type) {
9859
- case "text":
9860
- if (event.text === "") break;
9861
- textBuffer += event.text;
9862
- while (textBuffer.length > this.chunkLimit) {
9863
- const { chunk, rest } = splitAtBoundary(textBuffer, this.chunkLimit);
9864
- textBuffer = rest;
9865
- const payload = { text: chunk };
9866
- payloads.push(payload);
9867
- await callbacks?.onPartialReply?.(payload);
9868
- }
9869
- break;
9870
- case "tool_use": break;
9871
- case "tool_result": {
9872
- const payload = { text: formatToolResult(event.toolId, event.output, event.isError) };
9873
- await callbacks?.onToolResult?.(payload);
9874
- break;
9875
- }
9876
- case "error": {
9877
- const payload = {
9878
- text: event.code ? `[${event.code}] ${event.message}` : event.message,
9879
- isError: true
9880
- };
9881
- payloads.push(payload);
9882
- await callbacks?.onBlockReply?.(payload);
9883
- break;
9884
- }
9885
- case "done":
9886
- if (textBuffer.length > 0) {
9887
- const payload = { text: textBuffer };
9888
- payloads.push(payload);
9889
- await callbacks?.onBlockReply?.(payload);
9890
- textBuffer = "";
9891
- }
9892
- break;
9893
- }
9894
- if (textBuffer.length > 0) {
9895
- const payload = { text: textBuffer };
9896
- payloads.push(payload);
9897
- }
9898
- return payloads;
9257
+ ];
9258
+ function stripIpv6Brackets(value) {
9259
+ if (value.startsWith("[") && value.endsWith("]")) return value.slice(1, -1);
9260
+ return value;
9261
+ }
9262
+ function isNumericIpv4LiteralPart(value) {
9263
+ return /^[0-9]+$/.test(value) || /^0x[0-9a-f]+$/i.test(value);
9264
+ }
9265
+ function parseIpv6WithEmbeddedIpv4(raw) {
9266
+ if (!raw.includes(":") || !raw.includes(".")) return;
9267
+ const match = /^(.*:)([^:%]+(?:\.[^:%]+){3})(%[0-9A-Za-z]+)?$/i.exec(raw);
9268
+ if (!match) return;
9269
+ const [, prefix, embeddedIpv4, zoneSuffix = ""] = match;
9270
+ if (!ipaddr.IPv4.isValidFourPartDecimal(embeddedIpv4)) return;
9271
+ const octets = embeddedIpv4.split(".").map((part) => Number.parseInt(part, 10));
9272
+ const normalizedIpv6 = `${prefix}${(octets[0] << 8 | octets[1]).toString(16)}:${(octets[2] << 8 | octets[3]).toString(16)}${zoneSuffix}`;
9273
+ if (!ipaddr.IPv6.isValid(normalizedIpv6)) return;
9274
+ return ipaddr.IPv6.parse(normalizedIpv6);
9275
+ }
9276
+ function isIpv4Address(address) {
9277
+ return address.kind() === "ipv4";
9278
+ }
9279
+ function isIpv6Address(address) {
9280
+ return address.kind() === "ipv6";
9281
+ }
9282
+ function normalizeIpv4MappedAddress(address) {
9283
+ if (!isIpv6Address(address)) return address;
9284
+ if (!address.isIPv4MappedAddress()) return address;
9285
+ return address.toIPv4Address();
9286
+ }
9287
+ function parseCanonicalIpAddress(raw) {
9288
+ const trimmed = raw?.trim();
9289
+ if (!trimmed) return;
9290
+ const normalized = stripIpv6Brackets(trimmed);
9291
+ if (!normalized) return;
9292
+ if (ipaddr.IPv4.isValid(normalized)) {
9293
+ if (!ipaddr.IPv4.isValidFourPartDecimal(normalized)) return;
9294
+ return ipaddr.IPv4.parse(normalized);
9295
+ }
9296
+ if (ipaddr.IPv6.isValid(normalized)) return ipaddr.IPv6.parse(normalized);
9297
+ return parseIpv6WithEmbeddedIpv4(normalized);
9298
+ }
9299
+ function parseLooseIpAddress(raw) {
9300
+ const trimmed = raw?.trim();
9301
+ if (!trimmed) return;
9302
+ const normalized = stripIpv6Brackets(trimmed);
9303
+ if (!normalized) return;
9304
+ if (ipaddr.isValid(normalized)) return ipaddr.parse(normalized);
9305
+ return parseIpv6WithEmbeddedIpv4(normalized);
9306
+ }
9307
+ function isCanonicalDottedDecimalIPv4(raw) {
9308
+ const trimmed = raw?.trim();
9309
+ if (!trimmed) return false;
9310
+ const normalized = stripIpv6Brackets(trimmed);
9311
+ if (!normalized) return false;
9312
+ return ipaddr.IPv4.isValidFourPartDecimal(normalized);
9313
+ }
9314
+ function isLegacyIpv4Literal(raw) {
9315
+ const trimmed = raw?.trim();
9316
+ if (!trimmed) return false;
9317
+ const normalized = stripIpv6Brackets(trimmed);
9318
+ if (!normalized || normalized.includes(":")) return false;
9319
+ if (isCanonicalDottedDecimalIPv4(normalized)) return false;
9320
+ const parts = normalized.split(".");
9321
+ if (parts.length === 0 || parts.length > 4) return false;
9322
+ if (parts.some((part) => part.length === 0)) return false;
9323
+ if (!parts.every((part) => isNumericIpv4LiteralPart(part))) return false;
9324
+ return true;
9325
+ }
9326
+ function isPrivateOrLoopbackIpAddress(raw) {
9327
+ const parsed = parseCanonicalIpAddress(raw);
9328
+ if (!parsed) return false;
9329
+ const normalized = normalizeIpv4MappedAddress(parsed);
9330
+ if (isIpv4Address(normalized)) return PRIVATE_OR_LOOPBACK_IPV4_RANGES.has(normalized.range());
9331
+ if (PRIVATE_OR_LOOPBACK_IPV6_RANGES.has(normalized.range())) return true;
9332
+ return (normalized.parts[0] & 65472) === 65216;
9333
+ }
9334
+ function isBlockedSpecialUseIpv4Address(address, options = {}) {
9335
+ const inRfc2544BenchmarkRange = address.match(RFC2544_BENCHMARK_PREFIX);
9336
+ if (inRfc2544BenchmarkRange && options.allowRfc2544BenchmarkRange === true) return false;
9337
+ return BLOCKED_IPV4_SPECIAL_USE_RANGES.has(address.range()) || inRfc2544BenchmarkRange;
9338
+ }
9339
+ function decodeIpv4FromHextets(high, low) {
9340
+ const octets = [
9341
+ high >>> 8 & 255,
9342
+ high & 255,
9343
+ low >>> 8 & 255,
9344
+ low & 255
9345
+ ];
9346
+ return ipaddr.IPv4.parse(octets.join("."));
9347
+ }
9348
+ function extractEmbeddedIpv4FromIpv6(address) {
9349
+ if (address.isIPv4MappedAddress()) return address.toIPv4Address();
9350
+ if (address.range() === "rfc6145") return decodeIpv4FromHextets(address.parts[6], address.parts[7]);
9351
+ if (address.range() === "rfc6052") return decodeIpv4FromHextets(address.parts[6], address.parts[7]);
9352
+ for (const rule of EMBEDDED_IPV4_SENTINEL_RULES) {
9353
+ if (!rule.matches(address.parts)) continue;
9354
+ const [high, low] = rule.toHextets(address.parts);
9355
+ return decodeIpv4FromHextets(high, low);
9356
+ }
9357
+ }
9358
+
9359
+ //#endregion
9360
+ //#region src/infra/net/hostname.ts
9361
+ function normalizeHostname(hostname) {
9362
+ const normalized = hostname.trim().toLowerCase().replace(/\.$/, "");
9363
+ if (normalized.startsWith("[") && normalized.endsWith("]")) return normalized.slice(1, -1);
9364
+ return normalized;
9365
+ }
9366
+
9367
+ //#endregion
9368
+ //#region src/infra/net/ssrf.ts
9369
+ var SsrFBlockedError = class extends Error {
9370
+ constructor(message) {
9371
+ super(message);
9372
+ this.name = "SsrFBlockedError";
9899
9373
  }
9900
9374
  };
9901
- /** Format a tool result for display. */
9902
- function formatToolResult(toolId, output, isError) {
9903
- return `${isError ? `Tool ${toolId} error` : `Tool ${toolId} result`}: ${output}`;
9375
+ const BLOCKED_HOSTNAMES = new Set([
9376
+ "localhost",
9377
+ "localhost.localdomain",
9378
+ "metadata.google.internal"
9379
+ ]);
9380
+ function normalizeHostnameSet(values) {
9381
+ if (!values || values.length === 0) return /* @__PURE__ */ new Set();
9382
+ return new Set(values.map((value) => normalizeHostname(value)).filter(Boolean));
9904
9383
  }
9905
- /**
9906
- * Split text at the nearest safe boundary before the limit.
9907
- *
9908
- * Preference order:
9909
- * 1. Paragraph break (\n\n)
9910
- * 2. Line break (\n)
9911
- * 3. Word boundary (space)
9912
- * 4. Hard split at limit
9913
- *
9914
- * Markdown-aware: preserves code fence boundaries by closing/reopening
9915
- * fences at split points when a split occurs inside a fenced code block.
9916
- */
9917
- function splitAtBoundary(text, limit) {
9918
- const fenceInfo = findOpenCodeFence(text, limit);
9919
- if (fenceInfo !== void 0) {
9920
- const beforeFence = text.substring(0, fenceInfo.fenceStart);
9921
- if (beforeFence.trimEnd().length > 0) {
9922
- const trimmed = beforeFence.trimEnd();
9384
+ function normalizeHostnameAllowlist(values) {
9385
+ if (!values || values.length === 0) return [];
9386
+ return Array.from(new Set(values.map((value) => normalizeHostname(value)).filter((value) => value !== "*" && value !== "*." && value.length > 0)));
9387
+ }
9388
+ function resolveAllowPrivateNetwork(policy) {
9389
+ return policy?.dangerouslyAllowPrivateNetwork === true || policy?.allowPrivateNetwork === true;
9390
+ }
9391
+ function resolveIpv4SpecialUseBlockOptions(policy) {
9392
+ return { allowRfc2544BenchmarkRange: policy?.allowRfc2544BenchmarkRange === true };
9393
+ }
9394
+ function isHostnameAllowedByPattern(hostname, pattern) {
9395
+ if (pattern.startsWith("*.")) {
9396
+ const suffix = pattern.slice(2);
9397
+ if (!suffix || hostname === suffix) return false;
9398
+ return hostname.endsWith(`.${suffix}`);
9399
+ }
9400
+ return hostname === pattern;
9401
+ }
9402
+ function matchesHostnameAllowlist(hostname, allowlist) {
9403
+ if (allowlist.length === 0) return true;
9404
+ return allowlist.some((pattern) => isHostnameAllowedByPattern(hostname, pattern));
9405
+ }
9406
+ function looksLikeUnsupportedIpv4Literal(address) {
9407
+ const parts = address.split(".");
9408
+ if (parts.length === 0 || parts.length > 4) return false;
9409
+ if (parts.some((part) => part.length === 0)) return true;
9410
+ return parts.every((part) => /^[0-9]+$/.test(part) || /^0x/i.test(part));
9411
+ }
9412
+ function isPrivateIpAddress(address, policy) {
9413
+ let normalized = address.trim().toLowerCase();
9414
+ if (normalized.startsWith("[") && normalized.endsWith("]")) normalized = normalized.slice(1, -1);
9415
+ if (!normalized) return false;
9416
+ const blockOptions = resolveIpv4SpecialUseBlockOptions(policy);
9417
+ const strictIp = parseCanonicalIpAddress(normalized);
9418
+ if (strictIp) {
9419
+ if (isIpv4Address(strictIp)) return isBlockedSpecialUseIpv4Address(strictIp, blockOptions);
9420
+ if (isPrivateOrLoopbackIpAddress(strictIp.toString())) return true;
9421
+ const embeddedIpv4 = extractEmbeddedIpv4FromIpv6(strictIp);
9422
+ if (embeddedIpv4) return isBlockedSpecialUseIpv4Address(embeddedIpv4, blockOptions);
9423
+ return false;
9424
+ }
9425
+ if (normalized.includes(":") && !parseLooseIpAddress(normalized)) return true;
9426
+ if (!isCanonicalDottedDecimalIPv4(normalized) && isLegacyIpv4Literal(normalized)) return true;
9427
+ if (looksLikeUnsupportedIpv4Literal(normalized)) return true;
9428
+ return false;
9429
+ }
9430
+ function isBlockedHostnameNormalized(normalized) {
9431
+ if (BLOCKED_HOSTNAMES.has(normalized)) return true;
9432
+ return normalized.endsWith(".localhost") || normalized.endsWith(".local") || normalized.endsWith(".internal");
9433
+ }
9434
+ function isBlockedHostnameOrIp(hostname, policy) {
9435
+ const normalized = normalizeHostname(hostname);
9436
+ if (!normalized) return false;
9437
+ return isBlockedHostnameNormalized(normalized) || isPrivateIpAddress(normalized, policy);
9438
+ }
9439
+ const BLOCKED_HOST_OR_IP_MESSAGE = "Blocked hostname or private/internal/special-use IP address";
9440
+ const BLOCKED_RESOLVED_IP_MESSAGE = "Blocked: resolves to private/internal/special-use IP address";
9441
+ function assertAllowedHostOrIpOrThrow(hostnameOrIp, policy) {
9442
+ if (isBlockedHostnameOrIp(hostnameOrIp, policy)) throw new SsrFBlockedError(BLOCKED_HOST_OR_IP_MESSAGE);
9443
+ }
9444
+ function assertAllowedResolvedAddressesOrThrow(results, policy) {
9445
+ for (const entry of results) if (isBlockedHostnameOrIp(entry.address, policy)) throw new SsrFBlockedError(BLOCKED_RESOLVED_IP_MESSAGE);
9446
+ }
9447
+ function createPinnedLookup(params) {
9448
+ const normalizedHost = normalizeHostname(params.hostname);
9449
+ const fallback = params.fallback ?? lookup;
9450
+ const fallbackLookup = fallback;
9451
+ const fallbackWithOptions = fallback;
9452
+ const records = params.addresses.map((address) => ({
9453
+ address,
9454
+ family: address.includes(":") ? 6 : 4
9455
+ }));
9456
+ let index = 0;
9457
+ return ((host, options, callback) => {
9458
+ const cb = typeof options === "function" ? options : callback;
9459
+ if (!cb) return;
9460
+ const normalized = normalizeHostname(host);
9461
+ if (!normalized || normalized !== normalizedHost) {
9462
+ if (typeof options === "function" || options === void 0) return fallbackLookup(host, cb);
9463
+ return fallbackWithOptions(host, options, cb);
9464
+ }
9465
+ const opts = typeof options === "object" && options !== null ? options : {};
9466
+ const requestedFamily = typeof options === "number" ? options : typeof opts.family === "number" ? opts.family : 0;
9467
+ const candidates = requestedFamily === 4 || requestedFamily === 6 ? records.filter((entry) => entry.family === requestedFamily) : records;
9468
+ const usable = candidates.length > 0 ? candidates : records;
9469
+ if (opts.all) {
9470
+ cb(null, usable);
9471
+ return;
9472
+ }
9473
+ const chosen = usable[index % usable.length];
9474
+ index += 1;
9475
+ cb(null, chosen.address, chosen.family);
9476
+ });
9477
+ }
9478
+ function dedupeAndPreferIpv4(results) {
9479
+ const seen = /* @__PURE__ */ new Set();
9480
+ const ipv4 = [];
9481
+ const otherFamilies = [];
9482
+ for (const entry of results) {
9483
+ if (seen.has(entry.address)) continue;
9484
+ seen.add(entry.address);
9485
+ if (entry.family === 4) {
9486
+ ipv4.push(entry.address);
9487
+ continue;
9488
+ }
9489
+ otherFamilies.push(entry.address);
9490
+ }
9491
+ return [...ipv4, ...otherFamilies];
9492
+ }
9493
+ async function resolvePinnedHostnameWithPolicy(hostname, params = {}) {
9494
+ const normalized = normalizeHostname(hostname);
9495
+ if (!normalized) throw new Error("Invalid hostname");
9496
+ const allowPrivateNetwork = resolveAllowPrivateNetwork(params.policy);
9497
+ const allowedHostnames = normalizeHostnameSet(params.policy?.allowedHostnames);
9498
+ const hostnameAllowlist = normalizeHostnameAllowlist(params.policy?.hostnameAllowlist);
9499
+ const isExplicitAllowed = allowedHostnames.has(normalized);
9500
+ const skipPrivateNetworkChecks = allowPrivateNetwork || isExplicitAllowed;
9501
+ if (!matchesHostnameAllowlist(normalized, hostnameAllowlist)) throw new SsrFBlockedError(`Blocked hostname (not in allowlist): ${hostname}`);
9502
+ if (!skipPrivateNetworkChecks) assertAllowedHostOrIpOrThrow(normalized, params.policy);
9503
+ const results = await (params.lookupFn ?? lookup$1)(normalized, { all: true });
9504
+ if (results.length === 0) throw new Error(`Unable to resolve hostname: ${hostname}`);
9505
+ if (!skipPrivateNetworkChecks) assertAllowedResolvedAddressesOrThrow(results, params.policy);
9506
+ const addresses = dedupeAndPreferIpv4(results);
9507
+ if (addresses.length === 0) throw new Error(`Unable to resolve hostname: ${hostname}`);
9508
+ return {
9509
+ hostname: normalized,
9510
+ addresses,
9511
+ lookup: createPinnedLookup({
9512
+ hostname: normalized,
9513
+ addresses
9514
+ })
9515
+ };
9516
+ }
9517
+ function createPinnedDispatcher(pinned) {
9518
+ return new Agent({ connect: {
9519
+ lookup: pinned.lookup,
9520
+ autoSelectFamily: true,
9521
+ autoSelectFamilyAttemptTimeout: 300
9522
+ } });
9523
+ }
9524
+ async function closeDispatcher(dispatcher) {
9525
+ if (!dispatcher) return;
9526
+ const candidate = dispatcher;
9527
+ try {
9528
+ if (typeof candidate.close === "function") {
9529
+ await candidate.close();
9530
+ return;
9531
+ }
9532
+ if (typeof candidate.destroy === "function") candidate.destroy();
9533
+ } catch {}
9534
+ }
9535
+
9536
+ //#endregion
9537
+ //#region src/infra/net/fetch-guard.ts
9538
+ const DEFAULT_MAX_REDIRECTS = 3;
9539
+ const CROSS_ORIGIN_REDIRECT_SENSITIVE_HEADERS = [
9540
+ "authorization",
9541
+ "proxy-authorization",
9542
+ "cookie",
9543
+ "cookie2"
9544
+ ];
9545
+ function isRedirectStatus(status) {
9546
+ return status === 301 || status === 302 || status === 303 || status === 307 || status === 308;
9547
+ }
9548
+ function stripSensitiveHeadersForCrossOriginRedirect(init) {
9549
+ if (!init?.headers) return init;
9550
+ const headers = new Headers(init.headers);
9551
+ for (const header of CROSS_ORIGIN_REDIRECT_SENSITIVE_HEADERS) headers.delete(header);
9552
+ return {
9553
+ ...init,
9554
+ headers
9555
+ };
9556
+ }
9557
+ function buildAbortSignal(params) {
9558
+ const { timeoutMs, signal } = params;
9559
+ if (!timeoutMs && !signal) return {
9560
+ signal: void 0,
9561
+ cleanup: () => {}
9562
+ };
9563
+ if (!timeoutMs) return {
9564
+ signal,
9565
+ cleanup: () => {}
9566
+ };
9567
+ const controller = new AbortController();
9568
+ const timeoutId = setTimeout(controller.abort.bind(controller), timeoutMs);
9569
+ const onAbort = bindAbortRelay(controller);
9570
+ if (signal) if (signal.aborted) controller.abort();
9571
+ else signal.addEventListener("abort", onAbort, { once: true });
9572
+ const cleanup = () => {
9573
+ clearTimeout(timeoutId);
9574
+ if (signal) signal.removeEventListener("abort", onAbort);
9575
+ };
9576
+ return {
9577
+ signal: controller.signal,
9578
+ cleanup
9579
+ };
9580
+ }
9581
+ async function fetchWithSsrFGuard(params) {
9582
+ const fetcher = params.fetchImpl ?? globalThis.fetch;
9583
+ if (!fetcher) throw new Error("fetch is not available");
9584
+ const maxRedirects = typeof params.maxRedirects === "number" && Number.isFinite(params.maxRedirects) ? Math.max(0, Math.floor(params.maxRedirects)) : DEFAULT_MAX_REDIRECTS;
9585
+ const { signal, cleanup } = buildAbortSignal({
9586
+ timeoutMs: params.timeoutMs,
9587
+ signal: params.signal
9588
+ });
9589
+ let released = false;
9590
+ const release = async (dispatcher) => {
9591
+ if (released) return;
9592
+ released = true;
9593
+ cleanup();
9594
+ await closeDispatcher(dispatcher ?? void 0);
9595
+ };
9596
+ const visited = /* @__PURE__ */ new Set();
9597
+ let currentUrl = params.url;
9598
+ let currentInit = params.init ? { ...params.init } : void 0;
9599
+ let redirectCount = 0;
9600
+ while (true) {
9601
+ let parsedUrl;
9602
+ try {
9603
+ parsedUrl = new URL(currentUrl);
9604
+ } catch {
9605
+ await release();
9606
+ throw new Error("Invalid URL: must be http or https");
9607
+ }
9608
+ if (!["http:", "https:"].includes(parsedUrl.protocol)) {
9609
+ await release();
9610
+ throw new Error("Invalid URL: must be http or https");
9611
+ }
9612
+ let dispatcher = null;
9613
+ try {
9614
+ const pinned = await resolvePinnedHostnameWithPolicy(parsedUrl.hostname, {
9615
+ lookupFn: params.lookupFn,
9616
+ policy: params.policy
9617
+ });
9618
+ if (params.pinDns !== false) dispatcher = createPinnedDispatcher(pinned);
9619
+ const init = {
9620
+ ...currentInit ? { ...currentInit } : {},
9621
+ redirect: "manual",
9622
+ ...dispatcher ? { dispatcher } : {},
9623
+ ...signal ? { signal } : {}
9624
+ };
9625
+ const response = await fetcher(parsedUrl.toString(), init);
9626
+ if (isRedirectStatus(response.status)) {
9627
+ const location = response.headers.get("location");
9628
+ if (!location) {
9629
+ await release(dispatcher);
9630
+ throw new Error(`Redirect missing location header (${response.status})`);
9631
+ }
9632
+ redirectCount += 1;
9633
+ if (redirectCount > maxRedirects) {
9634
+ await release(dispatcher);
9635
+ throw new Error(`Too many redirects (limit: ${maxRedirects})`);
9636
+ }
9637
+ const nextParsedUrl = new URL(location, parsedUrl);
9638
+ const nextUrl = nextParsedUrl.toString();
9639
+ if (visited.has(nextUrl)) {
9640
+ await release(dispatcher);
9641
+ throw new Error("Redirect loop detected");
9642
+ }
9643
+ if (nextParsedUrl.origin !== parsedUrl.origin) currentInit = stripSensitiveHeadersForCrossOriginRedirect(currentInit);
9644
+ visited.add(nextUrl);
9645
+ response.body?.cancel();
9646
+ await closeDispatcher(dispatcher);
9647
+ currentUrl = nextUrl;
9648
+ continue;
9649
+ }
9923
9650
  return {
9924
- chunk: trimmed,
9925
- rest: text.substring(trimmed.length).trimStart()
9651
+ response,
9652
+ finalUrl: currentUrl,
9653
+ release: async () => release(dispatcher)
9926
9654
  };
9927
- }
9928
- const closingFence = `\n${fenceInfo.fence}`;
9929
- const openingFence = `${fenceInfo.fence}\n`;
9930
- const splitPoint = findSplitPoint(text, limit - closingFence.length);
9931
- return {
9932
- chunk: text.substring(0, splitPoint) + closingFence,
9933
- rest: openingFence + text.substring(splitPoint)
9934
- };
9655
+ } catch (err) {
9656
+ if (err instanceof SsrFBlockedError) logWarn(`security: blocked URL fetch (${params.auditContext ?? "url-fetch"}) target=${parsedUrl.origin}${parsedUrl.pathname} reason=${err.message}`);
9657
+ await release(dispatcher);
9658
+ throw err;
9659
+ }
9935
9660
  }
9936
- const splitPoint = findSplitPoint(text, limit);
9937
- return {
9938
- chunk: text.substring(0, splitPoint),
9939
- rest: text.substring(splitPoint)
9940
- };
9941
9661
  }
9942
- /** Find the best split point within the text up to the given limit. */
9943
- function findSplitPoint(text, limit) {
9944
- if (limit <= 0) return Math.min(1, text.length);
9945
- const searchRegion = text.substring(0, limit);
9946
- const paragraphIdx = searchRegion.lastIndexOf("\n\n");
9947
- if (paragraphIdx > 0) return paragraphIdx + 2;
9948
- const lineIdx = searchRegion.lastIndexOf("\n");
9949
- if (lineIdx > 0) return lineIdx + 1;
9950
- const spaceIdx = searchRegion.lastIndexOf(" ");
9951
- if (spaceIdx > 0) return spaceIdx + 1;
9952
- return limit;
9662
+
9663
+ //#endregion
9664
+ //#region src/media/constants.ts
9665
+ const MAX_IMAGE_BYTES = 6 * 1024 * 1024;
9666
+ const MAX_AUDIO_BYTES = 16 * 1024 * 1024;
9667
+ const MAX_VIDEO_BYTES = 16 * 1024 * 1024;
9668
+ const MAX_DOCUMENT_BYTES = 100 * 1024 * 1024;
9669
+
9670
+ //#endregion
9671
+ //#region src/media/mime.ts
9672
+ const EXT_BY_MIME = {
9673
+ "image/heic": ".heic",
9674
+ "image/heif": ".heif",
9675
+ "image/jpeg": ".jpg",
9676
+ "image/png": ".png",
9677
+ "image/webp": ".webp",
9678
+ "image/gif": ".gif",
9679
+ "audio/ogg": ".ogg",
9680
+ "audio/mpeg": ".mp3",
9681
+ "audio/x-m4a": ".m4a",
9682
+ "audio/mp4": ".m4a",
9683
+ "video/mp4": ".mp4",
9684
+ "video/quicktime": ".mov",
9685
+ "application/pdf": ".pdf",
9686
+ "application/json": ".json",
9687
+ "application/zip": ".zip",
9688
+ "application/gzip": ".gz",
9689
+ "application/x-tar": ".tar",
9690
+ "application/x-7z-compressed": ".7z",
9691
+ "application/vnd.rar": ".rar",
9692
+ "application/msword": ".doc",
9693
+ "application/vnd.ms-excel": ".xls",
9694
+ "application/vnd.ms-powerpoint": ".ppt",
9695
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document": ".docx",
9696
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": ".xlsx",
9697
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation": ".pptx",
9698
+ "text/csv": ".csv",
9699
+ "text/plain": ".txt",
9700
+ "text/markdown": ".md"
9701
+ };
9702
+ const MIME_BY_EXT = {
9703
+ ...Object.fromEntries(Object.entries(EXT_BY_MIME).map(([mime, ext]) => [ext, mime])),
9704
+ ".jpeg": "image/jpeg"
9705
+ };
9706
+ function normalizeMimeType(mime) {
9707
+ if (!mime) return;
9708
+ return mime.split(";")[0]?.trim().toLowerCase() || void 0;
9953
9709
  }
9954
- /**
9955
- * Detect if the text has an unclosed code fence at or before the limit position.
9956
- * Returns info about the open fence, or undefined if no open fence.
9957
- */
9958
- function findOpenCodeFence(text, limit) {
9959
- const fenceRegex = /^(`{3,}|~{3,})/gm;
9960
- let openFence;
9961
- let match;
9962
- while ((match = fenceRegex.exec(text)) !== null) {
9963
- if (match.index >= limit) break;
9964
- if (openFence === void 0) openFence = {
9965
- fenceStart: match.index,
9966
- fence: match[1]
9967
- };
9968
- else if (match[1].charAt(0) === openFence.fence.charAt(0) && match[1].length >= openFence.fence.length) openFence = void 0;
9710
+ async function sniffMime(buffer) {
9711
+ if (!buffer) return;
9712
+ try {
9713
+ return (await fileTypeFromBuffer(buffer))?.mime ?? void 0;
9714
+ } catch {
9715
+ return;
9969
9716
  }
9970
- return openFence;
9717
+ }
9718
+ function getFileExtension(filePath) {
9719
+ if (!filePath) return;
9720
+ try {
9721
+ if (/^https?:\/\//i.test(filePath)) {
9722
+ const url = new URL(filePath);
9723
+ return path.extname(url.pathname).toLowerCase() || void 0;
9724
+ }
9725
+ } catch {}
9726
+ return path.extname(filePath).toLowerCase() || void 0;
9727
+ }
9728
+ function detectMime(opts) {
9729
+ return detectMimeImpl(opts);
9730
+ }
9731
+ function isGenericMime(mime) {
9732
+ if (!mime) return true;
9733
+ const m = mime.toLowerCase();
9734
+ return m === "application/octet-stream" || m === "application/zip";
9735
+ }
9736
+ async function detectMimeImpl(opts) {
9737
+ const ext = getFileExtension(opts.filePath);
9738
+ const extMime = ext ? MIME_BY_EXT[ext] : void 0;
9739
+ const headerMime = normalizeMimeType(opts.headerMime);
9740
+ const sniffed = await sniffMime(opts.buffer);
9741
+ if (sniffed && (!isGenericMime(sniffed) || !extMime)) return sniffed;
9742
+ if (extMime) return extMime;
9743
+ if (headerMime && !isGenericMime(headerMime)) return headerMime;
9744
+ if (sniffed) return sniffed;
9745
+ if (headerMime) return headerMime;
9746
+ }
9747
+ function extensionForMime$1(mime) {
9748
+ const normalized = normalizeMimeType(mime);
9749
+ if (!normalized) return;
9750
+ return EXT_BY_MIME[normalized];
9971
9751
  }
9972
9752
 
9973
9753
  //#endregion
9974
- //#region src/middleware/error-classifier.ts
9975
- const retryablePatterns = [
9976
- /rate.?limit/i,
9977
- /429/i,
9978
- /503/i,
9979
- /overloaded/i,
9980
- /ETIMEDOUT/i,
9981
- /ECONNRESET/i,
9982
- /ECONNREFUSED/i,
9983
- /network/i
9984
- ];
9985
- const contextOverflowPatterns = [
9986
- /context.?length/i,
9987
- /context.?window/i,
9988
- /context.?overflow/i,
9989
- /too many tokens/i,
9990
- /maximum context/i,
9991
- /token.?limit/i
9992
- ];
9993
- const fatalAuthPatterns = [
9994
- /401/i,
9995
- /403/i,
9996
- /unauthorized/i,
9997
- /forbidden/i,
9998
- /invalid.?key/i,
9999
- /authentication/i
10000
- ];
10001
- /**
10002
- * Classify an error message string into an actionable category.
10003
- *
10004
- * Uses first-match-wins semantics across ordered pattern arrays:
10005
- * 1. Retryable patterns checked first
10006
- * 2. Context overflow patterns checked second
10007
- * 3. Fatal auth patterns checked third
10008
- * 4. Default: "fatal" for unmatched messages
10009
- *
10010
- * Case-insensitive matching throughout.
10011
- */
10012
- function classifyError(message) {
10013
- for (const pattern of retryablePatterns) if (pattern.test(message)) return "retryable";
10014
- for (const pattern of contextOverflowPatterns) if (pattern.test(message)) return "context_overflow";
10015
- for (const pattern of fatalAuthPatterns) if (pattern.test(message)) return "fatal";
10016
- return "fatal";
9754
+ //#region src/media/read-response-with-limit.ts
9755
+ async function readResponseWithLimit(res, maxBytes, opts) {
9756
+ const onOverflow = opts?.onOverflow ?? ((params) => /* @__PURE__ */ new Error(`Content too large: ${params.size} bytes (limit: ${params.maxBytes} bytes)`));
9757
+ const body = res.body;
9758
+ if (!body || typeof body.getReader !== "function") {
9759
+ const fallback = Buffer.from(await res.arrayBuffer());
9760
+ if (fallback.length > maxBytes) throw onOverflow({
9761
+ size: fallback.length,
9762
+ maxBytes,
9763
+ res
9764
+ });
9765
+ return fallback;
9766
+ }
9767
+ const reader = body.getReader();
9768
+ const chunks = [];
9769
+ let total = 0;
9770
+ try {
9771
+ while (true) {
9772
+ const { done, value } = await reader.read();
9773
+ if (done) break;
9774
+ if (value?.length) {
9775
+ total += value.length;
9776
+ if (total > maxBytes) {
9777
+ try {
9778
+ await reader.cancel();
9779
+ } catch {}
9780
+ throw onOverflow({
9781
+ size: total,
9782
+ maxBytes,
9783
+ res
9784
+ });
9785
+ }
9786
+ chunks.push(value);
9787
+ }
9788
+ }
9789
+ } finally {
9790
+ try {
9791
+ reader.releaseLock();
9792
+ } catch {}
9793
+ }
9794
+ return Buffer.concat(chunks.map((chunk) => Buffer.from(chunk)), total);
10017
9795
  }
10018
9796
 
10019
9797
  //#endregion
10020
- //#region src/middleware/mcp-side-effects.ts
10021
- async function readMcpSideEffects(filePath) {
10022
- const result = {
10023
- sentTexts: [],
10024
- sentMediaUrls: [],
10025
- sentTargets: [],
10026
- cronAdds: 0
10027
- };
10028
- let content;
9798
+ //#region src/media/fetch.ts
9799
+ var MediaFetchError = class extends Error {
9800
+ constructor(code, message) {
9801
+ super(message);
9802
+ this.code = code;
9803
+ this.name = "MediaFetchError";
9804
+ }
9805
+ };
9806
+ function stripQuotes(value) {
9807
+ return value.replace(/^["']|["']$/g, "");
9808
+ }
9809
+ function parseContentDispositionFileName(header) {
9810
+ if (!header) return;
9811
+ const starMatch = /filename\*\s*=\s*([^;]+)/i.exec(header);
9812
+ if (starMatch?.[1]) {
9813
+ const cleaned = stripQuotes(starMatch[1].trim());
9814
+ const encoded = cleaned.split("''").slice(1).join("''") || cleaned;
9815
+ try {
9816
+ return path.basename(decodeURIComponent(encoded));
9817
+ } catch {
9818
+ return path.basename(encoded);
9819
+ }
9820
+ }
9821
+ const match = /filename\s*=\s*([^;]+)/i.exec(header);
9822
+ if (match?.[1]) return path.basename(stripQuotes(match[1].trim()));
9823
+ }
9824
+ async function readErrorBodySnippet(res, maxChars = 200) {
10029
9825
  try {
10030
- content = await readFile(filePath, "utf-8");
9826
+ const text = await res.text();
9827
+ if (!text) return;
9828
+ const collapsed = text.replace(/\s+/g, " ").trim();
9829
+ if (!collapsed) return;
9830
+ if (collapsed.length <= maxChars) return collapsed;
9831
+ return `${collapsed.slice(0, maxChars)}…`;
10031
9832
  } catch {
10032
- return result;
9833
+ return;
10033
9834
  }
10034
- const lines = content.split("\n").filter(Boolean);
10035
- for (const line of lines) {
10036
- let record;
9835
+ }
9836
+ async function fetchRemoteMedia(options) {
9837
+ const { url, fetchImpl, filePathHint, maxBytes, maxRedirects, ssrfPolicy, lookupFn } = options;
9838
+ let res;
9839
+ let finalUrl = url;
9840
+ let release = null;
9841
+ try {
9842
+ const result = await fetchWithSsrFGuard({
9843
+ url,
9844
+ fetchImpl,
9845
+ maxRedirects,
9846
+ policy: ssrfPolicy,
9847
+ lookupFn
9848
+ });
9849
+ res = result.response;
9850
+ finalUrl = result.finalUrl;
9851
+ release = result.release;
9852
+ } catch (err) {
9853
+ throw new MediaFetchError("fetch_failed", `Failed to fetch media from ${url}: ${String(err)}`);
9854
+ }
9855
+ try {
9856
+ if (!res.ok) {
9857
+ const statusText = res.statusText ? ` ${res.statusText}` : "";
9858
+ const redirected = finalUrl !== url ? ` (redirected to ${finalUrl})` : "";
9859
+ let detail = `HTTP ${res.status}${statusText}`;
9860
+ if (!res.body) detail = `HTTP ${res.status}${statusText}; empty response body`;
9861
+ else {
9862
+ const snippet = await readErrorBodySnippet(res);
9863
+ if (snippet) detail += `; body: ${snippet}`;
9864
+ }
9865
+ throw new MediaFetchError("http_error", `Failed to fetch media from ${url}${redirected}: ${detail}`);
9866
+ }
9867
+ const contentLength = res.headers.get("content-length");
9868
+ if (maxBytes && contentLength) {
9869
+ const length = Number(contentLength);
9870
+ if (Number.isFinite(length) && length > maxBytes) throw new MediaFetchError("max_bytes", `Failed to fetch media from ${url}: content length ${length} exceeds maxBytes ${maxBytes}`);
9871
+ }
9872
+ const buffer = maxBytes ? await readResponseWithLimit(res, maxBytes, { onOverflow: ({ maxBytes, res }) => new MediaFetchError("max_bytes", `Failed to fetch media from ${res.url || url}: payload exceeds maxBytes ${maxBytes}`) }) : Buffer.from(await res.arrayBuffer());
9873
+ let fileNameFromUrl;
10037
9874
  try {
10038
- record = JSON.parse(line);
10039
- } catch {
10040
- continue;
9875
+ const parsed = new URL(finalUrl);
9876
+ fileNameFromUrl = path.basename(parsed.pathname) || void 0;
9877
+ } catch {}
9878
+ const headerFileName = parseContentDispositionFileName(res.headers.get("content-disposition"));
9879
+ let fileName = headerFileName || fileNameFromUrl || (filePathHint ? path.basename(filePathHint) : void 0);
9880
+ const filePathForMime = headerFileName && path.extname(headerFileName) ? headerFileName : filePathHint ?? finalUrl;
9881
+ const contentType = await detectMime({
9882
+ buffer,
9883
+ headerMime: res.headers.get("content-type"),
9884
+ filePath: filePathForMime
9885
+ });
9886
+ if (fileName && !path.extname(fileName) && contentType) {
9887
+ const ext = extensionForMime$1(contentType);
9888
+ if (ext) fileName = `${fileName}${ext}`;
10041
9889
  }
10042
- if (record.type === "message_sent") {
10043
- result.sentTexts.push(record.text);
10044
- if (record.mediaUrl) result.sentMediaUrls.push(record.mediaUrl);
10045
- const target = {
10046
- tool: record.tool,
10047
- provider: record.provider,
10048
- ...record.accountId ? { accountId: record.accountId } : {},
10049
- ...record.to ? { to: record.to } : {}
10050
- };
10051
- result.sentTargets.push(target);
10052
- } else if (record.type === "cron_added") result.cronAdds += 1;
10053
- else if (record.type === "heartbeat_report") result.heartbeatReport = {
10054
- anythingDone: record.anythingDone,
10055
- summary: record.summary
9890
+ return {
9891
+ buffer,
9892
+ contentType: contentType ?? void 0,
9893
+ fileName
10056
9894
  };
9895
+ } finally {
9896
+ if (release) await release();
10057
9897
  }
10058
- return result;
9898
+ }
9899
+
9900
+ //#endregion
9901
+ //#region src/middleware/media-resolver.ts
9902
+ /** Max download size for inbound channel media (100 MB). */
9903
+ const MAX_INBOUND_MEDIA_BYTES = 100 * 1024 * 1024;
9904
+ /**
9905
+ * Resolve an array of media URLs (HTTP or local paths) into MediaAttachment
9906
+ * objects suitable for passing to {@link AgentRuntime.execute}.
9907
+ *
9908
+ * Remote URLs are downloaded into `tempDir` so that CLI runtimes can access
9909
+ * them as local files. Local paths are validated for MIME type only.
9910
+ *
9911
+ * Individual resolution failures are silently skipped — a single bad URL
9912
+ * should not prevent the rest of the message from being processed.
9913
+ */
9914
+ async function resolveMediaAttachments(mediaUrls, tempDir) {
9915
+ const results = [];
9916
+ for (const [index, url] of mediaUrls.entries()) try {
9917
+ const attachment = await resolveOne(url, tempDir, index);
9918
+ if (attachment) {
9919
+ logDebug(`[media-resolver] resolved: url=${url} mime=${attachment.mimeType} path=${attachment.filePath}`);
9920
+ results.push(attachment);
9921
+ }
9922
+ } catch (err) {
9923
+ logDebug(`[media-resolver] failed: url=${url} error=${String(err)}`);
9924
+ }
9925
+ return results;
9926
+ }
9927
+ async function resolveOne(url, tempDir, index) {
9928
+ if (/^https?:\/\//i.test(url)) return downloadRemote(url, tempDir, index);
9929
+ return resolveLocal(url);
9930
+ }
9931
+ async function downloadRemote(url, tempDir, index) {
9932
+ const fetched = await fetchRemoteMedia({
9933
+ url,
9934
+ maxBytes: MAX_INBOUND_MEDIA_BYTES
9935
+ });
9936
+ const mimeType = fetched.contentType ?? "application/octet-stream";
9937
+ const fileName = `inbound-media-${index}${extensionForMime$1(mimeType) ?? ""}`;
9938
+ const filePath = join(tempDir, fileName);
9939
+ await writeFile(filePath, fetched.buffer);
9940
+ return {
9941
+ mimeType,
9942
+ filePath,
9943
+ sourceUrl: url,
9944
+ fileName: fetched.fileName ?? fileName
9945
+ };
9946
+ }
9947
+ async function resolveLocal(filePath) {
9948
+ return {
9949
+ mimeType: await detectMime({ filePath }) ?? "application/octet-stream",
9950
+ filePath
9951
+ };
10059
9952
  }
10060
9953
 
10061
9954
  //#endregion
@@ -10074,6 +9967,12 @@ var CLIRuntimeBase = class CLIRuntimeBase {
10074
9967
  this.command = command;
10075
9968
  this.timeoutMs = timeoutMs;
10076
9969
  }
9970
+ /**
9971
+ * Construct a custom stdin payload for the subprocess.
9972
+ * When this returns a string, it is written to stdin instead of
9973
+ * the default large-prompt fallback. Subclasses may override.
9974
+ */
9975
+ buildStdinPayload(_params) {}
10077
9976
  /** Whether this CLI accepts prompts via stdin. Subclasses may override. */
10078
9977
  get supportsStdinPrompt() {
10079
9978
  return true;
@@ -10088,11 +9987,18 @@ var CLIRuntimeBase = class CLIRuntimeBase {
10088
9987
  }
10089
9988
  async *execute(params) {
10090
9989
  const args = this.buildArgs(params);
9990
+ if (params.extraArgs && params.extraArgs.length > 0) args.push(...params.extraArgs);
9991
+ const runtimeEnv = this.buildEnv(params);
9992
+ const callerEnv = params.env ?? {};
10091
9993
  const env = {
10092
9994
  ...process.env,
10093
- ...this.buildEnv(params),
10094
- ...params.env
9995
+ ...runtimeEnv,
9996
+ ...callerEnv
10095
9997
  };
9998
+ logDebug(`[agent-runtime] spawn: ${this.command} ${args.map((a) => JSON.stringify(a)).join(" ")}`);
9999
+ logDebug(`[agent-runtime] cwd: ${params.workingDirectory ?? process.cwd()}`);
10000
+ if (Object.keys(runtimeEnv).length > 0) logDebug(`[agent-runtime] runtime env keys: ${Object.keys(runtimeEnv).join(", ")}`);
10001
+ if (Object.keys(callerEnv).length > 0) logDebug(`[agent-runtime] caller env keys: ${Object.keys(callerEnv).join(", ")}`);
10096
10002
  const child = spawn(this.command, args, {
10097
10003
  cwd: params.workingDirectory,
10098
10004
  env,
@@ -10102,9 +10008,11 @@ var CLIRuntimeBase = class CLIRuntimeBase {
10102
10008
  "pipe"
10103
10009
  ]
10104
10010
  });
10011
+ logDebug(`[agent-runtime] spawned pid=${child.pid}`);
10105
10012
  const startMs = Date.now();
10106
10013
  const stderrChunks = [];
10107
10014
  let aborted = false;
10015
+ let yieldedEvents = false;
10108
10016
  let escalationTimer;
10109
10017
  const killWithEscalation = () => {
10110
10018
  if (escalationTimer === void 0) escalationTimer = setTimeout(() => {
@@ -10126,6 +10034,7 @@ var CLIRuntimeBase = class CLIRuntimeBase {
10126
10034
  if (watchdogTimer !== void 0) clearTimeout(watchdogTimer);
10127
10035
  watchdogTimer = setTimeout(() => {
10128
10036
  watchdogFired = true;
10037
+ logDebug(`[agent-runtime] pid=${child.pid}: watchdog timeout after ${this.timeoutMs}ms`);
10129
10038
  killWithEscalation();
10130
10039
  }, this.timeoutMs);
10131
10040
  };
@@ -10165,10 +10074,18 @@ var CLIRuntimeBase = class CLIRuntimeBase {
10165
10074
  });
10166
10075
  });
10167
10076
  });
10168
- if (this.supportsStdinPrompt && params.prompt.length > CLIRuntimeBase.STDIN_PROMPT_THRESHOLD && child.stdin) child.stdin.write(params.prompt);
10077
+ const customStdin = this.buildStdinPayload(params);
10078
+ if (customStdin !== void 0 && child.stdin) {
10079
+ logDebug(`[agent-runtime] pid=${child.pid}: delivering custom stdin payload (${customStdin.length} chars)`);
10080
+ child.stdin.write(customStdin);
10081
+ } else if (this.supportsStdinPrompt && params.prompt.length > CLIRuntimeBase.STDIN_PROMPT_THRESHOLD && child.stdin) {
10082
+ logDebug(`[agent-runtime] pid=${child.pid}: delivering prompt via stdin (${params.prompt.length} chars)`);
10083
+ child.stdin.write(params.prompt);
10084
+ }
10169
10085
  child.stdin?.end();
10170
10086
  const onAbort = () => {
10171
10087
  aborted = true;
10088
+ logDebug(`[agent-runtime] pid=${child.pid}: abort signal received`);
10172
10089
  killWithEscalation();
10173
10090
  };
10174
10091
  if (params.abortSignal) if (params.abortSignal.aborted) {
@@ -10183,6 +10100,7 @@ var CLIRuntimeBase = class CLIRuntimeBase {
10183
10100
  while (eventQueue.length > 0) {
10184
10101
  const event = eventQueue.shift();
10185
10102
  if (event === null || event === void 0) break;
10103
+ yieldedEvents = true;
10186
10104
  yield event;
10187
10105
  }
10188
10106
  }
@@ -10190,9 +10108,16 @@ var CLIRuntimeBase = class CLIRuntimeBase {
10190
10108
  if (watchdogTimer !== void 0) clearTimeout(watchdogTimer);
10191
10109
  params.abortSignal?.removeEventListener("abort", onAbort);
10192
10110
  }
10193
- await exitPromise;
10111
+ const { code: exitCode, signal: exitSignal } = await exitPromise;
10194
10112
  if (escalationTimer !== void 0) clearTimeout(escalationTimer);
10195
10113
  const durationMs = Date.now() - startMs;
10114
+ logDebug(`[agent-runtime] pid=${child.pid}: exited code=${exitCode} signal=${exitSignal} duration=${durationMs}ms`);
10115
+ const stderr = stderrChunks.join("");
10116
+ if (stderr && (exitCode !== 0 || !yieldedEvents)) yield {
10117
+ type: "error",
10118
+ message: stderr.trim(),
10119
+ code: "CLI_STDERR"
10120
+ };
10196
10121
  if (watchdogFired) yield {
10197
10122
  type: "error",
10198
10123
  message: `Watchdog timeout: no output for ${this.timeoutMs}ms`,
@@ -10210,7 +10135,8 @@ var CLIRuntimeBase = class CLIRuntimeBase {
10210
10135
  sessionId: void 0,
10211
10136
  durationMs,
10212
10137
  usage: void 0,
10213
- aborted
10138
+ aborted,
10139
+ stderr: stderr || void 0
10214
10140
  }
10215
10141
  };
10216
10142
  }
@@ -10225,12 +10151,17 @@ var CLIRuntimeBase = class CLIRuntimeBase {
10225
10151
  var ClaudeCliRuntime = class extends CLIRuntimeBase {
10226
10152
  constructor() {
10227
10153
  super("claude");
10154
+ this.mediaCapabilities = {
10155
+ acceptsInbound: ["image/"],
10156
+ emitsOutbound: false
10157
+ };
10228
10158
  this.accumulatedText = "";
10229
10159
  this.toolBuffer = null;
10230
10160
  }
10231
10161
  async *execute(params) {
10232
10162
  this.resetState();
10233
- for await (const event of super.execute(params)) {
10163
+ const prepared = await this.prepareMedia(params);
10164
+ for await (const event of super.execute(prepared)) {
10234
10165
  if (event.type === "done") this.enrichDoneEvent(event);
10235
10166
  yield event;
10236
10167
  }
@@ -10244,9 +10175,34 @@ var ClaudeCliRuntime = class extends CLIRuntimeBase {
10244
10175
  ];
10245
10176
  if (params.sessionId) args.push("--resume", params.sessionId);
10246
10177
  if (params.mcpServers && Object.keys(params.mcpServers).length > 0) args.push("--mcp-config", JSON.stringify({ mcpServers: params.mcpServers }));
10247
- args.push("--print", params.prompt);
10178
+ if (params.media?.some((m) => m.mimeType.startsWith("image/") && m.base64)) args.push("-p", "--input-format", "stream-json");
10179
+ else args.push("--print", params.prompt);
10248
10180
  return args;
10249
10181
  }
10182
+ buildStdinPayload(params) {
10183
+ const images = params.media?.filter((m) => m.mimeType.startsWith("image/") && m.base64);
10184
+ if (!images?.length) return;
10185
+ const content = images.map((img) => ({
10186
+ type: "image",
10187
+ source: {
10188
+ type: "base64",
10189
+ media_type: img.mimeType,
10190
+ data: img.base64
10191
+ }
10192
+ }));
10193
+ content.push({
10194
+ type: "text",
10195
+ text: params.prompt
10196
+ });
10197
+ const envelope = {
10198
+ type: "user",
10199
+ message: {
10200
+ role: "user",
10201
+ content
10202
+ }
10203
+ };
10204
+ return JSON.stringify(envelope) + "\n";
10205
+ }
10250
10206
  extractEvent(line) {
10251
10207
  const parsed = JSON.parse(line);
10252
10208
  if (!isObject$3(parsed)) return null;
@@ -10261,6 +10217,11 @@ var ClaudeCliRuntime = class extends CLIRuntimeBase {
10261
10217
  }
10262
10218
  if (parsed.type === "result") {
10263
10219
  this.storeResultData(parsed);
10220
+ if (parsed.is_error === true && typeof parsed.result === "string" && parsed.result) return {
10221
+ type: "error",
10222
+ message: parsed.result,
10223
+ code: "CLI_ERROR"
10224
+ };
10264
10225
  return null;
10265
10226
  }
10266
10227
  return null;
@@ -10303,6 +10264,10 @@ var ClaudeCliRuntime = class extends CLIRuntimeBase {
10303
10264
  if (this.toolBuffer) this.toolBuffer.input += delta.partial_json;
10304
10265
  return null;
10305
10266
  }
10267
+ if (delta.type === "thinking_delta" && typeof delta.thinking === "string") return {
10268
+ type: "thinking",
10269
+ text: delta.thinking
10270
+ };
10306
10271
  return null;
10307
10272
  }
10308
10273
  handleContentBlockStop() {
@@ -10349,6 +10314,37 @@ var ClaudeCliRuntime = class extends CLIRuntimeBase {
10349
10314
  if (this.resultData?.durationApiMs !== void 0) result.apiDurationMs = this.resultData.durationApiMs;
10350
10315
  if (this.resultData?.numTurns !== void 0) result.numTurns = this.resultData.numTurns;
10351
10316
  }
10317
+ /**
10318
+ * Read image files referenced by media attachments and populate their base64 field.
10319
+ * Non-image media types are filtered out (audio/video are not supported natively).
10320
+ */
10321
+ async prepareMedia(params) {
10322
+ if (!params.media?.length) return params;
10323
+ const prepared = [];
10324
+ for (const attachment of params.media) {
10325
+ if (!attachment.mimeType.startsWith("image/")) continue;
10326
+ if (attachment.base64) {
10327
+ prepared.push(attachment);
10328
+ continue;
10329
+ }
10330
+ if (attachment.filePath) {
10331
+ try {
10332
+ const buffer = await readFile(attachment.filePath);
10333
+ prepared.push({
10334
+ ...attachment,
10335
+ base64: buffer.toString("base64")
10336
+ });
10337
+ } catch {
10338
+ logDebug(`[claude-runtime] failed to read media file: ${attachment.filePath}`);
10339
+ }
10340
+ continue;
10341
+ }
10342
+ }
10343
+ return {
10344
+ ...params,
10345
+ media: prepared.length > 0 ? prepared : void 0
10346
+ };
10347
+ }
10352
10348
  resetState() {
10353
10349
  this.currentSessionId = void 0;
10354
10350
  this.accumulatedText = "";
@@ -10385,6 +10381,10 @@ function parseUsage(raw) {
10385
10381
  var CodexCliRuntime = class extends CLIRuntimeBase {
10386
10382
  constructor() {
10387
10383
  super("codex");
10384
+ this.mediaCapabilities = {
10385
+ acceptsInbound: ["image/"],
10386
+ emitsOutbound: false
10387
+ };
10388
10388
  this.accumulatedText = "";
10389
10389
  this.lastEmittedTextLength = 0;
10390
10390
  this.itemCounter = 0;
@@ -10413,13 +10413,17 @@ var CodexCliRuntime = class extends CLIRuntimeBase {
10413
10413
  params.sessionId,
10414
10414
  params.prompt
10415
10415
  ];
10416
- return [
10416
+ const args = [
10417
10417
  "exec",
10418
10418
  "--json",
10419
10419
  "--color",
10420
- "never",
10421
- params.prompt
10420
+ "never"
10422
10421
  ];
10422
+ if (params.media) {
10423
+ for (const attachment of params.media) if (attachment.mimeType.startsWith("image/") && attachment.filePath) args.push("--image", attachment.filePath);
10424
+ }
10425
+ args.push(params.prompt);
10426
+ return args;
10423
10427
  }
10424
10428
  extractEvent(line) {
10425
10429
  const parsed = JSON.parse(line);
@@ -10466,12 +10470,22 @@ var CodexCliRuntime = class extends CLIRuntimeBase {
10466
10470
  case "agent_message":
10467
10471
  this.lastEmittedTextLength = 0;
10468
10472
  return null;
10473
+ case "reasoning": return null;
10469
10474
  default: return null;
10470
10475
  }
10471
10476
  }
10472
10477
  handleItemUpdated(parsed) {
10473
10478
  const item = isObject$2(parsed.item) ? parsed.item : null;
10474
- if (!item || item.type !== "agent_message") return null;
10479
+ if (!item) return null;
10480
+ if (item.type === "reasoning") {
10481
+ const text = this.extractReasoningText(item);
10482
+ if (text) return {
10483
+ type: "thinking",
10484
+ text
10485
+ };
10486
+ return null;
10487
+ }
10488
+ if (item.type !== "agent_message") return null;
10475
10489
  const fullText = this.extractMessageText(item);
10476
10490
  if (fullText === void 0) return null;
10477
10491
  const delta = fullText.substring(this.lastEmittedTextLength);
@@ -10504,6 +10518,14 @@ var CodexCliRuntime = class extends CLIRuntimeBase {
10504
10518
  }
10505
10519
  return null;
10506
10520
  }
10521
+ case "reasoning": {
10522
+ const text = this.extractReasoningText(item);
10523
+ if (text) return {
10524
+ type: "thinking",
10525
+ text
10526
+ };
10527
+ return null;
10528
+ }
10507
10529
  case "command_execution": {
10508
10530
  const toolId = this.currentToolId ?? this.extractToolId(item);
10509
10531
  this.currentToolId = void 0;
@@ -10573,6 +10595,14 @@ var CodexCliRuntime = class extends CLIRuntimeBase {
10573
10595
  }
10574
10596
  if (typeof item.text === "string") return item.text;
10575
10597
  }
10598
+ extractReasoningText(item) {
10599
+ if (Array.isArray(item.summary)) {
10600
+ const textParts = [];
10601
+ for (const part of item.summary) if (isObject$2(part) && part.type === "summary_text" && typeof part.text === "string") textParts.push(part.text);
10602
+ if (textParts.length > 0) return textParts.join("");
10603
+ }
10604
+ if (typeof item.text === "string") return item.text;
10605
+ }
10576
10606
  resetState() {
10577
10607
  this.currentSessionId = void 0;
10578
10608
  this.accumulatedText = "";
@@ -10709,6 +10739,15 @@ function isObject$2(value) {
10709
10739
  var GeminiCliRuntime = class extends CLIRuntimeBase {
10710
10740
  constructor() {
10711
10741
  super("gemini");
10742
+ this.mediaCapabilities = {
10743
+ acceptsInbound: [
10744
+ "image/",
10745
+ "audio/",
10746
+ "video/",
10747
+ "application/pdf"
10748
+ ],
10749
+ emitsOutbound: false
10750
+ };
10712
10751
  this.accumulatedText = "";
10713
10752
  }
10714
10753
  get supportsStdinPrompt() {
@@ -10719,12 +10758,14 @@ var GeminiCliRuntime = class extends CLIRuntimeBase {
10719
10758
  const mcpConfigManager = params.mcpServers && Object.keys(params.mcpServers).length > 0 ? new GeminiMcpConfigManager(params.workingDirectory, params.mcpServers) : null;
10720
10759
  try {
10721
10760
  await mcpConfigManager?.setup();
10722
- for await (const event of super.execute(params)) {
10761
+ const prepared = await this.prepareMedia(params);
10762
+ for await (const event of super.execute(prepared)) {
10723
10763
  if (event.type === "done") this.enrichDoneEvent(event);
10724
10764
  yield event;
10725
10765
  }
10726
10766
  } finally {
10727
10767
  await mcpConfigManager?.teardown();
10768
+ await this.cleanupMediaTempDir();
10728
10769
  }
10729
10770
  }
10730
10771
  buildArgs(params) {
@@ -10814,10 +10855,52 @@ var GeminiCliRuntime = class extends CLIRuntimeBase {
10814
10855
  if (this.resultStats.toolCalls !== void 0) result.numTurns = this.resultStats.toolCalls;
10815
10856
  }
10816
10857
  }
10858
+ /**
10859
+ * Save media attachments to temp files and inject `@path` references into
10860
+ * the prompt. Gemini CLI resolves `@path` inline references natively.
10861
+ */
10862
+ async prepareMedia(params) {
10863
+ if (!params.media?.length) return params;
10864
+ const tempDir = join(tmpdir(), `remoteclaw-gemini-media-${randomUUID()}`);
10865
+ await mkdir(tempDir, { recursive: true });
10866
+ this.mediaTempDir = tempDir;
10867
+ const mediaRefs = [];
10868
+ for (const attachment of params.media) {
10869
+ const ext = extensionForMime(attachment.mimeType);
10870
+ const filePath = join(tempDir, `media-${mediaRefs.length}${ext}`);
10871
+ if (attachment.base64) {
10872
+ await writeFile(filePath, Buffer.from(attachment.base64, "base64"));
10873
+ mediaRefs.push(filePath);
10874
+ } else if (attachment.filePath) try {
10875
+ await writeFile(filePath, await readFile(attachment.filePath));
10876
+ mediaRefs.push(filePath);
10877
+ } catch {
10878
+ logDebug(`[gemini-runtime] failed to read media file: ${attachment.filePath}`);
10879
+ }
10880
+ }
10881
+ if (mediaRefs.length === 0) return params;
10882
+ const mediaPrefix = mediaRefs.map((ref) => `@${ref}`).join(" ");
10883
+ return {
10884
+ ...params,
10885
+ prompt: `${mediaPrefix} ${params.prompt}`
10886
+ };
10887
+ }
10888
+ async cleanupMediaTempDir() {
10889
+ if (this.mediaTempDir) {
10890
+ try {
10891
+ await rm(this.mediaTempDir, {
10892
+ recursive: true,
10893
+ force: true
10894
+ });
10895
+ } catch {}
10896
+ this.mediaTempDir = void 0;
10897
+ }
10898
+ }
10817
10899
  resetState() {
10818
10900
  this.currentSessionId = void 0;
10819
10901
  this.accumulatedText = "";
10820
10902
  this.resultStats = void 0;
10903
+ this.mediaTempDir = void 0;
10821
10904
  }
10822
10905
  };
10823
10906
  /**
@@ -10879,6 +10962,23 @@ var GeminiMcpConfigManager = class {
10879
10962
  function isObject$1(value) {
10880
10963
  return typeof value === "object" && value !== null && !Array.isArray(value);
10881
10964
  }
10965
+ /** Map common MIME types to file extensions for Gemini CLI `@path` references. */
10966
+ function extensionForMime(mimeType) {
10967
+ return {
10968
+ "image/jpeg": ".jpg",
10969
+ "image/png": ".png",
10970
+ "image/gif": ".gif",
10971
+ "image/webp": ".webp",
10972
+ "audio/ogg": ".ogg",
10973
+ "audio/mpeg": ".mp3",
10974
+ "audio/wav": ".wav",
10975
+ "audio/webm": ".weba",
10976
+ "video/mp4": ".mp4",
10977
+ "video/webm": ".webm",
10978
+ "video/quicktime": ".mov",
10979
+ "application/pdf": ".pdf"
10980
+ }[mimeType] ?? "";
10981
+ }
10882
10982
 
10883
10983
  //#endregion
10884
10984
  //#region src/middleware/runtimes/opencode.ts
@@ -10897,6 +10997,10 @@ function isObject$1(value) {
10897
10997
  var OpenCodeCliRuntime = class extends CLIRuntimeBase {
10898
10998
  constructor() {
10899
10999
  super("opencode");
11000
+ this.mediaCapabilities = {
11001
+ acceptsInbound: [],
11002
+ emitsOutbound: false
11003
+ };
10900
11004
  this.accumulatedText = "";
10901
11005
  this.pendingEvents = [];
10902
11006
  this.toolCounter = 0;
@@ -10935,7 +11039,7 @@ var OpenCodeCliRuntime = class extends CLIRuntimeBase {
10935
11039
  case "tool_use": return this.handleToolUse(data);
10936
11040
  case "step_start": return null;
10937
11041
  case "step_finish": return this.handleStepFinish(data);
10938
- case "reasoning": return null;
11042
+ case "reasoning": return this.handleReasoning(data);
10939
11043
  case "error": return this.handleError(data);
10940
11044
  default: return null;
10941
11045
  }
@@ -10981,6 +11085,14 @@ var OpenCodeCliRuntime = class extends CLIRuntimeBase {
10981
11085
  message: typeof parsed.message === "string" ? parsed.message : "Unknown error"
10982
11086
  };
10983
11087
  }
11088
+ handleReasoning(parsed) {
11089
+ const content = typeof parsed.text === "string" ? parsed.text : typeof parsed.content === "string" ? parsed.content : "";
11090
+ if (!content) return null;
11091
+ return {
11092
+ type: "thinking",
11093
+ text: content
11094
+ };
11095
+ }
10984
11096
  enrichDoneEvent(event) {
10985
11097
  const { result } = event;
10986
11098
  result.text = this.accumulatedText;
@@ -11075,12 +11187,42 @@ const SUPPORTED_PROVIDERS = [
11075
11187
  "codex",
11076
11188
  "opencode"
11077
11189
  ];
11190
+ const validatedCommands = /* @__PURE__ */ new Set();
11191
+ /**
11192
+ * Verify that a CLI binary exists on PATH.
11193
+ *
11194
+ * Results are cached per process lifetime so the `which` lookup runs at most
11195
+ * once per command.
11196
+ */
11197
+ function validateExecutable(command) {
11198
+ if (validatedCommands.has(command)) {
11199
+ logDebug(`[runtime-factory] executable already validated: ${command}`);
11200
+ return;
11201
+ }
11202
+ try {
11203
+ execFileSync("which", [command], { stdio: "ignore" });
11204
+ logDebug(`[runtime-factory] executable validated: ${command}`);
11205
+ validatedCommands.add(command);
11206
+ } catch {
11207
+ throw new Error(`Runtime '${command}' is configured but the '${command}' binary was not found on PATH. Install it or set agents.defaults.runtime to a different provider.`);
11208
+ }
11209
+ }
11078
11210
  function createCliRuntime(provider) {
11079
- switch (provider.trim().toLowerCase()) {
11080
- case "claude": return new ClaudeCliRuntime();
11081
- case "gemini": return new GeminiCliRuntime();
11082
- case "codex": return new CodexCliRuntime();
11083
- case "opencode": return new OpenCodeCliRuntime();
11211
+ const normalized = provider.trim().toLowerCase();
11212
+ logDebug(`[runtime-factory] creating runtime: provider=${normalized}`);
11213
+ switch (normalized) {
11214
+ case "claude":
11215
+ validateExecutable(normalized);
11216
+ return new ClaudeCliRuntime();
11217
+ case "gemini":
11218
+ validateExecutable(normalized);
11219
+ return new GeminiCliRuntime();
11220
+ case "codex":
11221
+ validateExecutable(normalized);
11222
+ return new CodexCliRuntime();
11223
+ case "opencode":
11224
+ validateExecutable(normalized);
11225
+ return new OpenCodeCliRuntime();
11084
11226
  default: throw new Error(`Unknown runtime provider "${provider}". Supported providers: ${SUPPORTED_PROVIDERS.join(", ")}`);
11085
11227
  }
11086
11228
  }
@@ -11231,6 +11373,8 @@ var ChannelBridge = class {
11231
11373
  #workspaceDir;
11232
11374
  #chunkLimit;
11233
11375
  #mcpServerPath;
11376
+ #runtimeArgs;
11377
+ #runtimeEnv;
11234
11378
  constructor(options) {
11235
11379
  this.#provider = options.provider;
11236
11380
  this.#sessionMap = options.sessionMap;
@@ -11239,6 +11383,8 @@ var ChannelBridge = class {
11239
11383
  this.#workspaceDir = options.workspaceDir ?? DEFAULT_WORKSPACE_DIR;
11240
11384
  this.#chunkLimit = options.chunkLimit;
11241
11385
  this.#mcpServerPath = options.mcpServerPath ?? DEFAULT_MCP_SERVER_PATH;
11386
+ this.#runtimeArgs = options.runtimeArgs;
11387
+ this.#runtimeEnv = options.runtimeEnv;
11242
11388
  }
11243
11389
  /**
11244
11390
  * Process an incoming channel message through the full agent execution pipeline.
@@ -11248,7 +11394,9 @@ var ChannelBridge = class {
11248
11394
  */
11249
11395
  async handle(message, callbacks, abortSignal) {
11250
11396
  const sessionKey = buildSessionKey(message);
11397
+ logDebug(`[channel-bridge] handle: channel=${message.provider} from=${message.from} channelId=${message.channelId} threadId=${message.replyToId ?? "none"} agentId=${message.agentId ?? "default"} media=${message.mediaUrls?.length ?? 0}`);
11251
11398
  const existingSessionId = await this.#sessionMap.get(sessionKey);
11399
+ logDebug(`[channel-bridge] session lookup: key=${formatSessionKeyString(sessionKey)} ${existingSessionId ? `hit=${existingSessionId}` : "miss"}`);
11252
11400
  const hookRunner = getGlobalHookRunner();
11253
11401
  if (existingSessionId && hookRunner?.hasHooks("session_resumed")) await hookRunner.runSessionResumed({
11254
11402
  sessionId: existingSessionId,
@@ -11275,9 +11423,10 @@ var ChannelBridge = class {
11275
11423
  const sideEffectsFile = join(invocationDir, "side-effects.ndjson");
11276
11424
  try {
11277
11425
  const mcpServers = this.#buildMcpConfig(message, sessionKey, sideEffectsFile);
11426
+ logDebug(`[channel-bridge] creating runtime: provider=${this.#provider}`);
11278
11427
  const runtime = createCliRuntime(this.#provider);
11279
11428
  let workspaceDir = this.#workspaceDir;
11280
- let extraEnv;
11429
+ let hookEnv;
11281
11430
  const runId = randomUUID();
11282
11431
  if (hookRunner?.hasHooks("before_runtime_spawn")) {
11283
11432
  const spawnResult = await hookRunner.runBeforeRuntimeSpawn({
@@ -11293,9 +11442,23 @@ var ChannelBridge = class {
11293
11442
  channelId: message.channelId,
11294
11443
  runtimeName: this.#provider
11295
11444
  });
11296
- if (spawnResult?.workspaceDir) workspaceDir = spawnResult.workspaceDir;
11297
- if (spawnResult?.env) extraEnv = spawnResult.env;
11445
+ if (spawnResult?.workspaceDir) {
11446
+ logDebug(`[channel-bridge] hook overrode workspaceDir: ${this.#workspaceDir} -> ${spawnResult.workspaceDir}`);
11447
+ workspaceDir = spawnResult.workspaceDir;
11448
+ }
11449
+ if (spawnResult?.env) {
11450
+ logDebug(`[channel-bridge] hook injected env keys: ${Object.keys(spawnResult.env).join(", ")}`);
11451
+ hookEnv = spawnResult.env;
11452
+ }
11298
11453
  }
11454
+ const resolvedMedia = message.mediaUrls?.length ? await resolveMediaAttachments(message.mediaUrls, invocationDir) : void 0;
11455
+ if (resolvedMedia?.length) logDebug(`[channel-bridge] resolved ${resolvedMedia.length}/${message.mediaUrls.length} media attachments`);
11456
+ const { supported: supportedMedia, unsupported: unsupportedMedia } = resolvedMedia?.length ? partitionMedia(runtime, resolvedMedia) : {
11457
+ supported: [],
11458
+ unsupported: []
11459
+ };
11460
+ const mediaWarning = formatUnsupportedMediaWarning(unsupportedMedia, this.#provider);
11461
+ if (unsupportedMedia.length > 0) logDebug(`[channel-bridge] unsupported media: ${unsupportedMedia.length} attachment(s) not accepted by ${this.#provider}`);
11299
11462
  const adapter = new DeliveryAdapter(this.#chunkLimit !== void 0 ? { chunkLimit: this.#chunkLimit } : void 0);
11300
11463
  let runResult;
11301
11464
  let lastError;
@@ -11303,11 +11466,16 @@ var ChannelBridge = class {
11303
11466
  try {
11304
11467
  const captured = captureResult(runtime.execute({
11305
11468
  prompt: systemPrompt + (message.extraContext ? "\n\n" + message.extraContext : "") + "\n\n" + message.text,
11469
+ media: supportedMedia?.length ? supportedMedia : void 0,
11306
11470
  sessionId: existingSessionId,
11307
11471
  mcpServers,
11308
11472
  abortSignal,
11309
11473
  workingDirectory: workspaceDir,
11310
- env: extraEnv
11474
+ env: this.#runtimeEnv || hookEnv ? {
11475
+ ...this.#runtimeEnv,
11476
+ ...hookEnv
11477
+ } : void 0,
11478
+ extraArgs: this.#runtimeArgs
11311
11479
  }));
11312
11480
  payloads = await adapter.process(captured.events, callbacks);
11313
11481
  runResult = captured.getResult();
@@ -11315,6 +11483,7 @@ var ChannelBridge = class {
11315
11483
  } catch (err) {
11316
11484
  const errMsg = String(err);
11317
11485
  const category = classifyError(errMsg);
11486
+ logDebug(`[channel-bridge] runtime threw: category=${category} error=${errMsg.slice(0, 500)}`);
11318
11487
  lastError = errMsg;
11319
11488
  payloads = [];
11320
11489
  runResult = {
@@ -11322,13 +11491,18 @@ var ChannelBridge = class {
11322
11491
  errorSubtype: category === "context_overflow" ? "context_window" : category
11323
11492
  };
11324
11493
  }
11494
+ if (mediaWarning) payloads.unshift({ text: mediaWarning });
11325
11495
  let mcp;
11326
11496
  try {
11327
11497
  mcp = await readMcpSideEffects(sideEffectsFile);
11328
11498
  } catch {
11329
11499
  mcp = { ...EMPTY_SIDE_EFFECTS };
11330
11500
  }
11331
- if (runResult?.sessionId) await this.#sessionMap.set(sessionKey, runResult.sessionId);
11501
+ logDebug(`[channel-bridge] side effects: sentTexts=${mcp.sentTexts.length} sentMedia=${mcp.sentMediaUrls.length} cronAdds=${mcp.cronAdds}`);
11502
+ if (runResult?.sessionId) {
11503
+ logDebug(`[channel-bridge] session update: key=${formatSessionKeyString(sessionKey)} sessionId=${runResult.sessionId}`);
11504
+ await this.#sessionMap.set(sessionKey, runResult.sessionId);
11505
+ }
11332
11506
  const finalResult = runResult ?? { ...DEFAULT_RUN_RESULT };
11333
11507
  if (hookRunner) {
11334
11508
  const runtimeCtx = {
@@ -11356,6 +11530,7 @@ var ChannelBridge = class {
11356
11530
  durationMs: finalResult.durationMs
11357
11531
  }, runtimeCtx);
11358
11532
  }
11533
+ logDebug(`[channel-bridge] complete: runId=${runId} duration=${finalResult.durationMs}ms payloads=${payloads.length} error=${lastError ?? "none"}`);
11359
11534
  return {
11360
11535
  payloads,
11361
11536
  run: finalResult,
@@ -11517,4 +11692,4 @@ function resolveGatewayCredentialsFromConfig(params) {
11517
11692
  }
11518
11693
 
11519
11694
  //#endregion
11520
- export { ChannelBridge, DEFAULT_MODEL, DEFAULT_PROVIDER, ensureAgentWorkspace, loadSessionStore, resolveAgentDir, resolveAgentIdentity, resolveAgentTimeoutMs, resolveAgentWorkspaceDir, resolveGatewayCredentialsFromConfig, resolveGatewayPort, resolveSessionFilePath, resolveStorePath, saveSessionStore };
11695
+ export { ChannelBridge, ensureAgentWorkspace, loadSessionStore, resolveAgentDir, resolveAgentIdentity, resolveAgentTimeoutMs, resolveAgentWorkspaceDir, resolveGatewayCredentialsFromConfig, resolveGatewayPort, resolveSessionFilePath, resolveStorePath, saveSessionStore };