@captain-app/openclaw 2026.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1686) hide show
  1. package/CHANGELOG.md +1528 -0
  2. package/LICENSE +21 -0
  3. package/README-header.png +0 -0
  4. package/README.md +539 -0
  5. package/assets/avatar-placeholder.svg +19 -0
  6. package/assets/chrome-extension/README.md +22 -0
  7. package/assets/chrome-extension/background.js +438 -0
  8. package/assets/chrome-extension/icons/icon128.png +0 -0
  9. package/assets/chrome-extension/icons/icon16.png +0 -0
  10. package/assets/chrome-extension/icons/icon32.png +0 -0
  11. package/assets/chrome-extension/icons/icon48.png +0 -0
  12. package/assets/chrome-extension/manifest.json +25 -0
  13. package/assets/chrome-extension/options.html +196 -0
  14. package/assets/chrome-extension/options.js +59 -0
  15. package/assets/dmg-background-small.png +0 -0
  16. package/assets/dmg-background.png +0 -0
  17. package/dist/accounts-ClnuDahN.js +250 -0
  18. package/dist/accounts-DzBgAM3C.js +251 -0
  19. package/dist/acp-cli-BEDDkzXH.js +926 -0
  20. package/dist/acp-cli-CwV4mdnW.js +923 -0
  21. package/dist/agent-CArjbSeE.js +695 -0
  22. package/dist/agent-CB7x5HLT.js +695 -0
  23. package/dist/agent-scope-BbT4OG2N.js +545 -0
  24. package/dist/agent-scope-C_O6Vpl0.js +545 -0
  25. package/dist/agent-scope-Csu2B6AM.js +606 -0
  26. package/dist/archive-CWrnG1CH.js +85 -0
  27. package/dist/archive-ccN9aDgq.js +85 -0
  28. package/dist/audit-DXPkQ275.js +1686 -0
  29. package/dist/audit-eH7nwgsM.js +1686 -0
  30. package/dist/auth-health-Bj7Gjbv0.js +149 -0
  31. package/dist/auth-health-CjjJhHey.js +149 -0
  32. package/dist/auth-nnRYiqpH.js +192 -0
  33. package/dist/auth-profiles-DVLfuixr.js +2954 -0
  34. package/dist/auth-y1BLPUhX.js +192 -0
  35. package/dist/boolean-Wzu0-e0P.js +30 -0
  36. package/dist/brew-Cqi8b49_.js +46 -0
  37. package/dist/brew-DyBGNK8A.js +46 -0
  38. package/dist/build-info.json +5 -0
  39. package/dist/call-B7EveN4V.js +252 -0
  40. package/dist/call-vuUQIjOj.js +252 -0
  41. package/dist/canvas-host/a2ui/.bundle.hash +1 -0
  42. package/dist/canvas-host/a2ui/a2ui.bundle.js +17780 -0
  43. package/dist/canvas-host/a2ui/index.html +307 -0
  44. package/dist/channel-options-CJfmOkol.js +32 -0
  45. package/dist/channel-options-lFguMTz1.js +62 -0
  46. package/dist/channel-selection-BmND9mWj.js +51 -0
  47. package/dist/channel-selection-cGhL9G0c.js +51 -0
  48. package/dist/channel-summary-B4G513Eb.js +1154 -0
  49. package/dist/channel-summary-MCwBCa5y.js +1154 -0
  50. package/dist/channels-cli-C2Of1mZG.js +1411 -0
  51. package/dist/channels-cli-DFynrP1H.js +1413 -0
  52. package/dist/channels-status-issues-YohTjZ-I.js +18 -0
  53. package/dist/channels-status-issues-ZcR1U-m5.js +18 -0
  54. package/dist/chrome-B3IuUad-.js +1953 -0
  55. package/dist/chrome-BZ9K48w9.js +1973 -0
  56. package/dist/clack-prompter-B9yLhyOm.js +92 -0
  57. package/dist/clack-prompter-BybM9xdL.js +92 -0
  58. package/dist/cli/daemon-cli.js +2 -0
  59. package/dist/cli-BJZdJwug.js +89 -0
  60. package/dist/cli-BQSoKu3d.js +86 -0
  61. package/dist/cli-utils-CO4jEMn0.js +43 -0
  62. package/dist/cli-utils-gtE-0a0D.js +43 -0
  63. package/dist/client-DPqNOpK3.js +1609 -0
  64. package/dist/client-DySXIFCA.js +1609 -0
  65. package/dist/command-format-CFzL448l.js +52 -0
  66. package/dist/command-format-DELazozB.js +52 -0
  67. package/dist/command-format-ayFsmwwz.js +38 -0
  68. package/dist/command-options-CsjxK4cZ.js +33 -0
  69. package/dist/commands-BRe9VTyU.js +229 -0
  70. package/dist/completion-cli-DlkjK0iC.js +390 -0
  71. package/dist/completion-cli-E6Pt41AL.js +387 -0
  72. package/dist/config-BtSTwPcH.js +4882 -0
  73. package/dist/config-DfMIMT-f.js +4881 -0
  74. package/dist/config-_d7_WcRv.js +5623 -0
  75. package/dist/config-guard-wSnm-U8a.js +5628 -0
  76. package/dist/configure-CPHAFKlg.js +895 -0
  77. package/dist/configure-DK1XgXYx.js +894 -0
  78. package/dist/constants-CNTiY-ZN.js +65 -0
  79. package/dist/constants-hpmbslG7.js +65 -0
  80. package/dist/control-service-CqX5g_ko.js +61 -0
  81. package/dist/control-service-o6xe3hEb.js +61 -0
  82. package/dist/control-ui/apple-touch-icon.png +0 -0
  83. package/dist/control-ui/assets/index-RwcW4Xl0.css +1 -0
  84. package/dist/control-ui/assets/index-ryaCcbyp.js +4584 -0
  85. package/dist/control-ui/assets/index-ryaCcbyp.js.map +1 -0
  86. package/dist/control-ui/favicon-32.png +0 -0
  87. package/dist/control-ui/favicon.ico +0 -0
  88. package/dist/control-ui/favicon.svg +22 -0
  89. package/dist/control-ui/index.html +17 -0
  90. package/dist/cron-cli-BoSaDgvH.js +453 -0
  91. package/dist/cron-cli-qVandvsD.js +456 -0
  92. package/dist/daemon-cli-C4gGWa15.js +760 -0
  93. package/dist/daemon-cli-DV_X0Krf.js +761 -0
  94. package/dist/daemon-runtime-D5hbSrdO.js +460 -0
  95. package/dist/daemon-runtime-DXUfrXBC.js +460 -0
  96. package/dist/deliver-BxK5nI2P.js +2587 -0
  97. package/dist/deliver-Dwzg9LUd.js +2557 -0
  98. package/dist/deliver-qpYZp20m.js +2587 -0
  99. package/dist/deps-CUXtMV9d.js +27 -0
  100. package/dist/deps-WBvZpFV_.js +27 -0
  101. package/dist/devices-cli-B2s18Qrh.js +207 -0
  102. package/dist/devices-cli-D1UEtMUJ.js +204 -0
  103. package/dist/directory-cli-BXQbrkfM.js +247 -0
  104. package/dist/directory-cli-CqA7tRbq.js +244 -0
  105. package/dist/dispatcher-Dyv7T-1r.js +160 -0
  106. package/dist/dns-cli-CWxKD22D.js +198 -0
  107. package/dist/dns-cli-CzKr_Fxj.js +201 -0
  108. package/dist/docs-cli-BNyxUbWr.js +159 -0
  109. package/dist/docs-cli-DYpTbo3i.js +161 -0
  110. package/dist/doctor-C8fDYZLq.js +2583 -0
  111. package/dist/doctor-hYcqp7c0.js +2585 -0
  112. package/dist/entry.js +1326 -0
  113. package/dist/env-l7QVNj6j.js +32 -0
  114. package/dist/errors-CMCg46fK.js +1952 -0
  115. package/dist/exec-B8JKbXKW.js +246 -0
  116. package/dist/exec-BMnoMcZW.js +1099 -0
  117. package/dist/exec-HEWTMJ7j.js +246 -0
  118. package/dist/exec-approvals-DtrnHx6M.js +1026 -0
  119. package/dist/exec-approvals-Y42bE8ud.js +1026 -0
  120. package/dist/exec-approvals-cli-CIedYxP3.js +385 -0
  121. package/dist/exec-approvals-cli-xpbxnj4O.js +388 -0
  122. package/dist/extensionAPI.js +66572 -0
  123. package/dist/format-Dzy9uRLE.js +34 -0
  124. package/dist/format-sj0fELBK.js +34 -0
  125. package/dist/gateway-cli-5A-KNLEC.js +16635 -0
  126. package/dist/gateway-cli-B8kS4chb.js +16637 -0
  127. package/dist/gateway-rpc-15n38Ize.js +28 -0
  128. package/dist/gateway-rpc-TMVRgGfj.js +28 -0
  129. package/dist/github-copilot-auth-DVZj4Zgh.js +1104 -0
  130. package/dist/github-copilot-auth-DeGYyLY9.js +1104 -0
  131. package/dist/github-copilot-token-B3SA95yo.js +103 -0
  132. package/dist/github-copilot-token-C8XFYz0i.js +103 -0
  133. package/dist/github-copilot-token-CnxakiSC.js +103 -0
  134. package/dist/gmail-setup-utils-CWPC386a.js +428 -0
  135. package/dist/gmail-setup-utils-eJVB5Ewp.js +428 -0
  136. package/dist/health-format-B0tMTk3C.js +1189 -0
  137. package/dist/health-format-DaURVaUn.js +1188 -0
  138. package/dist/help-format-CEsRHU2f.js +17 -0
  139. package/dist/help-format-GuCWws6r.js +17 -0
  140. package/dist/helpers-BEJ-phFf.js +25 -0
  141. package/dist/helpers-BtbBZVKZ.js +10 -0
  142. package/dist/helpers-C12w9zxf.js +10 -0
  143. package/dist/helpers-CzjGJZmJ.js +25 -0
  144. package/dist/hooks/bundled/boot-md/HOOK.md +19 -0
  145. package/dist/hooks/bundled/command-logger/HOOK.md +122 -0
  146. package/dist/hooks/bundled/session-memory/HOOK.md +109 -0
  147. package/dist/hooks/bundled/soul-evil/HOOK.md +71 -0
  148. package/dist/hooks-cli-BZCMAnW2.js +1058 -0
  149. package/dist/hooks-cli-D0CEFg3P.js +1061 -0
  150. package/dist/hooks-status-Bn7_O8PM.js +443 -0
  151. package/dist/hooks-status-BrWVfIn0.js +443 -0
  152. package/dist/image-BS022pvv.js +1421 -0
  153. package/dist/image-BzJtY34J.js +629 -0
  154. package/dist/image-CBqmIbQQ.js +629 -0
  155. package/dist/index.js +5809 -0
  156. package/dist/installs-BP4K5L33.js +388 -0
  157. package/dist/installs-DOpTt7VZ.js +388 -0
  158. package/dist/is-main-B4o72sqg.js +25 -0
  159. package/dist/is-main-PYGa3tDA.js +25 -0
  160. package/dist/links-B4nk2iDf.js +15 -0
  161. package/dist/links-DwjRqxgR.js +15 -0
  162. package/dist/loader-Cn4EV_pf.js +63690 -0
  163. package/dist/logging-CS3tbYDj.js +15 -0
  164. package/dist/logging-CY-Q5cwf.js +1 -0
  165. package/dist/logging-DhiLkhLw.js +15 -0
  166. package/dist/logging-pqyrk15z.js +1 -0
  167. package/dist/login-qr-CD164Aw1.js +478 -0
  168. package/dist/login-qr-D7Zdgji2.js +478 -0
  169. package/dist/login-qr-YgILJ4VC.js +475 -0
  170. package/dist/logs-cli-BdS0Uv0I.js +227 -0
  171. package/dist/logs-cli-CqSN1GzB.js +230 -0
  172. package/dist/manager-CfGY5zND.js +2870 -0
  173. package/dist/manager-CjuBqFRL.js +2870 -0
  174. package/dist/manager-CoBEAQKm.js +2872 -0
  175. package/dist/manifest-registry-Bwjq9Iev.js +668 -0
  176. package/dist/manifest-registry-D2Yntqcb.js +668 -0
  177. package/dist/message-channel-Cjsiqxok.js +105 -0
  178. package/dist/message-channel-D6v_oPAg.js +105 -0
  179. package/dist/model-selection-Cv5Ox_tY.js +2956 -0
  180. package/dist/model-selection-Dr-5U5-l.js +2708 -0
  181. package/dist/models-cli-B39ckynD.js +2541 -0
  182. package/dist/models-cli-DoiYsBYw.js +2544 -0
  183. package/dist/net-CFCxaipF.js +137 -0
  184. package/dist/net-DKJPqXuW.js +137 -0
  185. package/dist/node-cli-C_FYF-RA.js +1456 -0
  186. package/dist/node-cli-DWPoNsQS.js +1459 -0
  187. package/dist/node-service-DcJREOww.js +67 -0
  188. package/dist/node-service-DuZ9Us9h.js +67 -0
  189. package/dist/nodes-cli-Elo6tlen.js +1210 -0
  190. package/dist/nodes-cli-zqryRUWB.js +1207 -0
  191. package/dist/nodes-screen-C4aCrxie.js +157 -0
  192. package/dist/nodes-screen-D4PSynkR.js +157 -0
  193. package/dist/note-CQhSvgQv.js +73 -0
  194. package/dist/note-_C44YfAQ.js +73 -0
  195. package/dist/onboard-channels-CHBDi-ZA.js +670 -0
  196. package/dist/onboard-channels-DOEKyxaL.js +670 -0
  197. package/dist/onboard-skills-BUTXREDZ.js +3327 -0
  198. package/dist/onboard-skills-CSLYZmZA.js +3327 -0
  199. package/dist/onboarding-CgKb8b39.js +3232 -0
  200. package/dist/openclaw-root-9ILYSmJ9.js +84 -0
  201. package/dist/openclaw-root-Cvotktkd.js +84 -0
  202. package/dist/pairing-cli-B4UGR2at.js +114 -0
  203. package/dist/pairing-cli-BWDDl8cf.js +117 -0
  204. package/dist/pairing-labels-ClZ-fTWT.js +9 -0
  205. package/dist/pairing-labels-Ds7BPOkj.js +9 -0
  206. package/dist/pairing-store-DDLNuzmx.js +391 -0
  207. package/dist/pairing-store-DRn08lZD.js +391 -0
  208. package/dist/parse-87ybtYW1.js +23 -0
  209. package/dist/parse-OCFfznr3.js +23 -0
  210. package/dist/parse-log-line-C9aL5PUL.js +44 -0
  211. package/dist/parse-log-line-DxRaGzQb.js +44 -0
  212. package/dist/parse-timeout-CFqNj7No.js +16 -0
  213. package/dist/parse-timeout-DV8NQQWk.js +16 -0
  214. package/dist/path-env-C7kiJUgG.js +77 -0
  215. package/dist/path-env-DEj4CiFN.js +77 -0
  216. package/dist/paths-B-q1nXdY.js +43 -0
  217. package/dist/paths-B1kfl4h5.js +164 -0
  218. package/dist/paths-B4kigINg.js +40 -0
  219. package/dist/paths-CHGbP1-A.js +43 -0
  220. package/dist/paths-scjhy7N2.js +180 -0
  221. package/dist/pi-embedded-helpers-C19wUpMB.js +8451 -0
  222. package/dist/pi-embedded-helpers-CT5VuLCb.js +1293 -0
  223. package/dist/pi-embedded-helpers-Dl8e5Rf8.js +1293 -0
  224. package/dist/pi-model-discovery-B6CsmK6Y.js +20 -0
  225. package/dist/pi-model-discovery-DsRqYJLy.js +20 -0
  226. package/dist/pi-model-discovery-EhM2JAQo.js +20 -0
  227. package/dist/pi-tools.policy-BvkSDFDN.js +229 -0
  228. package/dist/plugin-auto-enable-Bd_StZzz.js +461 -0
  229. package/dist/plugin-auto-enable-DBhXb_0x.js +461 -0
  230. package/dist/plugin-sdk/agent-scope-DdwUKIOe.js +606 -0
  231. package/dist/plugin-sdk/chrome-G8apFa5p.js +1953 -0
  232. package/dist/plugin-sdk/command-format-qUVxzqYm.js +52 -0
  233. package/dist/plugin-sdk/config-Cm1M7tgH.js +5623 -0
  234. package/dist/plugin-sdk/deliver-Cl8uowiO.js +2557 -0
  235. package/dist/plugin-sdk/exec-Cm9b2r9Q.js +1107 -0
  236. package/dist/plugin-sdk/github-copilot-token-BHNcM4_B.js +103 -0
  237. package/dist/plugin-sdk/image-7PgoS2VD.js +1421 -0
  238. package/dist/plugin-sdk/index.d.ts +8908 -0
  239. package/dist/plugin-sdk/index.js +70888 -0
  240. package/dist/plugin-sdk/login-qr-qTALvWi2.js +475 -0
  241. package/dist/plugin-sdk/manager-Cs3EQZCb.js +2870 -0
  242. package/dist/plugin-sdk/model-selection-BgC1E1a7.js +2708 -0
  243. package/dist/plugin-sdk/paths-BYpoyRv5.js +164 -0
  244. package/dist/plugin-sdk/paths-DNQE-bvr.js +40 -0
  245. package/dist/plugin-sdk/pi-embedded-helpers-5jNqW_dE.js +8755 -0
  246. package/dist/plugin-sdk/pi-model-discovery-BUGEht9A.js +20 -0
  247. package/dist/plugin-sdk/pw-ai-COTtei4a.js +1649 -0
  248. package/dist/plugin-sdk/qmd-manager-ClSwiAJl.js +615 -0
  249. package/dist/plugin-sdk/redact-2AzjOfk2.js +94 -0
  250. package/dist/plugin-sdk/rolldown-runtime-Cbj13DAv.js +20 -0
  251. package/dist/plugin-sdk/sqlite-gCW7MlLs.js +215 -0
  252. package/dist/plugin-sdk/transcript-events-DGF257vD.js +17 -0
  253. package/dist/plugins-C3Bm-HQV.js +494 -0
  254. package/dist/plugins-QJjTXliB.js +495 -0
  255. package/dist/plugins-cli-DTci0JQb.js +443 -0
  256. package/dist/plugins-cli-wJsN1HHK.js +440 -0
  257. package/dist/ports-CiW9dmMq.js +96 -0
  258. package/dist/program-BWpTHh1I.js +188 -0
  259. package/dist/progress-Bcjniu7m.js +133 -0
  260. package/dist/progress-CvaSPjS9.js +133 -0
  261. package/dist/prompt-style-CFsleyxV.js +9 -0
  262. package/dist/prompt-style-DYJdrXyV.js +9 -0
  263. package/dist/prompts-Bt9fwsg2.js +10 -0
  264. package/dist/prompts-CudpZgTI.js +10 -0
  265. package/dist/pw-ai-08F3GD-3.js +1649 -0
  266. package/dist/pw-ai-ZmHxHQnx.js +1651 -0
  267. package/dist/pw-ai-tNPuRNn3.js +1649 -0
  268. package/dist/qmd-manager-2r-4n3sP.js +617 -0
  269. package/dist/qmd-manager-CF52nuBg.js +615 -0
  270. package/dist/qmd-manager-HEm5H2mk.js +616 -0
  271. package/dist/redact-BICFkpn7.js +97 -0
  272. package/dist/redact-BIMJ3ntQ.js +94 -0
  273. package/dist/redact-KzWHRS5J.js +97 -0
  274. package/dist/register.subclis-D2K25c84.js +348 -0
  275. package/dist/register.subclis-Dd8LbOLi.js +342 -0
  276. package/dist/reply-5UNWRwMn.js +63693 -0
  277. package/dist/restart-sentinel-Cr0vUxB8.js +65 -0
  278. package/dist/restart-sentinel-DUemCjgU.js +65 -0
  279. package/dist/rolldown-runtime-Cbj13DAv.js +20 -0
  280. package/dist/routes-C6UpTPas.js +2410 -0
  281. package/dist/routes-ClNyEvlm.js +2410 -0
  282. package/dist/rpc-D0mf7DIw.js +95 -0
  283. package/dist/rpc-DYdOrgd9.js +95 -0
  284. package/dist/run-main-CojI7gWx.js +194 -0
  285. package/dist/runtime-guard-68M_evhb.js +60 -0
  286. package/dist/runtime-guard-DkjmhnBD.js +60 -0
  287. package/dist/sandbox-Ca81z3Tw.js +2924 -0
  288. package/dist/sandbox-cli-D75GApgp.js +459 -0
  289. package/dist/sandbox-cli-E4SJsC1C.js +462 -0
  290. package/dist/sandbox-knontqD9.js +2925 -0
  291. package/dist/security-cli-BLihvXO-.js +503 -0
  292. package/dist/security-cli-IGQCsK4g.js +506 -0
  293. package/dist/server-context-B9GX5GOI.js +740 -0
  294. package/dist/server-context-BFH7HB_M.js +740 -0
  295. package/dist/server-node-events-CTdHBiEA.js +218 -0
  296. package/dist/server-node-events-DAV14qPr.js +215 -0
  297. package/dist/service-BZNBq9hq.js +680 -0
  298. package/dist/service-C-BLXx9U.js +680 -0
  299. package/dist/service-audit-BfJv4NqZ.js +542 -0
  300. package/dist/service-audit-Bw3M2OEI.js +542 -0
  301. package/dist/shared-5SH-45AX.js +74 -0
  302. package/dist/shared-BxRm5uLU.js +74 -0
  303. package/dist/shared-C80Rmxsd.js +150 -0
  304. package/dist/shared-fGK6_D2v.js +150 -0
  305. package/dist/skills-Bhp0l6UK.js +693 -0
  306. package/dist/skills-Tky2kCMO.js +694 -0
  307. package/dist/skills-cli-6rCClAE4.js +287 -0
  308. package/dist/skills-cli-C4nLCrLw.js +290 -0
  309. package/dist/skills-status-CENcKr3I.js +187 -0
  310. package/dist/skills-status-DX1eUYvk.js +187 -0
  311. package/dist/sqlite-CmdZSZRx.js +197 -0
  312. package/dist/sqlite-Dnmf3LS7.js +215 -0
  313. package/dist/sqlite-QDf0yuU0.js +215 -0
  314. package/dist/status-BSfGAp2D.js +27 -0
  315. package/dist/status-Bp_2NMjt.js +27 -0
  316. package/dist/status-C0ANDr0T.js +3140 -0
  317. package/dist/status-CCHBIZnm.js +21 -0
  318. package/dist/status-Vuqbw2Bb.js +21 -0
  319. package/dist/status.update-BZW5r8Su.js +79 -0
  320. package/dist/status.update-BnD93_O8.js +79 -0
  321. package/dist/subsystem-CAq3uyo7.js +834 -0
  322. package/dist/system-cli-Bb9zmCO1.js +83 -0
  323. package/dist/system-cli-TIIQ04ls.js +80 -0
  324. package/dist/systemd-0Qa_nGqe.js +438 -0
  325. package/dist/systemd-Czb0Xsm7.js +438 -0
  326. package/dist/systemd-hints-CWoEOQRb.js +19 -0
  327. package/dist/systemd-hints-Cv3RN_mZ.js +19 -0
  328. package/dist/systemd-linger-CsdvcIoS.js +75 -0
  329. package/dist/systemd-linger-DKUFHcLn.js +75 -0
  330. package/dist/table-DNPESyNj.js +279 -0
  331. package/dist/table-DS4-gmkV.js +279 -0
  332. package/dist/tailnet-Bg_vE5qi.js +42 -0
  333. package/dist/tailnet-CrNWlQRJ.js +42 -0
  334. package/dist/tailscale-CBv58toW.js +252 -0
  335. package/dist/tailscale-DCnMs7_q.js +225 -0
  336. package/dist/tool-display-BEACy9rK.js +795 -0
  337. package/dist/tool-display-NYQnSpdo.js +795 -0
  338. package/dist/transcript-events-CsB1Saa6.js +17 -0
  339. package/dist/transcript-events-DDYvbmRV.js +17 -0
  340. package/dist/transcript-events-JLH5W4He.js +17 -0
  341. package/dist/tui--NY0rnjr.js +2542 -0
  342. package/dist/tui-DqJfGtvM.js +2543 -0
  343. package/dist/tui-cli-BuHNY6wF.js +54 -0
  344. package/dist/tui-cli-LMFV982e.js +57 -0
  345. package/dist/update-CRpHtCgz.js +317 -0
  346. package/dist/update-D3qruxhj.js +317 -0
  347. package/dist/update-cli-CFF-pslM.js +948 -0
  348. package/dist/update-cli-cn9pEMX7.js +951 -0
  349. package/dist/update-runner-CxGU142L.js +1221 -0
  350. package/dist/update-runner-DNobz_ft.js +1221 -0
  351. package/dist/utils-CKSrBNwq.js +192 -0
  352. package/dist/utils-DX85MiPR.js +188 -0
  353. package/dist/webhooks-cli-BGtt2HAR.js +312 -0
  354. package/dist/webhooks-cli-DHLZrEO_.js +309 -0
  355. package/dist/widearea-dns-BpG7ATO8.js +127 -0
  356. package/dist/widearea-dns-D4wkCJly.js +127 -0
  357. package/dist/ws-3zr8WUwL.js +13 -0
  358. package/dist/ws-log-BXcT2xQk.js +267 -0
  359. package/dist/ws-log-DbDIUsgz.js +267 -0
  360. package/dist/ws-lzrgabja.js +13 -0
  361. package/dist/wsl-D2O2qOrl.js +160 -0
  362. package/docs/.i18n/README.md +31 -0
  363. package/docs/.i18n/glossary.zh-CN.json +190 -0
  364. package/docs/.i18n/zh-CN.tm.jsonl +1329 -0
  365. package/docs/CNAME +1 -0
  366. package/docs/_config.yml +53 -0
  367. package/docs/_layouts/default.html +145 -0
  368. package/docs/assets/markdown.css +179 -0
  369. package/docs/assets/openclaw-logo-text-dark.png +0 -0
  370. package/docs/assets/openclaw-logo-text.png +0 -0
  371. package/docs/assets/pixel-lobster.svg +60 -0
  372. package/docs/assets/showcase/agents-ui.jpg +0 -0
  373. package/docs/assets/showcase/bambu-cli.png +0 -0
  374. package/docs/assets/showcase/codexmonitor.png +0 -0
  375. package/docs/assets/showcase/gohome-grafana.png +0 -0
  376. package/docs/assets/showcase/ios-testflight.jpg +0 -0
  377. package/docs/assets/showcase/oura-health.png +0 -0
  378. package/docs/assets/showcase/padel-cli.svg +11 -0
  379. package/docs/assets/showcase/padel-screenshot.jpg +0 -0
  380. package/docs/assets/showcase/papla-tts.jpg +0 -0
  381. package/docs/assets/showcase/pr-review-telegram.jpg +0 -0
  382. package/docs/assets/showcase/roborock-screenshot.jpg +0 -0
  383. package/docs/assets/showcase/roborock-status.svg +13 -0
  384. package/docs/assets/showcase/roof-camera-sky.jpg +0 -0
  385. package/docs/assets/showcase/snag.png +0 -0
  386. package/docs/assets/showcase/tesco-shop.jpg +0 -0
  387. package/docs/assets/showcase/wienerlinien.png +0 -0
  388. package/docs/assets/showcase/wine-cellar-skill.jpg +0 -0
  389. package/docs/assets/showcase/winix-air-purifier.jpg +0 -0
  390. package/docs/assets/showcase/xuezh-pronunciation.jpeg +0 -0
  391. package/docs/assets/terminal.css +473 -0
  392. package/docs/assets/theme.js +55 -0
  393. package/docs/automation/auth-monitoring.md +44 -0
  394. package/docs/automation/cron-jobs.md +468 -0
  395. package/docs/automation/cron-vs-heartbeat.md +282 -0
  396. package/docs/automation/gmail-pubsub.md +256 -0
  397. package/docs/automation/poll.md +69 -0
  398. package/docs/automation/webhook.md +163 -0
  399. package/docs/bedrock.md +176 -0
  400. package/docs/brave-search.md +41 -0
  401. package/docs/broadcast-groups.md +442 -0
  402. package/docs/channels/bluebubbles.md +338 -0
  403. package/docs/channels/discord.md +475 -0
  404. package/docs/channels/feishu.md +507 -0
  405. package/docs/channels/googlechat.md +250 -0
  406. package/docs/channels/grammy.md +31 -0
  407. package/docs/channels/imessage.md +299 -0
  408. package/docs/channels/index.md +46 -0
  409. package/docs/channels/line.md +186 -0
  410. package/docs/channels/location.md +56 -0
  411. package/docs/channels/matrix.md +233 -0
  412. package/docs/channels/mattermost.md +138 -0
  413. package/docs/channels/msteams.md +768 -0
  414. package/docs/channels/nextcloud-talk.md +136 -0
  415. package/docs/channels/nostr.md +233 -0
  416. package/docs/channels/signal.md +202 -0
  417. package/docs/channels/slack.md +548 -0
  418. package/docs/channels/telegram.md +750 -0
  419. package/docs/channels/tlon.md +132 -0
  420. package/docs/channels/troubleshooting.md +29 -0
  421. package/docs/channels/twitch.md +379 -0
  422. package/docs/channels/whatsapp.md +404 -0
  423. package/docs/channels/zalo.md +189 -0
  424. package/docs/channels/zalouser.md +140 -0
  425. package/docs/cli/acp.md +170 -0
  426. package/docs/cli/agent.md +24 -0
  427. package/docs/cli/agents.md +75 -0
  428. package/docs/cli/approvals.md +50 -0
  429. package/docs/cli/browser.md +107 -0
  430. package/docs/cli/channels.md +79 -0
  431. package/docs/cli/config.md +50 -0
  432. package/docs/cli/configure.md +33 -0
  433. package/docs/cli/cron.md +42 -0
  434. package/docs/cli/dashboard.md +16 -0
  435. package/docs/cli/devices.md +67 -0
  436. package/docs/cli/directory.md +63 -0
  437. package/docs/cli/dns.md +23 -0
  438. package/docs/cli/docs.md +15 -0
  439. package/docs/cli/doctor.md +41 -0
  440. package/docs/cli/gateway.md +199 -0
  441. package/docs/cli/health.md +21 -0
  442. package/docs/cli/hooks.md +304 -0
  443. package/docs/cli/index.md +1029 -0
  444. package/docs/cli/logs.md +24 -0
  445. package/docs/cli/memory.md +45 -0
  446. package/docs/cli/message.md +239 -0
  447. package/docs/cli/models.md +79 -0
  448. package/docs/cli/node.md +112 -0
  449. package/docs/cli/nodes.md +73 -0
  450. package/docs/cli/onboard.md +29 -0
  451. package/docs/cli/pairing.md +21 -0
  452. package/docs/cli/plugins.md +62 -0
  453. package/docs/cli/reset.md +17 -0
  454. package/docs/cli/sandbox.md +152 -0
  455. package/docs/cli/security.md +26 -0
  456. package/docs/cli/sessions.md +16 -0
  457. package/docs/cli/setup.md +29 -0
  458. package/docs/cli/skills.md +26 -0
  459. package/docs/cli/status.md +26 -0
  460. package/docs/cli/system.md +60 -0
  461. package/docs/cli/tui.md +23 -0
  462. package/docs/cli/uninstall.md +17 -0
  463. package/docs/cli/update.md +98 -0
  464. package/docs/cli/voicecall.md +34 -0
  465. package/docs/cli/webhooks.md +25 -0
  466. package/docs/concepts/agent-loop.md +146 -0
  467. package/docs/concepts/agent-workspace.md +233 -0
  468. package/docs/concepts/agent.md +123 -0
  469. package/docs/concepts/architecture.md +129 -0
  470. package/docs/concepts/channel-routing.md +114 -0
  471. package/docs/concepts/compaction.md +61 -0
  472. package/docs/concepts/context.md +161 -0
  473. package/docs/concepts/group-messages.md +84 -0
  474. package/docs/concepts/groups.md +373 -0
  475. package/docs/concepts/markdown-formatting.md +130 -0
  476. package/docs/concepts/memory.md +546 -0
  477. package/docs/concepts/messages.md +154 -0
  478. package/docs/concepts/model-failover.md +149 -0
  479. package/docs/concepts/model-providers.md +316 -0
  480. package/docs/concepts/models.md +208 -0
  481. package/docs/concepts/multi-agent.md +376 -0
  482. package/docs/concepts/oauth.md +145 -0
  483. package/docs/concepts/presence.md +102 -0
  484. package/docs/concepts/queue.md +89 -0
  485. package/docs/concepts/retry.md +69 -0
  486. package/docs/concepts/session-pruning.md +122 -0
  487. package/docs/concepts/session-tool.md +193 -0
  488. package/docs/concepts/session.md +188 -0
  489. package/docs/concepts/sessions.md +10 -0
  490. package/docs/concepts/streaming.md +135 -0
  491. package/docs/concepts/system-prompt.md +115 -0
  492. package/docs/concepts/timezone.md +91 -0
  493. package/docs/concepts/typebox.md +289 -0
  494. package/docs/concepts/typing-indicators.md +68 -0
  495. package/docs/concepts/usage-tracking.md +35 -0
  496. package/docs/date-time.md +128 -0
  497. package/docs/debug/node-issue.md +83 -0
  498. package/docs/debugging.md +162 -0
  499. package/docs/diagnostics/flags.md +91 -0
  500. package/docs/docs.json +1587 -0
  501. package/docs/environment.md +81 -0
  502. package/docs/experiments/onboarding-config-protocol.md +40 -0
  503. package/docs/experiments/plans/cron-add-hardening.md +63 -0
  504. package/docs/experiments/plans/group-policy-hardening.md +40 -0
  505. package/docs/experiments/plans/openresponses-gateway.md +123 -0
  506. package/docs/experiments/proposals/model-config.md +36 -0
  507. package/docs/experiments/research/memory.md +228 -0
  508. package/docs/gateway/authentication.md +145 -0
  509. package/docs/gateway/background-process.md +93 -0
  510. package/docs/gateway/bonjour.md +167 -0
  511. package/docs/gateway/bridge-protocol.md +89 -0
  512. package/docs/gateway/cli-backends.md +223 -0
  513. package/docs/gateway/configuration-examples.md +606 -0
  514. package/docs/gateway/configuration.md +3393 -0
  515. package/docs/gateway/discovery.md +116 -0
  516. package/docs/gateway/doctor.md +282 -0
  517. package/docs/gateway/gateway-lock.md +34 -0
  518. package/docs/gateway/health.md +35 -0
  519. package/docs/gateway/heartbeat.md +302 -0
  520. package/docs/gateway/index.md +328 -0
  521. package/docs/gateway/local-models.md +150 -0
  522. package/docs/gateway/logging.md +113 -0
  523. package/docs/gateway/multiple-gateways.md +112 -0
  524. package/docs/gateway/openai-http-api.md +118 -0
  525. package/docs/gateway/openresponses-http-api.md +317 -0
  526. package/docs/gateway/pairing.md +99 -0
  527. package/docs/gateway/protocol.md +221 -0
  528. package/docs/gateway/remote-gateway-readme.md +157 -0
  529. package/docs/gateway/remote.md +127 -0
  530. package/docs/gateway/sandbox-vs-tool-policy-vs-elevated.md +128 -0
  531. package/docs/gateway/sandboxing.md +193 -0
  532. package/docs/gateway/security/formal-verification.md +164 -0
  533. package/docs/gateway/security/index.md +825 -0
  534. package/docs/gateway/tailscale.md +127 -0
  535. package/docs/gateway/tools-invoke-http-api.md +85 -0
  536. package/docs/gateway/troubleshooting.md +767 -0
  537. package/docs/help/faq.md +2830 -0
  538. package/docs/help/index.md +21 -0
  539. package/docs/help/troubleshooting.md +98 -0
  540. package/docs/hooks/soul-evil.md +69 -0
  541. package/docs/hooks.md +913 -0
  542. package/docs/images/feishu-step2-create-app.png +0 -0
  543. package/docs/images/feishu-step3-credentials.png +0 -0
  544. package/docs/images/feishu-step4-permissions.png +0 -0
  545. package/docs/images/feishu-step5-bot-capability.png +0 -0
  546. package/docs/images/feishu-step6-event-subscription.png +0 -0
  547. package/docs/images/groups-flow.svg +52 -0
  548. package/docs/images/mobile-ui-screenshot.png +0 -0
  549. package/docs/index.md +258 -0
  550. package/docs/install/ansible.md +208 -0
  551. package/docs/install/bun.md +59 -0
  552. package/docs/install/development-channels.md +75 -0
  553. package/docs/install/docker.md +567 -0
  554. package/docs/install/index.md +185 -0
  555. package/docs/install/installer.md +123 -0
  556. package/docs/install/migrating.md +192 -0
  557. package/docs/install/nix.md +96 -0
  558. package/docs/install/node.md +78 -0
  559. package/docs/install/uninstall.md +128 -0
  560. package/docs/install/updating.md +228 -0
  561. package/docs/logging.md +350 -0
  562. package/docs/multi-agent-sandbox-tools.md +395 -0
  563. package/docs/network.md +54 -0
  564. package/docs/nodes/audio.md +114 -0
  565. package/docs/nodes/camera.md +156 -0
  566. package/docs/nodes/images.md +72 -0
  567. package/docs/nodes/index.md +341 -0
  568. package/docs/nodes/location-command.md +113 -0
  569. package/docs/nodes/media-understanding.md +379 -0
  570. package/docs/nodes/talk.md +90 -0
  571. package/docs/nodes/voicewake.md +65 -0
  572. package/docs/northflank.mdx +53 -0
  573. package/docs/perplexity.md +80 -0
  574. package/docs/pi-dev.md +70 -0
  575. package/docs/pi.md +612 -0
  576. package/docs/platforms/android.md +148 -0
  577. package/docs/platforms/digitalocean.md +262 -0
  578. package/docs/platforms/exe-dev.md +125 -0
  579. package/docs/platforms/fly.md +486 -0
  580. package/docs/platforms/gcp.md +503 -0
  581. package/docs/platforms/hetzner.md +330 -0
  582. package/docs/platforms/index.md +53 -0
  583. package/docs/platforms/ios.md +107 -0
  584. package/docs/platforms/linux.md +94 -0
  585. package/docs/platforms/mac/bundled-gateway.md +73 -0
  586. package/docs/platforms/mac/canvas.md +125 -0
  587. package/docs/platforms/mac/child-process.md +69 -0
  588. package/docs/platforms/mac/dev-setup.md +102 -0
  589. package/docs/platforms/mac/health.md +34 -0
  590. package/docs/platforms/mac/icon.md +31 -0
  591. package/docs/platforms/mac/logging.md +57 -0
  592. package/docs/platforms/mac/menu-bar.md +81 -0
  593. package/docs/platforms/mac/peekaboo.md +65 -0
  594. package/docs/platforms/mac/permissions.md +44 -0
  595. package/docs/platforms/mac/release.md +85 -0
  596. package/docs/platforms/mac/remote.md +83 -0
  597. package/docs/platforms/mac/signing.md +47 -0
  598. package/docs/platforms/mac/skills.md +33 -0
  599. package/docs/platforms/mac/voice-overlay.md +60 -0
  600. package/docs/platforms/mac/voicewake.md +67 -0
  601. package/docs/platforms/mac/webchat.md +41 -0
  602. package/docs/platforms/mac/xpc.md +61 -0
  603. package/docs/platforms/macos-vm.md +281 -0
  604. package/docs/platforms/macos.md +203 -0
  605. package/docs/platforms/oracle.md +303 -0
  606. package/docs/platforms/raspberry-pi.md +358 -0
  607. package/docs/platforms/windows.md +159 -0
  608. package/docs/plugin.md +664 -0
  609. package/docs/plugins/agent-tools.md +99 -0
  610. package/docs/plugins/manifest.md +71 -0
  611. package/docs/plugins/voice-call.md +284 -0
  612. package/docs/plugins/zalouser.md +81 -0
  613. package/docs/prose.md +134 -0
  614. package/docs/providers/anthropic.md +152 -0
  615. package/docs/providers/claude-max-api-proxy.md +148 -0
  616. package/docs/providers/cloudflare-ai-gateway.md +71 -0
  617. package/docs/providers/deepgram.md +93 -0
  618. package/docs/providers/github-copilot.md +72 -0
  619. package/docs/providers/glm.md +33 -0
  620. package/docs/providers/index.md +63 -0
  621. package/docs/providers/minimax.md +208 -0
  622. package/docs/providers/models.md +51 -0
  623. package/docs/providers/moonshot.md +142 -0
  624. package/docs/providers/ollama.md +223 -0
  625. package/docs/providers/openai.md +62 -0
  626. package/docs/providers/opencode.md +36 -0
  627. package/docs/providers/openrouter.md +37 -0
  628. package/docs/providers/qwen.md +53 -0
  629. package/docs/providers/synthetic.md +99 -0
  630. package/docs/providers/venice.md +267 -0
  631. package/docs/providers/vercel-ai-gateway.md +50 -0
  632. package/docs/providers/xiaomi.md +64 -0
  633. package/docs/providers/zai.md +36 -0
  634. package/docs/railway.mdx +99 -0
  635. package/docs/refactor/clawnet.md +417 -0
  636. package/docs/refactor/exec-host.md +316 -0
  637. package/docs/refactor/outbound-session-mirroring.md +85 -0
  638. package/docs/refactor/plugin-sdk.md +214 -0
  639. package/docs/refactor/strict-config.md +93 -0
  640. package/docs/reference/AGENTS.default.md +124 -0
  641. package/docs/reference/RELEASING.md +120 -0
  642. package/docs/reference/api-usage-costs.md +137 -0
  643. package/docs/reference/device-models.md +47 -0
  644. package/docs/reference/rpc.md +43 -0
  645. package/docs/reference/session-management-compaction.md +285 -0
  646. package/docs/reference/templates/AGENTS.dev.md +83 -0
  647. package/docs/reference/templates/AGENTS.md +218 -0
  648. package/docs/reference/templates/BOOT.md +10 -0
  649. package/docs/reference/templates/BOOTSTRAP.md +61 -0
  650. package/docs/reference/templates/HEARTBEAT.md +11 -0
  651. package/docs/reference/templates/IDENTITY.dev.md +47 -0
  652. package/docs/reference/templates/IDENTITY.md +27 -0
  653. package/docs/reference/templates/SOUL.dev.md +76 -0
  654. package/docs/reference/templates/SOUL.md +42 -0
  655. package/docs/reference/templates/TOOLS.dev.md +24 -0
  656. package/docs/reference/templates/TOOLS.md +46 -0
  657. package/docs/reference/templates/USER.dev.md +18 -0
  658. package/docs/reference/templates/USER.md +22 -0
  659. package/docs/reference/test.md +50 -0
  660. package/docs/reference/transcript-hygiene.md +129 -0
  661. package/docs/render.mdx +165 -0
  662. package/docs/scripts.md +28 -0
  663. package/docs/security/formal-verification.md +164 -0
  664. package/docs/start/getting-started.md +208 -0
  665. package/docs/start/hubs.md +185 -0
  666. package/docs/start/lore.md +219 -0
  667. package/docs/start/onboarding.md +110 -0
  668. package/docs/start/openclaw.md +241 -0
  669. package/docs/start/pairing.md +86 -0
  670. package/docs/start/setup.md +149 -0
  671. package/docs/start/showcase.md +416 -0
  672. package/docs/start/wizard.md +349 -0
  673. package/docs/testing.md +368 -0
  674. package/docs/token-use.md +112 -0
  675. package/docs/tools/agent-send.md +53 -0
  676. package/docs/tools/apply-patch.md +50 -0
  677. package/docs/tools/browser-linux-troubleshooting.md +139 -0
  678. package/docs/tools/browser-login.md +68 -0
  679. package/docs/tools/browser.md +576 -0
  680. package/docs/tools/chrome-extension.md +178 -0
  681. package/docs/tools/clawhub.md +257 -0
  682. package/docs/tools/creating-skills.md +54 -0
  683. package/docs/tools/elevated.md +57 -0
  684. package/docs/tools/exec-approvals.md +246 -0
  685. package/docs/tools/exec.md +179 -0
  686. package/docs/tools/firecrawl.md +61 -0
  687. package/docs/tools/index.md +509 -0
  688. package/docs/tools/llm-task.md +115 -0
  689. package/docs/tools/lobster.md +342 -0
  690. package/docs/tools/reactions.md +22 -0
  691. package/docs/tools/skills-config.md +76 -0
  692. package/docs/tools/skills.md +300 -0
  693. package/docs/tools/slash-commands.md +198 -0
  694. package/docs/tools/subagents.md +151 -0
  695. package/docs/tools/thinking.md +73 -0
  696. package/docs/tools/web.md +261 -0
  697. package/docs/tts.md +396 -0
  698. package/docs/tui.md +159 -0
  699. package/docs/vps.md +43 -0
  700. package/docs/web/control-ui.md +221 -0
  701. package/docs/web/dashboard.md +46 -0
  702. package/docs/web/index.md +116 -0
  703. package/docs/web/webchat.md +49 -0
  704. package/docs/whatsapp-openclaw-ai-zh.jpg +0 -0
  705. package/docs/whatsapp-openclaw.jpg +0 -0
  706. package/docs/zh-CN/AGENTS.md +59 -0
  707. package/docs/zh-CN/automation/auth-monitoring.md +47 -0
  708. package/docs/zh-CN/automation/cron-jobs.md +424 -0
  709. package/docs/zh-CN/automation/cron-vs-heartbeat.md +286 -0
  710. package/docs/zh-CN/automation/gmail-pubsub.md +249 -0
  711. package/docs/zh-CN/automation/poll.md +76 -0
  712. package/docs/zh-CN/automation/webhook.md +163 -0
  713. package/docs/zh-CN/bedrock.md +170 -0
  714. package/docs/zh-CN/brave-search.md +48 -0
  715. package/docs/zh-CN/broadcast-groups.md +449 -0
  716. package/docs/zh-CN/channels/bluebubbles.md +271 -0
  717. package/docs/zh-CN/channels/discord.md +468 -0
  718. package/docs/zh-CN/channels/feishu.md +513 -0
  719. package/docs/zh-CN/channels/googlechat.md +257 -0
  720. package/docs/zh-CN/channels/grammy.md +38 -0
  721. package/docs/zh-CN/channels/imessage.md +302 -0
  722. package/docs/zh-CN/channels/index.md +53 -0
  723. package/docs/zh-CN/channels/line.md +180 -0
  724. package/docs/zh-CN/channels/location.md +63 -0
  725. package/docs/zh-CN/channels/matrix.md +221 -0
  726. package/docs/zh-CN/channels/mattermost.md +144 -0
  727. package/docs/zh-CN/channels/msteams.md +775 -0
  728. package/docs/zh-CN/channels/nextcloud-talk.md +142 -0
  729. package/docs/zh-CN/channels/nostr.md +240 -0
  730. package/docs/zh-CN/channels/signal.md +209 -0
  731. package/docs/zh-CN/channels/slack.md +531 -0
  732. package/docs/zh-CN/channels/telegram.md +751 -0
  733. package/docs/zh-CN/channels/tlon.md +136 -0
  734. package/docs/zh-CN/channels/troubleshooting.md +36 -0
  735. package/docs/zh-CN/channels/twitch.md +385 -0
  736. package/docs/zh-CN/channels/whatsapp.md +411 -0
  737. package/docs/zh-CN/channels/zalo.md +196 -0
  738. package/docs/zh-CN/channels/zalouser.md +147 -0
  739. package/docs/zh-CN/cli/acp.md +173 -0
  740. package/docs/zh-CN/cli/agent.md +30 -0
  741. package/docs/zh-CN/cli/agents.md +82 -0
  742. package/docs/zh-CN/cli/approvals.md +57 -0
  743. package/docs/zh-CN/cli/browser.md +114 -0
  744. package/docs/zh-CN/cli/channels.md +86 -0
  745. package/docs/zh-CN/cli/config.md +57 -0
  746. package/docs/zh-CN/cli/configure.md +38 -0
  747. package/docs/zh-CN/cli/cron.md +43 -0
  748. package/docs/zh-CN/cli/dashboard.md +23 -0
  749. package/docs/zh-CN/cli/devices.md +74 -0
  750. package/docs/zh-CN/cli/directory.md +70 -0
  751. package/docs/zh-CN/cli/dns.md +30 -0
  752. package/docs/zh-CN/cli/docs.md +22 -0
  753. package/docs/zh-CN/cli/doctor.md +48 -0
  754. package/docs/zh-CN/cli/gateway.md +206 -0
  755. package/docs/zh-CN/cli/health.md +28 -0
  756. package/docs/zh-CN/cli/hooks.md +311 -0
  757. package/docs/zh-CN/cli/index.md +1032 -0
  758. package/docs/zh-CN/cli/logs.md +31 -0
  759. package/docs/zh-CN/cli/memory.md +52 -0
  760. package/docs/zh-CN/cli/message.md +246 -0
  761. package/docs/zh-CN/cli/models.md +85 -0
  762. package/docs/zh-CN/cli/node.md +115 -0
  763. package/docs/zh-CN/cli/nodes.md +80 -0
  764. package/docs/zh-CN/cli/onboard.md +36 -0
  765. package/docs/zh-CN/cli/pairing.md +28 -0
  766. package/docs/zh-CN/cli/plugins.md +66 -0
  767. package/docs/zh-CN/cli/reset.md +24 -0
  768. package/docs/zh-CN/cli/sandbox.md +158 -0
  769. package/docs/zh-CN/cli/security.md +33 -0
  770. package/docs/zh-CN/cli/sessions.md +23 -0
  771. package/docs/zh-CN/cli/setup.md +36 -0
  772. package/docs/zh-CN/cli/skills.md +33 -0
  773. package/docs/zh-CN/cli/status.md +33 -0
  774. package/docs/zh-CN/cli/system.md +63 -0
  775. package/docs/zh-CN/cli/tui.md +30 -0
  776. package/docs/zh-CN/cli/uninstall.md +24 -0
  777. package/docs/zh-CN/cli/update.md +101 -0
  778. package/docs/zh-CN/cli/voicecall.md +41 -0
  779. package/docs/zh-CN/cli/webhooks.md +32 -0
  780. package/docs/zh-CN/concepts/agent-loop.md +146 -0
  781. package/docs/zh-CN/concepts/agent-workspace.md +219 -0
  782. package/docs/zh-CN/concepts/agent.md +115 -0
  783. package/docs/zh-CN/concepts/architecture.md +123 -0
  784. package/docs/zh-CN/concepts/channel-routing.md +117 -0
  785. package/docs/zh-CN/concepts/compaction.md +67 -0
  786. package/docs/zh-CN/concepts/context.md +168 -0
  787. package/docs/zh-CN/concepts/group-messages.md +91 -0
  788. package/docs/zh-CN/concepts/groups.md +379 -0
  789. package/docs/zh-CN/concepts/markdown-formatting.md +117 -0
  790. package/docs/zh-CN/concepts/memory.md +412 -0
  791. package/docs/zh-CN/concepts/messages.md +141 -0
  792. package/docs/zh-CN/concepts/model-failover.md +145 -0
  793. package/docs/zh-CN/concepts/model-providers.md +320 -0
  794. package/docs/zh-CN/concepts/models.md +196 -0
  795. package/docs/zh-CN/concepts/multi-agent.md +372 -0
  796. package/docs/zh-CN/concepts/oauth.md +151 -0
  797. package/docs/zh-CN/concepts/presence.md +99 -0
  798. package/docs/zh-CN/concepts/queue.md +94 -0
  799. package/docs/zh-CN/concepts/retry.md +76 -0
  800. package/docs/zh-CN/concepts/session-pruning.md +129 -0
  801. package/docs/zh-CN/concepts/session-tool.md +200 -0
  802. package/docs/zh-CN/concepts/session.md +166 -0
  803. package/docs/zh-CN/concepts/sessions.md +17 -0
  804. package/docs/zh-CN/concepts/streaming.md +133 -0
  805. package/docs/zh-CN/concepts/system-prompt.md +101 -0
  806. package/docs/zh-CN/concepts/timezone.md +96 -0
  807. package/docs/zh-CN/concepts/typebox.md +284 -0
  808. package/docs/zh-CN/concepts/typing-indicators.md +74 -0
  809. package/docs/zh-CN/concepts/usage-tracking.md +42 -0
  810. package/docs/zh-CN/date-time.md +129 -0
  811. package/docs/zh-CN/debug/node-issue.md +90 -0
  812. package/docs/zh-CN/debugging.md +160 -0
  813. package/docs/zh-CN/diagnostics/flags.md +98 -0
  814. package/docs/zh-CN/environment.md +88 -0
  815. package/docs/zh-CN/experiments/onboarding-config-protocol.md +47 -0
  816. package/docs/zh-CN/experiments/plans/cron-add-hardening.md +70 -0
  817. package/docs/zh-CN/experiments/plans/group-policy-hardening.md +45 -0
  818. package/docs/zh-CN/experiments/plans/openresponses-gateway.md +121 -0
  819. package/docs/zh-CN/experiments/proposals/model-config.md +42 -0
  820. package/docs/zh-CN/experiments/research/memory.md +235 -0
  821. package/docs/zh-CN/gateway/authentication.md +142 -0
  822. package/docs/zh-CN/gateway/background-process.md +100 -0
  823. package/docs/zh-CN/gateway/bonjour.md +174 -0
  824. package/docs/zh-CN/gateway/bridge-protocol.md +86 -0
  825. package/docs/zh-CN/gateway/cli-backends.md +213 -0
  826. package/docs/zh-CN/gateway/configuration-examples.md +587 -0
  827. package/docs/zh-CN/gateway/configuration.md +3332 -0
  828. package/docs/zh-CN/gateway/discovery.md +123 -0
  829. package/docs/zh-CN/gateway/doctor.md +238 -0
  830. package/docs/zh-CN/gateway/gateway-lock.md +41 -0
  831. package/docs/zh-CN/gateway/health.md +42 -0
  832. package/docs/zh-CN/gateway/heartbeat.md +274 -0
  833. package/docs/zh-CN/gateway/index.md +335 -0
  834. package/docs/zh-CN/gateway/local-models.md +157 -0
  835. package/docs/zh-CN/gateway/logging.md +114 -0
  836. package/docs/zh-CN/gateway/multiple-gateways.md +119 -0
  837. package/docs/zh-CN/gateway/openai-http-api.md +125 -0
  838. package/docs/zh-CN/gateway/openresponses-http-api.md +317 -0
  839. package/docs/zh-CN/gateway/pairing.md +99 -0
  840. package/docs/zh-CN/gateway/protocol.md +220 -0
  841. package/docs/zh-CN/gateway/remote-gateway-readme.md +164 -0
  842. package/docs/zh-CN/gateway/remote.md +133 -0
  843. package/docs/zh-CN/gateway/sandbox-vs-tool-policy-vs-elevated.md +135 -0
  844. package/docs/zh-CN/gateway/sandboxing.md +188 -0
  845. package/docs/zh-CN/gateway/security/formal-verification.md +169 -0
  846. package/docs/zh-CN/gateway/security/index.md +777 -0
  847. package/docs/zh-CN/gateway/tailscale.md +124 -0
  848. package/docs/zh-CN/gateway/tools-invoke-http-api.md +92 -0
  849. package/docs/zh-CN/gateway/troubleshooting.md +771 -0
  850. package/docs/zh-CN/help/faq.md +2628 -0
  851. package/docs/zh-CN/help/index.md +28 -0
  852. package/docs/zh-CN/help/troubleshooting.md +104 -0
  853. package/docs/zh-CN/hooks/soul-evil.md +72 -0
  854. package/docs/zh-CN/hooks.md +919 -0
  855. package/docs/zh-CN/index.md +264 -0
  856. package/docs/zh-CN/install/ansible.md +215 -0
  857. package/docs/zh-CN/install/bun.md +65 -0
  858. package/docs/zh-CN/install/development-channels.md +81 -0
  859. package/docs/zh-CN/install/docker.md +532 -0
  860. package/docs/zh-CN/install/index.md +193 -0
  861. package/docs/zh-CN/install/installer.md +128 -0
  862. package/docs/zh-CN/install/migrating.md +199 -0
  863. package/docs/zh-CN/install/nix.md +99 -0
  864. package/docs/zh-CN/install/node.md +85 -0
  865. package/docs/zh-CN/install/uninstall.md +135 -0
  866. package/docs/zh-CN/install/updating.md +233 -0
  867. package/docs/zh-CN/logging.md +329 -0
  868. package/docs/zh-CN/multi-agent-sandbox-tools.md +401 -0
  869. package/docs/zh-CN/network.md +59 -0
  870. package/docs/zh-CN/nodes/audio.md +120 -0
  871. package/docs/zh-CN/nodes/camera.md +162 -0
  872. package/docs/zh-CN/nodes/images.md +79 -0
  873. package/docs/zh-CN/nodes/index.md +348 -0
  874. package/docs/zh-CN/nodes/location-command.md +120 -0
  875. package/docs/zh-CN/nodes/media-understanding.md +380 -0
  876. package/docs/zh-CN/nodes/talk.md +97 -0
  877. package/docs/zh-CN/nodes/voicewake.md +72 -0
  878. package/docs/zh-CN/northflank.mdx +60 -0
  879. package/docs/zh-CN/perplexity.md +84 -0
  880. package/docs/zh-CN/pi-dev.md +77 -0
  881. package/docs/zh-CN/pi.md +619 -0
  882. package/docs/zh-CN/platforms/android.md +155 -0
  883. package/docs/zh-CN/platforms/digitalocean.md +269 -0
  884. package/docs/zh-CN/platforms/exe-dev.md +127 -0
  885. package/docs/zh-CN/platforms/fly.md +490 -0
  886. package/docs/zh-CN/platforms/gcp.md +510 -0
  887. package/docs/zh-CN/platforms/hetzner.md +337 -0
  888. package/docs/zh-CN/platforms/index.md +60 -0
  889. package/docs/zh-CN/platforms/ios.md +114 -0
  890. package/docs/zh-CN/platforms/linux.md +101 -0
  891. package/docs/zh-CN/platforms/mac/bundled-gateway.md +75 -0
  892. package/docs/zh-CN/platforms/mac/canvas.md +128 -0
  893. package/docs/zh-CN/platforms/mac/child-process.md +73 -0
  894. package/docs/zh-CN/platforms/mac/dev-setup.md +109 -0
  895. package/docs/zh-CN/platforms/mac/health.md +41 -0
  896. package/docs/zh-CN/platforms/mac/icon.md +38 -0
  897. package/docs/zh-CN/platforms/mac/logging.md +64 -0
  898. package/docs/zh-CN/platforms/mac/menu-bar.md +88 -0
  899. package/docs/zh-CN/platforms/mac/peekaboo.md +62 -0
  900. package/docs/zh-CN/platforms/mac/permissions.md +46 -0
  901. package/docs/zh-CN/platforms/mac/release.md +92 -0
  902. package/docs/zh-CN/platforms/mac/remote.md +90 -0
  903. package/docs/zh-CN/platforms/mac/signing.md +54 -0
  904. package/docs/zh-CN/platforms/mac/skills.md +40 -0
  905. package/docs/zh-CN/platforms/mac/voice-overlay.md +67 -0
  906. package/docs/zh-CN/platforms/mac/voicewake.md +74 -0
  907. package/docs/zh-CN/platforms/mac/webchat.md +43 -0
  908. package/docs/zh-CN/platforms/mac/xpc.md +68 -0
  909. package/docs/zh-CN/platforms/macos-vm.md +288 -0
  910. package/docs/zh-CN/platforms/macos.md +193 -0
  911. package/docs/zh-CN/platforms/oracle.md +310 -0
  912. package/docs/zh-CN/platforms/raspberry-pi.md +365 -0
  913. package/docs/zh-CN/platforms/windows.md +156 -0
  914. package/docs/zh-CN/plugin.md +639 -0
  915. package/docs/zh-CN/plugins/agent-tools.md +99 -0
  916. package/docs/zh-CN/plugins/manifest.md +68 -0
  917. package/docs/zh-CN/plugins/voice-call.md +250 -0
  918. package/docs/zh-CN/plugins/zalouser.md +88 -0
  919. package/docs/zh-CN/prose.md +141 -0
  920. package/docs/zh-CN/providers/anthropic.md +159 -0
  921. package/docs/zh-CN/providers/claude-max-api-proxy.md +155 -0
  922. package/docs/zh-CN/providers/deepgram.md +97 -0
  923. package/docs/zh-CN/providers/github-copilot.md +67 -0
  924. package/docs/zh-CN/providers/glm.md +39 -0
  925. package/docs/zh-CN/providers/index.md +68 -0
  926. package/docs/zh-CN/providers/minimax.md +206 -0
  927. package/docs/zh-CN/providers/models.md +55 -0
  928. package/docs/zh-CN/providers/moonshot.md +145 -0
  929. package/docs/zh-CN/providers/ollama.md +230 -0
  930. package/docs/zh-CN/providers/openai.md +68 -0
  931. package/docs/zh-CN/providers/opencode.md +41 -0
  932. package/docs/zh-CN/providers/openrouter.md +43 -0
  933. package/docs/zh-CN/providers/qwen.md +55 -0
  934. package/docs/zh-CN/providers/synthetic.md +102 -0
  935. package/docs/zh-CN/providers/venice.md +274 -0
  936. package/docs/zh-CN/providers/vercel-ai-gateway.md +57 -0
  937. package/docs/zh-CN/providers/xiaomi.md +68 -0
  938. package/docs/zh-CN/providers/zai.md +41 -0
  939. package/docs/zh-CN/railway.mdx +106 -0
  940. package/docs/zh-CN/refactor/clawnet.md +424 -0
  941. package/docs/zh-CN/refactor/exec-host.md +323 -0
  942. package/docs/zh-CN/refactor/outbound-session-mirroring.md +92 -0
  943. package/docs/zh-CN/refactor/plugin-sdk.md +221 -0
  944. package/docs/zh-CN/refactor/strict-config.md +100 -0
  945. package/docs/zh-CN/reference/AGENTS.default.md +131 -0
  946. package/docs/zh-CN/reference/RELEASING.md +123 -0
  947. package/docs/zh-CN/reference/api-usage-costs.md +136 -0
  948. package/docs/zh-CN/reference/device-models.md +54 -0
  949. package/docs/zh-CN/reference/rpc.md +48 -0
  950. package/docs/zh-CN/reference/session-management-compaction.md +287 -0
  951. package/docs/zh-CN/reference/templates/AGENTS.dev.md +89 -0
  952. package/docs/zh-CN/reference/templates/AGENTS.md +225 -0
  953. package/docs/zh-CN/reference/templates/BOOT.md +17 -0
  954. package/docs/zh-CN/reference/templates/BOOTSTRAP.md +68 -0
  955. package/docs/zh-CN/reference/templates/HEARTBEAT.md +18 -0
  956. package/docs/zh-CN/reference/templates/IDENTITY.dev.md +54 -0
  957. package/docs/zh-CN/reference/templates/IDENTITY.md +35 -0
  958. package/docs/zh-CN/reference/templates/SOUL.dev.md +83 -0
  959. package/docs/zh-CN/reference/templates/SOUL.md +49 -0
  960. package/docs/zh-CN/reference/templates/TOOLS.dev.md +31 -0
  961. package/docs/zh-CN/reference/templates/TOOLS.md +53 -0
  962. package/docs/zh-CN/reference/templates/USER.dev.md +25 -0
  963. package/docs/zh-CN/reference/templates/USER.md +30 -0
  964. package/docs/zh-CN/reference/test.md +57 -0
  965. package/docs/zh-CN/reference/transcript-hygiene.md +109 -0
  966. package/docs/zh-CN/render.mdx +169 -0
  967. package/docs/zh-CN/scripts.md +35 -0
  968. package/docs/zh-CN/security/formal-verification.md +171 -0
  969. package/docs/zh-CN/start/getting-started.md +206 -0
  970. package/docs/zh-CN/start/hubs.md +191 -0
  971. package/docs/zh-CN/start/lore.md +226 -0
  972. package/docs/zh-CN/start/onboarding.md +105 -0
  973. package/docs/zh-CN/start/openclaw.md +248 -0
  974. package/docs/zh-CN/start/pairing.md +89 -0
  975. package/docs/zh-CN/start/setup.md +153 -0
  976. package/docs/zh-CN/start/showcase.md +423 -0
  977. package/docs/zh-CN/start/wizard.md +331 -0
  978. package/docs/zh-CN/testing.md +375 -0
  979. package/docs/zh-CN/token-use.md +119 -0
  980. package/docs/zh-CN/tools/agent-send.md +59 -0
  981. package/docs/zh-CN/tools/apply-patch.md +57 -0
  982. package/docs/zh-CN/tools/browser-linux-troubleshooting.md +144 -0
  983. package/docs/zh-CN/tools/browser-login.md +75 -0
  984. package/docs/zh-CN/tools/browser.md +553 -0
  985. package/docs/zh-CN/tools/chrome-extension.md +183 -0
  986. package/docs/zh-CN/tools/clawhub.md +209 -0
  987. package/docs/zh-CN/tools/creating-skills.md +61 -0
  988. package/docs/zh-CN/tools/elevated.md +64 -0
  989. package/docs/zh-CN/tools/exec-approvals.md +234 -0
  990. package/docs/zh-CN/tools/exec.md +169 -0
  991. package/docs/zh-CN/tools/firecrawl.md +68 -0
  992. package/docs/zh-CN/tools/index.md +515 -0
  993. package/docs/zh-CN/tools/llm-task.md +117 -0
  994. package/docs/zh-CN/tools/lobster.md +349 -0
  995. package/docs/zh-CN/tools/reactions.md +29 -0
  996. package/docs/zh-CN/tools/skills-config.md +78 -0
  997. package/docs/zh-CN/tools/skills.md +279 -0
  998. package/docs/zh-CN/tools/slash-commands.md +205 -0
  999. package/docs/zh-CN/tools/subagents.md +156 -0
  1000. package/docs/zh-CN/tools/thinking.md +80 -0
  1001. package/docs/zh-CN/tools/web.md +257 -0
  1002. package/docs/zh-CN/tts.md +375 -0
  1003. package/docs/zh-CN/tui.md +166 -0
  1004. package/docs/zh-CN/vps.md +47 -0
  1005. package/docs/zh-CN/web/control-ui.md +191 -0
  1006. package/docs/zh-CN/web/dashboard.md +53 -0
  1007. package/docs/zh-CN/web/index.md +118 -0
  1008. package/docs/zh-CN/web/webchat.md +56 -0
  1009. package/extensions/bluebubbles/README.md +45 -0
  1010. package/extensions/bluebubbles/index.ts +19 -0
  1011. package/extensions/bluebubbles/node_modules/.bin/openclaw +21 -0
  1012. package/extensions/bluebubbles/openclaw.plugin.json +9 -0
  1013. package/extensions/bluebubbles/package.json +36 -0
  1014. package/extensions/bluebubbles/src/accounts.ts +88 -0
  1015. package/extensions/bluebubbles/src/actions.test.ts +650 -0
  1016. package/extensions/bluebubbles/src/actions.ts +438 -0
  1017. package/extensions/bluebubbles/src/attachments.test.ts +345 -0
  1018. package/extensions/bluebubbles/src/attachments.ts +300 -0
  1019. package/extensions/bluebubbles/src/channel.ts +414 -0
  1020. package/extensions/bluebubbles/src/chat.test.ts +461 -0
  1021. package/extensions/bluebubbles/src/chat.ts +378 -0
  1022. package/extensions/bluebubbles/src/config-schema.ts +51 -0
  1023. package/extensions/bluebubbles/src/media-send.ts +174 -0
  1024. package/extensions/bluebubbles/src/monitor.test.ts +2342 -0
  1025. package/extensions/bluebubbles/src/monitor.ts +2490 -0
  1026. package/extensions/bluebubbles/src/onboarding.ts +352 -0
  1027. package/extensions/bluebubbles/src/probe.ts +135 -0
  1028. package/extensions/bluebubbles/src/reactions.test.ts +392 -0
  1029. package/extensions/bluebubbles/src/reactions.ts +188 -0
  1030. package/extensions/bluebubbles/src/runtime.ts +14 -0
  1031. package/extensions/bluebubbles/src/send.test.ts +808 -0
  1032. package/extensions/bluebubbles/src/send.ts +467 -0
  1033. package/extensions/bluebubbles/src/targets.test.ts +183 -0
  1034. package/extensions/bluebubbles/src/targets.ts +422 -0
  1035. package/extensions/bluebubbles/src/types.ts +127 -0
  1036. package/extensions/copilot-proxy/README.md +24 -0
  1037. package/extensions/copilot-proxy/index.ts +148 -0
  1038. package/extensions/copilot-proxy/node_modules/.bin/openclaw +21 -0
  1039. package/extensions/copilot-proxy/openclaw.plugin.json +9 -0
  1040. package/extensions/copilot-proxy/package.json +14 -0
  1041. package/extensions/diagnostics-otel/index.ts +15 -0
  1042. package/extensions/diagnostics-otel/node_modules/.bin/openclaw +21 -0
  1043. package/extensions/diagnostics-otel/openclaw.plugin.json +8 -0
  1044. package/extensions/diagnostics-otel/package.json +27 -0
  1045. package/extensions/diagnostics-otel/src/service.test.ts +226 -0
  1046. package/extensions/diagnostics-otel/src/service.ts +635 -0
  1047. package/extensions/discord/index.ts +17 -0
  1048. package/extensions/discord/node_modules/.bin/openclaw +21 -0
  1049. package/extensions/discord/openclaw.plugin.json +9 -0
  1050. package/extensions/discord/package.json +14 -0
  1051. package/extensions/discord/src/channel.ts +422 -0
  1052. package/extensions/discord/src/runtime.ts +14 -0
  1053. package/extensions/feishu/README.md +47 -0
  1054. package/extensions/feishu/index.ts +15 -0
  1055. package/extensions/feishu/node_modules/.bin/openclaw +21 -0
  1056. package/extensions/feishu/openclaw.plugin.json +9 -0
  1057. package/extensions/feishu/package.json +33 -0
  1058. package/extensions/feishu/src/channel.ts +276 -0
  1059. package/extensions/feishu/src/config-schema.ts +46 -0
  1060. package/extensions/feishu/src/onboarding.ts +278 -0
  1061. package/extensions/google-antigravity-auth/README.md +24 -0
  1062. package/extensions/google-antigravity-auth/index.ts +461 -0
  1063. package/extensions/google-antigravity-auth/node_modules/.bin/openclaw +21 -0
  1064. package/extensions/google-antigravity-auth/openclaw.plugin.json +9 -0
  1065. package/extensions/google-antigravity-auth/package.json +14 -0
  1066. package/extensions/google-gemini-cli-auth/README.md +35 -0
  1067. package/extensions/google-gemini-cli-auth/index.ts +88 -0
  1068. package/extensions/google-gemini-cli-auth/node_modules/.bin/openclaw +21 -0
  1069. package/extensions/google-gemini-cli-auth/oauth.test.ts +240 -0
  1070. package/extensions/google-gemini-cli-auth/oauth.ts +662 -0
  1071. package/extensions/google-gemini-cli-auth/openclaw.plugin.json +9 -0
  1072. package/extensions/google-gemini-cli-auth/package.json +14 -0
  1073. package/extensions/googlechat/index.ts +19 -0
  1074. package/extensions/googlechat/node_modules/.bin/openclaw +21 -0
  1075. package/extensions/googlechat/openclaw.plugin.json +9 -0
  1076. package/extensions/googlechat/package.json +39 -0
  1077. package/extensions/googlechat/src/accounts.ts +147 -0
  1078. package/extensions/googlechat/src/actions.ts +181 -0
  1079. package/extensions/googlechat/src/api.test.ts +61 -0
  1080. package/extensions/googlechat/src/api.ts +282 -0
  1081. package/extensions/googlechat/src/auth.ts +123 -0
  1082. package/extensions/googlechat/src/channel.ts +583 -0
  1083. package/extensions/googlechat/src/monitor.test.ts +22 -0
  1084. package/extensions/googlechat/src/monitor.ts +949 -0
  1085. package/extensions/googlechat/src/onboarding.ts +269 -0
  1086. package/extensions/googlechat/src/runtime.ts +14 -0
  1087. package/extensions/googlechat/src/targets.test.ts +32 -0
  1088. package/extensions/googlechat/src/targets.ts +65 -0
  1089. package/extensions/googlechat/src/types.config.ts +3 -0
  1090. package/extensions/googlechat/src/types.ts +73 -0
  1091. package/extensions/imessage/index.ts +17 -0
  1092. package/extensions/imessage/node_modules/.bin/openclaw +21 -0
  1093. package/extensions/imessage/openclaw.plugin.json +9 -0
  1094. package/extensions/imessage/package.json +14 -0
  1095. package/extensions/imessage/src/channel.ts +294 -0
  1096. package/extensions/imessage/src/runtime.ts +14 -0
  1097. package/extensions/line/index.ts +19 -0
  1098. package/extensions/line/node_modules/.bin/openclaw +21 -0
  1099. package/extensions/line/openclaw.plugin.json +9 -0
  1100. package/extensions/line/package.json +29 -0
  1101. package/extensions/line/src/card-command.ts +344 -0
  1102. package/extensions/line/src/channel.logout.test.ts +99 -0
  1103. package/extensions/line/src/channel.sendPayload.test.ts +306 -0
  1104. package/extensions/line/src/channel.ts +780 -0
  1105. package/extensions/line/src/runtime.ts +14 -0
  1106. package/extensions/llm-task/README.md +97 -0
  1107. package/extensions/llm-task/index.ts +6 -0
  1108. package/extensions/llm-task/node_modules/.bin/openclaw +21 -0
  1109. package/extensions/llm-task/openclaw.plugin.json +21 -0
  1110. package/extensions/llm-task/package.json +14 -0
  1111. package/extensions/llm-task/src/llm-task-tool.test.ts +138 -0
  1112. package/extensions/llm-task/src/llm-task-tool.ts +245 -0
  1113. package/extensions/lobster/README.md +75 -0
  1114. package/extensions/lobster/SKILL.md +97 -0
  1115. package/extensions/lobster/index.ts +14 -0
  1116. package/extensions/lobster/node_modules/.bin/openclaw +21 -0
  1117. package/extensions/lobster/openclaw.plugin.json +10 -0
  1118. package/extensions/lobster/package.json +14 -0
  1119. package/extensions/lobster/src/lobster-tool.test.ts +247 -0
  1120. package/extensions/lobster/src/lobster-tool.ts +328 -0
  1121. package/extensions/matrix/CHANGELOG.md +87 -0
  1122. package/extensions/matrix/index.ts +17 -0
  1123. package/extensions/matrix/node_modules/.bin/markdown-it +21 -0
  1124. package/extensions/matrix/node_modules/.bin/openclaw +21 -0
  1125. package/extensions/matrix/openclaw.plugin.json +9 -0
  1126. package/extensions/matrix/package.json +36 -0
  1127. package/extensions/matrix/src/actions.ts +195 -0
  1128. package/extensions/matrix/src/channel.directory.test.ts +64 -0
  1129. package/extensions/matrix/src/channel.ts +439 -0
  1130. package/extensions/matrix/src/config-schema.ts +62 -0
  1131. package/extensions/matrix/src/directory-live.ts +188 -0
  1132. package/extensions/matrix/src/group-mentions.ts +66 -0
  1133. package/extensions/matrix/src/matrix/accounts.test.ts +82 -0
  1134. package/extensions/matrix/src/matrix/accounts.ts +65 -0
  1135. package/extensions/matrix/src/matrix/actions/client.ts +57 -0
  1136. package/extensions/matrix/src/matrix/actions/messages.ts +128 -0
  1137. package/extensions/matrix/src/matrix/actions/pins.ts +76 -0
  1138. package/extensions/matrix/src/matrix/actions/reactions.ts +96 -0
  1139. package/extensions/matrix/src/matrix/actions/room.ts +85 -0
  1140. package/extensions/matrix/src/matrix/actions/summary.ts +75 -0
  1141. package/extensions/matrix/src/matrix/actions/types.ts +84 -0
  1142. package/extensions/matrix/src/matrix/actions.ts +15 -0
  1143. package/extensions/matrix/src/matrix/active-client.ts +11 -0
  1144. package/extensions/matrix/src/matrix/client/config.ts +160 -0
  1145. package/extensions/matrix/src/matrix/client/create-client.ts +123 -0
  1146. package/extensions/matrix/src/matrix/client/logging.ts +36 -0
  1147. package/extensions/matrix/src/matrix/client/runtime.ts +4 -0
  1148. package/extensions/matrix/src/matrix/client/shared.ts +170 -0
  1149. package/extensions/matrix/src/matrix/client/storage.ts +131 -0
  1150. package/extensions/matrix/src/matrix/client/types.ts +34 -0
  1151. package/extensions/matrix/src/matrix/client.test.ts +56 -0
  1152. package/extensions/matrix/src/matrix/client.ts +5 -0
  1153. package/extensions/matrix/src/matrix/credentials.ts +105 -0
  1154. package/extensions/matrix/src/matrix/deps.ts +60 -0
  1155. package/extensions/matrix/src/matrix/format.test.ts +33 -0
  1156. package/extensions/matrix/src/matrix/format.ts +22 -0
  1157. package/extensions/matrix/src/matrix/index.ts +11 -0
  1158. package/extensions/matrix/src/matrix/monitor/allowlist.test.ts +45 -0
  1159. package/extensions/matrix/src/matrix/monitor/allowlist.ts +103 -0
  1160. package/extensions/matrix/src/matrix/monitor/auto-join.ts +71 -0
  1161. package/extensions/matrix/src/matrix/monitor/direct.ts +104 -0
  1162. package/extensions/matrix/src/matrix/monitor/events.ts +101 -0
  1163. package/extensions/matrix/src/matrix/monitor/handler.ts +661 -0
  1164. package/extensions/matrix/src/matrix/monitor/index.ts +338 -0
  1165. package/extensions/matrix/src/matrix/monitor/location.ts +100 -0
  1166. package/extensions/matrix/src/matrix/monitor/media.test.ts +102 -0
  1167. package/extensions/matrix/src/matrix/monitor/media.ts +113 -0
  1168. package/extensions/matrix/src/matrix/monitor/mentions.ts +31 -0
  1169. package/extensions/matrix/src/matrix/monitor/replies.ts +97 -0
  1170. package/extensions/matrix/src/matrix/monitor/room-info.ts +55 -0
  1171. package/extensions/matrix/src/matrix/monitor/rooms.test.ts +39 -0
  1172. package/extensions/matrix/src/matrix/monitor/rooms.ts +47 -0
  1173. package/extensions/matrix/src/matrix/monitor/threads.ts +68 -0
  1174. package/extensions/matrix/src/matrix/monitor/types.ts +39 -0
  1175. package/extensions/matrix/src/matrix/poll-types.test.ts +21 -0
  1176. package/extensions/matrix/src/matrix/poll-types.ts +166 -0
  1177. package/extensions/matrix/src/matrix/probe.ts +70 -0
  1178. package/extensions/matrix/src/matrix/send/client.ts +66 -0
  1179. package/extensions/matrix/src/matrix/send/formatting.ts +89 -0
  1180. package/extensions/matrix/src/matrix/send/media.ts +229 -0
  1181. package/extensions/matrix/src/matrix/send/targets.test.ts +98 -0
  1182. package/extensions/matrix/src/matrix/send/targets.ts +136 -0
  1183. package/extensions/matrix/src/matrix/send/types.ts +109 -0
  1184. package/extensions/matrix/src/matrix/send.test.ts +171 -0
  1185. package/extensions/matrix/src/matrix/send.ts +260 -0
  1186. package/extensions/matrix/src/onboarding.ts +449 -0
  1187. package/extensions/matrix/src/outbound.ts +52 -0
  1188. package/extensions/matrix/src/resolve-targets.test.ts +48 -0
  1189. package/extensions/matrix/src/resolve-targets.ts +135 -0
  1190. package/extensions/matrix/src/runtime.ts +14 -0
  1191. package/extensions/matrix/src/tool-actions.ts +164 -0
  1192. package/extensions/matrix/src/types.ts +95 -0
  1193. package/extensions/mattermost/index.ts +17 -0
  1194. package/extensions/mattermost/node_modules/.bin/openclaw +21 -0
  1195. package/extensions/mattermost/openclaw.plugin.json +9 -0
  1196. package/extensions/mattermost/package.json +28 -0
  1197. package/extensions/mattermost/src/channel.test.ts +48 -0
  1198. package/extensions/mattermost/src/channel.ts +337 -0
  1199. package/extensions/mattermost/src/config-schema.ts +55 -0
  1200. package/extensions/mattermost/src/group-mentions.ts +15 -0
  1201. package/extensions/mattermost/src/mattermost/accounts.ts +128 -0
  1202. package/extensions/mattermost/src/mattermost/client.ts +220 -0
  1203. package/extensions/mattermost/src/mattermost/index.ts +9 -0
  1204. package/extensions/mattermost/src/mattermost/monitor-helpers.ts +166 -0
  1205. package/extensions/mattermost/src/mattermost/monitor.ts +987 -0
  1206. package/extensions/mattermost/src/mattermost/probe.ts +74 -0
  1207. package/extensions/mattermost/src/mattermost/send.ts +231 -0
  1208. package/extensions/mattermost/src/normalize.ts +46 -0
  1209. package/extensions/mattermost/src/onboarding-helpers.ts +44 -0
  1210. package/extensions/mattermost/src/onboarding.ts +186 -0
  1211. package/extensions/mattermost/src/runtime.ts +14 -0
  1212. package/extensions/mattermost/src/types.ts +50 -0
  1213. package/extensions/memory-core/index.ts +38 -0
  1214. package/extensions/memory-core/node_modules/.bin/openclaw +21 -0
  1215. package/extensions/memory-core/openclaw.plugin.json +9 -0
  1216. package/extensions/memory-core/package.json +17 -0
  1217. package/extensions/memory-lancedb/config.ts +139 -0
  1218. package/extensions/memory-lancedb/index.test.ts +295 -0
  1219. package/extensions/memory-lancedb/index.ts +608 -0
  1220. package/extensions/memory-lancedb/node_modules/.bin/openai +21 -0
  1221. package/extensions/memory-lancedb/node_modules/.bin/openclaw +21 -0
  1222. package/extensions/memory-lancedb/openclaw.plugin.json +60 -0
  1223. package/extensions/memory-lancedb/package.json +19 -0
  1224. package/extensions/minimax-portal-auth/README.md +33 -0
  1225. package/extensions/minimax-portal-auth/index.ts +155 -0
  1226. package/extensions/minimax-portal-auth/node_modules/.bin/openclaw +21 -0
  1227. package/extensions/minimax-portal-auth/oauth.ts +247 -0
  1228. package/extensions/minimax-portal-auth/openclaw.plugin.json +9 -0
  1229. package/extensions/minimax-portal-auth/package.json +14 -0
  1230. package/extensions/msteams/CHANGELOG.md +83 -0
  1231. package/extensions/msteams/index.ts +17 -0
  1232. package/extensions/msteams/node_modules/.bin/openclaw +21 -0
  1233. package/extensions/msteams/openclaw.plugin.json +9 -0
  1234. package/extensions/msteams/package.json +39 -0
  1235. package/extensions/msteams/src/attachments/download.ts +283 -0
  1236. package/extensions/msteams/src/attachments/graph.ts +353 -0
  1237. package/extensions/msteams/src/attachments/html.ts +90 -0
  1238. package/extensions/msteams/src/attachments/payload.ts +22 -0
  1239. package/extensions/msteams/src/attachments/shared.ts +291 -0
  1240. package/extensions/msteams/src/attachments/types.ts +37 -0
  1241. package/extensions/msteams/src/attachments.test.ts +459 -0
  1242. package/extensions/msteams/src/attachments.ts +18 -0
  1243. package/extensions/msteams/src/channel.directory.test.ts +48 -0
  1244. package/extensions/msteams/src/channel.ts +459 -0
  1245. package/extensions/msteams/src/conversation-store-fs.test.ts +88 -0
  1246. package/extensions/msteams/src/conversation-store-fs.ts +165 -0
  1247. package/extensions/msteams/src/conversation-store-memory.ts +47 -0
  1248. package/extensions/msteams/src/conversation-store.ts +41 -0
  1249. package/extensions/msteams/src/directory-live.ts +205 -0
  1250. package/extensions/msteams/src/errors.test.ts +45 -0
  1251. package/extensions/msteams/src/errors.ts +190 -0
  1252. package/extensions/msteams/src/file-consent-helpers.test.ts +243 -0
  1253. package/extensions/msteams/src/file-consent-helpers.ts +73 -0
  1254. package/extensions/msteams/src/file-consent.ts +126 -0
  1255. package/extensions/msteams/src/graph-chat.ts +53 -0
  1256. package/extensions/msteams/src/graph-upload.ts +453 -0
  1257. package/extensions/msteams/src/inbound.test.ts +66 -0
  1258. package/extensions/msteams/src/inbound.ts +48 -0
  1259. package/extensions/msteams/src/index.ts +4 -0
  1260. package/extensions/msteams/src/media-helpers.test.ts +189 -0
  1261. package/extensions/msteams/src/media-helpers.ts +86 -0
  1262. package/extensions/msteams/src/messenger.test.ts +248 -0
  1263. package/extensions/msteams/src/messenger.ts +495 -0
  1264. package/extensions/msteams/src/monitor-handler/inbound-media.ts +128 -0
  1265. package/extensions/msteams/src/monitor-handler/message-handler.ts +640 -0
  1266. package/extensions/msteams/src/monitor-handler.ts +162 -0
  1267. package/extensions/msteams/src/monitor-types.ts +5 -0
  1268. package/extensions/msteams/src/monitor.ts +295 -0
  1269. package/extensions/msteams/src/onboarding.ts +431 -0
  1270. package/extensions/msteams/src/outbound.ts +46 -0
  1271. package/extensions/msteams/src/pending-uploads.ts +89 -0
  1272. package/extensions/msteams/src/policy.test.ts +209 -0
  1273. package/extensions/msteams/src/policy.ts +273 -0
  1274. package/extensions/msteams/src/polls-store-memory.ts +32 -0
  1275. package/extensions/msteams/src/polls-store.test.ts +38 -0
  1276. package/extensions/msteams/src/polls.test.ts +72 -0
  1277. package/extensions/msteams/src/polls.ts +315 -0
  1278. package/extensions/msteams/src/probe.test.ts +58 -0
  1279. package/extensions/msteams/src/probe.ts +107 -0
  1280. package/extensions/msteams/src/reply-dispatcher.ts +130 -0
  1281. package/extensions/msteams/src/resolve-allowlist.ts +297 -0
  1282. package/extensions/msteams/src/runtime.ts +14 -0
  1283. package/extensions/msteams/src/sdk-types.ts +19 -0
  1284. package/extensions/msteams/src/sdk.ts +33 -0
  1285. package/extensions/msteams/src/send-context.ts +164 -0
  1286. package/extensions/msteams/src/send.ts +519 -0
  1287. package/extensions/msteams/src/sent-message-cache.test.ts +15 -0
  1288. package/extensions/msteams/src/sent-message-cache.ts +47 -0
  1289. package/extensions/msteams/src/storage.ts +25 -0
  1290. package/extensions/msteams/src/store-fs.ts +83 -0
  1291. package/extensions/msteams/src/token.ts +19 -0
  1292. package/extensions/nextcloud-talk/index.ts +17 -0
  1293. package/extensions/nextcloud-talk/node_modules/.bin/openclaw +21 -0
  1294. package/extensions/nextcloud-talk/openclaw.plugin.json +9 -0
  1295. package/extensions/nextcloud-talk/package.json +33 -0
  1296. package/extensions/nextcloud-talk/src/accounts.ts +174 -0
  1297. package/extensions/nextcloud-talk/src/channel.ts +409 -0
  1298. package/extensions/nextcloud-talk/src/config-schema.ts +78 -0
  1299. package/extensions/nextcloud-talk/src/format.ts +79 -0
  1300. package/extensions/nextcloud-talk/src/inbound.ts +317 -0
  1301. package/extensions/nextcloud-talk/src/monitor.ts +246 -0
  1302. package/extensions/nextcloud-talk/src/normalize.ts +39 -0
  1303. package/extensions/nextcloud-talk/src/onboarding.ts +343 -0
  1304. package/extensions/nextcloud-talk/src/policy.test.ts +33 -0
  1305. package/extensions/nextcloud-talk/src/policy.ts +180 -0
  1306. package/extensions/nextcloud-talk/src/room-info.ts +125 -0
  1307. package/extensions/nextcloud-talk/src/runtime.ts +14 -0
  1308. package/extensions/nextcloud-talk/src/send.ts +210 -0
  1309. package/extensions/nextcloud-talk/src/signature.ts +72 -0
  1310. package/extensions/nextcloud-talk/src/types.ts +179 -0
  1311. package/extensions/nostr/CHANGELOG.md +74 -0
  1312. package/extensions/nostr/README.md +136 -0
  1313. package/extensions/nostr/index.ts +68 -0
  1314. package/extensions/nostr/node_modules/.bin/openclaw +21 -0
  1315. package/extensions/nostr/openclaw.plugin.json +9 -0
  1316. package/extensions/nostr/package.json +34 -0
  1317. package/extensions/nostr/src/channel.test.ts +151 -0
  1318. package/extensions/nostr/src/channel.ts +353 -0
  1319. package/extensions/nostr/src/config-schema.ts +90 -0
  1320. package/extensions/nostr/src/metrics.ts +478 -0
  1321. package/extensions/nostr/src/nostr-bus.fuzz.test.ts +533 -0
  1322. package/extensions/nostr/src/nostr-bus.integration.test.ts +448 -0
  1323. package/extensions/nostr/src/nostr-bus.test.ts +199 -0
  1324. package/extensions/nostr/src/nostr-bus.ts +715 -0
  1325. package/extensions/nostr/src/nostr-profile-http.test.ts +378 -0
  1326. package/extensions/nostr/src/nostr-profile-http.ts +519 -0
  1327. package/extensions/nostr/src/nostr-profile-import.test.ts +119 -0
  1328. package/extensions/nostr/src/nostr-profile-import.ts +262 -0
  1329. package/extensions/nostr/src/nostr-profile.fuzz.test.ts +477 -0
  1330. package/extensions/nostr/src/nostr-profile.test.ts +410 -0
  1331. package/extensions/nostr/src/nostr-profile.ts +277 -0
  1332. package/extensions/nostr/src/nostr-state-store.test.ts +131 -0
  1333. package/extensions/nostr/src/nostr-state-store.ts +226 -0
  1334. package/extensions/nostr/src/runtime.ts +14 -0
  1335. package/extensions/nostr/src/seen-tracker.ts +303 -0
  1336. package/extensions/nostr/src/types.test.ts +157 -0
  1337. package/extensions/nostr/src/types.ts +101 -0
  1338. package/extensions/nostr/test/setup.ts +5 -0
  1339. package/extensions/open-prose/README.md +25 -0
  1340. package/extensions/open-prose/index.ts +5 -0
  1341. package/extensions/open-prose/node_modules/.bin/openclaw +21 -0
  1342. package/extensions/open-prose/openclaw.plugin.json +11 -0
  1343. package/extensions/open-prose/package.json +14 -0
  1344. package/extensions/open-prose/skills/prose/LICENSE +21 -0
  1345. package/extensions/open-prose/skills/prose/SKILL.md +323 -0
  1346. package/extensions/open-prose/skills/prose/alt-borges.md +141 -0
  1347. package/extensions/open-prose/skills/prose/alts/arabian-nights.md +358 -0
  1348. package/extensions/open-prose/skills/prose/alts/borges.md +360 -0
  1349. package/extensions/open-prose/skills/prose/alts/folk.md +322 -0
  1350. package/extensions/open-prose/skills/prose/alts/homer.md +346 -0
  1351. package/extensions/open-prose/skills/prose/alts/kafka.md +373 -0
  1352. package/extensions/open-prose/skills/prose/compiler.md +2971 -0
  1353. package/extensions/open-prose/skills/prose/examples/01-hello-world.prose +4 -0
  1354. package/extensions/open-prose/skills/prose/examples/02-research-and-summarize.prose +6 -0
  1355. package/extensions/open-prose/skills/prose/examples/03-code-review.prose +17 -0
  1356. package/extensions/open-prose/skills/prose/examples/04-write-and-refine.prose +14 -0
  1357. package/extensions/open-prose/skills/prose/examples/05-debug-issue.prose +20 -0
  1358. package/extensions/open-prose/skills/prose/examples/06-explain-codebase.prose +17 -0
  1359. package/extensions/open-prose/skills/prose/examples/07-refactor.prose +20 -0
  1360. package/extensions/open-prose/skills/prose/examples/08-blog-post.prose +20 -0
  1361. package/extensions/open-prose/skills/prose/examples/09-research-with-agents.prose +25 -0
  1362. package/extensions/open-prose/skills/prose/examples/10-code-review-agents.prose +32 -0
  1363. package/extensions/open-prose/skills/prose/examples/11-skills-and-imports.prose +27 -0
  1364. package/extensions/open-prose/skills/prose/examples/12-secure-agent-permissions.prose +43 -0
  1365. package/extensions/open-prose/skills/prose/examples/13-variables-and-context.prose +51 -0
  1366. package/extensions/open-prose/skills/prose/examples/14-composition-blocks.prose +48 -0
  1367. package/extensions/open-prose/skills/prose/examples/15-inline-sequences.prose +23 -0
  1368. package/extensions/open-prose/skills/prose/examples/16-parallel-reviews.prose +19 -0
  1369. package/extensions/open-prose/skills/prose/examples/17-parallel-research.prose +19 -0
  1370. package/extensions/open-prose/skills/prose/examples/18-mixed-parallel-sequential.prose +36 -0
  1371. package/extensions/open-prose/skills/prose/examples/19-advanced-parallel.prose +71 -0
  1372. package/extensions/open-prose/skills/prose/examples/20-fixed-loops.prose +20 -0
  1373. package/extensions/open-prose/skills/prose/examples/21-pipeline-operations.prose +35 -0
  1374. package/extensions/open-prose/skills/prose/examples/22-error-handling.prose +51 -0
  1375. package/extensions/open-prose/skills/prose/examples/23-retry-with-backoff.prose +63 -0
  1376. package/extensions/open-prose/skills/prose/examples/24-choice-blocks.prose +86 -0
  1377. package/extensions/open-prose/skills/prose/examples/25-conditionals.prose +114 -0
  1378. package/extensions/open-prose/skills/prose/examples/26-parameterized-blocks.prose +100 -0
  1379. package/extensions/open-prose/skills/prose/examples/27-string-interpolation.prose +105 -0
  1380. package/extensions/open-prose/skills/prose/examples/28-automated-pr-review.prose +37 -0
  1381. package/extensions/open-prose/skills/prose/examples/28-gas-town.prose +1572 -0
  1382. package/extensions/open-prose/skills/prose/examples/29-captains-chair.prose +218 -0
  1383. package/extensions/open-prose/skills/prose/examples/30-captains-chair-simple.prose +42 -0
  1384. package/extensions/open-prose/skills/prose/examples/31-captains-chair-with-memory.prose +145 -0
  1385. package/extensions/open-prose/skills/prose/examples/33-pr-review-autofix.prose +168 -0
  1386. package/extensions/open-prose/skills/prose/examples/34-content-pipeline.prose +204 -0
  1387. package/extensions/open-prose/skills/prose/examples/35-feature-factory.prose +296 -0
  1388. package/extensions/open-prose/skills/prose/examples/36-bug-hunter.prose +237 -0
  1389. package/extensions/open-prose/skills/prose/examples/37-the-forge.prose +1474 -0
  1390. package/extensions/open-prose/skills/prose/examples/38-skill-scan.prose +455 -0
  1391. package/extensions/open-prose/skills/prose/examples/39-architect-by-simulation.prose +277 -0
  1392. package/extensions/open-prose/skills/prose/examples/40-rlm-self-refine.prose +32 -0
  1393. package/extensions/open-prose/skills/prose/examples/41-rlm-divide-conquer.prose +38 -0
  1394. package/extensions/open-prose/skills/prose/examples/42-rlm-filter-recurse.prose +46 -0
  1395. package/extensions/open-prose/skills/prose/examples/43-rlm-pairwise.prose +50 -0
  1396. package/extensions/open-prose/skills/prose/examples/44-run-endpoint-ux-test.prose +261 -0
  1397. package/extensions/open-prose/skills/prose/examples/45-plugin-release.prose +159 -0
  1398. package/extensions/open-prose/skills/prose/examples/45-run-endpoint-ux-test-with-remediation.prose +637 -0
  1399. package/extensions/open-prose/skills/prose/examples/46-run-endpoint-ux-test-fast.prose +148 -0
  1400. package/extensions/open-prose/skills/prose/examples/46-workflow-crystallizer.prose +225 -0
  1401. package/extensions/open-prose/skills/prose/examples/47-language-self-improvement.prose +356 -0
  1402. package/extensions/open-prose/skills/prose/examples/48-habit-miner.prose +445 -0
  1403. package/extensions/open-prose/skills/prose/examples/49-prose-run-retrospective.prose +210 -0
  1404. package/extensions/open-prose/skills/prose/examples/README.md +391 -0
  1405. package/extensions/open-prose/skills/prose/examples/roadmap/README.md +22 -0
  1406. package/extensions/open-prose/skills/prose/examples/roadmap/iterative-refinement.prose +20 -0
  1407. package/extensions/open-prose/skills/prose/examples/roadmap/parallel-review.prose +18 -0
  1408. package/extensions/open-prose/skills/prose/examples/roadmap/simple-pipeline.prose +17 -0
  1409. package/extensions/open-prose/skills/prose/examples/roadmap/syntax/open-prose-syntax.prose +223 -0
  1410. package/extensions/open-prose/skills/prose/guidance/antipatterns.md +951 -0
  1411. package/extensions/open-prose/skills/prose/guidance/patterns.md +700 -0
  1412. package/extensions/open-prose/skills/prose/guidance/system-prompt.md +180 -0
  1413. package/extensions/open-prose/skills/prose/help.md +144 -0
  1414. package/extensions/open-prose/skills/prose/lib/README.md +108 -0
  1415. package/extensions/open-prose/skills/prose/lib/calibrator.prose +215 -0
  1416. package/extensions/open-prose/skills/prose/lib/cost-analyzer.prose +174 -0
  1417. package/extensions/open-prose/skills/prose/lib/error-forensics.prose +250 -0
  1418. package/extensions/open-prose/skills/prose/lib/inspector.prose +196 -0
  1419. package/extensions/open-prose/skills/prose/lib/profiler.prose +460 -0
  1420. package/extensions/open-prose/skills/prose/lib/program-improver.prose +275 -0
  1421. package/extensions/open-prose/skills/prose/lib/project-memory.prose +118 -0
  1422. package/extensions/open-prose/skills/prose/lib/user-memory.prose +93 -0
  1423. package/extensions/open-prose/skills/prose/lib/vm-improver.prose +243 -0
  1424. package/extensions/open-prose/skills/prose/primitives/session.md +593 -0
  1425. package/extensions/open-prose/skills/prose/prose.md +1237 -0
  1426. package/extensions/open-prose/skills/prose/state/filesystem.md +498 -0
  1427. package/extensions/open-prose/skills/prose/state/in-context.md +384 -0
  1428. package/extensions/open-prose/skills/prose/state/postgres.md +880 -0
  1429. package/extensions/open-prose/skills/prose/state/sqlite.md +574 -0
  1430. package/extensions/qwen-portal-auth/README.md +24 -0
  1431. package/extensions/qwen-portal-auth/index.ts +130 -0
  1432. package/extensions/qwen-portal-auth/oauth.ts +190 -0
  1433. package/extensions/qwen-portal-auth/openclaw.plugin.json +9 -0
  1434. package/extensions/signal/index.ts +17 -0
  1435. package/extensions/signal/node_modules/.bin/openclaw +21 -0
  1436. package/extensions/signal/openclaw.plugin.json +9 -0
  1437. package/extensions/signal/package.json +14 -0
  1438. package/extensions/signal/src/channel.ts +315 -0
  1439. package/extensions/signal/src/runtime.ts +14 -0
  1440. package/extensions/slack/index.ts +17 -0
  1441. package/extensions/slack/node_modules/.bin/openclaw +21 -0
  1442. package/extensions/slack/openclaw.plugin.json +9 -0
  1443. package/extensions/slack/package.json +14 -0
  1444. package/extensions/slack/src/channel.ts +604 -0
  1445. package/extensions/slack/src/runtime.ts +14 -0
  1446. package/extensions/telegram/index.ts +17 -0
  1447. package/extensions/telegram/node_modules/.bin/openclaw +21 -0
  1448. package/extensions/telegram/openclaw.plugin.json +9 -0
  1449. package/extensions/telegram/package.json +14 -0
  1450. package/extensions/telegram/src/channel.ts +482 -0
  1451. package/extensions/telegram/src/runtime.ts +14 -0
  1452. package/extensions/tlon/README.md +5 -0
  1453. package/extensions/tlon/index.ts +17 -0
  1454. package/extensions/tlon/node_modules/.bin/openclaw +21 -0
  1455. package/extensions/tlon/openclaw.plugin.json +9 -0
  1456. package/extensions/tlon/package.json +33 -0
  1457. package/extensions/tlon/src/channel.ts +392 -0
  1458. package/extensions/tlon/src/config-schema.test.ts +31 -0
  1459. package/extensions/tlon/src/config-schema.ts +43 -0
  1460. package/extensions/tlon/src/monitor/discovery.ts +76 -0
  1461. package/extensions/tlon/src/monitor/history.ts +90 -0
  1462. package/extensions/tlon/src/monitor/index.ts +553 -0
  1463. package/extensions/tlon/src/monitor/processed-messages.test.ts +23 -0
  1464. package/extensions/tlon/src/monitor/processed-messages.ts +46 -0
  1465. package/extensions/tlon/src/monitor/utils.ts +105 -0
  1466. package/extensions/tlon/src/onboarding.ts +214 -0
  1467. package/extensions/tlon/src/runtime.ts +14 -0
  1468. package/extensions/tlon/src/targets.ts +89 -0
  1469. package/extensions/tlon/src/types.ts +92 -0
  1470. package/extensions/tlon/src/urbit/auth.ts +18 -0
  1471. package/extensions/tlon/src/urbit/http-api.ts +38 -0
  1472. package/extensions/tlon/src/urbit/send.test.ts +38 -0
  1473. package/extensions/tlon/src/urbit/send.ts +131 -0
  1474. package/extensions/tlon/src/urbit/sse-client.test.ts +40 -0
  1475. package/extensions/tlon/src/urbit/sse-client.ts +395 -0
  1476. package/extensions/twitch/CHANGELOG.md +45 -0
  1477. package/extensions/twitch/README.md +89 -0
  1478. package/extensions/twitch/index.ts +20 -0
  1479. package/extensions/twitch/node_modules/.bin/openclaw +21 -0
  1480. package/extensions/twitch/openclaw.plugin.json +9 -0
  1481. package/extensions/twitch/package.json +20 -0
  1482. package/extensions/twitch/src/access-control.test.ts +489 -0
  1483. package/extensions/twitch/src/access-control.ts +166 -0
  1484. package/extensions/twitch/src/actions.ts +173 -0
  1485. package/extensions/twitch/src/client-manager-registry.ts +115 -0
  1486. package/extensions/twitch/src/config-schema.ts +82 -0
  1487. package/extensions/twitch/src/config.test.ts +87 -0
  1488. package/extensions/twitch/src/config.ts +116 -0
  1489. package/extensions/twitch/src/monitor.ts +261 -0
  1490. package/extensions/twitch/src/onboarding.test.ts +311 -0
  1491. package/extensions/twitch/src/onboarding.ts +417 -0
  1492. package/extensions/twitch/src/outbound.test.ts +373 -0
  1493. package/extensions/twitch/src/outbound.ts +184 -0
  1494. package/extensions/twitch/src/plugin.test.ts +39 -0
  1495. package/extensions/twitch/src/plugin.ts +274 -0
  1496. package/extensions/twitch/src/probe.test.ts +195 -0
  1497. package/extensions/twitch/src/probe.ts +120 -0
  1498. package/extensions/twitch/src/resolver.ts +137 -0
  1499. package/extensions/twitch/src/runtime.ts +14 -0
  1500. package/extensions/twitch/src/send.test.ts +289 -0
  1501. package/extensions/twitch/src/send.ts +136 -0
  1502. package/extensions/twitch/src/status.test.ts +270 -0
  1503. package/extensions/twitch/src/status.ts +178 -0
  1504. package/extensions/twitch/src/token.test.ts +171 -0
  1505. package/extensions/twitch/src/token.ts +91 -0
  1506. package/extensions/twitch/src/twitch-client.test.ts +589 -0
  1507. package/extensions/twitch/src/twitch-client.ts +277 -0
  1508. package/extensions/twitch/src/types.ts +141 -0
  1509. package/extensions/twitch/src/utils/markdown.ts +98 -0
  1510. package/extensions/twitch/src/utils/twitch.ts +78 -0
  1511. package/extensions/twitch/test/setup.ts +7 -0
  1512. package/extensions/voice-call/CHANGELOG.md +109 -0
  1513. package/extensions/voice-call/README.md +139 -0
  1514. package/extensions/voice-call/index.ts +493 -0
  1515. package/extensions/voice-call/node_modules/.bin/openclaw +21 -0
  1516. package/extensions/voice-call/openclaw.plugin.json +559 -0
  1517. package/extensions/voice-call/package.json +19 -0
  1518. package/extensions/voice-call/src/allowlist.ts +19 -0
  1519. package/extensions/voice-call/src/cli.ts +279 -0
  1520. package/extensions/voice-call/src/config.test.ts +234 -0
  1521. package/extensions/voice-call/src/config.ts +523 -0
  1522. package/extensions/voice-call/src/core-bridge.ts +159 -0
  1523. package/extensions/voice-call/src/manager/context.ts +21 -0
  1524. package/extensions/voice-call/src/manager/events.ts +188 -0
  1525. package/extensions/voice-call/src/manager/lookup.ts +35 -0
  1526. package/extensions/voice-call/src/manager/outbound.ts +275 -0
  1527. package/extensions/voice-call/src/manager/state.ts +48 -0
  1528. package/extensions/voice-call/src/manager/store.ts +91 -0
  1529. package/extensions/voice-call/src/manager/timers.ts +89 -0
  1530. package/extensions/voice-call/src/manager/twiml.ts +9 -0
  1531. package/extensions/voice-call/src/manager.test.ts +194 -0
  1532. package/extensions/voice-call/src/manager.ts +887 -0
  1533. package/extensions/voice-call/src/media-stream.test.ts +96 -0
  1534. package/extensions/voice-call/src/media-stream.ts +411 -0
  1535. package/extensions/voice-call/src/providers/base.ts +67 -0
  1536. package/extensions/voice-call/src/providers/index.ts +10 -0
  1537. package/extensions/voice-call/src/providers/mock.ts +165 -0
  1538. package/extensions/voice-call/src/providers/plivo.test.ts +27 -0
  1539. package/extensions/voice-call/src/providers/plivo.ts +515 -0
  1540. package/extensions/voice-call/src/providers/stt-openai-realtime.ts +311 -0
  1541. package/extensions/voice-call/src/providers/telnyx.ts +371 -0
  1542. package/extensions/voice-call/src/providers/tts-openai.ts +259 -0
  1543. package/extensions/voice-call/src/providers/twilio/api.ts +42 -0
  1544. package/extensions/voice-call/src/providers/twilio/webhook.ts +32 -0
  1545. package/extensions/voice-call/src/providers/twilio.test.ts +60 -0
  1546. package/extensions/voice-call/src/providers/twilio.ts +626 -0
  1547. package/extensions/voice-call/src/response-generator.ts +158 -0
  1548. package/extensions/voice-call/src/runtime.ts +212 -0
  1549. package/extensions/voice-call/src/telephony-audio.ts +90 -0
  1550. package/extensions/voice-call/src/telephony-tts.ts +104 -0
  1551. package/extensions/voice-call/src/tunnel.ts +314 -0
  1552. package/extensions/voice-call/src/types.ts +272 -0
  1553. package/extensions/voice-call/src/utils.ts +14 -0
  1554. package/extensions/voice-call/src/voice-mapping.ts +67 -0
  1555. package/extensions/voice-call/src/webhook-security.test.ts +377 -0
  1556. package/extensions/voice-call/src/webhook-security.ts +689 -0
  1557. package/extensions/voice-call/src/webhook.ts +491 -0
  1558. package/extensions/whatsapp/index.ts +17 -0
  1559. package/extensions/whatsapp/node_modules/.bin/openclaw +21 -0
  1560. package/extensions/whatsapp/openclaw.plugin.json +9 -0
  1561. package/extensions/whatsapp/package.json +14 -0
  1562. package/extensions/whatsapp/src/channel.ts +508 -0
  1563. package/extensions/whatsapp/src/runtime.ts +14 -0
  1564. package/extensions/zalo/CHANGELOG.md +89 -0
  1565. package/extensions/zalo/README.md +50 -0
  1566. package/extensions/zalo/index.ts +19 -0
  1567. package/extensions/zalo/node_modules/.bin/openclaw +21 -0
  1568. package/extensions/zalo/openclaw.plugin.json +9 -0
  1569. package/extensions/zalo/package.json +36 -0
  1570. package/extensions/zalo/src/accounts.ts +80 -0
  1571. package/extensions/zalo/src/actions.ts +67 -0
  1572. package/extensions/zalo/src/api.ts +208 -0
  1573. package/extensions/zalo/src/channel.directory.test.ts +43 -0
  1574. package/extensions/zalo/src/channel.ts +414 -0
  1575. package/extensions/zalo/src/config-schema.ts +24 -0
  1576. package/extensions/zalo/src/monitor.ts +753 -0
  1577. package/extensions/zalo/src/monitor.webhook.test.ts +73 -0
  1578. package/extensions/zalo/src/onboarding.ts +401 -0
  1579. package/extensions/zalo/src/probe.ts +46 -0
  1580. package/extensions/zalo/src/proxy.ts +21 -0
  1581. package/extensions/zalo/src/runtime.ts +14 -0
  1582. package/extensions/zalo/src/send.ts +124 -0
  1583. package/extensions/zalo/src/status-issues.ts +53 -0
  1584. package/extensions/zalo/src/token.ts +63 -0
  1585. package/extensions/zalo/src/types.ts +42 -0
  1586. package/extensions/zalouser/CHANGELOG.md +61 -0
  1587. package/extensions/zalouser/README.md +225 -0
  1588. package/extensions/zalouser/index.ts +31 -0
  1589. package/extensions/zalouser/node_modules/.bin/openclaw +21 -0
  1590. package/extensions/zalouser/openclaw.plugin.json +9 -0
  1591. package/extensions/zalouser/package.json +36 -0
  1592. package/extensions/zalouser/src/accounts.ts +135 -0
  1593. package/extensions/zalouser/src/channel.test.ts +18 -0
  1594. package/extensions/zalouser/src/channel.ts +686 -0
  1595. package/extensions/zalouser/src/config-schema.ts +27 -0
  1596. package/extensions/zalouser/src/monitor.ts +590 -0
  1597. package/extensions/zalouser/src/onboarding.ts +504 -0
  1598. package/extensions/zalouser/src/probe.ts +28 -0
  1599. package/extensions/zalouser/src/runtime.ts +14 -0
  1600. package/extensions/zalouser/src/send.ts +160 -0
  1601. package/extensions/zalouser/src/status-issues.test.ts +57 -0
  1602. package/extensions/zalouser/src/status-issues.ts +89 -0
  1603. package/extensions/zalouser/src/tool.ts +164 -0
  1604. package/extensions/zalouser/src/types.ts +108 -0
  1605. package/extensions/zalouser/src/zca.ts +202 -0
  1606. package/openclaw.mjs +14 -0
  1607. package/package.json +245 -0
  1608. package/skills/1password/SKILL.md +70 -0
  1609. package/skills/1password/references/cli-examples.md +29 -0
  1610. package/skills/1password/references/get-started.md +17 -0
  1611. package/skills/apple-notes/SKILL.md +77 -0
  1612. package/skills/apple-reminders/SKILL.md +96 -0
  1613. package/skills/bear-notes/SKILL.md +107 -0
  1614. package/skills/bird/SKILL.md +224 -0
  1615. package/skills/blogwatcher/SKILL.md +69 -0
  1616. package/skills/blucli/SKILL.md +47 -0
  1617. package/skills/bluebubbles/SKILL.md +131 -0
  1618. package/skills/camsnap/SKILL.md +45 -0
  1619. package/skills/canvas/SKILL.md +198 -0
  1620. package/skills/clawhub/SKILL.md +77 -0
  1621. package/skills/coding-agent/SKILL.md +284 -0
  1622. package/skills/discord/SKILL.md +578 -0
  1623. package/skills/eightctl/SKILL.md +50 -0
  1624. package/skills/food-order/SKILL.md +48 -0
  1625. package/skills/gemini/SKILL.md +43 -0
  1626. package/skills/ghostly-projects/SKILL.md +160 -0
  1627. package/skills/gifgrep/SKILL.md +79 -0
  1628. package/skills/github/SKILL.md +77 -0
  1629. package/skills/gog/SKILL.md +116 -0
  1630. package/skills/goplaces/SKILL.md +52 -0
  1631. package/skills/healthcheck/SKILL.md +245 -0
  1632. package/skills/himalaya/SKILL.md +257 -0
  1633. package/skills/himalaya/references/configuration.md +184 -0
  1634. package/skills/himalaya/references/message-composition.md +199 -0
  1635. package/skills/imsg/SKILL.md +74 -0
  1636. package/skills/linear/SKILL.md +111 -0
  1637. package/skills/linear/linear.sh +204 -0
  1638. package/skills/local-places/SERVER_README.md +101 -0
  1639. package/skills/local-places/SKILL.md +102 -0
  1640. package/skills/local-places/pyproject.toml +21 -0
  1641. package/skills/local-places/src/local_places/__init__.py +2 -0
  1642. package/skills/local-places/src/local_places/google_places.py +314 -0
  1643. package/skills/local-places/src/local_places/main.py +65 -0
  1644. package/skills/local-places/src/local_places/schemas.py +107 -0
  1645. package/skills/mcporter/SKILL.md +61 -0
  1646. package/skills/model-usage/SKILL.md +69 -0
  1647. package/skills/model-usage/references/codexbar-cli.md +33 -0
  1648. package/skills/model-usage/scripts/model_usage.py +310 -0
  1649. package/skills/nano-banana-pro/SKILL.md +58 -0
  1650. package/skills/nano-banana-pro/scripts/generate_image.py +184 -0
  1651. package/skills/nano-pdf/SKILL.md +38 -0
  1652. package/skills/notion/SKILL.md +172 -0
  1653. package/skills/obsidian/SKILL.md +81 -0
  1654. package/skills/openai-image-gen/SKILL.md +89 -0
  1655. package/skills/openai-image-gen/scripts/gen.py +240 -0
  1656. package/skills/openai-whisper/SKILL.md +38 -0
  1657. package/skills/openai-whisper-api/SKILL.md +52 -0
  1658. package/skills/openai-whisper-api/scripts/transcribe.sh +85 -0
  1659. package/skills/openhue/SKILL.md +51 -0
  1660. package/skills/oracle/SKILL.md +125 -0
  1661. package/skills/ordercli/SKILL.md +78 -0
  1662. package/skills/peekaboo/SKILL.md +190 -0
  1663. package/skills/sag/SKILL.md +87 -0
  1664. package/skills/session-logs/SKILL.md +115 -0
  1665. package/skills/sherpa-onnx-tts/SKILL.md +103 -0
  1666. package/skills/sherpa-onnx-tts/bin/sherpa-onnx-tts +178 -0
  1667. package/skills/skill-creator/SKILL.md +370 -0
  1668. package/skills/skill-creator/license.txt +202 -0
  1669. package/skills/skill-creator/scripts/init_skill.py +378 -0
  1670. package/skills/skill-creator/scripts/package_skill.py +111 -0
  1671. package/skills/skill-creator/scripts/quick_validate.py +101 -0
  1672. package/skills/slack/SKILL.md +144 -0
  1673. package/skills/songsee/SKILL.md +49 -0
  1674. package/skills/sonoscli/SKILL.md +46 -0
  1675. package/skills/spotify-player/SKILL.md +64 -0
  1676. package/skills/summarize/SKILL.md +87 -0
  1677. package/skills/things-mac/SKILL.md +86 -0
  1678. package/skills/tmux/SKILL.md +135 -0
  1679. package/skills/tmux/scripts/find-sessions.sh +112 -0
  1680. package/skills/tmux/scripts/wait-for-text.sh +83 -0
  1681. package/skills/trello/SKILL.md +95 -0
  1682. package/skills/video-frames/SKILL.md +46 -0
  1683. package/skills/video-frames/scripts/frame.sh +81 -0
  1684. package/skills/voice-call/SKILL.md +45 -0
  1685. package/skills/wacli/SKILL.md +72 -0
  1686. package/skills/weather/SKILL.md +54 -0
@@ -0,0 +1,2587 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-Cbj13DAv.js";
2
+ import { i as isMessagingToolDuplicate } from "./pi-embedded-helpers-Dl8e5Rf8.js";
3
+ import { M as normalizeAccountId$1 } from "./agent-scope-BbT4OG2N.js";
4
+ import { A as logVerbose, C as getActivePluginRegistry, N as shouldLogVerbose } from "./subsystem-CAq3uyo7.js";
5
+ import { h as resolveUserPath } from "./utils-CKSrBNwq.js";
6
+ import { i as loadConfig } from "./config-BtSTwPcH.js";
7
+ import { r as normalizeChannelId, t as getChannelPlugin } from "./plugins-QJjTXliB.js";
8
+ import { V as getChannelDock, l as appendAssistantMessageToSessionTranscript, q as resolveSignalAccount, u as resolveMirroredTranscriptText } from "./sandbox-knontqD9.js";
9
+ import { C as resolvePinnedHostnameWithPolicy, S as resolvePinnedHostname, _ as maxBytesForKind, a as optimizeImageToPng, b as closeDispatcher, c as saveMediaBuffer, i as hasAlphaChannel, l as detectMime, n as convertHeicToJpeg, o as resizeToJpeg, u as extensionForMime, v as mediaKindFromMime, x as createPinnedDispatcher } from "./routes-ClNyEvlm.js";
10
+ import { t as INTERNAL_MESSAGE_CHANNEL } from "./message-channel-D6v_oPAg.js";
11
+ import { fileURLToPath } from "node:url";
12
+ import path from "node:path";
13
+ import fs from "node:fs/promises";
14
+ import { randomUUID } from "node:crypto";
15
+ import MarkdownIt from "markdown-it";
16
+
17
+ //#region src/infra/net/fetch-guard.ts
18
+ const DEFAULT_MAX_REDIRECTS = 3;
19
+ function isRedirectStatus(status) {
20
+ return status === 301 || status === 302 || status === 303 || status === 307 || status === 308;
21
+ }
22
+ function buildAbortSignal(params) {
23
+ const { timeoutMs, signal } = params;
24
+ if (!timeoutMs && !signal) return {
25
+ signal: void 0,
26
+ cleanup: () => {}
27
+ };
28
+ if (!timeoutMs) return {
29
+ signal,
30
+ cleanup: () => {}
31
+ };
32
+ const controller = new AbortController();
33
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
34
+ const onAbort = () => controller.abort();
35
+ if (signal) if (signal.aborted) controller.abort();
36
+ else signal.addEventListener("abort", onAbort, { once: true });
37
+ const cleanup = () => {
38
+ clearTimeout(timeoutId);
39
+ if (signal) signal.removeEventListener("abort", onAbort);
40
+ };
41
+ return {
42
+ signal: controller.signal,
43
+ cleanup
44
+ };
45
+ }
46
+ async function fetchWithSsrFGuard(params) {
47
+ const fetcher = params.fetchImpl ?? globalThis.fetch;
48
+ if (!fetcher) throw new Error("fetch is not available");
49
+ const maxRedirects = typeof params.maxRedirects === "number" && Number.isFinite(params.maxRedirects) ? Math.max(0, Math.floor(params.maxRedirects)) : DEFAULT_MAX_REDIRECTS;
50
+ const { signal, cleanup } = buildAbortSignal({
51
+ timeoutMs: params.timeoutMs,
52
+ signal: params.signal
53
+ });
54
+ let released = false;
55
+ const release = async (dispatcher) => {
56
+ if (released) return;
57
+ released = true;
58
+ cleanup();
59
+ await closeDispatcher(dispatcher ?? void 0);
60
+ };
61
+ const visited = /* @__PURE__ */ new Set();
62
+ let currentUrl = params.url;
63
+ let redirectCount = 0;
64
+ while (true) {
65
+ let parsedUrl;
66
+ try {
67
+ parsedUrl = new URL(currentUrl);
68
+ } catch {
69
+ await release();
70
+ throw new Error("Invalid URL: must be http or https");
71
+ }
72
+ if (!["http:", "https:"].includes(parsedUrl.protocol)) {
73
+ await release();
74
+ throw new Error("Invalid URL: must be http or https");
75
+ }
76
+ let dispatcher = null;
77
+ try {
78
+ const pinned = Boolean(params.policy?.allowPrivateNetwork || params.policy?.allowedHostnames?.length) ? await resolvePinnedHostnameWithPolicy(parsedUrl.hostname, {
79
+ lookupFn: params.lookupFn,
80
+ policy: params.policy
81
+ }) : await resolvePinnedHostname(parsedUrl.hostname, params.lookupFn);
82
+ if (params.pinDns !== false) dispatcher = createPinnedDispatcher(pinned);
83
+ const init = {
84
+ ...params.init ? { ...params.init } : {},
85
+ redirect: "manual",
86
+ ...dispatcher ? { dispatcher } : {},
87
+ ...signal ? { signal } : {}
88
+ };
89
+ const response = await fetcher(parsedUrl.toString(), init);
90
+ if (isRedirectStatus(response.status)) {
91
+ const location = response.headers.get("location");
92
+ if (!location) {
93
+ await release(dispatcher);
94
+ throw new Error(`Redirect missing location header (${response.status})`);
95
+ }
96
+ redirectCount += 1;
97
+ if (redirectCount > maxRedirects) {
98
+ await release(dispatcher);
99
+ throw new Error(`Too many redirects (limit: ${maxRedirects})`);
100
+ }
101
+ const nextUrl = new URL(location, parsedUrl).toString();
102
+ if (visited.has(nextUrl)) {
103
+ await release(dispatcher);
104
+ throw new Error("Redirect loop detected");
105
+ }
106
+ visited.add(nextUrl);
107
+ response.body?.cancel();
108
+ await closeDispatcher(dispatcher);
109
+ currentUrl = nextUrl;
110
+ continue;
111
+ }
112
+ return {
113
+ response,
114
+ finalUrl: currentUrl,
115
+ release: async () => release(dispatcher)
116
+ };
117
+ } catch (err) {
118
+ await release(dispatcher);
119
+ throw err;
120
+ }
121
+ }
122
+ }
123
+
124
+ //#endregion
125
+ //#region src/media/fetch.ts
126
+ var MediaFetchError = class extends Error {
127
+ constructor(code, message) {
128
+ super(message);
129
+ this.code = code;
130
+ this.name = "MediaFetchError";
131
+ }
132
+ };
133
+ function stripQuotes(value) {
134
+ return value.replace(/^["']|["']$/g, "");
135
+ }
136
+ function parseContentDispositionFileName(header) {
137
+ if (!header) return;
138
+ const starMatch = /filename\*\s*=\s*([^;]+)/i.exec(header);
139
+ if (starMatch?.[1]) {
140
+ const cleaned = stripQuotes(starMatch[1].trim());
141
+ const encoded = cleaned.split("''").slice(1).join("''") || cleaned;
142
+ try {
143
+ return path.basename(decodeURIComponent(encoded));
144
+ } catch {
145
+ return path.basename(encoded);
146
+ }
147
+ }
148
+ const match = /filename\s*=\s*([^;]+)/i.exec(header);
149
+ if (match?.[1]) return path.basename(stripQuotes(match[1].trim()));
150
+ }
151
+ async function readErrorBodySnippet(res, maxChars = 200) {
152
+ try {
153
+ const text = await res.text();
154
+ if (!text) return;
155
+ const collapsed = text.replace(/\s+/g, " ").trim();
156
+ if (!collapsed) return;
157
+ if (collapsed.length <= maxChars) return collapsed;
158
+ return `${collapsed.slice(0, maxChars)}…`;
159
+ } catch {
160
+ return;
161
+ }
162
+ }
163
+ async function fetchRemoteMedia(options) {
164
+ const { url, fetchImpl, filePathHint, maxBytes, maxRedirects, ssrfPolicy, lookupFn } = options;
165
+ let res;
166
+ let finalUrl = url;
167
+ let release = null;
168
+ try {
169
+ const result = await fetchWithSsrFGuard({
170
+ url,
171
+ fetchImpl,
172
+ maxRedirects,
173
+ policy: ssrfPolicy,
174
+ lookupFn
175
+ });
176
+ res = result.response;
177
+ finalUrl = result.finalUrl;
178
+ release = result.release;
179
+ } catch (err) {
180
+ throw new MediaFetchError("fetch_failed", `Failed to fetch media from ${url}: ${String(err)}`);
181
+ }
182
+ try {
183
+ if (!res.ok) {
184
+ const statusText = res.statusText ? ` ${res.statusText}` : "";
185
+ const redirected = finalUrl !== url ? ` (redirected to ${finalUrl})` : "";
186
+ let detail = `HTTP ${res.status}${statusText}`;
187
+ if (!res.body) detail = `HTTP ${res.status}${statusText}; empty response body`;
188
+ else {
189
+ const snippet = await readErrorBodySnippet(res);
190
+ if (snippet) detail += `; body: ${snippet}`;
191
+ }
192
+ throw new MediaFetchError("http_error", `Failed to fetch media from ${url}${redirected}: ${detail}`);
193
+ }
194
+ const contentLength = res.headers.get("content-length");
195
+ if (maxBytes && contentLength) {
196
+ const length = Number(contentLength);
197
+ if (Number.isFinite(length) && length > maxBytes) throw new MediaFetchError("max_bytes", `Failed to fetch media from ${url}: content length ${length} exceeds maxBytes ${maxBytes}`);
198
+ }
199
+ const buffer = maxBytes ? await readResponseWithLimit(res, maxBytes) : Buffer.from(await res.arrayBuffer());
200
+ let fileNameFromUrl;
201
+ try {
202
+ const parsed = new URL(finalUrl);
203
+ fileNameFromUrl = path.basename(parsed.pathname) || void 0;
204
+ } catch {}
205
+ const headerFileName = parseContentDispositionFileName(res.headers.get("content-disposition"));
206
+ let fileName = headerFileName || fileNameFromUrl || (filePathHint ? path.basename(filePathHint) : void 0);
207
+ const filePathForMime = headerFileName && path.extname(headerFileName) ? headerFileName : filePathHint ?? finalUrl;
208
+ const contentType = await detectMime({
209
+ buffer,
210
+ headerMime: res.headers.get("content-type"),
211
+ filePath: filePathForMime
212
+ });
213
+ if (fileName && !path.extname(fileName) && contentType) {
214
+ const ext = extensionForMime(contentType);
215
+ if (ext) fileName = `${fileName}${ext}`;
216
+ }
217
+ return {
218
+ buffer,
219
+ contentType: contentType ?? void 0,
220
+ fileName
221
+ };
222
+ } finally {
223
+ if (release) await release();
224
+ }
225
+ }
226
+ async function readResponseWithLimit(res, maxBytes) {
227
+ const body = res.body;
228
+ if (!body || typeof body.getReader !== "function") {
229
+ const fallback = Buffer.from(await res.arrayBuffer());
230
+ if (fallback.length > maxBytes) throw new MediaFetchError("max_bytes", `Failed to fetch media from ${res.url || "response"}: payload exceeds maxBytes ${maxBytes}`);
231
+ return fallback;
232
+ }
233
+ const reader = body.getReader();
234
+ const chunks = [];
235
+ let total = 0;
236
+ try {
237
+ while (true) {
238
+ const { done, value } = await reader.read();
239
+ if (done) break;
240
+ if (value?.length) {
241
+ total += value.length;
242
+ if (total > maxBytes) {
243
+ try {
244
+ await reader.cancel();
245
+ } catch {}
246
+ throw new MediaFetchError("max_bytes", `Failed to fetch media from ${res.url || "response"}: payload exceeds maxBytes ${maxBytes}`);
247
+ }
248
+ chunks.push(value);
249
+ }
250
+ }
251
+ } finally {
252
+ try {
253
+ reader.releaseLock();
254
+ } catch {}
255
+ }
256
+ return Buffer.concat(chunks.map((chunk) => Buffer.from(chunk)), total);
257
+ }
258
+
259
+ //#endregion
260
+ //#region src/auto-reply/tokens.ts
261
+ const HEARTBEAT_TOKEN = "HEARTBEAT_OK";
262
+ const SILENT_REPLY_TOKEN = "NO_REPLY";
263
+ function escapeRegExp(value) {
264
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
265
+ }
266
+ function isSilentReplyText(text, token = SILENT_REPLY_TOKEN) {
267
+ if (!text) return false;
268
+ const escaped = escapeRegExp(token);
269
+ if (new RegExp(`^\\s*${escaped}(?=$|\\W)`).test(text)) return true;
270
+ return new RegExp(`\\b${escaped}\\b\\W*$`).test(text);
271
+ }
272
+
273
+ //#endregion
274
+ //#region src/markdown/fences.ts
275
+ function parseFenceSpans(buffer) {
276
+ const spans = [];
277
+ let open;
278
+ let offset = 0;
279
+ while (offset <= buffer.length) {
280
+ const nextNewline = buffer.indexOf("\n", offset);
281
+ const lineEnd = nextNewline === -1 ? buffer.length : nextNewline;
282
+ const line = buffer.slice(offset, lineEnd);
283
+ const match = line.match(/^( {0,3})(`{3,}|~{3,})(.*)$/);
284
+ if (match) {
285
+ const indent = match[1];
286
+ const marker = match[2];
287
+ const markerChar = marker[0];
288
+ const markerLen = marker.length;
289
+ if (!open) open = {
290
+ start: offset,
291
+ markerChar,
292
+ markerLen,
293
+ openLine: line,
294
+ marker,
295
+ indent
296
+ };
297
+ else if (open.markerChar === markerChar && markerLen >= open.markerLen) {
298
+ const end = lineEnd;
299
+ spans.push({
300
+ start: open.start,
301
+ end,
302
+ openLine: open.openLine,
303
+ marker: open.marker,
304
+ indent: open.indent
305
+ });
306
+ open = void 0;
307
+ }
308
+ }
309
+ if (nextNewline === -1) break;
310
+ offset = nextNewline + 1;
311
+ }
312
+ if (open) spans.push({
313
+ start: open.start,
314
+ end: buffer.length,
315
+ openLine: open.openLine,
316
+ marker: open.marker,
317
+ indent: open.indent
318
+ });
319
+ return spans;
320
+ }
321
+ function findFenceSpanAt(spans, index) {
322
+ return spans.find((span) => index > span.start && index < span.end);
323
+ }
324
+ function isSafeFenceBreak(spans, index) {
325
+ return !findFenceSpanAt(spans, index);
326
+ }
327
+
328
+ //#endregion
329
+ //#region src/auto-reply/chunk.ts
330
+ const DEFAULT_CHUNK_LIMIT = 4e3;
331
+ const DEFAULT_CHUNK_MODE = "length";
332
+ function resolveChunkLimitForProvider(cfgSection, accountId) {
333
+ if (!cfgSection) return;
334
+ const normalizedAccountId = normalizeAccountId$1(accountId);
335
+ const accounts = cfgSection.accounts;
336
+ if (accounts && typeof accounts === "object") {
337
+ const direct = accounts[normalizedAccountId];
338
+ if (typeof direct?.textChunkLimit === "number") return direct.textChunkLimit;
339
+ const matchKey = Object.keys(accounts).find((key) => key.toLowerCase() === normalizedAccountId.toLowerCase());
340
+ const match = matchKey ? accounts[matchKey] : void 0;
341
+ if (typeof match?.textChunkLimit === "number") return match.textChunkLimit;
342
+ }
343
+ return cfgSection.textChunkLimit;
344
+ }
345
+ function resolveTextChunkLimit(cfg, provider, accountId, opts) {
346
+ const fallback = typeof opts?.fallbackLimit === "number" && opts.fallbackLimit > 0 ? opts.fallbackLimit : DEFAULT_CHUNK_LIMIT;
347
+ const providerOverride = (() => {
348
+ if (!provider || provider === INTERNAL_MESSAGE_CHANNEL) return;
349
+ return resolveChunkLimitForProvider((cfg?.channels)?.[provider] ?? cfg?.[provider], accountId);
350
+ })();
351
+ if (typeof providerOverride === "number" && providerOverride > 0) return providerOverride;
352
+ return fallback;
353
+ }
354
+ function resolveChunkModeForProvider(cfgSection, accountId) {
355
+ if (!cfgSection) return;
356
+ const normalizedAccountId = normalizeAccountId$1(accountId);
357
+ const accounts = cfgSection.accounts;
358
+ if (accounts && typeof accounts === "object") {
359
+ const direct = accounts[normalizedAccountId];
360
+ if (direct?.chunkMode) return direct.chunkMode;
361
+ const matchKey = Object.keys(accounts).find((key) => key.toLowerCase() === normalizedAccountId.toLowerCase());
362
+ const match = matchKey ? accounts[matchKey] : void 0;
363
+ if (match?.chunkMode) return match.chunkMode;
364
+ }
365
+ return cfgSection.chunkMode;
366
+ }
367
+ function resolveChunkMode(cfg, provider, accountId) {
368
+ if (!provider || provider === INTERNAL_MESSAGE_CHANNEL) return DEFAULT_CHUNK_MODE;
369
+ return resolveChunkModeForProvider((cfg?.channels)?.[provider] ?? cfg?.[provider], accountId) ?? DEFAULT_CHUNK_MODE;
370
+ }
371
+ /**
372
+ * Split text on newlines, trimming line whitespace.
373
+ * Blank lines are folded into the next non-empty line as leading "\n" prefixes.
374
+ * Long lines can be split by length (default) or kept intact via splitLongLines:false.
375
+ */
376
+ function chunkByNewline(text, maxLineLength, opts) {
377
+ if (!text) return [];
378
+ if (maxLineLength <= 0) return text.trim() ? [text] : [];
379
+ const splitLongLines = opts?.splitLongLines !== false;
380
+ const trimLines = opts?.trimLines !== false;
381
+ const lines = splitByNewline(text, opts?.isSafeBreak);
382
+ const chunks = [];
383
+ let pendingBlankLines = 0;
384
+ for (const line of lines) {
385
+ const trimmed = line.trim();
386
+ if (!trimmed) {
387
+ pendingBlankLines += 1;
388
+ continue;
389
+ }
390
+ const maxPrefix = Math.max(0, maxLineLength - 1);
391
+ const cappedBlankLines = pendingBlankLines > 0 ? Math.min(pendingBlankLines, maxPrefix) : 0;
392
+ const prefix = cappedBlankLines > 0 ? "\n".repeat(cappedBlankLines) : "";
393
+ pendingBlankLines = 0;
394
+ const lineValue = trimLines ? trimmed : line;
395
+ if (!splitLongLines || lineValue.length + prefix.length <= maxLineLength) {
396
+ chunks.push(prefix + lineValue);
397
+ continue;
398
+ }
399
+ const firstLimit = Math.max(1, maxLineLength - prefix.length);
400
+ const first = lineValue.slice(0, firstLimit);
401
+ chunks.push(prefix + first);
402
+ const remaining = lineValue.slice(firstLimit);
403
+ if (remaining) chunks.push(...chunkText(remaining, maxLineLength));
404
+ }
405
+ if (pendingBlankLines > 0 && chunks.length > 0) chunks[chunks.length - 1] += "\n".repeat(pendingBlankLines);
406
+ return chunks;
407
+ }
408
+ /**
409
+ * Split text into chunks on paragraph boundaries (blank lines), preserving lists and
410
+ * single-newline line wraps inside paragraphs.
411
+ *
412
+ * - Only breaks at paragraph separators ("\n\n" or more, allowing whitespace on blank lines)
413
+ * - Packs multiple paragraphs into a single chunk up to `limit`
414
+ * - Falls back to length-based splitting when a single paragraph exceeds `limit`
415
+ * (unless `splitLongParagraphs` is disabled)
416
+ */
417
+ function chunkByParagraph(text, limit, opts) {
418
+ if (!text) return [];
419
+ if (limit <= 0) return [text];
420
+ const splitLongParagraphs = opts?.splitLongParagraphs !== false;
421
+ const normalized = text.replace(/\r\n?/g, "\n");
422
+ if (!/\n[\t ]*\n+/.test(normalized)) {
423
+ if (normalized.length <= limit) return [normalized];
424
+ if (!splitLongParagraphs) return [normalized];
425
+ return chunkText(normalized, limit);
426
+ }
427
+ const spans = parseFenceSpans(normalized);
428
+ const parts = [];
429
+ const re = /\n[\t ]*\n+/g;
430
+ let lastIndex = 0;
431
+ for (const match of normalized.matchAll(re)) {
432
+ const idx = match.index ?? 0;
433
+ if (!isSafeFenceBreak(spans, idx)) continue;
434
+ parts.push(normalized.slice(lastIndex, idx));
435
+ lastIndex = idx + match[0].length;
436
+ }
437
+ parts.push(normalized.slice(lastIndex));
438
+ const chunks = [];
439
+ for (const part of parts) {
440
+ const paragraph = part.replace(/\s+$/g, "");
441
+ if (!paragraph.trim()) continue;
442
+ if (paragraph.length <= limit) chunks.push(paragraph);
443
+ else if (!splitLongParagraphs) chunks.push(paragraph);
444
+ else chunks.push(...chunkText(paragraph, limit));
445
+ }
446
+ return chunks;
447
+ }
448
+ /**
449
+ * Unified chunking function that dispatches based on mode.
450
+ */
451
+ function chunkTextWithMode(text, limit, mode) {
452
+ if (mode === "newline") return chunkByParagraph(text, limit);
453
+ return chunkText(text, limit);
454
+ }
455
+ function chunkMarkdownTextWithMode(text, limit, mode) {
456
+ if (mode === "newline") {
457
+ const paragraphChunks = chunkByParagraph(text, limit, { splitLongParagraphs: false });
458
+ const out = [];
459
+ for (const chunk of paragraphChunks) {
460
+ const nested = chunkMarkdownText(chunk, limit);
461
+ if (!nested.length && chunk) out.push(chunk);
462
+ else out.push(...nested);
463
+ }
464
+ return out;
465
+ }
466
+ return chunkMarkdownText(text, limit);
467
+ }
468
+ function splitByNewline(text, isSafeBreak = () => true) {
469
+ const lines = [];
470
+ let start = 0;
471
+ for (let i = 0; i < text.length; i++) if (text[i] === "\n" && isSafeBreak(i)) {
472
+ lines.push(text.slice(start, i));
473
+ start = i + 1;
474
+ }
475
+ lines.push(text.slice(start));
476
+ return lines;
477
+ }
478
+ function chunkText(text, limit) {
479
+ if (!text) return [];
480
+ if (limit <= 0) return [text];
481
+ if (text.length <= limit) return [text];
482
+ const chunks = [];
483
+ let remaining = text;
484
+ while (remaining.length > limit) {
485
+ const { lastNewline, lastWhitespace } = scanParenAwareBreakpoints(remaining.slice(0, limit));
486
+ let breakIdx = lastNewline > 0 ? lastNewline : lastWhitespace;
487
+ if (breakIdx <= 0) breakIdx = limit;
488
+ const chunk = remaining.slice(0, breakIdx).trimEnd();
489
+ if (chunk.length > 0) chunks.push(chunk);
490
+ const brokeOnSeparator = breakIdx < remaining.length && /\s/.test(remaining[breakIdx]);
491
+ const nextStart = Math.min(remaining.length, breakIdx + (brokeOnSeparator ? 1 : 0));
492
+ remaining = remaining.slice(nextStart).trimStart();
493
+ }
494
+ if (remaining.length) chunks.push(remaining);
495
+ return chunks;
496
+ }
497
+ function chunkMarkdownText(text, limit) {
498
+ if (!text) return [];
499
+ if (limit <= 0) return [text];
500
+ if (text.length <= limit) return [text];
501
+ const chunks = [];
502
+ let remaining = text;
503
+ while (remaining.length > limit) {
504
+ const spans = parseFenceSpans(remaining);
505
+ const softBreak = pickSafeBreakIndex(remaining.slice(0, limit), spans);
506
+ let breakIdx = softBreak > 0 ? softBreak : limit;
507
+ const initialFence = isSafeFenceBreak(spans, breakIdx) ? void 0 : findFenceSpanAt(spans, breakIdx);
508
+ let fenceToSplit = initialFence;
509
+ if (initialFence) {
510
+ const closeLine = `${initialFence.indent}${initialFence.marker}`;
511
+ const maxIdxIfNeedNewline = limit - (closeLine.length + 1);
512
+ if (maxIdxIfNeedNewline <= 0) {
513
+ fenceToSplit = void 0;
514
+ breakIdx = limit;
515
+ } else {
516
+ const minProgressIdx = Math.min(remaining.length, initialFence.start + initialFence.openLine.length + 2);
517
+ const maxIdxIfAlreadyNewline = limit - closeLine.length;
518
+ let pickedNewline = false;
519
+ let lastNewline = remaining.lastIndexOf("\n", Math.max(0, maxIdxIfAlreadyNewline - 1));
520
+ while (lastNewline !== -1) {
521
+ const candidateBreak = lastNewline + 1;
522
+ if (candidateBreak < minProgressIdx) break;
523
+ const candidateFence = findFenceSpanAt(spans, candidateBreak);
524
+ if (candidateFence && candidateFence.start === initialFence.start) {
525
+ breakIdx = Math.max(1, candidateBreak);
526
+ pickedNewline = true;
527
+ break;
528
+ }
529
+ lastNewline = remaining.lastIndexOf("\n", lastNewline - 1);
530
+ }
531
+ if (!pickedNewline) if (minProgressIdx > maxIdxIfAlreadyNewline) {
532
+ fenceToSplit = void 0;
533
+ breakIdx = limit;
534
+ } else breakIdx = Math.max(minProgressIdx, maxIdxIfNeedNewline);
535
+ }
536
+ const fenceAtBreak = findFenceSpanAt(spans, breakIdx);
537
+ fenceToSplit = fenceAtBreak && fenceAtBreak.start === initialFence.start ? fenceAtBreak : void 0;
538
+ }
539
+ let rawChunk = remaining.slice(0, breakIdx);
540
+ if (!rawChunk) break;
541
+ const brokeOnSeparator = breakIdx < remaining.length && /\s/.test(remaining[breakIdx]);
542
+ const nextStart = Math.min(remaining.length, breakIdx + (brokeOnSeparator ? 1 : 0));
543
+ let next = remaining.slice(nextStart);
544
+ if (fenceToSplit) {
545
+ const closeLine = `${fenceToSplit.indent}${fenceToSplit.marker}`;
546
+ rawChunk = rawChunk.endsWith("\n") ? `${rawChunk}${closeLine}` : `${rawChunk}\n${closeLine}`;
547
+ next = `${fenceToSplit.openLine}\n${next}`;
548
+ } else next = stripLeadingNewlines(next);
549
+ chunks.push(rawChunk);
550
+ remaining = next;
551
+ }
552
+ if (remaining.length) chunks.push(remaining);
553
+ return chunks;
554
+ }
555
+ function stripLeadingNewlines(value) {
556
+ let i = 0;
557
+ while (i < value.length && value[i] === "\n") i++;
558
+ return i > 0 ? value.slice(i) : value;
559
+ }
560
+ function pickSafeBreakIndex(window, spans) {
561
+ const { lastNewline, lastWhitespace } = scanParenAwareBreakpoints(window, (index) => isSafeFenceBreak(spans, index));
562
+ if (lastNewline > 0) return lastNewline;
563
+ if (lastWhitespace > 0) return lastWhitespace;
564
+ return -1;
565
+ }
566
+ function scanParenAwareBreakpoints(window, isAllowed = () => true) {
567
+ let lastNewline = -1;
568
+ let lastWhitespace = -1;
569
+ let depth = 0;
570
+ for (let i = 0; i < window.length; i++) {
571
+ if (!isAllowed(i)) continue;
572
+ const char = window[i];
573
+ if (char === "(") {
574
+ depth += 1;
575
+ continue;
576
+ }
577
+ if (char === ")" && depth > 0) {
578
+ depth -= 1;
579
+ continue;
580
+ }
581
+ if (depth !== 0) continue;
582
+ if (char === "\n") lastNewline = i;
583
+ else if (/\s/.test(char)) lastWhitespace = i;
584
+ }
585
+ return {
586
+ lastNewline,
587
+ lastWhitespace
588
+ };
589
+ }
590
+
591
+ //#endregion
592
+ //#region src/config/markdown-tables.ts
593
+ const DEFAULT_TABLE_MODES = new Map([["signal", "bullets"], ["whatsapp", "bullets"]]);
594
+ const isMarkdownTableMode = (value) => value === "off" || value === "bullets" || value === "code";
595
+ function resolveMarkdownModeFromSection(section, accountId) {
596
+ if (!section) return;
597
+ const normalizedAccountId = normalizeAccountId$1(accountId);
598
+ const accounts = section.accounts;
599
+ if (accounts && typeof accounts === "object") {
600
+ const directMode = accounts[normalizedAccountId]?.markdown?.tables;
601
+ if (isMarkdownTableMode(directMode)) return directMode;
602
+ const matchKey = Object.keys(accounts).find((key) => key.toLowerCase() === normalizedAccountId.toLowerCase());
603
+ const matchMode = (matchKey ? accounts[matchKey] : void 0)?.markdown?.tables;
604
+ if (isMarkdownTableMode(matchMode)) return matchMode;
605
+ }
606
+ const sectionMode = section.markdown?.tables;
607
+ return isMarkdownTableMode(sectionMode) ? sectionMode : void 0;
608
+ }
609
+ function resolveMarkdownTableMode(params) {
610
+ const channel = normalizeChannelId(params.channel);
611
+ const defaultMode = channel ? DEFAULT_TABLE_MODES.get(channel) ?? "code" : "code";
612
+ if (!channel || !params.cfg) return defaultMode;
613
+ return resolveMarkdownModeFromSection(params.cfg.channels?.[channel] ?? params.cfg?.[channel], params.accountId) ?? defaultMode;
614
+ }
615
+
616
+ //#endregion
617
+ //#region src/web/media.ts
618
+ const HEIC_MIME_RE = /^image\/hei[cf]$/i;
619
+ const HEIC_EXT_RE = /\.(heic|heif)$/i;
620
+ const MB$1 = 1024 * 1024;
621
+ function formatMb(bytes, digits = 2) {
622
+ return (bytes / MB$1).toFixed(digits);
623
+ }
624
+ function formatCapLimit(label, cap, size) {
625
+ return `${label} exceeds ${formatMb(cap, 0)}MB limit (got ${formatMb(size)}MB)`;
626
+ }
627
+ function formatCapReduce(label, cap, size) {
628
+ return `${label} could not be reduced below ${formatMb(cap, 0)}MB (got ${formatMb(size)}MB)`;
629
+ }
630
+ function isHeicSource(opts) {
631
+ if (opts.contentType && HEIC_MIME_RE.test(opts.contentType.trim())) return true;
632
+ if (opts.fileName && HEIC_EXT_RE.test(opts.fileName.trim())) return true;
633
+ return false;
634
+ }
635
+ function toJpegFileName(fileName) {
636
+ if (!fileName) return;
637
+ const trimmed = fileName.trim();
638
+ if (!trimmed) return fileName;
639
+ const parsed = path.parse(trimmed);
640
+ if (!parsed.ext || HEIC_EXT_RE.test(parsed.ext)) return path.format({
641
+ dir: parsed.dir,
642
+ name: parsed.name || trimmed,
643
+ ext: ".jpg"
644
+ });
645
+ return path.format({
646
+ dir: parsed.dir,
647
+ name: parsed.name,
648
+ ext: ".jpg"
649
+ });
650
+ }
651
+ function logOptimizedImage(params) {
652
+ if (!shouldLogVerbose()) return;
653
+ if (params.optimized.optimizedSize >= params.originalSize) return;
654
+ if (params.optimized.format === "png") {
655
+ logVerbose(`Optimized PNG (preserving alpha) from ${formatMb(params.originalSize)}MB to ${formatMb(params.optimized.optimizedSize)}MB (side≤${params.optimized.resizeSide}px)`);
656
+ return;
657
+ }
658
+ logVerbose(`Optimized media from ${formatMb(params.originalSize)}MB to ${formatMb(params.optimized.optimizedSize)}MB (side≤${params.optimized.resizeSide}px, q=${params.optimized.quality})`);
659
+ }
660
+ async function optimizeImageWithFallback(params) {
661
+ const { buffer, cap, meta } = params;
662
+ if ((meta?.contentType === "image/png" || meta?.fileName?.toLowerCase().endsWith(".png")) && await hasAlphaChannel(buffer)) {
663
+ const optimized = await optimizeImageToPng(buffer, cap);
664
+ if (optimized.buffer.length <= cap) return {
665
+ ...optimized,
666
+ format: "png"
667
+ };
668
+ if (shouldLogVerbose()) logVerbose(`PNG with alpha still exceeds ${formatMb(cap, 0)}MB after optimization; falling back to JPEG`);
669
+ }
670
+ return {
671
+ ...await optimizeImageToJpeg(buffer, cap, meta),
672
+ format: "jpeg"
673
+ };
674
+ }
675
+ async function loadWebMediaInternal(mediaUrl, options = {}) {
676
+ const { maxBytes, optimizeImages = true, ssrfPolicy } = options;
677
+ if (mediaUrl.startsWith("file://")) try {
678
+ mediaUrl = fileURLToPath(mediaUrl);
679
+ } catch {
680
+ throw new Error(`Invalid file:// URL: ${mediaUrl}`);
681
+ }
682
+ const optimizeAndClampImage = async (buffer, cap, meta) => {
683
+ const originalSize = buffer.length;
684
+ const optimized = await optimizeImageWithFallback({
685
+ buffer,
686
+ cap,
687
+ meta
688
+ });
689
+ logOptimizedImage({
690
+ originalSize,
691
+ optimized
692
+ });
693
+ if (optimized.buffer.length > cap) throw new Error(formatCapReduce("Media", cap, optimized.buffer.length));
694
+ const contentType = optimized.format === "png" ? "image/png" : "image/jpeg";
695
+ const fileName = optimized.format === "jpeg" && meta && isHeicSource(meta) ? toJpegFileName(meta.fileName) : meta?.fileName;
696
+ return {
697
+ buffer: optimized.buffer,
698
+ contentType,
699
+ kind: "image",
700
+ fileName
701
+ };
702
+ };
703
+ const clampAndFinalize = async (params) => {
704
+ const cap = maxBytes !== void 0 ? maxBytes : maxBytesForKind(params.kind);
705
+ if (params.kind === "image") {
706
+ const isGif = params.contentType === "image/gif";
707
+ if (isGif || !optimizeImages) {
708
+ if (params.buffer.length > cap) throw new Error(formatCapLimit(isGif ? "GIF" : "Media", cap, params.buffer.length));
709
+ return {
710
+ buffer: params.buffer,
711
+ contentType: params.contentType,
712
+ kind: params.kind,
713
+ fileName: params.fileName
714
+ };
715
+ }
716
+ return { ...await optimizeAndClampImage(params.buffer, cap, {
717
+ contentType: params.contentType,
718
+ fileName: params.fileName
719
+ }) };
720
+ }
721
+ if (params.buffer.length > cap) throw new Error(formatCapLimit("Media", cap, params.buffer.length));
722
+ return {
723
+ buffer: params.buffer,
724
+ contentType: params.contentType ?? void 0,
725
+ kind: params.kind,
726
+ fileName: params.fileName
727
+ };
728
+ };
729
+ if (/^https?:\/\//i.test(mediaUrl)) {
730
+ const defaultFetchCap = maxBytesForKind("unknown");
731
+ const { buffer, contentType, fileName } = await fetchRemoteMedia({
732
+ url: mediaUrl,
733
+ maxBytes: maxBytes === void 0 ? defaultFetchCap : optimizeImages ? Math.max(maxBytes, defaultFetchCap) : maxBytes,
734
+ ssrfPolicy
735
+ });
736
+ return await clampAndFinalize({
737
+ buffer,
738
+ contentType,
739
+ kind: mediaKindFromMime(contentType),
740
+ fileName
741
+ });
742
+ }
743
+ if (mediaUrl.startsWith("~")) mediaUrl = resolveUserPath(mediaUrl);
744
+ const data = await fs.readFile(mediaUrl);
745
+ const mime = await detectMime({
746
+ buffer: data,
747
+ filePath: mediaUrl
748
+ });
749
+ const kind = mediaKindFromMime(mime);
750
+ let fileName = path.basename(mediaUrl) || void 0;
751
+ if (fileName && !path.extname(fileName) && mime) {
752
+ const ext = extensionForMime(mime);
753
+ if (ext) fileName = `${fileName}${ext}`;
754
+ }
755
+ return await clampAndFinalize({
756
+ buffer: data,
757
+ contentType: mime,
758
+ kind,
759
+ fileName
760
+ });
761
+ }
762
+ async function loadWebMedia(mediaUrl, maxBytes, options) {
763
+ return await loadWebMediaInternal(mediaUrl, {
764
+ maxBytes,
765
+ optimizeImages: true,
766
+ ssrfPolicy: options?.ssrfPolicy
767
+ });
768
+ }
769
+ async function loadWebMediaRaw(mediaUrl, maxBytes, options) {
770
+ return await loadWebMediaInternal(mediaUrl, {
771
+ maxBytes,
772
+ optimizeImages: false,
773
+ ssrfPolicy: options?.ssrfPolicy
774
+ });
775
+ }
776
+ async function optimizeImageToJpeg(buffer, maxBytes, opts = {}) {
777
+ let source = buffer;
778
+ if (isHeicSource(opts)) try {
779
+ source = await convertHeicToJpeg(buffer);
780
+ } catch (err) {
781
+ throw new Error(`HEIC image conversion failed: ${String(err)}`, { cause: err });
782
+ }
783
+ const sides = [
784
+ 2048,
785
+ 1536,
786
+ 1280,
787
+ 1024,
788
+ 800
789
+ ];
790
+ const qualities = [
791
+ 80,
792
+ 70,
793
+ 60,
794
+ 50,
795
+ 40
796
+ ];
797
+ let smallest = null;
798
+ for (const side of sides) for (const quality of qualities) try {
799
+ const out = await resizeToJpeg({
800
+ buffer: source,
801
+ maxSide: side,
802
+ quality,
803
+ withoutEnlargement: true
804
+ });
805
+ const size = out.length;
806
+ if (!smallest || size < smallest.size) smallest = {
807
+ buffer: out,
808
+ size,
809
+ resizeSide: side,
810
+ quality
811
+ };
812
+ if (size <= maxBytes) return {
813
+ buffer: out,
814
+ optimizedSize: size,
815
+ resizeSide: side,
816
+ quality
817
+ };
818
+ } catch {}
819
+ if (smallest) return {
820
+ buffer: smallest.buffer,
821
+ optimizedSize: smallest.size,
822
+ resizeSide: smallest.resizeSide,
823
+ quality: smallest.quality
824
+ };
825
+ throw new Error("Failed to optimize image");
826
+ }
827
+
828
+ //#endregion
829
+ //#region src/markdown/ir.ts
830
+ function createMarkdownIt(options) {
831
+ const md = new MarkdownIt({
832
+ html: false,
833
+ linkify: options.linkify ?? true,
834
+ breaks: false,
835
+ typographer: false
836
+ });
837
+ md.enable("strikethrough");
838
+ if (options.tableMode && options.tableMode !== "off") md.enable("table");
839
+ else md.disable("table");
840
+ if (options.autolink === false) md.disable("autolink");
841
+ return md;
842
+ }
843
+ function getAttr(token, name) {
844
+ if (token.attrGet) return token.attrGet(name);
845
+ if (token.attrs) {
846
+ for (const [key, value] of token.attrs) if (key === name) return value;
847
+ }
848
+ return null;
849
+ }
850
+ function createTextToken(base, content) {
851
+ return {
852
+ ...base,
853
+ type: "text",
854
+ content,
855
+ children: void 0
856
+ };
857
+ }
858
+ function applySpoilerTokens(tokens) {
859
+ for (const token of tokens) if (token.children && token.children.length > 0) token.children = injectSpoilersIntoInline(token.children);
860
+ }
861
+ function injectSpoilersIntoInline(tokens) {
862
+ const result = [];
863
+ const state = { spoilerOpen: false };
864
+ for (const token of tokens) {
865
+ if (token.type !== "text") {
866
+ result.push(token);
867
+ continue;
868
+ }
869
+ const content = token.content ?? "";
870
+ if (!content.includes("||")) {
871
+ result.push(token);
872
+ continue;
873
+ }
874
+ let index = 0;
875
+ while (index < content.length) {
876
+ const next = content.indexOf("||", index);
877
+ if (next === -1) {
878
+ if (index < content.length) result.push(createTextToken(token, content.slice(index)));
879
+ break;
880
+ }
881
+ if (next > index) result.push(createTextToken(token, content.slice(index, next)));
882
+ state.spoilerOpen = !state.spoilerOpen;
883
+ result.push({ type: state.spoilerOpen ? "spoiler_open" : "spoiler_close" });
884
+ index = next + 2;
885
+ }
886
+ }
887
+ return result;
888
+ }
889
+ function initRenderTarget() {
890
+ return {
891
+ text: "",
892
+ styles: [],
893
+ openStyles: [],
894
+ links: [],
895
+ linkStack: []
896
+ };
897
+ }
898
+ function resolveRenderTarget(state) {
899
+ return state.table?.currentCell ?? state;
900
+ }
901
+ function appendText(state, value) {
902
+ if (!value) return;
903
+ const target = resolveRenderTarget(state);
904
+ target.text += value;
905
+ }
906
+ function openStyle(state, style) {
907
+ const target = resolveRenderTarget(state);
908
+ target.openStyles.push({
909
+ style,
910
+ start: target.text.length
911
+ });
912
+ }
913
+ function closeStyle(state, style) {
914
+ const target = resolveRenderTarget(state);
915
+ for (let i = target.openStyles.length - 1; i >= 0; i -= 1) if (target.openStyles[i]?.style === style) {
916
+ const start = target.openStyles[i].start;
917
+ target.openStyles.splice(i, 1);
918
+ const end = target.text.length;
919
+ if (end > start) target.styles.push({
920
+ start,
921
+ end,
922
+ style
923
+ });
924
+ return;
925
+ }
926
+ }
927
+ function appendParagraphSeparator(state) {
928
+ if (state.env.listStack.length > 0) return;
929
+ if (state.table) return;
930
+ state.text += "\n\n";
931
+ }
932
+ function appendListPrefix(state) {
933
+ const stack = state.env.listStack;
934
+ const top = stack[stack.length - 1];
935
+ if (!top) return;
936
+ top.index += 1;
937
+ const indent = " ".repeat(Math.max(0, stack.length - 1));
938
+ const prefix = top.type === "ordered" ? `${top.index}. ` : "• ";
939
+ state.text += `${indent}${prefix}`;
940
+ }
941
+ function renderInlineCode(state, content) {
942
+ if (!content) return;
943
+ const target = resolveRenderTarget(state);
944
+ const start = target.text.length;
945
+ target.text += content;
946
+ target.styles.push({
947
+ start,
948
+ end: start + content.length,
949
+ style: "code"
950
+ });
951
+ }
952
+ function renderCodeBlock(state, content) {
953
+ let code = content ?? "";
954
+ if (!code.endsWith("\n")) code = `${code}\n`;
955
+ const target = resolveRenderTarget(state);
956
+ const start = target.text.length;
957
+ target.text += code;
958
+ target.styles.push({
959
+ start,
960
+ end: start + code.length,
961
+ style: "code_block"
962
+ });
963
+ if (state.env.listStack.length === 0) target.text += "\n";
964
+ }
965
+ function handleLinkClose(state) {
966
+ const target = resolveRenderTarget(state);
967
+ const link = target.linkStack.pop();
968
+ if (!link?.href) return;
969
+ const href = link.href.trim();
970
+ if (!href) return;
971
+ const start = link.labelStart;
972
+ const end = target.text.length;
973
+ if (end <= start) {
974
+ target.links.push({
975
+ start,
976
+ end,
977
+ href
978
+ });
979
+ return;
980
+ }
981
+ target.links.push({
982
+ start,
983
+ end,
984
+ href
985
+ });
986
+ }
987
+ function initTableState() {
988
+ return {
989
+ headers: [],
990
+ rows: [],
991
+ currentRow: [],
992
+ currentCell: null,
993
+ inHeader: false
994
+ };
995
+ }
996
+ function finishTableCell(cell) {
997
+ closeRemainingStyles(cell);
998
+ return {
999
+ text: cell.text,
1000
+ styles: cell.styles,
1001
+ links: cell.links
1002
+ };
1003
+ }
1004
+ function trimCell(cell) {
1005
+ const text = cell.text;
1006
+ let start = 0;
1007
+ let end = text.length;
1008
+ while (start < end && /\s/.test(text[start] ?? "")) start += 1;
1009
+ while (end > start && /\s/.test(text[end - 1] ?? "")) end -= 1;
1010
+ if (start === 0 && end === text.length) return cell;
1011
+ const trimmedText = text.slice(start, end);
1012
+ const trimmedLength = trimmedText.length;
1013
+ const trimmedStyles = [];
1014
+ for (const span of cell.styles) {
1015
+ const sliceStart = Math.max(0, span.start - start);
1016
+ const sliceEnd = Math.min(trimmedLength, span.end - start);
1017
+ if (sliceEnd > sliceStart) trimmedStyles.push({
1018
+ start: sliceStart,
1019
+ end: sliceEnd,
1020
+ style: span.style
1021
+ });
1022
+ }
1023
+ const trimmedLinks = [];
1024
+ for (const span of cell.links) {
1025
+ const sliceStart = Math.max(0, span.start - start);
1026
+ const sliceEnd = Math.min(trimmedLength, span.end - start);
1027
+ if (sliceEnd > sliceStart) trimmedLinks.push({
1028
+ start: sliceStart,
1029
+ end: sliceEnd,
1030
+ href: span.href
1031
+ });
1032
+ }
1033
+ return {
1034
+ text: trimmedText,
1035
+ styles: trimmedStyles,
1036
+ links: trimmedLinks
1037
+ };
1038
+ }
1039
+ function appendCell(state, cell) {
1040
+ if (!cell.text) return;
1041
+ const start = state.text.length;
1042
+ state.text += cell.text;
1043
+ for (const span of cell.styles) state.styles.push({
1044
+ start: start + span.start,
1045
+ end: start + span.end,
1046
+ style: span.style
1047
+ });
1048
+ for (const link of cell.links) state.links.push({
1049
+ start: start + link.start,
1050
+ end: start + link.end,
1051
+ href: link.href
1052
+ });
1053
+ }
1054
+ function renderTableAsBullets(state) {
1055
+ if (!state.table) return;
1056
+ const headers = state.table.headers.map(trimCell);
1057
+ const rows = state.table.rows.map((row) => row.map(trimCell));
1058
+ if (headers.length === 0 && rows.length === 0) return;
1059
+ if (headers.length > 1 && rows.length > 0) for (const row of rows) {
1060
+ if (row.length === 0) continue;
1061
+ const rowLabel = row[0];
1062
+ if (rowLabel?.text) {
1063
+ const labelStart = state.text.length;
1064
+ appendCell(state, rowLabel);
1065
+ const labelEnd = state.text.length;
1066
+ if (labelEnd > labelStart) state.styles.push({
1067
+ start: labelStart,
1068
+ end: labelEnd,
1069
+ style: "bold"
1070
+ });
1071
+ state.text += "\n";
1072
+ }
1073
+ for (let i = 1; i < row.length; i++) {
1074
+ const header = headers[i];
1075
+ const value = row[i];
1076
+ if (!value?.text) continue;
1077
+ state.text += "• ";
1078
+ if (header?.text) {
1079
+ appendCell(state, header);
1080
+ state.text += ": ";
1081
+ } else state.text += `Column ${i}: `;
1082
+ appendCell(state, value);
1083
+ state.text += "\n";
1084
+ }
1085
+ state.text += "\n";
1086
+ }
1087
+ else for (const row of rows) {
1088
+ for (let i = 0; i < row.length; i++) {
1089
+ const header = headers[i];
1090
+ const value = row[i];
1091
+ if (!value?.text) continue;
1092
+ state.text += "• ";
1093
+ if (header?.text) {
1094
+ appendCell(state, header);
1095
+ state.text += ": ";
1096
+ }
1097
+ appendCell(state, value);
1098
+ state.text += "\n";
1099
+ }
1100
+ state.text += "\n";
1101
+ }
1102
+ }
1103
+ function renderTableAsCode(state) {
1104
+ if (!state.table) return;
1105
+ const headers = state.table.headers.map(trimCell);
1106
+ const rows = state.table.rows.map((row) => row.map(trimCell));
1107
+ const columnCount = Math.max(headers.length, ...rows.map((row) => row.length));
1108
+ if (columnCount === 0) return;
1109
+ const widths = Array.from({ length: columnCount }, () => 0);
1110
+ const updateWidths = (cells) => {
1111
+ for (let i = 0; i < columnCount; i += 1) {
1112
+ const width = cells[i]?.text.length ?? 0;
1113
+ if (widths[i] < width) widths[i] = width;
1114
+ }
1115
+ };
1116
+ updateWidths(headers);
1117
+ for (const row of rows) updateWidths(row);
1118
+ const codeStart = state.text.length;
1119
+ const appendRow = (cells) => {
1120
+ state.text += "|";
1121
+ for (let i = 0; i < columnCount; i += 1) {
1122
+ state.text += " ";
1123
+ const cell = cells[i];
1124
+ if (cell) appendCell(state, cell);
1125
+ const pad = widths[i] - (cell?.text.length ?? 0);
1126
+ if (pad > 0) state.text += " ".repeat(pad);
1127
+ state.text += " |";
1128
+ }
1129
+ state.text += "\n";
1130
+ };
1131
+ const appendDivider = () => {
1132
+ state.text += "|";
1133
+ for (let i = 0; i < columnCount; i += 1) {
1134
+ const dashCount = Math.max(3, widths[i]);
1135
+ state.text += ` ${"-".repeat(dashCount)} |`;
1136
+ }
1137
+ state.text += "\n";
1138
+ };
1139
+ appendRow(headers);
1140
+ appendDivider();
1141
+ for (const row of rows) appendRow(row);
1142
+ const codeEnd = state.text.length;
1143
+ if (codeEnd > codeStart) state.styles.push({
1144
+ start: codeStart,
1145
+ end: codeEnd,
1146
+ style: "code_block"
1147
+ });
1148
+ if (state.env.listStack.length === 0) state.text += "\n";
1149
+ }
1150
+ function renderTokens(tokens, state) {
1151
+ for (const token of tokens) switch (token.type) {
1152
+ case "inline":
1153
+ if (token.children) renderTokens(token.children, state);
1154
+ break;
1155
+ case "text":
1156
+ appendText(state, token.content ?? "");
1157
+ break;
1158
+ case "em_open":
1159
+ openStyle(state, "italic");
1160
+ break;
1161
+ case "em_close":
1162
+ closeStyle(state, "italic");
1163
+ break;
1164
+ case "strong_open":
1165
+ openStyle(state, "bold");
1166
+ break;
1167
+ case "strong_close":
1168
+ closeStyle(state, "bold");
1169
+ break;
1170
+ case "s_open":
1171
+ openStyle(state, "strikethrough");
1172
+ break;
1173
+ case "s_close":
1174
+ closeStyle(state, "strikethrough");
1175
+ break;
1176
+ case "code_inline":
1177
+ renderInlineCode(state, token.content ?? "");
1178
+ break;
1179
+ case "spoiler_open":
1180
+ if (state.enableSpoilers) openStyle(state, "spoiler");
1181
+ break;
1182
+ case "spoiler_close":
1183
+ if (state.enableSpoilers) closeStyle(state, "spoiler");
1184
+ break;
1185
+ case "link_open": {
1186
+ const href = getAttr(token, "href") ?? "";
1187
+ const target = resolveRenderTarget(state);
1188
+ target.linkStack.push({
1189
+ href,
1190
+ labelStart: target.text.length
1191
+ });
1192
+ break;
1193
+ }
1194
+ case "link_close":
1195
+ handleLinkClose(state);
1196
+ break;
1197
+ case "image":
1198
+ appendText(state, token.content ?? "");
1199
+ break;
1200
+ case "softbreak":
1201
+ case "hardbreak":
1202
+ appendText(state, "\n");
1203
+ break;
1204
+ case "paragraph_close":
1205
+ appendParagraphSeparator(state);
1206
+ break;
1207
+ case "heading_open":
1208
+ if (state.headingStyle === "bold") openStyle(state, "bold");
1209
+ break;
1210
+ case "heading_close":
1211
+ if (state.headingStyle === "bold") closeStyle(state, "bold");
1212
+ appendParagraphSeparator(state);
1213
+ break;
1214
+ case "blockquote_open":
1215
+ if (state.blockquotePrefix) state.text += state.blockquotePrefix;
1216
+ break;
1217
+ case "blockquote_close":
1218
+ state.text += "\n";
1219
+ break;
1220
+ case "bullet_list_open":
1221
+ state.env.listStack.push({
1222
+ type: "bullet",
1223
+ index: 0
1224
+ });
1225
+ break;
1226
+ case "bullet_list_close":
1227
+ state.env.listStack.pop();
1228
+ break;
1229
+ case "ordered_list_open": {
1230
+ const start = Number(getAttr(token, "start") ?? "1");
1231
+ state.env.listStack.push({
1232
+ type: "ordered",
1233
+ index: start - 1
1234
+ });
1235
+ break;
1236
+ }
1237
+ case "ordered_list_close":
1238
+ state.env.listStack.pop();
1239
+ break;
1240
+ case "list_item_open":
1241
+ appendListPrefix(state);
1242
+ break;
1243
+ case "list_item_close":
1244
+ state.text += "\n";
1245
+ break;
1246
+ case "code_block":
1247
+ case "fence":
1248
+ renderCodeBlock(state, token.content ?? "");
1249
+ break;
1250
+ case "html_block":
1251
+ case "html_inline":
1252
+ appendText(state, token.content ?? "");
1253
+ break;
1254
+ case "table_open":
1255
+ if (state.tableMode !== "off") {
1256
+ state.table = initTableState();
1257
+ state.hasTables = true;
1258
+ }
1259
+ break;
1260
+ case "table_close":
1261
+ if (state.table) {
1262
+ if (state.tableMode === "bullets") renderTableAsBullets(state);
1263
+ else if (state.tableMode === "code") renderTableAsCode(state);
1264
+ }
1265
+ state.table = null;
1266
+ break;
1267
+ case "thead_open":
1268
+ if (state.table) state.table.inHeader = true;
1269
+ break;
1270
+ case "thead_close":
1271
+ if (state.table) state.table.inHeader = false;
1272
+ break;
1273
+ case "tbody_open":
1274
+ case "tbody_close": break;
1275
+ case "tr_open":
1276
+ if (state.table) state.table.currentRow = [];
1277
+ break;
1278
+ case "tr_close":
1279
+ if (state.table) {
1280
+ if (state.table.inHeader) state.table.headers = state.table.currentRow;
1281
+ else state.table.rows.push(state.table.currentRow);
1282
+ state.table.currentRow = [];
1283
+ }
1284
+ break;
1285
+ case "th_open":
1286
+ case "td_open":
1287
+ if (state.table) state.table.currentCell = initRenderTarget();
1288
+ break;
1289
+ case "th_close":
1290
+ case "td_close":
1291
+ if (state.table?.currentCell) {
1292
+ state.table.currentRow.push(finishTableCell(state.table.currentCell));
1293
+ state.table.currentCell = null;
1294
+ }
1295
+ break;
1296
+ case "hr":
1297
+ state.text += "\n";
1298
+ break;
1299
+ default:
1300
+ if (token.children) renderTokens(token.children, state);
1301
+ break;
1302
+ }
1303
+ }
1304
+ function closeRemainingStyles(target) {
1305
+ for (let i = target.openStyles.length - 1; i >= 0; i -= 1) {
1306
+ const open = target.openStyles[i];
1307
+ const end = target.text.length;
1308
+ if (end > open.start) target.styles.push({
1309
+ start: open.start,
1310
+ end,
1311
+ style: open.style
1312
+ });
1313
+ }
1314
+ target.openStyles = [];
1315
+ }
1316
+ function clampStyleSpans(spans, maxLength) {
1317
+ const clamped = [];
1318
+ for (const span of spans) {
1319
+ const start = Math.max(0, Math.min(span.start, maxLength));
1320
+ const end = Math.max(start, Math.min(span.end, maxLength));
1321
+ if (end > start) clamped.push({
1322
+ start,
1323
+ end,
1324
+ style: span.style
1325
+ });
1326
+ }
1327
+ return clamped;
1328
+ }
1329
+ function clampLinkSpans(spans, maxLength) {
1330
+ const clamped = [];
1331
+ for (const span of spans) {
1332
+ const start = Math.max(0, Math.min(span.start, maxLength));
1333
+ const end = Math.max(start, Math.min(span.end, maxLength));
1334
+ if (end > start) clamped.push({
1335
+ start,
1336
+ end,
1337
+ href: span.href
1338
+ });
1339
+ }
1340
+ return clamped;
1341
+ }
1342
+ function mergeStyleSpans(spans) {
1343
+ const sorted = [...spans].toSorted((a, b) => {
1344
+ if (a.start !== b.start) return a.start - b.start;
1345
+ if (a.end !== b.end) return a.end - b.end;
1346
+ return a.style.localeCompare(b.style);
1347
+ });
1348
+ const merged = [];
1349
+ for (const span of sorted) {
1350
+ const prev = merged[merged.length - 1];
1351
+ if (prev && prev.style === span.style && span.start <= prev.end) {
1352
+ prev.end = Math.max(prev.end, span.end);
1353
+ continue;
1354
+ }
1355
+ merged.push({ ...span });
1356
+ }
1357
+ return merged;
1358
+ }
1359
+ function sliceStyleSpans(spans, start, end) {
1360
+ if (spans.length === 0) return [];
1361
+ const sliced = [];
1362
+ for (const span of spans) {
1363
+ const sliceStart = Math.max(span.start, start);
1364
+ const sliceEnd = Math.min(span.end, end);
1365
+ if (sliceEnd > sliceStart) sliced.push({
1366
+ start: sliceStart - start,
1367
+ end: sliceEnd - start,
1368
+ style: span.style
1369
+ });
1370
+ }
1371
+ return mergeStyleSpans(sliced);
1372
+ }
1373
+ function sliceLinkSpans(spans, start, end) {
1374
+ if (spans.length === 0) return [];
1375
+ const sliced = [];
1376
+ for (const span of spans) {
1377
+ const sliceStart = Math.max(span.start, start);
1378
+ const sliceEnd = Math.min(span.end, end);
1379
+ if (sliceEnd > sliceStart) sliced.push({
1380
+ start: sliceStart - start,
1381
+ end: sliceEnd - start,
1382
+ href: span.href
1383
+ });
1384
+ }
1385
+ return sliced;
1386
+ }
1387
+ function markdownToIR(markdown, options = {}) {
1388
+ return markdownToIRWithMeta(markdown, options).ir;
1389
+ }
1390
+ function markdownToIRWithMeta(markdown, options = {}) {
1391
+ const env = { listStack: [] };
1392
+ const tokens = createMarkdownIt(options).parse(markdown ?? "", env);
1393
+ if (options.enableSpoilers) applySpoilerTokens(tokens);
1394
+ const tableMode = options.tableMode ?? "off";
1395
+ const state = {
1396
+ text: "",
1397
+ styles: [],
1398
+ openStyles: [],
1399
+ links: [],
1400
+ linkStack: [],
1401
+ env,
1402
+ headingStyle: options.headingStyle ?? "none",
1403
+ blockquotePrefix: options.blockquotePrefix ?? "",
1404
+ enableSpoilers: options.enableSpoilers ?? false,
1405
+ tableMode,
1406
+ table: null,
1407
+ hasTables: false
1408
+ };
1409
+ renderTokens(tokens, state);
1410
+ closeRemainingStyles(state);
1411
+ const trimmedLength = state.text.trimEnd().length;
1412
+ let codeBlockEnd = 0;
1413
+ for (const span of state.styles) {
1414
+ if (span.style !== "code_block") continue;
1415
+ if (span.end > codeBlockEnd) codeBlockEnd = span.end;
1416
+ }
1417
+ const finalLength = Math.max(trimmedLength, codeBlockEnd);
1418
+ return {
1419
+ ir: {
1420
+ text: finalLength === state.text.length ? state.text : state.text.slice(0, finalLength),
1421
+ styles: mergeStyleSpans(clampStyleSpans(state.styles, finalLength)),
1422
+ links: clampLinkSpans(state.links, finalLength)
1423
+ },
1424
+ hasTables: state.hasTables
1425
+ };
1426
+ }
1427
+ function chunkMarkdownIR(ir, limit) {
1428
+ if (!ir.text) return [];
1429
+ if (limit <= 0 || ir.text.length <= limit) return [ir];
1430
+ const chunks = chunkText(ir.text, limit);
1431
+ const results = [];
1432
+ let cursor = 0;
1433
+ chunks.forEach((chunk, index) => {
1434
+ if (!chunk) return;
1435
+ if (index > 0) while (cursor < ir.text.length && /\s/.test(ir.text[cursor] ?? "")) cursor += 1;
1436
+ const start = cursor;
1437
+ const end = Math.min(ir.text.length, start + chunk.length);
1438
+ results.push({
1439
+ text: chunk,
1440
+ styles: sliceStyleSpans(ir.styles, start, end),
1441
+ links: sliceLinkSpans(ir.links, start, end)
1442
+ });
1443
+ cursor = end;
1444
+ });
1445
+ return results;
1446
+ }
1447
+
1448
+ //#endregion
1449
+ //#region src/infra/fetch.ts
1450
+ function withDuplex(init, input) {
1451
+ const hasInitBody = init?.body != null;
1452
+ const hasRequestBody = !hasInitBody && typeof Request !== "undefined" && input instanceof Request && input.body != null;
1453
+ if (!hasInitBody && !hasRequestBody) return init;
1454
+ if (init && "duplex" in init) return init;
1455
+ return init ? {
1456
+ ...init,
1457
+ duplex: "half"
1458
+ } : { duplex: "half" };
1459
+ }
1460
+ function wrapFetchWithAbortSignal(fetchImpl) {
1461
+ const wrapped = ((input, init) => {
1462
+ const patchedInit = withDuplex(init, input);
1463
+ const signal = patchedInit?.signal;
1464
+ if (!signal) return fetchImpl(input, patchedInit);
1465
+ if (typeof AbortSignal !== "undefined" && signal instanceof AbortSignal) return fetchImpl(input, patchedInit);
1466
+ if (typeof AbortController === "undefined") return fetchImpl(input, patchedInit);
1467
+ if (typeof signal.addEventListener !== "function") return fetchImpl(input, patchedInit);
1468
+ const controller = new AbortController();
1469
+ const onAbort = () => controller.abort();
1470
+ if (signal.aborted) controller.abort();
1471
+ else signal.addEventListener("abort", onAbort, { once: true });
1472
+ const response = fetchImpl(input, {
1473
+ ...patchedInit,
1474
+ signal: controller.signal
1475
+ });
1476
+ if (typeof signal.removeEventListener === "function") response.finally(() => {
1477
+ signal.removeEventListener("abort", onAbort);
1478
+ });
1479
+ return response;
1480
+ });
1481
+ const fetchWithPreconnect = fetchImpl;
1482
+ wrapped.preconnect = typeof fetchWithPreconnect.preconnect === "function" ? fetchWithPreconnect.preconnect.bind(fetchWithPreconnect) : () => {};
1483
+ return Object.assign(wrapped, fetchImpl);
1484
+ }
1485
+ function resolveFetch(fetchImpl) {
1486
+ const resolved = fetchImpl ?? globalThis.fetch;
1487
+ if (!resolved) return;
1488
+ return wrapFetchWithAbortSignal(resolved);
1489
+ }
1490
+
1491
+ //#endregion
1492
+ //#region src/signal/client.ts
1493
+ const DEFAULT_TIMEOUT_MS = 1e4;
1494
+ function normalizeBaseUrl(url) {
1495
+ const trimmed = url.trim();
1496
+ if (!trimmed) throw new Error("Signal base URL is required");
1497
+ if (/^https?:\/\//i.test(trimmed)) return trimmed.replace(/\/+$/, "");
1498
+ return `http://${trimmed}`.replace(/\/+$/, "");
1499
+ }
1500
+ async function fetchWithTimeout(url, init, timeoutMs) {
1501
+ const fetchImpl = resolveFetch();
1502
+ if (!fetchImpl) throw new Error("fetch is not available");
1503
+ const controller = new AbortController();
1504
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
1505
+ try {
1506
+ return await fetchImpl(url, {
1507
+ ...init,
1508
+ signal: controller.signal
1509
+ });
1510
+ } finally {
1511
+ clearTimeout(timer);
1512
+ }
1513
+ }
1514
+ async function signalRpcRequest(method, params, opts) {
1515
+ const baseUrl = normalizeBaseUrl(opts.baseUrl);
1516
+ const id = randomUUID();
1517
+ const body = JSON.stringify({
1518
+ jsonrpc: "2.0",
1519
+ method,
1520
+ params,
1521
+ id
1522
+ });
1523
+ const res = await fetchWithTimeout(`${baseUrl}/api/v1/rpc`, {
1524
+ method: "POST",
1525
+ headers: { "Content-Type": "application/json" },
1526
+ body
1527
+ }, opts.timeoutMs ?? DEFAULT_TIMEOUT_MS);
1528
+ if (res.status === 201) return;
1529
+ const text = await res.text();
1530
+ if (!text) throw new Error(`Signal RPC empty response (status ${res.status})`);
1531
+ const parsed = JSON.parse(text);
1532
+ if (parsed.error) {
1533
+ const code = parsed.error.code ?? "unknown";
1534
+ const msg = parsed.error.message ?? "Signal RPC error";
1535
+ throw new Error(`Signal RPC ${code}: ${msg}`);
1536
+ }
1537
+ return parsed.result;
1538
+ }
1539
+ async function signalCheck(baseUrl, timeoutMs = DEFAULT_TIMEOUT_MS) {
1540
+ const normalized = normalizeBaseUrl(baseUrl);
1541
+ try {
1542
+ const res = await fetchWithTimeout(`${normalized}/api/v1/check`, { method: "GET" }, timeoutMs);
1543
+ if (!res.ok) return {
1544
+ ok: false,
1545
+ status: res.status,
1546
+ error: `HTTP ${res.status}`
1547
+ };
1548
+ return {
1549
+ ok: true,
1550
+ status: res.status,
1551
+ error: null
1552
+ };
1553
+ } catch (err) {
1554
+ return {
1555
+ ok: false,
1556
+ status: null,
1557
+ error: err instanceof Error ? err.message : String(err)
1558
+ };
1559
+ }
1560
+ }
1561
+ async function streamSignalEvents(params) {
1562
+ const baseUrl = normalizeBaseUrl(params.baseUrl);
1563
+ const url = new URL(`${baseUrl}/api/v1/events`);
1564
+ if (params.account) url.searchParams.set("account", params.account);
1565
+ const fetchImpl = resolveFetch();
1566
+ if (!fetchImpl) throw new Error("fetch is not available");
1567
+ const res = await fetchImpl(url, {
1568
+ method: "GET",
1569
+ headers: { Accept: "text/event-stream" },
1570
+ signal: params.abortSignal
1571
+ });
1572
+ if (!res.ok || !res.body) throw new Error(`Signal SSE failed (${res.status} ${res.statusText || "error"})`);
1573
+ const reader = res.body.getReader();
1574
+ const decoder = new TextDecoder();
1575
+ let buffer = "";
1576
+ let currentEvent = {};
1577
+ const flushEvent = () => {
1578
+ if (!currentEvent.data && !currentEvent.event && !currentEvent.id) return;
1579
+ params.onEvent({
1580
+ event: currentEvent.event,
1581
+ data: currentEvent.data,
1582
+ id: currentEvent.id
1583
+ });
1584
+ currentEvent = {};
1585
+ };
1586
+ while (true) {
1587
+ const { value, done } = await reader.read();
1588
+ if (done) break;
1589
+ buffer += decoder.decode(value, { stream: true });
1590
+ let lineEnd = buffer.indexOf("\n");
1591
+ while (lineEnd !== -1) {
1592
+ let line = buffer.slice(0, lineEnd);
1593
+ buffer = buffer.slice(lineEnd + 1);
1594
+ if (line.endsWith("\r")) line = line.slice(0, -1);
1595
+ if (line === "") {
1596
+ flushEvent();
1597
+ lineEnd = buffer.indexOf("\n");
1598
+ continue;
1599
+ }
1600
+ if (line.startsWith(":")) {
1601
+ lineEnd = buffer.indexOf("\n");
1602
+ continue;
1603
+ }
1604
+ const [rawField, ...rest] = line.split(":");
1605
+ const field = rawField.trim();
1606
+ const rawValue = rest.join(":");
1607
+ const value = rawValue.startsWith(" ") ? rawValue.slice(1) : rawValue;
1608
+ if (field === "event") currentEvent.event = value;
1609
+ else if (field === "data") currentEvent.data = currentEvent.data ? `${currentEvent.data}\n${value}` : value;
1610
+ else if (field === "id") currentEvent.id = value;
1611
+ lineEnd = buffer.indexOf("\n");
1612
+ }
1613
+ }
1614
+ flushEvent();
1615
+ }
1616
+
1617
+ //#endregion
1618
+ //#region src/signal/format.ts
1619
+ function mapStyle(style) {
1620
+ switch (style) {
1621
+ case "bold": return "BOLD";
1622
+ case "italic": return "ITALIC";
1623
+ case "strikethrough": return "STRIKETHROUGH";
1624
+ case "code":
1625
+ case "code_block": return "MONOSPACE";
1626
+ case "spoiler": return "SPOILER";
1627
+ default: return null;
1628
+ }
1629
+ }
1630
+ function mergeStyles(styles) {
1631
+ const sorted = [...styles].toSorted((a, b) => {
1632
+ if (a.start !== b.start) return a.start - b.start;
1633
+ if (a.length !== b.length) return a.length - b.length;
1634
+ return a.style.localeCompare(b.style);
1635
+ });
1636
+ const merged = [];
1637
+ for (const style of sorted) {
1638
+ const prev = merged[merged.length - 1];
1639
+ if (prev && prev.style === style.style && style.start <= prev.start + prev.length) {
1640
+ const prevEnd = prev.start + prev.length;
1641
+ prev.length = Math.max(prevEnd, style.start + style.length) - prev.start;
1642
+ continue;
1643
+ }
1644
+ merged.push({ ...style });
1645
+ }
1646
+ return merged;
1647
+ }
1648
+ function clampStyles(styles, maxLength) {
1649
+ const clamped = [];
1650
+ for (const style of styles) {
1651
+ const start = Math.max(0, Math.min(style.start, maxLength));
1652
+ const length = Math.min(style.start + style.length, maxLength) - start;
1653
+ if (length > 0) clamped.push({
1654
+ start,
1655
+ length,
1656
+ style: style.style
1657
+ });
1658
+ }
1659
+ return clamped;
1660
+ }
1661
+ function applyInsertionsToStyles(spans, insertions) {
1662
+ if (insertions.length === 0) return spans;
1663
+ const sortedInsertions = [...insertions].toSorted((a, b) => a.pos - b.pos);
1664
+ let updated = spans;
1665
+ for (const insertion of sortedInsertions) {
1666
+ const next = [];
1667
+ for (const span of updated) {
1668
+ if (span.end <= insertion.pos) {
1669
+ next.push(span);
1670
+ continue;
1671
+ }
1672
+ if (span.start >= insertion.pos) {
1673
+ next.push({
1674
+ start: span.start + insertion.length,
1675
+ end: span.end + insertion.length,
1676
+ style: span.style
1677
+ });
1678
+ continue;
1679
+ }
1680
+ if (span.start < insertion.pos && span.end > insertion.pos) {
1681
+ if (insertion.pos > span.start) next.push({
1682
+ start: span.start,
1683
+ end: insertion.pos,
1684
+ style: span.style
1685
+ });
1686
+ const shiftedStart = insertion.pos + insertion.length;
1687
+ const shiftedEnd = span.end + insertion.length;
1688
+ if (shiftedEnd > shiftedStart) next.push({
1689
+ start: shiftedStart,
1690
+ end: shiftedEnd,
1691
+ style: span.style
1692
+ });
1693
+ }
1694
+ }
1695
+ updated = next;
1696
+ }
1697
+ return updated;
1698
+ }
1699
+ function renderSignalText(ir) {
1700
+ const text = ir.text ?? "";
1701
+ if (!text) return {
1702
+ text: "",
1703
+ styles: []
1704
+ };
1705
+ const sortedLinks = [...ir.links].toSorted((a, b) => a.start - b.start);
1706
+ let out = "";
1707
+ let cursor = 0;
1708
+ const insertions = [];
1709
+ for (const link of sortedLinks) {
1710
+ if (link.start < cursor) continue;
1711
+ out += text.slice(cursor, link.end);
1712
+ const href = link.href.trim();
1713
+ const trimmedLabel = text.slice(link.start, link.end).trim();
1714
+ const comparableHref = href.startsWith("mailto:") ? href.slice(7) : href;
1715
+ if (href) {
1716
+ if (!trimmedLabel) {
1717
+ out += href;
1718
+ insertions.push({
1719
+ pos: link.end,
1720
+ length: href.length
1721
+ });
1722
+ } else if (trimmedLabel !== href && trimmedLabel !== comparableHref) {
1723
+ const addition = ` (${href})`;
1724
+ out += addition;
1725
+ insertions.push({
1726
+ pos: link.end,
1727
+ length: addition.length
1728
+ });
1729
+ }
1730
+ }
1731
+ cursor = link.end;
1732
+ }
1733
+ out += text.slice(cursor);
1734
+ const adjusted = applyInsertionsToStyles(ir.styles.map((span) => {
1735
+ const mapped = mapStyle(span.style);
1736
+ if (!mapped) return null;
1737
+ return {
1738
+ start: span.start,
1739
+ end: span.end,
1740
+ style: mapped
1741
+ };
1742
+ }).filter((span) => span !== null), insertions);
1743
+ const trimmedText = out.trimEnd();
1744
+ const trimmedLength = trimmedText.length;
1745
+ return {
1746
+ text: trimmedText,
1747
+ styles: mergeStyles(clampStyles(adjusted.map((span) => ({
1748
+ start: span.start,
1749
+ length: span.end - span.start,
1750
+ style: span.style
1751
+ })), trimmedLength))
1752
+ };
1753
+ }
1754
+ function markdownToSignalText(markdown, options = {}) {
1755
+ return renderSignalText(markdownToIR(markdown ?? "", {
1756
+ linkify: true,
1757
+ enableSpoilers: true,
1758
+ headingStyle: "none",
1759
+ blockquotePrefix: "",
1760
+ tableMode: options.tableMode
1761
+ }));
1762
+ }
1763
+ function markdownToSignalTextChunks(markdown, limit, options = {}) {
1764
+ return chunkMarkdownIR(markdownToIR(markdown ?? "", {
1765
+ linkify: true,
1766
+ enableSpoilers: true,
1767
+ headingStyle: "none",
1768
+ blockquotePrefix: "",
1769
+ tableMode: options.tableMode
1770
+ }), limit).map((chunk) => renderSignalText(chunk));
1771
+ }
1772
+
1773
+ //#endregion
1774
+ //#region src/signal/send.ts
1775
+ function parseTarget(raw) {
1776
+ let value = raw.trim();
1777
+ if (!value) throw new Error("Signal recipient is required");
1778
+ if (value.toLowerCase().startsWith("signal:")) value = value.slice(7).trim();
1779
+ const normalized = value.toLowerCase();
1780
+ if (normalized.startsWith("group:")) return {
1781
+ type: "group",
1782
+ groupId: value.slice(6).trim()
1783
+ };
1784
+ if (normalized.startsWith("username:")) return {
1785
+ type: "username",
1786
+ username: value.slice(9).trim()
1787
+ };
1788
+ if (normalized.startsWith("u:")) return {
1789
+ type: "username",
1790
+ username: value.trim()
1791
+ };
1792
+ return {
1793
+ type: "recipient",
1794
+ recipient: value
1795
+ };
1796
+ }
1797
+ function buildTargetParams(target, allow) {
1798
+ if (target.type === "recipient") {
1799
+ if (!allow.recipient) return null;
1800
+ return { recipient: [target.recipient] };
1801
+ }
1802
+ if (target.type === "group") {
1803
+ if (!allow.group) return null;
1804
+ return { groupId: target.groupId };
1805
+ }
1806
+ if (target.type === "username") {
1807
+ if (!allow.username) return null;
1808
+ return { username: [target.username] };
1809
+ }
1810
+ return null;
1811
+ }
1812
+ function resolveSignalRpcContext(opts, accountInfo) {
1813
+ const hasBaseUrl = Boolean(opts.baseUrl?.trim());
1814
+ const hasAccount = Boolean(opts.account?.trim());
1815
+ const resolvedAccount = accountInfo || (!hasBaseUrl || !hasAccount ? resolveSignalAccount({
1816
+ cfg: loadConfig(),
1817
+ accountId: opts.accountId
1818
+ }) : void 0);
1819
+ const baseUrl = opts.baseUrl?.trim() || resolvedAccount?.baseUrl;
1820
+ if (!baseUrl) throw new Error("Signal base URL is required");
1821
+ return {
1822
+ baseUrl,
1823
+ account: opts.account?.trim() || resolvedAccount?.config.account?.trim()
1824
+ };
1825
+ }
1826
+ async function resolveAttachment(mediaUrl, maxBytes) {
1827
+ const media = await loadWebMedia(mediaUrl, maxBytes);
1828
+ const saved = await saveMediaBuffer(media.buffer, media.contentType ?? void 0, "outbound", maxBytes);
1829
+ return {
1830
+ path: saved.path,
1831
+ contentType: saved.contentType
1832
+ };
1833
+ }
1834
+ async function sendMessageSignal(to, text, opts = {}) {
1835
+ const cfg = loadConfig();
1836
+ const accountInfo = resolveSignalAccount({
1837
+ cfg,
1838
+ accountId: opts.accountId
1839
+ });
1840
+ const { baseUrl, account } = resolveSignalRpcContext(opts, accountInfo);
1841
+ const target = parseTarget(to);
1842
+ let message = text ?? "";
1843
+ let messageFromPlaceholder = false;
1844
+ let textStyles = [];
1845
+ const textMode = opts.textMode ?? "markdown";
1846
+ const maxBytes = (() => {
1847
+ if (typeof opts.maxBytes === "number") return opts.maxBytes;
1848
+ if (typeof accountInfo.config.mediaMaxMb === "number") return accountInfo.config.mediaMaxMb * 1024 * 1024;
1849
+ if (typeof cfg.agents?.defaults?.mediaMaxMb === "number") return cfg.agents.defaults.mediaMaxMb * 1024 * 1024;
1850
+ return 8 * 1024 * 1024;
1851
+ })();
1852
+ let attachments;
1853
+ if (opts.mediaUrl?.trim()) {
1854
+ const resolved = await resolveAttachment(opts.mediaUrl.trim(), maxBytes);
1855
+ attachments = [resolved.path];
1856
+ const kind = mediaKindFromMime(resolved.contentType ?? void 0);
1857
+ if (!message && kind) {
1858
+ message = kind === "image" ? "<media:image>" : `<media:${kind}>`;
1859
+ messageFromPlaceholder = true;
1860
+ }
1861
+ }
1862
+ if (message.trim() && !messageFromPlaceholder) if (textMode === "plain") textStyles = opts.textStyles ?? [];
1863
+ else {
1864
+ const tableMode = resolveMarkdownTableMode({
1865
+ cfg,
1866
+ channel: "signal",
1867
+ accountId: accountInfo.accountId
1868
+ });
1869
+ const formatted = markdownToSignalText(message, { tableMode });
1870
+ message = formatted.text;
1871
+ textStyles = formatted.styles;
1872
+ }
1873
+ if (!message.trim() && (!attachments || attachments.length === 0)) throw new Error("Signal send requires text or media");
1874
+ const params = { message };
1875
+ if (textStyles.length > 0) params["text-style"] = textStyles.map((style) => `${style.start}:${style.length}:${style.style}`);
1876
+ if (account) params.account = account;
1877
+ if (attachments && attachments.length > 0) params.attachments = attachments;
1878
+ const targetParams = buildTargetParams(target, {
1879
+ recipient: true,
1880
+ group: true,
1881
+ username: true
1882
+ });
1883
+ if (!targetParams) throw new Error("Signal recipient is required");
1884
+ Object.assign(params, targetParams);
1885
+ const timestamp = (await signalRpcRequest("send", params, {
1886
+ baseUrl,
1887
+ timeoutMs: opts.timeoutMs
1888
+ }))?.timestamp;
1889
+ return {
1890
+ messageId: timestamp ? String(timestamp) : "unknown",
1891
+ timestamp
1892
+ };
1893
+ }
1894
+ async function sendTypingSignal(to, opts = {}) {
1895
+ const { baseUrl, account } = resolveSignalRpcContext(opts);
1896
+ const targetParams = buildTargetParams(parseTarget(to), {
1897
+ recipient: true,
1898
+ group: true
1899
+ });
1900
+ if (!targetParams) return false;
1901
+ const params = { ...targetParams };
1902
+ if (account) params.account = account;
1903
+ if (opts.stop) params.stop = true;
1904
+ await signalRpcRequest("sendTyping", params, {
1905
+ baseUrl,
1906
+ timeoutMs: opts.timeoutMs
1907
+ });
1908
+ return true;
1909
+ }
1910
+ async function sendReadReceiptSignal(to, targetTimestamp, opts = {}) {
1911
+ if (!Number.isFinite(targetTimestamp) || targetTimestamp <= 0) return false;
1912
+ const { baseUrl, account } = resolveSignalRpcContext(opts);
1913
+ const targetParams = buildTargetParams(parseTarget(to), { recipient: true });
1914
+ if (!targetParams) return false;
1915
+ const params = {
1916
+ ...targetParams,
1917
+ targetTimestamp,
1918
+ type: opts.type ?? "read"
1919
+ };
1920
+ if (account) params.account = account;
1921
+ await signalRpcRequest("sendReceipt", params, {
1922
+ baseUrl,
1923
+ timeoutMs: opts.timeoutMs
1924
+ });
1925
+ return true;
1926
+ }
1927
+
1928
+ //#endregion
1929
+ //#region src/utils/directive-tags.ts
1930
+ const AUDIO_TAG_RE = /\[\[\s*audio_as_voice\s*\]\]/gi;
1931
+ const REPLY_TAG_RE = /\[\[\s*(?:reply_to_current|reply_to\s*:\s*([^\]\n]+))\s*\]\]/gi;
1932
+ function normalizeDirectiveWhitespace(text) {
1933
+ return text.replace(/[ \t]+/g, " ").replace(/[ \t]*\n[ \t]*/g, "\n").trim();
1934
+ }
1935
+ function parseInlineDirectives(text, options = {}) {
1936
+ const { currentMessageId, stripAudioTag = true, stripReplyTags = true } = options;
1937
+ if (!text) return {
1938
+ text: "",
1939
+ audioAsVoice: false,
1940
+ replyToCurrent: false,
1941
+ hasAudioTag: false,
1942
+ hasReplyTag: false
1943
+ };
1944
+ let cleaned = text;
1945
+ let audioAsVoice = false;
1946
+ let hasAudioTag = false;
1947
+ let hasReplyTag = false;
1948
+ let sawCurrent = false;
1949
+ let lastExplicitId;
1950
+ cleaned = cleaned.replace(AUDIO_TAG_RE, (match) => {
1951
+ audioAsVoice = true;
1952
+ hasAudioTag = true;
1953
+ return stripAudioTag ? " " : match;
1954
+ });
1955
+ cleaned = cleaned.replace(REPLY_TAG_RE, (match, idRaw) => {
1956
+ hasReplyTag = true;
1957
+ if (idRaw === void 0) sawCurrent = true;
1958
+ else {
1959
+ const id = idRaw.trim();
1960
+ if (id) lastExplicitId = id;
1961
+ }
1962
+ return stripReplyTags ? " " : match;
1963
+ });
1964
+ cleaned = normalizeDirectiveWhitespace(cleaned);
1965
+ const replyToId = lastExplicitId ?? (sawCurrent ? currentMessageId?.trim() || void 0 : void 0);
1966
+ return {
1967
+ text: cleaned,
1968
+ audioAsVoice,
1969
+ replyToId,
1970
+ replyToExplicitId: lastExplicitId,
1971
+ replyToCurrent: sawCurrent,
1972
+ hasAudioTag,
1973
+ hasReplyTag
1974
+ };
1975
+ }
1976
+
1977
+ //#endregion
1978
+ //#region src/media/audio-tags.ts
1979
+ /**
1980
+ * Extract audio mode tag from text.
1981
+ * Supports [[audio_as_voice]] to send audio as voice bubble instead of file.
1982
+ * Default is file (preserves backward compatibility).
1983
+ */
1984
+ function parseAudioTag(text) {
1985
+ const result = parseInlineDirectives(text, { stripReplyTags: false });
1986
+ return {
1987
+ text: result.text,
1988
+ audioAsVoice: result.audioAsVoice,
1989
+ hadTag: result.hasAudioTag
1990
+ };
1991
+ }
1992
+
1993
+ //#endregion
1994
+ //#region src/media/parse.ts
1995
+ const MEDIA_TOKEN_RE = /\bMEDIA:\s*`?([^\n]+)`?/gi;
1996
+ function normalizeMediaSource(src) {
1997
+ return src.startsWith("file://") ? src.replace("file://", "") : src;
1998
+ }
1999
+ function cleanCandidate(raw) {
2000
+ return raw.replace(/^[`"'[{(]+/, "").replace(/[`"'\\})\],]+$/, "");
2001
+ }
2002
+ function isValidMedia(candidate, opts) {
2003
+ if (!candidate) return false;
2004
+ if (candidate.length > 4096) return false;
2005
+ if (!opts?.allowSpaces && /\s/.test(candidate)) return false;
2006
+ if (/^https?:\/\//i.test(candidate)) return true;
2007
+ return candidate.startsWith("./") && !candidate.includes("..");
2008
+ }
2009
+ function unwrapQuoted(value) {
2010
+ const trimmed = value.trim();
2011
+ if (trimmed.length < 2) return;
2012
+ const first = trimmed[0];
2013
+ if (first !== trimmed[trimmed.length - 1]) return;
2014
+ if (first !== `"` && first !== "'" && first !== "`") return;
2015
+ return trimmed.slice(1, -1).trim();
2016
+ }
2017
+ function isInsideFence(fenceSpans, offset) {
2018
+ return fenceSpans.some((span) => offset >= span.start && offset < span.end);
2019
+ }
2020
+ function splitMediaFromOutput(raw) {
2021
+ const trimmedRaw = raw.trimEnd();
2022
+ if (!trimmedRaw.trim()) return { text: "" };
2023
+ const media = [];
2024
+ let foundMediaToken = false;
2025
+ const fenceSpans = parseFenceSpans(trimmedRaw);
2026
+ const lines = trimmedRaw.split("\n");
2027
+ const keptLines = [];
2028
+ let lineOffset = 0;
2029
+ for (const line of lines) {
2030
+ if (isInsideFence(fenceSpans, lineOffset)) {
2031
+ keptLines.push(line);
2032
+ lineOffset += line.length + 1;
2033
+ continue;
2034
+ }
2035
+ if (!line.trimStart().startsWith("MEDIA:")) {
2036
+ keptLines.push(line);
2037
+ lineOffset += line.length + 1;
2038
+ continue;
2039
+ }
2040
+ const matches = Array.from(line.matchAll(MEDIA_TOKEN_RE));
2041
+ if (matches.length === 0) {
2042
+ keptLines.push(line);
2043
+ lineOffset += line.length + 1;
2044
+ continue;
2045
+ }
2046
+ const pieces = [];
2047
+ let cursor = 0;
2048
+ for (const match of matches) {
2049
+ const start = match.index ?? 0;
2050
+ pieces.push(line.slice(cursor, start));
2051
+ const payload = match[1];
2052
+ const unwrapped = unwrapQuoted(payload);
2053
+ const payloadValue = unwrapped ?? payload;
2054
+ const parts = unwrapped ? [unwrapped] : payload.split(/\s+/).filter(Boolean);
2055
+ const mediaStartIndex = media.length;
2056
+ let validCount = 0;
2057
+ const invalidParts = [];
2058
+ let hasValidMedia = false;
2059
+ for (const part of parts) {
2060
+ const candidate = normalizeMediaSource(cleanCandidate(part));
2061
+ if (isValidMedia(candidate, unwrapped ? { allowSpaces: true } : void 0)) {
2062
+ media.push(candidate);
2063
+ hasValidMedia = true;
2064
+ foundMediaToken = true;
2065
+ validCount += 1;
2066
+ } else invalidParts.push(part);
2067
+ }
2068
+ const trimmedPayload = payloadValue.trim();
2069
+ const looksLikeLocalPath = trimmedPayload.startsWith("/") || trimmedPayload.startsWith("./") || trimmedPayload.startsWith("../") || trimmedPayload.startsWith("~") || trimmedPayload.startsWith("file://");
2070
+ if (!unwrapped && validCount === 1 && invalidParts.length > 0 && /\s/.test(payloadValue) && looksLikeLocalPath) {
2071
+ const fallback = normalizeMediaSource(cleanCandidate(payloadValue));
2072
+ if (isValidMedia(fallback, { allowSpaces: true })) {
2073
+ media.splice(mediaStartIndex, media.length - mediaStartIndex, fallback);
2074
+ hasValidMedia = true;
2075
+ foundMediaToken = true;
2076
+ validCount = 1;
2077
+ invalidParts.length = 0;
2078
+ }
2079
+ }
2080
+ if (!hasValidMedia) {
2081
+ const fallback = normalizeMediaSource(cleanCandidate(payloadValue));
2082
+ if (isValidMedia(fallback, { allowSpaces: true })) {
2083
+ media.push(fallback);
2084
+ hasValidMedia = true;
2085
+ foundMediaToken = true;
2086
+ invalidParts.length = 0;
2087
+ }
2088
+ }
2089
+ if (hasValidMedia) {
2090
+ if (invalidParts.length > 0) pieces.push(invalidParts.join(" "));
2091
+ } else pieces.push(match[0]);
2092
+ cursor = start + match[0].length;
2093
+ }
2094
+ pieces.push(line.slice(cursor));
2095
+ const cleanedLine = pieces.join("").replace(/[ \t]{2,}/g, " ").trim();
2096
+ if (cleanedLine) keptLines.push(cleanedLine);
2097
+ lineOffset += line.length + 1;
2098
+ }
2099
+ let cleanedText = keptLines.join("\n").replace(/[ \t]+\n/g, "\n").replace(/[ \t]{2,}/g, " ").replace(/\n{2,}/g, "\n").trim();
2100
+ const audioTagResult = parseAudioTag(cleanedText);
2101
+ const hasAudioAsVoice = audioTagResult.audioAsVoice;
2102
+ if (audioTagResult.hadTag) cleanedText = audioTagResult.text.replace(/\n{2,}/g, "\n").trim();
2103
+ if (media.length === 0) {
2104
+ const result = { text: foundMediaToken || hasAudioAsVoice ? cleanedText : trimmedRaw };
2105
+ if (hasAudioAsVoice) result.audioAsVoice = true;
2106
+ return result;
2107
+ }
2108
+ return {
2109
+ text: cleanedText,
2110
+ mediaUrls: media,
2111
+ mediaUrl: media[0],
2112
+ ...hasAudioAsVoice ? { audioAsVoice: true } : {}
2113
+ };
2114
+ }
2115
+
2116
+ //#endregion
2117
+ //#region src/auto-reply/reply/reply-directives.ts
2118
+ function parseReplyDirectives(raw, options = {}) {
2119
+ const split = splitMediaFromOutput(raw);
2120
+ let text = split.text ?? "";
2121
+ const replyParsed = parseInlineDirectives(text, {
2122
+ currentMessageId: options.currentMessageId,
2123
+ stripAudioTag: false,
2124
+ stripReplyTags: true
2125
+ });
2126
+ if (replyParsed.hasReplyTag) text = replyParsed.text;
2127
+ const silentToken = options.silentToken ?? SILENT_REPLY_TOKEN;
2128
+ const isSilent = isSilentReplyText(text, silentToken);
2129
+ if (isSilent) text = "";
2130
+ return {
2131
+ text,
2132
+ mediaUrls: split.mediaUrls,
2133
+ mediaUrl: split.mediaUrl,
2134
+ replyToId: replyParsed.replyToId,
2135
+ replyToCurrent: replyParsed.replyToCurrent,
2136
+ replyToTag: replyParsed.hasReplyTag,
2137
+ audioAsVoice: split.audioAsVoice,
2138
+ isSilent
2139
+ };
2140
+ }
2141
+
2142
+ //#endregion
2143
+ //#region src/infra/outbound/target-normalization.ts
2144
+ function normalizeChannelTargetInput(raw) {
2145
+ return raw.trim();
2146
+ }
2147
+ function normalizeTargetForProvider(provider, raw) {
2148
+ if (!raw) return;
2149
+ const providerId = normalizeChannelId(provider);
2150
+ return ((providerId ? getChannelPlugin(providerId) : void 0)?.messaging?.normalizeTarget?.(raw) ?? (raw.trim().toLowerCase() || void 0)) || void 0;
2151
+ }
2152
+ function buildTargetResolverSignature(channel) {
2153
+ const resolver = getChannelPlugin(channel)?.messaging?.targetResolver;
2154
+ const hint = resolver?.hint ?? "";
2155
+ const looksLike = resolver?.looksLikeId;
2156
+ return hashSignature(`${hint}|${looksLike ? looksLike.toString() : ""}`);
2157
+ }
2158
+ function hashSignature(value) {
2159
+ let hash = 5381;
2160
+ for (let i = 0; i < value.length; i += 1) hash = (hash << 5) + hash ^ value.charCodeAt(i);
2161
+ return (hash >>> 0).toString(36);
2162
+ }
2163
+
2164
+ //#endregion
2165
+ //#region src/channels/plugins/media-limits.ts
2166
+ const MB = 1024 * 1024;
2167
+ function resolveChannelMediaMaxBytes(params) {
2168
+ const accountId = normalizeAccountId$1(params.accountId);
2169
+ const channelLimit = params.resolveChannelLimitMb({
2170
+ cfg: params.cfg,
2171
+ accountId
2172
+ });
2173
+ if (channelLimit) return channelLimit * MB;
2174
+ if (params.cfg.agents?.defaults?.mediaMaxMb) return params.cfg.agents.defaults.mediaMaxMb * MB;
2175
+ }
2176
+
2177
+ //#endregion
2178
+ //#region src/channels/plugins/outbound/load.ts
2179
+ const cache = /* @__PURE__ */ new Map();
2180
+ let lastRegistry = null;
2181
+ function ensureCacheForRegistry(registry) {
2182
+ if (registry === lastRegistry) return;
2183
+ cache.clear();
2184
+ lastRegistry = registry;
2185
+ }
2186
+ async function loadChannelOutboundAdapter(id) {
2187
+ const registry = getActivePluginRegistry();
2188
+ ensureCacheForRegistry(registry);
2189
+ const cached = cache.get(id);
2190
+ if (cached) return cached;
2191
+ const outbound = (registry?.channels.find((entry) => entry.plugin.id === id))?.plugin.outbound;
2192
+ if (outbound) {
2193
+ cache.set(id, outbound);
2194
+ return outbound;
2195
+ }
2196
+ }
2197
+
2198
+ //#endregion
2199
+ //#region src/auto-reply/reply/reply-tags.ts
2200
+ function extractReplyToTag(text, currentMessageId) {
2201
+ const result = parseInlineDirectives(text, {
2202
+ currentMessageId,
2203
+ stripAudioTag: false
2204
+ });
2205
+ return {
2206
+ cleaned: result.text,
2207
+ replyToId: result.replyToId,
2208
+ replyToCurrent: result.replyToCurrent,
2209
+ hasTag: result.hasReplyTag
2210
+ };
2211
+ }
2212
+
2213
+ //#endregion
2214
+ //#region src/auto-reply/reply/reply-threading.ts
2215
+ function resolveReplyToMode(cfg, channel, accountId, chatType) {
2216
+ const provider = normalizeChannelId(channel);
2217
+ if (!provider) return "all";
2218
+ return getChannelDock(provider)?.threading?.resolveReplyToMode?.({
2219
+ cfg,
2220
+ accountId,
2221
+ chatType
2222
+ }) ?? "all";
2223
+ }
2224
+ function createReplyToModeFilter(mode, opts = {}) {
2225
+ let hasThreaded = false;
2226
+ return (payload) => {
2227
+ if (!payload.replyToId) return payload;
2228
+ if (mode === "off") {
2229
+ if (opts.allowTagsWhenOff && payload.replyToTag) return payload;
2230
+ return {
2231
+ ...payload,
2232
+ replyToId: void 0
2233
+ };
2234
+ }
2235
+ if (mode === "all") return payload;
2236
+ if (hasThreaded) return {
2237
+ ...payload,
2238
+ replyToId: void 0
2239
+ };
2240
+ hasThreaded = true;
2241
+ return payload;
2242
+ };
2243
+ }
2244
+ function createReplyToModeFilterForChannel(mode, channel) {
2245
+ const provider = normalizeChannelId(channel);
2246
+ return createReplyToModeFilter(mode, { allowTagsWhenOff: provider ? Boolean(getChannelDock(provider)?.threading?.allowTagsWhenOff) : false });
2247
+ }
2248
+
2249
+ //#endregion
2250
+ //#region src/auto-reply/reply/reply-payloads.ts
2251
+ function applyReplyTagsToPayload(payload, currentMessageId) {
2252
+ if (typeof payload.text !== "string") {
2253
+ if (!payload.replyToCurrent || payload.replyToId) return payload;
2254
+ return {
2255
+ ...payload,
2256
+ replyToId: currentMessageId?.trim() || void 0
2257
+ };
2258
+ }
2259
+ if (!payload.text.includes("[[")) {
2260
+ if (!payload.replyToCurrent || payload.replyToId) return payload;
2261
+ return {
2262
+ ...payload,
2263
+ replyToId: currentMessageId?.trim() || void 0,
2264
+ replyToTag: payload.replyToTag ?? true
2265
+ };
2266
+ }
2267
+ const { cleaned, replyToId, replyToCurrent, hasTag } = extractReplyToTag(payload.text, currentMessageId);
2268
+ return {
2269
+ ...payload,
2270
+ text: cleaned ? cleaned : void 0,
2271
+ replyToId: replyToId ?? payload.replyToId,
2272
+ replyToTag: hasTag || payload.replyToTag,
2273
+ replyToCurrent: replyToCurrent || payload.replyToCurrent
2274
+ };
2275
+ }
2276
+ function isRenderablePayload(payload) {
2277
+ return Boolean(payload.text || payload.mediaUrl || payload.mediaUrls && payload.mediaUrls.length > 0 || payload.audioAsVoice || payload.channelData);
2278
+ }
2279
+ function applyReplyThreading(params) {
2280
+ const { payloads, replyToMode, replyToChannel, currentMessageId } = params;
2281
+ const applyReplyToMode = createReplyToModeFilterForChannel(replyToMode, replyToChannel);
2282
+ return payloads.map((payload) => applyReplyTagsToPayload(payload, currentMessageId)).filter(isRenderablePayload).map(applyReplyToMode);
2283
+ }
2284
+ function filterMessagingToolDuplicates(params) {
2285
+ const { payloads, sentTexts } = params;
2286
+ if (sentTexts.length === 0) return payloads;
2287
+ return payloads.filter((payload) => !isMessagingToolDuplicate(payload.text ?? "", sentTexts));
2288
+ }
2289
+ function normalizeAccountId(value) {
2290
+ const trimmed = value?.trim();
2291
+ return trimmed ? trimmed.toLowerCase() : void 0;
2292
+ }
2293
+ function shouldSuppressMessagingToolReplies(params) {
2294
+ const provider = params.messageProvider?.trim().toLowerCase();
2295
+ if (!provider) return false;
2296
+ const originTarget = normalizeTargetForProvider(provider, params.originatingTo);
2297
+ if (!originTarget) return false;
2298
+ const originAccount = normalizeAccountId(params.accountId);
2299
+ const sentTargets = params.messagingToolSentTargets ?? [];
2300
+ if (sentTargets.length === 0) return false;
2301
+ return sentTargets.some((target) => {
2302
+ if (!target?.provider) return false;
2303
+ if (target.provider.trim().toLowerCase() !== provider) return false;
2304
+ const targetKey = normalizeTargetForProvider(provider, target.to);
2305
+ if (!targetKey) return false;
2306
+ const targetAccount = normalizeAccountId(target.accountId);
2307
+ if (originAccount && targetAccount && originAccount !== targetAccount) return false;
2308
+ return targetKey === originTarget;
2309
+ });
2310
+ }
2311
+
2312
+ //#endregion
2313
+ //#region src/infra/outbound/payloads.ts
2314
+ function mergeMediaUrls(...lists) {
2315
+ const seen = /* @__PURE__ */ new Set();
2316
+ const merged = [];
2317
+ for (const list of lists) {
2318
+ if (!list) continue;
2319
+ for (const entry of list) {
2320
+ const trimmed = entry?.trim();
2321
+ if (!trimmed) continue;
2322
+ if (seen.has(trimmed)) continue;
2323
+ seen.add(trimmed);
2324
+ merged.push(trimmed);
2325
+ }
2326
+ }
2327
+ return merged;
2328
+ }
2329
+ function normalizeReplyPayloadsForDelivery(payloads) {
2330
+ return payloads.flatMap((payload) => {
2331
+ const parsed = parseReplyDirectives(payload.text ?? "");
2332
+ const explicitMediaUrls = payload.mediaUrls ?? parsed.mediaUrls;
2333
+ const explicitMediaUrl = payload.mediaUrl ?? parsed.mediaUrl;
2334
+ const mergedMedia = mergeMediaUrls(explicitMediaUrls, explicitMediaUrl ? [explicitMediaUrl] : void 0);
2335
+ const resolvedMediaUrl = (explicitMediaUrls?.length ?? 0) > 1 ? void 0 : explicitMediaUrl;
2336
+ const next = {
2337
+ ...payload,
2338
+ text: parsed.text ?? "",
2339
+ mediaUrls: mergedMedia.length ? mergedMedia : void 0,
2340
+ mediaUrl: resolvedMediaUrl,
2341
+ replyToId: payload.replyToId ?? parsed.replyToId,
2342
+ replyToTag: payload.replyToTag || parsed.replyToTag,
2343
+ replyToCurrent: payload.replyToCurrent || parsed.replyToCurrent,
2344
+ audioAsVoice: Boolean(payload.audioAsVoice || parsed.audioAsVoice)
2345
+ };
2346
+ if (parsed.isSilent && mergedMedia.length === 0) return [];
2347
+ if (!isRenderablePayload(next)) return [];
2348
+ return [next];
2349
+ });
2350
+ }
2351
+ function normalizeOutboundPayloads(payloads) {
2352
+ return normalizeReplyPayloadsForDelivery(payloads).map((payload) => {
2353
+ const channelData = payload.channelData;
2354
+ const normalized = {
2355
+ text: payload.text ?? "",
2356
+ mediaUrls: payload.mediaUrls ?? (payload.mediaUrl ? [payload.mediaUrl] : [])
2357
+ };
2358
+ if (channelData && Object.keys(channelData).length > 0) normalized.channelData = channelData;
2359
+ return normalized;
2360
+ }).filter((payload) => payload.text || payload.mediaUrls.length > 0 || Boolean(payload.channelData && Object.keys(payload.channelData).length > 0));
2361
+ }
2362
+ function normalizeOutboundPayloadsForJson(payloads) {
2363
+ return normalizeReplyPayloadsForDelivery(payloads).map((payload) => ({
2364
+ text: payload.text ?? "",
2365
+ mediaUrl: payload.mediaUrl ?? null,
2366
+ mediaUrls: payload.mediaUrls ?? (payload.mediaUrl ? [payload.mediaUrl] : void 0),
2367
+ channelData: payload.channelData
2368
+ }));
2369
+ }
2370
+ function formatOutboundPayloadLog(payload) {
2371
+ const lines = [];
2372
+ if (payload.text) lines.push(payload.text.trimEnd());
2373
+ for (const url of payload.mediaUrls) lines.push(`MEDIA:${url}`);
2374
+ return lines.join("\n");
2375
+ }
2376
+
2377
+ //#endregion
2378
+ //#region src/infra/outbound/deliver.ts
2379
+ var deliver_exports = /* @__PURE__ */ __exportAll({ deliverOutboundPayloads: () => deliverOutboundPayloads });
2380
+ function throwIfAborted(abortSignal) {
2381
+ if (abortSignal?.aborted) throw new Error("Outbound delivery aborted");
2382
+ }
2383
+ async function createChannelHandler(params) {
2384
+ const outbound = await loadChannelOutboundAdapter(params.channel);
2385
+ if (!outbound?.sendText || !outbound?.sendMedia) throw new Error(`Outbound not configured for channel: ${params.channel}`);
2386
+ const handler = createPluginHandler({
2387
+ outbound,
2388
+ cfg: params.cfg,
2389
+ channel: params.channel,
2390
+ to: params.to,
2391
+ accountId: params.accountId,
2392
+ replyToId: params.replyToId,
2393
+ threadId: params.threadId,
2394
+ deps: params.deps,
2395
+ gifPlayback: params.gifPlayback
2396
+ });
2397
+ if (!handler) throw new Error(`Outbound not configured for channel: ${params.channel}`);
2398
+ return handler;
2399
+ }
2400
+ function createPluginHandler(params) {
2401
+ const outbound = params.outbound;
2402
+ if (!outbound?.sendText || !outbound?.sendMedia) return null;
2403
+ const sendText = outbound.sendText;
2404
+ const sendMedia = outbound.sendMedia;
2405
+ return {
2406
+ chunker: outbound.chunker ?? null,
2407
+ chunkerMode: outbound.chunkerMode,
2408
+ textChunkLimit: outbound.textChunkLimit,
2409
+ sendPayload: outbound.sendPayload ? async (payload) => outbound.sendPayload({
2410
+ cfg: params.cfg,
2411
+ to: params.to,
2412
+ text: payload.text ?? "",
2413
+ mediaUrl: payload.mediaUrl,
2414
+ accountId: params.accountId,
2415
+ replyToId: params.replyToId,
2416
+ threadId: params.threadId,
2417
+ gifPlayback: params.gifPlayback,
2418
+ deps: params.deps,
2419
+ payload
2420
+ }) : void 0,
2421
+ sendText: async (text) => sendText({
2422
+ cfg: params.cfg,
2423
+ to: params.to,
2424
+ text,
2425
+ accountId: params.accountId,
2426
+ replyToId: params.replyToId,
2427
+ threadId: params.threadId,
2428
+ gifPlayback: params.gifPlayback,
2429
+ deps: params.deps
2430
+ }),
2431
+ sendMedia: async (caption, mediaUrl) => sendMedia({
2432
+ cfg: params.cfg,
2433
+ to: params.to,
2434
+ text: caption,
2435
+ mediaUrl,
2436
+ accountId: params.accountId,
2437
+ replyToId: params.replyToId,
2438
+ threadId: params.threadId,
2439
+ gifPlayback: params.gifPlayback,
2440
+ deps: params.deps
2441
+ })
2442
+ };
2443
+ }
2444
+ async function deliverOutboundPayloads(params) {
2445
+ const { cfg, channel, to, payloads } = params;
2446
+ const accountId = params.accountId;
2447
+ const deps = params.deps;
2448
+ const abortSignal = params.abortSignal;
2449
+ const sendSignal = params.deps?.sendSignal ?? sendMessageSignal;
2450
+ const results = [];
2451
+ const handler = await createChannelHandler({
2452
+ cfg,
2453
+ channel,
2454
+ to,
2455
+ deps,
2456
+ accountId,
2457
+ replyToId: params.replyToId,
2458
+ threadId: params.threadId,
2459
+ gifPlayback: params.gifPlayback
2460
+ });
2461
+ const textLimit = handler.chunker ? resolveTextChunkLimit(cfg, channel, accountId, { fallbackLimit: handler.textChunkLimit }) : void 0;
2462
+ const chunkMode = handler.chunker ? resolveChunkMode(cfg, channel, accountId) : "length";
2463
+ const isSignalChannel = channel === "signal";
2464
+ const signalTableMode = isSignalChannel ? resolveMarkdownTableMode({
2465
+ cfg,
2466
+ channel: "signal",
2467
+ accountId
2468
+ }) : "code";
2469
+ const signalMaxBytes = isSignalChannel ? resolveChannelMediaMaxBytes({
2470
+ cfg,
2471
+ resolveChannelLimitMb: ({ cfg, accountId }) => cfg.channels?.signal?.accounts?.[accountId]?.mediaMaxMb ?? cfg.channels?.signal?.mediaMaxMb,
2472
+ accountId
2473
+ }) : void 0;
2474
+ const sendTextChunks = async (text) => {
2475
+ throwIfAborted(abortSignal);
2476
+ if (!handler.chunker || textLimit === void 0) {
2477
+ results.push(await handler.sendText(text));
2478
+ return;
2479
+ }
2480
+ if (chunkMode === "newline") {
2481
+ const blockChunks = (handler.chunkerMode ?? "text") === "markdown" ? chunkMarkdownTextWithMode(text, textLimit, "newline") : chunkByParagraph(text, textLimit);
2482
+ if (!blockChunks.length && text) blockChunks.push(text);
2483
+ for (const blockChunk of blockChunks) {
2484
+ const chunks = handler.chunker(blockChunk, textLimit);
2485
+ if (!chunks.length && blockChunk) chunks.push(blockChunk);
2486
+ for (const chunk of chunks) {
2487
+ throwIfAborted(abortSignal);
2488
+ results.push(await handler.sendText(chunk));
2489
+ }
2490
+ }
2491
+ return;
2492
+ }
2493
+ const chunks = handler.chunker(text, textLimit);
2494
+ for (const chunk of chunks) {
2495
+ throwIfAborted(abortSignal);
2496
+ results.push(await handler.sendText(chunk));
2497
+ }
2498
+ };
2499
+ const sendSignalText = async (text, styles) => {
2500
+ throwIfAborted(abortSignal);
2501
+ return {
2502
+ channel: "signal",
2503
+ ...await sendSignal(to, text, {
2504
+ maxBytes: signalMaxBytes,
2505
+ accountId: accountId ?? void 0,
2506
+ textMode: "plain",
2507
+ textStyles: styles
2508
+ })
2509
+ };
2510
+ };
2511
+ const sendSignalTextChunks = async (text) => {
2512
+ throwIfAborted(abortSignal);
2513
+ let signalChunks = textLimit === void 0 ? markdownToSignalTextChunks(text, Number.POSITIVE_INFINITY, { tableMode: signalTableMode }) : markdownToSignalTextChunks(text, textLimit, { tableMode: signalTableMode });
2514
+ if (signalChunks.length === 0 && text) signalChunks = [{
2515
+ text,
2516
+ styles: []
2517
+ }];
2518
+ for (const chunk of signalChunks) {
2519
+ throwIfAborted(abortSignal);
2520
+ results.push(await sendSignalText(chunk.text, chunk.styles));
2521
+ }
2522
+ };
2523
+ const sendSignalMedia = async (caption, mediaUrl) => {
2524
+ throwIfAborted(abortSignal);
2525
+ const formatted = markdownToSignalTextChunks(caption, Number.POSITIVE_INFINITY, { tableMode: signalTableMode })[0] ?? {
2526
+ text: caption,
2527
+ styles: []
2528
+ };
2529
+ return {
2530
+ channel: "signal",
2531
+ ...await sendSignal(to, formatted.text, {
2532
+ mediaUrl,
2533
+ maxBytes: signalMaxBytes,
2534
+ accountId: accountId ?? void 0,
2535
+ textMode: "plain",
2536
+ textStyles: formatted.styles
2537
+ })
2538
+ };
2539
+ };
2540
+ const normalizedPayloads = normalizeReplyPayloadsForDelivery(payloads);
2541
+ for (const payload of normalizedPayloads) {
2542
+ const payloadSummary = {
2543
+ text: payload.text ?? "",
2544
+ mediaUrls: payload.mediaUrls ?? (payload.mediaUrl ? [payload.mediaUrl] : []),
2545
+ channelData: payload.channelData
2546
+ };
2547
+ try {
2548
+ throwIfAborted(abortSignal);
2549
+ params.onPayload?.(payloadSummary);
2550
+ if (handler.sendPayload && payload.channelData) {
2551
+ results.push(await handler.sendPayload(payload));
2552
+ continue;
2553
+ }
2554
+ if (payloadSummary.mediaUrls.length === 0) {
2555
+ if (isSignalChannel) await sendSignalTextChunks(payloadSummary.text);
2556
+ else await sendTextChunks(payloadSummary.text);
2557
+ continue;
2558
+ }
2559
+ let first = true;
2560
+ for (const url of payloadSummary.mediaUrls) {
2561
+ throwIfAborted(abortSignal);
2562
+ const caption = first ? payloadSummary.text : "";
2563
+ first = false;
2564
+ if (isSignalChannel) results.push(await sendSignalMedia(caption, url));
2565
+ else results.push(await handler.sendMedia(caption, url));
2566
+ }
2567
+ } catch (err) {
2568
+ if (!params.bestEffort) throw err;
2569
+ params.onError?.(err, payloadSummary);
2570
+ }
2571
+ }
2572
+ if (params.mirror && results.length > 0) {
2573
+ const mirrorText = resolveMirroredTranscriptText({
2574
+ text: params.mirror.text,
2575
+ mediaUrls: params.mirror.mediaUrls
2576
+ });
2577
+ if (mirrorText) await appendAssistantMessageToSessionTranscript({
2578
+ agentId: params.mirror.agentId,
2579
+ sessionKey: params.mirror.sessionKey,
2580
+ text: mirrorText
2581
+ });
2582
+ }
2583
+ return results;
2584
+ }
2585
+
2586
+ //#endregion
2587
+ export { markdownToIRWithMeta as A, resolveTextChunkLimit as B, signalCheck as C, wrapFetchWithAbortSignal as D, resolveFetch as E, chunkMarkdownText as F, SILENT_REPLY_TOKEN as G, isSafeFenceBreak as H, chunkMarkdownTextWithMode as I, fetchRemoteMedia as J, isSilentReplyText as K, chunkText as L, loadWebMediaRaw as M, resolveMarkdownTableMode as N, chunkMarkdownIR as O, chunkByNewline as P, chunkTextWithMode as R, sendTypingSignal as S, streamSignalEvents as T, parseFenceSpans as U, findFenceSpanAt as V, HEARTBEAT_TOKEN as W, fetchWithSsrFGuard as Y, parseReplyDirectives as _, normalizeOutboundPayloadsForJson as a, sendMessageSignal as b, applyReplyThreading as c, shouldSuppressMessagingToolReplies as d, createReplyToModeFilterForChannel as f, normalizeTargetForProvider as g, normalizeChannelTargetInput as h, normalizeOutboundPayloads as i, loadWebMedia as j, markdownToIR as k, filterMessagingToolDuplicates as l, buildTargetResolverSignature as m, deliver_exports as n, normalizeReplyPayloadsForDelivery as o, resolveReplyToMode as p, MediaFetchError as q, formatOutboundPayloadLog as r, applyReplyTagsToPayload as s, deliverOutboundPayloads as t, isRenderablePayload as u, splitMediaFromOutput as v, signalRpcRequest as w, sendReadReceiptSignal as x, parseInlineDirectives as y, resolveChunkMode as z };