@guadskill/openclaw-proxy 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 (1732) hide show
  1. package/CHANGELOG.md +1573 -0
  2. package/LICENSE +21 -0
  3. package/README-header.png +0 -0
  4. package/README.md +544 -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-Bslzkc7p.js +926 -0
  20. package/dist/acp-cli-BzMBTZq1.js +923 -0
  21. package/dist/agent-B20ZAlPq.js +700 -0
  22. package/dist/agent-C6oB1C7Q.js +700 -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-BRhJgzXf.js +85 -0
  27. package/dist/archive-ccN9aDgq.js +85 -0
  28. package/dist/audit-DM36chrb.js +1852 -0
  29. package/dist/audit-FONb40op.js +1852 -0
  30. package/dist/auth-BpEOJZNM.js +192 -0
  31. package/dist/auth-health-TxjASTBn.js +149 -0
  32. package/dist/auth-health-iSVoRZJo.js +149 -0
  33. package/dist/auth-nnRYiqpH.js +192 -0
  34. package/dist/auth-profiles-CvXmOJ7i.js +2937 -0
  35. package/dist/boolean-Wzu0-e0P.js +30 -0
  36. package/dist/brew-DyBGNK8A.js +46 -0
  37. package/dist/brew-pE1HlyB8.js +46 -0
  38. package/dist/build-info.json +5 -0
  39. package/dist/call-8orFRlzD.js +278 -0
  40. package/dist/call-HmkY2Og0.js +278 -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-BxaoxlLY.js +32 -0
  45. package/dist/channel-options-CGuly8Kg.js +62 -0
  46. package/dist/channel-selection-BWwIiYxA.js +51 -0
  47. package/dist/channel-selection-DnMbJBwK.js +51 -0
  48. package/dist/channel-summary-BvUzkAtV.js +1154 -0
  49. package/dist/channel-summary-CJK-YnpL.js +1154 -0
  50. package/dist/channels-cli-CM1kVis1.js +1412 -0
  51. package/dist/channels-cli-CTlZwvwc.js +1414 -0
  52. package/dist/channels-status-issues-DfeplQer.js +18 -0
  53. package/dist/channels-status-issues-ssvYlSeV.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-DL4_d-3B.js +92 -0
  58. package/dist/cli/daemon-cli.js +2 -0
  59. package/dist/cli-DO2o1szx.js +89 -0
  60. package/dist/cli-DsHfoV34.js +86 -0
  61. package/dist/cli-utils-BkRQdAoC.js +43 -0
  62. package/dist/cli-utils-D2NrEoOM.js +43 -0
  63. package/dist/client-B6l_NSED.js +1609 -0
  64. package/dist/client-CBaY9GLK.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-DQONlSAJ.js +33 -0
  69. package/dist/commands-BfzmpQgG.js +229 -0
  70. package/dist/completion-cli-DJFm8nL6.js +434 -0
  71. package/dist/completion-cli-iU8FQxNX.js +773 -0
  72. package/dist/config-BNDgPGKU.js +4898 -0
  73. package/dist/config-Cl0qV63v.js +5640 -0
  74. package/dist/config-guard-DumiN0l-.js +5752 -0
  75. package/dist/config-hfzHFLcB.js +4899 -0
  76. package/dist/configure-BE0S7d0e.js +895 -0
  77. package/dist/configure-CNtWsnCY.js +896 -0
  78. package/dist/constants-BwSEqbCV.js +65 -0
  79. package/dist/constants-D1op9uGI.js +65 -0
  80. package/dist/control-service-B08kuW3q.js +61 -0
  81. package/dist/control-service-DB9k683J.js +61 -0
  82. package/dist/control-ui/apple-touch-icon.png +0 -0
  83. package/dist/control-ui/assets/index-BoXosYY6.css +1 -0
  84. package/dist/control-ui/assets/index-CTtQ0yWI.js +4585 -0
  85. package/dist/control-ui/assets/index-CTtQ0yWI.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-B-TPicN5.js +453 -0
  91. package/dist/cron-cli-KBjJ7UC0.js +456 -0
  92. package/dist/daemon-cli-2YS_h4NB.js +761 -0
  93. package/dist/daemon-cli-B3wzJJRD.js +760 -0
  94. package/dist/daemon-runtime-Cpz5kXBh.js +460 -0
  95. package/dist/daemon-runtime-DCL2NSog.js +460 -0
  96. package/dist/deliver-B2kB-lvv.js +2557 -0
  97. package/dist/deliver-BJ16ioKR.js +2545 -0
  98. package/dist/deliver-CTAU2Lsl.js +2545 -0
  99. package/dist/deps-CfB_dTjF.js +27 -0
  100. package/dist/deps-Csz0wi5R.js +27 -0
  101. package/dist/devices-cli-CVi-8CzD.js +207 -0
  102. package/dist/devices-cli-jOQsjZDH.js +204 -0
  103. package/dist/directory-cli-Deru7wk3.js +247 -0
  104. package/dist/directory-cli-bNH5-BVN.js +244 -0
  105. package/dist/dispatcher-TNQCvlrC.js +160 -0
  106. package/dist/dns-cli-C2unpGnO.js +201 -0
  107. package/dist/dns-cli-CICc3UCV.js +198 -0
  108. package/dist/docs-cli-D6jhnbl-.js +159 -0
  109. package/dist/docs-cli-DV4dtZuW.js +161 -0
  110. package/dist/doctor-BdMh4FQ7.js +2586 -0
  111. package/dist/doctor-Dac1oots.js +2584 -0
  112. package/dist/entry.js +1330 -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-BvZBpCaF.js +1043 -0
  119. package/dist/exec-approvals-BxNysSke.js +1043 -0
  120. package/dist/exec-approvals-cli-CgMFSqMo.js +385 -0
  121. package/dist/exec-approvals-cli-Dtiu-o66.js +388 -0
  122. package/dist/extensionAPI.js +67199 -0
  123. package/dist/fetch-CcCleeU3.js +44 -0
  124. package/dist/fetch-a2WIvOW7.js +44 -0
  125. package/dist/format-BgR4sIly.js +34 -0
  126. package/dist/format-tlvh4-cQ.js +34 -0
  127. package/dist/gateway-cli-CW6pFvMo.js +16934 -0
  128. package/dist/gateway-cli-CaPPMciY.js +16935 -0
  129. package/dist/gateway-rpc-FzvIp9rt.js +28 -0
  130. package/dist/gateway-rpc-St1jAOcL.js +28 -0
  131. package/dist/github-copilot-auth-Lsi_w3ly.js +1189 -0
  132. package/dist/github-copilot-auth-w5X7lOri.js +1189 -0
  133. package/dist/github-copilot-token-B3SA95yo.js +103 -0
  134. package/dist/github-copilot-token-C8XFYz0i.js +103 -0
  135. package/dist/github-copilot-token-CnxakiSC.js +103 -0
  136. package/dist/gmail-setup-utils-DaIfgRFK.js +428 -0
  137. package/dist/gmail-setup-utils-DgiUqBKC.js +428 -0
  138. package/dist/health-format-_ZnCrN3w.js +1211 -0
  139. package/dist/health-format-u34MPaDj.js +1210 -0
  140. package/dist/help-format-BlaVZH29.js +17 -0
  141. package/dist/help-format-CfZ94KRN.js +17 -0
  142. package/dist/helpers-BiyEksaK.js +25 -0
  143. package/dist/helpers-C12w9zxf.js +10 -0
  144. package/dist/helpers-CbjwQEou.js +25 -0
  145. package/dist/helpers-D37DRpCZ.js +10 -0
  146. package/dist/hooks/bundled/boot-md/HOOK.md +19 -0
  147. package/dist/hooks/bundled/command-logger/HOOK.md +122 -0
  148. package/dist/hooks/bundled/session-memory/HOOK.md +109 -0
  149. package/dist/hooks/bundled/soul-evil/HOOK.md +71 -0
  150. package/dist/hooks-cli-B6KpLq7n.js +1058 -0
  151. package/dist/hooks-cli-BEcZ1djY.js +1061 -0
  152. package/dist/hooks-status-Bz2z9WxH.js +443 -0
  153. package/dist/hooks-status-JZCCkoAJ.js +443 -0
  154. package/dist/image-4YNIgY-_.js +1421 -0
  155. package/dist/image-DHat2qLh.js +629 -0
  156. package/dist/image-DzJBIV0I.js +629 -0
  157. package/dist/index.js +5936 -0
  158. package/dist/installs-C0Xjvfhf.js +425 -0
  159. package/dist/installs-DOAiYAqW.js +425 -0
  160. package/dist/is-main-DMohpoM9.js +25 -0
  161. package/dist/is-main-PYGa3tDA.js +25 -0
  162. package/dist/links-B4nk2iDf.js +15 -0
  163. package/dist/links-B5pRdmo1.js +15 -0
  164. package/dist/loader-BL29rrWH.js +64272 -0
  165. package/dist/logging-6zx7VGt-.js +15 -0
  166. package/dist/logging-BuJAMSjm.js +15 -0
  167. package/dist/logging-CY-Q5cwf.js +1 -0
  168. package/dist/logging-pqyrk15z.js +1 -0
  169. package/dist/login-qr-BxE22mru.js +475 -0
  170. package/dist/login-qr-D1apt7XW.js +478 -0
  171. package/dist/login-qr-EVccyUKT.js +478 -0
  172. package/dist/logs-cli-ByJNFJRZ.js +230 -0
  173. package/dist/logs-cli-C3XkZdMo.js +227 -0
  174. package/dist/manager-C4ILl-d3.js +2870 -0
  175. package/dist/manager-CAjzs8zZ.js +2870 -0
  176. package/dist/manager-DSKsNxD0.js +2872 -0
  177. package/dist/manifest-registry-Bwjq9Iev.js +668 -0
  178. package/dist/manifest-registry-D2Yntqcb.js +668 -0
  179. package/dist/message-channel-B8sq-ATS.js +110 -0
  180. package/dist/message-channel-CQ6DgRUw.js +110 -0
  181. package/dist/model-selection-BlR8RpVg.js +2939 -0
  182. package/dist/model-selection-mzTqrNoj.js +2691 -0
  183. package/dist/models-cli-BCmJaSiT.js +2544 -0
  184. package/dist/models-cli-BpDnCgsE.js +2541 -0
  185. package/dist/net-Cb7aIE0d.js +137 -0
  186. package/dist/net-DKJPqXuW.js +137 -0
  187. package/dist/node-cli-B8YjPAwG.js +1456 -0
  188. package/dist/node-cli-CEhBhWXG.js +1459 -0
  189. package/dist/node-service-C0voAvkx.js +67 -0
  190. package/dist/node-service-Cl1tk1LE.js +67 -0
  191. package/dist/nodes-cli-2ED0s8IX.js +1207 -0
  192. package/dist/nodes-cli-Br0tbTmz.js +1210 -0
  193. package/dist/nodes-screen-D3Sc9uSV.js +157 -0
  194. package/dist/nodes-screen-DtXuFQdk.js +157 -0
  195. package/dist/note-DLYOWdeB.js +73 -0
  196. package/dist/note-_C44YfAQ.js +73 -0
  197. package/dist/onboard-channels-CHz0pcOF.js +670 -0
  198. package/dist/onboard-channels-ChUCLsjA.js +670 -0
  199. package/dist/onboard-skills-D9ClIyDs.js +3546 -0
  200. package/dist/onboard-skills-inA2uKre.js +3546 -0
  201. package/dist/onboarding-B8Tw755f.js +3271 -0
  202. package/dist/openclaw-root-9ILYSmJ9.js +84 -0
  203. package/dist/openclaw-root-Cvotktkd.js +84 -0
  204. package/dist/pairing-cli-BDQoD24i.js +117 -0
  205. package/dist/pairing-cli-DZTystii.js +114 -0
  206. package/dist/pairing-labels-EjeFHyx0.js +9 -0
  207. package/dist/pairing-labels-mgB0IlYv.js +9 -0
  208. package/dist/pairing-store-9odwlfpf.js +391 -0
  209. package/dist/pairing-store-DZhxkFBw.js +391 -0
  210. package/dist/parse-DbH9TEJ1.js +23 -0
  211. package/dist/parse-DqAvJRIf.js +23 -0
  212. package/dist/parse-log-line-BxDgv4Uo.js +44 -0
  213. package/dist/parse-log-line-Dg-RjsyO.js +44 -0
  214. package/dist/parse-timeout-BndZ8KMO.js +16 -0
  215. package/dist/parse-timeout-DFSPLxpY.js +16 -0
  216. package/dist/path-env-D0zha4n7.js +77 -0
  217. package/dist/path-env-DEj4CiFN.js +77 -0
  218. package/dist/paths-B-q1nXdY.js +43 -0
  219. package/dist/paths-B1kfl4h5.js +164 -0
  220. package/dist/paths-B4kigINg.js +40 -0
  221. package/dist/paths-BlKGresh.js +43 -0
  222. package/dist/paths-scjhy7N2.js +180 -0
  223. package/dist/pi-embedded-helpers-Bc28x5wO.js +1298 -0
  224. package/dist/pi-embedded-helpers-D6XTIi2t.js +1298 -0
  225. package/dist/pi-embedded-helpers-qgoWGXt5.js +8475 -0
  226. package/dist/pi-model-discovery-B6CsmK6Y.js +20 -0
  227. package/dist/pi-model-discovery-DsRqYJLy.js +20 -0
  228. package/dist/pi-model-discovery-EhM2JAQo.js +20 -0
  229. package/dist/pi-tools.policy-BM1uYSYK.js +229 -0
  230. package/dist/plugin-auto-enable-CT0GLtRB.js +461 -0
  231. package/dist/plugin-auto-enable-Gq-Hco1V.js +461 -0
  232. package/dist/plugin-sdk/index.d.ts +8854 -0
  233. package/dist/plugin-sdk/index.js +24301 -0
  234. package/dist/plugin-sdk/pi-model-discovery-Dw3A6oXH.js +37 -0
  235. package/dist/plugins-C3Bm-HQV.js +494 -0
  236. package/dist/plugins-QJjTXliB.js +495 -0
  237. package/dist/plugins-cli-CD3qOzIc.js +441 -0
  238. package/dist/plugins-cli-CI0jwJ23.js +444 -0
  239. package/dist/ports-DsQlpea1.js +96 -0
  240. package/dist/program-yfwD40IH.js +192 -0
  241. package/dist/progress-Bcjniu7m.js +133 -0
  242. package/dist/progress-xpLtQsNY.js +133 -0
  243. package/dist/prompt-style-CFsleyxV.js +9 -0
  244. package/dist/prompt-style-vzh0MGHs.js +9 -0
  245. package/dist/prompts-CudpZgTI.js +10 -0
  246. package/dist/prompts-Drly230e.js +10 -0
  247. package/dist/proxy-fetch-Y5wGyQ3j.js +53 -0
  248. package/dist/proxy-fetch-_AVgCPth.js +53 -0
  249. package/dist/pw-ai-08F3GD-3.js +1649 -0
  250. package/dist/pw-ai-BiJd1PM1.js +1651 -0
  251. package/dist/pw-ai-tNPuRNn3.js +1649 -0
  252. package/dist/qmd-manager-BqkNpRLl.js +617 -0
  253. package/dist/qmd-manager-CF52nuBg.js +615 -0
  254. package/dist/qmd-manager-DQrW_IJO.js +616 -0
  255. package/dist/redact-BIMJ3ntQ.js +94 -0
  256. package/dist/redact-Bt-krp_b.js +97 -0
  257. package/dist/redact-KzWHRS5J.js +97 -0
  258. package/dist/register.subclis-Bh09soRX.js +348 -0
  259. package/dist/reply-Bd8FvjsB.js +64275 -0
  260. package/dist/restart-sentinel-0jZiP6wa.js +65 -0
  261. package/dist/restart-sentinel-BfNkhRcY.js +65 -0
  262. package/dist/rolldown-runtime-Cbj13DAv.js +20 -0
  263. package/dist/routes-BM_KybLk.js +2410 -0
  264. package/dist/routes-DW4Wu2jw.js +2410 -0
  265. package/dist/rpc-DCfTOgsV.js +95 -0
  266. package/dist/rpc-xptVI4aX.js +95 -0
  267. package/dist/run-main-BDjv9pg0.js +196 -0
  268. package/dist/runtime-guard-3G4IRfJ2.js +60 -0
  269. package/dist/runtime-guard-83TpoNmK.js +60 -0
  270. package/dist/sandbox-CUP2w5rn.js +2943 -0
  271. package/dist/sandbox-CudnqybF.js +2944 -0
  272. package/dist/sandbox-cli-BpbWFbKA.js +462 -0
  273. package/dist/sandbox-cli-L_UvQieX.js +459 -0
  274. package/dist/security-cli-BDw18wWm.js +504 -0
  275. package/dist/security-cli-CSheoOJ9.js +507 -0
  276. package/dist/server-context-BFH7HB_M.js +740 -0
  277. package/dist/server-context-cZ1L3VL8.js +740 -0
  278. package/dist/server-node-events-Csw2mwVU.js +215 -0
  279. package/dist/server-node-events-S70f4mOe.js +218 -0
  280. package/dist/service-B1GsXJaa.js +859 -0
  281. package/dist/service-BeVe7-_W.js +859 -0
  282. package/dist/service-audit-CgT8PF6a.js +542 -0
  283. package/dist/service-audit-D2MqRzJ6.js +542 -0
  284. package/dist/shared-BpcIsygQ.js +74 -0
  285. package/dist/shared-C4ID2bDG.js +74 -0
  286. package/dist/shared-D0vX4-Vw.js +150 -0
  287. package/dist/shared-D7q29LDD.js +150 -0
  288. package/dist/skill-scanner-COatt01v.js +255 -0
  289. package/dist/skill-scanner-D75vg4aF.js +255 -0
  290. package/dist/skills-BMyDQ-63.js +693 -0
  291. package/dist/skills-Tky2kCMO.js +694 -0
  292. package/dist/skills-cli-CKs5zc-y.js +287 -0
  293. package/dist/skills-cli-VpE6OBOn.js +290 -0
  294. package/dist/skills-status-C4pCFdXL.js +187 -0
  295. package/dist/skills-status-Ca3rn_Ir.js +187 -0
  296. package/dist/sqlite-BS0q--MG.js +197 -0
  297. package/dist/sqlite-Dnmf3LS7.js +215 -0
  298. package/dist/sqlite-QDf0yuU0.js +215 -0
  299. package/dist/status-BqtiImKF.js +21 -0
  300. package/dist/status-CD2PjMdD.js +21 -0
  301. package/dist/status-CT09OZrt.js +27 -0
  302. package/dist/status-ChVEOKZu.js +3179 -0
  303. package/dist/status-DtvGB1uS.js +27 -0
  304. package/dist/status.update-9fYSKqax.js +79 -0
  305. package/dist/status.update-B7lcxLT1.js +79 -0
  306. package/dist/subsystem-CAq3uyo7.js +834 -0
  307. package/dist/system-cli-CWVJgwZk.js +83 -0
  308. package/dist/system-cli-zT4ISi7G.js +80 -0
  309. package/dist/systemd-DeSLoJgE.js +438 -0
  310. package/dist/systemd-hints-3-E4ndGf.js +19 -0
  311. package/dist/systemd-hints-Ct78rpa1.js +19 -0
  312. package/dist/systemd-linger-Cd6P7vEV.js +75 -0
  313. package/dist/systemd-linger-DC9yGjen.js +75 -0
  314. package/dist/systemd-x41DoAVw.js +438 -0
  315. package/dist/table-BGYjbJbA.js +279 -0
  316. package/dist/table-DTx1GQy4.js +279 -0
  317. package/dist/tailnet-Bg_vE5qi.js +42 -0
  318. package/dist/tailnet-CrNWlQRJ.js +42 -0
  319. package/dist/tailscale-B6H8NmyN.js +252 -0
  320. package/dist/tailscale-DCnMs7_q.js +225 -0
  321. package/dist/tool-display-BEACy9rK.js +795 -0
  322. package/dist/tool-display-PgbqPY5M.js +795 -0
  323. package/dist/transcript-events-Bv_eRVym.js +17 -0
  324. package/dist/transcript-events-CsB1Saa6.js +17 -0
  325. package/dist/transcript-events-JLH5W4He.js +17 -0
  326. package/dist/tui-CEMsOJ2R.js +2669 -0
  327. package/dist/tui-HBCUFvqd.js +2670 -0
  328. package/dist/tui-cli-BJHaKh4i.js +55 -0
  329. package/dist/tui-cli-CSXxe8zT.js +58 -0
  330. package/dist/update-B4_d8CFN.js +317 -0
  331. package/dist/update-BadBiZRo.js +317 -0
  332. package/dist/update-cli-DUx5iNuh.js +990 -0
  333. package/dist/update-cli-eqUw2bP0.js +988 -0
  334. package/dist/update-runner-C6CdBo-h.js +1310 -0
  335. package/dist/update-runner-zrM-LkXQ.js +1310 -0
  336. package/dist/utils-CKSrBNwq.js +192 -0
  337. package/dist/utils-DX85MiPR.js +188 -0
  338. package/dist/webhooks-cli-C8WVG2ja.js +309 -0
  339. package/dist/webhooks-cli-DkqThM7-.js +312 -0
  340. package/dist/widearea-dns-D9Al4QRv.js +127 -0
  341. package/dist/widearea-dns-DDNQMGyz.js +127 -0
  342. package/dist/ws-3zr8WUwL.js +13 -0
  343. package/dist/ws-log-C7XrTO_G.js +267 -0
  344. package/dist/ws-log-DjH95yNf.js +267 -0
  345. package/dist/ws-lzrgabja.js +13 -0
  346. package/dist/wsl-VVr_6ZkA.js +160 -0
  347. package/docs/.i18n/README.md +31 -0
  348. package/docs/.i18n/glossary.zh-CN.json +210 -0
  349. package/docs/.i18n/zh-CN.tm.jsonl +1329 -0
  350. package/docs/CNAME +1 -0
  351. package/docs/assets/macos-onboarding/01-macos-warning.jpeg +0 -0
  352. package/docs/assets/macos-onboarding/02-local-networks.jpeg +0 -0
  353. package/docs/assets/macos-onboarding/03-security-notice.png +0 -0
  354. package/docs/assets/macos-onboarding/04-choose-gateway.png +0 -0
  355. package/docs/assets/macos-onboarding/05-permissions.png +0 -0
  356. package/docs/assets/openclaw-logo-text-dark.png +0 -0
  357. package/docs/assets/openclaw-logo-text.png +0 -0
  358. package/docs/assets/pixel-lobster.svg +60 -0
  359. package/docs/assets/showcase/agents-ui.jpg +0 -0
  360. package/docs/assets/showcase/bambu-cli.png +0 -0
  361. package/docs/assets/showcase/codexmonitor.png +0 -0
  362. package/docs/assets/showcase/gohome-grafana.png +0 -0
  363. package/docs/assets/showcase/ios-testflight.jpg +0 -0
  364. package/docs/assets/showcase/oura-health.png +0 -0
  365. package/docs/assets/showcase/padel-cli.svg +11 -0
  366. package/docs/assets/showcase/padel-screenshot.jpg +0 -0
  367. package/docs/assets/showcase/papla-tts.jpg +0 -0
  368. package/docs/assets/showcase/pr-review-telegram.jpg +0 -0
  369. package/docs/assets/showcase/roborock-screenshot.jpg +0 -0
  370. package/docs/assets/showcase/roborock-status.svg +13 -0
  371. package/docs/assets/showcase/roof-camera-sky.jpg +0 -0
  372. package/docs/assets/showcase/snag.png +0 -0
  373. package/docs/assets/showcase/tesco-shop.jpg +0 -0
  374. package/docs/assets/showcase/wienerlinien.png +0 -0
  375. package/docs/assets/showcase/wine-cellar-skill.jpg +0 -0
  376. package/docs/assets/showcase/winix-air-purifier.jpg +0 -0
  377. package/docs/assets/showcase/xuezh-pronunciation.jpeg +0 -0
  378. package/docs/automation/auth-monitoring.md +44 -0
  379. package/docs/automation/cron-jobs.md +468 -0
  380. package/docs/automation/cron-vs-heartbeat.md +282 -0
  381. package/docs/automation/gmail-pubsub.md +256 -0
  382. package/docs/automation/poll.md +69 -0
  383. package/docs/automation/webhook.md +163 -0
  384. package/docs/bedrock.md +176 -0
  385. package/docs/brave-search.md +41 -0
  386. package/docs/broadcast-groups.md +442 -0
  387. package/docs/channels/bluebubbles.md +338 -0
  388. package/docs/channels/discord.md +476 -0
  389. package/docs/channels/feishu.md +577 -0
  390. package/docs/channels/googlechat.md +250 -0
  391. package/docs/channels/grammy.md +31 -0
  392. package/docs/channels/imessage.md +299 -0
  393. package/docs/channels/index.md +46 -0
  394. package/docs/channels/line.md +186 -0
  395. package/docs/channels/location.md +56 -0
  396. package/docs/channels/matrix.md +233 -0
  397. package/docs/channels/mattermost.md +138 -0
  398. package/docs/channels/msteams.md +768 -0
  399. package/docs/channels/nextcloud-talk.md +136 -0
  400. package/docs/channels/nostr.md +233 -0
  401. package/docs/channels/signal.md +202 -0
  402. package/docs/channels/slack.md +548 -0
  403. package/docs/channels/telegram.md +769 -0
  404. package/docs/channels/tlon.md +132 -0
  405. package/docs/channels/troubleshooting.md +29 -0
  406. package/docs/channels/twitch.md +379 -0
  407. package/docs/channels/whatsapp.md +404 -0
  408. package/docs/channels/zalo.md +189 -0
  409. package/docs/channels/zalouser.md +140 -0
  410. package/docs/cli/acp.md +170 -0
  411. package/docs/cli/agent.md +24 -0
  412. package/docs/cli/agents.md +75 -0
  413. package/docs/cli/approvals.md +50 -0
  414. package/docs/cli/browser.md +107 -0
  415. package/docs/cli/channels.md +79 -0
  416. package/docs/cli/config.md +50 -0
  417. package/docs/cli/configure.md +33 -0
  418. package/docs/cli/cron.md +42 -0
  419. package/docs/cli/dashboard.md +16 -0
  420. package/docs/cli/devices.md +70 -0
  421. package/docs/cli/directory.md +63 -0
  422. package/docs/cli/dns.md +23 -0
  423. package/docs/cli/docs.md +15 -0
  424. package/docs/cli/doctor.md +41 -0
  425. package/docs/cli/gateway.md +202 -0
  426. package/docs/cli/health.md +21 -0
  427. package/docs/cli/hooks.md +304 -0
  428. package/docs/cli/index.md +1031 -0
  429. package/docs/cli/logs.md +24 -0
  430. package/docs/cli/memory.md +45 -0
  431. package/docs/cli/message.md +239 -0
  432. package/docs/cli/models.md +79 -0
  433. package/docs/cli/node.md +112 -0
  434. package/docs/cli/nodes.md +73 -0
  435. package/docs/cli/onboard.md +43 -0
  436. package/docs/cli/pairing.md +21 -0
  437. package/docs/cli/plugins.md +62 -0
  438. package/docs/cli/reset.md +17 -0
  439. package/docs/cli/sandbox.md +152 -0
  440. package/docs/cli/security.md +26 -0
  441. package/docs/cli/sessions.md +16 -0
  442. package/docs/cli/setup.md +29 -0
  443. package/docs/cli/skills.md +26 -0
  444. package/docs/cli/status.md +26 -0
  445. package/docs/cli/system.md +60 -0
  446. package/docs/cli/tui.md +23 -0
  447. package/docs/cli/uninstall.md +17 -0
  448. package/docs/cli/update.md +98 -0
  449. package/docs/cli/voicecall.md +34 -0
  450. package/docs/cli/webhooks.md +25 -0
  451. package/docs/concepts/agent-loop.md +146 -0
  452. package/docs/concepts/agent-workspace.md +233 -0
  453. package/docs/concepts/agent.md +123 -0
  454. package/docs/concepts/architecture.md +129 -0
  455. package/docs/concepts/channel-routing.md +114 -0
  456. package/docs/concepts/compaction.md +61 -0
  457. package/docs/concepts/context.md +161 -0
  458. package/docs/concepts/features.md +53 -0
  459. package/docs/concepts/group-messages.md +84 -0
  460. package/docs/concepts/groups.md +373 -0
  461. package/docs/concepts/markdown-formatting.md +130 -0
  462. package/docs/concepts/memory.md +546 -0
  463. package/docs/concepts/messages.md +154 -0
  464. package/docs/concepts/model-failover.md +149 -0
  465. package/docs/concepts/model-providers.md +316 -0
  466. package/docs/concepts/models.md +208 -0
  467. package/docs/concepts/multi-agent.md +376 -0
  468. package/docs/concepts/oauth.md +145 -0
  469. package/docs/concepts/presence.md +102 -0
  470. package/docs/concepts/queue.md +89 -0
  471. package/docs/concepts/retry.md +69 -0
  472. package/docs/concepts/session-pruning.md +122 -0
  473. package/docs/concepts/session-tool.md +193 -0
  474. package/docs/concepts/session.md +204 -0
  475. package/docs/concepts/sessions.md +10 -0
  476. package/docs/concepts/streaming.md +135 -0
  477. package/docs/concepts/system-prompt.md +115 -0
  478. package/docs/concepts/timezone.md +91 -0
  479. package/docs/concepts/typebox.md +289 -0
  480. package/docs/concepts/typing-indicators.md +68 -0
  481. package/docs/concepts/usage-tracking.md +35 -0
  482. package/docs/date-time.md +128 -0
  483. package/docs/debug/node-issue.md +83 -0
  484. package/docs/debugging.md +162 -0
  485. package/docs/diagnostics/flags.md +91 -0
  486. package/docs/docs.json +1736 -0
  487. package/docs/environment.md +81 -0
  488. package/docs/experiments/onboarding-config-protocol.md +40 -0
  489. package/docs/experiments/plans/cron-add-hardening.md +63 -0
  490. package/docs/experiments/plans/group-policy-hardening.md +40 -0
  491. package/docs/experiments/plans/openresponses-gateway.md +123 -0
  492. package/docs/experiments/proposals/model-config.md +36 -0
  493. package/docs/experiments/research/memory.md +228 -0
  494. package/docs/gateway/authentication.md +145 -0
  495. package/docs/gateway/background-process.md +93 -0
  496. package/docs/gateway/bonjour.md +167 -0
  497. package/docs/gateway/bridge-protocol.md +89 -0
  498. package/docs/gateway/cli-backends.md +225 -0
  499. package/docs/gateway/configuration-examples.md +606 -0
  500. package/docs/gateway/configuration.md +3411 -0
  501. package/docs/gateway/discovery.md +116 -0
  502. package/docs/gateway/doctor.md +282 -0
  503. package/docs/gateway/gateway-lock.md +34 -0
  504. package/docs/gateway/health.md +35 -0
  505. package/docs/gateway/heartbeat.md +362 -0
  506. package/docs/gateway/index.md +328 -0
  507. package/docs/gateway/local-models.md +150 -0
  508. package/docs/gateway/logging.md +113 -0
  509. package/docs/gateway/multiple-gateways.md +112 -0
  510. package/docs/gateway/network-model.md +17 -0
  511. package/docs/gateway/openai-http-api.md +118 -0
  512. package/docs/gateway/openresponses-http-api.md +317 -0
  513. package/docs/gateway/pairing.md +99 -0
  514. package/docs/gateway/protocol.md +221 -0
  515. package/docs/gateway/remote-gateway-readme.md +157 -0
  516. package/docs/gateway/remote.md +129 -0
  517. package/docs/gateway/sandbox-vs-tool-policy-vs-elevated.md +128 -0
  518. package/docs/gateway/sandboxing.md +193 -0
  519. package/docs/gateway/security/formal-verification.md +164 -0
  520. package/docs/gateway/security/index.md +825 -0
  521. package/docs/gateway/tailscale.md +127 -0
  522. package/docs/gateway/tools-invoke-http-api.md +85 -0
  523. package/docs/gateway/troubleshooting.md +767 -0
  524. package/docs/help/faq.md +2829 -0
  525. package/docs/help/index.md +21 -0
  526. package/docs/help/troubleshooting.md +98 -0
  527. package/docs/hooks/soul-evil.md +69 -0
  528. package/docs/hooks.md +913 -0
  529. package/docs/images/feishu-step2-create-app.png +0 -0
  530. package/docs/images/feishu-step3-credentials.png +0 -0
  531. package/docs/images/feishu-step4-permissions.png +0 -0
  532. package/docs/images/feishu-step5-bot-capability.png +0 -0
  533. package/docs/images/feishu-step6-event-subscription.png +0 -0
  534. package/docs/images/groups-flow.svg +52 -0
  535. package/docs/images/mobile-ui-screenshot.png +0 -0
  536. package/docs/index.md +192 -0
  537. package/docs/install/ansible.md +208 -0
  538. package/docs/install/bun.md +59 -0
  539. package/docs/install/development-channels.md +75 -0
  540. package/docs/install/docker.md +567 -0
  541. package/docs/install/exe-dev.md +126 -0
  542. package/docs/install/fly.md +486 -0
  543. package/docs/install/gcp.md +503 -0
  544. package/docs/install/hetzner.md +330 -0
  545. package/docs/install/index.md +187 -0
  546. package/docs/install/installer.md +123 -0
  547. package/docs/install/macos-vm.md +281 -0
  548. package/docs/install/migrating.md +192 -0
  549. package/docs/install/nix.md +96 -0
  550. package/docs/install/node.md +78 -0
  551. package/docs/install/northflank.mdx +53 -0
  552. package/docs/install/railway.mdx +99 -0
  553. package/docs/install/render.mdx +165 -0
  554. package/docs/install/uninstall.md +128 -0
  555. package/docs/install/updating.md +228 -0
  556. package/docs/logging.md +350 -0
  557. package/docs/multi-agent-sandbox-tools.md +395 -0
  558. package/docs/network.md +54 -0
  559. package/docs/nodes/audio.md +114 -0
  560. package/docs/nodes/camera.md +156 -0
  561. package/docs/nodes/images.md +72 -0
  562. package/docs/nodes/index.md +341 -0
  563. package/docs/nodes/location-command.md +113 -0
  564. package/docs/nodes/media-understanding.md +379 -0
  565. package/docs/nodes/talk.md +90 -0
  566. package/docs/nodes/voicewake.md +65 -0
  567. package/docs/perplexity.md +80 -0
  568. package/docs/pi-dev.md +70 -0
  569. package/docs/pi.md +612 -0
  570. package/docs/platforms/android.md +148 -0
  571. package/docs/platforms/digitalocean.md +262 -0
  572. package/docs/platforms/index.md +53 -0
  573. package/docs/platforms/ios.md +107 -0
  574. package/docs/platforms/linux.md +94 -0
  575. package/docs/platforms/mac/bundled-gateway.md +73 -0
  576. package/docs/platforms/mac/canvas.md +125 -0
  577. package/docs/platforms/mac/child-process.md +69 -0
  578. package/docs/platforms/mac/dev-setup.md +102 -0
  579. package/docs/platforms/mac/health.md +34 -0
  580. package/docs/platforms/mac/icon.md +31 -0
  581. package/docs/platforms/mac/logging.md +57 -0
  582. package/docs/platforms/mac/menu-bar.md +81 -0
  583. package/docs/platforms/mac/peekaboo.md +65 -0
  584. package/docs/platforms/mac/permissions.md +44 -0
  585. package/docs/platforms/mac/release.md +85 -0
  586. package/docs/platforms/mac/remote.md +83 -0
  587. package/docs/platforms/mac/signing.md +47 -0
  588. package/docs/platforms/mac/skills.md +33 -0
  589. package/docs/platforms/mac/voice-overlay.md +60 -0
  590. package/docs/platforms/mac/voicewake.md +67 -0
  591. package/docs/platforms/mac/webchat.md +41 -0
  592. package/docs/platforms/mac/xpc.md +61 -0
  593. package/docs/platforms/macos.md +203 -0
  594. package/docs/platforms/oracle.md +303 -0
  595. package/docs/platforms/raspberry-pi.md +358 -0
  596. package/docs/platforms/windows.md +159 -0
  597. package/docs/plugin.md +664 -0
  598. package/docs/plugins/agent-tools.md +99 -0
  599. package/docs/plugins/manifest.md +71 -0
  600. package/docs/plugins/voice-call.md +284 -0
  601. package/docs/plugins/zalouser.md +81 -0
  602. package/docs/prose.md +134 -0
  603. package/docs/providers/anthropic.md +152 -0
  604. package/docs/providers/claude-max-api-proxy.md +148 -0
  605. package/docs/providers/cloudflare-ai-gateway.md +71 -0
  606. package/docs/providers/deepgram.md +93 -0
  607. package/docs/providers/github-copilot.md +72 -0
  608. package/docs/providers/glm.md +33 -0
  609. package/docs/providers/index.md +63 -0
  610. package/docs/providers/minimax.md +208 -0
  611. package/docs/providers/models.md +51 -0
  612. package/docs/providers/moonshot.md +142 -0
  613. package/docs/providers/ollama.md +277 -0
  614. package/docs/providers/openai.md +62 -0
  615. package/docs/providers/opencode.md +36 -0
  616. package/docs/providers/openrouter.md +37 -0
  617. package/docs/providers/qwen.md +53 -0
  618. package/docs/providers/synthetic.md +99 -0
  619. package/docs/providers/venice.md +267 -0
  620. package/docs/providers/vercel-ai-gateway.md +50 -0
  621. package/docs/providers/xiaomi.md +64 -0
  622. package/docs/providers/zai.md +36 -0
  623. package/docs/refactor/clawnet.md +417 -0
  624. package/docs/refactor/exec-host.md +316 -0
  625. package/docs/refactor/outbound-session-mirroring.md +85 -0
  626. package/docs/refactor/plugin-sdk.md +214 -0
  627. package/docs/refactor/strict-config.md +93 -0
  628. package/docs/reference/AGENTS.default.md +124 -0
  629. package/docs/reference/RELEASING.md +120 -0
  630. package/docs/reference/api-usage-costs.md +137 -0
  631. package/docs/reference/credits.md +27 -0
  632. package/docs/reference/device-models.md +47 -0
  633. package/docs/reference/rpc.md +43 -0
  634. package/docs/reference/session-management-compaction.md +285 -0
  635. package/docs/reference/templates/AGENTS.dev.md +83 -0
  636. package/docs/reference/templates/AGENTS.md +218 -0
  637. package/docs/reference/templates/BOOT.md +10 -0
  638. package/docs/reference/templates/BOOTSTRAP.md +61 -0
  639. package/docs/reference/templates/HEARTBEAT.md +11 -0
  640. package/docs/reference/templates/IDENTITY.dev.md +47 -0
  641. package/docs/reference/templates/IDENTITY.md +29 -0
  642. package/docs/reference/templates/SOUL.dev.md +76 -0
  643. package/docs/reference/templates/SOUL.md +42 -0
  644. package/docs/reference/templates/TOOLS.dev.md +24 -0
  645. package/docs/reference/templates/TOOLS.md +46 -0
  646. package/docs/reference/templates/USER.dev.md +18 -0
  647. package/docs/reference/templates/USER.md +22 -0
  648. package/docs/reference/test.md +50 -0
  649. package/docs/reference/transcript-hygiene.md +129 -0
  650. package/docs/reference/wizard.md +268 -0
  651. package/docs/scripts.md +28 -0
  652. package/docs/security/formal-verification.md +164 -0
  653. package/docs/start/bootstrapping.md +41 -0
  654. package/docs/start/docs-directory.md +64 -0
  655. package/docs/start/getting-started.md +120 -0
  656. package/docs/start/hubs.md +197 -0
  657. package/docs/start/lore.md +219 -0
  658. package/docs/start/onboarding.md +80 -0
  659. package/docs/start/openclaw.md +224 -0
  660. package/docs/start/pairing.md +86 -0
  661. package/docs/start/quickstart.md +22 -0
  662. package/docs/start/setup.md +162 -0
  663. package/docs/start/showcase.md +416 -0
  664. package/docs/start/wizard-cli-automation.md +141 -0
  665. package/docs/start/wizard-cli-reference.md +244 -0
  666. package/docs/start/wizard.md +108 -0
  667. package/docs/style.css +3 -0
  668. package/docs/testing.md +368 -0
  669. package/docs/token-use.md +112 -0
  670. package/docs/tools/agent-send.md +53 -0
  671. package/docs/tools/apply-patch.md +50 -0
  672. package/docs/tools/browser-linux-troubleshooting.md +139 -0
  673. package/docs/tools/browser-login.md +68 -0
  674. package/docs/tools/browser.md +576 -0
  675. package/docs/tools/chrome-extension.md +178 -0
  676. package/docs/tools/clawhub.md +257 -0
  677. package/docs/tools/creating-skills.md +54 -0
  678. package/docs/tools/elevated.md +57 -0
  679. package/docs/tools/exec-approvals.md +246 -0
  680. package/docs/tools/exec.md +179 -0
  681. package/docs/tools/firecrawl.md +61 -0
  682. package/docs/tools/index.md +512 -0
  683. package/docs/tools/llm-task.md +115 -0
  684. package/docs/tools/lobster.md +342 -0
  685. package/docs/tools/reactions.md +22 -0
  686. package/docs/tools/skills-config.md +76 -0
  687. package/docs/tools/skills.md +300 -0
  688. package/docs/tools/slash-commands.md +198 -0
  689. package/docs/tools/subagents.md +151 -0
  690. package/docs/tools/thinking.md +74 -0
  691. package/docs/tools/web.md +261 -0
  692. package/docs/tts.md +396 -0
  693. package/docs/tui.md +162 -0
  694. package/docs/vps.md +43 -0
  695. package/docs/web/control-ui.md +223 -0
  696. package/docs/web/dashboard.md +46 -0
  697. package/docs/web/index.md +116 -0
  698. package/docs/web/webchat.md +49 -0
  699. package/docs/whatsapp-openclaw-ai-zh.jpg +0 -0
  700. package/docs/whatsapp-openclaw.jpg +0 -0
  701. package/docs/zh-CN/AGENTS.md +59 -0
  702. package/docs/zh-CN/automation/auth-monitoring.md +47 -0
  703. package/docs/zh-CN/automation/cron-jobs.md +424 -0
  704. package/docs/zh-CN/automation/cron-vs-heartbeat.md +286 -0
  705. package/docs/zh-CN/automation/gmail-pubsub.md +249 -0
  706. package/docs/zh-CN/automation/poll.md +76 -0
  707. package/docs/zh-CN/automation/webhook.md +163 -0
  708. package/docs/zh-CN/bedrock.md +170 -0
  709. package/docs/zh-CN/brave-search.md +48 -0
  710. package/docs/zh-CN/broadcast-groups.md +449 -0
  711. package/docs/zh-CN/channels/bluebubbles.md +271 -0
  712. package/docs/zh-CN/channels/discord.md +468 -0
  713. package/docs/zh-CN/channels/feishu.md +629 -0
  714. package/docs/zh-CN/channels/googlechat.md +257 -0
  715. package/docs/zh-CN/channels/grammy.md +38 -0
  716. package/docs/zh-CN/channels/imessage.md +302 -0
  717. package/docs/zh-CN/channels/index.md +53 -0
  718. package/docs/zh-CN/channels/line.md +180 -0
  719. package/docs/zh-CN/channels/location.md +63 -0
  720. package/docs/zh-CN/channels/matrix.md +221 -0
  721. package/docs/zh-CN/channels/mattermost.md +144 -0
  722. package/docs/zh-CN/channels/msteams.md +775 -0
  723. package/docs/zh-CN/channels/nextcloud-talk.md +142 -0
  724. package/docs/zh-CN/channels/nostr.md +240 -0
  725. package/docs/zh-CN/channels/signal.md +209 -0
  726. package/docs/zh-CN/channels/slack.md +531 -0
  727. package/docs/zh-CN/channels/telegram.md +751 -0
  728. package/docs/zh-CN/channels/tlon.md +136 -0
  729. package/docs/zh-CN/channels/troubleshooting.md +36 -0
  730. package/docs/zh-CN/channels/twitch.md +385 -0
  731. package/docs/zh-CN/channels/whatsapp.md +411 -0
  732. package/docs/zh-CN/channels/zalo.md +196 -0
  733. package/docs/zh-CN/channels/zalouser.md +147 -0
  734. package/docs/zh-CN/cli/acp.md +173 -0
  735. package/docs/zh-CN/cli/agent.md +30 -0
  736. package/docs/zh-CN/cli/agents.md +82 -0
  737. package/docs/zh-CN/cli/approvals.md +57 -0
  738. package/docs/zh-CN/cli/browser.md +114 -0
  739. package/docs/zh-CN/cli/channels.md +86 -0
  740. package/docs/zh-CN/cli/config.md +57 -0
  741. package/docs/zh-CN/cli/configure.md +38 -0
  742. package/docs/zh-CN/cli/cron.md +43 -0
  743. package/docs/zh-CN/cli/dashboard.md +23 -0
  744. package/docs/zh-CN/cli/devices.md +74 -0
  745. package/docs/zh-CN/cli/directory.md +70 -0
  746. package/docs/zh-CN/cli/dns.md +30 -0
  747. package/docs/zh-CN/cli/docs.md +22 -0
  748. package/docs/zh-CN/cli/doctor.md +48 -0
  749. package/docs/zh-CN/cli/gateway.md +206 -0
  750. package/docs/zh-CN/cli/health.md +28 -0
  751. package/docs/zh-CN/cli/hooks.md +311 -0
  752. package/docs/zh-CN/cli/index.md +1032 -0
  753. package/docs/zh-CN/cli/logs.md +31 -0
  754. package/docs/zh-CN/cli/memory.md +52 -0
  755. package/docs/zh-CN/cli/message.md +246 -0
  756. package/docs/zh-CN/cli/models.md +85 -0
  757. package/docs/zh-CN/cli/node.md +115 -0
  758. package/docs/zh-CN/cli/nodes.md +80 -0
  759. package/docs/zh-CN/cli/onboard.md +36 -0
  760. package/docs/zh-CN/cli/pairing.md +28 -0
  761. package/docs/zh-CN/cli/plugins.md +66 -0
  762. package/docs/zh-CN/cli/reset.md +24 -0
  763. package/docs/zh-CN/cli/sandbox.md +158 -0
  764. package/docs/zh-CN/cli/security.md +33 -0
  765. package/docs/zh-CN/cli/sessions.md +23 -0
  766. package/docs/zh-CN/cli/setup.md +36 -0
  767. package/docs/zh-CN/cli/skills.md +33 -0
  768. package/docs/zh-CN/cli/status.md +33 -0
  769. package/docs/zh-CN/cli/system.md +63 -0
  770. package/docs/zh-CN/cli/tui.md +30 -0
  771. package/docs/zh-CN/cli/uninstall.md +24 -0
  772. package/docs/zh-CN/cli/update.md +101 -0
  773. package/docs/zh-CN/cli/voicecall.md +41 -0
  774. package/docs/zh-CN/cli/webhooks.md +32 -0
  775. package/docs/zh-CN/concepts/agent-loop.md +146 -0
  776. package/docs/zh-CN/concepts/agent-workspace.md +219 -0
  777. package/docs/zh-CN/concepts/agent.md +115 -0
  778. package/docs/zh-CN/concepts/architecture.md +123 -0
  779. package/docs/zh-CN/concepts/channel-routing.md +117 -0
  780. package/docs/zh-CN/concepts/compaction.md +67 -0
  781. package/docs/zh-CN/concepts/context.md +168 -0
  782. package/docs/zh-CN/concepts/features.md +59 -0
  783. package/docs/zh-CN/concepts/group-messages.md +91 -0
  784. package/docs/zh-CN/concepts/groups.md +379 -0
  785. package/docs/zh-CN/concepts/markdown-formatting.md +117 -0
  786. package/docs/zh-CN/concepts/memory.md +412 -0
  787. package/docs/zh-CN/concepts/messages.md +141 -0
  788. package/docs/zh-CN/concepts/model-failover.md +145 -0
  789. package/docs/zh-CN/concepts/model-providers.md +320 -0
  790. package/docs/zh-CN/concepts/models.md +196 -0
  791. package/docs/zh-CN/concepts/multi-agent.md +372 -0
  792. package/docs/zh-CN/concepts/oauth.md +151 -0
  793. package/docs/zh-CN/concepts/presence.md +99 -0
  794. package/docs/zh-CN/concepts/queue.md +94 -0
  795. package/docs/zh-CN/concepts/retry.md +76 -0
  796. package/docs/zh-CN/concepts/session-pruning.md +129 -0
  797. package/docs/zh-CN/concepts/session-tool.md +200 -0
  798. package/docs/zh-CN/concepts/session.md +166 -0
  799. package/docs/zh-CN/concepts/sessions.md +17 -0
  800. package/docs/zh-CN/concepts/streaming.md +133 -0
  801. package/docs/zh-CN/concepts/system-prompt.md +101 -0
  802. package/docs/zh-CN/concepts/timezone.md +96 -0
  803. package/docs/zh-CN/concepts/typebox.md +284 -0
  804. package/docs/zh-CN/concepts/typing-indicators.md +74 -0
  805. package/docs/zh-CN/concepts/usage-tracking.md +42 -0
  806. package/docs/zh-CN/date-time.md +129 -0
  807. package/docs/zh-CN/debug/node-issue.md +90 -0
  808. package/docs/zh-CN/debugging.md +160 -0
  809. package/docs/zh-CN/diagnostics/flags.md +98 -0
  810. package/docs/zh-CN/environment.md +88 -0
  811. package/docs/zh-CN/experiments/onboarding-config-protocol.md +47 -0
  812. package/docs/zh-CN/experiments/plans/cron-add-hardening.md +70 -0
  813. package/docs/zh-CN/experiments/plans/group-policy-hardening.md +45 -0
  814. package/docs/zh-CN/experiments/plans/openresponses-gateway.md +121 -0
  815. package/docs/zh-CN/experiments/proposals/model-config.md +42 -0
  816. package/docs/zh-CN/experiments/research/memory.md +235 -0
  817. package/docs/zh-CN/gateway/authentication.md +142 -0
  818. package/docs/zh-CN/gateway/background-process.md +100 -0
  819. package/docs/zh-CN/gateway/bonjour.md +174 -0
  820. package/docs/zh-CN/gateway/bridge-protocol.md +86 -0
  821. package/docs/zh-CN/gateway/cli-backends.md +213 -0
  822. package/docs/zh-CN/gateway/configuration-examples.md +587 -0
  823. package/docs/zh-CN/gateway/configuration.md +3332 -0
  824. package/docs/zh-CN/gateway/discovery.md +123 -0
  825. package/docs/zh-CN/gateway/doctor.md +238 -0
  826. package/docs/zh-CN/gateway/gateway-lock.md +41 -0
  827. package/docs/zh-CN/gateway/health.md +42 -0
  828. package/docs/zh-CN/gateway/heartbeat.md +274 -0
  829. package/docs/zh-CN/gateway/index.md +335 -0
  830. package/docs/zh-CN/gateway/local-models.md +157 -0
  831. package/docs/zh-CN/gateway/logging.md +114 -0
  832. package/docs/zh-CN/gateway/multiple-gateways.md +119 -0
  833. package/docs/zh-CN/gateway/network-model.md +23 -0
  834. package/docs/zh-CN/gateway/openai-http-api.md +125 -0
  835. package/docs/zh-CN/gateway/openresponses-http-api.md +317 -0
  836. package/docs/zh-CN/gateway/pairing.md +99 -0
  837. package/docs/zh-CN/gateway/protocol.md +220 -0
  838. package/docs/zh-CN/gateway/remote-gateway-readme.md +164 -0
  839. package/docs/zh-CN/gateway/remote.md +133 -0
  840. package/docs/zh-CN/gateway/sandbox-vs-tool-policy-vs-elevated.md +135 -0
  841. package/docs/zh-CN/gateway/sandboxing.md +188 -0
  842. package/docs/zh-CN/gateway/security/formal-verification.md +169 -0
  843. package/docs/zh-CN/gateway/security/index.md +777 -0
  844. package/docs/zh-CN/gateway/tailscale.md +124 -0
  845. package/docs/zh-CN/gateway/tools-invoke-http-api.md +92 -0
  846. package/docs/zh-CN/gateway/troubleshooting.md +771 -0
  847. package/docs/zh-CN/help/faq.md +2628 -0
  848. package/docs/zh-CN/help/index.md +28 -0
  849. package/docs/zh-CN/help/troubleshooting.md +104 -0
  850. package/docs/zh-CN/hooks/soul-evil.md +72 -0
  851. package/docs/zh-CN/hooks.md +919 -0
  852. package/docs/zh-CN/index.md +186 -0
  853. package/docs/zh-CN/install/ansible.md +215 -0
  854. package/docs/zh-CN/install/bun.md +65 -0
  855. package/docs/zh-CN/install/development-channels.md +81 -0
  856. package/docs/zh-CN/install/docker.md +532 -0
  857. package/docs/zh-CN/install/exe-dev.md +127 -0
  858. package/docs/zh-CN/install/fly.md +490 -0
  859. package/docs/zh-CN/install/gcp.md +510 -0
  860. package/docs/zh-CN/install/hetzner.md +337 -0
  861. package/docs/zh-CN/install/index.md +193 -0
  862. package/docs/zh-CN/install/installer.md +128 -0
  863. package/docs/zh-CN/install/macos-vm.md +288 -0
  864. package/docs/zh-CN/install/migrating.md +199 -0
  865. package/docs/zh-CN/install/nix.md +99 -0
  866. package/docs/zh-CN/install/node.md +85 -0
  867. package/docs/zh-CN/install/northflank.mdx +60 -0
  868. package/docs/zh-CN/install/railway.mdx +106 -0
  869. package/docs/zh-CN/install/render.mdx +169 -0
  870. package/docs/zh-CN/install/uninstall.md +135 -0
  871. package/docs/zh-CN/install/updating.md +233 -0
  872. package/docs/zh-CN/logging.md +329 -0
  873. package/docs/zh-CN/multi-agent-sandbox-tools.md +401 -0
  874. package/docs/zh-CN/network.md +59 -0
  875. package/docs/zh-CN/nodes/audio.md +120 -0
  876. package/docs/zh-CN/nodes/camera.md +162 -0
  877. package/docs/zh-CN/nodes/images.md +79 -0
  878. package/docs/zh-CN/nodes/index.md +348 -0
  879. package/docs/zh-CN/nodes/location-command.md +120 -0
  880. package/docs/zh-CN/nodes/media-understanding.md +380 -0
  881. package/docs/zh-CN/nodes/talk.md +97 -0
  882. package/docs/zh-CN/nodes/voicewake.md +72 -0
  883. package/docs/zh-CN/perplexity.md +84 -0
  884. package/docs/zh-CN/pi-dev.md +77 -0
  885. package/docs/zh-CN/pi.md +619 -0
  886. package/docs/zh-CN/platforms/android.md +155 -0
  887. package/docs/zh-CN/platforms/digitalocean.md +269 -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.md +193 -0
  910. package/docs/zh-CN/platforms/oracle.md +310 -0
  911. package/docs/zh-CN/platforms/raspberry-pi.md +365 -0
  912. package/docs/zh-CN/platforms/windows.md +156 -0
  913. package/docs/zh-CN/plugin.md +639 -0
  914. package/docs/zh-CN/plugins/agent-tools.md +99 -0
  915. package/docs/zh-CN/plugins/manifest.md +68 -0
  916. package/docs/zh-CN/plugins/voice-call.md +250 -0
  917. package/docs/zh-CN/plugins/zalouser.md +88 -0
  918. package/docs/zh-CN/prose.md +141 -0
  919. package/docs/zh-CN/providers/anthropic.md +159 -0
  920. package/docs/zh-CN/providers/claude-max-api-proxy.md +155 -0
  921. package/docs/zh-CN/providers/deepgram.md +97 -0
  922. package/docs/zh-CN/providers/github-copilot.md +67 -0
  923. package/docs/zh-CN/providers/glm.md +39 -0
  924. package/docs/zh-CN/providers/index.md +68 -0
  925. package/docs/zh-CN/providers/minimax.md +206 -0
  926. package/docs/zh-CN/providers/models.md +55 -0
  927. package/docs/zh-CN/providers/moonshot.md +145 -0
  928. package/docs/zh-CN/providers/ollama.md +230 -0
  929. package/docs/zh-CN/providers/openai.md +68 -0
  930. package/docs/zh-CN/providers/opencode.md +41 -0
  931. package/docs/zh-CN/providers/openrouter.md +43 -0
  932. package/docs/zh-CN/providers/qwen.md +55 -0
  933. package/docs/zh-CN/providers/synthetic.md +102 -0
  934. package/docs/zh-CN/providers/venice.md +274 -0
  935. package/docs/zh-CN/providers/vercel-ai-gateway.md +57 -0
  936. package/docs/zh-CN/providers/xiaomi.md +68 -0
  937. package/docs/zh-CN/providers/zai.md +41 -0
  938. package/docs/zh-CN/refactor/clawnet.md +424 -0
  939. package/docs/zh-CN/refactor/exec-host.md +323 -0
  940. package/docs/zh-CN/refactor/outbound-session-mirroring.md +92 -0
  941. package/docs/zh-CN/refactor/plugin-sdk.md +221 -0
  942. package/docs/zh-CN/refactor/strict-config.md +100 -0
  943. package/docs/zh-CN/reference/AGENTS.default.md +131 -0
  944. package/docs/zh-CN/reference/RELEASING.md +123 -0
  945. package/docs/zh-CN/reference/api-usage-costs.md +136 -0
  946. package/docs/zh-CN/reference/credits.md +34 -0
  947. package/docs/zh-CN/reference/device-models.md +54 -0
  948. package/docs/zh-CN/reference/rpc.md +48 -0
  949. package/docs/zh-CN/reference/session-management-compaction.md +287 -0
  950. package/docs/zh-CN/reference/templates/AGENTS.dev.md +89 -0
  951. package/docs/zh-CN/reference/templates/AGENTS.md +225 -0
  952. package/docs/zh-CN/reference/templates/BOOT.md +17 -0
  953. package/docs/zh-CN/reference/templates/BOOTSTRAP.md +68 -0
  954. package/docs/zh-CN/reference/templates/HEARTBEAT.md +18 -0
  955. package/docs/zh-CN/reference/templates/IDENTITY.dev.md +54 -0
  956. package/docs/zh-CN/reference/templates/IDENTITY.md +36 -0
  957. package/docs/zh-CN/reference/templates/SOUL.dev.md +83 -0
  958. package/docs/zh-CN/reference/templates/SOUL.md +49 -0
  959. package/docs/zh-CN/reference/templates/TOOLS.dev.md +31 -0
  960. package/docs/zh-CN/reference/templates/TOOLS.md +53 -0
  961. package/docs/zh-CN/reference/templates/USER.dev.md +25 -0
  962. package/docs/zh-CN/reference/templates/USER.md +30 -0
  963. package/docs/zh-CN/reference/test.md +57 -0
  964. package/docs/zh-CN/reference/transcript-hygiene.md +109 -0
  965. package/docs/zh-CN/scripts.md +35 -0
  966. package/docs/zh-CN/security/formal-verification.md +171 -0
  967. package/docs/zh-CN/start/docs-directory.md +70 -0
  968. package/docs/zh-CN/start/getting-started.md +206 -0
  969. package/docs/zh-CN/start/hubs.md +200 -0
  970. package/docs/zh-CN/start/lore.md +226 -0
  971. package/docs/zh-CN/start/onboarding.md +105 -0
  972. package/docs/zh-CN/start/openclaw.md +248 -0
  973. package/docs/zh-CN/start/pairing.md +89 -0
  974. package/docs/zh-CN/start/quickstart.md +88 -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 +2499 -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 +149 -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/index.ts +63 -0
  1054. package/extensions/feishu/node_modules/.bin/openclaw +21 -0
  1055. package/extensions/feishu/openclaw.plugin.json +10 -0
  1056. package/extensions/feishu/package.json +37 -0
  1057. package/extensions/feishu/skills/feishu-doc/SKILL.md +105 -0
  1058. package/extensions/feishu/skills/feishu-doc/references/block-types.md +103 -0
  1059. package/extensions/feishu/skills/feishu-drive/SKILL.md +97 -0
  1060. package/extensions/feishu/skills/feishu-perm/SKILL.md +119 -0
  1061. package/extensions/feishu/skills/feishu-wiki/SKILL.md +111 -0
  1062. package/extensions/feishu/src/accounts.ts +144 -0
  1063. package/extensions/feishu/src/bitable.ts +459 -0
  1064. package/extensions/feishu/src/bot.ts +871 -0
  1065. package/extensions/feishu/src/channel.ts +341 -0
  1066. package/extensions/feishu/src/client.ts +118 -0
  1067. package/extensions/feishu/src/config-schema.ts +172 -0
  1068. package/extensions/feishu/src/directory.ts +177 -0
  1069. package/extensions/feishu/src/doc-schema.ts +47 -0
  1070. package/extensions/feishu/src/docx.ts +521 -0
  1071. package/extensions/feishu/src/drive-schema.ts +46 -0
  1072. package/extensions/feishu/src/drive.ts +227 -0
  1073. package/extensions/feishu/src/media.ts +527 -0
  1074. package/extensions/feishu/src/mention.ts +126 -0
  1075. package/extensions/feishu/src/monitor.ts +190 -0
  1076. package/extensions/feishu/src/onboarding.ts +356 -0
  1077. package/extensions/feishu/src/outbound.ts +40 -0
  1078. package/extensions/feishu/src/perm-schema.ts +52 -0
  1079. package/extensions/feishu/src/perm.ts +173 -0
  1080. package/extensions/feishu/src/policy.ts +104 -0
  1081. package/extensions/feishu/src/probe.ts +44 -0
  1082. package/extensions/feishu/src/reactions.ts +160 -0
  1083. package/extensions/feishu/src/reply-dispatcher.ts +184 -0
  1084. package/extensions/feishu/src/runtime.ts +14 -0
  1085. package/extensions/feishu/src/send.ts +358 -0
  1086. package/extensions/feishu/src/targets.ts +78 -0
  1087. package/extensions/feishu/src/tools-config.ts +21 -0
  1088. package/extensions/feishu/src/types.ts +75 -0
  1089. package/extensions/feishu/src/typing.ts +80 -0
  1090. package/extensions/feishu/src/wiki-schema.ts +55 -0
  1091. package/extensions/feishu/src/wiki.ts +232 -0
  1092. package/extensions/google-antigravity-auth/README.md +24 -0
  1093. package/extensions/google-antigravity-auth/index.ts +461 -0
  1094. package/extensions/google-antigravity-auth/node_modules/.bin/openclaw +21 -0
  1095. package/extensions/google-antigravity-auth/openclaw.plugin.json +9 -0
  1096. package/extensions/google-antigravity-auth/package.json +14 -0
  1097. package/extensions/google-gemini-cli-auth/README.md +35 -0
  1098. package/extensions/google-gemini-cli-auth/index.ts +88 -0
  1099. package/extensions/google-gemini-cli-auth/node_modules/.bin/openclaw +21 -0
  1100. package/extensions/google-gemini-cli-auth/oauth.test.ts +240 -0
  1101. package/extensions/google-gemini-cli-auth/oauth.ts +662 -0
  1102. package/extensions/google-gemini-cli-auth/openclaw.plugin.json +9 -0
  1103. package/extensions/google-gemini-cli-auth/package.json +14 -0
  1104. package/extensions/googlechat/index.ts +19 -0
  1105. package/extensions/googlechat/node_modules/.bin/clawdbot +21 -0
  1106. package/extensions/googlechat/node_modules/.bin/moltbot +21 -0
  1107. package/extensions/googlechat/node_modules/.bin/openclaw +21 -0
  1108. package/extensions/googlechat/openclaw.plugin.json +9 -0
  1109. package/extensions/googlechat/package.json +39 -0
  1110. package/extensions/googlechat/src/accounts.ts +147 -0
  1111. package/extensions/googlechat/src/actions.ts +181 -0
  1112. package/extensions/googlechat/src/api.test.ts +61 -0
  1113. package/extensions/googlechat/src/api.ts +282 -0
  1114. package/extensions/googlechat/src/auth.ts +123 -0
  1115. package/extensions/googlechat/src/channel.ts +583 -0
  1116. package/extensions/googlechat/src/monitor.test.ts +22 -0
  1117. package/extensions/googlechat/src/monitor.ts +960 -0
  1118. package/extensions/googlechat/src/onboarding.ts +269 -0
  1119. package/extensions/googlechat/src/runtime.ts +14 -0
  1120. package/extensions/googlechat/src/targets.test.ts +32 -0
  1121. package/extensions/googlechat/src/targets.ts +65 -0
  1122. package/extensions/googlechat/src/types.config.ts +3 -0
  1123. package/extensions/googlechat/src/types.ts +73 -0
  1124. package/extensions/imessage/index.ts +17 -0
  1125. package/extensions/imessage/node_modules/.bin/openclaw +21 -0
  1126. package/extensions/imessage/openclaw.plugin.json +9 -0
  1127. package/extensions/imessage/package.json +14 -0
  1128. package/extensions/imessage/src/channel.ts +294 -0
  1129. package/extensions/imessage/src/runtime.ts +14 -0
  1130. package/extensions/line/index.ts +19 -0
  1131. package/extensions/line/node_modules/.bin/clawdbot +21 -0
  1132. package/extensions/line/node_modules/.bin/moltbot +21 -0
  1133. package/extensions/line/node_modules/.bin/openclaw +21 -0
  1134. package/extensions/line/openclaw.plugin.json +9 -0
  1135. package/extensions/line/package.json +29 -0
  1136. package/extensions/line/src/card-command.ts +344 -0
  1137. package/extensions/line/src/channel.logout.test.ts +99 -0
  1138. package/extensions/line/src/channel.sendPayload.test.ts +306 -0
  1139. package/extensions/line/src/channel.ts +780 -0
  1140. package/extensions/line/src/runtime.ts +14 -0
  1141. package/extensions/llm-task/README.md +97 -0
  1142. package/extensions/llm-task/index.ts +6 -0
  1143. package/extensions/llm-task/node_modules/.bin/openclaw +21 -0
  1144. package/extensions/llm-task/openclaw.plugin.json +21 -0
  1145. package/extensions/llm-task/package.json +14 -0
  1146. package/extensions/llm-task/src/llm-task-tool.test.ts +138 -0
  1147. package/extensions/llm-task/src/llm-task-tool.ts +245 -0
  1148. package/extensions/lobster/README.md +75 -0
  1149. package/extensions/lobster/SKILL.md +97 -0
  1150. package/extensions/lobster/index.ts +14 -0
  1151. package/extensions/lobster/node_modules/.bin/openclaw +21 -0
  1152. package/extensions/lobster/openclaw.plugin.json +10 -0
  1153. package/extensions/lobster/package.json +14 -0
  1154. package/extensions/lobster/src/lobster-tool.test.ts +247 -0
  1155. package/extensions/lobster/src/lobster-tool.ts +328 -0
  1156. package/extensions/matrix/CHANGELOG.md +93 -0
  1157. package/extensions/matrix/index.ts +17 -0
  1158. package/extensions/matrix/node_modules/.bin/clawdbot +21 -0
  1159. package/extensions/matrix/node_modules/.bin/markdown-it +21 -0
  1160. package/extensions/matrix/node_modules/.bin/moltbot +21 -0
  1161. package/extensions/matrix/node_modules/.bin/openclaw +21 -0
  1162. package/extensions/matrix/openclaw.plugin.json +9 -0
  1163. package/extensions/matrix/package.json +36 -0
  1164. package/extensions/matrix/src/actions.ts +195 -0
  1165. package/extensions/matrix/src/channel.directory.test.ts +64 -0
  1166. package/extensions/matrix/src/channel.ts +439 -0
  1167. package/extensions/matrix/src/config-schema.ts +63 -0
  1168. package/extensions/matrix/src/directory-live.ts +188 -0
  1169. package/extensions/matrix/src/group-mentions.ts +66 -0
  1170. package/extensions/matrix/src/matrix/accounts.test.ts +82 -0
  1171. package/extensions/matrix/src/matrix/accounts.ts +65 -0
  1172. package/extensions/matrix/src/matrix/actions/client.ts +57 -0
  1173. package/extensions/matrix/src/matrix/actions/messages.ts +128 -0
  1174. package/extensions/matrix/src/matrix/actions/pins.ts +76 -0
  1175. package/extensions/matrix/src/matrix/actions/reactions.ts +96 -0
  1176. package/extensions/matrix/src/matrix/actions/room.ts +85 -0
  1177. package/extensions/matrix/src/matrix/actions/summary.ts +75 -0
  1178. package/extensions/matrix/src/matrix/actions/types.ts +84 -0
  1179. package/extensions/matrix/src/matrix/actions.ts +15 -0
  1180. package/extensions/matrix/src/matrix/active-client.ts +11 -0
  1181. package/extensions/matrix/src/matrix/client/config.ts +160 -0
  1182. package/extensions/matrix/src/matrix/client/create-client.ts +123 -0
  1183. package/extensions/matrix/src/matrix/client/logging.ts +36 -0
  1184. package/extensions/matrix/src/matrix/client/runtime.ts +4 -0
  1185. package/extensions/matrix/src/matrix/client/shared.ts +170 -0
  1186. package/extensions/matrix/src/matrix/client/storage.ts +131 -0
  1187. package/extensions/matrix/src/matrix/client/types.ts +34 -0
  1188. package/extensions/matrix/src/matrix/client.test.ts +56 -0
  1189. package/extensions/matrix/src/matrix/client.ts +5 -0
  1190. package/extensions/matrix/src/matrix/credentials.ts +105 -0
  1191. package/extensions/matrix/src/matrix/deps.ts +60 -0
  1192. package/extensions/matrix/src/matrix/format.test.ts +33 -0
  1193. package/extensions/matrix/src/matrix/format.ts +22 -0
  1194. package/extensions/matrix/src/matrix/index.ts +11 -0
  1195. package/extensions/matrix/src/matrix/monitor/allowlist.test.ts +45 -0
  1196. package/extensions/matrix/src/matrix/monitor/allowlist.ts +103 -0
  1197. package/extensions/matrix/src/matrix/monitor/auto-join.ts +71 -0
  1198. package/extensions/matrix/src/matrix/monitor/direct.ts +104 -0
  1199. package/extensions/matrix/src/matrix/monitor/events.ts +101 -0
  1200. package/extensions/matrix/src/matrix/monitor/handler.ts +665 -0
  1201. package/extensions/matrix/src/matrix/monitor/index.ts +338 -0
  1202. package/extensions/matrix/src/matrix/monitor/location.ts +100 -0
  1203. package/extensions/matrix/src/matrix/monitor/media.test.ts +102 -0
  1204. package/extensions/matrix/src/matrix/monitor/media.ts +113 -0
  1205. package/extensions/matrix/src/matrix/monitor/mentions.ts +31 -0
  1206. package/extensions/matrix/src/matrix/monitor/replies.ts +97 -0
  1207. package/extensions/matrix/src/matrix/monitor/room-info.ts +55 -0
  1208. package/extensions/matrix/src/matrix/monitor/rooms.test.ts +39 -0
  1209. package/extensions/matrix/src/matrix/monitor/rooms.ts +47 -0
  1210. package/extensions/matrix/src/matrix/monitor/threads.ts +68 -0
  1211. package/extensions/matrix/src/matrix/monitor/types.ts +39 -0
  1212. package/extensions/matrix/src/matrix/poll-types.test.ts +21 -0
  1213. package/extensions/matrix/src/matrix/poll-types.ts +166 -0
  1214. package/extensions/matrix/src/matrix/probe.ts +70 -0
  1215. package/extensions/matrix/src/matrix/send/client.ts +66 -0
  1216. package/extensions/matrix/src/matrix/send/formatting.ts +89 -0
  1217. package/extensions/matrix/src/matrix/send/media.ts +229 -0
  1218. package/extensions/matrix/src/matrix/send/targets.test.ts +98 -0
  1219. package/extensions/matrix/src/matrix/send/targets.ts +136 -0
  1220. package/extensions/matrix/src/matrix/send/types.ts +109 -0
  1221. package/extensions/matrix/src/matrix/send.test.ts +171 -0
  1222. package/extensions/matrix/src/matrix/send.ts +260 -0
  1223. package/extensions/matrix/src/onboarding.ts +449 -0
  1224. package/extensions/matrix/src/outbound.ts +52 -0
  1225. package/extensions/matrix/src/resolve-targets.test.ts +48 -0
  1226. package/extensions/matrix/src/resolve-targets.ts +135 -0
  1227. package/extensions/matrix/src/runtime.ts +14 -0
  1228. package/extensions/matrix/src/tool-actions.ts +164 -0
  1229. package/extensions/matrix/src/types.ts +97 -0
  1230. package/extensions/mattermost/index.ts +17 -0
  1231. package/extensions/mattermost/node_modules/.bin/openclaw +21 -0
  1232. package/extensions/mattermost/openclaw.plugin.json +9 -0
  1233. package/extensions/mattermost/package.json +28 -0
  1234. package/extensions/mattermost/src/channel.test.ts +72 -0
  1235. package/extensions/mattermost/src/channel.ts +337 -0
  1236. package/extensions/mattermost/src/config-schema.ts +56 -0
  1237. package/extensions/mattermost/src/group-mentions.ts +15 -0
  1238. package/extensions/mattermost/src/mattermost/accounts.ts +128 -0
  1239. package/extensions/mattermost/src/mattermost/client.ts +220 -0
  1240. package/extensions/mattermost/src/mattermost/index.ts +9 -0
  1241. package/extensions/mattermost/src/mattermost/monitor-helpers.ts +166 -0
  1242. package/extensions/mattermost/src/mattermost/monitor.ts +991 -0
  1243. package/extensions/mattermost/src/mattermost/probe.ts +74 -0
  1244. package/extensions/mattermost/src/mattermost/send.ts +231 -0
  1245. package/extensions/mattermost/src/normalize.ts +46 -0
  1246. package/extensions/mattermost/src/onboarding-helpers.ts +44 -0
  1247. package/extensions/mattermost/src/onboarding.ts +186 -0
  1248. package/extensions/mattermost/src/runtime.ts +14 -0
  1249. package/extensions/mattermost/src/types.ts +52 -0
  1250. package/extensions/memory-core/index.ts +38 -0
  1251. package/extensions/memory-core/node_modules/.bin/clawdbot +21 -0
  1252. package/extensions/memory-core/node_modules/.bin/moltbot +21 -0
  1253. package/extensions/memory-core/node_modules/.bin/openclaw +21 -0
  1254. package/extensions/memory-core/openclaw.plugin.json +9 -0
  1255. package/extensions/memory-core/package.json +17 -0
  1256. package/extensions/memory-lancedb/config.ts +139 -0
  1257. package/extensions/memory-lancedb/index.test.ts +295 -0
  1258. package/extensions/memory-lancedb/index.ts +608 -0
  1259. package/extensions/memory-lancedb/node_modules/.bin/openai +21 -0
  1260. package/extensions/memory-lancedb/node_modules/.bin/openclaw +21 -0
  1261. package/extensions/memory-lancedb/openclaw.plugin.json +60 -0
  1262. package/extensions/memory-lancedb/package.json +19 -0
  1263. package/extensions/minimax-portal-auth/README.md +33 -0
  1264. package/extensions/minimax-portal-auth/index.ts +155 -0
  1265. package/extensions/minimax-portal-auth/node_modules/.bin/openclaw +21 -0
  1266. package/extensions/minimax-portal-auth/oauth.ts +247 -0
  1267. package/extensions/minimax-portal-auth/openclaw.plugin.json +9 -0
  1268. package/extensions/minimax-portal-auth/package.json +14 -0
  1269. package/extensions/msteams/CHANGELOG.md +89 -0
  1270. package/extensions/msteams/index.ts +17 -0
  1271. package/extensions/msteams/node_modules/.bin/clawdbot +21 -0
  1272. package/extensions/msteams/node_modules/.bin/moltbot +21 -0
  1273. package/extensions/msteams/node_modules/.bin/openclaw +21 -0
  1274. package/extensions/msteams/openclaw.plugin.json +9 -0
  1275. package/extensions/msteams/package.json +39 -0
  1276. package/extensions/msteams/src/attachments/download.ts +283 -0
  1277. package/extensions/msteams/src/attachments/graph.ts +353 -0
  1278. package/extensions/msteams/src/attachments/html.ts +90 -0
  1279. package/extensions/msteams/src/attachments/payload.ts +22 -0
  1280. package/extensions/msteams/src/attachments/shared.ts +291 -0
  1281. package/extensions/msteams/src/attachments/types.ts +37 -0
  1282. package/extensions/msteams/src/attachments.test.ts +459 -0
  1283. package/extensions/msteams/src/attachments.ts +18 -0
  1284. package/extensions/msteams/src/channel.directory.test.ts +48 -0
  1285. package/extensions/msteams/src/channel.ts +459 -0
  1286. package/extensions/msteams/src/conversation-store-fs.test.ts +88 -0
  1287. package/extensions/msteams/src/conversation-store-fs.ts +165 -0
  1288. package/extensions/msteams/src/conversation-store-memory.ts +47 -0
  1289. package/extensions/msteams/src/conversation-store.ts +41 -0
  1290. package/extensions/msteams/src/directory-live.ts +205 -0
  1291. package/extensions/msteams/src/errors.test.ts +45 -0
  1292. package/extensions/msteams/src/errors.ts +190 -0
  1293. package/extensions/msteams/src/file-consent-helpers.test.ts +243 -0
  1294. package/extensions/msteams/src/file-consent-helpers.ts +73 -0
  1295. package/extensions/msteams/src/file-consent.ts +126 -0
  1296. package/extensions/msteams/src/graph-chat.ts +53 -0
  1297. package/extensions/msteams/src/graph-upload.ts +453 -0
  1298. package/extensions/msteams/src/inbound.test.ts +66 -0
  1299. package/extensions/msteams/src/inbound.ts +48 -0
  1300. package/extensions/msteams/src/index.ts +4 -0
  1301. package/extensions/msteams/src/media-helpers.test.ts +189 -0
  1302. package/extensions/msteams/src/media-helpers.ts +86 -0
  1303. package/extensions/msteams/src/messenger.test.ts +248 -0
  1304. package/extensions/msteams/src/messenger.ts +495 -0
  1305. package/extensions/msteams/src/monitor-handler/inbound-media.ts +128 -0
  1306. package/extensions/msteams/src/monitor-handler/message-handler.ts +641 -0
  1307. package/extensions/msteams/src/monitor-handler.ts +162 -0
  1308. package/extensions/msteams/src/monitor-types.ts +5 -0
  1309. package/extensions/msteams/src/monitor.ts +295 -0
  1310. package/extensions/msteams/src/onboarding.ts +431 -0
  1311. package/extensions/msteams/src/outbound.ts +46 -0
  1312. package/extensions/msteams/src/pending-uploads.ts +89 -0
  1313. package/extensions/msteams/src/policy.test.ts +209 -0
  1314. package/extensions/msteams/src/policy.ts +273 -0
  1315. package/extensions/msteams/src/polls-store-memory.ts +32 -0
  1316. package/extensions/msteams/src/polls-store.test.ts +38 -0
  1317. package/extensions/msteams/src/polls.test.ts +72 -0
  1318. package/extensions/msteams/src/polls.ts +315 -0
  1319. package/extensions/msteams/src/probe.test.ts +58 -0
  1320. package/extensions/msteams/src/probe.ts +107 -0
  1321. package/extensions/msteams/src/reply-dispatcher.ts +132 -0
  1322. package/extensions/msteams/src/resolve-allowlist.ts +297 -0
  1323. package/extensions/msteams/src/runtime.ts +14 -0
  1324. package/extensions/msteams/src/sdk-types.ts +19 -0
  1325. package/extensions/msteams/src/sdk.ts +33 -0
  1326. package/extensions/msteams/src/send-context.ts +164 -0
  1327. package/extensions/msteams/src/send.ts +519 -0
  1328. package/extensions/msteams/src/sent-message-cache.test.ts +15 -0
  1329. package/extensions/msteams/src/sent-message-cache.ts +47 -0
  1330. package/extensions/msteams/src/storage.ts +25 -0
  1331. package/extensions/msteams/src/store-fs.ts +83 -0
  1332. package/extensions/msteams/src/token.ts +19 -0
  1333. package/extensions/nextcloud-talk/index.ts +17 -0
  1334. package/extensions/nextcloud-talk/node_modules/.bin/openclaw +21 -0
  1335. package/extensions/nextcloud-talk/openclaw.plugin.json +9 -0
  1336. package/extensions/nextcloud-talk/package.json +33 -0
  1337. package/extensions/nextcloud-talk/src/accounts.ts +174 -0
  1338. package/extensions/nextcloud-talk/src/channel.ts +409 -0
  1339. package/extensions/nextcloud-talk/src/config-schema.ts +79 -0
  1340. package/extensions/nextcloud-talk/src/format.ts +79 -0
  1341. package/extensions/nextcloud-talk/src/inbound.ts +327 -0
  1342. package/extensions/nextcloud-talk/src/monitor.ts +246 -0
  1343. package/extensions/nextcloud-talk/src/normalize.ts +39 -0
  1344. package/extensions/nextcloud-talk/src/onboarding.ts +343 -0
  1345. package/extensions/nextcloud-talk/src/policy.test.ts +33 -0
  1346. package/extensions/nextcloud-talk/src/policy.ts +180 -0
  1347. package/extensions/nextcloud-talk/src/room-info.ts +125 -0
  1348. package/extensions/nextcloud-talk/src/runtime.ts +14 -0
  1349. package/extensions/nextcloud-talk/src/send.ts +215 -0
  1350. package/extensions/nextcloud-talk/src/signature.ts +72 -0
  1351. package/extensions/nextcloud-talk/src/types.ts +181 -0
  1352. package/extensions/nostr/CHANGELOG.md +80 -0
  1353. package/extensions/nostr/README.md +136 -0
  1354. package/extensions/nostr/index.ts +68 -0
  1355. package/extensions/nostr/node_modules/.bin/clawdbot +21 -0
  1356. package/extensions/nostr/node_modules/.bin/moltbot +21 -0
  1357. package/extensions/nostr/node_modules/.bin/openclaw +21 -0
  1358. package/extensions/nostr/openclaw.plugin.json +9 -0
  1359. package/extensions/nostr/package.json +34 -0
  1360. package/extensions/nostr/src/channel.test.ts +151 -0
  1361. package/extensions/nostr/src/channel.ts +353 -0
  1362. package/extensions/nostr/src/config-schema.ts +90 -0
  1363. package/extensions/nostr/src/metrics.ts +478 -0
  1364. package/extensions/nostr/src/nostr-bus.fuzz.test.ts +533 -0
  1365. package/extensions/nostr/src/nostr-bus.integration.test.ts +448 -0
  1366. package/extensions/nostr/src/nostr-bus.test.ts +199 -0
  1367. package/extensions/nostr/src/nostr-bus.ts +715 -0
  1368. package/extensions/nostr/src/nostr-profile-http.test.ts +378 -0
  1369. package/extensions/nostr/src/nostr-profile-http.ts +519 -0
  1370. package/extensions/nostr/src/nostr-profile-import.test.ts +119 -0
  1371. package/extensions/nostr/src/nostr-profile-import.ts +262 -0
  1372. package/extensions/nostr/src/nostr-profile.fuzz.test.ts +477 -0
  1373. package/extensions/nostr/src/nostr-profile.test.ts +410 -0
  1374. package/extensions/nostr/src/nostr-profile.ts +277 -0
  1375. package/extensions/nostr/src/nostr-state-store.test.ts +131 -0
  1376. package/extensions/nostr/src/nostr-state-store.ts +226 -0
  1377. package/extensions/nostr/src/runtime.ts +14 -0
  1378. package/extensions/nostr/src/seen-tracker.ts +303 -0
  1379. package/extensions/nostr/src/types.test.ts +157 -0
  1380. package/extensions/nostr/src/types.ts +101 -0
  1381. package/extensions/nostr/test/setup.ts +5 -0
  1382. package/extensions/open-prose/README.md +25 -0
  1383. package/extensions/open-prose/index.ts +5 -0
  1384. package/extensions/open-prose/node_modules/.bin/openclaw +21 -0
  1385. package/extensions/open-prose/openclaw.plugin.json +11 -0
  1386. package/extensions/open-prose/package.json +14 -0
  1387. package/extensions/open-prose/skills/prose/LICENSE +21 -0
  1388. package/extensions/open-prose/skills/prose/SKILL.md +323 -0
  1389. package/extensions/open-prose/skills/prose/alt-borges.md +141 -0
  1390. package/extensions/open-prose/skills/prose/alts/arabian-nights.md +358 -0
  1391. package/extensions/open-prose/skills/prose/alts/borges.md +360 -0
  1392. package/extensions/open-prose/skills/prose/alts/folk.md +322 -0
  1393. package/extensions/open-prose/skills/prose/alts/homer.md +346 -0
  1394. package/extensions/open-prose/skills/prose/alts/kafka.md +373 -0
  1395. package/extensions/open-prose/skills/prose/compiler.md +2971 -0
  1396. package/extensions/open-prose/skills/prose/examples/01-hello-world.prose +4 -0
  1397. package/extensions/open-prose/skills/prose/examples/02-research-and-summarize.prose +6 -0
  1398. package/extensions/open-prose/skills/prose/examples/03-code-review.prose +17 -0
  1399. package/extensions/open-prose/skills/prose/examples/04-write-and-refine.prose +14 -0
  1400. package/extensions/open-prose/skills/prose/examples/05-debug-issue.prose +20 -0
  1401. package/extensions/open-prose/skills/prose/examples/06-explain-codebase.prose +17 -0
  1402. package/extensions/open-prose/skills/prose/examples/07-refactor.prose +20 -0
  1403. package/extensions/open-prose/skills/prose/examples/08-blog-post.prose +20 -0
  1404. package/extensions/open-prose/skills/prose/examples/09-research-with-agents.prose +25 -0
  1405. package/extensions/open-prose/skills/prose/examples/10-code-review-agents.prose +32 -0
  1406. package/extensions/open-prose/skills/prose/examples/11-skills-and-imports.prose +27 -0
  1407. package/extensions/open-prose/skills/prose/examples/12-secure-agent-permissions.prose +43 -0
  1408. package/extensions/open-prose/skills/prose/examples/13-variables-and-context.prose +51 -0
  1409. package/extensions/open-prose/skills/prose/examples/14-composition-blocks.prose +48 -0
  1410. package/extensions/open-prose/skills/prose/examples/15-inline-sequences.prose +23 -0
  1411. package/extensions/open-prose/skills/prose/examples/16-parallel-reviews.prose +19 -0
  1412. package/extensions/open-prose/skills/prose/examples/17-parallel-research.prose +19 -0
  1413. package/extensions/open-prose/skills/prose/examples/18-mixed-parallel-sequential.prose +36 -0
  1414. package/extensions/open-prose/skills/prose/examples/19-advanced-parallel.prose +71 -0
  1415. package/extensions/open-prose/skills/prose/examples/20-fixed-loops.prose +20 -0
  1416. package/extensions/open-prose/skills/prose/examples/21-pipeline-operations.prose +35 -0
  1417. package/extensions/open-prose/skills/prose/examples/22-error-handling.prose +51 -0
  1418. package/extensions/open-prose/skills/prose/examples/23-retry-with-backoff.prose +63 -0
  1419. package/extensions/open-prose/skills/prose/examples/24-choice-blocks.prose +86 -0
  1420. package/extensions/open-prose/skills/prose/examples/25-conditionals.prose +114 -0
  1421. package/extensions/open-prose/skills/prose/examples/26-parameterized-blocks.prose +100 -0
  1422. package/extensions/open-prose/skills/prose/examples/27-string-interpolation.prose +105 -0
  1423. package/extensions/open-prose/skills/prose/examples/28-automated-pr-review.prose +37 -0
  1424. package/extensions/open-prose/skills/prose/examples/28-gas-town.prose +1572 -0
  1425. package/extensions/open-prose/skills/prose/examples/29-captains-chair.prose +218 -0
  1426. package/extensions/open-prose/skills/prose/examples/30-captains-chair-simple.prose +42 -0
  1427. package/extensions/open-prose/skills/prose/examples/31-captains-chair-with-memory.prose +145 -0
  1428. package/extensions/open-prose/skills/prose/examples/33-pr-review-autofix.prose +168 -0
  1429. package/extensions/open-prose/skills/prose/examples/34-content-pipeline.prose +204 -0
  1430. package/extensions/open-prose/skills/prose/examples/35-feature-factory.prose +296 -0
  1431. package/extensions/open-prose/skills/prose/examples/36-bug-hunter.prose +237 -0
  1432. package/extensions/open-prose/skills/prose/examples/37-the-forge.prose +1474 -0
  1433. package/extensions/open-prose/skills/prose/examples/38-skill-scan.prose +455 -0
  1434. package/extensions/open-prose/skills/prose/examples/39-architect-by-simulation.prose +277 -0
  1435. package/extensions/open-prose/skills/prose/examples/40-rlm-self-refine.prose +32 -0
  1436. package/extensions/open-prose/skills/prose/examples/41-rlm-divide-conquer.prose +38 -0
  1437. package/extensions/open-prose/skills/prose/examples/42-rlm-filter-recurse.prose +46 -0
  1438. package/extensions/open-prose/skills/prose/examples/43-rlm-pairwise.prose +50 -0
  1439. package/extensions/open-prose/skills/prose/examples/44-run-endpoint-ux-test.prose +261 -0
  1440. package/extensions/open-prose/skills/prose/examples/45-plugin-release.prose +159 -0
  1441. package/extensions/open-prose/skills/prose/examples/45-run-endpoint-ux-test-with-remediation.prose +637 -0
  1442. package/extensions/open-prose/skills/prose/examples/46-run-endpoint-ux-test-fast.prose +148 -0
  1443. package/extensions/open-prose/skills/prose/examples/46-workflow-crystallizer.prose +225 -0
  1444. package/extensions/open-prose/skills/prose/examples/47-language-self-improvement.prose +356 -0
  1445. package/extensions/open-prose/skills/prose/examples/48-habit-miner.prose +445 -0
  1446. package/extensions/open-prose/skills/prose/examples/49-prose-run-retrospective.prose +210 -0
  1447. package/extensions/open-prose/skills/prose/examples/README.md +391 -0
  1448. package/extensions/open-prose/skills/prose/examples/roadmap/README.md +22 -0
  1449. package/extensions/open-prose/skills/prose/examples/roadmap/iterative-refinement.prose +20 -0
  1450. package/extensions/open-prose/skills/prose/examples/roadmap/parallel-review.prose +18 -0
  1451. package/extensions/open-prose/skills/prose/examples/roadmap/simple-pipeline.prose +17 -0
  1452. package/extensions/open-prose/skills/prose/examples/roadmap/syntax/open-prose-syntax.prose +223 -0
  1453. package/extensions/open-prose/skills/prose/guidance/antipatterns.md +951 -0
  1454. package/extensions/open-prose/skills/prose/guidance/patterns.md +700 -0
  1455. package/extensions/open-prose/skills/prose/guidance/system-prompt.md +180 -0
  1456. package/extensions/open-prose/skills/prose/help.md +144 -0
  1457. package/extensions/open-prose/skills/prose/lib/README.md +108 -0
  1458. package/extensions/open-prose/skills/prose/lib/calibrator.prose +215 -0
  1459. package/extensions/open-prose/skills/prose/lib/cost-analyzer.prose +174 -0
  1460. package/extensions/open-prose/skills/prose/lib/error-forensics.prose +250 -0
  1461. package/extensions/open-prose/skills/prose/lib/inspector.prose +196 -0
  1462. package/extensions/open-prose/skills/prose/lib/profiler.prose +460 -0
  1463. package/extensions/open-prose/skills/prose/lib/program-improver.prose +275 -0
  1464. package/extensions/open-prose/skills/prose/lib/project-memory.prose +118 -0
  1465. package/extensions/open-prose/skills/prose/lib/user-memory.prose +93 -0
  1466. package/extensions/open-prose/skills/prose/lib/vm-improver.prose +243 -0
  1467. package/extensions/open-prose/skills/prose/primitives/session.md +593 -0
  1468. package/extensions/open-prose/skills/prose/prose.md +1237 -0
  1469. package/extensions/open-prose/skills/prose/state/filesystem.md +498 -0
  1470. package/extensions/open-prose/skills/prose/state/in-context.md +384 -0
  1471. package/extensions/open-prose/skills/prose/state/postgres.md +880 -0
  1472. package/extensions/open-prose/skills/prose/state/sqlite.md +574 -0
  1473. package/extensions/qwen-portal-auth/README.md +24 -0
  1474. package/extensions/qwen-portal-auth/index.ts +130 -0
  1475. package/extensions/qwen-portal-auth/oauth.ts +190 -0
  1476. package/extensions/qwen-portal-auth/openclaw.plugin.json +9 -0
  1477. package/extensions/signal/index.ts +17 -0
  1478. package/extensions/signal/node_modules/.bin/openclaw +21 -0
  1479. package/extensions/signal/openclaw.plugin.json +9 -0
  1480. package/extensions/signal/package.json +14 -0
  1481. package/extensions/signal/src/channel.ts +315 -0
  1482. package/extensions/signal/src/runtime.ts +14 -0
  1483. package/extensions/slack/index.ts +17 -0
  1484. package/extensions/slack/node_modules/.bin/openclaw +21 -0
  1485. package/extensions/slack/openclaw.plugin.json +9 -0
  1486. package/extensions/slack/package.json +14 -0
  1487. package/extensions/slack/src/channel.ts +604 -0
  1488. package/extensions/slack/src/runtime.ts +14 -0
  1489. package/extensions/telegram/index.ts +17 -0
  1490. package/extensions/telegram/node_modules/.bin/openclaw +21 -0
  1491. package/extensions/telegram/openclaw.plugin.json +9 -0
  1492. package/extensions/telegram/package.json +14 -0
  1493. package/extensions/telegram/src/channel.ts +482 -0
  1494. package/extensions/telegram/src/runtime.ts +14 -0
  1495. package/extensions/tlon/README.md +5 -0
  1496. package/extensions/tlon/index.ts +17 -0
  1497. package/extensions/tlon/node_modules/.bin/openclaw +21 -0
  1498. package/extensions/tlon/openclaw.plugin.json +9 -0
  1499. package/extensions/tlon/package.json +33 -0
  1500. package/extensions/tlon/src/channel.ts +392 -0
  1501. package/extensions/tlon/src/config-schema.test.ts +31 -0
  1502. package/extensions/tlon/src/config-schema.ts +45 -0
  1503. package/extensions/tlon/src/monitor/discovery.ts +76 -0
  1504. package/extensions/tlon/src/monitor/history.ts +90 -0
  1505. package/extensions/tlon/src/monitor/index.ts +580 -0
  1506. package/extensions/tlon/src/monitor/processed-messages.test.ts +23 -0
  1507. package/extensions/tlon/src/monitor/processed-messages.ts +46 -0
  1508. package/extensions/tlon/src/monitor/utils.ts +106 -0
  1509. package/extensions/tlon/src/onboarding.ts +214 -0
  1510. package/extensions/tlon/src/runtime.ts +14 -0
  1511. package/extensions/tlon/src/targets.ts +89 -0
  1512. package/extensions/tlon/src/types.ts +92 -0
  1513. package/extensions/tlon/src/urbit/auth.ts +18 -0
  1514. package/extensions/tlon/src/urbit/http-api.ts +38 -0
  1515. package/extensions/tlon/src/urbit/send.test.ts +38 -0
  1516. package/extensions/tlon/src/urbit/send.ts +131 -0
  1517. package/extensions/tlon/src/urbit/sse-client.test.ts +40 -0
  1518. package/extensions/tlon/src/urbit/sse-client.ts +395 -0
  1519. package/extensions/twitch/CHANGELOG.md +51 -0
  1520. package/extensions/twitch/README.md +89 -0
  1521. package/extensions/twitch/index.ts +20 -0
  1522. package/extensions/twitch/node_modules/.bin/clawdbot +21 -0
  1523. package/extensions/twitch/node_modules/.bin/moltbot +21 -0
  1524. package/extensions/twitch/node_modules/.bin/openclaw +21 -0
  1525. package/extensions/twitch/openclaw.plugin.json +9 -0
  1526. package/extensions/twitch/package.json +20 -0
  1527. package/extensions/twitch/src/access-control.test.ts +489 -0
  1528. package/extensions/twitch/src/access-control.ts +166 -0
  1529. package/extensions/twitch/src/actions.ts +173 -0
  1530. package/extensions/twitch/src/client-manager-registry.ts +115 -0
  1531. package/extensions/twitch/src/config-schema.ts +84 -0
  1532. package/extensions/twitch/src/config.test.ts +87 -0
  1533. package/extensions/twitch/src/config.ts +116 -0
  1534. package/extensions/twitch/src/monitor.ts +272 -0
  1535. package/extensions/twitch/src/onboarding.test.ts +311 -0
  1536. package/extensions/twitch/src/onboarding.ts +417 -0
  1537. package/extensions/twitch/src/outbound.test.ts +373 -0
  1538. package/extensions/twitch/src/outbound.ts +184 -0
  1539. package/extensions/twitch/src/plugin.test.ts +39 -0
  1540. package/extensions/twitch/src/plugin.ts +274 -0
  1541. package/extensions/twitch/src/probe.test.ts +195 -0
  1542. package/extensions/twitch/src/probe.ts +120 -0
  1543. package/extensions/twitch/src/resolver.ts +137 -0
  1544. package/extensions/twitch/src/runtime.ts +14 -0
  1545. package/extensions/twitch/src/send.test.ts +289 -0
  1546. package/extensions/twitch/src/send.ts +136 -0
  1547. package/extensions/twitch/src/status.test.ts +270 -0
  1548. package/extensions/twitch/src/status.ts +178 -0
  1549. package/extensions/twitch/src/token.test.ts +171 -0
  1550. package/extensions/twitch/src/token.ts +91 -0
  1551. package/extensions/twitch/src/twitch-client.test.ts +589 -0
  1552. package/extensions/twitch/src/twitch-client.ts +277 -0
  1553. package/extensions/twitch/src/types.ts +143 -0
  1554. package/extensions/twitch/src/utils/markdown.ts +98 -0
  1555. package/extensions/twitch/src/utils/twitch.ts +78 -0
  1556. package/extensions/twitch/test/setup.ts +7 -0
  1557. package/extensions/voice-call/CHANGELOG.md +115 -0
  1558. package/extensions/voice-call/README.md +139 -0
  1559. package/extensions/voice-call/index.ts +493 -0
  1560. package/extensions/voice-call/node_modules/.bin/openclaw +21 -0
  1561. package/extensions/voice-call/openclaw.plugin.json +559 -0
  1562. package/extensions/voice-call/package.json +19 -0
  1563. package/extensions/voice-call/src/allowlist.ts +19 -0
  1564. package/extensions/voice-call/src/cli.ts +279 -0
  1565. package/extensions/voice-call/src/config.test.ts +234 -0
  1566. package/extensions/voice-call/src/config.ts +523 -0
  1567. package/extensions/voice-call/src/core-bridge.ts +159 -0
  1568. package/extensions/voice-call/src/manager/context.ts +21 -0
  1569. package/extensions/voice-call/src/manager/events.ts +188 -0
  1570. package/extensions/voice-call/src/manager/lookup.ts +35 -0
  1571. package/extensions/voice-call/src/manager/outbound.ts +275 -0
  1572. package/extensions/voice-call/src/manager/state.ts +48 -0
  1573. package/extensions/voice-call/src/manager/store.ts +91 -0
  1574. package/extensions/voice-call/src/manager/timers.ts +89 -0
  1575. package/extensions/voice-call/src/manager/twiml.ts +9 -0
  1576. package/extensions/voice-call/src/manager.test.ts +224 -0
  1577. package/extensions/voice-call/src/manager.ts +887 -0
  1578. package/extensions/voice-call/src/media-stream.test.ts +96 -0
  1579. package/extensions/voice-call/src/media-stream.ts +411 -0
  1580. package/extensions/voice-call/src/providers/base.ts +67 -0
  1581. package/extensions/voice-call/src/providers/index.ts +10 -0
  1582. package/extensions/voice-call/src/providers/mock.ts +165 -0
  1583. package/extensions/voice-call/src/providers/plivo.test.ts +27 -0
  1584. package/extensions/voice-call/src/providers/plivo.ts +515 -0
  1585. package/extensions/voice-call/src/providers/stt-openai-realtime.ts +311 -0
  1586. package/extensions/voice-call/src/providers/telnyx.ts +371 -0
  1587. package/extensions/voice-call/src/providers/tts-openai.ts +259 -0
  1588. package/extensions/voice-call/src/providers/twilio/api.ts +42 -0
  1589. package/extensions/voice-call/src/providers/twilio/webhook.ts +32 -0
  1590. package/extensions/voice-call/src/providers/twilio.test.ts +60 -0
  1591. package/extensions/voice-call/src/providers/twilio.ts +626 -0
  1592. package/extensions/voice-call/src/response-generator.ts +158 -0
  1593. package/extensions/voice-call/src/runtime.ts +212 -0
  1594. package/extensions/voice-call/src/telephony-audio.ts +90 -0
  1595. package/extensions/voice-call/src/telephony-tts.ts +104 -0
  1596. package/extensions/voice-call/src/tunnel.ts +314 -0
  1597. package/extensions/voice-call/src/types.ts +272 -0
  1598. package/extensions/voice-call/src/utils.ts +14 -0
  1599. package/extensions/voice-call/src/voice-mapping.ts +67 -0
  1600. package/extensions/voice-call/src/webhook-security.test.ts +377 -0
  1601. package/extensions/voice-call/src/webhook-security.ts +689 -0
  1602. package/extensions/voice-call/src/webhook.ts +491 -0
  1603. package/extensions/whatsapp/index.ts +17 -0
  1604. package/extensions/whatsapp/node_modules/.bin/openclaw +21 -0
  1605. package/extensions/whatsapp/openclaw.plugin.json +9 -0
  1606. package/extensions/whatsapp/package.json +14 -0
  1607. package/extensions/whatsapp/src/channel.ts +508 -0
  1608. package/extensions/whatsapp/src/runtime.ts +14 -0
  1609. package/extensions/zalo/CHANGELOG.md +95 -0
  1610. package/extensions/zalo/README.md +50 -0
  1611. package/extensions/zalo/index.ts +19 -0
  1612. package/extensions/zalo/node_modules/.bin/clawdbot +21 -0
  1613. package/extensions/zalo/node_modules/.bin/moltbot +21 -0
  1614. package/extensions/zalo/node_modules/.bin/openclaw +21 -0
  1615. package/extensions/zalo/openclaw.plugin.json +9 -0
  1616. package/extensions/zalo/package.json +36 -0
  1617. package/extensions/zalo/src/accounts.ts +80 -0
  1618. package/extensions/zalo/src/actions.ts +67 -0
  1619. package/extensions/zalo/src/api.ts +208 -0
  1620. package/extensions/zalo/src/channel.directory.test.ts +43 -0
  1621. package/extensions/zalo/src/channel.ts +414 -0
  1622. package/extensions/zalo/src/config-schema.ts +25 -0
  1623. package/extensions/zalo/src/monitor.ts +764 -0
  1624. package/extensions/zalo/src/monitor.webhook.test.ts +73 -0
  1625. package/extensions/zalo/src/onboarding.ts +401 -0
  1626. package/extensions/zalo/src/probe.ts +46 -0
  1627. package/extensions/zalo/src/proxy.ts +21 -0
  1628. package/extensions/zalo/src/runtime.ts +14 -0
  1629. package/extensions/zalo/src/send.ts +124 -0
  1630. package/extensions/zalo/src/status-issues.ts +53 -0
  1631. package/extensions/zalo/src/token.ts +63 -0
  1632. package/extensions/zalo/src/types.ts +44 -0
  1633. package/extensions/zalouser/CHANGELOG.md +67 -0
  1634. package/extensions/zalouser/README.md +225 -0
  1635. package/extensions/zalouser/index.ts +31 -0
  1636. package/extensions/zalouser/node_modules/.bin/clawdbot +21 -0
  1637. package/extensions/zalouser/node_modules/.bin/moltbot +21 -0
  1638. package/extensions/zalouser/node_modules/.bin/openclaw +21 -0
  1639. package/extensions/zalouser/openclaw.plugin.json +9 -0
  1640. package/extensions/zalouser/package.json +36 -0
  1641. package/extensions/zalouser/src/accounts.ts +135 -0
  1642. package/extensions/zalouser/src/channel.test.ts +18 -0
  1643. package/extensions/zalouser/src/channel.ts +686 -0
  1644. package/extensions/zalouser/src/config-schema.ts +28 -0
  1645. package/extensions/zalouser/src/monitor.ts +601 -0
  1646. package/extensions/zalouser/src/onboarding.ts +504 -0
  1647. package/extensions/zalouser/src/probe.ts +28 -0
  1648. package/extensions/zalouser/src/runtime.ts +14 -0
  1649. package/extensions/zalouser/src/send.ts +160 -0
  1650. package/extensions/zalouser/src/status-issues.test.ts +57 -0
  1651. package/extensions/zalouser/src/status-issues.ts +89 -0
  1652. package/extensions/zalouser/src/tool.ts +164 -0
  1653. package/extensions/zalouser/src/types.ts +110 -0
  1654. package/extensions/zalouser/src/zca.ts +202 -0
  1655. package/openclaw.mjs +14 -0
  1656. package/package.json +244 -0
  1657. package/skills/1password/SKILL.md +70 -0
  1658. package/skills/1password/references/cli-examples.md +29 -0
  1659. package/skills/1password/references/get-started.md +17 -0
  1660. package/skills/apple-notes/SKILL.md +77 -0
  1661. package/skills/apple-reminders/SKILL.md +96 -0
  1662. package/skills/bear-notes/SKILL.md +107 -0
  1663. package/skills/bird/SKILL.md +224 -0
  1664. package/skills/blogwatcher/SKILL.md +69 -0
  1665. package/skills/blucli/SKILL.md +47 -0
  1666. package/skills/bluebubbles/SKILL.md +131 -0
  1667. package/skills/camsnap/SKILL.md +45 -0
  1668. package/skills/canvas/SKILL.md +198 -0
  1669. package/skills/clawhub/SKILL.md +77 -0
  1670. package/skills/coding-agent/SKILL.md +284 -0
  1671. package/skills/discord/SKILL.md +578 -0
  1672. package/skills/eightctl/SKILL.md +50 -0
  1673. package/skills/food-order/SKILL.md +48 -0
  1674. package/skills/gemini/SKILL.md +43 -0
  1675. package/skills/gifgrep/SKILL.md +79 -0
  1676. package/skills/github/SKILL.md +77 -0
  1677. package/skills/gog/SKILL.md +116 -0
  1678. package/skills/goplaces/SKILL.md +52 -0
  1679. package/skills/healthcheck/SKILL.md +245 -0
  1680. package/skills/himalaya/SKILL.md +257 -0
  1681. package/skills/himalaya/references/configuration.md +184 -0
  1682. package/skills/himalaya/references/message-composition.md +199 -0
  1683. package/skills/imsg/SKILL.md +74 -0
  1684. package/skills/local-places/SERVER_README.md +101 -0
  1685. package/skills/local-places/SKILL.md +102 -0
  1686. package/skills/local-places/pyproject.toml +21 -0
  1687. package/skills/local-places/src/local_places/__init__.py +2 -0
  1688. package/skills/local-places/src/local_places/google_places.py +314 -0
  1689. package/skills/local-places/src/local_places/main.py +65 -0
  1690. package/skills/local-places/src/local_places/schemas.py +107 -0
  1691. package/skills/mcporter/SKILL.md +61 -0
  1692. package/skills/model-usage/SKILL.md +69 -0
  1693. package/skills/model-usage/references/codexbar-cli.md +33 -0
  1694. package/skills/model-usage/scripts/model_usage.py +310 -0
  1695. package/skills/nano-banana-pro/SKILL.md +58 -0
  1696. package/skills/nano-banana-pro/scripts/generate_image.py +184 -0
  1697. package/skills/nano-pdf/SKILL.md +38 -0
  1698. package/skills/notion/SKILL.md +172 -0
  1699. package/skills/obsidian/SKILL.md +81 -0
  1700. package/skills/openai-image-gen/SKILL.md +89 -0
  1701. package/skills/openai-image-gen/scripts/gen.py +240 -0
  1702. package/skills/openai-whisper/SKILL.md +38 -0
  1703. package/skills/openai-whisper-api/SKILL.md +52 -0
  1704. package/skills/openai-whisper-api/scripts/transcribe.sh +85 -0
  1705. package/skills/openhue/SKILL.md +51 -0
  1706. package/skills/oracle/SKILL.md +125 -0
  1707. package/skills/ordercli/SKILL.md +78 -0
  1708. package/skills/peekaboo/SKILL.md +190 -0
  1709. package/skills/sag/SKILL.md +87 -0
  1710. package/skills/session-logs/SKILL.md +115 -0
  1711. package/skills/sherpa-onnx-tts/SKILL.md +103 -0
  1712. package/skills/sherpa-onnx-tts/bin/sherpa-onnx-tts +178 -0
  1713. package/skills/skill-creator/SKILL.md +370 -0
  1714. package/skills/skill-creator/license.txt +202 -0
  1715. package/skills/skill-creator/scripts/init_skill.py +378 -0
  1716. package/skills/skill-creator/scripts/package_skill.py +111 -0
  1717. package/skills/skill-creator/scripts/quick_validate.py +101 -0
  1718. package/skills/slack/SKILL.md +144 -0
  1719. package/skills/songsee/SKILL.md +49 -0
  1720. package/skills/sonoscli/SKILL.md +46 -0
  1721. package/skills/spotify-player/SKILL.md +64 -0
  1722. package/skills/summarize/SKILL.md +87 -0
  1723. package/skills/things-mac/SKILL.md +86 -0
  1724. package/skills/tmux/SKILL.md +135 -0
  1725. package/skills/tmux/scripts/find-sessions.sh +112 -0
  1726. package/skills/tmux/scripts/wait-for-text.sh +83 -0
  1727. package/skills/trello/SKILL.md +95 -0
  1728. package/skills/video-frames/SKILL.md +46 -0
  1729. package/skills/video-frames/scripts/frame.sh +81 -0
  1730. package/skills/voice-call/SKILL.md +45 -0
  1731. package/skills/wacli/SKILL.md +72 -0
  1732. package/skills/weather/SKILL.md +54 -0
@@ -0,0 +1,2944 @@
1
+ import { r as STATE_DIR } from "./paths-scjhy7N2.js";
2
+ import { D as DEFAULT_AGENT_ID, E as DEFAULT_ACCOUNT_ID, F as resolveAgentIdFromSessionKey, M as normalizeAccountId$1, N as normalizeAgentId, P as normalizeMainKey, b as DEFAULT_USER_FILENAME, d as DEFAULT_AGENTS_FILENAME, f as DEFAULT_AGENT_WORKSPACE_DIR, h as DEFAULT_IDENTITY_FILENAME, k as buildAgentMainSessionKey, l as resolveSessionAgentId, m as DEFAULT_HEARTBEAT_FILENAME, n as resolveAgentConfig, p as DEFAULT_BOOTSTRAP_FILENAME, v as DEFAULT_SOUL_FILENAME, x as ensureAgentWorkspace, y as DEFAULT_TOOLS_FILENAME } from "./agent-scope-BbT4OG2N.js";
3
+ import { c as defaultRuntime, m as CHAT_CHANNEL_ORDER, p as CHANNEL_IDS, v as getChatChannelMeta, w as requireActivePluginRegistry } from "./subsystem-CAq3uyo7.js";
4
+ import { d as normalizeE164, h as resolveUserPath } from "./utils-CKSrBNwq.js";
5
+ import { t as formatCliCommand } from "./command-format-DELazozB.js";
6
+ import { i as loadConfig } from "./config-hfzHFLcB.js";
7
+ import { a as normalizeWhatsAppTarget, b as normalizeChatType, c as resolveTelegramAccount, m as resolveSlackReplyToMode, p as resolveSlackAccount, r as normalizeChannelId, v as resolveDiscordAccount } from "./plugins-QJjTXliB.js";
8
+ import { M as DEFAULT_OPENCLAW_BROWSER_COLOR, P as DEFAULT_OPENCLAW_BROWSER_PROFILE_NAME, j as DEFAULT_BROWSER_EVALUATE_ENABLED } from "./chrome-BZ9K48w9.js";
9
+ import { o as syncSkillsToWorkspace } from "./skills-Tky2kCMO.js";
10
+ import { t as registerBrowserRoutes } from "./routes-DW4Wu2jw.js";
11
+ import { a as resolveProfile, t as createBrowserRouteContext } from "./server-context-cZ1L3VL8.js";
12
+ import { c as listDeliverableMessageChannels, l as normalizeMessageChannel } from "./message-channel-B8sq-ATS.js";
13
+ import { n as resolveWhatsAppAccount } from "./accounts-DzBgAM3C.js";
14
+ import { r as resolveSessionTranscriptPath, t as resolveDefaultSessionStorePath } from "./paths-B-q1nXdY.js";
15
+ import { t as emitSessionTranscriptUpdate } from "./transcript-events-CsB1Saa6.js";
16
+ import os from "node:os";
17
+ import path from "node:path";
18
+ import fs from "node:fs";
19
+ import JSON5 from "json5";
20
+ import fs$1 from "node:fs/promises";
21
+ import { spawn } from "node:child_process";
22
+ import crypto from "node:crypto";
23
+ import { CURRENT_SESSION_VERSION, SessionManager } from "@mariozechner/pi-coding-agent";
24
+ import express from "express";
25
+
26
+ //#region src/channels/conversation-label.ts
27
+ function extractConversationId(from) {
28
+ const trimmed = from?.trim();
29
+ if (!trimmed) return;
30
+ const parts = trimmed.split(":").filter(Boolean);
31
+ return parts.length > 0 ? parts[parts.length - 1] : trimmed;
32
+ }
33
+ function shouldAppendId(id) {
34
+ if (/^[0-9]+$/.test(id)) return true;
35
+ if (id.includes("@g.us")) return true;
36
+ return false;
37
+ }
38
+ function resolveConversationLabel(ctx) {
39
+ const explicit = ctx.ConversationLabel?.trim();
40
+ if (explicit) return explicit;
41
+ const threadLabel = ctx.ThreadLabel?.trim();
42
+ if (threadLabel) return threadLabel;
43
+ if (normalizeChatType(ctx.ChatType) === "direct") return ctx.SenderName?.trim() || ctx.From?.trim() || void 0;
44
+ const base = ctx.GroupChannel?.trim() || ctx.GroupSubject?.trim() || ctx.GroupSpace?.trim() || ctx.From?.trim() || "";
45
+ if (!base) return;
46
+ const id = extractConversationId(ctx.From);
47
+ if (!id) return base;
48
+ if (!shouldAppendId(id)) return base;
49
+ if (base === id) return base;
50
+ if (base.includes(id)) return base;
51
+ if (base.toLowerCase().includes(" id:")) return base;
52
+ if (base.startsWith("#") || base.startsWith("@")) return base;
53
+ return `${base} id:${id}`;
54
+ }
55
+
56
+ //#endregion
57
+ //#region src/agents/sandbox/constants.ts
58
+ const DEFAULT_SANDBOX_WORKSPACE_ROOT = path.join(os.homedir(), ".openclaw", "sandboxes");
59
+ const DEFAULT_SANDBOX_IMAGE = "openclaw-sandbox:bookworm-slim";
60
+ const DEFAULT_SANDBOX_CONTAINER_PREFIX = "openclaw-sbx-";
61
+ const DEFAULT_SANDBOX_WORKDIR = "/workspace";
62
+ const DEFAULT_SANDBOX_IDLE_HOURS = 24;
63
+ const DEFAULT_SANDBOX_MAX_AGE_DAYS = 7;
64
+ const DEFAULT_TOOL_ALLOW = [
65
+ "exec",
66
+ "process",
67
+ "read",
68
+ "write",
69
+ "edit",
70
+ "apply_patch",
71
+ "image",
72
+ "sessions_list",
73
+ "sessions_history",
74
+ "sessions_send",
75
+ "sessions_spawn",
76
+ "session_status"
77
+ ];
78
+ const DEFAULT_TOOL_DENY = [
79
+ "browser",
80
+ "canvas",
81
+ "nodes",
82
+ "cron",
83
+ "gateway",
84
+ ...CHANNEL_IDS
85
+ ];
86
+ const DEFAULT_SANDBOX_BROWSER_IMAGE = "openclaw-sandbox-browser:bookworm-slim";
87
+ const DEFAULT_SANDBOX_COMMON_IMAGE = "openclaw-sandbox-common:bookworm-slim";
88
+ const DEFAULT_SANDBOX_BROWSER_PREFIX = "openclaw-sbx-browser-";
89
+ const DEFAULT_SANDBOX_BROWSER_CDP_PORT = 9222;
90
+ const DEFAULT_SANDBOX_BROWSER_VNC_PORT = 5900;
91
+ const DEFAULT_SANDBOX_BROWSER_NOVNC_PORT = 6080;
92
+ const DEFAULT_SANDBOX_BROWSER_AUTOSTART_TIMEOUT_MS = 12e3;
93
+ const SANDBOX_AGENT_WORKSPACE_MOUNT = "/agent";
94
+ const resolvedSandboxStateDir = STATE_DIR ?? path.join(os.homedir(), ".openclaw");
95
+ const SANDBOX_STATE_DIR = path.join(resolvedSandboxStateDir, "sandbox");
96
+ const SANDBOX_REGISTRY_PATH = path.join(SANDBOX_STATE_DIR, "containers.json");
97
+ const SANDBOX_BROWSER_REGISTRY_PATH = path.join(SANDBOX_STATE_DIR, "browsers.json");
98
+
99
+ //#endregion
100
+ //#region src/agents/tool-policy.ts
101
+ const TOOL_NAME_ALIASES = {
102
+ bash: "exec",
103
+ "apply-patch": "apply_patch"
104
+ };
105
+ const TOOL_GROUPS = {
106
+ "group:memory": ["memory_search", "memory_get"],
107
+ "group:web": ["web_search", "web_fetch"],
108
+ "group:fs": [
109
+ "read",
110
+ "write",
111
+ "edit",
112
+ "apply_patch"
113
+ ],
114
+ "group:runtime": ["exec", "process"],
115
+ "group:sessions": [
116
+ "sessions_list",
117
+ "sessions_history",
118
+ "sessions_send",
119
+ "sessions_spawn",
120
+ "session_status"
121
+ ],
122
+ "group:ui": ["browser", "canvas"],
123
+ "group:automation": ["cron", "gateway"],
124
+ "group:messaging": ["message"],
125
+ "group:nodes": ["nodes"],
126
+ "group:openclaw": [
127
+ "browser",
128
+ "canvas",
129
+ "nodes",
130
+ "cron",
131
+ "message",
132
+ "gateway",
133
+ "agents_list",
134
+ "sessions_list",
135
+ "sessions_history",
136
+ "sessions_send",
137
+ "sessions_spawn",
138
+ "session_status",
139
+ "memory_search",
140
+ "memory_get",
141
+ "web_search",
142
+ "web_fetch",
143
+ "image"
144
+ ]
145
+ };
146
+ const OWNER_ONLY_TOOL_NAMES = new Set(["whatsapp_login"]);
147
+ const TOOL_PROFILES = {
148
+ minimal: { allow: ["session_status"] },
149
+ coding: { allow: [
150
+ "group:fs",
151
+ "group:runtime",
152
+ "group:sessions",
153
+ "group:memory",
154
+ "image"
155
+ ] },
156
+ messaging: { allow: [
157
+ "group:messaging",
158
+ "sessions_list",
159
+ "sessions_history",
160
+ "sessions_send",
161
+ "session_status"
162
+ ] },
163
+ full: {}
164
+ };
165
+ function normalizeToolName(name) {
166
+ const normalized = name.trim().toLowerCase();
167
+ return TOOL_NAME_ALIASES[normalized] ?? normalized;
168
+ }
169
+ function isOwnerOnlyToolName(name) {
170
+ return OWNER_ONLY_TOOL_NAMES.has(normalizeToolName(name));
171
+ }
172
+ function applyOwnerOnlyToolPolicy(tools, senderIsOwner) {
173
+ const withGuard = tools.map((tool) => {
174
+ if (!isOwnerOnlyToolName(tool.name)) return tool;
175
+ if (senderIsOwner || !tool.execute) return tool;
176
+ return {
177
+ ...tool,
178
+ execute: async () => {
179
+ throw new Error("Tool restricted to owner senders.");
180
+ }
181
+ };
182
+ });
183
+ if (senderIsOwner) return withGuard;
184
+ return withGuard.filter((tool) => !isOwnerOnlyToolName(tool.name));
185
+ }
186
+ function normalizeToolList(list) {
187
+ if (!list) return [];
188
+ return list.map(normalizeToolName).filter(Boolean);
189
+ }
190
+ function expandToolGroups(list) {
191
+ const normalized = normalizeToolList(list);
192
+ const expanded = [];
193
+ for (const value of normalized) {
194
+ const group = TOOL_GROUPS[value];
195
+ if (group) {
196
+ expanded.push(...group);
197
+ continue;
198
+ }
199
+ expanded.push(value);
200
+ }
201
+ return Array.from(new Set(expanded));
202
+ }
203
+ function collectExplicitAllowlist(policies) {
204
+ const entries = [];
205
+ for (const policy of policies) {
206
+ if (!policy?.allow) continue;
207
+ for (const value of policy.allow) {
208
+ if (typeof value !== "string") continue;
209
+ const trimmed = value.trim();
210
+ if (trimmed) entries.push(trimmed);
211
+ }
212
+ }
213
+ return entries;
214
+ }
215
+ function buildPluginToolGroups(params) {
216
+ const all = [];
217
+ const byPlugin = /* @__PURE__ */ new Map();
218
+ for (const tool of params.tools) {
219
+ const meta = params.toolMeta(tool);
220
+ if (!meta) continue;
221
+ const name = normalizeToolName(tool.name);
222
+ all.push(name);
223
+ const pluginId = meta.pluginId.toLowerCase();
224
+ const list = byPlugin.get(pluginId) ?? [];
225
+ list.push(name);
226
+ byPlugin.set(pluginId, list);
227
+ }
228
+ return {
229
+ all,
230
+ byPlugin
231
+ };
232
+ }
233
+ function expandPluginGroups(list, groups) {
234
+ if (!list || list.length === 0) return list;
235
+ const expanded = [];
236
+ for (const entry of list) {
237
+ const normalized = normalizeToolName(entry);
238
+ if (normalized === "group:plugins") {
239
+ if (groups.all.length > 0) expanded.push(...groups.all);
240
+ else expanded.push(normalized);
241
+ continue;
242
+ }
243
+ const tools = groups.byPlugin.get(normalized);
244
+ if (tools && tools.length > 0) {
245
+ expanded.push(...tools);
246
+ continue;
247
+ }
248
+ expanded.push(normalized);
249
+ }
250
+ return Array.from(new Set(expanded));
251
+ }
252
+ function expandPolicyWithPluginGroups(policy, groups) {
253
+ if (!policy) return;
254
+ return {
255
+ allow: expandPluginGroups(policy.allow, groups),
256
+ deny: expandPluginGroups(policy.deny, groups)
257
+ };
258
+ }
259
+ function stripPluginOnlyAllowlist(policy, groups, coreTools) {
260
+ if (!policy?.allow || policy.allow.length === 0) return {
261
+ policy,
262
+ unknownAllowlist: [],
263
+ strippedAllowlist: false
264
+ };
265
+ const normalized = normalizeToolList(policy.allow);
266
+ if (normalized.length === 0) return {
267
+ policy,
268
+ unknownAllowlist: [],
269
+ strippedAllowlist: false
270
+ };
271
+ const pluginIds = new Set(groups.byPlugin.keys());
272
+ const pluginTools = new Set(groups.all);
273
+ const unknownAllowlist = [];
274
+ let hasCoreEntry = false;
275
+ for (const entry of normalized) {
276
+ if (entry === "*") {
277
+ hasCoreEntry = true;
278
+ continue;
279
+ }
280
+ const isPluginEntry = entry === "group:plugins" || pluginIds.has(entry) || pluginTools.has(entry);
281
+ const isCoreEntry = expandToolGroups([entry]).some((tool) => coreTools.has(tool));
282
+ if (isCoreEntry) hasCoreEntry = true;
283
+ if (!isCoreEntry && !isPluginEntry) unknownAllowlist.push(entry);
284
+ }
285
+ const strippedAllowlist = !hasCoreEntry;
286
+ if (strippedAllowlist) {}
287
+ return {
288
+ policy: strippedAllowlist ? {
289
+ ...policy,
290
+ allow: void 0
291
+ } : policy,
292
+ unknownAllowlist: Array.from(new Set(unknownAllowlist)),
293
+ strippedAllowlist
294
+ };
295
+ }
296
+ function resolveToolProfilePolicy(profile) {
297
+ if (!profile) return;
298
+ const resolved = TOOL_PROFILES[profile];
299
+ if (!resolved) return;
300
+ if (!resolved.allow && !resolved.deny) return;
301
+ return {
302
+ allow: resolved.allow ? [...resolved.allow] : void 0,
303
+ deny: resolved.deny ? [...resolved.deny] : void 0
304
+ };
305
+ }
306
+
307
+ //#endregion
308
+ //#region src/agents/sandbox/tool-policy.ts
309
+ function compilePattern(pattern) {
310
+ const normalized = pattern.trim().toLowerCase();
311
+ if (!normalized) return {
312
+ kind: "exact",
313
+ value: ""
314
+ };
315
+ if (normalized === "*") return { kind: "all" };
316
+ if (!normalized.includes("*")) return {
317
+ kind: "exact",
318
+ value: normalized
319
+ };
320
+ const escaped = normalized.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
321
+ return {
322
+ kind: "regex",
323
+ value: new RegExp(`^${escaped.replaceAll("\\*", ".*")}$`)
324
+ };
325
+ }
326
+ function compilePatterns(patterns) {
327
+ if (!Array.isArray(patterns)) return [];
328
+ return expandToolGroups(patterns).map(compilePattern).filter((pattern) => pattern.kind !== "exact" || pattern.value);
329
+ }
330
+ function matchesAny(name, patterns) {
331
+ for (const pattern of patterns) {
332
+ if (pattern.kind === "all") return true;
333
+ if (pattern.kind === "exact" && name === pattern.value) return true;
334
+ if (pattern.kind === "regex" && pattern.value.test(name)) return true;
335
+ }
336
+ return false;
337
+ }
338
+ function isToolAllowed(policy, name) {
339
+ const normalized = name.trim().toLowerCase();
340
+ if (matchesAny(normalized, compilePatterns(policy.deny))) return false;
341
+ const allow = compilePatterns(policy.allow);
342
+ if (allow.length === 0) return true;
343
+ return matchesAny(normalized, allow);
344
+ }
345
+ function resolveSandboxToolPolicyForAgent(cfg, agentId) {
346
+ const agentConfig = cfg && agentId ? resolveAgentConfig(cfg, agentId) : void 0;
347
+ const agentAllow = agentConfig?.tools?.sandbox?.tools?.allow;
348
+ const agentDeny = agentConfig?.tools?.sandbox?.tools?.deny;
349
+ const globalAllow = cfg?.tools?.sandbox?.tools?.allow;
350
+ const globalDeny = cfg?.tools?.sandbox?.tools?.deny;
351
+ const allowSource = Array.isArray(agentAllow) ? {
352
+ source: "agent",
353
+ key: "agents.list[].tools.sandbox.tools.allow"
354
+ } : Array.isArray(globalAllow) ? {
355
+ source: "global",
356
+ key: "tools.sandbox.tools.allow"
357
+ } : {
358
+ source: "default",
359
+ key: "tools.sandbox.tools.allow"
360
+ };
361
+ const denySource = Array.isArray(agentDeny) ? {
362
+ source: "agent",
363
+ key: "agents.list[].tools.sandbox.tools.deny"
364
+ } : Array.isArray(globalDeny) ? {
365
+ source: "global",
366
+ key: "tools.sandbox.tools.deny"
367
+ } : {
368
+ source: "default",
369
+ key: "tools.sandbox.tools.deny"
370
+ };
371
+ const deny = Array.isArray(agentDeny) ? agentDeny : Array.isArray(globalDeny) ? globalDeny : [...DEFAULT_TOOL_DENY];
372
+ const allow = Array.isArray(agentAllow) ? agentAllow : Array.isArray(globalAllow) ? globalAllow : [...DEFAULT_TOOL_ALLOW];
373
+ const expandedDeny = expandToolGroups(deny);
374
+ let expandedAllow = expandToolGroups(allow);
375
+ if (!expandedDeny.map((v) => v.toLowerCase()).includes("image") && !expandedAllow.map((v) => v.toLowerCase()).includes("image")) expandedAllow = [...expandedAllow, "image"];
376
+ return {
377
+ allow: expandedAllow,
378
+ deny: expandedDeny,
379
+ sources: {
380
+ allow: allowSource,
381
+ deny: denySource
382
+ }
383
+ };
384
+ }
385
+
386
+ //#endregion
387
+ //#region src/agents/sandbox/config.ts
388
+ function resolveSandboxScope(params) {
389
+ if (params.scope) return params.scope;
390
+ if (typeof params.perSession === "boolean") return params.perSession ? "session" : "shared";
391
+ return "agent";
392
+ }
393
+ function resolveSandboxDockerConfig(params) {
394
+ const agentDocker = params.scope === "shared" ? void 0 : params.agentDocker;
395
+ const globalDocker = params.globalDocker;
396
+ const env = agentDocker?.env ? {
397
+ ...globalDocker?.env ?? { LANG: "C.UTF-8" },
398
+ ...agentDocker.env
399
+ } : globalDocker?.env ?? { LANG: "C.UTF-8" };
400
+ const ulimits = agentDocker?.ulimits ? {
401
+ ...globalDocker?.ulimits,
402
+ ...agentDocker.ulimits
403
+ } : globalDocker?.ulimits;
404
+ const binds = [...globalDocker?.binds ?? [], ...agentDocker?.binds ?? []];
405
+ return {
406
+ image: agentDocker?.image ?? globalDocker?.image ?? DEFAULT_SANDBOX_IMAGE,
407
+ containerPrefix: agentDocker?.containerPrefix ?? globalDocker?.containerPrefix ?? DEFAULT_SANDBOX_CONTAINER_PREFIX,
408
+ workdir: agentDocker?.workdir ?? globalDocker?.workdir ?? DEFAULT_SANDBOX_WORKDIR,
409
+ readOnlyRoot: agentDocker?.readOnlyRoot ?? globalDocker?.readOnlyRoot ?? true,
410
+ tmpfs: agentDocker?.tmpfs ?? globalDocker?.tmpfs ?? [
411
+ "/tmp",
412
+ "/var/tmp",
413
+ "/run"
414
+ ],
415
+ network: agentDocker?.network ?? globalDocker?.network ?? "none",
416
+ user: agentDocker?.user ?? globalDocker?.user,
417
+ capDrop: agentDocker?.capDrop ?? globalDocker?.capDrop ?? ["ALL"],
418
+ env,
419
+ setupCommand: agentDocker?.setupCommand ?? globalDocker?.setupCommand,
420
+ pidsLimit: agentDocker?.pidsLimit ?? globalDocker?.pidsLimit,
421
+ memory: agentDocker?.memory ?? globalDocker?.memory,
422
+ memorySwap: agentDocker?.memorySwap ?? globalDocker?.memorySwap,
423
+ cpus: agentDocker?.cpus ?? globalDocker?.cpus,
424
+ ulimits,
425
+ seccompProfile: agentDocker?.seccompProfile ?? globalDocker?.seccompProfile,
426
+ apparmorProfile: agentDocker?.apparmorProfile ?? globalDocker?.apparmorProfile,
427
+ dns: agentDocker?.dns ?? globalDocker?.dns,
428
+ extraHosts: agentDocker?.extraHosts ?? globalDocker?.extraHosts,
429
+ binds: binds.length ? binds : void 0
430
+ };
431
+ }
432
+ function resolveSandboxBrowserConfig(params) {
433
+ const agentBrowser = params.scope === "shared" ? void 0 : params.agentBrowser;
434
+ const globalBrowser = params.globalBrowser;
435
+ return {
436
+ enabled: agentBrowser?.enabled ?? globalBrowser?.enabled ?? false,
437
+ image: agentBrowser?.image ?? globalBrowser?.image ?? DEFAULT_SANDBOX_BROWSER_IMAGE,
438
+ containerPrefix: agentBrowser?.containerPrefix ?? globalBrowser?.containerPrefix ?? DEFAULT_SANDBOX_BROWSER_PREFIX,
439
+ cdpPort: agentBrowser?.cdpPort ?? globalBrowser?.cdpPort ?? DEFAULT_SANDBOX_BROWSER_CDP_PORT,
440
+ vncPort: agentBrowser?.vncPort ?? globalBrowser?.vncPort ?? DEFAULT_SANDBOX_BROWSER_VNC_PORT,
441
+ noVncPort: agentBrowser?.noVncPort ?? globalBrowser?.noVncPort ?? DEFAULT_SANDBOX_BROWSER_NOVNC_PORT,
442
+ headless: agentBrowser?.headless ?? globalBrowser?.headless ?? false,
443
+ enableNoVnc: agentBrowser?.enableNoVnc ?? globalBrowser?.enableNoVnc ?? true,
444
+ allowHostControl: agentBrowser?.allowHostControl ?? globalBrowser?.allowHostControl ?? false,
445
+ autoStart: agentBrowser?.autoStart ?? globalBrowser?.autoStart ?? true,
446
+ autoStartTimeoutMs: agentBrowser?.autoStartTimeoutMs ?? globalBrowser?.autoStartTimeoutMs ?? DEFAULT_SANDBOX_BROWSER_AUTOSTART_TIMEOUT_MS
447
+ };
448
+ }
449
+ function resolveSandboxPruneConfig(params) {
450
+ const agentPrune = params.scope === "shared" ? void 0 : params.agentPrune;
451
+ const globalPrune = params.globalPrune;
452
+ return {
453
+ idleHours: agentPrune?.idleHours ?? globalPrune?.idleHours ?? DEFAULT_SANDBOX_IDLE_HOURS,
454
+ maxAgeDays: agentPrune?.maxAgeDays ?? globalPrune?.maxAgeDays ?? DEFAULT_SANDBOX_MAX_AGE_DAYS
455
+ };
456
+ }
457
+ function resolveSandboxConfigForAgent(cfg, agentId) {
458
+ const agent = cfg?.agents?.defaults?.sandbox;
459
+ let agentSandbox;
460
+ const agentConfig = cfg && agentId ? resolveAgentConfig(cfg, agentId) : void 0;
461
+ if (agentConfig?.sandbox) agentSandbox = agentConfig.sandbox;
462
+ const scope = resolveSandboxScope({
463
+ scope: agentSandbox?.scope ?? agent?.scope,
464
+ perSession: agentSandbox?.perSession ?? agent?.perSession
465
+ });
466
+ const toolPolicy = resolveSandboxToolPolicyForAgent(cfg, agentId);
467
+ return {
468
+ mode: agentSandbox?.mode ?? agent?.mode ?? "off",
469
+ scope,
470
+ workspaceAccess: agentSandbox?.workspaceAccess ?? agent?.workspaceAccess ?? "none",
471
+ workspaceRoot: agentSandbox?.workspaceRoot ?? agent?.workspaceRoot ?? DEFAULT_SANDBOX_WORKSPACE_ROOT,
472
+ docker: resolveSandboxDockerConfig({
473
+ scope,
474
+ globalDocker: agent?.docker,
475
+ agentDocker: agentSandbox?.docker
476
+ }),
477
+ browser: resolveSandboxBrowserConfig({
478
+ scope,
479
+ globalBrowser: agent?.browser,
480
+ agentBrowser: agentSandbox?.browser
481
+ }),
482
+ tools: {
483
+ allow: toolPolicy.allow,
484
+ deny: toolPolicy.deny
485
+ },
486
+ prune: resolveSandboxPruneConfig({
487
+ scope,
488
+ globalPrune: agent?.prune,
489
+ agentPrune: agentSandbox?.prune
490
+ })
491
+ };
492
+ }
493
+
494
+ //#endregion
495
+ //#region src/browser/bridge-server.ts
496
+ async function startBrowserBridgeServer(params) {
497
+ const host = params.host ?? "127.0.0.1";
498
+ const port = params.port ?? 0;
499
+ const app = express();
500
+ app.use(express.json({ limit: "1mb" }));
501
+ const authToken = params.authToken?.trim();
502
+ if (authToken) app.use((req, res, next) => {
503
+ if (String(req.headers.authorization ?? "").trim() === `Bearer ${authToken}`) return next();
504
+ res.status(401).send("Unauthorized");
505
+ });
506
+ const state = {
507
+ server: null,
508
+ port,
509
+ resolved: params.resolved,
510
+ profiles: /* @__PURE__ */ new Map()
511
+ };
512
+ registerBrowserRoutes(app, createBrowserRouteContext({
513
+ getState: () => state,
514
+ onEnsureAttachTarget: params.onEnsureAttachTarget
515
+ }));
516
+ const server = await new Promise((resolve, reject) => {
517
+ const s = app.listen(port, host, () => resolve(s));
518
+ s.once("error", reject);
519
+ });
520
+ const resolvedPort = server.address()?.port ?? port;
521
+ state.server = server;
522
+ state.port = resolvedPort;
523
+ state.resolved.controlPort = resolvedPort;
524
+ return {
525
+ server,
526
+ port: resolvedPort,
527
+ baseUrl: `http://${host}:${resolvedPort}`,
528
+ state
529
+ };
530
+ }
531
+ async function stopBrowserBridgeServer(server) {
532
+ await new Promise((resolve) => {
533
+ server.close(() => resolve());
534
+ });
535
+ }
536
+
537
+ //#endregion
538
+ //#region src/agents/sandbox/browser-bridges.ts
539
+ const BROWSER_BRIDGES = /* @__PURE__ */ new Map();
540
+
541
+ //#endregion
542
+ //#region src/agents/sandbox/config-hash.ts
543
+ function isPrimitive(value) {
544
+ return value === null || typeof value !== "object" && typeof value !== "function";
545
+ }
546
+ function normalizeForHash(value) {
547
+ if (value === void 0) return;
548
+ if (Array.isArray(value)) {
549
+ const normalized = value.map(normalizeForHash).filter((item) => item !== void 0);
550
+ const primitives = normalized.filter(isPrimitive);
551
+ if (primitives.length === normalized.length) return [...primitives].toSorted((a, b) => primitiveToString(a).localeCompare(primitiveToString(b)));
552
+ return normalized;
553
+ }
554
+ if (value && typeof value === "object") {
555
+ const entries = Object.entries(value).toSorted(([a], [b]) => a.localeCompare(b));
556
+ const normalized = {};
557
+ for (const [key, entryValue] of entries) {
558
+ const next = normalizeForHash(entryValue);
559
+ if (next !== void 0) normalized[key] = next;
560
+ }
561
+ return normalized;
562
+ }
563
+ return value;
564
+ }
565
+ function primitiveToString(value) {
566
+ if (value === null) return "null";
567
+ if (typeof value === "string") return value;
568
+ if (typeof value === "number") return String(value);
569
+ if (typeof value === "boolean") return value ? "true" : "false";
570
+ return JSON.stringify(value);
571
+ }
572
+ function computeSandboxConfigHash(input) {
573
+ const payload = normalizeForHash(input);
574
+ const raw = JSON.stringify(payload);
575
+ return crypto.createHash("sha1").update(raw).digest("hex");
576
+ }
577
+
578
+ //#endregion
579
+ //#region src/agents/sandbox/registry.ts
580
+ async function readRegistry() {
581
+ try {
582
+ const raw = await fs$1.readFile(SANDBOX_REGISTRY_PATH, "utf-8");
583
+ const parsed = JSON.parse(raw);
584
+ if (parsed && Array.isArray(parsed.entries)) return parsed;
585
+ } catch {}
586
+ return { entries: [] };
587
+ }
588
+ async function writeRegistry(registry) {
589
+ await fs$1.mkdir(SANDBOX_STATE_DIR, { recursive: true });
590
+ await fs$1.writeFile(SANDBOX_REGISTRY_PATH, `${JSON.stringify(registry, null, 2)}\n`, "utf-8");
591
+ }
592
+ async function updateRegistry(entry) {
593
+ const registry = await readRegistry();
594
+ const existing = registry.entries.find((item) => item.containerName === entry.containerName);
595
+ const next = registry.entries.filter((item) => item.containerName !== entry.containerName);
596
+ next.push({
597
+ ...entry,
598
+ createdAtMs: existing?.createdAtMs ?? entry.createdAtMs,
599
+ image: existing?.image ?? entry.image,
600
+ configHash: entry.configHash ?? existing?.configHash
601
+ });
602
+ await writeRegistry({ entries: next });
603
+ }
604
+ async function removeRegistryEntry(containerName) {
605
+ const registry = await readRegistry();
606
+ const next = registry.entries.filter((item) => item.containerName !== containerName);
607
+ if (next.length === registry.entries.length) return;
608
+ await writeRegistry({ entries: next });
609
+ }
610
+ async function readBrowserRegistry() {
611
+ try {
612
+ const raw = await fs$1.readFile(SANDBOX_BROWSER_REGISTRY_PATH, "utf-8");
613
+ const parsed = JSON.parse(raw);
614
+ if (parsed && Array.isArray(parsed.entries)) return parsed;
615
+ } catch {}
616
+ return { entries: [] };
617
+ }
618
+ async function writeBrowserRegistry(registry) {
619
+ await fs$1.mkdir(SANDBOX_STATE_DIR, { recursive: true });
620
+ await fs$1.writeFile(SANDBOX_BROWSER_REGISTRY_PATH, `${JSON.stringify(registry, null, 2)}\n`, "utf-8");
621
+ }
622
+ async function updateBrowserRegistry(entry) {
623
+ const registry = await readBrowserRegistry();
624
+ const existing = registry.entries.find((item) => item.containerName === entry.containerName);
625
+ const next = registry.entries.filter((item) => item.containerName !== entry.containerName);
626
+ next.push({
627
+ ...entry,
628
+ createdAtMs: existing?.createdAtMs ?? entry.createdAtMs,
629
+ image: existing?.image ?? entry.image
630
+ });
631
+ await writeBrowserRegistry({ entries: next });
632
+ }
633
+ async function removeBrowserRegistryEntry(containerName) {
634
+ const registry = await readBrowserRegistry();
635
+ const next = registry.entries.filter((item) => item.containerName !== containerName);
636
+ if (next.length === registry.entries.length) return;
637
+ await writeBrowserRegistry({ entries: next });
638
+ }
639
+
640
+ //#endregion
641
+ //#region src/agents/sandbox/shared.ts
642
+ function slugifySessionKey(value) {
643
+ const trimmed = value.trim() || "session";
644
+ const hash = crypto.createHash("sha1").update(trimmed).digest("hex").slice(0, 8);
645
+ return `${trimmed.toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 32) || "session"}-${hash}`;
646
+ }
647
+ function resolveSandboxWorkspaceDir(root, sessionKey) {
648
+ const resolvedRoot = resolveUserPath(root);
649
+ const slug = slugifySessionKey(sessionKey);
650
+ return path.join(resolvedRoot, slug);
651
+ }
652
+ function resolveSandboxScopeKey(scope, sessionKey) {
653
+ const trimmed = sessionKey.trim() || "main";
654
+ if (scope === "shared") return "shared";
655
+ if (scope === "session") return trimmed;
656
+ return `agent:${resolveAgentIdFromSessionKey(trimmed)}`;
657
+ }
658
+ function resolveSandboxAgentId(scopeKey) {
659
+ const trimmed = scopeKey.trim();
660
+ if (!trimmed || trimmed === "shared") return;
661
+ const parts = trimmed.split(":").filter(Boolean);
662
+ if (parts[0] === "agent" && parts[1]) return normalizeAgentId(parts[1]);
663
+ return resolveAgentIdFromSessionKey(trimmed);
664
+ }
665
+
666
+ //#endregion
667
+ //#region src/agents/sandbox/docker.ts
668
+ const HOT_CONTAINER_WINDOW_MS = 300 * 1e3;
669
+ function execDocker(args, opts) {
670
+ return new Promise((resolve, reject) => {
671
+ const child = spawn("docker", args, { stdio: [
672
+ "ignore",
673
+ "pipe",
674
+ "pipe"
675
+ ] });
676
+ let stdout = "";
677
+ let stderr = "";
678
+ child.stdout?.on("data", (chunk) => {
679
+ stdout += chunk.toString();
680
+ });
681
+ child.stderr?.on("data", (chunk) => {
682
+ stderr += chunk.toString();
683
+ });
684
+ child.on("close", (code) => {
685
+ const exitCode = code ?? 0;
686
+ if (exitCode !== 0 && !opts?.allowFailure) {
687
+ reject(new Error(stderr.trim() || `docker ${args.join(" ")} failed`));
688
+ return;
689
+ }
690
+ resolve({
691
+ stdout,
692
+ stderr,
693
+ code: exitCode
694
+ });
695
+ });
696
+ });
697
+ }
698
+ async function readDockerPort(containerName, port) {
699
+ const result = await execDocker([
700
+ "port",
701
+ containerName,
702
+ `${port}/tcp`
703
+ ], { allowFailure: true });
704
+ if (result.code !== 0) return null;
705
+ const match = (result.stdout.trim().split(/\r?\n/)[0] ?? "").match(/:(\d+)\s*$/);
706
+ if (!match) return null;
707
+ const mapped = Number.parseInt(match[1] ?? "", 10);
708
+ return Number.isFinite(mapped) ? mapped : null;
709
+ }
710
+ async function dockerImageExists(image) {
711
+ const result = await execDocker([
712
+ "image",
713
+ "inspect",
714
+ image
715
+ ], { allowFailure: true });
716
+ if (result.code === 0) return true;
717
+ const stderr = result.stderr.trim();
718
+ if (stderr.includes("No such image")) return false;
719
+ throw new Error(`Failed to inspect sandbox image: ${stderr}`);
720
+ }
721
+ async function ensureDockerImage(image) {
722
+ if (await dockerImageExists(image)) return;
723
+ if (image === DEFAULT_SANDBOX_IMAGE) {
724
+ await execDocker(["pull", "debian:bookworm-slim"]);
725
+ await execDocker([
726
+ "tag",
727
+ "debian:bookworm-slim",
728
+ DEFAULT_SANDBOX_IMAGE
729
+ ]);
730
+ return;
731
+ }
732
+ throw new Error(`Sandbox image not found: ${image}. Build or pull it first.`);
733
+ }
734
+ async function dockerContainerState(name) {
735
+ const result = await execDocker([
736
+ "inspect",
737
+ "-f",
738
+ "{{.State.Running}}",
739
+ name
740
+ ], { allowFailure: true });
741
+ if (result.code !== 0) return {
742
+ exists: false,
743
+ running: false
744
+ };
745
+ return {
746
+ exists: true,
747
+ running: result.stdout.trim() === "true"
748
+ };
749
+ }
750
+ function normalizeDockerLimit(value) {
751
+ if (value === void 0 || value === null) return;
752
+ if (typeof value === "number") return Number.isFinite(value) ? String(value) : void 0;
753
+ const trimmed = value.trim();
754
+ return trimmed ? trimmed : void 0;
755
+ }
756
+ function formatUlimitValue(name, value) {
757
+ if (!name.trim()) return null;
758
+ if (typeof value === "number" || typeof value === "string") {
759
+ const raw = String(value).trim();
760
+ return raw ? `${name}=${raw}` : null;
761
+ }
762
+ const soft = typeof value.soft === "number" ? Math.max(0, value.soft) : void 0;
763
+ const hard = typeof value.hard === "number" ? Math.max(0, value.hard) : void 0;
764
+ if (soft === void 0 && hard === void 0) return null;
765
+ if (soft === void 0) return `${name}=${hard}`;
766
+ if (hard === void 0) return `${name}=${soft}`;
767
+ return `${name}=${soft}:${hard}`;
768
+ }
769
+ function buildSandboxCreateArgs(params) {
770
+ const createdAtMs = params.createdAtMs ?? Date.now();
771
+ const args = [
772
+ "create",
773
+ "--name",
774
+ params.name
775
+ ];
776
+ args.push("--label", "openclaw.sandbox=1");
777
+ args.push("--label", `openclaw.sessionKey=${params.scopeKey}`);
778
+ args.push("--label", `openclaw.createdAtMs=${createdAtMs}`);
779
+ if (params.configHash) args.push("--label", `openclaw.configHash=${params.configHash}`);
780
+ for (const [key, value] of Object.entries(params.labels ?? {})) if (key && value) args.push("--label", `${key}=${value}`);
781
+ if (params.cfg.readOnlyRoot) args.push("--read-only");
782
+ for (const entry of params.cfg.tmpfs) args.push("--tmpfs", entry);
783
+ if (params.cfg.network) args.push("--network", params.cfg.network);
784
+ if (params.cfg.user) args.push("--user", params.cfg.user);
785
+ for (const cap of params.cfg.capDrop) args.push("--cap-drop", cap);
786
+ args.push("--security-opt", "no-new-privileges");
787
+ if (params.cfg.seccompProfile) args.push("--security-opt", `seccomp=${params.cfg.seccompProfile}`);
788
+ if (params.cfg.apparmorProfile) args.push("--security-opt", `apparmor=${params.cfg.apparmorProfile}`);
789
+ for (const entry of params.cfg.dns ?? []) if (entry.trim()) args.push("--dns", entry);
790
+ for (const entry of params.cfg.extraHosts ?? []) if (entry.trim()) args.push("--add-host", entry);
791
+ if (typeof params.cfg.pidsLimit === "number" && params.cfg.pidsLimit > 0) args.push("--pids-limit", String(params.cfg.pidsLimit));
792
+ const memory = normalizeDockerLimit(params.cfg.memory);
793
+ if (memory) args.push("--memory", memory);
794
+ const memorySwap = normalizeDockerLimit(params.cfg.memorySwap);
795
+ if (memorySwap) args.push("--memory-swap", memorySwap);
796
+ if (typeof params.cfg.cpus === "number" && params.cfg.cpus > 0) args.push("--cpus", String(params.cfg.cpus));
797
+ for (const [name, value] of Object.entries(params.cfg.ulimits ?? {})) {
798
+ const formatted = formatUlimitValue(name, value);
799
+ if (formatted) args.push("--ulimit", formatted);
800
+ }
801
+ if (params.cfg.binds?.length) for (const bind of params.cfg.binds) args.push("-v", bind);
802
+ return args;
803
+ }
804
+ async function createSandboxContainer(params) {
805
+ const { name, cfg, workspaceDir, scopeKey } = params;
806
+ await ensureDockerImage(cfg.image);
807
+ const args = buildSandboxCreateArgs({
808
+ name,
809
+ cfg,
810
+ scopeKey,
811
+ configHash: params.configHash
812
+ });
813
+ args.push("--workdir", cfg.workdir);
814
+ const mainMountSuffix = params.workspaceAccess === "ro" && workspaceDir === params.agentWorkspaceDir ? ":ro" : "";
815
+ args.push("-v", `${workspaceDir}:${cfg.workdir}${mainMountSuffix}`);
816
+ if (params.workspaceAccess !== "none" && workspaceDir !== params.agentWorkspaceDir) {
817
+ const agentMountSuffix = params.workspaceAccess === "ro" ? ":ro" : "";
818
+ args.push("-v", `${params.agentWorkspaceDir}:${SANDBOX_AGENT_WORKSPACE_MOUNT}${agentMountSuffix}`);
819
+ }
820
+ args.push(cfg.image, "sleep", "infinity");
821
+ await execDocker(args);
822
+ await execDocker(["start", name]);
823
+ if (cfg.setupCommand?.trim()) await execDocker([
824
+ "exec",
825
+ "-i",
826
+ name,
827
+ "sh",
828
+ "-lc",
829
+ cfg.setupCommand
830
+ ]);
831
+ }
832
+ async function readContainerConfigHash(containerName) {
833
+ const readLabel = async (label) => {
834
+ const result = await execDocker([
835
+ "inspect",
836
+ "-f",
837
+ `{{ index .Config.Labels "${label}" }}`,
838
+ containerName
839
+ ], { allowFailure: true });
840
+ if (result.code !== 0) return null;
841
+ const raw = result.stdout.trim();
842
+ if (!raw || raw === "<no value>") return null;
843
+ return raw;
844
+ };
845
+ return await readLabel("openclaw.configHash");
846
+ }
847
+ function formatSandboxRecreateHint(params) {
848
+ if (params.scope === "session") return formatCliCommand(`openclaw sandbox recreate --session ${params.sessionKey}`);
849
+ if (params.scope === "agent") return formatCliCommand(`openclaw sandbox recreate --agent ${resolveSandboxAgentId(params.sessionKey) ?? "main"}`);
850
+ return formatCliCommand("openclaw sandbox recreate --all");
851
+ }
852
+ async function ensureSandboxContainer(params) {
853
+ const scopeKey = resolveSandboxScopeKey(params.cfg.scope, params.sessionKey);
854
+ const slug = params.cfg.scope === "shared" ? "shared" : slugifySessionKey(scopeKey);
855
+ const containerName = `${params.cfg.docker.containerPrefix}${slug}`.slice(0, 63);
856
+ const expectedHash = computeSandboxConfigHash({
857
+ docker: params.cfg.docker,
858
+ workspaceAccess: params.cfg.workspaceAccess,
859
+ workspaceDir: params.workspaceDir,
860
+ agentWorkspaceDir: params.agentWorkspaceDir
861
+ });
862
+ const now = Date.now();
863
+ const state = await dockerContainerState(containerName);
864
+ let hasContainer = state.exists;
865
+ let running = state.running;
866
+ let currentHash = null;
867
+ let hashMismatch = false;
868
+ let registryEntry;
869
+ if (hasContainer) {
870
+ registryEntry = (await readRegistry()).entries.find((entry) => entry.containerName === containerName);
871
+ currentHash = await readContainerConfigHash(containerName);
872
+ if (!currentHash) currentHash = registryEntry?.configHash ?? null;
873
+ hashMismatch = !currentHash || currentHash !== expectedHash;
874
+ if (hashMismatch) {
875
+ const lastUsedAtMs = registryEntry?.lastUsedAtMs;
876
+ if (running && (typeof lastUsedAtMs !== "number" || now - lastUsedAtMs < HOT_CONTAINER_WINDOW_MS)) {
877
+ const hint = formatSandboxRecreateHint({
878
+ scope: params.cfg.scope,
879
+ sessionKey: scopeKey
880
+ });
881
+ defaultRuntime.log(`Sandbox config changed for ${containerName} (recently used). Recreate to apply: ${hint}`);
882
+ } else {
883
+ await execDocker([
884
+ "rm",
885
+ "-f",
886
+ containerName
887
+ ], { allowFailure: true });
888
+ hasContainer = false;
889
+ running = false;
890
+ }
891
+ }
892
+ }
893
+ if (!hasContainer) await createSandboxContainer({
894
+ name: containerName,
895
+ cfg: params.cfg.docker,
896
+ workspaceDir: params.workspaceDir,
897
+ workspaceAccess: params.cfg.workspaceAccess,
898
+ agentWorkspaceDir: params.agentWorkspaceDir,
899
+ scopeKey,
900
+ configHash: expectedHash
901
+ });
902
+ else if (!running) await execDocker(["start", containerName]);
903
+ await updateRegistry({
904
+ containerName,
905
+ sessionKey: scopeKey,
906
+ createdAtMs: now,
907
+ lastUsedAtMs: now,
908
+ image: params.cfg.docker.image,
909
+ configHash: hashMismatch && running ? currentHash ?? void 0 : expectedHash
910
+ });
911
+ return containerName;
912
+ }
913
+
914
+ //#endregion
915
+ //#region src/agents/sandbox/browser.ts
916
+ async function waitForSandboxCdp(params) {
917
+ const deadline = Date.now() + Math.max(0, params.timeoutMs);
918
+ const url = `http://127.0.0.1:${params.cdpPort}/json/version`;
919
+ while (Date.now() < deadline) {
920
+ try {
921
+ const ctrl = new AbortController();
922
+ const t = setTimeout(() => ctrl.abort(), 1e3);
923
+ try {
924
+ if ((await fetch(url, { signal: ctrl.signal })).ok) return true;
925
+ } finally {
926
+ clearTimeout(t);
927
+ }
928
+ } catch {}
929
+ await new Promise((r) => setTimeout(r, 150));
930
+ }
931
+ return false;
932
+ }
933
+ function buildSandboxBrowserResolvedConfig(params) {
934
+ return {
935
+ enabled: true,
936
+ evaluateEnabled: params.evaluateEnabled,
937
+ controlPort: params.controlPort,
938
+ cdpProtocol: "http",
939
+ cdpHost: "127.0.0.1",
940
+ cdpIsLoopback: true,
941
+ remoteCdpTimeoutMs: 1500,
942
+ remoteCdpHandshakeTimeoutMs: 3e3,
943
+ color: DEFAULT_OPENCLAW_BROWSER_COLOR,
944
+ executablePath: void 0,
945
+ headless: params.headless,
946
+ noSandbox: false,
947
+ attachOnly: true,
948
+ defaultProfile: DEFAULT_OPENCLAW_BROWSER_PROFILE_NAME,
949
+ profiles: { [DEFAULT_OPENCLAW_BROWSER_PROFILE_NAME]: {
950
+ cdpPort: params.cdpPort,
951
+ color: DEFAULT_OPENCLAW_BROWSER_COLOR
952
+ } }
953
+ };
954
+ }
955
+ async function ensureSandboxBrowserImage(image) {
956
+ if ((await execDocker([
957
+ "image",
958
+ "inspect",
959
+ image
960
+ ], { allowFailure: true })).code === 0) return;
961
+ throw new Error(`Sandbox browser image not found: ${image}. Build it with scripts/sandbox-browser-setup.sh.`);
962
+ }
963
+ async function ensureSandboxBrowser(params) {
964
+ if (!params.cfg.browser.enabled) return null;
965
+ if (!isToolAllowed(params.cfg.tools, "browser")) return null;
966
+ const slug = params.cfg.scope === "shared" ? "shared" : slugifySessionKey(params.scopeKey);
967
+ const containerName = `${params.cfg.browser.containerPrefix}${slug}`.slice(0, 63);
968
+ const state = await dockerContainerState(containerName);
969
+ if (!state.exists) {
970
+ await ensureSandboxBrowserImage(params.cfg.browser.image ?? DEFAULT_SANDBOX_BROWSER_IMAGE);
971
+ const args = buildSandboxCreateArgs({
972
+ name: containerName,
973
+ cfg: params.cfg.docker,
974
+ scopeKey: params.scopeKey,
975
+ labels: { "openclaw.sandboxBrowser": "1" }
976
+ });
977
+ const mainMountSuffix = params.cfg.workspaceAccess === "ro" && params.workspaceDir === params.agentWorkspaceDir ? ":ro" : "";
978
+ args.push("-v", `${params.workspaceDir}:${params.cfg.docker.workdir}${mainMountSuffix}`);
979
+ if (params.cfg.workspaceAccess !== "none" && params.workspaceDir !== params.agentWorkspaceDir) {
980
+ const agentMountSuffix = params.cfg.workspaceAccess === "ro" ? ":ro" : "";
981
+ args.push("-v", `${params.agentWorkspaceDir}:${SANDBOX_AGENT_WORKSPACE_MOUNT}${agentMountSuffix}`);
982
+ }
983
+ args.push("-p", `127.0.0.1::${params.cfg.browser.cdpPort}`);
984
+ if (params.cfg.browser.enableNoVnc && !params.cfg.browser.headless) args.push("-p", `127.0.0.1::${params.cfg.browser.noVncPort}`);
985
+ args.push("-e", `OPENCLAW_BROWSER_HEADLESS=${params.cfg.browser.headless ? "1" : "0"}`);
986
+ args.push("-e", `OPENCLAW_BROWSER_ENABLE_NOVNC=${params.cfg.browser.enableNoVnc ? "1" : "0"}`);
987
+ args.push("-e", `OPENCLAW_BROWSER_CDP_PORT=${params.cfg.browser.cdpPort}`);
988
+ args.push("-e", `OPENCLAW_BROWSER_VNC_PORT=${params.cfg.browser.vncPort}`);
989
+ args.push("-e", `OPENCLAW_BROWSER_NOVNC_PORT=${params.cfg.browser.noVncPort}`);
990
+ args.push(params.cfg.browser.image);
991
+ await execDocker(args);
992
+ await execDocker(["start", containerName]);
993
+ } else if (!state.running) await execDocker(["start", containerName]);
994
+ const mappedCdp = await readDockerPort(containerName, params.cfg.browser.cdpPort);
995
+ if (!mappedCdp) throw new Error(`Failed to resolve CDP port mapping for ${containerName}.`);
996
+ const mappedNoVnc = params.cfg.browser.enableNoVnc && !params.cfg.browser.headless ? await readDockerPort(containerName, params.cfg.browser.noVncPort) : null;
997
+ const existing = BROWSER_BRIDGES.get(params.scopeKey);
998
+ const existingProfile = existing ? resolveProfile(existing.bridge.state.resolved, DEFAULT_OPENCLAW_BROWSER_PROFILE_NAME) : null;
999
+ const shouldReuse = existing && existing.containerName === containerName && existingProfile?.cdpPort === mappedCdp;
1000
+ if (existing && !shouldReuse) {
1001
+ await stopBrowserBridgeServer(existing.bridge.server).catch(() => void 0);
1002
+ BROWSER_BRIDGES.delete(params.scopeKey);
1003
+ }
1004
+ const bridge = (() => {
1005
+ if (shouldReuse && existing) return existing.bridge;
1006
+ return null;
1007
+ })();
1008
+ const ensureBridge = async () => {
1009
+ if (bridge) return bridge;
1010
+ const onEnsureAttachTarget = params.cfg.browser.autoStart ? async () => {
1011
+ const state = await dockerContainerState(containerName);
1012
+ if (state.exists && !state.running) await execDocker(["start", containerName]);
1013
+ if (!await waitForSandboxCdp({
1014
+ cdpPort: mappedCdp,
1015
+ timeoutMs: params.cfg.browser.autoStartTimeoutMs
1016
+ })) throw new Error(`Sandbox browser CDP did not become reachable on 127.0.0.1:${mappedCdp} within ${params.cfg.browser.autoStartTimeoutMs}ms.`);
1017
+ } : void 0;
1018
+ return await startBrowserBridgeServer({
1019
+ resolved: buildSandboxBrowserResolvedConfig({
1020
+ controlPort: 0,
1021
+ cdpPort: mappedCdp,
1022
+ headless: params.cfg.browser.headless,
1023
+ evaluateEnabled: params.evaluateEnabled ?? DEFAULT_BROWSER_EVALUATE_ENABLED
1024
+ }),
1025
+ onEnsureAttachTarget
1026
+ });
1027
+ };
1028
+ const resolvedBridge = await ensureBridge();
1029
+ if (!shouldReuse) BROWSER_BRIDGES.set(params.scopeKey, {
1030
+ bridge: resolvedBridge,
1031
+ containerName
1032
+ });
1033
+ const now = Date.now();
1034
+ await updateBrowserRegistry({
1035
+ containerName,
1036
+ sessionKey: params.scopeKey,
1037
+ createdAtMs: now,
1038
+ lastUsedAtMs: now,
1039
+ image: params.cfg.browser.image,
1040
+ cdpPort: mappedCdp,
1041
+ noVncPort: mappedNoVnc ?? void 0
1042
+ });
1043
+ const noVncUrl = mappedNoVnc && params.cfg.browser.enableNoVnc && !params.cfg.browser.headless ? `http://127.0.0.1:${mappedNoVnc}/vnc.html?autoconnect=1&resize=remote` : void 0;
1044
+ return {
1045
+ bridgeUrl: resolvedBridge.baseUrl,
1046
+ noVncUrl,
1047
+ containerName
1048
+ };
1049
+ }
1050
+
1051
+ //#endregion
1052
+ //#region src/agents/sandbox/prune.ts
1053
+ let lastPruneAtMs = 0;
1054
+ async function pruneSandboxContainers(cfg) {
1055
+ const now = Date.now();
1056
+ const idleHours = cfg.prune.idleHours;
1057
+ const maxAgeDays = cfg.prune.maxAgeDays;
1058
+ if (idleHours === 0 && maxAgeDays === 0) return;
1059
+ const registry = await readRegistry();
1060
+ for (const entry of registry.entries) {
1061
+ const idleMs = now - entry.lastUsedAtMs;
1062
+ const ageMs = now - entry.createdAtMs;
1063
+ if (idleHours > 0 && idleMs > idleHours * 60 * 60 * 1e3 || maxAgeDays > 0 && ageMs > maxAgeDays * 24 * 60 * 60 * 1e3) try {
1064
+ await execDocker([
1065
+ "rm",
1066
+ "-f",
1067
+ entry.containerName
1068
+ ], { allowFailure: true });
1069
+ } catch {} finally {
1070
+ await removeRegistryEntry(entry.containerName);
1071
+ }
1072
+ }
1073
+ }
1074
+ async function pruneSandboxBrowsers(cfg) {
1075
+ const now = Date.now();
1076
+ const idleHours = cfg.prune.idleHours;
1077
+ const maxAgeDays = cfg.prune.maxAgeDays;
1078
+ if (idleHours === 0 && maxAgeDays === 0) return;
1079
+ const registry = await readBrowserRegistry();
1080
+ for (const entry of registry.entries) {
1081
+ const idleMs = now - entry.lastUsedAtMs;
1082
+ const ageMs = now - entry.createdAtMs;
1083
+ if (idleHours > 0 && idleMs > idleHours * 60 * 60 * 1e3 || maxAgeDays > 0 && ageMs > maxAgeDays * 24 * 60 * 60 * 1e3) try {
1084
+ await execDocker([
1085
+ "rm",
1086
+ "-f",
1087
+ entry.containerName
1088
+ ], { allowFailure: true });
1089
+ } catch {} finally {
1090
+ await removeBrowserRegistryEntry(entry.containerName);
1091
+ const bridge = BROWSER_BRIDGES.get(entry.sessionKey);
1092
+ if (bridge?.containerName === entry.containerName) {
1093
+ await stopBrowserBridgeServer(bridge.bridge.server).catch(() => void 0);
1094
+ BROWSER_BRIDGES.delete(entry.sessionKey);
1095
+ }
1096
+ }
1097
+ }
1098
+ }
1099
+ async function maybePruneSandboxes(cfg) {
1100
+ const now = Date.now();
1101
+ if (now - lastPruneAtMs < 300 * 1e3) return;
1102
+ lastPruneAtMs = now;
1103
+ try {
1104
+ await pruneSandboxContainers(cfg);
1105
+ await pruneSandboxBrowsers(cfg);
1106
+ } catch (error) {
1107
+ const message = error instanceof Error ? error.message : typeof error === "string" ? error : JSON.stringify(error);
1108
+ defaultRuntime.error?.(`Sandbox prune failed: ${message ?? "unknown error"}`);
1109
+ }
1110
+ }
1111
+
1112
+ //#endregion
1113
+ //#region src/config/sessions/group.ts
1114
+ const getGroupSurfaces = () => new Set([...listDeliverableMessageChannels(), "webchat"]);
1115
+ function normalizeGroupLabel(raw) {
1116
+ const trimmed = raw?.trim().toLowerCase() ?? "";
1117
+ if (!trimmed) return "";
1118
+ return trimmed.replace(/\s+/g, "-").replace(/[^a-z0-9#@._+-]+/g, "-").replace(/-{2,}/g, "-").replace(/^[-.]+|[-.]+$/g, "");
1119
+ }
1120
+ function shortenGroupId(value) {
1121
+ const trimmed = value?.trim() ?? "";
1122
+ if (!trimmed) return "";
1123
+ if (trimmed.length <= 14) return trimmed;
1124
+ return `${trimmed.slice(0, 6)}...${trimmed.slice(-4)}`;
1125
+ }
1126
+ function buildGroupDisplayName(params) {
1127
+ const providerKey = (params.provider?.trim().toLowerCase() || "group").trim();
1128
+ const groupChannel = params.groupChannel?.trim();
1129
+ const space = params.space?.trim();
1130
+ const subject = params.subject?.trim();
1131
+ const detail = (groupChannel && space ? `${space}${groupChannel.startsWith("#") ? "" : "#"}${groupChannel}` : groupChannel || subject || space || "") || "";
1132
+ const fallbackId = params.id?.trim() || params.key;
1133
+ const rawLabel = detail || fallbackId;
1134
+ let token = normalizeGroupLabel(rawLabel);
1135
+ if (!token) token = normalizeGroupLabel(shortenGroupId(rawLabel));
1136
+ if (!params.groupChannel && token.startsWith("#")) token = token.replace(/^#+/, "");
1137
+ if (token && !/^[@#]/.test(token) && !token.startsWith("g-") && !token.includes("#")) token = `g-${token}`;
1138
+ return token ? `${providerKey}:${token}` : providerKey;
1139
+ }
1140
+ function resolveGroupSessionKey(ctx) {
1141
+ const from = typeof ctx.From === "string" ? ctx.From.trim() : "";
1142
+ const chatType = ctx.ChatType?.trim().toLowerCase();
1143
+ const normalizedChatType = chatType === "channel" ? "channel" : chatType === "group" ? "group" : void 0;
1144
+ const isWhatsAppGroupId = from.toLowerCase().endsWith("@g.us");
1145
+ if (!(normalizedChatType === "group" || normalizedChatType === "channel" || from.includes(":group:") || from.includes(":channel:") || isWhatsAppGroupId)) return null;
1146
+ const providerHint = ctx.Provider?.trim().toLowerCase();
1147
+ const parts = from.split(":").filter(Boolean);
1148
+ const head = parts[0]?.trim().toLowerCase() ?? "";
1149
+ const headIsSurface = head ? getGroupSurfaces().has(head) : false;
1150
+ const provider = headIsSurface ? head : providerHint ?? (isWhatsAppGroupId ? "whatsapp" : void 0);
1151
+ if (!provider) return null;
1152
+ const second = parts[1]?.trim().toLowerCase();
1153
+ const secondIsKind = second === "group" || second === "channel";
1154
+ const kind = secondIsKind ? second : from.includes(":channel:") || normalizedChatType === "channel" ? "channel" : "group";
1155
+ const finalId = (headIsSurface ? secondIsKind ? parts.slice(2).join(":") : parts.slice(1).join(":") : from).trim().toLowerCase();
1156
+ if (!finalId) return null;
1157
+ return {
1158
+ key: `${provider}:${kind}:${finalId}`,
1159
+ channel: provider,
1160
+ id: finalId,
1161
+ chatType: kind === "channel" ? "channel" : "group"
1162
+ };
1163
+ }
1164
+
1165
+ //#endregion
1166
+ //#region src/imessage/accounts.ts
1167
+ function resolveAccountConfig$1(cfg, accountId) {
1168
+ const accounts = cfg.channels?.imessage?.accounts;
1169
+ if (!accounts || typeof accounts !== "object") return;
1170
+ return accounts[accountId];
1171
+ }
1172
+ function mergeIMessageAccountConfig(cfg, accountId) {
1173
+ const { accounts: _ignored, ...base } = cfg.channels?.imessage ?? {};
1174
+ const account = resolveAccountConfig$1(cfg, accountId) ?? {};
1175
+ return {
1176
+ ...base,
1177
+ ...account
1178
+ };
1179
+ }
1180
+ function resolveIMessageAccount(params) {
1181
+ const accountId = normalizeAccountId$1(params.accountId);
1182
+ const baseEnabled = params.cfg.channels?.imessage?.enabled !== false;
1183
+ const merged = mergeIMessageAccountConfig(params.cfg, accountId);
1184
+ const accountEnabled = merged.enabled !== false;
1185
+ const configured = Boolean(merged.cliPath?.trim() || merged.dbPath?.trim() || merged.service || merged.region?.trim() || merged.allowFrom && merged.allowFrom.length > 0 || merged.groupAllowFrom && merged.groupAllowFrom.length > 0 || merged.dmPolicy || merged.groupPolicy || typeof merged.includeAttachments === "boolean" || typeof merged.mediaMaxMb === "number" || typeof merged.textChunkLimit === "number" || merged.groups && Object.keys(merged.groups).length > 0);
1186
+ return {
1187
+ accountId,
1188
+ enabled: baseEnabled && accountEnabled,
1189
+ name: merged.name?.trim() || void 0,
1190
+ config: merged,
1191
+ configured
1192
+ };
1193
+ }
1194
+
1195
+ //#endregion
1196
+ //#region src/signal/accounts.ts
1197
+ function listConfiguredAccountIds(cfg) {
1198
+ const accounts = cfg.channels?.signal?.accounts;
1199
+ if (!accounts || typeof accounts !== "object") return [];
1200
+ return Object.keys(accounts).filter(Boolean);
1201
+ }
1202
+ function listSignalAccountIds(cfg) {
1203
+ const ids = listConfiguredAccountIds(cfg);
1204
+ if (ids.length === 0) return [DEFAULT_ACCOUNT_ID];
1205
+ return ids.toSorted((a, b) => a.localeCompare(b));
1206
+ }
1207
+ function resolveAccountConfig(cfg, accountId) {
1208
+ const accounts = cfg.channels?.signal?.accounts;
1209
+ if (!accounts || typeof accounts !== "object") return;
1210
+ return accounts[accountId];
1211
+ }
1212
+ function mergeSignalAccountConfig(cfg, accountId) {
1213
+ const { accounts: _ignored, ...base } = cfg.channels?.signal ?? {};
1214
+ const account = resolveAccountConfig(cfg, accountId) ?? {};
1215
+ return {
1216
+ ...base,
1217
+ ...account
1218
+ };
1219
+ }
1220
+ function resolveSignalAccount(params) {
1221
+ const accountId = normalizeAccountId$1(params.accountId);
1222
+ const baseEnabled = params.cfg.channels?.signal?.enabled !== false;
1223
+ const merged = mergeSignalAccountConfig(params.cfg, accountId);
1224
+ const accountEnabled = merged.enabled !== false;
1225
+ const enabled = baseEnabled && accountEnabled;
1226
+ const host = merged.httpHost?.trim() || "127.0.0.1";
1227
+ const port = merged.httpPort ?? 8080;
1228
+ const baseUrl = merged.httpUrl?.trim() || `http://${host}:${port}`;
1229
+ const configured = Boolean(merged.account?.trim() || merged.httpUrl?.trim() || merged.cliPath?.trim() || merged.httpHost?.trim() || typeof merged.httpPort === "number" || typeof merged.autoStart === "boolean");
1230
+ return {
1231
+ accountId,
1232
+ enabled,
1233
+ name: merged.name?.trim() || void 0,
1234
+ baseUrl,
1235
+ configured,
1236
+ config: merged
1237
+ };
1238
+ }
1239
+ function listEnabledSignalAccounts(cfg) {
1240
+ return listSignalAccountIds(cfg).map((accountId) => resolveSignalAccount({
1241
+ cfg,
1242
+ accountId
1243
+ })).filter((account) => account.enabled);
1244
+ }
1245
+
1246
+ //#endregion
1247
+ //#region src/slack/threading-tool-context.ts
1248
+ function buildSlackThreadingToolContext(params) {
1249
+ const configuredReplyToMode = resolveSlackReplyToMode(resolveSlackAccount({
1250
+ cfg: params.cfg,
1251
+ accountId: params.accountId
1252
+ }), params.context.ChatType);
1253
+ const effectiveReplyToMode = params.context.ThreadLabel ? "all" : configuredReplyToMode;
1254
+ const threadId = params.context.MessageThreadId ?? params.context.ReplyToId;
1255
+ return {
1256
+ currentChannelId: params.context.To?.startsWith("channel:") ? params.context.To.slice(8) : void 0,
1257
+ currentThreadTs: threadId != null ? String(threadId) : void 0,
1258
+ replyToMode: effectiveReplyToMode,
1259
+ hasRepliedRef: params.hasRepliedRef
1260
+ };
1261
+ }
1262
+
1263
+ //#endregion
1264
+ //#region src/config/group-policy.ts
1265
+ function normalizeSenderKey(value) {
1266
+ const trimmed = value.trim();
1267
+ if (!trimmed) return "";
1268
+ return (trimmed.startsWith("@") ? trimmed.slice(1) : trimmed).toLowerCase();
1269
+ }
1270
+ function resolveToolsBySender(params) {
1271
+ const toolsBySender = params.toolsBySender;
1272
+ if (!toolsBySender) return;
1273
+ const entries = Object.entries(toolsBySender);
1274
+ if (entries.length === 0) return;
1275
+ const normalized = /* @__PURE__ */ new Map();
1276
+ let wildcard;
1277
+ for (const [rawKey, policy] of entries) {
1278
+ if (!policy) continue;
1279
+ const key = normalizeSenderKey(rawKey);
1280
+ if (!key) continue;
1281
+ if (key === "*") {
1282
+ wildcard = policy;
1283
+ continue;
1284
+ }
1285
+ if (!normalized.has(key)) normalized.set(key, policy);
1286
+ }
1287
+ const candidates = [];
1288
+ const pushCandidate = (value) => {
1289
+ const trimmed = value?.trim();
1290
+ if (!trimmed) return;
1291
+ candidates.push(trimmed);
1292
+ };
1293
+ pushCandidate(params.senderId);
1294
+ pushCandidate(params.senderE164);
1295
+ pushCandidate(params.senderUsername);
1296
+ pushCandidate(params.senderName);
1297
+ for (const candidate of candidates) {
1298
+ const key = normalizeSenderKey(candidate);
1299
+ if (!key) continue;
1300
+ const match = normalized.get(key);
1301
+ if (match) return match;
1302
+ }
1303
+ return wildcard;
1304
+ }
1305
+ function resolveChannelGroups(cfg, channel, accountId) {
1306
+ const normalizedAccountId = normalizeAccountId$1(accountId);
1307
+ const channelConfig = cfg.channels?.[channel];
1308
+ if (!channelConfig) return;
1309
+ return channelConfig.accounts?.[normalizedAccountId]?.groups ?? channelConfig.accounts?.[Object.keys(channelConfig.accounts ?? {}).find((key) => key.toLowerCase() === normalizedAccountId.toLowerCase()) ?? ""]?.groups ?? channelConfig.groups;
1310
+ }
1311
+ function resolveChannelGroupPolicy(params) {
1312
+ const { cfg, channel } = params;
1313
+ const groups = resolveChannelGroups(cfg, channel, params.accountId);
1314
+ const allowlistEnabled = Boolean(groups && Object.keys(groups).length > 0);
1315
+ const normalizedId = params.groupId?.trim();
1316
+ const groupConfig = normalizedId && groups ? groups[normalizedId] : void 0;
1317
+ const defaultConfig = groups?.["*"];
1318
+ return {
1319
+ allowlistEnabled,
1320
+ allowed: !allowlistEnabled || allowlistEnabled && Boolean(groups && Object.hasOwn(groups, "*")) || (normalizedId ? Boolean(groups && Object.hasOwn(groups, normalizedId)) : false),
1321
+ groupConfig,
1322
+ defaultConfig
1323
+ };
1324
+ }
1325
+ function resolveChannelGroupRequireMention(params) {
1326
+ const { requireMentionOverride, overrideOrder = "after-config" } = params;
1327
+ const { groupConfig, defaultConfig } = resolveChannelGroupPolicy(params);
1328
+ const configMention = typeof groupConfig?.requireMention === "boolean" ? groupConfig.requireMention : typeof defaultConfig?.requireMention === "boolean" ? defaultConfig.requireMention : void 0;
1329
+ if (overrideOrder === "before-config" && typeof requireMentionOverride === "boolean") return requireMentionOverride;
1330
+ if (typeof configMention === "boolean") return configMention;
1331
+ if (overrideOrder !== "before-config" && typeof requireMentionOverride === "boolean") return requireMentionOverride;
1332
+ return true;
1333
+ }
1334
+ function resolveChannelGroupToolsPolicy(params) {
1335
+ const { groupConfig, defaultConfig } = resolveChannelGroupPolicy(params);
1336
+ const groupSenderPolicy = resolveToolsBySender({
1337
+ toolsBySender: groupConfig?.toolsBySender,
1338
+ senderId: params.senderId,
1339
+ senderName: params.senderName,
1340
+ senderUsername: params.senderUsername,
1341
+ senderE164: params.senderE164
1342
+ });
1343
+ if (groupSenderPolicy) return groupSenderPolicy;
1344
+ if (groupConfig?.tools) return groupConfig.tools;
1345
+ const defaultSenderPolicy = resolveToolsBySender({
1346
+ toolsBySender: defaultConfig?.toolsBySender,
1347
+ senderId: params.senderId,
1348
+ senderName: params.senderName,
1349
+ senderUsername: params.senderUsername,
1350
+ senderE164: params.senderE164
1351
+ });
1352
+ if (defaultSenderPolicy) return defaultSenderPolicy;
1353
+ if (defaultConfig?.tools) return defaultConfig.tools;
1354
+ }
1355
+
1356
+ //#endregion
1357
+ //#region src/channels/plugins/group-mentions.ts
1358
+ function normalizeDiscordSlug(value) {
1359
+ if (!value) return "";
1360
+ let text = value.trim().toLowerCase();
1361
+ if (!text) return "";
1362
+ text = text.replace(/^[@#]+/, "");
1363
+ text = text.replace(/[\s_]+/g, "-");
1364
+ text = text.replace(/[^a-z0-9-]+/g, "-");
1365
+ text = text.replace(/-{2,}/g, "-").replace(/^-+|-+$/g, "");
1366
+ return text;
1367
+ }
1368
+ function normalizeSlackSlug(raw) {
1369
+ const trimmed = raw?.trim().toLowerCase() ?? "";
1370
+ if (!trimmed) return "";
1371
+ return trimmed.replace(/\s+/g, "-").replace(/[^a-z0-9#@._+-]+/g, "-").replace(/-{2,}/g, "-").replace(/^[-.]+|[-.]+$/g, "");
1372
+ }
1373
+ function parseTelegramGroupId(value) {
1374
+ const raw = value?.trim() ?? "";
1375
+ if (!raw) return {
1376
+ chatId: void 0,
1377
+ topicId: void 0
1378
+ };
1379
+ const parts = raw.split(":").filter(Boolean);
1380
+ if (parts.length >= 3 && parts[1] === "topic" && /^-?\d+$/.test(parts[0]) && /^\d+$/.test(parts[2])) return {
1381
+ chatId: parts[0],
1382
+ topicId: parts[2]
1383
+ };
1384
+ if (parts.length >= 2 && /^-?\d+$/.test(parts[0]) && /^\d+$/.test(parts[1])) return {
1385
+ chatId: parts[0],
1386
+ topicId: parts[1]
1387
+ };
1388
+ return {
1389
+ chatId: raw,
1390
+ topicId: void 0
1391
+ };
1392
+ }
1393
+ function resolveTelegramRequireMention(params) {
1394
+ const { cfg, chatId, topicId } = params;
1395
+ if (!chatId) return;
1396
+ const groupConfig = cfg.channels?.telegram?.groups?.[chatId];
1397
+ const groupDefault = cfg.channels?.telegram?.groups?.["*"];
1398
+ const topicConfig = topicId && groupConfig?.topics ? groupConfig.topics[topicId] : void 0;
1399
+ const defaultTopicConfig = topicId && groupDefault?.topics ? groupDefault.topics[topicId] : void 0;
1400
+ if (typeof topicConfig?.requireMention === "boolean") return topicConfig.requireMention;
1401
+ if (typeof defaultTopicConfig?.requireMention === "boolean") return defaultTopicConfig.requireMention;
1402
+ if (typeof groupConfig?.requireMention === "boolean") return groupConfig.requireMention;
1403
+ if (typeof groupDefault?.requireMention === "boolean") return groupDefault.requireMention;
1404
+ }
1405
+ function resolveDiscordGuildEntry(guilds, groupSpace) {
1406
+ if (!guilds || Object.keys(guilds).length === 0) return null;
1407
+ const space = groupSpace?.trim() ?? "";
1408
+ if (space && guilds[space]) return guilds[space];
1409
+ const normalized = normalizeDiscordSlug(space);
1410
+ if (normalized && guilds[normalized]) return guilds[normalized];
1411
+ if (normalized) {
1412
+ const match = Object.values(guilds).find((entry) => normalizeDiscordSlug(entry?.slug ?? void 0) === normalized);
1413
+ if (match) return match;
1414
+ }
1415
+ return guilds["*"] ?? null;
1416
+ }
1417
+ function resolveTelegramGroupRequireMention(params) {
1418
+ const { chatId, topicId } = parseTelegramGroupId(params.groupId);
1419
+ const requireMention = resolveTelegramRequireMention({
1420
+ cfg: params.cfg,
1421
+ chatId,
1422
+ topicId
1423
+ });
1424
+ if (typeof requireMention === "boolean") return requireMention;
1425
+ return resolveChannelGroupRequireMention({
1426
+ cfg: params.cfg,
1427
+ channel: "telegram",
1428
+ groupId: chatId ?? params.groupId,
1429
+ accountId: params.accountId
1430
+ });
1431
+ }
1432
+ function resolveWhatsAppGroupRequireMention(params) {
1433
+ return resolveChannelGroupRequireMention({
1434
+ cfg: params.cfg,
1435
+ channel: "whatsapp",
1436
+ groupId: params.groupId,
1437
+ accountId: params.accountId
1438
+ });
1439
+ }
1440
+ function resolveIMessageGroupRequireMention(params) {
1441
+ return resolveChannelGroupRequireMention({
1442
+ cfg: params.cfg,
1443
+ channel: "imessage",
1444
+ groupId: params.groupId,
1445
+ accountId: params.accountId
1446
+ });
1447
+ }
1448
+ function resolveDiscordGroupRequireMention(params) {
1449
+ const guildEntry = resolveDiscordGuildEntry(params.cfg.channels?.discord?.guilds, params.groupSpace);
1450
+ const channelEntries = guildEntry?.channels;
1451
+ if (channelEntries && Object.keys(channelEntries).length > 0) {
1452
+ const groupChannel = params.groupChannel;
1453
+ const channelSlug = normalizeDiscordSlug(groupChannel);
1454
+ const entry = (params.groupId ? channelEntries[params.groupId] : void 0) ?? (channelSlug ? channelEntries[channelSlug] ?? channelEntries[`#${channelSlug}`] : void 0) ?? (groupChannel ? channelEntries[normalizeDiscordSlug(groupChannel)] : void 0);
1455
+ if (entry && typeof entry.requireMention === "boolean") return entry.requireMention;
1456
+ }
1457
+ if (typeof guildEntry?.requireMention === "boolean") return guildEntry.requireMention;
1458
+ return true;
1459
+ }
1460
+ function resolveGoogleChatGroupRequireMention(params) {
1461
+ return resolveChannelGroupRequireMention({
1462
+ cfg: params.cfg,
1463
+ channel: "googlechat",
1464
+ groupId: params.groupId,
1465
+ accountId: params.accountId
1466
+ });
1467
+ }
1468
+ function resolveGoogleChatGroupToolPolicy(params) {
1469
+ return resolveChannelGroupToolsPolicy({
1470
+ cfg: params.cfg,
1471
+ channel: "googlechat",
1472
+ groupId: params.groupId,
1473
+ accountId: params.accountId,
1474
+ senderId: params.senderId,
1475
+ senderName: params.senderName,
1476
+ senderUsername: params.senderUsername,
1477
+ senderE164: params.senderE164
1478
+ });
1479
+ }
1480
+ function resolveSlackGroupRequireMention(params) {
1481
+ const channels = resolveSlackAccount({
1482
+ cfg: params.cfg,
1483
+ accountId: params.accountId
1484
+ }).channels ?? {};
1485
+ if (Object.keys(channels).length === 0) return true;
1486
+ const channelId = params.groupId?.trim();
1487
+ const channelName = params.groupChannel?.replace(/^#/, "");
1488
+ const normalizedName = normalizeSlackSlug(channelName);
1489
+ const candidates = [
1490
+ channelId ?? "",
1491
+ channelName ? `#${channelName}` : "",
1492
+ channelName ?? "",
1493
+ normalizedName
1494
+ ].filter(Boolean);
1495
+ let matched;
1496
+ for (const candidate of candidates) if (candidate && channels[candidate]) {
1497
+ matched = channels[candidate];
1498
+ break;
1499
+ }
1500
+ const fallback = channels["*"];
1501
+ const resolved = matched ?? fallback;
1502
+ if (typeof resolved?.requireMention === "boolean") return resolved.requireMention;
1503
+ return true;
1504
+ }
1505
+ function resolveTelegramGroupToolPolicy(params) {
1506
+ const { chatId } = parseTelegramGroupId(params.groupId);
1507
+ return resolveChannelGroupToolsPolicy({
1508
+ cfg: params.cfg,
1509
+ channel: "telegram",
1510
+ groupId: chatId ?? params.groupId,
1511
+ accountId: params.accountId,
1512
+ senderId: params.senderId,
1513
+ senderName: params.senderName,
1514
+ senderUsername: params.senderUsername,
1515
+ senderE164: params.senderE164
1516
+ });
1517
+ }
1518
+ function resolveWhatsAppGroupToolPolicy(params) {
1519
+ return resolveChannelGroupToolsPolicy({
1520
+ cfg: params.cfg,
1521
+ channel: "whatsapp",
1522
+ groupId: params.groupId,
1523
+ accountId: params.accountId,
1524
+ senderId: params.senderId,
1525
+ senderName: params.senderName,
1526
+ senderUsername: params.senderUsername,
1527
+ senderE164: params.senderE164
1528
+ });
1529
+ }
1530
+ function resolveIMessageGroupToolPolicy(params) {
1531
+ return resolveChannelGroupToolsPolicy({
1532
+ cfg: params.cfg,
1533
+ channel: "imessage",
1534
+ groupId: params.groupId,
1535
+ accountId: params.accountId,
1536
+ senderId: params.senderId,
1537
+ senderName: params.senderName,
1538
+ senderUsername: params.senderUsername,
1539
+ senderE164: params.senderE164
1540
+ });
1541
+ }
1542
+ function resolveDiscordGroupToolPolicy(params) {
1543
+ const guildEntry = resolveDiscordGuildEntry(params.cfg.channels?.discord?.guilds, params.groupSpace);
1544
+ const channelEntries = guildEntry?.channels;
1545
+ if (channelEntries && Object.keys(channelEntries).length > 0) {
1546
+ const groupChannel = params.groupChannel;
1547
+ const channelSlug = normalizeDiscordSlug(groupChannel);
1548
+ const entry = (params.groupId ? channelEntries[params.groupId] : void 0) ?? (channelSlug ? channelEntries[channelSlug] ?? channelEntries[`#${channelSlug}`] : void 0) ?? (groupChannel ? channelEntries[normalizeDiscordSlug(groupChannel)] : void 0);
1549
+ const senderPolicy = resolveToolsBySender({
1550
+ toolsBySender: entry?.toolsBySender,
1551
+ senderId: params.senderId,
1552
+ senderName: params.senderName,
1553
+ senderUsername: params.senderUsername,
1554
+ senderE164: params.senderE164
1555
+ });
1556
+ if (senderPolicy) return senderPolicy;
1557
+ if (entry?.tools) return entry.tools;
1558
+ }
1559
+ const guildSenderPolicy = resolveToolsBySender({
1560
+ toolsBySender: guildEntry?.toolsBySender,
1561
+ senderId: params.senderId,
1562
+ senderName: params.senderName,
1563
+ senderUsername: params.senderUsername,
1564
+ senderE164: params.senderE164
1565
+ });
1566
+ if (guildSenderPolicy) return guildSenderPolicy;
1567
+ if (guildEntry?.tools) return guildEntry.tools;
1568
+ }
1569
+ function resolveSlackGroupToolPolicy(params) {
1570
+ const channels = resolveSlackAccount({
1571
+ cfg: params.cfg,
1572
+ accountId: params.accountId
1573
+ }).channels ?? {};
1574
+ if (Object.keys(channels).length === 0) return;
1575
+ const channelId = params.groupId?.trim();
1576
+ const channelName = params.groupChannel?.replace(/^#/, "");
1577
+ const normalizedName = normalizeSlackSlug(channelName);
1578
+ const candidates = [
1579
+ channelId ?? "",
1580
+ channelName ? `#${channelName}` : "",
1581
+ channelName ?? "",
1582
+ normalizedName
1583
+ ].filter(Boolean);
1584
+ let matched;
1585
+ for (const candidate of candidates) if (candidate && channels[candidate]) {
1586
+ matched = channels[candidate];
1587
+ break;
1588
+ }
1589
+ const resolved = matched ?? channels["*"];
1590
+ const senderPolicy = resolveToolsBySender({
1591
+ toolsBySender: resolved?.toolsBySender,
1592
+ senderId: params.senderId,
1593
+ senderName: params.senderName,
1594
+ senderUsername: params.senderUsername,
1595
+ senderE164: params.senderE164
1596
+ });
1597
+ if (senderPolicy) return senderPolicy;
1598
+ if (resolved?.tools) return resolved.tools;
1599
+ }
1600
+
1601
+ //#endregion
1602
+ //#region src/channels/dock.ts
1603
+ const formatLower = (allowFrom) => allowFrom.map((entry) => String(entry).trim()).filter(Boolean).map((entry) => entry.toLowerCase());
1604
+ const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1605
+ const DOCKS = {
1606
+ telegram: {
1607
+ id: "telegram",
1608
+ capabilities: {
1609
+ chatTypes: [
1610
+ "direct",
1611
+ "group",
1612
+ "channel",
1613
+ "thread"
1614
+ ],
1615
+ nativeCommands: true,
1616
+ blockStreaming: true
1617
+ },
1618
+ outbound: { textChunkLimit: 4e3 },
1619
+ config: {
1620
+ resolveAllowFrom: ({ cfg, accountId }) => (resolveTelegramAccount({
1621
+ cfg,
1622
+ accountId
1623
+ }).config.allowFrom ?? []).map((entry) => String(entry)),
1624
+ formatAllowFrom: ({ allowFrom }) => allowFrom.map((entry) => String(entry).trim()).filter(Boolean).map((entry) => entry.replace(/^(telegram|tg):/i, "")).map((entry) => entry.toLowerCase())
1625
+ },
1626
+ groups: {
1627
+ resolveRequireMention: resolveTelegramGroupRequireMention,
1628
+ resolveToolPolicy: resolveTelegramGroupToolPolicy
1629
+ },
1630
+ threading: {
1631
+ resolveReplyToMode: ({ cfg }) => cfg.channels?.telegram?.replyToMode ?? "first",
1632
+ buildToolContext: ({ context, hasRepliedRef }) => {
1633
+ const threadId = context.MessageThreadId ?? context.ReplyToId;
1634
+ return {
1635
+ currentChannelId: context.To?.trim() || void 0,
1636
+ currentThreadTs: threadId != null ? String(threadId) : void 0,
1637
+ hasRepliedRef
1638
+ };
1639
+ }
1640
+ }
1641
+ },
1642
+ whatsapp: {
1643
+ id: "whatsapp",
1644
+ capabilities: {
1645
+ chatTypes: ["direct", "group"],
1646
+ polls: true,
1647
+ reactions: true,
1648
+ media: true
1649
+ },
1650
+ commands: {
1651
+ enforceOwnerForCommands: true,
1652
+ skipWhenConfigEmpty: true
1653
+ },
1654
+ outbound: { textChunkLimit: 4e3 },
1655
+ config: {
1656
+ resolveAllowFrom: ({ cfg, accountId }) => resolveWhatsAppAccount({
1657
+ cfg,
1658
+ accountId
1659
+ }).allowFrom ?? [],
1660
+ formatAllowFrom: ({ allowFrom }) => allowFrom.map((entry) => String(entry).trim()).filter((entry) => Boolean(entry)).map((entry) => entry === "*" ? entry : normalizeWhatsAppTarget(entry)).filter((entry) => Boolean(entry))
1661
+ },
1662
+ groups: {
1663
+ resolveRequireMention: resolveWhatsAppGroupRequireMention,
1664
+ resolveToolPolicy: resolveWhatsAppGroupToolPolicy,
1665
+ resolveGroupIntroHint: () => "WhatsApp IDs: SenderId is the participant JID; [message_id: ...] is the message id for reactions (use SenderId as participant)."
1666
+ },
1667
+ mentions: { stripPatterns: ({ ctx }) => {
1668
+ const selfE164 = (ctx.To ?? "").replace(/^whatsapp:/, "");
1669
+ if (!selfE164) return [];
1670
+ const escaped = escapeRegExp(selfE164);
1671
+ return [escaped, `@${escaped}`];
1672
+ } },
1673
+ threading: { buildToolContext: ({ context, hasRepliedRef }) => {
1674
+ return {
1675
+ currentChannelId: context.From?.trim() || context.To?.trim() || void 0,
1676
+ currentThreadTs: context.ReplyToId,
1677
+ hasRepliedRef
1678
+ };
1679
+ } }
1680
+ },
1681
+ discord: {
1682
+ id: "discord",
1683
+ capabilities: {
1684
+ chatTypes: [
1685
+ "direct",
1686
+ "channel",
1687
+ "thread"
1688
+ ],
1689
+ polls: true,
1690
+ reactions: true,
1691
+ media: true,
1692
+ nativeCommands: true,
1693
+ threads: true
1694
+ },
1695
+ outbound: { textChunkLimit: 2e3 },
1696
+ streaming: { blockStreamingCoalesceDefaults: {
1697
+ minChars: 1500,
1698
+ idleMs: 1e3
1699
+ } },
1700
+ elevated: { allowFromFallback: ({ cfg }) => cfg.channels?.discord?.dm?.allowFrom },
1701
+ config: {
1702
+ resolveAllowFrom: ({ cfg, accountId }) => (resolveDiscordAccount({
1703
+ cfg,
1704
+ accountId
1705
+ }).config.dm?.allowFrom ?? []).map((entry) => String(entry)),
1706
+ formatAllowFrom: ({ allowFrom }) => formatLower(allowFrom)
1707
+ },
1708
+ groups: {
1709
+ resolveRequireMention: resolveDiscordGroupRequireMention,
1710
+ resolveToolPolicy: resolveDiscordGroupToolPolicy
1711
+ },
1712
+ mentions: { stripPatterns: () => ["<@!?\\d+>"] },
1713
+ threading: {
1714
+ resolveReplyToMode: ({ cfg }) => cfg.channels?.discord?.replyToMode ?? "off",
1715
+ buildToolContext: ({ context, hasRepliedRef }) => ({
1716
+ currentChannelId: context.To?.trim() || void 0,
1717
+ currentThreadTs: context.ReplyToId,
1718
+ hasRepliedRef
1719
+ })
1720
+ }
1721
+ },
1722
+ googlechat: {
1723
+ id: "googlechat",
1724
+ capabilities: {
1725
+ chatTypes: [
1726
+ "direct",
1727
+ "group",
1728
+ "thread"
1729
+ ],
1730
+ reactions: true,
1731
+ media: true,
1732
+ threads: true,
1733
+ blockStreaming: true
1734
+ },
1735
+ outbound: { textChunkLimit: 4e3 },
1736
+ config: {
1737
+ resolveAllowFrom: ({ cfg, accountId }) => {
1738
+ const channel = cfg.channels?.googlechat;
1739
+ const normalized = normalizeAccountId$1(accountId);
1740
+ return ((channel?.accounts?.[normalized] ?? channel?.accounts?.[Object.keys(channel?.accounts ?? {}).find((key) => key.toLowerCase() === normalized.toLowerCase()) ?? ""])?.dm?.allowFrom ?? channel?.dm?.allowFrom ?? []).map((entry) => String(entry));
1741
+ },
1742
+ formatAllowFrom: ({ allowFrom }) => allowFrom.map((entry) => String(entry).trim()).filter(Boolean).map((entry) => entry.replace(/^(googlechat|google-chat|gchat):/i, "").replace(/^user:/i, "").replace(/^users\//i, "").toLowerCase())
1743
+ },
1744
+ groups: {
1745
+ resolveRequireMention: resolveGoogleChatGroupRequireMention,
1746
+ resolveToolPolicy: resolveGoogleChatGroupToolPolicy
1747
+ },
1748
+ threading: {
1749
+ resolveReplyToMode: ({ cfg }) => cfg.channels?.googlechat?.replyToMode ?? "off",
1750
+ buildToolContext: ({ context, hasRepliedRef }) => {
1751
+ const threadId = context.MessageThreadId ?? context.ReplyToId;
1752
+ return {
1753
+ currentChannelId: context.To?.trim() || void 0,
1754
+ currentThreadTs: threadId != null ? String(threadId) : void 0,
1755
+ hasRepliedRef
1756
+ };
1757
+ }
1758
+ }
1759
+ },
1760
+ slack: {
1761
+ id: "slack",
1762
+ capabilities: {
1763
+ chatTypes: [
1764
+ "direct",
1765
+ "channel",
1766
+ "thread"
1767
+ ],
1768
+ reactions: true,
1769
+ media: true,
1770
+ nativeCommands: true,
1771
+ threads: true
1772
+ },
1773
+ outbound: { textChunkLimit: 4e3 },
1774
+ streaming: { blockStreamingCoalesceDefaults: {
1775
+ minChars: 1500,
1776
+ idleMs: 1e3
1777
+ } },
1778
+ config: {
1779
+ resolveAllowFrom: ({ cfg, accountId }) => (resolveSlackAccount({
1780
+ cfg,
1781
+ accountId
1782
+ }).dm?.allowFrom ?? []).map((entry) => String(entry)),
1783
+ formatAllowFrom: ({ allowFrom }) => formatLower(allowFrom)
1784
+ },
1785
+ groups: {
1786
+ resolveRequireMention: resolveSlackGroupRequireMention,
1787
+ resolveToolPolicy: resolveSlackGroupToolPolicy
1788
+ },
1789
+ mentions: { stripPatterns: () => ["<@[^>]+>"] },
1790
+ threading: {
1791
+ resolveReplyToMode: ({ cfg, accountId, chatType }) => resolveSlackReplyToMode(resolveSlackAccount({
1792
+ cfg,
1793
+ accountId
1794
+ }), chatType),
1795
+ allowTagsWhenOff: true,
1796
+ buildToolContext: (params) => buildSlackThreadingToolContext(params)
1797
+ }
1798
+ },
1799
+ signal: {
1800
+ id: "signal",
1801
+ capabilities: {
1802
+ chatTypes: ["direct", "group"],
1803
+ reactions: true,
1804
+ media: true
1805
+ },
1806
+ outbound: { textChunkLimit: 4e3 },
1807
+ streaming: { blockStreamingCoalesceDefaults: {
1808
+ minChars: 1500,
1809
+ idleMs: 1e3
1810
+ } },
1811
+ config: {
1812
+ resolveAllowFrom: ({ cfg, accountId }) => (resolveSignalAccount({
1813
+ cfg,
1814
+ accountId
1815
+ }).config.allowFrom ?? []).map((entry) => String(entry)),
1816
+ formatAllowFrom: ({ allowFrom }) => allowFrom.map((entry) => String(entry).trim()).filter(Boolean).map((entry) => entry === "*" ? "*" : normalizeE164(entry.replace(/^signal:/i, ""))).filter(Boolean)
1817
+ },
1818
+ threading: { buildToolContext: ({ context, hasRepliedRef }) => {
1819
+ return {
1820
+ currentChannelId: (context.ChatType?.toLowerCase() === "direct" ? context.From ?? context.To : context.To)?.trim() || void 0,
1821
+ currentThreadTs: context.ReplyToId,
1822
+ hasRepliedRef
1823
+ };
1824
+ } }
1825
+ },
1826
+ imessage: {
1827
+ id: "imessage",
1828
+ capabilities: {
1829
+ chatTypes: ["direct", "group"],
1830
+ reactions: true,
1831
+ media: true
1832
+ },
1833
+ outbound: { textChunkLimit: 4e3 },
1834
+ config: {
1835
+ resolveAllowFrom: ({ cfg, accountId }) => (resolveIMessageAccount({
1836
+ cfg,
1837
+ accountId
1838
+ }).config.allowFrom ?? []).map((entry) => String(entry)),
1839
+ formatAllowFrom: ({ allowFrom }) => allowFrom.map((entry) => String(entry).trim()).filter(Boolean)
1840
+ },
1841
+ groups: {
1842
+ resolveRequireMention: resolveIMessageGroupRequireMention,
1843
+ resolveToolPolicy: resolveIMessageGroupToolPolicy
1844
+ },
1845
+ threading: { buildToolContext: ({ context, hasRepliedRef }) => {
1846
+ return {
1847
+ currentChannelId: (context.ChatType?.toLowerCase() === "direct" ? context.From ?? context.To : context.To)?.trim() || void 0,
1848
+ currentThreadTs: context.ReplyToId,
1849
+ hasRepliedRef
1850
+ };
1851
+ } }
1852
+ }
1853
+ };
1854
+ function buildDockFromPlugin(plugin) {
1855
+ return {
1856
+ id: plugin.id,
1857
+ capabilities: plugin.capabilities,
1858
+ commands: plugin.commands,
1859
+ outbound: plugin.outbound?.textChunkLimit ? { textChunkLimit: plugin.outbound.textChunkLimit } : void 0,
1860
+ streaming: plugin.streaming ? { blockStreamingCoalesceDefaults: plugin.streaming.blockStreamingCoalesceDefaults } : void 0,
1861
+ elevated: plugin.elevated,
1862
+ config: plugin.config ? {
1863
+ resolveAllowFrom: plugin.config.resolveAllowFrom,
1864
+ formatAllowFrom: plugin.config.formatAllowFrom
1865
+ } : void 0,
1866
+ groups: plugin.groups,
1867
+ mentions: plugin.mentions,
1868
+ threading: plugin.threading,
1869
+ agentPrompt: plugin.agentPrompt
1870
+ };
1871
+ }
1872
+ function listPluginDockEntries() {
1873
+ const registry = requireActivePluginRegistry();
1874
+ const entries = [];
1875
+ const seen = /* @__PURE__ */ new Set();
1876
+ for (const entry of registry.channels) {
1877
+ const plugin = entry.plugin;
1878
+ const id = String(plugin.id).trim();
1879
+ if (!id || seen.has(id)) continue;
1880
+ seen.add(id);
1881
+ if (CHAT_CHANNEL_ORDER.includes(plugin.id)) continue;
1882
+ const dock = entry.dock ?? buildDockFromPlugin(plugin);
1883
+ entries.push({
1884
+ id: plugin.id,
1885
+ dock,
1886
+ order: plugin.meta.order
1887
+ });
1888
+ }
1889
+ return entries;
1890
+ }
1891
+ function listChannelDocks() {
1892
+ const baseEntries = CHAT_CHANNEL_ORDER.map((id) => ({
1893
+ id,
1894
+ dock: DOCKS[id],
1895
+ order: getChatChannelMeta(id).order
1896
+ }));
1897
+ const pluginEntries = listPluginDockEntries();
1898
+ const combined = [...baseEntries, ...pluginEntries];
1899
+ combined.sort((a, b) => {
1900
+ const indexA = CHAT_CHANNEL_ORDER.indexOf(a.id);
1901
+ const indexB = CHAT_CHANNEL_ORDER.indexOf(b.id);
1902
+ const orderA = a.order ?? (indexA === -1 ? 999 : indexA);
1903
+ const orderB = b.order ?? (indexB === -1 ? 999 : indexB);
1904
+ if (orderA !== orderB) return orderA - orderB;
1905
+ return String(a.id).localeCompare(String(b.id));
1906
+ });
1907
+ return combined.map((entry) => entry.dock);
1908
+ }
1909
+ function getChannelDock(id) {
1910
+ const core = DOCKS[id];
1911
+ if (core) return core;
1912
+ const pluginEntry = requireActivePluginRegistry().channels.find((entry) => entry.plugin.id === id);
1913
+ if (!pluginEntry) return;
1914
+ return pluginEntry.dock ?? buildDockFromPlugin(pluginEntry.plugin);
1915
+ }
1916
+
1917
+ //#endregion
1918
+ //#region src/config/sessions/metadata.ts
1919
+ const mergeOrigin = (existing, next) => {
1920
+ if (!existing && !next) return;
1921
+ const merged = existing ? { ...existing } : {};
1922
+ if (next?.label) merged.label = next.label;
1923
+ if (next?.provider) merged.provider = next.provider;
1924
+ if (next?.surface) merged.surface = next.surface;
1925
+ if (next?.chatType) merged.chatType = next.chatType;
1926
+ if (next?.from) merged.from = next.from;
1927
+ if (next?.to) merged.to = next.to;
1928
+ if (next?.accountId) merged.accountId = next.accountId;
1929
+ if (next?.threadId != null && next.threadId !== "") merged.threadId = next.threadId;
1930
+ return Object.keys(merged).length > 0 ? merged : void 0;
1931
+ };
1932
+ function deriveSessionOrigin(ctx) {
1933
+ const label = resolveConversationLabel(ctx)?.trim();
1934
+ const provider = normalizeMessageChannel(typeof ctx.OriginatingChannel === "string" && ctx.OriginatingChannel || ctx.Surface || ctx.Provider);
1935
+ const surface = ctx.Surface?.trim().toLowerCase();
1936
+ const chatType = normalizeChatType(ctx.ChatType) ?? void 0;
1937
+ const from = ctx.From?.trim();
1938
+ const to = (typeof ctx.OriginatingTo === "string" ? ctx.OriginatingTo : ctx.To)?.trim() ?? void 0;
1939
+ const accountId = ctx.AccountId?.trim();
1940
+ const threadId = ctx.MessageThreadId ?? void 0;
1941
+ const origin = {};
1942
+ if (label) origin.label = label;
1943
+ if (provider) origin.provider = provider;
1944
+ if (surface) origin.surface = surface;
1945
+ if (chatType) origin.chatType = chatType;
1946
+ if (from) origin.from = from;
1947
+ if (to) origin.to = to;
1948
+ if (accountId) origin.accountId = accountId;
1949
+ if (threadId != null && threadId !== "") origin.threadId = threadId;
1950
+ return Object.keys(origin).length > 0 ? origin : void 0;
1951
+ }
1952
+ function snapshotSessionOrigin(entry) {
1953
+ if (!entry?.origin) return;
1954
+ return { ...entry.origin };
1955
+ }
1956
+ function deriveGroupSessionPatch(params) {
1957
+ const resolution = params.groupResolution ?? resolveGroupSessionKey(params.ctx);
1958
+ if (!resolution?.channel) return null;
1959
+ const channel = resolution.channel;
1960
+ const subject = params.ctx.GroupSubject?.trim();
1961
+ const space = params.ctx.GroupSpace?.trim();
1962
+ const explicitChannel = params.ctx.GroupChannel?.trim();
1963
+ const normalizedChannel = normalizeChannelId(channel);
1964
+ const isChannelProvider = Boolean(normalizedChannel && getChannelDock(normalizedChannel)?.capabilities.chatTypes.includes("channel"));
1965
+ const nextGroupChannel = explicitChannel ?? ((resolution.chatType === "channel" || isChannelProvider) && subject && subject.startsWith("#") ? subject : void 0);
1966
+ const nextSubject = nextGroupChannel ? void 0 : subject;
1967
+ const patch = {
1968
+ chatType: resolution.chatType ?? "group",
1969
+ channel,
1970
+ groupId: resolution.id
1971
+ };
1972
+ if (nextSubject) patch.subject = nextSubject;
1973
+ if (nextGroupChannel) patch.groupChannel = nextGroupChannel;
1974
+ if (space) patch.space = space;
1975
+ const displayName = buildGroupDisplayName({
1976
+ provider: channel,
1977
+ subject: nextSubject ?? params.existing?.subject,
1978
+ groupChannel: nextGroupChannel ?? params.existing?.groupChannel,
1979
+ space: space ?? params.existing?.space,
1980
+ id: resolution.id,
1981
+ key: params.sessionKey
1982
+ });
1983
+ if (displayName) patch.displayName = displayName;
1984
+ return patch;
1985
+ }
1986
+ function deriveSessionMetaPatch(params) {
1987
+ const groupPatch = deriveGroupSessionPatch(params);
1988
+ const origin = deriveSessionOrigin(params.ctx);
1989
+ if (!groupPatch && !origin) return null;
1990
+ const patch = groupPatch ? { ...groupPatch } : {};
1991
+ const mergedOrigin = mergeOrigin(params.existing?.origin, origin);
1992
+ if (mergedOrigin) patch.origin = mergedOrigin;
1993
+ return Object.keys(patch).length > 0 ? patch : null;
1994
+ }
1995
+
1996
+ //#endregion
1997
+ //#region src/config/sessions/main-session.ts
1998
+ function resolveMainSessionKey(cfg) {
1999
+ if (cfg?.session?.scope === "global") return "global";
2000
+ const agents = cfg?.agents?.list ?? [];
2001
+ return buildAgentMainSessionKey({
2002
+ agentId: normalizeAgentId(agents.find((agent) => agent?.default)?.id ?? agents[0]?.id ?? DEFAULT_AGENT_ID),
2003
+ mainKey: normalizeMainKey(cfg?.session?.mainKey)
2004
+ });
2005
+ }
2006
+ function resolveMainSessionKeyFromConfig() {
2007
+ return resolveMainSessionKey(loadConfig());
2008
+ }
2009
+ function resolveAgentMainSessionKey(params) {
2010
+ const mainKey = normalizeMainKey(params.cfg?.session?.mainKey);
2011
+ return buildAgentMainSessionKey({
2012
+ agentId: params.agentId,
2013
+ mainKey
2014
+ });
2015
+ }
2016
+ function resolveExplicitAgentSessionKey(params) {
2017
+ const agentId = params.agentId?.trim();
2018
+ if (!agentId) return;
2019
+ return resolveAgentMainSessionKey({
2020
+ cfg: params.cfg,
2021
+ agentId
2022
+ });
2023
+ }
2024
+ function canonicalizeMainSessionAlias(params) {
2025
+ const raw = params.sessionKey.trim();
2026
+ if (!raw) return raw;
2027
+ const agentId = normalizeAgentId(params.agentId);
2028
+ const mainKey = normalizeMainKey(params.cfg?.session?.mainKey);
2029
+ const agentMainSessionKey = buildAgentMainSessionKey({
2030
+ agentId,
2031
+ mainKey
2032
+ });
2033
+ const agentMainAliasKey = buildAgentMainSessionKey({
2034
+ agentId,
2035
+ mainKey: "main"
2036
+ });
2037
+ const isMainAlias = raw === "main" || raw === mainKey || raw === agentMainSessionKey || raw === agentMainAliasKey;
2038
+ if (params.cfg?.session?.scope === "global" && isMainAlias) return "global";
2039
+ if (isMainAlias) return agentMainSessionKey;
2040
+ return raw;
2041
+ }
2042
+
2043
+ //#endregion
2044
+ //#region src/config/sessions/types.ts
2045
+ function mergeSessionEntry(existing, patch) {
2046
+ const sessionId = patch.sessionId ?? existing?.sessionId ?? crypto.randomUUID();
2047
+ const updatedAt = Math.max(existing?.updatedAt ?? 0, patch.updatedAt ?? 0, Date.now());
2048
+ if (!existing) return {
2049
+ ...patch,
2050
+ sessionId,
2051
+ updatedAt
2052
+ };
2053
+ return {
2054
+ ...existing,
2055
+ ...patch,
2056
+ sessionId,
2057
+ updatedAt
2058
+ };
2059
+ }
2060
+ const DEFAULT_RESET_TRIGGERS = ["/new", "/reset"];
2061
+ const DEFAULT_IDLE_MINUTES = 60;
2062
+
2063
+ //#endregion
2064
+ //#region src/config/sessions/reset.ts
2065
+ const DEFAULT_RESET_MODE = "daily";
2066
+ const DEFAULT_RESET_AT_HOUR = 4;
2067
+ const THREAD_SESSION_MARKERS = [":thread:", ":topic:"];
2068
+ const GROUP_SESSION_MARKERS = [":group:", ":channel:"];
2069
+ function isThreadSessionKey(sessionKey) {
2070
+ const normalized = (sessionKey ?? "").toLowerCase();
2071
+ if (!normalized) return false;
2072
+ return THREAD_SESSION_MARKERS.some((marker) => normalized.includes(marker));
2073
+ }
2074
+ function resolveSessionResetType(params) {
2075
+ if (params.isThread || isThreadSessionKey(params.sessionKey)) return "thread";
2076
+ if (params.isGroup) return "group";
2077
+ const normalized = (params.sessionKey ?? "").toLowerCase();
2078
+ if (GROUP_SESSION_MARKERS.some((marker) => normalized.includes(marker))) return "group";
2079
+ return "dm";
2080
+ }
2081
+ function resolveThreadFlag(params) {
2082
+ if (params.messageThreadId != null) return true;
2083
+ if (params.threadLabel?.trim()) return true;
2084
+ if (params.threadStarterBody?.trim()) return true;
2085
+ if (params.parentSessionKey?.trim()) return true;
2086
+ return isThreadSessionKey(params.sessionKey);
2087
+ }
2088
+ function resolveDailyResetAtMs(now, atHour) {
2089
+ const normalizedAtHour = normalizeResetAtHour(atHour);
2090
+ const resetAt = new Date(now);
2091
+ resetAt.setHours(normalizedAtHour, 0, 0, 0);
2092
+ if (now < resetAt.getTime()) resetAt.setDate(resetAt.getDate() - 1);
2093
+ return resetAt.getTime();
2094
+ }
2095
+ function resolveSessionResetPolicy(params) {
2096
+ const sessionCfg = params.sessionCfg;
2097
+ const baseReset = params.resetOverride ?? sessionCfg?.reset;
2098
+ const typeReset = params.resetOverride ? void 0 : sessionCfg?.resetByType?.[params.resetType];
2099
+ const hasExplicitReset = Boolean(baseReset || sessionCfg?.resetByType);
2100
+ const legacyIdleMinutes = params.resetOverride ? void 0 : sessionCfg?.idleMinutes;
2101
+ const mode = typeReset?.mode ?? baseReset?.mode ?? (!hasExplicitReset && legacyIdleMinutes != null ? "idle" : DEFAULT_RESET_MODE);
2102
+ const atHour = normalizeResetAtHour(typeReset?.atHour ?? baseReset?.atHour ?? DEFAULT_RESET_AT_HOUR);
2103
+ const idleMinutesRaw = typeReset?.idleMinutes ?? baseReset?.idleMinutes ?? legacyIdleMinutes;
2104
+ let idleMinutes;
2105
+ if (idleMinutesRaw != null) {
2106
+ const normalized = Math.floor(idleMinutesRaw);
2107
+ if (Number.isFinite(normalized)) idleMinutes = Math.max(normalized, 1);
2108
+ } else if (mode === "idle") idleMinutes = DEFAULT_IDLE_MINUTES;
2109
+ return {
2110
+ mode,
2111
+ atHour,
2112
+ idleMinutes
2113
+ };
2114
+ }
2115
+ function resolveChannelResetConfig(params) {
2116
+ const resetByChannel = params.sessionCfg?.resetByChannel;
2117
+ if (!resetByChannel) return;
2118
+ const normalized = normalizeMessageChannel(params.channel);
2119
+ const fallback = params.channel?.trim().toLowerCase();
2120
+ const key = normalized ?? fallback;
2121
+ if (!key) return;
2122
+ return resetByChannel[key] ?? resetByChannel[key.toLowerCase()];
2123
+ }
2124
+ function evaluateSessionFreshness(params) {
2125
+ const dailyResetAt = params.policy.mode === "daily" ? resolveDailyResetAtMs(params.now, params.policy.atHour) : void 0;
2126
+ const idleExpiresAt = params.policy.idleMinutes != null ? params.updatedAt + params.policy.idleMinutes * 6e4 : void 0;
2127
+ const staleDaily = dailyResetAt != null && params.updatedAt < dailyResetAt;
2128
+ const staleIdle = idleExpiresAt != null && params.now > idleExpiresAt;
2129
+ return {
2130
+ fresh: !(staleDaily || staleIdle),
2131
+ dailyResetAt,
2132
+ idleExpiresAt
2133
+ };
2134
+ }
2135
+ function normalizeResetAtHour(value) {
2136
+ if (typeof value !== "number" || !Number.isFinite(value)) return DEFAULT_RESET_AT_HOUR;
2137
+ const normalized = Math.floor(value);
2138
+ if (!Number.isFinite(normalized)) return DEFAULT_RESET_AT_HOUR;
2139
+ if (normalized < 0) return 0;
2140
+ if (normalized > 23) return 23;
2141
+ return normalized;
2142
+ }
2143
+
2144
+ //#endregion
2145
+ //#region src/config/sessions/session-key.ts
2146
+ function deriveSessionKey(scope, ctx) {
2147
+ if (scope === "global") return "global";
2148
+ const resolvedGroup = resolveGroupSessionKey(ctx);
2149
+ if (resolvedGroup) return resolvedGroup.key;
2150
+ return (ctx.From ? normalizeE164(ctx.From) : "") || "unknown";
2151
+ }
2152
+ /**
2153
+ * Resolve the session key with a canonical direct-chat bucket (default: "main").
2154
+ * All non-group direct chats collapse to this bucket; groups stay isolated.
2155
+ */
2156
+ function resolveSessionKey(scope, ctx, mainKey) {
2157
+ const explicit = ctx.SessionKey?.trim();
2158
+ if (explicit) return explicit.toLowerCase();
2159
+ const raw = deriveSessionKey(scope, ctx);
2160
+ if (scope === "global") return raw;
2161
+ const canonical = buildAgentMainSessionKey({
2162
+ agentId: DEFAULT_AGENT_ID,
2163
+ mainKey: normalizeMainKey(mainKey)
2164
+ });
2165
+ if (!(raw.includes(":group:") || raw.includes(":channel:"))) return canonical;
2166
+ return `agent:${DEFAULT_AGENT_ID}:${raw}`;
2167
+ }
2168
+
2169
+ //#endregion
2170
+ //#region src/utils/account-id.ts
2171
+ function normalizeAccountId(value) {
2172
+ if (typeof value !== "string") return;
2173
+ return value.trim() || void 0;
2174
+ }
2175
+
2176
+ //#endregion
2177
+ //#region src/utils/delivery-context.ts
2178
+ function normalizeDeliveryContext(context) {
2179
+ if (!context) return;
2180
+ const channel = typeof context.channel === "string" ? normalizeMessageChannel(context.channel) ?? context.channel.trim() : void 0;
2181
+ const to = typeof context.to === "string" ? context.to.trim() : void 0;
2182
+ const accountId = normalizeAccountId(context.accountId);
2183
+ const threadId = typeof context.threadId === "number" && Number.isFinite(context.threadId) ? Math.trunc(context.threadId) : typeof context.threadId === "string" ? context.threadId.trim() : void 0;
2184
+ const normalizedThreadId = typeof threadId === "string" ? threadId ? threadId : void 0 : threadId;
2185
+ if (!channel && !to && !accountId && normalizedThreadId == null) return;
2186
+ const normalized = {
2187
+ channel: channel || void 0,
2188
+ to: to || void 0,
2189
+ accountId
2190
+ };
2191
+ if (normalizedThreadId != null) normalized.threadId = normalizedThreadId;
2192
+ return normalized;
2193
+ }
2194
+ function normalizeSessionDeliveryFields(source) {
2195
+ if (!source) return {
2196
+ deliveryContext: void 0,
2197
+ lastChannel: void 0,
2198
+ lastTo: void 0,
2199
+ lastAccountId: void 0,
2200
+ lastThreadId: void 0
2201
+ };
2202
+ const merged = mergeDeliveryContext(normalizeDeliveryContext({
2203
+ channel: source.lastChannel ?? source.channel,
2204
+ to: source.lastTo,
2205
+ accountId: source.lastAccountId,
2206
+ threadId: source.lastThreadId
2207
+ }), normalizeDeliveryContext(source.deliveryContext));
2208
+ if (!merged) return {
2209
+ deliveryContext: void 0,
2210
+ lastChannel: void 0,
2211
+ lastTo: void 0,
2212
+ lastAccountId: void 0,
2213
+ lastThreadId: void 0
2214
+ };
2215
+ return {
2216
+ deliveryContext: merged,
2217
+ lastChannel: merged.channel,
2218
+ lastTo: merged.to,
2219
+ lastAccountId: merged.accountId,
2220
+ lastThreadId: merged.threadId
2221
+ };
2222
+ }
2223
+ function deliveryContextFromSession(entry) {
2224
+ if (!entry) return;
2225
+ return normalizeSessionDeliveryFields({
2226
+ channel: entry.channel,
2227
+ lastChannel: entry.lastChannel,
2228
+ lastTo: entry.lastTo,
2229
+ lastAccountId: entry.lastAccountId,
2230
+ lastThreadId: entry.lastThreadId ?? entry.deliveryContext?.threadId ?? entry.origin?.threadId,
2231
+ deliveryContext: entry.deliveryContext
2232
+ }).deliveryContext;
2233
+ }
2234
+ function mergeDeliveryContext(primary, fallback) {
2235
+ const normalizedPrimary = normalizeDeliveryContext(primary);
2236
+ const normalizedFallback = normalizeDeliveryContext(fallback);
2237
+ if (!normalizedPrimary && !normalizedFallback) return;
2238
+ return normalizeDeliveryContext({
2239
+ channel: normalizedPrimary?.channel ?? normalizedFallback?.channel,
2240
+ to: normalizedPrimary?.to ?? normalizedFallback?.to,
2241
+ accountId: normalizedPrimary?.accountId ?? normalizedFallback?.accountId,
2242
+ threadId: normalizedPrimary?.threadId ?? normalizedFallback?.threadId
2243
+ });
2244
+ }
2245
+ function deliveryContextKey(context) {
2246
+ const normalized = normalizeDeliveryContext(context);
2247
+ if (!normalized?.channel || !normalized?.to) return;
2248
+ const threadId = normalized.threadId != null && normalized.threadId !== "" ? String(normalized.threadId) : "";
2249
+ return `${normalized.channel}|${normalized.to}|${normalized.accountId ?? ""}|${threadId}`;
2250
+ }
2251
+
2252
+ //#endregion
2253
+ //#region src/config/cache-utils.ts
2254
+ function resolveCacheTtlMs(params) {
2255
+ const { envValue, defaultTtlMs } = params;
2256
+ if (envValue) {
2257
+ const parsed = Number.parseInt(envValue, 10);
2258
+ if (Number.isFinite(parsed) && parsed >= 0) return parsed;
2259
+ }
2260
+ return defaultTtlMs;
2261
+ }
2262
+ function isCacheEnabled(ttlMs) {
2263
+ return ttlMs > 0;
2264
+ }
2265
+ function getFileMtimeMs(filePath) {
2266
+ try {
2267
+ return fs.statSync(filePath).mtimeMs;
2268
+ } catch {
2269
+ return;
2270
+ }
2271
+ }
2272
+
2273
+ //#endregion
2274
+ //#region src/config/sessions/store.ts
2275
+ const SESSION_STORE_CACHE = /* @__PURE__ */ new Map();
2276
+ const DEFAULT_SESSION_STORE_TTL_MS = 45e3;
2277
+ function isSessionStoreRecord(value) {
2278
+ return !!value && typeof value === "object" && !Array.isArray(value);
2279
+ }
2280
+ function getSessionStoreTtl() {
2281
+ return resolveCacheTtlMs({
2282
+ envValue: process.env.OPENCLAW_SESSION_CACHE_TTL_MS,
2283
+ defaultTtlMs: DEFAULT_SESSION_STORE_TTL_MS
2284
+ });
2285
+ }
2286
+ function isSessionStoreCacheEnabled() {
2287
+ return isCacheEnabled(getSessionStoreTtl());
2288
+ }
2289
+ function isSessionStoreCacheValid(entry) {
2290
+ const now = Date.now();
2291
+ const ttl = getSessionStoreTtl();
2292
+ return now - entry.loadedAt <= ttl;
2293
+ }
2294
+ function invalidateSessionStoreCache(storePath) {
2295
+ SESSION_STORE_CACHE.delete(storePath);
2296
+ }
2297
+ function normalizeSessionEntryDelivery(entry) {
2298
+ const normalized = normalizeSessionDeliveryFields({
2299
+ channel: entry.channel,
2300
+ lastChannel: entry.lastChannel,
2301
+ lastTo: entry.lastTo,
2302
+ lastAccountId: entry.lastAccountId,
2303
+ lastThreadId: entry.lastThreadId ?? entry.deliveryContext?.threadId ?? entry.origin?.threadId,
2304
+ deliveryContext: entry.deliveryContext
2305
+ });
2306
+ const nextDelivery = normalized.deliveryContext;
2307
+ const sameDelivery = (entry.deliveryContext?.channel ?? void 0) === nextDelivery?.channel && (entry.deliveryContext?.to ?? void 0) === nextDelivery?.to && (entry.deliveryContext?.accountId ?? void 0) === nextDelivery?.accountId && (entry.deliveryContext?.threadId ?? void 0) === nextDelivery?.threadId;
2308
+ const sameLast = entry.lastChannel === normalized.lastChannel && entry.lastTo === normalized.lastTo && entry.lastAccountId === normalized.lastAccountId && entry.lastThreadId === normalized.lastThreadId;
2309
+ if (sameDelivery && sameLast) return entry;
2310
+ return {
2311
+ ...entry,
2312
+ deliveryContext: nextDelivery,
2313
+ lastChannel: normalized.lastChannel,
2314
+ lastTo: normalized.lastTo,
2315
+ lastAccountId: normalized.lastAccountId,
2316
+ lastThreadId: normalized.lastThreadId
2317
+ };
2318
+ }
2319
+ function normalizeSessionStore(store) {
2320
+ for (const [key, entry] of Object.entries(store)) {
2321
+ if (!entry) continue;
2322
+ const normalized = normalizeSessionEntryDelivery(entry);
2323
+ if (normalized !== entry) store[key] = normalized;
2324
+ }
2325
+ }
2326
+ function loadSessionStore(storePath, opts = {}) {
2327
+ if (!opts.skipCache && isSessionStoreCacheEnabled()) {
2328
+ const cached = SESSION_STORE_CACHE.get(storePath);
2329
+ if (cached && isSessionStoreCacheValid(cached)) {
2330
+ if (getFileMtimeMs(storePath) === cached.mtimeMs) return structuredClone(cached.store);
2331
+ invalidateSessionStoreCache(storePath);
2332
+ }
2333
+ }
2334
+ let store = {};
2335
+ let mtimeMs = getFileMtimeMs(storePath);
2336
+ try {
2337
+ const raw = fs.readFileSync(storePath, "utf-8");
2338
+ const parsed = JSON5.parse(raw);
2339
+ if (isSessionStoreRecord(parsed)) store = parsed;
2340
+ mtimeMs = getFileMtimeMs(storePath) ?? mtimeMs;
2341
+ } catch {}
2342
+ for (const entry of Object.values(store)) {
2343
+ if (!entry || typeof entry !== "object") continue;
2344
+ const rec = entry;
2345
+ if (typeof rec.channel !== "string" && typeof rec.provider === "string") {
2346
+ rec.channel = rec.provider;
2347
+ delete rec.provider;
2348
+ }
2349
+ if (typeof rec.lastChannel !== "string" && typeof rec.lastProvider === "string") {
2350
+ rec.lastChannel = rec.lastProvider;
2351
+ delete rec.lastProvider;
2352
+ }
2353
+ if (typeof rec.groupChannel !== "string" && typeof rec.room === "string") {
2354
+ rec.groupChannel = rec.room;
2355
+ delete rec.room;
2356
+ } else if ("room" in rec) delete rec.room;
2357
+ }
2358
+ if (!opts.skipCache && isSessionStoreCacheEnabled()) SESSION_STORE_CACHE.set(storePath, {
2359
+ store: structuredClone(store),
2360
+ loadedAt: Date.now(),
2361
+ storePath,
2362
+ mtimeMs
2363
+ });
2364
+ return structuredClone(store);
2365
+ }
2366
+ function readSessionUpdatedAt(params) {
2367
+ try {
2368
+ return loadSessionStore(params.storePath)[params.sessionKey]?.updatedAt;
2369
+ } catch {
2370
+ return;
2371
+ }
2372
+ }
2373
+ async function saveSessionStoreUnlocked(storePath, store) {
2374
+ invalidateSessionStoreCache(storePath);
2375
+ normalizeSessionStore(store);
2376
+ await fs.promises.mkdir(path.dirname(storePath), { recursive: true });
2377
+ const json = JSON.stringify(store, null, 2);
2378
+ if (process.platform === "win32") {
2379
+ try {
2380
+ await fs.promises.writeFile(storePath, json, "utf-8");
2381
+ } catch (err) {
2382
+ if ((err && typeof err === "object" && "code" in err ? String(err.code) : null) === "ENOENT") return;
2383
+ throw err;
2384
+ }
2385
+ return;
2386
+ }
2387
+ const tmp = `${storePath}.${process.pid}.${crypto.randomUUID()}.tmp`;
2388
+ try {
2389
+ await fs.promises.writeFile(tmp, json, {
2390
+ mode: 384,
2391
+ encoding: "utf-8"
2392
+ });
2393
+ await fs.promises.rename(tmp, storePath);
2394
+ await fs.promises.chmod(storePath, 384);
2395
+ } catch (err) {
2396
+ if ((err && typeof err === "object" && "code" in err ? String(err.code) : null) === "ENOENT") {
2397
+ try {
2398
+ await fs.promises.mkdir(path.dirname(storePath), { recursive: true });
2399
+ await fs.promises.writeFile(storePath, json, {
2400
+ mode: 384,
2401
+ encoding: "utf-8"
2402
+ });
2403
+ await fs.promises.chmod(storePath, 384);
2404
+ } catch (err2) {
2405
+ if ((err2 && typeof err2 === "object" && "code" in err2 ? String(err2.code) : null) === "ENOENT") return;
2406
+ throw err2;
2407
+ }
2408
+ return;
2409
+ }
2410
+ throw err;
2411
+ } finally {
2412
+ await fs.promises.rm(tmp, { force: true });
2413
+ }
2414
+ }
2415
+ async function saveSessionStore(storePath, store) {
2416
+ await withSessionStoreLock(storePath, async () => {
2417
+ await saveSessionStoreUnlocked(storePath, store);
2418
+ });
2419
+ }
2420
+ async function updateSessionStore(storePath, mutator) {
2421
+ return await withSessionStoreLock(storePath, async () => {
2422
+ const store = loadSessionStore(storePath, { skipCache: true });
2423
+ const result = await mutator(store);
2424
+ await saveSessionStoreUnlocked(storePath, store);
2425
+ return result;
2426
+ });
2427
+ }
2428
+ async function withSessionStoreLock(storePath, fn, opts = {}) {
2429
+ const timeoutMs = opts.timeoutMs ?? 1e4;
2430
+ const pollIntervalMs = opts.pollIntervalMs ?? 25;
2431
+ const staleMs = opts.staleMs ?? 3e4;
2432
+ const lockPath = `${storePath}.lock`;
2433
+ const startedAt = Date.now();
2434
+ await fs.promises.mkdir(path.dirname(storePath), { recursive: true });
2435
+ while (true) try {
2436
+ const handle = await fs.promises.open(lockPath, "wx");
2437
+ try {
2438
+ await handle.writeFile(JSON.stringify({
2439
+ pid: process.pid,
2440
+ startedAt: Date.now()
2441
+ }), "utf-8");
2442
+ } catch {}
2443
+ await handle.close();
2444
+ break;
2445
+ } catch (err) {
2446
+ const code = err && typeof err === "object" && "code" in err ? String(err.code) : null;
2447
+ if (code === "ENOENT") {
2448
+ await fs.promises.mkdir(path.dirname(storePath), { recursive: true }).catch(() => void 0);
2449
+ await new Promise((r) => setTimeout(r, pollIntervalMs));
2450
+ continue;
2451
+ }
2452
+ if (code !== "EEXIST") throw err;
2453
+ const now = Date.now();
2454
+ if (now - startedAt > timeoutMs) throw new Error(`timeout acquiring session store lock: ${lockPath}`, { cause: err });
2455
+ try {
2456
+ if (now - (await fs.promises.stat(lockPath)).mtimeMs > staleMs) {
2457
+ await fs.promises.unlink(lockPath);
2458
+ continue;
2459
+ }
2460
+ } catch {}
2461
+ await new Promise((r) => setTimeout(r, pollIntervalMs));
2462
+ }
2463
+ try {
2464
+ return await fn();
2465
+ } finally {
2466
+ await fs.promises.unlink(lockPath).catch(() => void 0);
2467
+ }
2468
+ }
2469
+ async function updateSessionStoreEntry(params) {
2470
+ const { storePath, sessionKey, update } = params;
2471
+ return await withSessionStoreLock(storePath, async () => {
2472
+ const store = loadSessionStore(storePath);
2473
+ const existing = store[sessionKey];
2474
+ if (!existing) return null;
2475
+ const patch = await update(existing);
2476
+ if (!patch) return existing;
2477
+ const next = mergeSessionEntry(existing, patch);
2478
+ store[sessionKey] = next;
2479
+ await saveSessionStoreUnlocked(storePath, store);
2480
+ return next;
2481
+ });
2482
+ }
2483
+ async function recordSessionMetaFromInbound(params) {
2484
+ const { storePath, sessionKey, ctx } = params;
2485
+ const createIfMissing = params.createIfMissing ?? true;
2486
+ return await updateSessionStore(storePath, (store) => {
2487
+ const existing = store[sessionKey];
2488
+ const patch = deriveSessionMetaPatch({
2489
+ ctx,
2490
+ sessionKey,
2491
+ existing,
2492
+ groupResolution: params.groupResolution
2493
+ });
2494
+ if (!patch) return existing ?? null;
2495
+ if (!existing && !createIfMissing) return null;
2496
+ const next = mergeSessionEntry(existing, patch);
2497
+ store[sessionKey] = next;
2498
+ return next;
2499
+ });
2500
+ }
2501
+ async function updateLastRoute(params) {
2502
+ const { storePath, sessionKey, channel, to, accountId, threadId, ctx } = params;
2503
+ return await withSessionStoreLock(storePath, async () => {
2504
+ const store = loadSessionStore(storePath);
2505
+ const existing = store[sessionKey];
2506
+ const now = Date.now();
2507
+ const merged = mergeDeliveryContext(mergeDeliveryContext(normalizeDeliveryContext(params.deliveryContext), normalizeDeliveryContext({
2508
+ channel,
2509
+ to,
2510
+ accountId,
2511
+ threadId
2512
+ })), deliveryContextFromSession(existing));
2513
+ const normalized = normalizeSessionDeliveryFields({ deliveryContext: {
2514
+ channel: merged?.channel,
2515
+ to: merged?.to,
2516
+ accountId: merged?.accountId,
2517
+ threadId: merged?.threadId
2518
+ } });
2519
+ const metaPatch = ctx ? deriveSessionMetaPatch({
2520
+ ctx,
2521
+ sessionKey,
2522
+ existing,
2523
+ groupResolution: params.groupResolution
2524
+ }) : null;
2525
+ const basePatch = {
2526
+ updatedAt: Math.max(existing?.updatedAt ?? 0, now),
2527
+ deliveryContext: normalized.deliveryContext,
2528
+ lastChannel: normalized.lastChannel,
2529
+ lastTo: normalized.lastTo,
2530
+ lastAccountId: normalized.lastAccountId,
2531
+ lastThreadId: normalized.lastThreadId
2532
+ };
2533
+ const next = mergeSessionEntry(existing, metaPatch ? {
2534
+ ...basePatch,
2535
+ ...metaPatch
2536
+ } : basePatch);
2537
+ store[sessionKey] = next;
2538
+ await saveSessionStoreUnlocked(storePath, store);
2539
+ return next;
2540
+ });
2541
+ }
2542
+
2543
+ //#endregion
2544
+ //#region src/config/sessions/transcript.ts
2545
+ function stripQuery(value) {
2546
+ const noHash = value.split("#")[0] ?? value;
2547
+ return noHash.split("?")[0] ?? noHash;
2548
+ }
2549
+ function extractFileNameFromMediaUrl(value) {
2550
+ const trimmed = value.trim();
2551
+ if (!trimmed) return null;
2552
+ const cleaned = stripQuery(trimmed);
2553
+ try {
2554
+ const parsed = new URL(cleaned);
2555
+ const base = path.basename(parsed.pathname);
2556
+ if (!base) return null;
2557
+ try {
2558
+ return decodeURIComponent(base);
2559
+ } catch {
2560
+ return base;
2561
+ }
2562
+ } catch {
2563
+ const base = path.basename(cleaned);
2564
+ if (!base || base === "/" || base === ".") return null;
2565
+ return base;
2566
+ }
2567
+ }
2568
+ function resolveMirroredTranscriptText(params) {
2569
+ const mediaUrls = params.mediaUrls?.filter((url) => url && url.trim()) ?? [];
2570
+ if (mediaUrls.length > 0) {
2571
+ const names = mediaUrls.map((url) => extractFileNameFromMediaUrl(url)).filter((name) => Boolean(name && name.trim()));
2572
+ if (names.length > 0) return names.join(", ");
2573
+ return "media";
2574
+ }
2575
+ const trimmed = (params.text ?? "").trim();
2576
+ return trimmed ? trimmed : null;
2577
+ }
2578
+ async function ensureSessionHeader(params) {
2579
+ if (fs.existsSync(params.sessionFile)) return;
2580
+ await fs.promises.mkdir(path.dirname(params.sessionFile), { recursive: true });
2581
+ const header = {
2582
+ type: "session",
2583
+ version: CURRENT_SESSION_VERSION,
2584
+ id: params.sessionId,
2585
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2586
+ cwd: process.cwd()
2587
+ };
2588
+ await fs.promises.writeFile(params.sessionFile, `${JSON.stringify(header)}\n`, "utf-8");
2589
+ }
2590
+ async function appendAssistantMessageToSessionTranscript(params) {
2591
+ const sessionKey = params.sessionKey.trim();
2592
+ if (!sessionKey) return {
2593
+ ok: false,
2594
+ reason: "missing sessionKey"
2595
+ };
2596
+ const mirrorText = resolveMirroredTranscriptText({
2597
+ text: params.text,
2598
+ mediaUrls: params.mediaUrls
2599
+ });
2600
+ if (!mirrorText) return {
2601
+ ok: false,
2602
+ reason: "empty text"
2603
+ };
2604
+ const storePath = params.storePath ?? resolveDefaultSessionStorePath(params.agentId);
2605
+ const entry = loadSessionStore(storePath, { skipCache: true })[sessionKey];
2606
+ if (!entry?.sessionId) return {
2607
+ ok: false,
2608
+ reason: `unknown sessionKey: ${sessionKey}`
2609
+ };
2610
+ const sessionFile = entry.sessionFile?.trim() || resolveSessionTranscriptPath(entry.sessionId, params.agentId);
2611
+ await ensureSessionHeader({
2612
+ sessionFile,
2613
+ sessionId: entry.sessionId
2614
+ });
2615
+ SessionManager.open(sessionFile).appendMessage({
2616
+ role: "assistant",
2617
+ content: [{
2618
+ type: "text",
2619
+ text: mirrorText
2620
+ }],
2621
+ api: "openai-responses",
2622
+ provider: "openclaw",
2623
+ model: "delivery-mirror",
2624
+ usage: {
2625
+ input: 0,
2626
+ output: 0,
2627
+ cacheRead: 0,
2628
+ cacheWrite: 0,
2629
+ totalTokens: 0,
2630
+ cost: {
2631
+ input: 0,
2632
+ output: 0,
2633
+ cacheRead: 0,
2634
+ cacheWrite: 0,
2635
+ total: 0
2636
+ }
2637
+ },
2638
+ stopReason: "stop",
2639
+ timestamp: Date.now()
2640
+ });
2641
+ if (!entry.sessionFile || entry.sessionFile !== sessionFile) await updateSessionStore(storePath, (current) => {
2642
+ current[sessionKey] = {
2643
+ ...entry,
2644
+ sessionFile
2645
+ };
2646
+ });
2647
+ emitSessionTranscriptUpdate(sessionFile);
2648
+ return {
2649
+ ok: true,
2650
+ sessionFile
2651
+ };
2652
+ }
2653
+
2654
+ //#endregion
2655
+ //#region src/agents/sandbox/runtime-status.ts
2656
+ function shouldSandboxSession(cfg, sessionKey, mainSessionKey) {
2657
+ if (cfg.mode === "off") return false;
2658
+ if (cfg.mode === "all") return true;
2659
+ return sessionKey.trim() !== mainSessionKey.trim();
2660
+ }
2661
+ function resolveMainSessionKeyForSandbox(params) {
2662
+ if (params.cfg?.session?.scope === "global") return "global";
2663
+ return resolveAgentMainSessionKey({
2664
+ cfg: params.cfg,
2665
+ agentId: params.agentId
2666
+ });
2667
+ }
2668
+ function resolveComparableSessionKeyForSandbox(params) {
2669
+ return canonicalizeMainSessionAlias({
2670
+ cfg: params.cfg,
2671
+ agentId: params.agentId,
2672
+ sessionKey: params.sessionKey
2673
+ });
2674
+ }
2675
+ function resolveSandboxRuntimeStatus(params) {
2676
+ const sessionKey = params.sessionKey?.trim() ?? "";
2677
+ const agentId = resolveSessionAgentId({
2678
+ sessionKey,
2679
+ config: params.cfg
2680
+ });
2681
+ const cfg = params.cfg;
2682
+ const sandboxCfg = resolveSandboxConfigForAgent(cfg, agentId);
2683
+ const mainSessionKey = resolveMainSessionKeyForSandbox({
2684
+ cfg,
2685
+ agentId
2686
+ });
2687
+ const sandboxed = sessionKey ? shouldSandboxSession(sandboxCfg, resolveComparableSessionKeyForSandbox({
2688
+ cfg,
2689
+ agentId,
2690
+ sessionKey
2691
+ }), mainSessionKey) : false;
2692
+ return {
2693
+ agentId,
2694
+ sessionKey,
2695
+ mainSessionKey,
2696
+ mode: sandboxCfg.mode,
2697
+ sandboxed,
2698
+ toolPolicy: resolveSandboxToolPolicyForAgent(cfg, agentId)
2699
+ };
2700
+ }
2701
+ function formatSandboxToolPolicyBlockedMessage(params) {
2702
+ const tool = params.toolName.trim().toLowerCase();
2703
+ if (!tool) return;
2704
+ const runtime = resolveSandboxRuntimeStatus({
2705
+ cfg: params.cfg,
2706
+ sessionKey: params.sessionKey
2707
+ });
2708
+ if (!runtime.sandboxed) return;
2709
+ const deny = new Set(expandToolGroups(runtime.toolPolicy.deny));
2710
+ const allow = expandToolGroups(runtime.toolPolicy.allow);
2711
+ const allowSet = allow.length > 0 ? new Set(allow) : null;
2712
+ const blockedByDeny = deny.has(tool);
2713
+ const blockedByAllow = allowSet ? !allowSet.has(tool) : false;
2714
+ if (!blockedByDeny && !blockedByAllow) return;
2715
+ const reasons = [];
2716
+ const fixes = [];
2717
+ if (blockedByDeny) {
2718
+ reasons.push("deny list");
2719
+ fixes.push(`Remove "${tool}" from ${runtime.toolPolicy.sources.deny.key}.`);
2720
+ }
2721
+ if (blockedByAllow) {
2722
+ reasons.push("allow list");
2723
+ fixes.push(`Add "${tool}" to ${runtime.toolPolicy.sources.allow.key} (or set it to [] to allow all).`);
2724
+ }
2725
+ const lines = [];
2726
+ lines.push(`Tool "${tool}" blocked by sandbox tool policy (mode=${runtime.mode}).`);
2727
+ lines.push(`Session: ${runtime.sessionKey || "(unknown)"}`);
2728
+ lines.push(`Reason: ${reasons.join(" + ")}`);
2729
+ lines.push("Fix:");
2730
+ lines.push(`- agents.defaults.sandbox.mode=off (disable sandbox)`);
2731
+ for (const fix of fixes) lines.push(`- ${fix}`);
2732
+ if (runtime.mode === "non-main") lines.push(`- Use main session key (direct): ${runtime.mainSessionKey}`);
2733
+ lines.push(`- See: ${formatCliCommand(`openclaw sandbox explain --session ${runtime.sessionKey}`)}`);
2734
+ return lines.join("\n");
2735
+ }
2736
+
2737
+ //#endregion
2738
+ //#region src/agents/sandbox/workspace.ts
2739
+ async function ensureSandboxWorkspace(workspaceDir, seedFrom, skipBootstrap) {
2740
+ await fs$1.mkdir(workspaceDir, { recursive: true });
2741
+ if (seedFrom) {
2742
+ const seed = resolveUserPath(seedFrom);
2743
+ const files = [
2744
+ DEFAULT_AGENTS_FILENAME,
2745
+ DEFAULT_SOUL_FILENAME,
2746
+ DEFAULT_TOOLS_FILENAME,
2747
+ DEFAULT_IDENTITY_FILENAME,
2748
+ DEFAULT_USER_FILENAME,
2749
+ DEFAULT_BOOTSTRAP_FILENAME,
2750
+ DEFAULT_HEARTBEAT_FILENAME
2751
+ ];
2752
+ for (const name of files) {
2753
+ const src = path.join(seed, name);
2754
+ const dest = path.join(workspaceDir, name);
2755
+ try {
2756
+ await fs$1.access(dest);
2757
+ } catch {
2758
+ try {
2759
+ const content = await fs$1.readFile(src, "utf-8");
2760
+ await fs$1.writeFile(dest, content, {
2761
+ encoding: "utf-8",
2762
+ flag: "wx"
2763
+ });
2764
+ } catch {}
2765
+ }
2766
+ }
2767
+ }
2768
+ await ensureAgentWorkspace({
2769
+ dir: workspaceDir,
2770
+ ensureBootstrapFiles: !skipBootstrap
2771
+ });
2772
+ }
2773
+
2774
+ //#endregion
2775
+ //#region src/agents/sandbox/context.ts
2776
+ async function resolveSandboxContext(params) {
2777
+ const rawSessionKey = params.sessionKey?.trim();
2778
+ if (!rawSessionKey) return null;
2779
+ const runtime = resolveSandboxRuntimeStatus({
2780
+ cfg: params.config,
2781
+ sessionKey: rawSessionKey
2782
+ });
2783
+ if (!runtime.sandboxed) return null;
2784
+ const cfg = resolveSandboxConfigForAgent(params.config, runtime.agentId);
2785
+ await maybePruneSandboxes(cfg);
2786
+ const agentWorkspaceDir = resolveUserPath(params.workspaceDir?.trim() || DEFAULT_AGENT_WORKSPACE_DIR);
2787
+ const workspaceRoot = resolveUserPath(cfg.workspaceRoot);
2788
+ const scopeKey = resolveSandboxScopeKey(cfg.scope, rawSessionKey);
2789
+ const sandboxWorkspaceDir = cfg.scope === "shared" ? workspaceRoot : resolveSandboxWorkspaceDir(workspaceRoot, scopeKey);
2790
+ const workspaceDir = cfg.workspaceAccess === "rw" ? agentWorkspaceDir : sandboxWorkspaceDir;
2791
+ if (workspaceDir === sandboxWorkspaceDir) {
2792
+ await ensureSandboxWorkspace(sandboxWorkspaceDir, agentWorkspaceDir, params.config?.agents?.defaults?.skipBootstrap);
2793
+ if (cfg.workspaceAccess !== "rw") try {
2794
+ await syncSkillsToWorkspace({
2795
+ sourceWorkspaceDir: agentWorkspaceDir,
2796
+ targetWorkspaceDir: sandboxWorkspaceDir,
2797
+ config: params.config
2798
+ });
2799
+ } catch (error) {
2800
+ const message = error instanceof Error ? error.message : JSON.stringify(error);
2801
+ defaultRuntime.error?.(`Sandbox skill sync failed: ${message}`);
2802
+ }
2803
+ } else await fs$1.mkdir(workspaceDir, { recursive: true });
2804
+ const containerName = await ensureSandboxContainer({
2805
+ sessionKey: rawSessionKey,
2806
+ workspaceDir,
2807
+ agentWorkspaceDir,
2808
+ cfg
2809
+ });
2810
+ const browser = await ensureSandboxBrowser({
2811
+ scopeKey,
2812
+ workspaceDir,
2813
+ agentWorkspaceDir,
2814
+ cfg,
2815
+ evaluateEnabled: params.config?.browser?.evaluateEnabled ?? DEFAULT_BROWSER_EVALUATE_ENABLED
2816
+ });
2817
+ return {
2818
+ enabled: true,
2819
+ sessionKey: rawSessionKey,
2820
+ workspaceDir,
2821
+ agentWorkspaceDir,
2822
+ workspaceAccess: cfg.workspaceAccess,
2823
+ containerName,
2824
+ containerWorkdir: cfg.docker.workdir,
2825
+ docker: cfg.docker,
2826
+ tools: cfg.tools,
2827
+ browserAllowHostControl: cfg.browser.allowHostControl,
2828
+ browser: browser ?? void 0
2829
+ };
2830
+ }
2831
+ async function ensureSandboxWorkspaceForSession(params) {
2832
+ const rawSessionKey = params.sessionKey?.trim();
2833
+ if (!rawSessionKey) return null;
2834
+ const runtime = resolveSandboxRuntimeStatus({
2835
+ cfg: params.config,
2836
+ sessionKey: rawSessionKey
2837
+ });
2838
+ if (!runtime.sandboxed) return null;
2839
+ const cfg = resolveSandboxConfigForAgent(params.config, runtime.agentId);
2840
+ const agentWorkspaceDir = resolveUserPath(params.workspaceDir?.trim() || DEFAULT_AGENT_WORKSPACE_DIR);
2841
+ const workspaceRoot = resolveUserPath(cfg.workspaceRoot);
2842
+ const scopeKey = resolveSandboxScopeKey(cfg.scope, rawSessionKey);
2843
+ const sandboxWorkspaceDir = cfg.scope === "shared" ? workspaceRoot : resolveSandboxWorkspaceDir(workspaceRoot, scopeKey);
2844
+ const workspaceDir = cfg.workspaceAccess === "rw" ? agentWorkspaceDir : sandboxWorkspaceDir;
2845
+ if (workspaceDir === sandboxWorkspaceDir) {
2846
+ await ensureSandboxWorkspace(sandboxWorkspaceDir, agentWorkspaceDir, params.config?.agents?.defaults?.skipBootstrap);
2847
+ if (cfg.workspaceAccess !== "rw") try {
2848
+ await syncSkillsToWorkspace({
2849
+ sourceWorkspaceDir: agentWorkspaceDir,
2850
+ targetWorkspaceDir: sandboxWorkspaceDir,
2851
+ config: params.config
2852
+ });
2853
+ } catch (error) {
2854
+ const message = error instanceof Error ? error.message : JSON.stringify(error);
2855
+ defaultRuntime.error?.(`Sandbox skill sync failed: ${message}`);
2856
+ }
2857
+ } else await fs$1.mkdir(workspaceDir, { recursive: true });
2858
+ return {
2859
+ workspaceDir,
2860
+ containerWorkdir: cfg.docker.workdir
2861
+ };
2862
+ }
2863
+
2864
+ //#endregion
2865
+ //#region src/agents/sandbox/manage.ts
2866
+ async function listSandboxContainers() {
2867
+ const config = loadConfig();
2868
+ const registry = await readRegistry();
2869
+ const results = [];
2870
+ for (const entry of registry.entries) {
2871
+ const state = await dockerContainerState(entry.containerName);
2872
+ let actualImage = entry.image;
2873
+ if (state.exists) try {
2874
+ const result = await execDocker([
2875
+ "inspect",
2876
+ "-f",
2877
+ "{{.Config.Image}}",
2878
+ entry.containerName
2879
+ ], { allowFailure: true });
2880
+ if (result.code === 0) actualImage = result.stdout.trim();
2881
+ } catch {}
2882
+ const configuredImage = resolveSandboxConfigForAgent(config, resolveSandboxAgentId(entry.sessionKey)).docker.image;
2883
+ results.push({
2884
+ ...entry,
2885
+ image: actualImage,
2886
+ running: state.running,
2887
+ imageMatch: actualImage === configuredImage
2888
+ });
2889
+ }
2890
+ return results;
2891
+ }
2892
+ async function listSandboxBrowsers() {
2893
+ const config = loadConfig();
2894
+ const registry = await readBrowserRegistry();
2895
+ const results = [];
2896
+ for (const entry of registry.entries) {
2897
+ const state = await dockerContainerState(entry.containerName);
2898
+ let actualImage = entry.image;
2899
+ if (state.exists) try {
2900
+ const result = await execDocker([
2901
+ "inspect",
2902
+ "-f",
2903
+ "{{.Config.Image}}",
2904
+ entry.containerName
2905
+ ], { allowFailure: true });
2906
+ if (result.code === 0) actualImage = result.stdout.trim();
2907
+ } catch {}
2908
+ const configuredImage = resolveSandboxConfigForAgent(config, resolveSandboxAgentId(entry.sessionKey)).browser.image;
2909
+ results.push({
2910
+ ...entry,
2911
+ image: actualImage,
2912
+ running: state.running,
2913
+ imageMatch: actualImage === configuredImage
2914
+ });
2915
+ }
2916
+ return results;
2917
+ }
2918
+ async function removeSandboxContainer(containerName) {
2919
+ try {
2920
+ await execDocker([
2921
+ "rm",
2922
+ "-f",
2923
+ containerName
2924
+ ], { allowFailure: true });
2925
+ } catch {}
2926
+ await removeRegistryEntry(containerName);
2927
+ }
2928
+ async function removeSandboxBrowserContainer(containerName) {
2929
+ try {
2930
+ await execDocker([
2931
+ "rm",
2932
+ "-f",
2933
+ containerName
2934
+ ], { allowFailure: true });
2935
+ } catch {}
2936
+ await removeBrowserRegistryEntry(containerName);
2937
+ for (const [sessionKey, bridge] of BROWSER_BRIDGES.entries()) if (bridge.containerName === containerName) {
2938
+ await stopBrowserBridgeServer(bridge.bridge.server).catch(() => void 0);
2939
+ BROWSER_BRIDGES.delete(sessionKey);
2940
+ }
2941
+ }
2942
+
2943
+ //#endregion
2944
+ export { resolveSandboxToolPolicyForAgent as $, resolveSessionResetPolicy as A, snapshotSessionOrigin as B, normalizeDeliveryContext as C, resolveSessionKey as D, deriveSessionKey as E, resolveAgentMainSessionKey as F, resolveChannelGroupToolsPolicy as G, listChannelDocks as H, resolveExplicitAgentSessionKey as I, resolveIMessageAccount as J, listEnabledSignalAccounts as K, resolveMainSessionKey as L, resolveThreadFlag as M, DEFAULT_RESET_TRIGGERS as N, evaluateSessionFreshness as O, canonicalizeMainSessionAlias as P, resolveSandboxScope as Q, resolveMainSessionKeyFromConfig as R, mergeDeliveryContext as S, normalizeAccountId as T, resolveChannelGroupPolicy as U, getChannelDock as V, resolveChannelGroupRequireMention as W, resolveGroupSessionKey as X, buildGroupDisplayName as Y, resolveSandboxConfigForAgent as Z, updateSessionStoreEntry as _, ensureSandboxWorkspaceForSession as a, normalizeToolName as at, deliveryContextFromSession as b, resolveSandboxRuntimeStatus as c, DEFAULT_SANDBOX_BROWSER_IMAGE as ct, loadSessionStore as d, resolveConversationLabel as dt, applyOwnerOnlyToolPolicy as et, readSessionUpdatedAt as f, updateSessionStore as g, updateLastRoute as h, removeSandboxContainer as i, expandToolGroups as it, resolveSessionResetType as j, resolveChannelResetConfig as k, appendAssistantMessageToSessionTranscript as l, DEFAULT_SANDBOX_COMMON_IMAGE as lt, saveSessionStore as m, listSandboxContainers as n, collectExplicitAllowlist as nt, resolveSandboxContext as o, resolveToolProfilePolicy as ot, recordSessionMetaFromInbound as p, resolveSignalAccount as q, removeSandboxBrowserContainer as r, expandPolicyWithPluginGroups as rt, formatSandboxToolPolicyBlockedMessage as s, stripPluginOnlyAllowlist as st, listSandboxBrowsers as t, buildPluginToolGroups as tt, resolveMirroredTranscriptText as u, DEFAULT_SANDBOX_IMAGE as ut, isCacheEnabled as v, normalizeSessionDeliveryFields as w, deliveryContextKey as x, resolveCacheTtlMs as y, deriveSessionMetaPatch as z };