@termix-it/cryptoclaw 1.0.0

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 (1222) hide show
  1. package/CHANGELOG.md +1615 -0
  2. package/LICENSE +21 -0
  3. package/README-header.png +0 -0
  4. package/README.md +331 -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/cryptoclaw.mjs +14 -0
  18. package/dist/accounts-BPjR5SyC.js +251 -0
  19. package/dist/accounts-CIGHxE7R.js +251 -0
  20. package/dist/acp-cli-DBWmJpUJ.js +924 -0
  21. package/dist/acp-cli-DG9nygBk.js +926 -0
  22. package/dist/agent-3MZVCC-N.js +702 -0
  23. package/dist/agent-IDE9krld.js +702 -0
  24. package/dist/agent-scope-DBl1We79.js +370 -0
  25. package/dist/agent-scope-DLfFOxP6.js +370 -0
  26. package/dist/agent-scope-e_oNRhGi.js +606 -0
  27. package/dist/archive-Dy3Ezb-5.js +85 -0
  28. package/dist/archive-iT9wNsml.js +85 -0
  29. package/dist/audit-Bj_dxNaD.js +1853 -0
  30. package/dist/audit-jaTyyQX1.js +1853 -0
  31. package/dist/auth-RTEHx2eI.js +192 -0
  32. package/dist/auth-health-BlspzqyF.js +149 -0
  33. package/dist/auth-health-CCM6Z3vK.js +149 -0
  34. package/dist/auth-phxCaFNX.js +192 -0
  35. package/dist/auth-profiles-DoD7YxsD.js +2939 -0
  36. package/dist/boolean-BsqeuxE6.js +30 -0
  37. package/dist/brew-CAcErcKz.js +46 -0
  38. package/dist/brew-CqnNFIkD.js +46 -0
  39. package/dist/build-info.json +5 -0
  40. package/dist/call-D2DXG0AC.js +278 -0
  41. package/dist/call-DqxlETxE.js +278 -0
  42. package/dist/canvas-host/a2ui/.bundle.hash +1 -0
  43. package/dist/canvas-host/a2ui/a2ui.bundle.js +17765 -0
  44. package/dist/canvas-host/a2ui/index.html +307 -0
  45. package/dist/channel-options-BHpXOBuP.js +32 -0
  46. package/dist/channel-options-DUkxROTo.js +62 -0
  47. package/dist/channel-selection-BdigfMZZ.js +51 -0
  48. package/dist/channel-selection-D7jFTFec.js +51 -0
  49. package/dist/channel-summary-CobMoKN6.js +1120 -0
  50. package/dist/channel-summary-DS0kcHm2.js +1120 -0
  51. package/dist/channels-cli-D7ZNRrq7.js +1414 -0
  52. package/dist/channels-cli-DBwffwqw.js +1413 -0
  53. package/dist/channels-status-issues-C2UGSPvH.js +18 -0
  54. package/dist/channels-status-issues-Dxmd7zYk.js +18 -0
  55. package/dist/chrome-CwbWzmh4.js +1973 -0
  56. package/dist/chrome-SVqOMFxA.js +1953 -0
  57. package/dist/clack-prompter-k_egRADS.js +92 -0
  58. package/dist/clack-prompter-nSmn5cZ2.js +92 -0
  59. package/dist/cli/daemon-cli.js +2 -0
  60. package/dist/cli-C9xiWnx9.js +86 -0
  61. package/dist/cli-D6C9z94O.js +88 -0
  62. package/dist/cli-utils-B7iQwCY5.js +43 -0
  63. package/dist/cli-utils-CgOu3WAB.js +43 -0
  64. package/dist/client-BaTYzXOU.js +1617 -0
  65. package/dist/client-N6zH1neq.js +1617 -0
  66. package/dist/command-format-9IsYy-9N.js +52 -0
  67. package/dist/command-format-B0bnyrEA.js +38 -0
  68. package/dist/command-format-n_udBm8l.js +52 -0
  69. package/dist/command-options-DL1PhuUF.js +33 -0
  70. package/dist/commands-Dpeoos11.js +230 -0
  71. package/dist/completion-cli-B5nR7jt8.js +434 -0
  72. package/dist/completion-cli-CZ8zPqPs.js +773 -0
  73. package/dist/config-DSpb2aMV.js +4916 -0
  74. package/dist/config-IwiWafT3.js +5657 -0
  75. package/dist/config-dQK4rbfx.js +4916 -0
  76. package/dist/config-guard-DwIb5Y-v.js +5719 -0
  77. package/dist/configure-7M9mLC4o.js +896 -0
  78. package/dist/configure-CivCcvkA.js +896 -0
  79. package/dist/constants-C2T4hQIk.js +65 -0
  80. package/dist/constants-DBvu3LzZ.js +65 -0
  81. package/dist/control-service-BXC31sNw.js +61 -0
  82. package/dist/control-service-lVzEzp9f.js +61 -0
  83. package/dist/control-ui/apple-touch-icon.png +0 -0
  84. package/dist/control-ui/assets/index-DQ-7PWhX.js +7553 -0
  85. package/dist/control-ui/assets/index-DQ-7PWhX.js.map +1 -0
  86. package/dist/control-ui/assets/index-nlpH70Eh.css +1 -0
  87. package/dist/control-ui/favicon-32.png +0 -0
  88. package/dist/control-ui/favicon.ico +0 -0
  89. package/dist/control-ui/favicon.svg +22 -0
  90. package/dist/control-ui/index.html +17 -0
  91. package/dist/cron-cli-DS8ytfYQ.js +455 -0
  92. package/dist/cron-cli-Djb3HUdz.js +457 -0
  93. package/dist/daemon-cli-KoaJ2nJX.js +758 -0
  94. package/dist/daemon-cli-ZQIKLvAO.js +758 -0
  95. package/dist/daemon-runtime-CHWbAfKs.js +517 -0
  96. package/dist/daemon-runtime-DEjUQVjL.js +517 -0
  97. package/dist/deliver-DVRzRmNN.js +2557 -0
  98. package/dist/deliver-OfX6bSYR.js +2587 -0
  99. package/dist/deliver-sPBfRlXT.js +2587 -0
  100. package/dist/deps-BSdWD2wF.js +27 -0
  101. package/dist/deps-CZOfeWEp.js +27 -0
  102. package/dist/devices-cli-DHSpDnCS.js +207 -0
  103. package/dist/devices-cli-b9iF_uOi.js +205 -0
  104. package/dist/directory-cli-D0dTuAem.js +247 -0
  105. package/dist/directory-cli-qniSxsHo.js +245 -0
  106. package/dist/dispatcher-DA3u3CwV.js +160 -0
  107. package/dist/dns-cli-C0JUNb9O.js +201 -0
  108. package/dist/dns-cli-DwwMpMuN.js +199 -0
  109. package/dist/docs-cli-BlFHCHDz.js +161 -0
  110. package/dist/docs-cli-BpSPrY3Y.js +160 -0
  111. package/dist/doctor-Da1XgFcW.js +2584 -0
  112. package/dist/doctor-qrtookj-.js +2585 -0
  113. package/dist/entry.js +1156 -0
  114. package/dist/env-B2Cd_6IS.js +32 -0
  115. package/dist/errors--S5IAxQx.js +1952 -0
  116. package/dist/exec-CLQSz0CI.js +246 -0
  117. package/dist/exec-CW_QjkBi.js +246 -0
  118. package/dist/exec-D7I5LU33.js +1099 -0
  119. package/dist/exec-approvals-CuXem6Li.js +1043 -0
  120. package/dist/exec-approvals-P7vwSw4O.js +1043 -0
  121. package/dist/exec-approvals-cli-Csgqkksl.js +386 -0
  122. package/dist/exec-approvals-cli-Dk4yHE2L.js +388 -0
  123. package/dist/extensionAPI.js +64497 -0
  124. package/dist/format-B7OjpGnt.js +34 -0
  125. package/dist/format-Dv1wz41T.js +34 -0
  126. package/dist/gateway-cli-CJ7H2DgV.js +17352 -0
  127. package/dist/gateway-cli-CrKl-bIH.js +17352 -0
  128. package/dist/gateway-rpc--CH0NWWR.js +28 -0
  129. package/dist/gateway-rpc-BPfCU2Vi.js +28 -0
  130. package/dist/github-copilot-auth-CcPEEb3Q.js +1190 -0
  131. package/dist/github-copilot-auth-h3beCc_l.js +1190 -0
  132. package/dist/github-copilot-token-C1sArkX4.js +103 -0
  133. package/dist/github-copilot-token-DL6Pou2p.js +103 -0
  134. package/dist/github-copilot-token-hMl1wyZp.js +103 -0
  135. package/dist/gmail-setup-utils-CnVYPhaQ.js +428 -0
  136. package/dist/gmail-setup-utils-pZ9NnOvB.js +428 -0
  137. package/dist/health-format-BcsR5dtU.js +1211 -0
  138. package/dist/health-format-Pl8qK65t.js +1212 -0
  139. package/dist/help-format-BzWwbeSF.js +17 -0
  140. package/dist/help-format-CUnac_bT.js +17 -0
  141. package/dist/helpers-5yebzF4C.js +25 -0
  142. package/dist/helpers-CQI-5xS9.js +25 -0
  143. package/dist/helpers-CzQjTUbz.js +10 -0
  144. package/dist/helpers-OUt4hxkS.js +10 -0
  145. package/dist/hooks/bundled/boot-md/HOOK.md +19 -0
  146. package/dist/hooks/bundled/command-logger/HOOK.md +122 -0
  147. package/dist/hooks/bundled/session-memory/HOOK.md +109 -0
  148. package/dist/hooks/bundled/soul-evil/HOOK.md +71 -0
  149. package/dist/hooks-cli-BKHTdsn4.js +1058 -0
  150. package/dist/hooks-cli-zkLY25DX.js +1060 -0
  151. package/dist/hooks-status-BETsyuUR.js +443 -0
  152. package/dist/hooks-status-nPgxLL-x.js +443 -0
  153. package/dist/image-BFNcQzKp.js +629 -0
  154. package/dist/image-CC_YKDB-.js +1421 -0
  155. package/dist/image-DAsWVn7Q.js +629 -0
  156. package/dist/index.js +5900 -0
  157. package/dist/installs-Byb3s_8P.js +425 -0
  158. package/dist/installs-CELeuogN.js +425 -0
  159. package/dist/is-main-B6kCyqsv.js +25 -0
  160. package/dist/is-main-CBExsRNQ.js +25 -0
  161. package/dist/links-Brcj2Oc-.js +15 -0
  162. package/dist/links-cf9h8BXu.js +15 -0
  163. package/dist/loader-CU4bkeKe.js +61131 -0
  164. package/dist/logging-5MtSkLpb.js +1 -0
  165. package/dist/logging-BJRQDTME.js +15 -0
  166. package/dist/logging-CD55MXc7.js +15 -0
  167. package/dist/logging-kuFzZMsG.js +1 -0
  168. package/dist/login-qr-BCr2GKX6.js +475 -0
  169. package/dist/login-qr-BMbekoZW.js +478 -0
  170. package/dist/login-qr-HIPJAnbT.js +478 -0
  171. package/dist/logs-cli-CM7-XOcZ.js +230 -0
  172. package/dist/logs-cli-aqjT7oHu.js +228 -0
  173. package/dist/manager-C5m5qpB0.js +2871 -0
  174. package/dist/manager-CtGvmGvM.js +2872 -0
  175. package/dist/manager-DpZlm3gk.js +2870 -0
  176. package/dist/manifest-registry-BdTzIlta.js +669 -0
  177. package/dist/manifest-registry-DVQHMj0y.js +669 -0
  178. package/dist/message-channel-CfYBy4y3.js +110 -0
  179. package/dist/message-channel-CvHWS3C2.js +110 -0
  180. package/dist/model-selection-Av0fLq51.js +2940 -0
  181. package/dist/model-selection-DuI_Ue9Q.js +2691 -0
  182. package/dist/models-cli-C0JOZ5oP.js +2541 -0
  183. package/dist/models-cli-gmkzOpbq.js +2543 -0
  184. package/dist/net-D4G66Xui.js +137 -0
  185. package/dist/net-YrbuVTd2.js +137 -0
  186. package/dist/node-cli-BND9LLkM.js +1457 -0
  187. package/dist/node-cli-DNRB94ib.js +1459 -0
  188. package/dist/node-service-DTgDFo7M.js +67 -0
  189. package/dist/node-service-JEBcPQat.js +67 -0
  190. package/dist/nodes-cli-BCWlqHyR.js +1208 -0
  191. package/dist/nodes-cli-DWSo5dX7.js +1210 -0
  192. package/dist/nodes-screen-CMvShBEB.js +157 -0
  193. package/dist/nodes-screen-Cok3-EJw.js +157 -0
  194. package/dist/note-C5M2AQOP.js +73 -0
  195. package/dist/note-DEz9ZK7G.js +73 -0
  196. package/dist/onboard-channels-B75LjjVZ.js +671 -0
  197. package/dist/onboard-channels-DJz2TusQ.js +671 -0
  198. package/dist/onboard-skills-ByHkU9nx.js +3615 -0
  199. package/dist/onboard-skills-Wknr7pxR.js +3615 -0
  200. package/dist/onboarding-BejDjkx5.js +3455 -0
  201. package/dist/openclaw-root-YSGWCNem.js +84 -0
  202. package/dist/openclaw-root-_zPXSqgo.js +84 -0
  203. package/dist/pairing-cli-CFqD3IdI.js +122 -0
  204. package/dist/pairing-cli-Cn5vt4oI.js +120 -0
  205. package/dist/pairing-store-BHzy16_t.js +391 -0
  206. package/dist/pairing-store-BOhO49Bi.js +391 -0
  207. package/dist/parse-BZz5lHzQ.js +23 -0
  208. package/dist/parse-Bw0oH-rT.js +23 -0
  209. package/dist/parse-log-line-BxDgv4Uo.js +44 -0
  210. package/dist/parse-log-line-CUrpqe1w.js +44 -0
  211. package/dist/parse-timeout-D1XX_zN_.js +16 -0
  212. package/dist/parse-timeout-Du-wHHNi.js +16 -0
  213. package/dist/path-env-DQ-mM2ya.js +77 -0
  214. package/dist/path-env-eQ-HoQtS.js +77 -0
  215. package/dist/paths-C3yk0MGu.js +43 -0
  216. package/dist/paths-C90k-Dud.js +166 -0
  217. package/dist/paths-CGrNQEMk.js +201 -0
  218. package/dist/paths-D2ytuv-2.js +201 -0
  219. package/dist/paths-Dlp4VNXa.js +40 -0
  220. package/dist/paths-KUslkJRs.js +43 -0
  221. package/dist/pi-embedded-helpers-B7ARjDEK.js +1298 -0
  222. package/dist/pi-embedded-helpers-CQ9sq3Uu.js +8475 -0
  223. package/dist/pi-embedded-helpers-FPVRDeKf.js +1298 -0
  224. package/dist/pi-model-discovery-DWTTaAgY.js +20 -0
  225. package/dist/pi-model-discovery-EhM2JAQo.js +20 -0
  226. package/dist/pi-model-discovery-EwKVHlZB.js +20 -0
  227. package/dist/pi-tools.policy-Du4RZy9R.js +230 -0
  228. package/dist/plugin-auto-enable-EBxTHjFJ.js +461 -0
  229. package/dist/plugin-auto-enable-RwRwIUKC.js +461 -0
  230. package/dist/plugin-sdk/index.d.ts +8453 -0
  231. package/dist/plugin-sdk/index.js +23445 -0
  232. package/dist/plugin-sdk/pi-model-discovery-Dw3A6oXH.js +37 -0
  233. package/dist/plugins-BI-p2ba9.js +495 -0
  234. package/dist/plugins-Dk4UBZwz.js +496 -0
  235. package/dist/plugins-cli-CMg0G56J.js +441 -0
  236. package/dist/plugins-cli-CX7QeUjq.js +443 -0
  237. package/dist/ports-nXmd4Efh.js +96 -0
  238. package/dist/program-EAMJAB_2.js +191 -0
  239. package/dist/progress-D-Oc-KAH.js +133 -0
  240. package/dist/progress-DTEUicRP.js +133 -0
  241. package/dist/prompt-style-BBlJlXtd.js +9 -0
  242. package/dist/prompt-style-BntC_Eoo.js +9 -0
  243. package/dist/prompts-C2D9_VZC.js +10 -0
  244. package/dist/prompts-FbZThK8w.js +10 -0
  245. package/dist/pw-ai-D2jD_dho.js +1651 -0
  246. package/dist/pw-ai-D6JUaD41.js +1650 -0
  247. package/dist/pw-ai-ba2bHPGA.js +1649 -0
  248. package/dist/qmd-manager-B-ijyM7o.js +615 -0
  249. package/dist/qmd-manager-C_Jah5eo.js +618 -0
  250. package/dist/qmd-manager-xo4abL0u.js +618 -0
  251. package/dist/redact-1PNP01B_.js +97 -0
  252. package/dist/redact-BIMJ3ntQ.js +94 -0
  253. package/dist/redact-CVRUv382.js +97 -0
  254. package/dist/register.subclis-CJGimm3-.js +348 -0
  255. package/dist/reply-DfepuqG0.js +61133 -0
  256. package/dist/rolldown-runtime-Cbj13DAv.js +20 -0
  257. package/dist/routes-DkckwrRx.js +2410 -0
  258. package/dist/routes-Q42qtNl1.js +2410 -0
  259. package/dist/rpc-B4lvrGrD.js +95 -0
  260. package/dist/rpc-CbWcXAQK.js +95 -0
  261. package/dist/run-main-JFY3X4Xh.js +194 -0
  262. package/dist/sandbox-BGqDfFaH.js +2945 -0
  263. package/dist/sandbox-D_Tt3WRq.js +2945 -0
  264. package/dist/sandbox-cli-CaxqKiTq.js +461 -0
  265. package/dist/sandbox-cli-DA0Cbrzl.js +463 -0
  266. package/dist/security-cli-BZjA_GAD.js +508 -0
  267. package/dist/security-cli-Ct-pfF2h.js +506 -0
  268. package/dist/server-context-B9ez46MY.js +740 -0
  269. package/dist/server-context-C53lhEx_.js +740 -0
  270. package/dist/server-node-events-Cb6QOeDH.js +218 -0
  271. package/dist/server-node-events-DONmQvJg.js +216 -0
  272. package/dist/service-C0ccl5rU.js +680 -0
  273. package/dist/service-audit-AsnhO40e.js +542 -0
  274. package/dist/service-audit-BM-iyLL7.js +542 -0
  275. package/dist/service-mrQPgOXl.js +680 -0
  276. package/dist/session-cost-usage-B3HzifR9.js +692 -0
  277. package/dist/session-cost-usage-DH3c4xJA.js +692 -0
  278. package/dist/session-key-C-ig2pxJ.js +177 -0
  279. package/dist/session-key-CYpWeuht.js +177 -0
  280. package/dist/shared-CBcCIWC0.js +74 -0
  281. package/dist/shared-CtNMbLRE.js +150 -0
  282. package/dist/shared-DCh7fkR2.js +150 -0
  283. package/dist/shared-Na5zjEUc.js +74 -0
  284. package/dist/skill-scanner-AfOudYI1.js +255 -0
  285. package/dist/skill-scanner-BoGjHXUZ.js +255 -0
  286. package/dist/skills-7V483a6m.js +693 -0
  287. package/dist/skills-CsZRBUj0.js +694 -0
  288. package/dist/skills-cli-DQaq5LBX.js +290 -0
  289. package/dist/skills-cli-dVugbaAb.js +288 -0
  290. package/dist/skills-status-4_4zVBvV.js +187 -0
  291. package/dist/skills-status-cD4rfMR9.js +187 -0
  292. package/dist/sqlite-C4DljFNL.js +215 -0
  293. package/dist/sqlite-CvQzxS7q.js +197 -0
  294. package/dist/sqlite-Dnmf3LS7.js +215 -0
  295. package/dist/status-BakhDLuG.js +27 -0
  296. package/dist/status-BqtiImKF.js +21 -0
  297. package/dist/status-DHPz4Mg_.js +3364 -0
  298. package/dist/status-DSoYX3Ep.js +27 -0
  299. package/dist/status-Drziap9H.js +21 -0
  300. package/dist/subsystem-Btuh5yZj.js +834 -0
  301. package/dist/system-cli-CUQswQPX.js +83 -0
  302. package/dist/system-cli-Cz7in_Xr.js +81 -0
  303. package/dist/systemd-CFHiVC1D.js +438 -0
  304. package/dist/systemd-hints-CgQqk98i.js +19 -0
  305. package/dist/systemd-hints-DKVCFZS3.js +19 -0
  306. package/dist/systemd-kY3NnWdi.js +438 -0
  307. package/dist/systemd-linger-CFK5jDdq.js +75 -0
  308. package/dist/systemd-linger-CxBBzOjC.js +75 -0
  309. package/dist/table-DAOPkdc_.js +279 -0
  310. package/dist/table-DDQGlZSe.js +279 -0
  311. package/dist/tailnet-CZq_ZSNX.js +42 -0
  312. package/dist/tailnet-D5wOWpOX.js +42 -0
  313. package/dist/tailscale-BY0igR48.js +252 -0
  314. package/dist/tailscale-CCLcQalf.js +225 -0
  315. package/dist/tool-display-B2rS2o6B.js +795 -0
  316. package/dist/tool-display-Zbh1CRw5.js +795 -0
  317. package/dist/transcript-events-BOK6eOU8.js +17 -0
  318. package/dist/transcript-events-D2kT5WSz.js +17 -0
  319. package/dist/transcript-events-JLH5W4He.js +17 -0
  320. package/dist/tui-DFVs6pRO.js +2672 -0
  321. package/dist/tui-cli-CBKZVd1C.js +58 -0
  322. package/dist/tui-cli-DexeJOgZ.js +56 -0
  323. package/dist/tui-qPHLsB-x.js +2672 -0
  324. package/dist/update-B2q3duJD.js +317 -0
  325. package/dist/update-DNnej3C6.js +317 -0
  326. package/dist/update-cli-BPUtZjbl.js +1031 -0
  327. package/dist/update-cli-ehTYbpaU.js +1032 -0
  328. package/dist/update-runner-BfncKnU6.js +1375 -0
  329. package/dist/update-runner-DAeygRSU.js +1375 -0
  330. package/dist/usage-format-C4JfTbSp.js +36 -0
  331. package/dist/usage-format-DvowRSs-.js +36 -0
  332. package/dist/utils-7IMqr8vR.js +189 -0
  333. package/dist/utils-D7jskKIf.js +192 -0
  334. package/dist/wallet-manager-7KHKMCbT.js +264 -0
  335. package/dist/wallet-manager-CT1ykq2O.js +264 -0
  336. package/dist/webhooks-cli-C0CV-1jG.js +310 -0
  337. package/dist/webhooks-cli-DT16BygW.js +312 -0
  338. package/dist/widearea-dns-BJZTAyT3.js +127 -0
  339. package/dist/widearea-dns-Dk82I4Xa.js +127 -0
  340. package/dist/ws-6_dFpKWQ.js +13 -0
  341. package/dist/ws-D64QKPe6.js +13 -0
  342. package/dist/ws-log-BhQmGM0R.js +267 -0
  343. package/dist/ws-log-DsyLcTqD.js +267 -0
  344. package/dist/wsl-C24YfxH9.js +160 -0
  345. package/docs/.i18n/README.md +31 -0
  346. package/docs/.i18n/glossary.zh-CN.json +210 -0
  347. package/docs/.i18n/zh-CN.tm.jsonl +1329 -0
  348. package/docs/CNAME +1 -0
  349. package/docs/assets/macos-onboarding/01-macos-warning.jpeg +0 -0
  350. package/docs/assets/macos-onboarding/02-local-networks.jpeg +0 -0
  351. package/docs/assets/macos-onboarding/03-security-notice.png +0 -0
  352. package/docs/assets/macos-onboarding/04-choose-gateway.png +0 -0
  353. package/docs/assets/macos-onboarding/05-permissions.png +0 -0
  354. package/docs/assets/openclaw-logo-text-dark.png +0 -0
  355. package/docs/assets/openclaw-logo-text.png +0 -0
  356. package/docs/assets/pixel-lobster.svg +60 -0
  357. package/docs/assets/showcase/agents-ui.jpg +0 -0
  358. package/docs/assets/showcase/bambu-cli.png +0 -0
  359. package/docs/assets/showcase/codexmonitor.png +0 -0
  360. package/docs/assets/showcase/gohome-grafana.png +0 -0
  361. package/docs/assets/showcase/ios-testflight.jpg +0 -0
  362. package/docs/assets/showcase/oura-health.png +0 -0
  363. package/docs/assets/showcase/padel-cli.svg +11 -0
  364. package/docs/assets/showcase/padel-screenshot.jpg +0 -0
  365. package/docs/assets/showcase/papla-tts.jpg +0 -0
  366. package/docs/assets/showcase/pr-review-telegram.jpg +0 -0
  367. package/docs/assets/showcase/roborock-screenshot.jpg +0 -0
  368. package/docs/assets/showcase/roborock-status.svg +13 -0
  369. package/docs/assets/showcase/roof-camera-sky.jpg +0 -0
  370. package/docs/assets/showcase/snag.png +0 -0
  371. package/docs/assets/showcase/tesco-shop.jpg +0 -0
  372. package/docs/assets/showcase/wienerlinien.png +0 -0
  373. package/docs/assets/showcase/wine-cellar-skill.jpg +0 -0
  374. package/docs/assets/showcase/winix-air-purifier.jpg +0 -0
  375. package/docs/assets/showcase/xuezh-pronunciation.jpeg +0 -0
  376. package/docs/automation/auth-monitoring.md +44 -0
  377. package/docs/automation/cron-jobs.md +468 -0
  378. package/docs/automation/cron-vs-heartbeat.md +282 -0
  379. package/docs/automation/gmail-pubsub.md +256 -0
  380. package/docs/automation/poll.md +69 -0
  381. package/docs/automation/webhook.md +163 -0
  382. package/docs/bedrock.md +176 -0
  383. package/docs/brave-search.md +41 -0
  384. package/docs/broadcast-groups.md +442 -0
  385. package/docs/channels/bluebubbles.md +338 -0
  386. package/docs/channels/discord.md +476 -0
  387. package/docs/channels/feishu.md +577 -0
  388. package/docs/channels/googlechat.md +250 -0
  389. package/docs/channels/grammy.md +31 -0
  390. package/docs/channels/imessage.md +299 -0
  391. package/docs/channels/index.md +46 -0
  392. package/docs/channels/line.md +186 -0
  393. package/docs/channels/location.md +56 -0
  394. package/docs/channels/matrix.md +233 -0
  395. package/docs/channels/mattermost.md +138 -0
  396. package/docs/channels/msteams.md +768 -0
  397. package/docs/channels/nextcloud-talk.md +136 -0
  398. package/docs/channels/nostr.md +233 -0
  399. package/docs/channels/signal.md +202 -0
  400. package/docs/channels/slack.md +548 -0
  401. package/docs/channels/telegram.md +769 -0
  402. package/docs/channels/tlon.md +132 -0
  403. package/docs/channels/troubleshooting.md +29 -0
  404. package/docs/channels/twitch.md +379 -0
  405. package/docs/channels/whatsapp.md +404 -0
  406. package/docs/channels/zalo.md +189 -0
  407. package/docs/channels/zalouser.md +140 -0
  408. package/docs/cli/acp.md +170 -0
  409. package/docs/cli/agent.md +24 -0
  410. package/docs/cli/agents.md +75 -0
  411. package/docs/cli/approvals.md +50 -0
  412. package/docs/cli/browser.md +107 -0
  413. package/docs/cli/channels.md +79 -0
  414. package/docs/cli/config.md +50 -0
  415. package/docs/cli/configure.md +33 -0
  416. package/docs/cli/cron.md +42 -0
  417. package/docs/cli/dashboard.md +16 -0
  418. package/docs/cli/devices.md +70 -0
  419. package/docs/cli/directory.md +63 -0
  420. package/docs/cli/dns.md +23 -0
  421. package/docs/cli/docs.md +15 -0
  422. package/docs/cli/doctor.md +41 -0
  423. package/docs/cli/gateway.md +202 -0
  424. package/docs/cli/health.md +21 -0
  425. package/docs/cli/hooks.md +304 -0
  426. package/docs/cli/index.md +1031 -0
  427. package/docs/cli/logs.md +24 -0
  428. package/docs/cli/memory.md +45 -0
  429. package/docs/cli/message.md +239 -0
  430. package/docs/cli/models.md +79 -0
  431. package/docs/cli/node.md +112 -0
  432. package/docs/cli/nodes.md +73 -0
  433. package/docs/cli/onboard.md +43 -0
  434. package/docs/cli/pairing.md +21 -0
  435. package/docs/cli/plugins.md +62 -0
  436. package/docs/cli/reset.md +17 -0
  437. package/docs/cli/sandbox.md +152 -0
  438. package/docs/cli/security.md +26 -0
  439. package/docs/cli/sessions.md +16 -0
  440. package/docs/cli/setup.md +29 -0
  441. package/docs/cli/skills.md +26 -0
  442. package/docs/cli/status.md +26 -0
  443. package/docs/cli/system.md +60 -0
  444. package/docs/cli/tui.md +23 -0
  445. package/docs/cli/uninstall.md +17 -0
  446. package/docs/cli/update.md +98 -0
  447. package/docs/cli/voicecall.md +34 -0
  448. package/docs/cli/webhooks.md +25 -0
  449. package/docs/concepts/agent-loop.md +146 -0
  450. package/docs/concepts/agent-workspace.md +233 -0
  451. package/docs/concepts/agent.md +123 -0
  452. package/docs/concepts/architecture.md +129 -0
  453. package/docs/concepts/channel-routing.md +114 -0
  454. package/docs/concepts/compaction.md +61 -0
  455. package/docs/concepts/context.md +161 -0
  456. package/docs/concepts/features.md +53 -0
  457. package/docs/concepts/group-messages.md +84 -0
  458. package/docs/concepts/groups.md +373 -0
  459. package/docs/concepts/markdown-formatting.md +130 -0
  460. package/docs/concepts/memory.md +546 -0
  461. package/docs/concepts/messages.md +154 -0
  462. package/docs/concepts/model-failover.md +149 -0
  463. package/docs/concepts/model-providers.md +316 -0
  464. package/docs/concepts/models.md +208 -0
  465. package/docs/concepts/multi-agent.md +376 -0
  466. package/docs/concepts/oauth.md +145 -0
  467. package/docs/concepts/presence.md +102 -0
  468. package/docs/concepts/queue.md +89 -0
  469. package/docs/concepts/retry.md +69 -0
  470. package/docs/concepts/session-pruning.md +122 -0
  471. package/docs/concepts/session-tool.md +193 -0
  472. package/docs/concepts/session.md +204 -0
  473. package/docs/concepts/sessions.md +10 -0
  474. package/docs/concepts/streaming.md +135 -0
  475. package/docs/concepts/system-prompt.md +115 -0
  476. package/docs/concepts/timezone.md +91 -0
  477. package/docs/concepts/typebox.md +289 -0
  478. package/docs/concepts/typing-indicators.md +68 -0
  479. package/docs/concepts/usage-tracking.md +35 -0
  480. package/docs/date-time.md +128 -0
  481. package/docs/debug/node-issue.md +83 -0
  482. package/docs/debugging.md +162 -0
  483. package/docs/diagnostics/flags.md +91 -0
  484. package/docs/docs.json +1736 -0
  485. package/docs/environment.md +81 -0
  486. package/docs/experiments/onboarding-config-protocol.md +40 -0
  487. package/docs/experiments/plans/cron-add-hardening.md +63 -0
  488. package/docs/experiments/plans/group-policy-hardening.md +40 -0
  489. package/docs/experiments/plans/openresponses-gateway.md +123 -0
  490. package/docs/experiments/proposals/model-config.md +36 -0
  491. package/docs/experiments/research/memory.md +228 -0
  492. package/docs/gateway/authentication.md +145 -0
  493. package/docs/gateway/background-process.md +93 -0
  494. package/docs/gateway/bonjour.md +167 -0
  495. package/docs/gateway/bridge-protocol.md +89 -0
  496. package/docs/gateway/cli-backends.md +225 -0
  497. package/docs/gateway/configuration-examples.md +606 -0
  498. package/docs/gateway/configuration.md +3411 -0
  499. package/docs/gateway/discovery.md +116 -0
  500. package/docs/gateway/doctor.md +282 -0
  501. package/docs/gateway/gateway-lock.md +34 -0
  502. package/docs/gateway/health.md +35 -0
  503. package/docs/gateway/heartbeat.md +362 -0
  504. package/docs/gateway/index.md +328 -0
  505. package/docs/gateway/local-models.md +150 -0
  506. package/docs/gateway/logging.md +113 -0
  507. package/docs/gateway/multiple-gateways.md +112 -0
  508. package/docs/gateway/network-model.md +17 -0
  509. package/docs/gateway/openai-http-api.md +118 -0
  510. package/docs/gateway/openresponses-http-api.md +317 -0
  511. package/docs/gateway/pairing.md +99 -0
  512. package/docs/gateway/protocol.md +221 -0
  513. package/docs/gateway/remote-gateway-readme.md +157 -0
  514. package/docs/gateway/remote.md +129 -0
  515. package/docs/gateway/sandbox-vs-tool-policy-vs-elevated.md +128 -0
  516. package/docs/gateway/sandboxing.md +193 -0
  517. package/docs/gateway/security/formal-verification.md +164 -0
  518. package/docs/gateway/security/index.md +825 -0
  519. package/docs/gateway/tailscale.md +127 -0
  520. package/docs/gateway/tools-invoke-http-api.md +85 -0
  521. package/docs/gateway/troubleshooting.md +767 -0
  522. package/docs/help/faq.md +2829 -0
  523. package/docs/help/index.md +21 -0
  524. package/docs/help/troubleshooting.md +98 -0
  525. package/docs/hooks/soul-evil.md +69 -0
  526. package/docs/hooks.md +913 -0
  527. package/docs/images/feishu-step2-create-app.png +0 -0
  528. package/docs/images/feishu-step3-credentials.png +0 -0
  529. package/docs/images/feishu-step4-permissions.png +0 -0
  530. package/docs/images/feishu-step5-bot-capability.png +0 -0
  531. package/docs/images/feishu-step6-event-subscription.png +0 -0
  532. package/docs/images/groups-flow.svg +52 -0
  533. package/docs/images/mobile-ui-screenshot.png +0 -0
  534. package/docs/index.md +192 -0
  535. package/docs/install/ansible.md +208 -0
  536. package/docs/install/bun.md +59 -0
  537. package/docs/install/development-channels.md +75 -0
  538. package/docs/install/docker.md +567 -0
  539. package/docs/install/exe-dev.md +126 -0
  540. package/docs/install/fly.md +486 -0
  541. package/docs/install/gcp.md +503 -0
  542. package/docs/install/hetzner.md +330 -0
  543. package/docs/install/index.md +187 -0
  544. package/docs/install/installer.md +123 -0
  545. package/docs/install/macos-vm.md +281 -0
  546. package/docs/install/migrating.md +192 -0
  547. package/docs/install/nix.md +96 -0
  548. package/docs/install/node.md +78 -0
  549. package/docs/install/northflank.mdx +53 -0
  550. package/docs/install/railway.mdx +99 -0
  551. package/docs/install/render.mdx +165 -0
  552. package/docs/install/uninstall.md +128 -0
  553. package/docs/install/updating.md +228 -0
  554. package/docs/logging.md +350 -0
  555. package/docs/multi-agent-sandbox-tools.md +395 -0
  556. package/docs/network.md +54 -0
  557. package/docs/nodes/audio.md +114 -0
  558. package/docs/nodes/camera.md +156 -0
  559. package/docs/nodes/images.md +72 -0
  560. package/docs/nodes/index.md +341 -0
  561. package/docs/nodes/location-command.md +113 -0
  562. package/docs/nodes/media-understanding.md +379 -0
  563. package/docs/nodes/talk.md +90 -0
  564. package/docs/nodes/voicewake.md +65 -0
  565. package/docs/perplexity.md +80 -0
  566. package/docs/pi-dev.md +70 -0
  567. package/docs/pi.md +612 -0
  568. package/docs/platforms/android.md +148 -0
  569. package/docs/platforms/digitalocean.md +262 -0
  570. package/docs/platforms/index.md +53 -0
  571. package/docs/platforms/ios.md +107 -0
  572. package/docs/platforms/linux.md +94 -0
  573. package/docs/platforms/mac/bundled-gateway.md +73 -0
  574. package/docs/platforms/mac/canvas.md +125 -0
  575. package/docs/platforms/mac/child-process.md +69 -0
  576. package/docs/platforms/mac/dev-setup.md +102 -0
  577. package/docs/platforms/mac/health.md +34 -0
  578. package/docs/platforms/mac/icon.md +31 -0
  579. package/docs/platforms/mac/logging.md +57 -0
  580. package/docs/platforms/mac/menu-bar.md +81 -0
  581. package/docs/platforms/mac/peekaboo.md +65 -0
  582. package/docs/platforms/mac/permissions.md +44 -0
  583. package/docs/platforms/mac/release.md +85 -0
  584. package/docs/platforms/mac/remote.md +83 -0
  585. package/docs/platforms/mac/signing.md +47 -0
  586. package/docs/platforms/mac/skills.md +33 -0
  587. package/docs/platforms/mac/voice-overlay.md +60 -0
  588. package/docs/platforms/mac/voicewake.md +67 -0
  589. package/docs/platforms/mac/webchat.md +41 -0
  590. package/docs/platforms/mac/xpc.md +61 -0
  591. package/docs/platforms/macos.md +203 -0
  592. package/docs/platforms/oracle.md +303 -0
  593. package/docs/platforms/raspberry-pi.md +358 -0
  594. package/docs/platforms/windows.md +159 -0
  595. package/docs/plugin.md +664 -0
  596. package/docs/plugins/agent-tools.md +99 -0
  597. package/docs/plugins/manifest.md +71 -0
  598. package/docs/plugins/voice-call.md +284 -0
  599. package/docs/plugins/zalouser.md +81 -0
  600. package/docs/prose.md +134 -0
  601. package/docs/providers/anthropic.md +152 -0
  602. package/docs/providers/claude-max-api-proxy.md +148 -0
  603. package/docs/providers/cloudflare-ai-gateway.md +71 -0
  604. package/docs/providers/deepgram.md +93 -0
  605. package/docs/providers/github-copilot.md +72 -0
  606. package/docs/providers/glm.md +33 -0
  607. package/docs/providers/index.md +63 -0
  608. package/docs/providers/minimax.md +208 -0
  609. package/docs/providers/models.md +51 -0
  610. package/docs/providers/moonshot.md +142 -0
  611. package/docs/providers/ollama.md +277 -0
  612. package/docs/providers/openai.md +62 -0
  613. package/docs/providers/opencode.md +36 -0
  614. package/docs/providers/openrouter.md +37 -0
  615. package/docs/providers/qwen.md +53 -0
  616. package/docs/providers/synthetic.md +99 -0
  617. package/docs/providers/venice.md +267 -0
  618. package/docs/providers/vercel-ai-gateway.md +50 -0
  619. package/docs/providers/xiaomi.md +64 -0
  620. package/docs/providers/zai.md +36 -0
  621. package/docs/refactor/clawnet.md +417 -0
  622. package/docs/refactor/exec-host.md +316 -0
  623. package/docs/refactor/outbound-session-mirroring.md +85 -0
  624. package/docs/refactor/plugin-sdk.md +214 -0
  625. package/docs/refactor/strict-config.md +93 -0
  626. package/docs/reference/AGENTS.default.md +124 -0
  627. package/docs/reference/RELEASING.md +120 -0
  628. package/docs/reference/api-usage-costs.md +137 -0
  629. package/docs/reference/credits.md +27 -0
  630. package/docs/reference/device-models.md +47 -0
  631. package/docs/reference/rpc.md +43 -0
  632. package/docs/reference/session-management-compaction.md +285 -0
  633. package/docs/reference/templates/AGENTS.dev.md +83 -0
  634. package/docs/reference/templates/AGENTS.md +218 -0
  635. package/docs/reference/templates/BOOT.md +10 -0
  636. package/docs/reference/templates/BOOTSTRAP.md +61 -0
  637. package/docs/reference/templates/HEARTBEAT.md +11 -0
  638. package/docs/reference/templates/IDENTITY.dev.md +47 -0
  639. package/docs/reference/templates/IDENTITY.md +27 -0
  640. package/docs/reference/templates/SOUL.dev.md +76 -0
  641. package/docs/reference/templates/SOUL.md +42 -0
  642. package/docs/reference/templates/TOOLS.dev.md +24 -0
  643. package/docs/reference/templates/TOOLS.md +46 -0
  644. package/docs/reference/templates/USER.dev.md +18 -0
  645. package/docs/reference/templates/USER.md +22 -0
  646. package/docs/reference/test.md +50 -0
  647. package/docs/reference/transcript-hygiene.md +129 -0
  648. package/docs/reference/wizard.md +268 -0
  649. package/docs/scripts.md +28 -0
  650. package/docs/security/formal-verification.md +164 -0
  651. package/docs/start/bootstrapping.md +41 -0
  652. package/docs/start/docs-directory.md +64 -0
  653. package/docs/start/getting-started.md +120 -0
  654. package/docs/start/hubs.md +197 -0
  655. package/docs/start/lore.md +219 -0
  656. package/docs/start/onboarding.md +80 -0
  657. package/docs/start/openclaw.md +224 -0
  658. package/docs/start/pairing.md +86 -0
  659. package/docs/start/quickstart.md +22 -0
  660. package/docs/start/setup.md +162 -0
  661. package/docs/start/showcase.md +416 -0
  662. package/docs/start/wizard-cli-automation.md +141 -0
  663. package/docs/start/wizard-cli-reference.md +244 -0
  664. package/docs/start/wizard.md +108 -0
  665. package/docs/style.css +3 -0
  666. package/docs/testing.md +368 -0
  667. package/docs/token-use.md +112 -0
  668. package/docs/tools/agent-send.md +53 -0
  669. package/docs/tools/apply-patch.md +50 -0
  670. package/docs/tools/browser-linux-troubleshooting.md +139 -0
  671. package/docs/tools/browser-login.md +68 -0
  672. package/docs/tools/browser.md +576 -0
  673. package/docs/tools/chrome-extension.md +178 -0
  674. package/docs/tools/clawhub.md +257 -0
  675. package/docs/tools/creating-skills.md +54 -0
  676. package/docs/tools/elevated.md +57 -0
  677. package/docs/tools/exec-approvals.md +246 -0
  678. package/docs/tools/exec.md +179 -0
  679. package/docs/tools/firecrawl.md +61 -0
  680. package/docs/tools/index.md +512 -0
  681. package/docs/tools/llm-task.md +115 -0
  682. package/docs/tools/lobster.md +342 -0
  683. package/docs/tools/reactions.md +22 -0
  684. package/docs/tools/skills-config.md +76 -0
  685. package/docs/tools/skills.md +300 -0
  686. package/docs/tools/slash-commands.md +198 -0
  687. package/docs/tools/subagents.md +151 -0
  688. package/docs/tools/thinking.md +74 -0
  689. package/docs/tools/web.md +261 -0
  690. package/docs/tts.md +396 -0
  691. package/docs/tui.md +162 -0
  692. package/docs/vps.md +43 -0
  693. package/docs/web/control-ui.md +223 -0
  694. package/docs/web/dashboard.md +46 -0
  695. package/docs/web/index.md +116 -0
  696. package/docs/web/webchat.md +49 -0
  697. package/docs/whatsapp-openclaw-ai-zh.jpg +0 -0
  698. package/docs/whatsapp-openclaw.jpg +0 -0
  699. package/docs/zh-CN/AGENTS.md +59 -0
  700. package/docs/zh-CN/automation/auth-monitoring.md +47 -0
  701. package/docs/zh-CN/automation/cron-jobs.md +424 -0
  702. package/docs/zh-CN/automation/cron-vs-heartbeat.md +286 -0
  703. package/docs/zh-CN/automation/gmail-pubsub.md +249 -0
  704. package/docs/zh-CN/automation/poll.md +76 -0
  705. package/docs/zh-CN/automation/webhook.md +163 -0
  706. package/docs/zh-CN/bedrock.md +170 -0
  707. package/docs/zh-CN/brave-search.md +48 -0
  708. package/docs/zh-CN/broadcast-groups.md +449 -0
  709. package/docs/zh-CN/channels/bluebubbles.md +271 -0
  710. package/docs/zh-CN/channels/discord.md +468 -0
  711. package/docs/zh-CN/channels/feishu.md +629 -0
  712. package/docs/zh-CN/channels/googlechat.md +257 -0
  713. package/docs/zh-CN/channels/grammy.md +38 -0
  714. package/docs/zh-CN/channels/imessage.md +302 -0
  715. package/docs/zh-CN/channels/index.md +53 -0
  716. package/docs/zh-CN/channels/line.md +180 -0
  717. package/docs/zh-CN/channels/location.md +63 -0
  718. package/docs/zh-CN/channels/matrix.md +221 -0
  719. package/docs/zh-CN/channels/mattermost.md +144 -0
  720. package/docs/zh-CN/channels/msteams.md +775 -0
  721. package/docs/zh-CN/channels/nextcloud-talk.md +142 -0
  722. package/docs/zh-CN/channels/nostr.md +240 -0
  723. package/docs/zh-CN/channels/signal.md +209 -0
  724. package/docs/zh-CN/channels/slack.md +531 -0
  725. package/docs/zh-CN/channels/telegram.md +751 -0
  726. package/docs/zh-CN/channels/tlon.md +136 -0
  727. package/docs/zh-CN/channels/troubleshooting.md +36 -0
  728. package/docs/zh-CN/channels/twitch.md +385 -0
  729. package/docs/zh-CN/channels/whatsapp.md +411 -0
  730. package/docs/zh-CN/channels/zalo.md +196 -0
  731. package/docs/zh-CN/channels/zalouser.md +147 -0
  732. package/docs/zh-CN/cli/acp.md +173 -0
  733. package/docs/zh-CN/cli/agent.md +30 -0
  734. package/docs/zh-CN/cli/agents.md +82 -0
  735. package/docs/zh-CN/cli/approvals.md +57 -0
  736. package/docs/zh-CN/cli/browser.md +114 -0
  737. package/docs/zh-CN/cli/channels.md +86 -0
  738. package/docs/zh-CN/cli/config.md +57 -0
  739. package/docs/zh-CN/cli/configure.md +38 -0
  740. package/docs/zh-CN/cli/cron.md +43 -0
  741. package/docs/zh-CN/cli/dashboard.md +23 -0
  742. package/docs/zh-CN/cli/devices.md +74 -0
  743. package/docs/zh-CN/cli/directory.md +70 -0
  744. package/docs/zh-CN/cli/dns.md +30 -0
  745. package/docs/zh-CN/cli/docs.md +22 -0
  746. package/docs/zh-CN/cli/doctor.md +48 -0
  747. package/docs/zh-CN/cli/gateway.md +206 -0
  748. package/docs/zh-CN/cli/health.md +28 -0
  749. package/docs/zh-CN/cli/hooks.md +311 -0
  750. package/docs/zh-CN/cli/index.md +1032 -0
  751. package/docs/zh-CN/cli/logs.md +31 -0
  752. package/docs/zh-CN/cli/memory.md +52 -0
  753. package/docs/zh-CN/cli/message.md +246 -0
  754. package/docs/zh-CN/cli/models.md +85 -0
  755. package/docs/zh-CN/cli/node.md +115 -0
  756. package/docs/zh-CN/cli/nodes.md +80 -0
  757. package/docs/zh-CN/cli/onboard.md +36 -0
  758. package/docs/zh-CN/cli/pairing.md +28 -0
  759. package/docs/zh-CN/cli/plugins.md +66 -0
  760. package/docs/zh-CN/cli/reset.md +24 -0
  761. package/docs/zh-CN/cli/sandbox.md +158 -0
  762. package/docs/zh-CN/cli/security.md +33 -0
  763. package/docs/zh-CN/cli/sessions.md +23 -0
  764. package/docs/zh-CN/cli/setup.md +36 -0
  765. package/docs/zh-CN/cli/skills.md +33 -0
  766. package/docs/zh-CN/cli/status.md +33 -0
  767. package/docs/zh-CN/cli/system.md +63 -0
  768. package/docs/zh-CN/cli/tui.md +30 -0
  769. package/docs/zh-CN/cli/uninstall.md +24 -0
  770. package/docs/zh-CN/cli/update.md +101 -0
  771. package/docs/zh-CN/cli/voicecall.md +41 -0
  772. package/docs/zh-CN/cli/webhooks.md +32 -0
  773. package/docs/zh-CN/concepts/agent-loop.md +146 -0
  774. package/docs/zh-CN/concepts/agent-workspace.md +219 -0
  775. package/docs/zh-CN/concepts/agent.md +115 -0
  776. package/docs/zh-CN/concepts/architecture.md +123 -0
  777. package/docs/zh-CN/concepts/channel-routing.md +117 -0
  778. package/docs/zh-CN/concepts/compaction.md +67 -0
  779. package/docs/zh-CN/concepts/context.md +168 -0
  780. package/docs/zh-CN/concepts/features.md +59 -0
  781. package/docs/zh-CN/concepts/group-messages.md +91 -0
  782. package/docs/zh-CN/concepts/groups.md +379 -0
  783. package/docs/zh-CN/concepts/markdown-formatting.md +117 -0
  784. package/docs/zh-CN/concepts/memory.md +412 -0
  785. package/docs/zh-CN/concepts/messages.md +141 -0
  786. package/docs/zh-CN/concepts/model-failover.md +145 -0
  787. package/docs/zh-CN/concepts/model-providers.md +320 -0
  788. package/docs/zh-CN/concepts/models.md +196 -0
  789. package/docs/zh-CN/concepts/multi-agent.md +372 -0
  790. package/docs/zh-CN/concepts/oauth.md +151 -0
  791. package/docs/zh-CN/concepts/presence.md +99 -0
  792. package/docs/zh-CN/concepts/queue.md +94 -0
  793. package/docs/zh-CN/concepts/retry.md +76 -0
  794. package/docs/zh-CN/concepts/session-pruning.md +129 -0
  795. package/docs/zh-CN/concepts/session-tool.md +200 -0
  796. package/docs/zh-CN/concepts/session.md +166 -0
  797. package/docs/zh-CN/concepts/sessions.md +17 -0
  798. package/docs/zh-CN/concepts/streaming.md +133 -0
  799. package/docs/zh-CN/concepts/system-prompt.md +101 -0
  800. package/docs/zh-CN/concepts/timezone.md +96 -0
  801. package/docs/zh-CN/concepts/typebox.md +284 -0
  802. package/docs/zh-CN/concepts/typing-indicators.md +74 -0
  803. package/docs/zh-CN/concepts/usage-tracking.md +42 -0
  804. package/docs/zh-CN/date-time.md +129 -0
  805. package/docs/zh-CN/debug/node-issue.md +90 -0
  806. package/docs/zh-CN/debugging.md +160 -0
  807. package/docs/zh-CN/diagnostics/flags.md +98 -0
  808. package/docs/zh-CN/environment.md +88 -0
  809. package/docs/zh-CN/experiments/onboarding-config-protocol.md +47 -0
  810. package/docs/zh-CN/experiments/plans/cron-add-hardening.md +70 -0
  811. package/docs/zh-CN/experiments/plans/group-policy-hardening.md +45 -0
  812. package/docs/zh-CN/experiments/plans/openresponses-gateway.md +121 -0
  813. package/docs/zh-CN/experiments/proposals/model-config.md +42 -0
  814. package/docs/zh-CN/experiments/research/memory.md +235 -0
  815. package/docs/zh-CN/gateway/authentication.md +142 -0
  816. package/docs/zh-CN/gateway/background-process.md +100 -0
  817. package/docs/zh-CN/gateway/bonjour.md +174 -0
  818. package/docs/zh-CN/gateway/bridge-protocol.md +86 -0
  819. package/docs/zh-CN/gateway/cli-backends.md +213 -0
  820. package/docs/zh-CN/gateway/configuration-examples.md +587 -0
  821. package/docs/zh-CN/gateway/configuration.md +3332 -0
  822. package/docs/zh-CN/gateway/discovery.md +123 -0
  823. package/docs/zh-CN/gateway/doctor.md +238 -0
  824. package/docs/zh-CN/gateway/gateway-lock.md +41 -0
  825. package/docs/zh-CN/gateway/health.md +42 -0
  826. package/docs/zh-CN/gateway/heartbeat.md +274 -0
  827. package/docs/zh-CN/gateway/index.md +335 -0
  828. package/docs/zh-CN/gateway/local-models.md +157 -0
  829. package/docs/zh-CN/gateway/logging.md +114 -0
  830. package/docs/zh-CN/gateway/multiple-gateways.md +119 -0
  831. package/docs/zh-CN/gateway/network-model.md +23 -0
  832. package/docs/zh-CN/gateway/openai-http-api.md +125 -0
  833. package/docs/zh-CN/gateway/openresponses-http-api.md +317 -0
  834. package/docs/zh-CN/gateway/pairing.md +99 -0
  835. package/docs/zh-CN/gateway/protocol.md +220 -0
  836. package/docs/zh-CN/gateway/remote-gateway-readme.md +164 -0
  837. package/docs/zh-CN/gateway/remote.md +133 -0
  838. package/docs/zh-CN/gateway/sandbox-vs-tool-policy-vs-elevated.md +135 -0
  839. package/docs/zh-CN/gateway/sandboxing.md +188 -0
  840. package/docs/zh-CN/gateway/security/formal-verification.md +169 -0
  841. package/docs/zh-CN/gateway/security/index.md +777 -0
  842. package/docs/zh-CN/gateway/tailscale.md +124 -0
  843. package/docs/zh-CN/gateway/tools-invoke-http-api.md +92 -0
  844. package/docs/zh-CN/gateway/troubleshooting.md +771 -0
  845. package/docs/zh-CN/help/faq.md +2628 -0
  846. package/docs/zh-CN/help/index.md +28 -0
  847. package/docs/zh-CN/help/troubleshooting.md +104 -0
  848. package/docs/zh-CN/hooks/soul-evil.md +72 -0
  849. package/docs/zh-CN/hooks.md +919 -0
  850. package/docs/zh-CN/index.md +186 -0
  851. package/docs/zh-CN/install/ansible.md +215 -0
  852. package/docs/zh-CN/install/bun.md +65 -0
  853. package/docs/zh-CN/install/development-channels.md +81 -0
  854. package/docs/zh-CN/install/docker.md +532 -0
  855. package/docs/zh-CN/install/exe-dev.md +127 -0
  856. package/docs/zh-CN/install/fly.md +490 -0
  857. package/docs/zh-CN/install/gcp.md +510 -0
  858. package/docs/zh-CN/install/hetzner.md +337 -0
  859. package/docs/zh-CN/install/index.md +193 -0
  860. package/docs/zh-CN/install/installer.md +128 -0
  861. package/docs/zh-CN/install/macos-vm.md +288 -0
  862. package/docs/zh-CN/install/migrating.md +199 -0
  863. package/docs/zh-CN/install/nix.md +99 -0
  864. package/docs/zh-CN/install/node.md +85 -0
  865. package/docs/zh-CN/install/northflank.mdx +60 -0
  866. package/docs/zh-CN/install/railway.mdx +106 -0
  867. package/docs/zh-CN/install/render.mdx +169 -0
  868. package/docs/zh-CN/install/uninstall.md +135 -0
  869. package/docs/zh-CN/install/updating.md +233 -0
  870. package/docs/zh-CN/logging.md +329 -0
  871. package/docs/zh-CN/multi-agent-sandbox-tools.md +401 -0
  872. package/docs/zh-CN/network.md +59 -0
  873. package/docs/zh-CN/nodes/audio.md +120 -0
  874. package/docs/zh-CN/nodes/camera.md +162 -0
  875. package/docs/zh-CN/nodes/images.md +79 -0
  876. package/docs/zh-CN/nodes/index.md +348 -0
  877. package/docs/zh-CN/nodes/location-command.md +120 -0
  878. package/docs/zh-CN/nodes/media-understanding.md +380 -0
  879. package/docs/zh-CN/nodes/talk.md +97 -0
  880. package/docs/zh-CN/nodes/voicewake.md +72 -0
  881. package/docs/zh-CN/perplexity.md +84 -0
  882. package/docs/zh-CN/pi-dev.md +77 -0
  883. package/docs/zh-CN/pi.md +619 -0
  884. package/docs/zh-CN/platforms/android.md +155 -0
  885. package/docs/zh-CN/platforms/digitalocean.md +269 -0
  886. package/docs/zh-CN/platforms/index.md +60 -0
  887. package/docs/zh-CN/platforms/ios.md +114 -0
  888. package/docs/zh-CN/platforms/linux.md +101 -0
  889. package/docs/zh-CN/platforms/mac/bundled-gateway.md +75 -0
  890. package/docs/zh-CN/platforms/mac/canvas.md +128 -0
  891. package/docs/zh-CN/platforms/mac/child-process.md +73 -0
  892. package/docs/zh-CN/platforms/mac/dev-setup.md +109 -0
  893. package/docs/zh-CN/platforms/mac/health.md +41 -0
  894. package/docs/zh-CN/platforms/mac/icon.md +38 -0
  895. package/docs/zh-CN/platforms/mac/logging.md +64 -0
  896. package/docs/zh-CN/platforms/mac/menu-bar.md +88 -0
  897. package/docs/zh-CN/platforms/mac/peekaboo.md +62 -0
  898. package/docs/zh-CN/platforms/mac/permissions.md +46 -0
  899. package/docs/zh-CN/platforms/mac/release.md +92 -0
  900. package/docs/zh-CN/platforms/mac/remote.md +90 -0
  901. package/docs/zh-CN/platforms/mac/signing.md +54 -0
  902. package/docs/zh-CN/platforms/mac/skills.md +40 -0
  903. package/docs/zh-CN/platforms/mac/voice-overlay.md +67 -0
  904. package/docs/zh-CN/platforms/mac/voicewake.md +74 -0
  905. package/docs/zh-CN/platforms/mac/webchat.md +43 -0
  906. package/docs/zh-CN/platforms/mac/xpc.md +68 -0
  907. package/docs/zh-CN/platforms/macos.md +193 -0
  908. package/docs/zh-CN/platforms/oracle.md +310 -0
  909. package/docs/zh-CN/platforms/raspberry-pi.md +365 -0
  910. package/docs/zh-CN/platforms/windows.md +156 -0
  911. package/docs/zh-CN/plugin.md +639 -0
  912. package/docs/zh-CN/plugins/agent-tools.md +99 -0
  913. package/docs/zh-CN/plugins/manifest.md +68 -0
  914. package/docs/zh-CN/plugins/voice-call.md +250 -0
  915. package/docs/zh-CN/plugins/zalouser.md +88 -0
  916. package/docs/zh-CN/prose.md +141 -0
  917. package/docs/zh-CN/providers/anthropic.md +159 -0
  918. package/docs/zh-CN/providers/claude-max-api-proxy.md +155 -0
  919. package/docs/zh-CN/providers/deepgram.md +97 -0
  920. package/docs/zh-CN/providers/github-copilot.md +67 -0
  921. package/docs/zh-CN/providers/glm.md +39 -0
  922. package/docs/zh-CN/providers/index.md +68 -0
  923. package/docs/zh-CN/providers/minimax.md +206 -0
  924. package/docs/zh-CN/providers/models.md +55 -0
  925. package/docs/zh-CN/providers/moonshot.md +145 -0
  926. package/docs/zh-CN/providers/ollama.md +230 -0
  927. package/docs/zh-CN/providers/openai.md +68 -0
  928. package/docs/zh-CN/providers/opencode.md +41 -0
  929. package/docs/zh-CN/providers/openrouter.md +43 -0
  930. package/docs/zh-CN/providers/qwen.md +55 -0
  931. package/docs/zh-CN/providers/synthetic.md +102 -0
  932. package/docs/zh-CN/providers/venice.md +274 -0
  933. package/docs/zh-CN/providers/vercel-ai-gateway.md +57 -0
  934. package/docs/zh-CN/providers/xiaomi.md +68 -0
  935. package/docs/zh-CN/providers/zai.md +41 -0
  936. package/docs/zh-CN/refactor/clawnet.md +424 -0
  937. package/docs/zh-CN/refactor/exec-host.md +323 -0
  938. package/docs/zh-CN/refactor/outbound-session-mirroring.md +92 -0
  939. package/docs/zh-CN/refactor/plugin-sdk.md +221 -0
  940. package/docs/zh-CN/refactor/strict-config.md +100 -0
  941. package/docs/zh-CN/reference/AGENTS.default.md +131 -0
  942. package/docs/zh-CN/reference/RELEASING.md +123 -0
  943. package/docs/zh-CN/reference/api-usage-costs.md +136 -0
  944. package/docs/zh-CN/reference/credits.md +34 -0
  945. package/docs/zh-CN/reference/device-models.md +54 -0
  946. package/docs/zh-CN/reference/rpc.md +48 -0
  947. package/docs/zh-CN/reference/session-management-compaction.md +287 -0
  948. package/docs/zh-CN/reference/templates/AGENTS.dev.md +89 -0
  949. package/docs/zh-CN/reference/templates/AGENTS.md +225 -0
  950. package/docs/zh-CN/reference/templates/BOOT.md +17 -0
  951. package/docs/zh-CN/reference/templates/BOOTSTRAP.md +68 -0
  952. package/docs/zh-CN/reference/templates/HEARTBEAT.md +18 -0
  953. package/docs/zh-CN/reference/templates/IDENTITY.dev.md +54 -0
  954. package/docs/zh-CN/reference/templates/IDENTITY.md +35 -0
  955. package/docs/zh-CN/reference/templates/SOUL.dev.md +83 -0
  956. package/docs/zh-CN/reference/templates/SOUL.md +49 -0
  957. package/docs/zh-CN/reference/templates/TOOLS.dev.md +31 -0
  958. package/docs/zh-CN/reference/templates/TOOLS.md +53 -0
  959. package/docs/zh-CN/reference/templates/USER.dev.md +25 -0
  960. package/docs/zh-CN/reference/templates/USER.md +30 -0
  961. package/docs/zh-CN/reference/test.md +57 -0
  962. package/docs/zh-CN/reference/transcript-hygiene.md +109 -0
  963. package/docs/zh-CN/scripts.md +35 -0
  964. package/docs/zh-CN/security/formal-verification.md +171 -0
  965. package/docs/zh-CN/start/docs-directory.md +70 -0
  966. package/docs/zh-CN/start/getting-started.md +206 -0
  967. package/docs/zh-CN/start/hubs.md +200 -0
  968. package/docs/zh-CN/start/lore.md +226 -0
  969. package/docs/zh-CN/start/onboarding.md +105 -0
  970. package/docs/zh-CN/start/openclaw.md +248 -0
  971. package/docs/zh-CN/start/pairing.md +89 -0
  972. package/docs/zh-CN/start/quickstart.md +88 -0
  973. package/docs/zh-CN/start/setup.md +153 -0
  974. package/docs/zh-CN/start/showcase.md +423 -0
  975. package/docs/zh-CN/start/wizard.md +331 -0
  976. package/docs/zh-CN/testing.md +375 -0
  977. package/docs/zh-CN/token-use.md +119 -0
  978. package/docs/zh-CN/tools/agent-send.md +59 -0
  979. package/docs/zh-CN/tools/apply-patch.md +57 -0
  980. package/docs/zh-CN/tools/browser-linux-troubleshooting.md +144 -0
  981. package/docs/zh-CN/tools/browser-login.md +75 -0
  982. package/docs/zh-CN/tools/browser.md +553 -0
  983. package/docs/zh-CN/tools/chrome-extension.md +183 -0
  984. package/docs/zh-CN/tools/clawhub.md +209 -0
  985. package/docs/zh-CN/tools/creating-skills.md +61 -0
  986. package/docs/zh-CN/tools/elevated.md +64 -0
  987. package/docs/zh-CN/tools/exec-approvals.md +234 -0
  988. package/docs/zh-CN/tools/exec.md +169 -0
  989. package/docs/zh-CN/tools/firecrawl.md +68 -0
  990. package/docs/zh-CN/tools/index.md +515 -0
  991. package/docs/zh-CN/tools/llm-task.md +117 -0
  992. package/docs/zh-CN/tools/lobster.md +349 -0
  993. package/docs/zh-CN/tools/reactions.md +29 -0
  994. package/docs/zh-CN/tools/skills-config.md +78 -0
  995. package/docs/zh-CN/tools/skills.md +279 -0
  996. package/docs/zh-CN/tools/slash-commands.md +205 -0
  997. package/docs/zh-CN/tools/subagents.md +156 -0
  998. package/docs/zh-CN/tools/thinking.md +80 -0
  999. package/docs/zh-CN/tools/web.md +257 -0
  1000. package/docs/zh-CN/tts.md +375 -0
  1001. package/docs/zh-CN/tui.md +166 -0
  1002. package/docs/zh-CN/vps.md +47 -0
  1003. package/docs/zh-CN/web/control-ui.md +191 -0
  1004. package/docs/zh-CN/web/dashboard.md +53 -0
  1005. package/docs/zh-CN/web/index.md +118 -0
  1006. package/docs/zh-CN/web/webchat.md +56 -0
  1007. package/extensions/blockchain/cryptoclaw.plugin.json +17 -0
  1008. package/extensions/blockchain/index.ts +284 -0
  1009. package/extensions/blockchain/node_modules/.bin/cryptoclaw +21 -0
  1010. package/extensions/blockchain/node_modules/.bin/tsc +21 -0
  1011. package/extensions/blockchain/node_modules/.bin/tsserver +21 -0
  1012. package/extensions/blockchain/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  1013. package/extensions/blockchain/package.json +16 -0
  1014. package/extensions/blockchain/src/evm/chains.ts +150 -0
  1015. package/extensions/blockchain/src/evm/services/abi/erc1155.ts +128 -0
  1016. package/extensions/blockchain/src/evm/services/abi/erc20.ts +96 -0
  1017. package/extensions/blockchain/src/evm/services/abi/erc721.ts +130 -0
  1018. package/extensions/blockchain/src/evm/services/abi/erc8004-identity.ts +158 -0
  1019. package/extensions/blockchain/src/evm/services/abi/erc8004-reputation.ts +120 -0
  1020. package/extensions/blockchain/src/evm/services/abi/router-v2.ts +115 -0
  1021. package/extensions/blockchain/src/evm/services/abi/router-v3.ts +81 -0
  1022. package/extensions/blockchain/src/evm/services/agent-identity-config.test.ts +117 -0
  1023. package/extensions/blockchain/src/evm/services/agent-identity-config.ts +75 -0
  1024. package/extensions/blockchain/src/evm/services/agent-identity-store.ts +37 -0
  1025. package/extensions/blockchain/src/evm/services/agent-identity.ts +262 -0
  1026. package/extensions/blockchain/src/evm/services/balance.ts +76 -0
  1027. package/extensions/blockchain/src/evm/services/blocks.ts +25 -0
  1028. package/extensions/blockchain/src/evm/services/clients.ts +48 -0
  1029. package/extensions/blockchain/src/evm/services/contracts.ts +52 -0
  1030. package/extensions/blockchain/src/evm/services/dex-config.test.ts +145 -0
  1031. package/extensions/blockchain/src/evm/services/dex-config.ts +164 -0
  1032. package/extensions/blockchain/src/evm/services/ens.ts +27 -0
  1033. package/extensions/blockchain/src/evm/services/security.test.ts +127 -0
  1034. package/extensions/blockchain/src/evm/services/security.ts +110 -0
  1035. package/extensions/blockchain/src/evm/services/swap.test.ts +204 -0
  1036. package/extensions/blockchain/src/evm/services/swap.ts +534 -0
  1037. package/extensions/blockchain/src/evm/services/tokens.ts +118 -0
  1038. package/extensions/blockchain/src/evm/services/transactions.ts +54 -0
  1039. package/extensions/blockchain/src/evm/services/transfer.ts +174 -0
  1040. package/extensions/blockchain/src/evm/services/utils.ts +18 -0
  1041. package/extensions/blockchain/src/evm/tools/block-tools.ts +34 -0
  1042. package/extensions/blockchain/src/evm/tools/contract-tools.ts +138 -0
  1043. package/extensions/blockchain/src/evm/tools/identity-tools.ts +305 -0
  1044. package/extensions/blockchain/src/evm/tools/network-tools.ts +58 -0
  1045. package/extensions/blockchain/src/evm/tools/nft-tools.ts +103 -0
  1046. package/extensions/blockchain/src/evm/tools/security-tools.ts +38 -0
  1047. package/extensions/blockchain/src/evm/tools/swap-tools.ts +314 -0
  1048. package/extensions/blockchain/src/evm/tools/token-tools.ts +167 -0
  1049. package/extensions/blockchain/src/evm/tools/tx-tools.ts +73 -0
  1050. package/extensions/blockchain/src/evm/tools/wallet-tools.ts +196 -0
  1051. package/extensions/blockchain/src/tx-gate/confirmation.ts +55 -0
  1052. package/extensions/blockchain/src/tx-gate/spending-limits.ts +94 -0
  1053. package/extensions/blockchain/src/wallet/active-wallet.ts +27 -0
  1054. package/extensions/blockchain/src/wallet/key-guard.test.ts +156 -0
  1055. package/extensions/blockchain/src/wallet/key-guard.ts +80 -0
  1056. package/extensions/blockchain/src/wallet/keystore.ts +88 -0
  1057. package/extensions/blockchain/src/wallet/wallet-manager.test.ts +215 -0
  1058. package/extensions/blockchain/src/wallet/wallet-manager.ts +212 -0
  1059. package/extensions/copilot-proxy/README.md +24 -0
  1060. package/extensions/copilot-proxy/index.ts +149 -0
  1061. package/extensions/copilot-proxy/node_modules/.bin/cryptoclaw +21 -0
  1062. package/extensions/copilot-proxy/openclaw.plugin.json +9 -0
  1063. package/extensions/copilot-proxy/package.json +14 -0
  1064. package/extensions/diagnostics-otel/index.ts +15 -0
  1065. package/extensions/diagnostics-otel/node_modules/.bin/acorn +21 -0
  1066. package/extensions/diagnostics-otel/node_modules/.bin/cryptoclaw +21 -0
  1067. package/extensions/diagnostics-otel/openclaw.plugin.json +8 -0
  1068. package/extensions/diagnostics-otel/package.json +27 -0
  1069. package/extensions/diagnostics-otel/src/service.test.ts +227 -0
  1070. package/extensions/diagnostics-otel/src/service.ts +635 -0
  1071. package/extensions/discord/index.ts +17 -0
  1072. package/extensions/discord/node_modules/.bin/cryptoclaw +21 -0
  1073. package/extensions/discord/openclaw.plugin.json +9 -0
  1074. package/extensions/discord/package.json +14 -0
  1075. package/extensions/discord/src/channel.ts +422 -0
  1076. package/extensions/discord/src/runtime.ts +14 -0
  1077. package/extensions/imessage/index.ts +17 -0
  1078. package/extensions/imessage/node_modules/.bin/cryptoclaw +21 -0
  1079. package/extensions/imessage/openclaw.plugin.json +9 -0
  1080. package/extensions/imessage/package.json +14 -0
  1081. package/extensions/imessage/src/channel.ts +294 -0
  1082. package/extensions/imessage/src/runtime.ts +14 -0
  1083. package/extensions/memory-core/index.ts +38 -0
  1084. package/extensions/memory-core/node_modules/.bin/cryptoclaw +21 -0
  1085. package/extensions/memory-core/openclaw.plugin.json +9 -0
  1086. package/extensions/memory-core/package.json +17 -0
  1087. package/extensions/memory-lancedb/config.ts +139 -0
  1088. package/extensions/memory-lancedb/index.test.ts +295 -0
  1089. package/extensions/memory-lancedb/index.ts +608 -0
  1090. package/extensions/memory-lancedb/node_modules/.bin/arrow2csv +21 -0
  1091. package/extensions/memory-lancedb/node_modules/.bin/cryptoclaw +21 -0
  1092. package/extensions/memory-lancedb/node_modules/.bin/openai +21 -0
  1093. package/extensions/memory-lancedb/openclaw.plugin.json +60 -0
  1094. package/extensions/memory-lancedb/package.json +19 -0
  1095. package/extensions/nostr/CHANGELOG.md +80 -0
  1096. package/extensions/nostr/README.md +136 -0
  1097. package/extensions/nostr/index.ts +68 -0
  1098. package/extensions/nostr/node_modules/.bin/cryptoclaw +21 -0
  1099. package/extensions/nostr/node_modules/.bin/tsc +21 -0
  1100. package/extensions/nostr/node_modules/.bin/tsserver +21 -0
  1101. package/extensions/nostr/openclaw.plugin.json +9 -0
  1102. package/extensions/nostr/package.json +34 -0
  1103. package/extensions/nostr/src/channel.test.ts +151 -0
  1104. package/extensions/nostr/src/channel.ts +353 -0
  1105. package/extensions/nostr/src/config-schema.ts +90 -0
  1106. package/extensions/nostr/src/metrics.ts +478 -0
  1107. package/extensions/nostr/src/nostr-bus.fuzz.test.ts +533 -0
  1108. package/extensions/nostr/src/nostr-bus.integration.test.ts +448 -0
  1109. package/extensions/nostr/src/nostr-bus.test.ts +199 -0
  1110. package/extensions/nostr/src/nostr-bus.ts +715 -0
  1111. package/extensions/nostr/src/nostr-profile-http.test.ts +378 -0
  1112. package/extensions/nostr/src/nostr-profile-http.ts +519 -0
  1113. package/extensions/nostr/src/nostr-profile-import.test.ts +119 -0
  1114. package/extensions/nostr/src/nostr-profile-import.ts +262 -0
  1115. package/extensions/nostr/src/nostr-profile.fuzz.test.ts +477 -0
  1116. package/extensions/nostr/src/nostr-profile.test.ts +410 -0
  1117. package/extensions/nostr/src/nostr-profile.ts +277 -0
  1118. package/extensions/nostr/src/nostr-state-store.test.ts +131 -0
  1119. package/extensions/nostr/src/nostr-state-store.ts +226 -0
  1120. package/extensions/nostr/src/runtime.ts +14 -0
  1121. package/extensions/nostr/src/seen-tracker.ts +303 -0
  1122. package/extensions/nostr/src/types.test.ts +157 -0
  1123. package/extensions/nostr/src/types.ts +101 -0
  1124. package/extensions/nostr/test/setup.ts +5 -0
  1125. package/extensions/signal/index.ts +17 -0
  1126. package/extensions/signal/node_modules/.bin/cryptoclaw +21 -0
  1127. package/extensions/signal/openclaw.plugin.json +9 -0
  1128. package/extensions/signal/package.json +14 -0
  1129. package/extensions/signal/src/channel.ts +315 -0
  1130. package/extensions/signal/src/runtime.ts +14 -0
  1131. package/extensions/slack/index.ts +17 -0
  1132. package/extensions/slack/node_modules/.bin/cryptoclaw +21 -0
  1133. package/extensions/slack/openclaw.plugin.json +9 -0
  1134. package/extensions/slack/package.json +14 -0
  1135. package/extensions/slack/src/channel.ts +604 -0
  1136. package/extensions/slack/src/runtime.ts +14 -0
  1137. package/extensions/telegram/index.ts +17 -0
  1138. package/extensions/telegram/node_modules/.bin/cryptoclaw +21 -0
  1139. package/extensions/telegram/openclaw.plugin.json +9 -0
  1140. package/extensions/telegram/package.json +14 -0
  1141. package/extensions/telegram/src/channel.ts +482 -0
  1142. package/extensions/telegram/src/runtime.ts +14 -0
  1143. package/extensions/voice-call/CHANGELOG.md +115 -0
  1144. package/extensions/voice-call/README.md +139 -0
  1145. package/extensions/voice-call/index.ts +493 -0
  1146. package/extensions/voice-call/node_modules/.bin/cryptoclaw +21 -0
  1147. package/extensions/voice-call/openclaw.plugin.json +559 -0
  1148. package/extensions/voice-call/package.json +19 -0
  1149. package/extensions/voice-call/src/allowlist.ts +19 -0
  1150. package/extensions/voice-call/src/cli.ts +279 -0
  1151. package/extensions/voice-call/src/config.test.ts +234 -0
  1152. package/extensions/voice-call/src/config.ts +523 -0
  1153. package/extensions/voice-call/src/core-bridge.ts +159 -0
  1154. package/extensions/voice-call/src/manager/context.ts +21 -0
  1155. package/extensions/voice-call/src/manager/events.ts +188 -0
  1156. package/extensions/voice-call/src/manager/lookup.ts +35 -0
  1157. package/extensions/voice-call/src/manager/outbound.ts +275 -0
  1158. package/extensions/voice-call/src/manager/state.ts +48 -0
  1159. package/extensions/voice-call/src/manager/store.ts +91 -0
  1160. package/extensions/voice-call/src/manager/timers.ts +89 -0
  1161. package/extensions/voice-call/src/manager/twiml.ts +9 -0
  1162. package/extensions/voice-call/src/manager.test.ts +224 -0
  1163. package/extensions/voice-call/src/manager.ts +887 -0
  1164. package/extensions/voice-call/src/media-stream.test.ts +96 -0
  1165. package/extensions/voice-call/src/media-stream.ts +411 -0
  1166. package/extensions/voice-call/src/providers/base.ts +67 -0
  1167. package/extensions/voice-call/src/providers/index.ts +10 -0
  1168. package/extensions/voice-call/src/providers/mock.ts +165 -0
  1169. package/extensions/voice-call/src/providers/plivo.test.ts +27 -0
  1170. package/extensions/voice-call/src/providers/plivo.ts +515 -0
  1171. package/extensions/voice-call/src/providers/stt-openai-realtime.ts +311 -0
  1172. package/extensions/voice-call/src/providers/telnyx.ts +371 -0
  1173. package/extensions/voice-call/src/providers/tts-openai.ts +259 -0
  1174. package/extensions/voice-call/src/providers/twilio/api.ts +42 -0
  1175. package/extensions/voice-call/src/providers/twilio/webhook.ts +32 -0
  1176. package/extensions/voice-call/src/providers/twilio.test.ts +60 -0
  1177. package/extensions/voice-call/src/providers/twilio.ts +626 -0
  1178. package/extensions/voice-call/src/response-generator.ts +158 -0
  1179. package/extensions/voice-call/src/runtime.ts +212 -0
  1180. package/extensions/voice-call/src/telephony-audio.ts +90 -0
  1181. package/extensions/voice-call/src/telephony-tts.ts +104 -0
  1182. package/extensions/voice-call/src/tunnel.ts +314 -0
  1183. package/extensions/voice-call/src/types.ts +272 -0
  1184. package/extensions/voice-call/src/utils.ts +14 -0
  1185. package/extensions/voice-call/src/voice-mapping.ts +67 -0
  1186. package/extensions/voice-call/src/webhook-security.test.ts +377 -0
  1187. package/extensions/voice-call/src/webhook-security.ts +689 -0
  1188. package/extensions/voice-call/src/webhook.ts +491 -0
  1189. package/extensions/whatsapp/index.ts +17 -0
  1190. package/extensions/whatsapp/node_modules/.bin/cryptoclaw +21 -0
  1191. package/extensions/whatsapp/openclaw.plugin.json +9 -0
  1192. package/extensions/whatsapp/package.json +14 -0
  1193. package/extensions/whatsapp/src/channel.ts +508 -0
  1194. package/extensions/whatsapp/src/runtime.ts +14 -0
  1195. package/package.json +242 -0
  1196. package/skills/aave-bsc/SKILL.md +55 -0
  1197. package/skills/agent-identity/SKILL.md +48 -0
  1198. package/skills/bird/SKILL.md +224 -0
  1199. package/skills/canvas/SKILL.md +204 -0
  1200. package/skills/coding-agent/SKILL.md +285 -0
  1201. package/skills/coingecko/SKILL.md +114 -0
  1202. package/skills/contract-deployer/SKILL.md +42 -0
  1203. package/skills/debank/SKILL.md +143 -0
  1204. package/skills/defi-dashboard/SKILL.md +49 -0
  1205. package/skills/defillama/SKILL.md +117 -0
  1206. package/skills/discord/SKILL.md +578 -0
  1207. package/skills/dune/SKILL.md +178 -0
  1208. package/skills/etherscan/SKILL.md +117 -0
  1209. package/skills/four-meme/SKILL.md +80 -0
  1210. package/skills/gas-tracker/SKILL.md +43 -0
  1211. package/skills/github/SKILL.md +77 -0
  1212. package/skills/macro-calendar/SKILL.md +132 -0
  1213. package/skills/market-data/SKILL.md +44 -0
  1214. package/skills/nft-manager/SKILL.md +46 -0
  1215. package/skills/portfolio-tracker/SKILL.md +55 -0
  1216. package/skills/security-check/SKILL.md +153 -0
  1217. package/skills/tmux/SKILL.md +135 -0
  1218. package/skills/tmux/scripts/find-sessions.sh +112 -0
  1219. package/skills/tmux/scripts/wait-for-text.sh +83 -0
  1220. package/skills/token-swap/SKILL.md +71 -0
  1221. package/skills/wallet-manager/SKILL.md +65 -0
  1222. package/skills/whale-watcher/SKILL.md +43 -0
@@ -0,0 +1,1953 @@
1
+ import { C as CONFIG_DIR, l as createSubsystemLogger, t as runCommandWithTimeout } from "./exec-D7I5LU33.js";
2
+ import { t as formatCliCommand } from "./command-format-n_udBm8l.js";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ import fs from "node:fs";
6
+ import fs$1 from "node:fs/promises";
7
+ import { execFileSync, spawn } from "node:child_process";
8
+ import { randomBytes } from "node:crypto";
9
+ import { createServer } from "node:http";
10
+ import WebSocket$1, { WebSocketServer } from "ws";
11
+ import { Buffer as Buffer$1 } from "node:buffer";
12
+ import net from "node:net";
13
+
14
+ //#region src/browser/constants.ts
15
+ const DEFAULT_CRYPTOCLAW_BROWSER_ENABLED = true;
16
+ const DEFAULT_BROWSER_EVALUATE_ENABLED = true;
17
+ const DEFAULT_CRYPTOCLAW_BROWSER_COLOR = "#FF4500";
18
+ const DEFAULT_CRYPTOCLAW_BROWSER_PROFILE_NAME = "openclaw";
19
+ const DEFAULT_BROWSER_DEFAULT_PROFILE_NAME = "chrome";
20
+ const DEFAULT_AI_SNAPSHOT_MAX_CHARS = 8e4;
21
+ const DEFAULT_AI_SNAPSHOT_EFFICIENT_MAX_CHARS = 1e4;
22
+ const DEFAULT_AI_SNAPSHOT_EFFICIENT_DEPTH = 6;
23
+
24
+ //#endregion
25
+ //#region src/infra/errors.ts
26
+ function extractErrorCode(err) {
27
+ if (!err || typeof err !== "object") return;
28
+ const code = err.code;
29
+ if (typeof code === "string") return code;
30
+ if (typeof code === "number") return String(code);
31
+ }
32
+ function formatErrorMessage(err) {
33
+ if (err instanceof Error) return err.message || err.name || "Error";
34
+ if (typeof err === "string") return err;
35
+ if (typeof err === "number" || typeof err === "boolean" || typeof err === "bigint") return String(err);
36
+ try {
37
+ return JSON.stringify(err);
38
+ } catch {
39
+ return Object.prototype.toString.call(err);
40
+ }
41
+ }
42
+ function formatUncaughtError(err) {
43
+ if (extractErrorCode(err) === "INVALID_CONFIG") return formatErrorMessage(err);
44
+ if (err instanceof Error) return err.stack ?? err.message ?? err.name;
45
+ return formatErrorMessage(err);
46
+ }
47
+
48
+ //#endregion
49
+ //#region src/infra/ws.ts
50
+ function rawDataToString(data, encoding = "utf8") {
51
+ if (typeof data === "string") return data;
52
+ if (Buffer$1.isBuffer(data)) return data.toString(encoding);
53
+ if (Array.isArray(data)) return Buffer$1.concat(data).toString(encoding);
54
+ if (data instanceof ArrayBuffer) return Buffer$1.from(data).toString(encoding);
55
+ return Buffer$1.from(String(data)).toString(encoding);
56
+ }
57
+
58
+ //#endregion
59
+ //#region src/browser/extension-relay.ts
60
+ const RELAY_AUTH_HEADER = "x-openclaw-relay-token";
61
+ function headerValue(value) {
62
+ if (!value) return;
63
+ if (Array.isArray(value)) return value[0];
64
+ return value;
65
+ }
66
+ function getHeader(req, name) {
67
+ return headerValue(req.headers[name.toLowerCase()]);
68
+ }
69
+ function isLoopbackHost$1(host) {
70
+ const h = host.trim().toLowerCase();
71
+ return h === "localhost" || h === "127.0.0.1" || h === "0.0.0.0" || h === "[::1]" || h === "::1" || h === "[::]" || h === "::";
72
+ }
73
+ function isLoopbackAddress(ip) {
74
+ if (!ip) return false;
75
+ if (ip === "127.0.0.1") return true;
76
+ if (ip.startsWith("127.")) return true;
77
+ if (ip === "::1") return true;
78
+ if (ip.startsWith("::ffff:127.")) return true;
79
+ return false;
80
+ }
81
+ function parseBaseUrl(raw) {
82
+ const parsed = new URL(raw.trim().replace(/\/$/, ""));
83
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") throw new Error(`extension relay cdpUrl must be http(s), got ${parsed.protocol}`);
84
+ const host = parsed.hostname;
85
+ const port = parsed.port?.trim() !== "" ? Number(parsed.port) : parsed.protocol === "https:" ? 443 : 80;
86
+ if (!Number.isFinite(port) || port <= 0 || port > 65535) throw new Error(`extension relay cdpUrl has invalid port: ${parsed.port || "(empty)"}`);
87
+ return {
88
+ host,
89
+ port,
90
+ baseUrl: parsed.toString().replace(/\/$/, "")
91
+ };
92
+ }
93
+ function text(res, status, bodyText) {
94
+ const body = Buffer.from(bodyText);
95
+ res.write(`HTTP/1.1 ${status} ${status === 200 ? "OK" : "ERR"}\r\nContent-Type: text/plain; charset=utf-8\r
96
+ Content-Length: ${body.length}\r\nConnection: close\r
97
+ \r
98
+ `);
99
+ res.write(body);
100
+ res.end();
101
+ }
102
+ function rejectUpgrade(socket, status, bodyText) {
103
+ text(socket, status, bodyText);
104
+ try {
105
+ socket.destroy();
106
+ } catch {}
107
+ }
108
+ const serversByPort = /* @__PURE__ */ new Map();
109
+ const relayAuthByPort = /* @__PURE__ */ new Map();
110
+ function relayAuthTokenForUrl(url) {
111
+ try {
112
+ const parsed = new URL(url);
113
+ if (!isLoopbackHost$1(parsed.hostname)) return null;
114
+ const port = parsed.port?.trim() !== "" ? Number(parsed.port) : parsed.protocol === "https:" || parsed.protocol === "wss:" ? 443 : 80;
115
+ if (!Number.isFinite(port)) return null;
116
+ return relayAuthByPort.get(port) ?? null;
117
+ } catch {
118
+ return null;
119
+ }
120
+ }
121
+ function getChromeExtensionRelayAuthHeaders(url) {
122
+ const token = relayAuthTokenForUrl(url);
123
+ if (!token) return {};
124
+ return { [RELAY_AUTH_HEADER]: token };
125
+ }
126
+ async function ensureChromeExtensionRelayServer(opts) {
127
+ const info = parseBaseUrl(opts.cdpUrl);
128
+ if (!isLoopbackHost$1(info.host)) throw new Error(`extension relay requires loopback cdpUrl host (got ${info.host})`);
129
+ const existing = serversByPort.get(info.port);
130
+ if (existing) return existing;
131
+ let extensionWs = null;
132
+ const cdpClients = /* @__PURE__ */ new Set();
133
+ const connectedTargets = /* @__PURE__ */ new Map();
134
+ const pendingExtension = /* @__PURE__ */ new Map();
135
+ let nextExtensionId = 1;
136
+ const sendToExtension = async (payload) => {
137
+ const ws = extensionWs;
138
+ if (!ws || ws.readyState !== WebSocket$1.OPEN) throw new Error("Chrome extension not connected");
139
+ ws.send(JSON.stringify(payload));
140
+ return await new Promise((resolve, reject) => {
141
+ const timer = setTimeout(() => {
142
+ pendingExtension.delete(payload.id);
143
+ reject(/* @__PURE__ */ new Error(`extension request timeout: ${payload.params.method}`));
144
+ }, 3e4);
145
+ pendingExtension.set(payload.id, {
146
+ resolve,
147
+ reject,
148
+ timer
149
+ });
150
+ });
151
+ };
152
+ const broadcastToCdpClients = (evt) => {
153
+ const msg = JSON.stringify(evt);
154
+ for (const ws of cdpClients) {
155
+ if (ws.readyState !== WebSocket$1.OPEN) continue;
156
+ ws.send(msg);
157
+ }
158
+ };
159
+ const sendResponseToCdp = (ws, res) => {
160
+ if (ws.readyState !== WebSocket$1.OPEN) return;
161
+ ws.send(JSON.stringify(res));
162
+ };
163
+ const ensureTargetEventsForClient = (ws, mode) => {
164
+ for (const target of connectedTargets.values()) if (mode === "autoAttach") ws.send(JSON.stringify({
165
+ method: "Target.attachedToTarget",
166
+ params: {
167
+ sessionId: target.sessionId,
168
+ targetInfo: {
169
+ ...target.targetInfo,
170
+ attached: true
171
+ },
172
+ waitingForDebugger: false
173
+ }
174
+ }));
175
+ else ws.send(JSON.stringify({
176
+ method: "Target.targetCreated",
177
+ params: { targetInfo: {
178
+ ...target.targetInfo,
179
+ attached: true
180
+ } }
181
+ }));
182
+ };
183
+ const routeCdpCommand = async (cmd) => {
184
+ switch (cmd.method) {
185
+ case "Browser.getVersion": return {
186
+ protocolVersion: "1.3",
187
+ product: "Chrome/CryptoClaw-Extension-Relay",
188
+ revision: "0",
189
+ userAgent: "CryptoClaw-Extension-Relay",
190
+ jsVersion: "V8"
191
+ };
192
+ case "Browser.setDownloadBehavior": return {};
193
+ case "Target.setAutoAttach":
194
+ case "Target.setDiscoverTargets": return {};
195
+ case "Target.getTargets": return { targetInfos: Array.from(connectedTargets.values()).map((t) => ({
196
+ ...t.targetInfo,
197
+ attached: true
198
+ })) };
199
+ case "Target.getTargetInfo": {
200
+ const params = cmd.params ?? {};
201
+ const targetId = typeof params.targetId === "string" ? params.targetId : void 0;
202
+ if (targetId) {
203
+ for (const t of connectedTargets.values()) if (t.targetId === targetId) return { targetInfo: t.targetInfo };
204
+ }
205
+ if (cmd.sessionId && connectedTargets.has(cmd.sessionId)) {
206
+ const t = connectedTargets.get(cmd.sessionId);
207
+ if (t) return { targetInfo: t.targetInfo };
208
+ }
209
+ return { targetInfo: Array.from(connectedTargets.values())[0]?.targetInfo };
210
+ }
211
+ case "Target.attachToTarget": {
212
+ const params = cmd.params ?? {};
213
+ const targetId = typeof params.targetId === "string" ? params.targetId : void 0;
214
+ if (!targetId) throw new Error("targetId required");
215
+ for (const t of connectedTargets.values()) if (t.targetId === targetId) return { sessionId: t.sessionId };
216
+ throw new Error("target not found");
217
+ }
218
+ default: return await sendToExtension({
219
+ id: nextExtensionId++,
220
+ method: "forwardCDPCommand",
221
+ params: {
222
+ method: cmd.method,
223
+ sessionId: cmd.sessionId,
224
+ params: cmd.params
225
+ }
226
+ });
227
+ }
228
+ };
229
+ const relayAuthToken = randomBytes(32).toString("base64url");
230
+ const server = createServer((req, res) => {
231
+ const path = new URL(req.url ?? "/", info.baseUrl).pathname;
232
+ if (path.startsWith("/json")) {
233
+ const token = getHeader(req, RELAY_AUTH_HEADER);
234
+ if (!token || token !== relayAuthToken) {
235
+ res.writeHead(401);
236
+ res.end("Unauthorized");
237
+ return;
238
+ }
239
+ }
240
+ if (req.method === "HEAD" && path === "/") {
241
+ res.writeHead(200);
242
+ res.end();
243
+ return;
244
+ }
245
+ if (path === "/") {
246
+ res.writeHead(200, { "Content-Type": "text/plain; charset=utf-8" });
247
+ res.end("OK");
248
+ return;
249
+ }
250
+ if (path === "/extension/status") {
251
+ res.writeHead(200, { "Content-Type": "application/json" });
252
+ res.end(JSON.stringify({ connected: Boolean(extensionWs) }));
253
+ return;
254
+ }
255
+ const cdpWsUrl = `${`ws://${req.headers.host?.trim() || `${info.host}:${info.port}`}`}/cdp`;
256
+ if ((path === "/json/version" || path === "/json/version/") && (req.method === "GET" || req.method === "PUT")) {
257
+ const payload = {
258
+ Browser: "CryptoClaw/extension-relay",
259
+ "Protocol-Version": "1.3"
260
+ };
261
+ if (extensionWs) payload.webSocketDebuggerUrl = cdpWsUrl;
262
+ res.writeHead(200, { "Content-Type": "application/json" });
263
+ res.end(JSON.stringify(payload));
264
+ return;
265
+ }
266
+ if (new Set([
267
+ "/json",
268
+ "/json/",
269
+ "/json/list",
270
+ "/json/list/"
271
+ ]).has(path) && (req.method === "GET" || req.method === "PUT")) {
272
+ const list = Array.from(connectedTargets.values()).map((t) => ({
273
+ id: t.targetId,
274
+ type: t.targetInfo.type ?? "page",
275
+ title: t.targetInfo.title ?? "",
276
+ description: t.targetInfo.title ?? "",
277
+ url: t.targetInfo.url ?? "",
278
+ webSocketDebuggerUrl: cdpWsUrl,
279
+ devtoolsFrontendUrl: `/devtools/inspector.html?ws=${cdpWsUrl.replace("ws://", "")}`
280
+ }));
281
+ res.writeHead(200, { "Content-Type": "application/json" });
282
+ res.end(JSON.stringify(list));
283
+ return;
284
+ }
285
+ const activateMatch = path.match(/^\/json\/activate\/(.+)$/);
286
+ if (activateMatch && (req.method === "GET" || req.method === "PUT")) {
287
+ const targetId = decodeURIComponent(activateMatch[1] ?? "").trim();
288
+ if (!targetId) {
289
+ res.writeHead(400);
290
+ res.end("targetId required");
291
+ return;
292
+ }
293
+ (async () => {
294
+ try {
295
+ await sendToExtension({
296
+ id: nextExtensionId++,
297
+ method: "forwardCDPCommand",
298
+ params: {
299
+ method: "Target.activateTarget",
300
+ params: { targetId }
301
+ }
302
+ });
303
+ } catch {}
304
+ })();
305
+ res.writeHead(200);
306
+ res.end("OK");
307
+ return;
308
+ }
309
+ const closeMatch = path.match(/^\/json\/close\/(.+)$/);
310
+ if (closeMatch && (req.method === "GET" || req.method === "PUT")) {
311
+ const targetId = decodeURIComponent(closeMatch[1] ?? "").trim();
312
+ if (!targetId) {
313
+ res.writeHead(400);
314
+ res.end("targetId required");
315
+ return;
316
+ }
317
+ (async () => {
318
+ try {
319
+ await sendToExtension({
320
+ id: nextExtensionId++,
321
+ method: "forwardCDPCommand",
322
+ params: {
323
+ method: "Target.closeTarget",
324
+ params: { targetId }
325
+ }
326
+ });
327
+ } catch {}
328
+ })();
329
+ res.writeHead(200);
330
+ res.end("OK");
331
+ return;
332
+ }
333
+ res.writeHead(404);
334
+ res.end("not found");
335
+ });
336
+ const wssExtension = new WebSocketServer({ noServer: true });
337
+ const wssCdp = new WebSocketServer({ noServer: true });
338
+ server.on("upgrade", (req, socket, head) => {
339
+ const pathname = new URL(req.url ?? "/", info.baseUrl).pathname;
340
+ const remote = req.socket.remoteAddress;
341
+ if (!isLoopbackAddress(remote)) {
342
+ rejectUpgrade(socket, 403, "Forbidden");
343
+ return;
344
+ }
345
+ const origin = headerValue(req.headers.origin);
346
+ if (origin && !origin.startsWith("chrome-extension://")) {
347
+ rejectUpgrade(socket, 403, "Forbidden: invalid origin");
348
+ return;
349
+ }
350
+ if (pathname === "/extension") {
351
+ if (extensionWs) {
352
+ rejectUpgrade(socket, 409, "Extension already connected");
353
+ return;
354
+ }
355
+ wssExtension.handleUpgrade(req, socket, head, (ws) => {
356
+ wssExtension.emit("connection", ws, req);
357
+ });
358
+ return;
359
+ }
360
+ if (pathname === "/cdp") {
361
+ const token = getHeader(req, RELAY_AUTH_HEADER);
362
+ if (!token || token !== relayAuthToken) {
363
+ rejectUpgrade(socket, 401, "Unauthorized");
364
+ return;
365
+ }
366
+ if (!extensionWs) {
367
+ rejectUpgrade(socket, 503, "Extension not connected");
368
+ return;
369
+ }
370
+ wssCdp.handleUpgrade(req, socket, head, (ws) => {
371
+ wssCdp.emit("connection", ws, req);
372
+ });
373
+ return;
374
+ }
375
+ rejectUpgrade(socket, 404, "Not Found");
376
+ });
377
+ wssExtension.on("connection", (ws) => {
378
+ extensionWs = ws;
379
+ const ping = setInterval(() => {
380
+ if (ws.readyState !== WebSocket$1.OPEN) return;
381
+ ws.send(JSON.stringify({ method: "ping" }));
382
+ }, 5e3);
383
+ ws.on("message", (data) => {
384
+ let parsed = null;
385
+ try {
386
+ parsed = JSON.parse(rawDataToString(data));
387
+ } catch {
388
+ return;
389
+ }
390
+ if (parsed && typeof parsed === "object" && "id" in parsed && typeof parsed.id === "number") {
391
+ const pending = pendingExtension.get(parsed.id);
392
+ if (!pending) return;
393
+ pendingExtension.delete(parsed.id);
394
+ clearTimeout(pending.timer);
395
+ if ("error" in parsed && typeof parsed.error === "string" && parsed.error.trim()) pending.reject(new Error(parsed.error));
396
+ else pending.resolve(parsed.result);
397
+ return;
398
+ }
399
+ if (parsed && typeof parsed === "object" && "method" in parsed) {
400
+ if (parsed.method === "pong") return;
401
+ if (parsed.method !== "forwardCDPEvent") return;
402
+ const evt = parsed;
403
+ const method = evt.params?.method;
404
+ const params = evt.params?.params;
405
+ const sessionId = evt.params?.sessionId;
406
+ if (!method || typeof method !== "string") return;
407
+ if (method === "Target.attachedToTarget") {
408
+ const attached = params ?? {};
409
+ if ((attached?.targetInfo?.type ?? "page") !== "page") return;
410
+ if (attached?.sessionId && attached?.targetInfo?.targetId) {
411
+ const prev = connectedTargets.get(attached.sessionId);
412
+ const nextTargetId = attached.targetInfo.targetId;
413
+ const prevTargetId = prev?.targetId;
414
+ const changedTarget = Boolean(prev && prevTargetId && prevTargetId !== nextTargetId);
415
+ connectedTargets.set(attached.sessionId, {
416
+ sessionId: attached.sessionId,
417
+ targetId: nextTargetId,
418
+ targetInfo: attached.targetInfo
419
+ });
420
+ if (changedTarget && prevTargetId) broadcastToCdpClients({
421
+ method: "Target.detachedFromTarget",
422
+ params: {
423
+ sessionId: attached.sessionId,
424
+ targetId: prevTargetId
425
+ },
426
+ sessionId: attached.sessionId
427
+ });
428
+ if (!prev || changedTarget) broadcastToCdpClients({
429
+ method,
430
+ params,
431
+ sessionId
432
+ });
433
+ return;
434
+ }
435
+ }
436
+ if (method === "Target.detachedFromTarget") {
437
+ const detached = params ?? {};
438
+ if (detached?.sessionId) connectedTargets.delete(detached.sessionId);
439
+ broadcastToCdpClients({
440
+ method,
441
+ params,
442
+ sessionId
443
+ });
444
+ return;
445
+ }
446
+ if (method === "Target.targetInfoChanged") {
447
+ const targetInfo = (params ?? {})?.targetInfo;
448
+ const targetId = targetInfo?.targetId;
449
+ if (targetId && (targetInfo?.type ?? "page") === "page") for (const [sid, target] of connectedTargets) {
450
+ if (target.targetId !== targetId) continue;
451
+ connectedTargets.set(sid, {
452
+ ...target,
453
+ targetInfo: {
454
+ ...target.targetInfo,
455
+ ...targetInfo
456
+ }
457
+ });
458
+ }
459
+ }
460
+ broadcastToCdpClients({
461
+ method,
462
+ params,
463
+ sessionId
464
+ });
465
+ }
466
+ });
467
+ ws.on("close", () => {
468
+ clearInterval(ping);
469
+ extensionWs = null;
470
+ for (const [, pending] of pendingExtension) {
471
+ clearTimeout(pending.timer);
472
+ pending.reject(/* @__PURE__ */ new Error("extension disconnected"));
473
+ }
474
+ pendingExtension.clear();
475
+ connectedTargets.clear();
476
+ for (const client of cdpClients) try {
477
+ client.close(1011, "extension disconnected");
478
+ } catch {}
479
+ cdpClients.clear();
480
+ });
481
+ });
482
+ wssCdp.on("connection", (ws) => {
483
+ cdpClients.add(ws);
484
+ ws.on("message", async (data) => {
485
+ let cmd = null;
486
+ try {
487
+ cmd = JSON.parse(rawDataToString(data));
488
+ } catch {
489
+ return;
490
+ }
491
+ if (!cmd || typeof cmd !== "object") return;
492
+ if (typeof cmd.id !== "number" || typeof cmd.method !== "string") return;
493
+ if (!extensionWs) {
494
+ sendResponseToCdp(ws, {
495
+ id: cmd.id,
496
+ sessionId: cmd.sessionId,
497
+ error: { message: "Extension not connected" }
498
+ });
499
+ return;
500
+ }
501
+ try {
502
+ const result = await routeCdpCommand(cmd);
503
+ if (cmd.method === "Target.setAutoAttach" && !cmd.sessionId) ensureTargetEventsForClient(ws, "autoAttach");
504
+ if (cmd.method === "Target.setDiscoverTargets") {
505
+ if ((cmd.params ?? {}).discover === true) ensureTargetEventsForClient(ws, "discover");
506
+ }
507
+ if (cmd.method === "Target.attachToTarget") {
508
+ const params = cmd.params ?? {};
509
+ const targetId = typeof params.targetId === "string" ? params.targetId : void 0;
510
+ if (targetId) {
511
+ const target = Array.from(connectedTargets.values()).find((t) => t.targetId === targetId);
512
+ if (target) ws.send(JSON.stringify({
513
+ method: "Target.attachedToTarget",
514
+ params: {
515
+ sessionId: target.sessionId,
516
+ targetInfo: {
517
+ ...target.targetInfo,
518
+ attached: true
519
+ },
520
+ waitingForDebugger: false
521
+ }
522
+ }));
523
+ }
524
+ }
525
+ sendResponseToCdp(ws, {
526
+ id: cmd.id,
527
+ sessionId: cmd.sessionId,
528
+ result
529
+ });
530
+ } catch (err) {
531
+ sendResponseToCdp(ws, {
532
+ id: cmd.id,
533
+ sessionId: cmd.sessionId,
534
+ error: { message: err instanceof Error ? err.message : String(err) }
535
+ });
536
+ }
537
+ });
538
+ ws.on("close", () => {
539
+ cdpClients.delete(ws);
540
+ });
541
+ });
542
+ await new Promise((resolve, reject) => {
543
+ server.listen(info.port, info.host, () => resolve());
544
+ server.once("error", reject);
545
+ });
546
+ const port = server.address()?.port ?? info.port;
547
+ const host = info.host;
548
+ const relay = {
549
+ host,
550
+ port,
551
+ baseUrl: `${new URL(info.baseUrl).protocol}//${host}:${port}`,
552
+ cdpWsUrl: `ws://${host}:${port}/cdp`,
553
+ extensionConnected: () => Boolean(extensionWs),
554
+ stop: async () => {
555
+ serversByPort.delete(port);
556
+ relayAuthByPort.delete(port);
557
+ try {
558
+ extensionWs?.close(1001, "server stopping");
559
+ } catch {}
560
+ for (const ws of cdpClients) try {
561
+ ws.close(1001, "server stopping");
562
+ } catch {}
563
+ await new Promise((resolve) => {
564
+ server.close(() => resolve());
565
+ });
566
+ wssExtension.close();
567
+ wssCdp.close();
568
+ }
569
+ };
570
+ relayAuthByPort.set(port, relayAuthToken);
571
+ serversByPort.set(port, relay);
572
+ return relay;
573
+ }
574
+ async function stopChromeExtensionRelayServer(opts) {
575
+ const info = parseBaseUrl(opts.cdpUrl);
576
+ const existing = serversByPort.get(info.port);
577
+ if (!existing) return false;
578
+ await existing.stop();
579
+ relayAuthByPort.delete(info.port);
580
+ return true;
581
+ }
582
+
583
+ //#endregion
584
+ //#region src/browser/cdp.helpers.ts
585
+ function isLoopbackHost(host) {
586
+ const h = host.trim().toLowerCase();
587
+ return h === "localhost" || h === "127.0.0.1" || h === "0.0.0.0" || h === "[::1]" || h === "::1" || h === "[::]" || h === "::";
588
+ }
589
+ function getHeadersWithAuth(url, headers = {}) {
590
+ const mergedHeaders = {
591
+ ...getChromeExtensionRelayAuthHeaders(url),
592
+ ...headers
593
+ };
594
+ try {
595
+ const parsed = new URL(url);
596
+ if (Object.keys(mergedHeaders).some((key) => key.toLowerCase() === "authorization")) return mergedHeaders;
597
+ if (parsed.username || parsed.password) {
598
+ const auth = Buffer.from(`${parsed.username}:${parsed.password}`).toString("base64");
599
+ return {
600
+ ...mergedHeaders,
601
+ Authorization: `Basic ${auth}`
602
+ };
603
+ }
604
+ } catch {}
605
+ return mergedHeaders;
606
+ }
607
+ function appendCdpPath(cdpUrl, path) {
608
+ const url = new URL(cdpUrl);
609
+ url.pathname = `${url.pathname.replace(/\/$/, "")}${path.startsWith("/") ? path : `/${path}`}`;
610
+ return url.toString();
611
+ }
612
+ function createCdpSender(ws) {
613
+ let nextId = 1;
614
+ const pending = /* @__PURE__ */ new Map();
615
+ const send = (method, params) => {
616
+ const id = nextId++;
617
+ const msg = {
618
+ id,
619
+ method,
620
+ params
621
+ };
622
+ ws.send(JSON.stringify(msg));
623
+ return new Promise((resolve, reject) => {
624
+ pending.set(id, {
625
+ resolve,
626
+ reject
627
+ });
628
+ });
629
+ };
630
+ const closeWithError = (err) => {
631
+ for (const [, p] of pending) p.reject(err);
632
+ pending.clear();
633
+ try {
634
+ ws.close();
635
+ } catch {}
636
+ };
637
+ ws.on("message", (data) => {
638
+ try {
639
+ const parsed = JSON.parse(rawDataToString(data));
640
+ if (typeof parsed.id !== "number") return;
641
+ const p = pending.get(parsed.id);
642
+ if (!p) return;
643
+ pending.delete(parsed.id);
644
+ if (parsed.error?.message) {
645
+ p.reject(new Error(parsed.error.message));
646
+ return;
647
+ }
648
+ p.resolve(parsed.result);
649
+ } catch {}
650
+ });
651
+ ws.on("close", () => {
652
+ closeWithError(/* @__PURE__ */ new Error("CDP socket closed"));
653
+ });
654
+ return {
655
+ send,
656
+ closeWithError
657
+ };
658
+ }
659
+ async function fetchJson(url, timeoutMs = 1500, init) {
660
+ const ctrl = new AbortController();
661
+ const t = setTimeout(() => ctrl.abort(), timeoutMs);
662
+ try {
663
+ const headers = getHeadersWithAuth(url, init?.headers || {});
664
+ const res = await fetch(url, {
665
+ ...init,
666
+ headers,
667
+ signal: ctrl.signal
668
+ });
669
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
670
+ return await res.json();
671
+ } finally {
672
+ clearTimeout(t);
673
+ }
674
+ }
675
+ async function withCdpSocket(wsUrl, fn, opts) {
676
+ const headers = getHeadersWithAuth(wsUrl, opts?.headers ?? {});
677
+ const ws = new WebSocket$1(wsUrl, {
678
+ handshakeTimeout: 5e3,
679
+ ...Object.keys(headers).length ? { headers } : {}
680
+ });
681
+ const { send, closeWithError } = createCdpSender(ws);
682
+ await new Promise((resolve, reject) => {
683
+ ws.once("open", () => resolve());
684
+ ws.once("error", (err) => reject(err));
685
+ });
686
+ try {
687
+ return await fn(send);
688
+ } catch (err) {
689
+ closeWithError(err instanceof Error ? err : new Error(String(err)));
690
+ throw err;
691
+ } finally {
692
+ try {
693
+ ws.close();
694
+ } catch {}
695
+ }
696
+ }
697
+
698
+ //#endregion
699
+ //#region src/browser/cdp.ts
700
+ function normalizeCdpWsUrl(wsUrl, cdpUrl) {
701
+ const ws = new URL(wsUrl);
702
+ const cdp = new URL(cdpUrl);
703
+ if (isLoopbackHost(ws.hostname) && !isLoopbackHost(cdp.hostname)) {
704
+ ws.hostname = cdp.hostname;
705
+ const cdpPort = cdp.port || (cdp.protocol === "https:" ? "443" : "80");
706
+ if (cdpPort) ws.port = cdpPort;
707
+ ws.protocol = cdp.protocol === "https:" ? "wss:" : "ws:";
708
+ }
709
+ if (cdp.protocol === "https:" && ws.protocol === "ws:") ws.protocol = "wss:";
710
+ if (!ws.username && !ws.password && (cdp.username || cdp.password)) {
711
+ ws.username = cdp.username;
712
+ ws.password = cdp.password;
713
+ }
714
+ for (const [key, value] of cdp.searchParams.entries()) if (!ws.searchParams.has(key)) ws.searchParams.append(key, value);
715
+ return ws.toString();
716
+ }
717
+ async function captureScreenshot(opts) {
718
+ return await withCdpSocket(opts.wsUrl, async (send) => {
719
+ await send("Page.enable");
720
+ let clip;
721
+ if (opts.fullPage) {
722
+ const metrics = await send("Page.getLayoutMetrics");
723
+ const size = metrics?.cssContentSize ?? metrics?.contentSize;
724
+ const width = Number(size?.width ?? 0);
725
+ const height = Number(size?.height ?? 0);
726
+ if (width > 0 && height > 0) clip = {
727
+ x: 0,
728
+ y: 0,
729
+ width,
730
+ height,
731
+ scale: 1
732
+ };
733
+ }
734
+ const format = opts.format ?? "png";
735
+ const quality = format === "jpeg" ? Math.max(0, Math.min(100, Math.round(opts.quality ?? 85))) : void 0;
736
+ const base64 = (await send("Page.captureScreenshot", {
737
+ format,
738
+ ...quality !== void 0 ? { quality } : {},
739
+ fromSurface: true,
740
+ captureBeyondViewport: true,
741
+ ...clip ? { clip } : {}
742
+ }))?.data;
743
+ if (!base64) throw new Error("Screenshot failed: missing data");
744
+ return Buffer.from(base64, "base64");
745
+ });
746
+ }
747
+ async function createTargetViaCdp(opts) {
748
+ const version = await fetchJson(appendCdpPath(opts.cdpUrl, "/json/version"), 1500);
749
+ const wsUrlRaw = String(version?.webSocketDebuggerUrl ?? "").trim();
750
+ const wsUrl = wsUrlRaw ? normalizeCdpWsUrl(wsUrlRaw, opts.cdpUrl) : "";
751
+ if (!wsUrl) throw new Error("CDP /json/version missing webSocketDebuggerUrl");
752
+ return await withCdpSocket(wsUrl, async (send) => {
753
+ const created = await send("Target.createTarget", { url: opts.url });
754
+ const targetId = String(created?.targetId ?? "").trim();
755
+ if (!targetId) throw new Error("CDP Target.createTarget returned no targetId");
756
+ return { targetId };
757
+ });
758
+ }
759
+ function axValue(v) {
760
+ if (!v || typeof v !== "object") return "";
761
+ const value = v.value;
762
+ if (typeof value === "string") return value;
763
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
764
+ return "";
765
+ }
766
+ function formatAriaSnapshot(nodes, limit) {
767
+ const byId = /* @__PURE__ */ new Map();
768
+ for (const n of nodes) if (n.nodeId) byId.set(n.nodeId, n);
769
+ const referenced = /* @__PURE__ */ new Set();
770
+ for (const n of nodes) for (const c of n.childIds ?? []) referenced.add(c);
771
+ const root = nodes.find((n) => n.nodeId && !referenced.has(n.nodeId)) ?? nodes[0];
772
+ if (!root?.nodeId) return [];
773
+ const out = [];
774
+ const stack = [{
775
+ id: root.nodeId,
776
+ depth: 0
777
+ }];
778
+ while (stack.length && out.length < limit) {
779
+ const popped = stack.pop();
780
+ if (!popped) break;
781
+ const { id, depth } = popped;
782
+ const n = byId.get(id);
783
+ if (!n) continue;
784
+ const role = axValue(n.role);
785
+ const name = axValue(n.name);
786
+ const value = axValue(n.value);
787
+ const description = axValue(n.description);
788
+ const ref = `ax${out.length + 1}`;
789
+ out.push({
790
+ ref,
791
+ role: role || "unknown",
792
+ name: name || "",
793
+ ...value ? { value } : {},
794
+ ...description ? { description } : {},
795
+ ...typeof n.backendDOMNodeId === "number" ? { backendDOMNodeId: n.backendDOMNodeId } : {},
796
+ depth
797
+ });
798
+ const children = (n.childIds ?? []).filter((c) => byId.has(c));
799
+ for (let i = children.length - 1; i >= 0; i--) {
800
+ const child = children[i];
801
+ if (child) stack.push({
802
+ id: child,
803
+ depth: depth + 1
804
+ });
805
+ }
806
+ }
807
+ return out;
808
+ }
809
+ async function snapshotAria(opts) {
810
+ const limit = Math.max(1, Math.min(2e3, Math.floor(opts.limit ?? 500)));
811
+ return await withCdpSocket(opts.wsUrl, async (send) => {
812
+ await send("Accessibility.enable").catch(() => {});
813
+ const res = await send("Accessibility.getFullAXTree");
814
+ return { nodes: formatAriaSnapshot(Array.isArray(res?.nodes) ? res.nodes : [], limit) };
815
+ });
816
+ }
817
+
818
+ //#endregion
819
+ //#region src/browser/chrome.executables.ts
820
+ const CHROMIUM_BUNDLE_IDS = new Set([
821
+ "com.google.Chrome",
822
+ "com.google.Chrome.beta",
823
+ "com.google.Chrome.canary",
824
+ "com.google.Chrome.dev",
825
+ "com.brave.Browser",
826
+ "com.brave.Browser.beta",
827
+ "com.brave.Browser.nightly",
828
+ "com.microsoft.Edge",
829
+ "com.microsoft.EdgeBeta",
830
+ "com.microsoft.EdgeDev",
831
+ "com.microsoft.EdgeCanary",
832
+ "org.chromium.Chromium",
833
+ "com.vivaldi.Vivaldi",
834
+ "com.operasoftware.Opera",
835
+ "com.operasoftware.OperaGX",
836
+ "com.yandex.desktop.yandex-browser",
837
+ "company.thebrowser.Browser"
838
+ ]);
839
+ const CHROMIUM_DESKTOP_IDS = new Set([
840
+ "google-chrome.desktop",
841
+ "google-chrome-beta.desktop",
842
+ "google-chrome-unstable.desktop",
843
+ "brave-browser.desktop",
844
+ "microsoft-edge.desktop",
845
+ "microsoft-edge-beta.desktop",
846
+ "microsoft-edge-dev.desktop",
847
+ "microsoft-edge-canary.desktop",
848
+ "chromium.desktop",
849
+ "chromium-browser.desktop",
850
+ "vivaldi.desktop",
851
+ "vivaldi-stable.desktop",
852
+ "opera.desktop",
853
+ "opera-gx.desktop",
854
+ "yandex-browser.desktop",
855
+ "org.chromium.Chromium.desktop"
856
+ ]);
857
+ const CHROMIUM_EXE_NAMES = new Set([
858
+ "chrome.exe",
859
+ "msedge.exe",
860
+ "brave.exe",
861
+ "brave-browser.exe",
862
+ "chromium.exe",
863
+ "vivaldi.exe",
864
+ "opera.exe",
865
+ "launcher.exe",
866
+ "yandex.exe",
867
+ "yandexbrowser.exe",
868
+ "google chrome",
869
+ "google chrome canary",
870
+ "brave browser",
871
+ "microsoft edge",
872
+ "chromium",
873
+ "chrome",
874
+ "brave",
875
+ "msedge",
876
+ "brave-browser",
877
+ "google-chrome",
878
+ "google-chrome-stable",
879
+ "google-chrome-beta",
880
+ "google-chrome-unstable",
881
+ "microsoft-edge",
882
+ "microsoft-edge-beta",
883
+ "microsoft-edge-dev",
884
+ "microsoft-edge-canary",
885
+ "chromium-browser",
886
+ "vivaldi",
887
+ "vivaldi-stable",
888
+ "opera",
889
+ "opera-stable",
890
+ "opera-gx",
891
+ "yandex-browser"
892
+ ]);
893
+ function exists$1(filePath) {
894
+ try {
895
+ return fs.existsSync(filePath);
896
+ } catch {
897
+ return false;
898
+ }
899
+ }
900
+ function execText(command, args, timeoutMs = 1200, maxBuffer = 1024 * 1024) {
901
+ try {
902
+ const output = execFileSync(command, args, {
903
+ timeout: timeoutMs,
904
+ encoding: "utf8",
905
+ maxBuffer
906
+ });
907
+ return String(output ?? "").trim() || null;
908
+ } catch {
909
+ return null;
910
+ }
911
+ }
912
+ function inferKindFromIdentifier(identifier) {
913
+ const id = identifier.toLowerCase();
914
+ if (id.includes("brave")) return "brave";
915
+ if (id.includes("edge")) return "edge";
916
+ if (id.includes("chromium")) return "chromium";
917
+ if (id.includes("canary")) return "canary";
918
+ if (id.includes("opera") || id.includes("vivaldi") || id.includes("yandex") || id.includes("thebrowser")) return "chromium";
919
+ return "chrome";
920
+ }
921
+ function inferKindFromExecutableName(name) {
922
+ const lower = name.toLowerCase();
923
+ if (lower.includes("brave")) return "brave";
924
+ if (lower.includes("edge") || lower.includes("msedge")) return "edge";
925
+ if (lower.includes("chromium")) return "chromium";
926
+ if (lower.includes("canary") || lower.includes("sxs")) return "canary";
927
+ if (lower.includes("opera") || lower.includes("vivaldi") || lower.includes("yandex")) return "chromium";
928
+ return "chrome";
929
+ }
930
+ function detectDefaultChromiumExecutable(platform) {
931
+ if (platform === "darwin") return detectDefaultChromiumExecutableMac();
932
+ if (platform === "linux") return detectDefaultChromiumExecutableLinux();
933
+ if (platform === "win32") return detectDefaultChromiumExecutableWindows();
934
+ return null;
935
+ }
936
+ function detectDefaultChromiumExecutableMac() {
937
+ const bundleId = detectDefaultBrowserBundleIdMac();
938
+ if (!bundleId || !CHROMIUM_BUNDLE_IDS.has(bundleId)) return null;
939
+ const appPathRaw = execText("/usr/bin/osascript", ["-e", `POSIX path of (path to application id "${bundleId}")`]);
940
+ if (!appPathRaw) return null;
941
+ const appPath = appPathRaw.trim().replace(/\/$/, "");
942
+ const exeName = execText("/usr/bin/defaults", [
943
+ "read",
944
+ path.join(appPath, "Contents", "Info"),
945
+ "CFBundleExecutable"
946
+ ]);
947
+ if (!exeName) return null;
948
+ const exePath = path.join(appPath, "Contents", "MacOS", exeName.trim());
949
+ if (!exists$1(exePath)) return null;
950
+ return {
951
+ kind: inferKindFromIdentifier(bundleId),
952
+ path: exePath
953
+ };
954
+ }
955
+ function detectDefaultBrowserBundleIdMac() {
956
+ const plistPath = path.join(os.homedir(), "Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist");
957
+ if (!exists$1(plistPath)) return null;
958
+ const handlersRaw = execText("/usr/bin/plutil", [
959
+ "-extract",
960
+ "LSHandlers",
961
+ "json",
962
+ "-o",
963
+ "-",
964
+ "--",
965
+ plistPath
966
+ ], 2e3, 5 * 1024 * 1024);
967
+ if (!handlersRaw) return null;
968
+ let handlers;
969
+ try {
970
+ handlers = JSON.parse(handlersRaw);
971
+ } catch {
972
+ return null;
973
+ }
974
+ if (!Array.isArray(handlers)) return null;
975
+ const resolveScheme = (scheme) => {
976
+ let candidate = null;
977
+ for (const entry of handlers) {
978
+ if (!entry || typeof entry !== "object") continue;
979
+ const record = entry;
980
+ if (record.LSHandlerURLScheme !== scheme) continue;
981
+ const role = typeof record.LSHandlerRoleAll === "string" && record.LSHandlerRoleAll || typeof record.LSHandlerRoleViewer === "string" && record.LSHandlerRoleViewer || null;
982
+ if (role) candidate = role;
983
+ }
984
+ return candidate;
985
+ };
986
+ return resolveScheme("http") ?? resolveScheme("https");
987
+ }
988
+ function detectDefaultChromiumExecutableLinux() {
989
+ const desktopId = execText("xdg-settings", ["get", "default-web-browser"]) || execText("xdg-mime", [
990
+ "query",
991
+ "default",
992
+ "x-scheme-handler/http"
993
+ ]);
994
+ if (!desktopId) return null;
995
+ const trimmed = desktopId.trim();
996
+ if (!CHROMIUM_DESKTOP_IDS.has(trimmed)) return null;
997
+ const desktopPath = findDesktopFilePath(trimmed);
998
+ if (!desktopPath) return null;
999
+ const execLine = readDesktopExecLine(desktopPath);
1000
+ if (!execLine) return null;
1001
+ const command = extractExecutableFromExecLine(execLine);
1002
+ if (!command) return null;
1003
+ const resolved = resolveLinuxExecutablePath(command);
1004
+ if (!resolved) return null;
1005
+ const exeName = path.posix.basename(resolved).toLowerCase();
1006
+ if (!CHROMIUM_EXE_NAMES.has(exeName)) return null;
1007
+ return {
1008
+ kind: inferKindFromExecutableName(exeName),
1009
+ path: resolved
1010
+ };
1011
+ }
1012
+ function detectDefaultChromiumExecutableWindows() {
1013
+ const progId = readWindowsProgId();
1014
+ const command = (progId ? readWindowsCommandForProgId(progId) : null) || readWindowsCommandForProgId("http");
1015
+ if (!command) return null;
1016
+ const exePath = extractWindowsExecutablePath(expandWindowsEnvVars(command));
1017
+ if (!exePath) return null;
1018
+ if (!exists$1(exePath)) return null;
1019
+ const exeName = path.win32.basename(exePath).toLowerCase();
1020
+ if (!CHROMIUM_EXE_NAMES.has(exeName)) return null;
1021
+ return {
1022
+ kind: inferKindFromExecutableName(exeName),
1023
+ path: exePath
1024
+ };
1025
+ }
1026
+ function findDesktopFilePath(desktopId) {
1027
+ const candidates = [
1028
+ path.join(os.homedir(), ".local", "share", "applications", desktopId),
1029
+ path.join("/usr/local/share/applications", desktopId),
1030
+ path.join("/usr/share/applications", desktopId),
1031
+ path.join("/var/lib/snapd/desktop/applications", desktopId)
1032
+ ];
1033
+ for (const candidate of candidates) if (exists$1(candidate)) return candidate;
1034
+ return null;
1035
+ }
1036
+ function readDesktopExecLine(desktopPath) {
1037
+ try {
1038
+ const lines = fs.readFileSync(desktopPath, "utf8").split(/\r?\n/);
1039
+ for (const line of lines) if (line.startsWith("Exec=")) return line.slice(5).trim();
1040
+ } catch {}
1041
+ return null;
1042
+ }
1043
+ function extractExecutableFromExecLine(execLine) {
1044
+ const tokens = splitExecLine(execLine);
1045
+ for (const token of tokens) {
1046
+ if (!token) continue;
1047
+ if (token === "env") continue;
1048
+ if (token.includes("=") && !token.startsWith("/") && !token.includes("\\")) continue;
1049
+ return token.replace(/^["']|["']$/g, "");
1050
+ }
1051
+ return null;
1052
+ }
1053
+ function splitExecLine(line) {
1054
+ const tokens = [];
1055
+ let current = "";
1056
+ let inQuotes = false;
1057
+ let quoteChar = "";
1058
+ for (let i = 0; i < line.length; i += 1) {
1059
+ const ch = line[i];
1060
+ if ((ch === "\"" || ch === "'") && (!inQuotes || ch === quoteChar)) {
1061
+ if (inQuotes) {
1062
+ inQuotes = false;
1063
+ quoteChar = "";
1064
+ } else {
1065
+ inQuotes = true;
1066
+ quoteChar = ch;
1067
+ }
1068
+ continue;
1069
+ }
1070
+ if (!inQuotes && /\s/.test(ch)) {
1071
+ if (current) {
1072
+ tokens.push(current);
1073
+ current = "";
1074
+ }
1075
+ continue;
1076
+ }
1077
+ current += ch;
1078
+ }
1079
+ if (current) tokens.push(current);
1080
+ return tokens;
1081
+ }
1082
+ function resolveLinuxExecutablePath(command) {
1083
+ const cleaned = command.trim().replace(/%[a-zA-Z]/g, "");
1084
+ if (!cleaned) return null;
1085
+ if (cleaned.startsWith("/")) return cleaned;
1086
+ const resolved = execText("which", [cleaned], 800);
1087
+ return resolved ? resolved.trim() : null;
1088
+ }
1089
+ function readWindowsProgId() {
1090
+ const output = execText("reg", [
1091
+ "query",
1092
+ "HKCU\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice",
1093
+ "/v",
1094
+ "ProgId"
1095
+ ]);
1096
+ if (!output) return null;
1097
+ return output.match(/ProgId\s+REG_\w+\s+(.+)$/im)?.[1]?.trim() || null;
1098
+ }
1099
+ function readWindowsCommandForProgId(progId) {
1100
+ const output = execText("reg", [
1101
+ "query",
1102
+ progId === "http" ? "HKCR\\http\\shell\\open\\command" : `HKCR\\${progId}\\shell\\open\\command`,
1103
+ "/ve"
1104
+ ]);
1105
+ if (!output) return null;
1106
+ return output.match(/REG_\w+\s+(.+)$/im)?.[1]?.trim() || null;
1107
+ }
1108
+ function expandWindowsEnvVars(value) {
1109
+ return value.replace(/%([^%]+)%/g, (_match, name) => {
1110
+ const key = String(name ?? "").trim();
1111
+ return key ? process.env[key] ?? `%${key}%` : _match;
1112
+ });
1113
+ }
1114
+ function extractWindowsExecutablePath(command) {
1115
+ const quoted = command.match(/"([^"]+\\.exe)"/i);
1116
+ if (quoted?.[1]) return quoted[1];
1117
+ const unquoted = command.match(/([^\\s]+\\.exe)/i);
1118
+ if (unquoted?.[1]) return unquoted[1];
1119
+ return null;
1120
+ }
1121
+ function findFirstExecutable(candidates) {
1122
+ for (const candidate of candidates) if (exists$1(candidate.path)) return candidate;
1123
+ return null;
1124
+ }
1125
+ function findChromeExecutableMac() {
1126
+ return findFirstExecutable([
1127
+ {
1128
+ kind: "chrome",
1129
+ path: "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
1130
+ },
1131
+ {
1132
+ kind: "chrome",
1133
+ path: path.join(os.homedir(), "Applications/Google Chrome.app/Contents/MacOS/Google Chrome")
1134
+ },
1135
+ {
1136
+ kind: "brave",
1137
+ path: "/Applications/Brave Browser.app/Contents/MacOS/Brave Browser"
1138
+ },
1139
+ {
1140
+ kind: "brave",
1141
+ path: path.join(os.homedir(), "Applications/Brave Browser.app/Contents/MacOS/Brave Browser")
1142
+ },
1143
+ {
1144
+ kind: "edge",
1145
+ path: "/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge"
1146
+ },
1147
+ {
1148
+ kind: "edge",
1149
+ path: path.join(os.homedir(), "Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge")
1150
+ },
1151
+ {
1152
+ kind: "chromium",
1153
+ path: "/Applications/Chromium.app/Contents/MacOS/Chromium"
1154
+ },
1155
+ {
1156
+ kind: "chromium",
1157
+ path: path.join(os.homedir(), "Applications/Chromium.app/Contents/MacOS/Chromium")
1158
+ },
1159
+ {
1160
+ kind: "canary",
1161
+ path: "/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary"
1162
+ },
1163
+ {
1164
+ kind: "canary",
1165
+ path: path.join(os.homedir(), "Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary")
1166
+ }
1167
+ ]);
1168
+ }
1169
+ function findChromeExecutableLinux() {
1170
+ return findFirstExecutable([
1171
+ {
1172
+ kind: "chrome",
1173
+ path: "/usr/bin/google-chrome"
1174
+ },
1175
+ {
1176
+ kind: "chrome",
1177
+ path: "/usr/bin/google-chrome-stable"
1178
+ },
1179
+ {
1180
+ kind: "chrome",
1181
+ path: "/usr/bin/chrome"
1182
+ },
1183
+ {
1184
+ kind: "brave",
1185
+ path: "/usr/bin/brave-browser"
1186
+ },
1187
+ {
1188
+ kind: "brave",
1189
+ path: "/usr/bin/brave-browser-stable"
1190
+ },
1191
+ {
1192
+ kind: "brave",
1193
+ path: "/usr/bin/brave"
1194
+ },
1195
+ {
1196
+ kind: "brave",
1197
+ path: "/snap/bin/brave"
1198
+ },
1199
+ {
1200
+ kind: "edge",
1201
+ path: "/usr/bin/microsoft-edge"
1202
+ },
1203
+ {
1204
+ kind: "edge",
1205
+ path: "/usr/bin/microsoft-edge-stable"
1206
+ },
1207
+ {
1208
+ kind: "chromium",
1209
+ path: "/usr/bin/chromium"
1210
+ },
1211
+ {
1212
+ kind: "chromium",
1213
+ path: "/usr/bin/chromium-browser"
1214
+ },
1215
+ {
1216
+ kind: "chromium",
1217
+ path: "/snap/bin/chromium"
1218
+ }
1219
+ ]);
1220
+ }
1221
+ function findChromeExecutableWindows() {
1222
+ const localAppData = process.env.LOCALAPPDATA ?? "";
1223
+ const programFiles = process.env.ProgramFiles ?? "C:\\Program Files";
1224
+ const programFilesX86 = process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)";
1225
+ const joinWin = path.win32.join;
1226
+ const candidates = [];
1227
+ if (localAppData) {
1228
+ candidates.push({
1229
+ kind: "chrome",
1230
+ path: joinWin(localAppData, "Google", "Chrome", "Application", "chrome.exe")
1231
+ });
1232
+ candidates.push({
1233
+ kind: "brave",
1234
+ path: joinWin(localAppData, "BraveSoftware", "Brave-Browser", "Application", "brave.exe")
1235
+ });
1236
+ candidates.push({
1237
+ kind: "edge",
1238
+ path: joinWin(localAppData, "Microsoft", "Edge", "Application", "msedge.exe")
1239
+ });
1240
+ candidates.push({
1241
+ kind: "chromium",
1242
+ path: joinWin(localAppData, "Chromium", "Application", "chrome.exe")
1243
+ });
1244
+ candidates.push({
1245
+ kind: "canary",
1246
+ path: joinWin(localAppData, "Google", "Chrome SxS", "Application", "chrome.exe")
1247
+ });
1248
+ }
1249
+ candidates.push({
1250
+ kind: "chrome",
1251
+ path: joinWin(programFiles, "Google", "Chrome", "Application", "chrome.exe")
1252
+ });
1253
+ candidates.push({
1254
+ kind: "chrome",
1255
+ path: joinWin(programFilesX86, "Google", "Chrome", "Application", "chrome.exe")
1256
+ });
1257
+ candidates.push({
1258
+ kind: "brave",
1259
+ path: joinWin(programFiles, "BraveSoftware", "Brave-Browser", "Application", "brave.exe")
1260
+ });
1261
+ candidates.push({
1262
+ kind: "brave",
1263
+ path: joinWin(programFilesX86, "BraveSoftware", "Brave-Browser", "Application", "brave.exe")
1264
+ });
1265
+ candidates.push({
1266
+ kind: "edge",
1267
+ path: joinWin(programFiles, "Microsoft", "Edge", "Application", "msedge.exe")
1268
+ });
1269
+ candidates.push({
1270
+ kind: "edge",
1271
+ path: joinWin(programFilesX86, "Microsoft", "Edge", "Application", "msedge.exe")
1272
+ });
1273
+ return findFirstExecutable(candidates);
1274
+ }
1275
+ function resolveBrowserExecutableForPlatform(resolved, platform) {
1276
+ if (resolved.executablePath) {
1277
+ if (!exists$1(resolved.executablePath)) throw new Error(`browser.executablePath not found: ${resolved.executablePath}`);
1278
+ return {
1279
+ kind: "custom",
1280
+ path: resolved.executablePath
1281
+ };
1282
+ }
1283
+ const detected = detectDefaultChromiumExecutable(platform);
1284
+ if (detected) return detected;
1285
+ if (platform === "darwin") return findChromeExecutableMac();
1286
+ if (platform === "linux") return findChromeExecutableLinux();
1287
+ if (platform === "win32") return findChromeExecutableWindows();
1288
+ return null;
1289
+ }
1290
+
1291
+ //#endregion
1292
+ //#region src/infra/ports-format.ts
1293
+ function classifyPortListener(listener, port) {
1294
+ const raw = `${listener.commandLine ?? ""} ${listener.command ?? ""}`.trim().toLowerCase();
1295
+ if (raw.includes("cryptoclaw") || raw.includes("openclaw")) return "gateway";
1296
+ if (raw.includes("ssh")) {
1297
+ const portToken = String(port);
1298
+ const tunnelPattern = new RegExp(`-(l|r)\\s*${portToken}\\b|-(l|r)${portToken}\\b|:${portToken}\\b`);
1299
+ if (!raw || tunnelPattern.test(raw)) return "ssh";
1300
+ return "ssh";
1301
+ }
1302
+ return "unknown";
1303
+ }
1304
+ function buildPortHints(listeners, port) {
1305
+ if (listeners.length === 0) return [];
1306
+ const kinds = new Set(listeners.map((listener) => classifyPortListener(listener, port)));
1307
+ const hints = [];
1308
+ if (kinds.has("gateway")) hints.push(`Gateway already running locally. Stop it (${formatCliCommand("cryptoclaw gateway stop")}) or use a different port.`);
1309
+ if (kinds.has("ssh")) hints.push("SSH tunnel already bound to this port. Close the tunnel or use a different local port in -L.");
1310
+ if (kinds.has("unknown")) hints.push("Another process is listening on this port.");
1311
+ if (listeners.length > 1) hints.push("Multiple listeners detected; ensure only one gateway/tunnel per port unless intentionally running isolated profiles.");
1312
+ return hints;
1313
+ }
1314
+ function formatPortListener(listener) {
1315
+ return `${listener.pid ? `pid ${listener.pid}` : "pid ?"}${listener.user ? ` ${listener.user}` : ""}: ${listener.commandLine || listener.command || "unknown"}${listener.address ? ` (${listener.address})` : ""}`;
1316
+ }
1317
+ function formatPortDiagnostics(diagnostics) {
1318
+ if (diagnostics.status !== "busy") return [`Port ${diagnostics.port} is free.`];
1319
+ const lines = [`Port ${diagnostics.port} is already in use.`];
1320
+ for (const listener of diagnostics.listeners) lines.push(`- ${formatPortListener(listener)}`);
1321
+ for (const hint of diagnostics.hints) lines.push(`- ${hint}`);
1322
+ return lines;
1323
+ }
1324
+
1325
+ //#endregion
1326
+ //#region src/infra/ports-lsof.ts
1327
+ const LSOF_CANDIDATES = process.platform === "darwin" ? ["/usr/sbin/lsof", "/usr/bin/lsof"] : ["/usr/bin/lsof", "/usr/sbin/lsof"];
1328
+ async function canExecute(path) {
1329
+ try {
1330
+ await fs$1.access(path, fs.constants.X_OK);
1331
+ return true;
1332
+ } catch {
1333
+ return false;
1334
+ }
1335
+ }
1336
+ async function resolveLsofCommand() {
1337
+ for (const candidate of LSOF_CANDIDATES) if (await canExecute(candidate)) return candidate;
1338
+ return "lsof";
1339
+ }
1340
+
1341
+ //#endregion
1342
+ //#region src/infra/ports-inspect.ts
1343
+ function isErrno$1(err) {
1344
+ return Boolean(err && typeof err === "object" && "code" in err);
1345
+ }
1346
+ async function runCommandSafe(argv, timeoutMs = 5e3) {
1347
+ try {
1348
+ const res = await runCommandWithTimeout(argv, { timeoutMs });
1349
+ return {
1350
+ stdout: res.stdout,
1351
+ stderr: res.stderr,
1352
+ code: res.code ?? 1
1353
+ };
1354
+ } catch (err) {
1355
+ return {
1356
+ stdout: "",
1357
+ stderr: "",
1358
+ code: 1,
1359
+ error: String(err)
1360
+ };
1361
+ }
1362
+ }
1363
+ function parseLsofFieldOutput(output) {
1364
+ const lines = output.split(/\r?\n/).filter(Boolean);
1365
+ const listeners = [];
1366
+ let current = {};
1367
+ for (const line of lines) if (line.startsWith("p")) {
1368
+ if (current.pid || current.command) listeners.push(current);
1369
+ const pid = Number.parseInt(line.slice(1), 10);
1370
+ current = Number.isFinite(pid) ? { pid } : {};
1371
+ } else if (line.startsWith("c")) current.command = line.slice(1);
1372
+ else if (line.startsWith("n")) {
1373
+ if (!current.address) current.address = line.slice(1);
1374
+ }
1375
+ if (current.pid || current.command) listeners.push(current);
1376
+ return listeners;
1377
+ }
1378
+ async function resolveUnixCommandLine(pid) {
1379
+ const res = await runCommandSafe([
1380
+ "ps",
1381
+ "-p",
1382
+ String(pid),
1383
+ "-o",
1384
+ "command="
1385
+ ]);
1386
+ if (res.code !== 0) return;
1387
+ return res.stdout.trim() || void 0;
1388
+ }
1389
+ async function resolveUnixUser(pid) {
1390
+ const res = await runCommandSafe([
1391
+ "ps",
1392
+ "-p",
1393
+ String(pid),
1394
+ "-o",
1395
+ "user="
1396
+ ]);
1397
+ if (res.code !== 0) return;
1398
+ return res.stdout.trim() || void 0;
1399
+ }
1400
+ async function readUnixListeners(port) {
1401
+ const errors = [];
1402
+ const res = await runCommandSafe([
1403
+ await resolveLsofCommand(),
1404
+ "-nP",
1405
+ `-iTCP:${port}`,
1406
+ "-sTCP:LISTEN",
1407
+ "-FpFcn"
1408
+ ]);
1409
+ if (res.code === 0) {
1410
+ const listeners = parseLsofFieldOutput(res.stdout);
1411
+ await Promise.all(listeners.map(async (listener) => {
1412
+ if (!listener.pid) return;
1413
+ const [commandLine, user] = await Promise.all([resolveUnixCommandLine(listener.pid), resolveUnixUser(listener.pid)]);
1414
+ if (commandLine) listener.commandLine = commandLine;
1415
+ if (user) listener.user = user;
1416
+ }));
1417
+ return {
1418
+ listeners,
1419
+ detail: res.stdout.trim() || void 0,
1420
+ errors
1421
+ };
1422
+ }
1423
+ const stderr = res.stderr.trim();
1424
+ if (res.code === 1 && !res.error && !stderr) return {
1425
+ listeners: [],
1426
+ detail: void 0,
1427
+ errors
1428
+ };
1429
+ if (res.error) errors.push(res.error);
1430
+ const detail = [stderr, res.stdout.trim()].filter(Boolean).join("\n");
1431
+ if (detail) errors.push(detail);
1432
+ return {
1433
+ listeners: [],
1434
+ detail: void 0,
1435
+ errors
1436
+ };
1437
+ }
1438
+ function parseNetstatListeners(output, port) {
1439
+ const listeners = [];
1440
+ const portToken = `:${port}`;
1441
+ for (const rawLine of output.split(/\r?\n/)) {
1442
+ const line = rawLine.trim();
1443
+ if (!line) continue;
1444
+ if (!line.toLowerCase().includes("listen")) continue;
1445
+ if (!line.includes(portToken)) continue;
1446
+ const parts = line.split(/\s+/);
1447
+ if (parts.length < 4) continue;
1448
+ const pidRaw = parts.at(-1);
1449
+ const pid = pidRaw ? Number.parseInt(pidRaw, 10) : NaN;
1450
+ const localAddr = parts[1];
1451
+ const listener = {};
1452
+ if (Number.isFinite(pid)) listener.pid = pid;
1453
+ if (localAddr?.includes(portToken)) listener.address = localAddr;
1454
+ listeners.push(listener);
1455
+ }
1456
+ return listeners;
1457
+ }
1458
+ async function resolveWindowsImageName(pid) {
1459
+ const res = await runCommandSafe([
1460
+ "tasklist",
1461
+ "/FI",
1462
+ `PID eq ${pid}`,
1463
+ "/FO",
1464
+ "LIST"
1465
+ ]);
1466
+ if (res.code !== 0) return;
1467
+ for (const rawLine of res.stdout.split(/\r?\n/)) {
1468
+ const line = rawLine.trim();
1469
+ if (!line.toLowerCase().startsWith("image name:")) continue;
1470
+ return line.slice(11).trim() || void 0;
1471
+ }
1472
+ }
1473
+ async function resolveWindowsCommandLine(pid) {
1474
+ const res = await runCommandSafe([
1475
+ "wmic",
1476
+ "process",
1477
+ "where",
1478
+ `ProcessId=${pid}`,
1479
+ "get",
1480
+ "CommandLine",
1481
+ "/value"
1482
+ ]);
1483
+ if (res.code !== 0) return;
1484
+ for (const rawLine of res.stdout.split(/\r?\n/)) {
1485
+ const line = rawLine.trim();
1486
+ if (!line.toLowerCase().startsWith("commandline=")) continue;
1487
+ return line.slice(12).trim() || void 0;
1488
+ }
1489
+ }
1490
+ async function readWindowsListeners(port) {
1491
+ const errors = [];
1492
+ const res = await runCommandSafe([
1493
+ "netstat",
1494
+ "-ano",
1495
+ "-p",
1496
+ "tcp"
1497
+ ]);
1498
+ if (res.code !== 0) {
1499
+ if (res.error) errors.push(res.error);
1500
+ const detail = [res.stderr.trim(), res.stdout.trim()].filter(Boolean).join("\n");
1501
+ if (detail) errors.push(detail);
1502
+ return {
1503
+ listeners: [],
1504
+ errors
1505
+ };
1506
+ }
1507
+ const listeners = parseNetstatListeners(res.stdout, port);
1508
+ await Promise.all(listeners.map(async (listener) => {
1509
+ if (!listener.pid) return;
1510
+ const [imageName, commandLine] = await Promise.all([resolveWindowsImageName(listener.pid), resolveWindowsCommandLine(listener.pid)]);
1511
+ if (imageName) listener.command = imageName;
1512
+ if (commandLine) listener.commandLine = commandLine;
1513
+ }));
1514
+ return {
1515
+ listeners,
1516
+ detail: res.stdout.trim() || void 0,
1517
+ errors
1518
+ };
1519
+ }
1520
+ async function tryListenOnHost(port, host) {
1521
+ try {
1522
+ await new Promise((resolve, reject) => {
1523
+ const tester = net.createServer().once("error", (err) => reject(err)).once("listening", () => {
1524
+ tester.close(() => resolve());
1525
+ }).listen({
1526
+ port,
1527
+ host,
1528
+ exclusive: true
1529
+ });
1530
+ });
1531
+ return "free";
1532
+ } catch (err) {
1533
+ if (isErrno$1(err) && err.code === "EADDRINUSE") return "busy";
1534
+ if (isErrno$1(err) && (err.code === "EADDRNOTAVAIL" || err.code === "EAFNOSUPPORT")) return "skip";
1535
+ return "unknown";
1536
+ }
1537
+ }
1538
+ async function checkPortInUse(port) {
1539
+ const hosts = [
1540
+ "127.0.0.1",
1541
+ "0.0.0.0",
1542
+ "::1",
1543
+ "::"
1544
+ ];
1545
+ let sawUnknown = false;
1546
+ for (const host of hosts) {
1547
+ const result = await tryListenOnHost(port, host);
1548
+ if (result === "busy") return "busy";
1549
+ if (result === "unknown") sawUnknown = true;
1550
+ }
1551
+ return sawUnknown ? "unknown" : "free";
1552
+ }
1553
+ async function inspectPortUsage(port) {
1554
+ const errors = [];
1555
+ const result = process.platform === "win32" ? await readWindowsListeners(port) : await readUnixListeners(port);
1556
+ errors.push(...result.errors);
1557
+ let listeners = result.listeners;
1558
+ let status = listeners.length > 0 ? "busy" : "unknown";
1559
+ if (listeners.length === 0) status = await checkPortInUse(port);
1560
+ if (status !== "busy") listeners = [];
1561
+ const hints = buildPortHints(listeners, port);
1562
+ if (status === "busy" && listeners.length === 0) hints.push("Port is in use but process details are unavailable (install lsof or run as an admin user).");
1563
+ return {
1564
+ port,
1565
+ status,
1566
+ listeners,
1567
+ hints,
1568
+ detail: result.detail,
1569
+ errors: errors.length > 0 ? errors : void 0
1570
+ };
1571
+ }
1572
+
1573
+ //#endregion
1574
+ //#region src/infra/ports.ts
1575
+ var PortInUseError = class extends Error {
1576
+ constructor(port, details) {
1577
+ super(`Port ${port} is already in use.`);
1578
+ this.name = "PortInUseError";
1579
+ this.port = port;
1580
+ this.details = details;
1581
+ }
1582
+ };
1583
+ function isErrno(err) {
1584
+ return Boolean(err && typeof err === "object" && "code" in err);
1585
+ }
1586
+ async function describePortOwner(port) {
1587
+ const diagnostics = await inspectPortUsage(port);
1588
+ if (diagnostics.listeners.length === 0) return;
1589
+ return formatPortDiagnostics(diagnostics).join("\n");
1590
+ }
1591
+ async function ensurePortAvailable(port) {
1592
+ try {
1593
+ await new Promise((resolve, reject) => {
1594
+ const tester = net.createServer().once("error", (err) => reject(err)).once("listening", () => {
1595
+ tester.close(() => resolve());
1596
+ }).listen(port);
1597
+ });
1598
+ } catch (err) {
1599
+ if (isErrno(err) && err.code === "EADDRINUSE") throw new PortInUseError(port, await describePortOwner(port));
1600
+ throw err;
1601
+ }
1602
+ }
1603
+
1604
+ //#endregion
1605
+ //#region src/browser/chrome.profile-decoration.ts
1606
+ function decoratedMarkerPath(userDataDir) {
1607
+ return path.join(userDataDir, ".openclaw-profile-decorated");
1608
+ }
1609
+ function safeReadJson(filePath) {
1610
+ try {
1611
+ if (!fs.existsSync(filePath)) return null;
1612
+ const raw = fs.readFileSync(filePath, "utf-8");
1613
+ const parsed = JSON.parse(raw);
1614
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return null;
1615
+ return parsed;
1616
+ } catch {
1617
+ return null;
1618
+ }
1619
+ }
1620
+ function safeWriteJson(filePath, data) {
1621
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
1622
+ fs.writeFileSync(filePath, JSON.stringify(data, null, 2));
1623
+ }
1624
+ function setDeep(obj, keys, value) {
1625
+ let node = obj;
1626
+ for (const key of keys.slice(0, -1)) {
1627
+ const next = node[key];
1628
+ if (typeof next !== "object" || next === null || Array.isArray(next)) node[key] = {};
1629
+ node = node[key];
1630
+ }
1631
+ node[keys[keys.length - 1] ?? ""] = value;
1632
+ }
1633
+ function parseHexRgbToSignedArgbInt(hex) {
1634
+ const cleaned = hex.trim().replace(/^#/, "");
1635
+ if (!/^[0-9a-fA-F]{6}$/.test(cleaned)) return null;
1636
+ const argbUnsigned = 255 << 24 | Number.parseInt(cleaned, 16);
1637
+ return argbUnsigned > 2147483647 ? argbUnsigned - 4294967296 : argbUnsigned;
1638
+ }
1639
+ function isProfileDecorated(userDataDir, desiredName, desiredColorHex) {
1640
+ const desiredColorInt = parseHexRgbToSignedArgbInt(desiredColorHex);
1641
+ const localStatePath = path.join(userDataDir, "Local State");
1642
+ const preferencesPath = path.join(userDataDir, "Default", "Preferences");
1643
+ const profile = safeReadJson(localStatePath)?.profile;
1644
+ const infoCache = typeof profile === "object" && profile !== null && !Array.isArray(profile) ? profile.info_cache : null;
1645
+ const info = typeof infoCache === "object" && infoCache !== null && !Array.isArray(infoCache) && typeof infoCache.Default === "object" && infoCache.Default !== null && !Array.isArray(infoCache.Default) ? infoCache.Default : null;
1646
+ const prefs = safeReadJson(preferencesPath);
1647
+ const browserTheme = (() => {
1648
+ const browser = prefs?.browser;
1649
+ const theme = typeof browser === "object" && browser !== null && !Array.isArray(browser) ? browser.theme : null;
1650
+ return typeof theme === "object" && theme !== null && !Array.isArray(theme) ? theme : null;
1651
+ })();
1652
+ const autogeneratedTheme = (() => {
1653
+ const autogenerated = prefs?.autogenerated;
1654
+ const theme = typeof autogenerated === "object" && autogenerated !== null && !Array.isArray(autogenerated) ? autogenerated.theme : null;
1655
+ return typeof theme === "object" && theme !== null && !Array.isArray(theme) ? theme : null;
1656
+ })();
1657
+ const nameOk = typeof info?.name === "string" ? info.name === desiredName : true;
1658
+ if (desiredColorInt == null) return nameOk;
1659
+ const localSeedOk = typeof info?.profile_color_seed === "number" ? info.profile_color_seed === desiredColorInt : false;
1660
+ const prefOk = typeof browserTheme?.user_color2 === "number" && browserTheme.user_color2 === desiredColorInt || typeof autogeneratedTheme?.color === "number" && autogeneratedTheme.color === desiredColorInt;
1661
+ return nameOk && localSeedOk && prefOk;
1662
+ }
1663
+ /**
1664
+ * Best-effort profile decoration (name + lobster-orange). Chrome preference keys
1665
+ * vary by version; we keep this conservative and idempotent.
1666
+ */
1667
+ function decorateOpenClawProfile(userDataDir, opts) {
1668
+ const desiredName = opts?.name ?? DEFAULT_CRYPTOCLAW_BROWSER_PROFILE_NAME;
1669
+ const desiredColor = (opts?.color ?? DEFAULT_CRYPTOCLAW_BROWSER_COLOR).toUpperCase();
1670
+ const desiredColorInt = parseHexRgbToSignedArgbInt(desiredColor);
1671
+ const localStatePath = path.join(userDataDir, "Local State");
1672
+ const preferencesPath = path.join(userDataDir, "Default", "Preferences");
1673
+ const localState = safeReadJson(localStatePath) ?? {};
1674
+ setDeep(localState, [
1675
+ "profile",
1676
+ "info_cache",
1677
+ "Default",
1678
+ "name"
1679
+ ], desiredName);
1680
+ setDeep(localState, [
1681
+ "profile",
1682
+ "info_cache",
1683
+ "Default",
1684
+ "shortcut_name"
1685
+ ], desiredName);
1686
+ setDeep(localState, [
1687
+ "profile",
1688
+ "info_cache",
1689
+ "Default",
1690
+ "user_name"
1691
+ ], desiredName);
1692
+ setDeep(localState, [
1693
+ "profile",
1694
+ "info_cache",
1695
+ "Default",
1696
+ "profile_color"
1697
+ ], desiredColor);
1698
+ setDeep(localState, [
1699
+ "profile",
1700
+ "info_cache",
1701
+ "Default",
1702
+ "user_color"
1703
+ ], desiredColor);
1704
+ if (desiredColorInt != null) {
1705
+ setDeep(localState, [
1706
+ "profile",
1707
+ "info_cache",
1708
+ "Default",
1709
+ "profile_color_seed"
1710
+ ], desiredColorInt);
1711
+ setDeep(localState, [
1712
+ "profile",
1713
+ "info_cache",
1714
+ "Default",
1715
+ "profile_highlight_color"
1716
+ ], desiredColorInt);
1717
+ setDeep(localState, [
1718
+ "profile",
1719
+ "info_cache",
1720
+ "Default",
1721
+ "default_avatar_fill_color"
1722
+ ], desiredColorInt);
1723
+ setDeep(localState, [
1724
+ "profile",
1725
+ "info_cache",
1726
+ "Default",
1727
+ "default_avatar_stroke_color"
1728
+ ], desiredColorInt);
1729
+ }
1730
+ safeWriteJson(localStatePath, localState);
1731
+ const prefs = safeReadJson(preferencesPath) ?? {};
1732
+ setDeep(prefs, ["profile", "name"], desiredName);
1733
+ setDeep(prefs, ["profile", "profile_color"], desiredColor);
1734
+ setDeep(prefs, ["profile", "user_color"], desiredColor);
1735
+ if (desiredColorInt != null) {
1736
+ setDeep(prefs, [
1737
+ "autogenerated",
1738
+ "theme",
1739
+ "color"
1740
+ ], desiredColorInt);
1741
+ setDeep(prefs, [
1742
+ "browser",
1743
+ "theme",
1744
+ "user_color2"
1745
+ ], desiredColorInt);
1746
+ }
1747
+ safeWriteJson(preferencesPath, prefs);
1748
+ try {
1749
+ fs.writeFileSync(decoratedMarkerPath(userDataDir), `${Date.now()}\n`, "utf-8");
1750
+ } catch {}
1751
+ }
1752
+ function ensureProfileCleanExit(userDataDir) {
1753
+ const preferencesPath = path.join(userDataDir, "Default", "Preferences");
1754
+ const prefs = safeReadJson(preferencesPath) ?? {};
1755
+ setDeep(prefs, ["exit_type"], "Normal");
1756
+ setDeep(prefs, ["exited_cleanly"], true);
1757
+ safeWriteJson(preferencesPath, prefs);
1758
+ }
1759
+
1760
+ //#endregion
1761
+ //#region src/browser/chrome.ts
1762
+ const log = createSubsystemLogger("browser").child("chrome");
1763
+ function exists(filePath) {
1764
+ try {
1765
+ return fs.existsSync(filePath);
1766
+ } catch {
1767
+ return false;
1768
+ }
1769
+ }
1770
+ function resolveBrowserExecutable(resolved) {
1771
+ return resolveBrowserExecutableForPlatform(resolved, process.platform);
1772
+ }
1773
+ function resolveOpenClawUserDataDir(profileName = DEFAULT_CRYPTOCLAW_BROWSER_PROFILE_NAME) {
1774
+ return path.join(CONFIG_DIR, "browser", profileName, "user-data");
1775
+ }
1776
+ function cdpUrlForPort(cdpPort) {
1777
+ return `http://127.0.0.1:${cdpPort}`;
1778
+ }
1779
+ async function isChromeReachable(cdpUrl, timeoutMs = 500) {
1780
+ const version = await fetchChromeVersion(cdpUrl, timeoutMs);
1781
+ return Boolean(version);
1782
+ }
1783
+ async function fetchChromeVersion(cdpUrl, timeoutMs = 500) {
1784
+ const ctrl = new AbortController();
1785
+ const t = setTimeout(() => ctrl.abort(), timeoutMs);
1786
+ try {
1787
+ const versionUrl = appendCdpPath(cdpUrl, "/json/version");
1788
+ const res = await fetch(versionUrl, {
1789
+ signal: ctrl.signal,
1790
+ headers: getHeadersWithAuth(versionUrl)
1791
+ });
1792
+ if (!res.ok) return null;
1793
+ const data = await res.json();
1794
+ if (!data || typeof data !== "object") return null;
1795
+ return data;
1796
+ } catch {
1797
+ return null;
1798
+ } finally {
1799
+ clearTimeout(t);
1800
+ }
1801
+ }
1802
+ async function getChromeWebSocketUrl(cdpUrl, timeoutMs = 500) {
1803
+ const version = await fetchChromeVersion(cdpUrl, timeoutMs);
1804
+ const wsUrl = String(version?.webSocketDebuggerUrl ?? "").trim();
1805
+ if (!wsUrl) return null;
1806
+ return normalizeCdpWsUrl(wsUrl, cdpUrl);
1807
+ }
1808
+ async function canOpenWebSocket(wsUrl, timeoutMs = 800) {
1809
+ return await new Promise((resolve) => {
1810
+ const headers = getHeadersWithAuth(wsUrl);
1811
+ const ws = new WebSocket$1(wsUrl, {
1812
+ handshakeTimeout: timeoutMs,
1813
+ ...Object.keys(headers).length ? { headers } : {}
1814
+ });
1815
+ const timer = setTimeout(() => {
1816
+ try {
1817
+ ws.terminate();
1818
+ } catch {}
1819
+ resolve(false);
1820
+ }, Math.max(50, timeoutMs + 25));
1821
+ ws.once("open", () => {
1822
+ clearTimeout(timer);
1823
+ try {
1824
+ ws.close();
1825
+ } catch {}
1826
+ resolve(true);
1827
+ });
1828
+ ws.once("error", () => {
1829
+ clearTimeout(timer);
1830
+ resolve(false);
1831
+ });
1832
+ });
1833
+ }
1834
+ async function isChromeCdpReady(cdpUrl, timeoutMs = 500, handshakeTimeoutMs = 800) {
1835
+ const wsUrl = await getChromeWebSocketUrl(cdpUrl, timeoutMs);
1836
+ if (!wsUrl) return false;
1837
+ return await canOpenWebSocket(wsUrl, handshakeTimeoutMs);
1838
+ }
1839
+ async function launchOpenClawChrome(resolved, profile) {
1840
+ if (!profile.cdpIsLoopback) throw new Error(`Profile "${profile.name}" is remote; cannot launch local Chrome.`);
1841
+ await ensurePortAvailable(profile.cdpPort);
1842
+ const exe = resolveBrowserExecutable(resolved);
1843
+ if (!exe) throw new Error("No supported browser found (Chrome/Brave/Edge/Chromium on macOS, Linux, or Windows).");
1844
+ const userDataDir = resolveOpenClawUserDataDir(profile.name);
1845
+ fs.mkdirSync(userDataDir, { recursive: true });
1846
+ const needsDecorate = !isProfileDecorated(userDataDir, profile.name, (profile.color ?? DEFAULT_CRYPTOCLAW_BROWSER_COLOR).toUpperCase());
1847
+ const spawnOnce = () => {
1848
+ const args = [
1849
+ `--remote-debugging-port=${profile.cdpPort}`,
1850
+ `--user-data-dir=${userDataDir}`,
1851
+ "--no-first-run",
1852
+ "--no-default-browser-check",
1853
+ "--disable-sync",
1854
+ "--disable-background-networking",
1855
+ "--disable-component-update",
1856
+ "--disable-features=Translate,MediaRouter",
1857
+ "--disable-session-crashed-bubble",
1858
+ "--hide-crash-restore-bubble",
1859
+ "--password-store=basic"
1860
+ ];
1861
+ if (resolved.headless) {
1862
+ args.push("--headless=new");
1863
+ args.push("--disable-gpu");
1864
+ }
1865
+ if (resolved.noSandbox) {
1866
+ args.push("--no-sandbox");
1867
+ args.push("--disable-setuid-sandbox");
1868
+ }
1869
+ if (process.platform === "linux") args.push("--disable-dev-shm-usage");
1870
+ args.push("about:blank");
1871
+ return spawn(exe.path, args, {
1872
+ stdio: "pipe",
1873
+ env: {
1874
+ ...process.env,
1875
+ HOME: os.homedir()
1876
+ }
1877
+ });
1878
+ };
1879
+ const startedAt = Date.now();
1880
+ const localStatePath = path.join(userDataDir, "Local State");
1881
+ const preferencesPath = path.join(userDataDir, "Default", "Preferences");
1882
+ if (!exists(localStatePath) || !exists(preferencesPath)) {
1883
+ const bootstrap = spawnOnce();
1884
+ const deadline = Date.now() + 1e4;
1885
+ while (Date.now() < deadline) {
1886
+ if (exists(localStatePath) && exists(preferencesPath)) break;
1887
+ await new Promise((r) => setTimeout(r, 100));
1888
+ }
1889
+ try {
1890
+ bootstrap.kill("SIGTERM");
1891
+ } catch {}
1892
+ const exitDeadline = Date.now() + 5e3;
1893
+ while (Date.now() < exitDeadline) {
1894
+ if (bootstrap.exitCode != null) break;
1895
+ await new Promise((r) => setTimeout(r, 50));
1896
+ }
1897
+ }
1898
+ if (needsDecorate) try {
1899
+ decorateOpenClawProfile(userDataDir, {
1900
+ name: profile.name,
1901
+ color: profile.color
1902
+ });
1903
+ log.info(`🦞 cryptoclaw browser profile decorated (${profile.color})`);
1904
+ } catch (err) {
1905
+ log.warn(`cryptoclaw browser profile decoration failed: ${String(err)}`);
1906
+ }
1907
+ try {
1908
+ ensureProfileCleanExit(userDataDir);
1909
+ } catch (err) {
1910
+ log.warn(`cryptoclaw browser clean-exit prefs failed: ${String(err)}`);
1911
+ }
1912
+ const proc = spawnOnce();
1913
+ const readyDeadline = Date.now() + 15e3;
1914
+ while (Date.now() < readyDeadline) {
1915
+ if (await isChromeReachable(profile.cdpUrl, 500)) break;
1916
+ await new Promise((r) => setTimeout(r, 200));
1917
+ }
1918
+ if (!await isChromeReachable(profile.cdpUrl, 500)) {
1919
+ try {
1920
+ proc.kill("SIGKILL");
1921
+ } catch {}
1922
+ throw new Error(`Failed to start Chrome CDP on port ${profile.cdpPort} for profile "${profile.name}".`);
1923
+ }
1924
+ const pid = proc.pid ?? -1;
1925
+ log.info(`🦞 cryptoclaw browser started (${exe.kind}) profile "${profile.name}" on 127.0.0.1:${profile.cdpPort} (pid ${pid})`);
1926
+ return {
1927
+ pid,
1928
+ exe,
1929
+ userDataDir,
1930
+ cdpPort: profile.cdpPort,
1931
+ startedAt,
1932
+ proc
1933
+ };
1934
+ }
1935
+ async function stopOpenClawChrome(running, timeoutMs = 2500) {
1936
+ const proc = running.proc;
1937
+ if (proc.killed) return;
1938
+ try {
1939
+ proc.kill("SIGTERM");
1940
+ } catch {}
1941
+ const start = Date.now();
1942
+ while (Date.now() - start < timeoutMs) {
1943
+ if (!proc.exitCode && proc.killed) break;
1944
+ if (!await isChromeReachable(cdpUrlForPort(running.cdpPort), 200)) return;
1945
+ await new Promise((r) => setTimeout(r, 100));
1946
+ }
1947
+ try {
1948
+ proc.kill("SIGKILL");
1949
+ } catch {}
1950
+ }
1951
+
1952
+ //#endregion
1953
+ export { DEFAULT_AI_SNAPSHOT_MAX_CHARS as C, DEFAULT_CRYPTOCLAW_BROWSER_ENABLED as D, DEFAULT_CRYPTOCLAW_BROWSER_COLOR as E, DEFAULT_CRYPTOCLAW_BROWSER_PROFILE_NAME as O, DEFAULT_AI_SNAPSHOT_EFFICIENT_MAX_CHARS as S, DEFAULT_BROWSER_EVALUATE_ENABLED as T, rawDataToString as _, resolveOpenClawUserDataDir as a, formatUncaughtError as b, captureScreenshot as c, normalizeCdpWsUrl as d, snapshotAria as f, stopChromeExtensionRelayServer as g, ensureChromeExtensionRelayServer as h, launchOpenClawChrome as i, createTargetViaCdp as l, getHeadersWithAuth as m, isChromeCdpReady as n, stopOpenClawChrome as o, appendCdpPath as p, isChromeReachable as r, resolveBrowserExecutableForPlatform as s, getChromeWebSocketUrl as t, formatAriaSnapshot as u, extractErrorCode as v, DEFAULT_BROWSER_DEFAULT_PROFILE_NAME as w, DEFAULT_AI_SNAPSHOT_EFFICIENT_DEPTH as x, formatErrorMessage as y };