@hanzo/bot 2026.3.7 → 2026.3.8

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 (450) hide show
  1. package/dist/{accounts-D-CXitCL.js → accounts-BVV0eCmx.js} +2 -2
  2. package/dist/{accounts-Da-TWEIc.js → accounts-C04lw_uh.js} +4 -4
  3. package/dist/{accounts-DRUpcCkN.js → accounts-CtzU1wJb.js} +2 -2
  4. package/dist/{acp-cli-DYkqqqaJ.js → acp-cli-CDUVvPjD.js} +28 -24
  5. package/dist/{active-listener-DlziGqIg.js → active-listener-NprMzFx6.js} +2 -2
  6. package/dist/{agent-scope-C5bklqr1.js → agent-scope-BcruZHHR.js} +5 -5
  7. package/dist/{agents-CH9da9zi.js → agents-D8rH1P3g.js} +20 -19
  8. package/dist/{agents.config-BQ8I8wuY.js → agents.config-OuZqDEe6.js} +4 -4
  9. package/dist/{api-0IJLBHQk.js → api-Bgrt1pfd.js} +1 -1
  10. package/dist/{api-key-rotation-DuxfwUin.js → api-key-rotation-C0toONXd.js} +2 -2
  11. package/dist/{audio-preflight-CpAXC_Ct.js → audio-preflight-BEc8i-bS.js} +4 -4
  12. package/dist/{audio-preflight-BnfuyvxO.js → audio-preflight-D_s-peid.js} +4 -4
  13. package/dist/audio-preflight-d9iZknwY.js +102 -0
  14. package/dist/{audio-transcription-runner-GcMnO6sT.js → audio-transcription-runner-BePCnZfw.js} +1 -1
  15. package/dist/{audio-transcription-runner-CAOjjGxN.js → audio-transcription-runner-X1KzI7dF.js} +1 -1
  16. package/dist/{audio-transcription-runner-DCsEpXgz.js → audio-transcription-runner-bvBQs8UB.js} +13 -13
  17. package/dist/{audit-DCJbont3.js → audit-BWNRwu8g.js} +28 -28
  18. package/dist/{audit-membership-runtime-BIZ4bigJ.js → audit-membership-runtime-Bki8LzkA.js} +7 -6
  19. package/dist/{auth-CqlFkBrB.js → auth-CWHo884l.js} +5 -5
  20. package/dist/{auth-choice-9obtL17m.js → auth-choice-DUtpqOiw.js} +25 -22
  21. package/dist/{auth-choice-w2mL3d_M.js → auth-choice-n72qSpix.js} +15 -14
  22. package/dist/{auth-choice-options-DMoNPDm6.js → auth-choice-options-D13GahL8.js} +1 -1
  23. package/dist/{auth-choice-prompt-Btp8AqFI.js → auth-choice-prompt-8z7z_AUr.js} +1 -1
  24. package/dist/{auth-choice.apply-helpers-JU7nAiWC.js → auth-choice.apply-helpers-DMhFdoYH.js} +3 -3
  25. package/dist/{auth-mode-policy-slU2Nkgr.js → auth-mode-policy-BopOhrK8.js} +1 -1
  26. package/dist/{auth-profiles-BCHBDrea.js → auth-profiles-BtxyXCZY.js} +48 -925
  27. package/dist/{auth-token-BfzDARSk.js → auth-token-zcumGtdt.js} +3 -3
  28. package/dist/{banner-C4sx0Vaf.js → banner-C1G_GtAz.js} +3 -3
  29. package/dist/{bonjour-discovery-CzNIGZ7K.js → bonjour-discovery-C1SH2QqR.js} +3 -3
  30. package/dist/{browser-cli-qPNZkfDX.js → browser-cli-Bd81bwqM.js} +36 -32
  31. package/dist/build-info.json +3 -3
  32. package/dist/bundled/boot-md/handler.js +6 -6
  33. package/dist/bundled/session-memory/handler.js +6 -6
  34. package/dist/{call-C4z2LJrI.js → call-DL23sPxF.js} +9 -8
  35. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  36. package/dist/{channel-account-context-DyLW8OD1.js → channel-account-context-DGbGZhGz.js} +3 -3
  37. package/dist/{channel-activity-Bch3Rz78.js → channel-activity-DItBzFyQ.js} +3 -3
  38. package/dist/{channel-options-ChtPFPQx.js → channel-options-DU65sVdF.js} +4 -4
  39. package/dist/{channel-selection-CXz2aSCs.js → channel-selection-BnXQH0vV.js} +2 -2
  40. package/dist/{channel-web-Bok0lFvq.js → channel-web-BbWnfun7.js} +25 -24
  41. package/dist/{channels-cli-B5oDUpEB.js → channels-cli-B8LCe0vu.js} +142 -135
  42. package/dist/{channels-status-issues-BAy-21Cb.js → channels-status-issues-DXNaEL8i.js} +1 -1
  43. package/dist/{chrome--CFg5C_H.js → chrome-B24-8NDM.js} +8 -8
  44. package/dist/{chrome-jCt9JCU8.js → chrome-C7OwLtx9.js} +8 -8
  45. package/dist/{chrome-TWq_09_a.js → chrome-D4EfbMKb.js} +7 -7
  46. package/dist/{clack-prompter-0Rux0QKP.js → clack-prompter-CNKAp_jq.js} +5 -5
  47. package/dist/clawbot-cli-Bv8oZgvA.js +36 -0
  48. package/dist/cli/daemon-cli.js +1 -1
  49. package/dist/cli-DXbYdTNH.js +162 -0
  50. package/dist/{client-DWdu7Vc_.js → client-Bvvecv3V.js} +25 -142
  51. package/dist/{clipboard-Bfhk9cp3.js → clipboard-DwO9zZBK.js} +1 -1
  52. package/dist/{cloud-connect-BERMG0cQ.js → cloud-connect-CknfBF39.js} +89 -52
  53. package/dist/cloud-launch-7mm4ZKXy.js +172 -0
  54. package/dist/{command-poll-backoff.runtime-COz7plyi.js → command-poll-backoff.runtime-ClRAZFDL.js} +1 -1
  55. package/dist/{command-registry-DTMuq-Fw.js → command-registry-CTaJSsqV.js} +11 -11
  56. package/dist/{command-secret-targets-B2OuvZQf.js → command-secret-targets-C382v6Qd.js} +6 -6
  57. package/dist/{commands-BAjCW6P6.js → commands-BoGUirwW.js} +2 -2
  58. package/dist/{commands-registry-bwa5zMJ1.js → commands-registry-Dn_5_JYs.js} +6 -6
  59. package/dist/{compact-CenE94cW.js → compact-CuLMew-8.js} +141 -910
  60. package/dist/{completion-cli-spiS5-xU.js → completion-cli-CixfDHo4.js} +6 -6
  61. package/dist/{config-cli-w-RlQ3jB.js → config-cli-Bu2Eakz-.js} +22 -19
  62. package/dist/{config-guard-rlTIXCSD.js → config-guard-Bt2BdsMd.js} +5 -5
  63. package/dist/{config-validation-B3rr-h3d.js → config-validation-WdHwRX05.js} +6 -6
  64. package/dist/{configure-YxPFskRy.js → configure-ClIJiVqS.js} +32 -31
  65. package/dist/{control-ui-assets-CvLJNwEr.js → control-ui-assets-Co9rmXkB.js} +3 -3
  66. package/dist/{credentials-DVX7Krq5.js → credentials-SIFZMlmo.js} +1 -1
  67. package/dist/{cron-cli-DI9DN0vu.js → cron-cli-DR13ajr7.js} +32 -28
  68. package/dist/{daemon-cli-OBRBnIhu.js → daemon-cli-C6ZVajFI.js} +28 -28
  69. package/dist/{daemon-install-CGk2QyeB.js → daemon-install-DsDcMh2v.js} +43 -39
  70. package/dist/{daemon-install-helpers-C1QLEGFF.js → daemon-install-helpers-BtOiCRD1.js} +7 -35
  71. package/dist/{deliver-DPkEY6xb.js → deliver-Bge0HwrF.js} +13 -13
  72. package/dist/{deliver-BVtVDxwX.js → deliver-D8dBbzpu.js} +1 -1
  73. package/dist/{deliver-DmfS4khs.js → deliver-DudaV86i.js} +1 -1
  74. package/dist/{deliver-runtime-G0G5orrZ.js → deliver-runtime-C76IMU4W.js} +3 -3
  75. package/dist/{deliver-runtime-PxJvVUhh.js → deliver-runtime-qDmQqiF-.js} +3 -3
  76. package/dist/deliver-runtime-s0eLCemL.js +63 -0
  77. package/dist/{delivery-queue-DgdE_Ifa.js → delivery-queue-BVKd_xSI.js} +1 -1
  78. package/dist/deps-send-discord.runtime-C8HKp3uO.js +37 -0
  79. package/dist/deps-send-imessage.runtime-ECy162Cs.js +36 -0
  80. package/dist/deps-send-signal.runtime-XbioSg-_.js +35 -0
  81. package/dist/deps-send-slack.runtime-BM7Vp8vX.js +33 -0
  82. package/dist/deps-send-telegram.runtime-IFD4dAk7.js +39 -0
  83. package/dist/deps-send-whatsapp.runtime-BHuShWkA.js +124 -0
  84. package/dist/{deps-send-whatsapp.runtime-CrzuaVhC.js → deps-send-whatsapp.runtime-Cq-TLsJw.js} +7 -7
  85. package/dist/{deps-send-whatsapp.runtime-8bLqjmui.js → deps-send-whatsapp.runtime-Cv_awFtm.js} +7 -7
  86. package/dist/device-identity-DtdLP7QQ.js +148 -0
  87. package/dist/{devices-cli-C7xKmiR9.js → devices-cli-DZRtpqol.js} +25 -21
  88. package/dist/{diagnostic-DCevSIi3.js → diagnostic-CXxZq_XY.js} +3 -3
  89. package/dist/{diagnostics-vhe8iPOe.js → diagnostics-GQuagqCt.js} +1 -1
  90. package/dist/{directory-cli-BrLvL2oD.js → directory-cli-Tqim_rB9.js} +24 -21
  91. package/dist/{dns-cli-Dcytc0em.js → dns-cli-AcAZnW-T.js} +19 -16
  92. package/dist/{dock-D1Nz-RwP.js → dock-nMBfeGKa.js} +7 -7
  93. package/dist/{docs-cli-CjnLrTzs.js → docs-cli-C6mNYtxD.js} +17 -16
  94. package/dist/{doctor-completion-BKaFgAAN.js → doctor-completion-Dg6AJY6Q.js} +4 -4
  95. package/dist/{doctor-config-flow-Bp3eehAS.js → doctor-config-flow-CKY6Mr3X.js} +19 -19
  96. package/dist/{enable-pUSco1cm.js → enable-BWraNcrd.js} +2 -2
  97. package/dist/entry.js +6 -5
  98. package/dist/{errors-Dh5KARaE.js → errors-ClLWB67m.js} +1 -1
  99. package/dist/{exec-B45rafWZ.js → exec-B8Hv4Nkd.js} +1 -1
  100. package/dist/{exec-approvals-B5leCM6K.js → exec-approvals-Bh1osORd.js} +1 -1
  101. package/dist/{exec-approvals-allowlist-CSlk-iUy.js → exec-approvals-allowlist-dlIMsRq0.js} +1 -1
  102. package/dist/{exec-approvals-cli-B722kWhJ.js → exec-approvals-cli-B2V935Or.js} +33 -29
  103. package/dist/{exec-safe-bin-runtime-policy-C4OXhXIe.js → exec-safe-bin-runtime-policy-Ds-cMyOt.js} +2 -2
  104. package/dist/extensionAPI.js +6 -6
  105. package/dist/{fetch-COQIeEVX.js → fetch-BPh3R9xH.js} +3 -3
  106. package/dist/{fetch-TlhZeXdg.js → fetch-DyJnPUwL.js} +1 -1
  107. package/dist/{fetch-guard-BiNciKHu.js → fetch-guard-hL-C2yQz.js} +3 -3
  108. package/dist/{frontmatter-BIwJR052.js → frontmatter-B0viix_h.js} +2 -2
  109. package/dist/{fs-safe-DtMJsayp.js → fs-safe-CFIinCN2.js} +3 -3
  110. package/dist/gateway-cli-DjWebqxe.js +1436 -0
  111. package/dist/{gateway-install-token-tifgQqTq.js → gateway-install-token-olAkdWwV.js} +6 -6
  112. package/dist/gateway-lock-DNpln_70.js +192 -0
  113. package/dist/{gateway-rpc--AYNXZQF.js → gateway-rpc-B37zbuoK.js} +3 -3
  114. package/dist/{github-copilot-token-Byc_YVYE.js → github-copilot-token-BKQ4nXAw.js} +2 -23
  115. package/dist/{gmail-setup-utils-B1wEc-nz.js → gmail-setup-utils-DuoBM8ed.js} +3 -3
  116. package/dist/{health-DTtmaQPz.js → health-Cs-k6kLT.js} +18 -16
  117. package/dist/{helpers-CIEbwEWl.js → helpers-DDBxLojl.js} +1 -1
  118. package/dist/{hooks-cli-DJDBpL-Z.js → hooks-cli-Zqdxhm6M.js} +123 -116
  119. package/dist/{hooks-status-CFT0VML6.js → hooks-status-DqCwY9M6.js} +4 -4
  120. package/dist/{image-DSK1hSSV.js → image-BOybyCis.js} +1 -1
  121. package/dist/{image-DFnt4Uwg.js → image-m1GU1uco.js} +7 -7
  122. package/dist/{image-BdZcUz8M.js → image-nUHQF6BX.js} +1 -1
  123. package/dist/{image-ops-DBPCaLYI.js → image-ops-Bnk-bI_x.js} +1 -1
  124. package/dist/{image-runtime-ueqmfx1a.js → image-runtime-B5M_-diF.js} +3 -3
  125. package/dist/image-runtime-CesErRak.js +57 -0
  126. package/dist/{image-runtime-xqxW2PQA.js → image-runtime-y4msd5bn.js} +3 -3
  127. package/dist/{inspect-BVm4U2OP.js → inspect-CMuOPXUf.js} +2 -2
  128. package/dist/{install-safe-path-Df97RWiJ.js → install-safe-path-BxdyoAni.js} +3 -3
  129. package/dist/{installs-BGMsioU1.js → installs-c4kWJSG4.js} +8 -8
  130. package/dist/ip-C7WWCRN7.js +204 -0
  131. package/dist/{ipv4-Difv_P0_.js → ipv4-DcjwXncJ.js} +2 -2
  132. package/dist/{ir-CaGizvli.js → ir-BjnGKA2N.js} +8 -8
  133. package/dist/{issue-format-DjqrcimU.js → issue-format-BMPYbT1P.js} +1 -1
  134. package/dist/json-file-CNp4GTiH.js +25 -0
  135. package/dist/{lifecycle-core-BXWGDU3R.js → lifecycle-core-fN_BonzB.js} +10 -10
  136. package/dist/{links-C7eMwu1P.js → links-DZZ9QxWA.js} +1 -1
  137. package/dist/llm-slug-generator.js +6 -6
  138. package/dist/local-launch-C2RER-G3.js +126 -0
  139. package/dist/{logger-DB-PHqB2.js → logger-DyQjakwH.js} +2 -1
  140. package/dist/{logging-CS4C9VwV.js → logging--bXnY6uw.js} +1 -1
  141. package/dist/{login-B8HwtO61.js → login-DTK-M8Is.js} +6 -6
  142. package/dist/{login-qr-amd1X6Dw.js → login-qr-CmnyPjTv.js} +29 -16
  143. package/dist/{logs-cli-BH8DNgo2.js → logs-cli-BSlzurlM.js} +27 -23
  144. package/dist/machine-name-BWZ0tBHk.js +41 -0
  145. package/dist/{manager-BYSXh-I3.js → manager-BVqjeGyT.js} +11 -11
  146. package/dist/manager-runtime-CBdUM6c8.js +27 -0
  147. package/dist/{manifest-registry-9oWnIuht.js → manifest-registry-m_hXBIk-.js} +4 -4
  148. package/dist/{memory-cli-C6ocXZHW.js → memory-cli-yvsbLFgi.js} +15 -14
  149. package/dist/{message-channel-7mpcAPwa.js → message-channel-DOpIvru6.js} +34 -2
  150. package/dist/{model-catalog-B3fDLVsV.js → model-catalog-DtjVcDuN.js} +11 -5
  151. package/dist/{model-picker-V0gt2kzq.js → model-picker-oa-NsQXX.js} +5 -4
  152. package/dist/{models-D9CovevI.js → models-Bi78FQeE.js} +26 -25
  153. package/dist/{models-cli-CQBq_lri.js → models-cli-DUkH_80R.js} +126 -119
  154. package/dist/{models-config-Tnpb1ctj.js → models-config-D_IvpQGa.js} +3 -2
  155. package/dist/{node-cli-Cy9sSHy5.js → node-cli-B1iGQlR9.js} +61 -54
  156. package/dist/{node-command-policy-C9mK2tft.js → node-command-policy-CeKPGmlP.js} +2 -2
  157. package/dist/node-commands-sMomb3e1.js +20 -0
  158. package/dist/{node-service-DB36GYv5.js → node-service-BLMp6VWJ.js} +2 -2
  159. package/dist/{nodes-cli-DEtlooE3.js → nodes-cli-CD9qv7k5.js} +39 -35
  160. package/dist/{nodes-screen-DmJ2G431.js → nodes-screen-X8daVm8e.js} +5 -5
  161. package/dist/{note-DI9vedAF.js → note-C3wyXRP2.js} +2 -2
  162. package/dist/{npm-pack-install-_OjtFm2J.js → npm-pack-install-B0X6q-Co.js} +3 -3
  163. package/dist/{npm-resolution-DzmQqopk.js → npm-resolution-CavQ2ST5.js} +5 -5
  164. package/dist/{oauth-env-DKoO0B8-.js → oauth-env-9SRuwpTK.js} +1 -1
  165. package/dist/{oauth-tls-preflight-Dzh0FiLy.js → oauth-tls-preflight-C_9v9ytQ.js} +2 -2
  166. package/dist/{onboard-B_1mmscr.js → onboard-Dgav6iT6.js} +17 -17
  167. package/dist/{onboard-auth.credentials-CtuA7DuT.js → onboard-auth.credentials-CMsut-0h.js} +4 -3
  168. package/dist/{onboard-channels-C1ZeD4r3.js → onboard-channels-oAN4ja4v.js} +26 -25
  169. package/dist/{onboard-custom-BU2l3aiF.js → onboard-custom-B3RIFmaw.js} +7 -7
  170. package/dist/{onboard-helpers-Dtu3-e93.js → onboard-helpers-BkwNJPNU.js} +12 -12
  171. package/dist/{onboard-hooks-w-a3FVVK.js → onboard-hooks-BRCGmt7Q.js} +12 -11
  172. package/dist/{onboard-remote-C-HD7hQU.js → onboard-remote-CE5v5J2R.js} +5 -5
  173. package/dist/{onboard-skills-DvgdlwqH.js → onboard-skills-DD5L2MsA.js} +5 -5
  174. package/dist/{onboarding-DozRyXTe.js → onboarding-gbgi-zx9.js} +23 -23
  175. package/dist/{onboarding.finalize-BfSNnhpS.js → onboarding.finalize-dk1j3ozb.js} +135 -128
  176. package/dist/{onboarding.gateway-config-C02W81hD.js → onboarding.gateway-config-DNQfWDVc.js} +39 -34
  177. package/dist/{onboarding.secret-input-BO32ZliB.js → onboarding.secret-input-BDId1_5K.js} +2 -2
  178. package/dist/{openai-codex-model-default-gJryyHmS.js → openai-codex-model-default-EWrFsdir.js} +5 -5
  179. package/dist/{openai-model-default-D2LuX7D-.js → openai-model-default-CcOzYsIQ.js} +3 -3
  180. package/dist/{outbound-CXQEMm6n.js → outbound-DCuHHD3G.js} +8 -8
  181. package/dist/{outbound-attachment-D7sOzAQn.js → outbound-attachment-Bm82Qbyl.js} +3 -3
  182. package/dist/{pairing-cli-BkbpM3Mt.js → pairing-cli-dXCvRk1U.js} +23 -20
  183. package/dist/{pairing-labels-CjKrz2C9.js → pairing-labels-B_3GjgjR.js} +1 -1
  184. package/dist/{pairing-store-nyK6CFoT.js → pairing-store-CXFEv3Gr.js} +5 -5
  185. package/dist/{pairing-token-Tb0YsOGr.js → pairing-token-BIAdQuAM.js} +1 -1
  186. package/dist/{path-alias-guards-CUaIvLOE.js → path-alias-guards-Bz8AnRb7.js} +1 -1
  187. package/dist/{path-env-LTMy-Xkk.js → path-env-CgmdxEc7.js} +1 -1
  188. package/dist/{path-safety-DwIbN_B2.js → path-safety-EkGa1GqP.js} +1 -1
  189. package/dist/{paths-Dr0uMr7v.js → paths-BBXgPm_n.js} +2 -2
  190. package/dist/{paths-0GcCtgXm.js → paths-gTdorMgW.js} +1 -1
  191. package/dist/{pi-embedded-DBn841N-.js → pi-embedded-BHXPs-Ix.js} +24 -24
  192. package/dist/{pi-embedded-DYc6emwb.js → pi-embedded-DvWHP6Nn.js} +24 -24
  193. package/dist/{pi-embedded-helpers-BMC2HFyB.js → pi-embedded-helpers-CCkKNz_h.js} +5 -5
  194. package/dist/{pi-embedded-helpers-DLm1Mtr2.js → pi-embedded-helpers-Ck1qEeMH.js} +3 -3
  195. package/dist/{pi-embedded-helpers-BtnBVL-4.js → pi-embedded-helpers-xIXwvwuE.js} +3 -3
  196. package/dist/{pi-model-discovery-BUP6uy2Q.js → pi-model-discovery-6_opNECD.js} +2 -1
  197. package/dist/pi-model-discovery-runtime-8K2F-Fkl.js +20 -0
  198. package/dist/{pi-tools.before-tool-call.runtime-r5_UoU-W.js → pi-tools.before-tool-call.runtime-BrFKAhWX.js} +16 -13
  199. package/dist/{pi-tools.policy-C_cbrlt5.js → pi-tools.policy-U1G3dAzL.js} +9 -9
  200. package/dist/{plugin-auto-enable-DdGdWKDo.js → plugin-auto-enable-3v7X3qMK.js} +6 -6
  201. package/dist/{plugin-registry-FdOZQF3c.js → plugin-registry-Brz1ypl9.js} +5 -5
  202. package/dist/{plugins-D3Wuignn.js → plugins-CCkC0dRo.js} +7 -6
  203. package/dist/{plugins-cli-CV4ilsn4.js → plugins-cli-DGfFRLeo.js} +123 -116
  204. package/dist/{ports-BZsa4E0e.js → ports-BG0KrTF5.js} +3 -2
  205. package/dist/{ports-B8DmvnDT.js → ports-BxwhTkI2.js} +5 -29
  206. package/dist/ports-lsof-C-KFQ3hh.js +27 -0
  207. package/dist/{probe-D23qt8BT.js → probe-AK77B0YW.js} +4 -4
  208. package/dist/{program-GusnXq4M.js → program-DfJJCEJW.js} +125 -118
  209. package/dist/{progress-DLHMb9Nz.js → progress-DB5E2Y0L.js} +1 -1
  210. package/dist/{prompt-select-styled-B8L90ha2.js → prompt-select-styled-Cm8h3ln5.js} +50 -49
  211. package/dist/{provider-auth-helpers-DCzPHYBh.js → provider-auth-helpers-BWFf-ICH.js} +9 -8
  212. package/dist/{proxy-env-CKBWNd19.js → proxy-env-a_fwG5uV.js} +1 -1
  213. package/dist/{proxy-fetch-CuomJeW8.js → proxy-fetch-B-9MM6tH.js} +1 -1
  214. package/dist/{push-apns-BNjpWCK5.js → push-apns-D7Kl5IlU.js} +6 -6
  215. package/dist/{pw-ai-DbzNFC8m.js → pw-ai-BuJLXHSR.js} +28 -24
  216. package/dist/{pw-ai-pJMhS79V.js → pw-ai-DsYmOxCp.js} +1 -1
  217. package/dist/{pw-ai-C-Sy12jT.js → pw-ai-DweqbnMJ.js} +1 -1
  218. package/dist/{qmd-manager-BuqPkrhL.js → qmd-manager-ChOTfdZQ.js} +14 -13
  219. package/dist/{qr-cli-DCqr6_WR.js → qr-cli-CNV3ou88.js} +8 -7
  220. package/dist/{redact-snapshot-COg8NLLO.js → redact-snapshot-DDgxiqE4.js} +3 -3
  221. package/dist/{register.agent-yjg7wijd.js → register.agent-B6lw56u_.js} +147 -140
  222. package/dist/register.configure-A26LOYA5.js +173 -0
  223. package/dist/{register.maintenance-B1tKJXP8.js → register.maintenance-Bv41DKCC.js} +144 -136
  224. package/dist/{register.message-BJm9UQ1U.js → register.message-BTZUaOa_.js} +119 -112
  225. package/dist/{register.onboard-Si5PW3Ke.js → register.onboard-Cla_XQtJ.js} +47 -43
  226. package/dist/{register.setup-Dgd21xa5.js → register.setup-BO3qmf_4.js} +46 -42
  227. package/dist/{register.status-health-sessions-DijNX4q2.js → register.status-health-sessions-DQxR8MS5.js} +134 -127
  228. package/dist/{register.subclis-RfmNwdNw.js → register.subclis-CasWzZR5.js} +32 -32
  229. package/dist/{registry-CxLUHPLp.js → registry-DnJ84ILp.js} +6 -83
  230. package/dist/{resolve-configured-secret-input-string-ySbc3h26.js → resolve-configured-secret-input-string-D9uWNIsN.js} +2 -2
  231. package/dist/restart-D97MOP8K.js +782 -0
  232. package/dist/{rpc-DaYUgLOy.js → rpc-DyZoASXQ.js} +4 -4
  233. package/dist/run-loop-Zvh_699t.js +224 -0
  234. package/dist/{run-main-t3x2kkjY.js → run-main-CgFUs81l.js} +148 -133
  235. package/dist/{runtime-BkR9qMZk.js → runtime-BBknab-X.js} +6 -5
  236. package/dist/runtime-CvdZtNmJ.js +100 -0
  237. package/dist/{runtime-config-collectors-CCkqshyY.js → runtime-config-collectors-CML7zUqZ.js} +2 -2
  238. package/dist/{runtime-guard-BMUPc-7K.js → runtime-guard-jpG1v0SY.js} +1 -1
  239. package/dist/runtime-whatsapp-login.runtime-COI7KRKp.js +23 -0
  240. package/dist/runtime-whatsapp-outbound.runtime-la1XDkPQ.js +33 -0
  241. package/dist/{sandbox-DN9CY7lp.js → sandbox-DKscghPx.js} +19 -18
  242. package/dist/{sandbox-cli-BoXV0LgP.js → sandbox-cli-CPwPZJBq.js} +52 -48
  243. package/dist/{secrets-cli-CyF7PIF1.js → secrets-cli-BY0IyBZM.js} +31 -26
  244. package/dist/{security-cli-Dyvx1GHA.js → security-cli-CG6OlQ29.js} +66 -61
  245. package/dist/{send-7T5wUQDt.js → send-BSbPEzn5.js} +7 -7
  246. package/dist/{send-Ge3BmrKO.js → send-C2xEPjDg.js} +8 -8
  247. package/dist/{send-DGbx1H-1.js → send-CFNNbHEA.js} +11 -11
  248. package/dist/{send-rLuC3ZNP.js → send-CIW-foVz.js} +7 -7
  249. package/dist/{send-CGAq-Ure.js → send-CZtdjq0Y.js} +20 -20
  250. package/dist/{gateway-cli-D7jJhAZQ.js → server-CG9eco0N.js} +122 -1835
  251. package/dist/{server-BM8Bplbe.js → server-DfSS2w17.js} +36 -32
  252. package/dist/{server-context-B1j20KiF.js → server-context-CcW_Z5sB.js} +15 -15
  253. package/dist/{server-lifecycle-D8uRbSiN.js → server-lifecycle-DWK8vMXD.js} +2 -2
  254. package/dist/{server-middleware-C0e-wReR.js → server-middleware-BtyTo4hI.js} +2 -2
  255. package/dist/{server-node-events-C876mSJD.js → server-node-events-Ck1bPPa5.js} +117 -110
  256. package/dist/{service-BJxGQl0h.js → service-DnXLOpYd.js} +2 -2
  257. package/dist/{session-1LXasKCO.js → session-Dnt2qKJU.js} +4 -4
  258. package/dist/{session-cost-usage-BKD6u4HD.js → session-cost-usage-CBHvFXhD.js} +3 -3
  259. package/dist/{session-utils-CigqosOc.js → session-utils-t4ZmEDMj.js} +9 -8
  260. package/dist/{sessions-Db2DF_68.js → sessions-BkKVGWHa.js} +13 -12
  261. package/dist/{sessions-CwRdJvxU.js → sessions-D6VEpJTN.js} +7 -7
  262. package/dist/{shared-DcKZdze7.js → shared-DKj9yygb.js} +4 -4
  263. package/dist/{skill-commands-BFUWbeCU.js → skill-commands-Dyi0nIIE.js} +8 -8
  264. package/dist/{skill-scanner-B5APVdka.js → skill-scanner-C6efDeWr.js} +2 -2
  265. package/dist/{skills-DjMDgmlj.js → skills-Cp-zTGor.js} +8 -8
  266. package/dist/{skills-cli-CvDeA9Mz.js → skills-cli-BcLVYbwo.js} +19 -16
  267. package/dist/{skills-install-jLz2vwvm.js → skills-install-LXdiRh5j.js} +10 -10
  268. package/dist/{skills-status-CeHRbTXe.js → skills-status-NIhVZfqm.js} +5 -5
  269. package/dist/slash-commands.runtime-Bq0XWi2w.js +28 -0
  270. package/dist/slash-dispatch.runtime-7RhcnuYY.js +119 -0
  271. package/dist/{slash-dispatch.runtime-DLP2IeNv.js → slash-dispatch.runtime-D28-UnsO.js} +6 -6
  272. package/dist/{slash-dispatch.runtime-Vp6IDoCc.js → slash-dispatch.runtime-DzpJjr3K.js} +6 -6
  273. package/dist/slash-skill-commands.runtime-HWFM7WtA.js +34 -0
  274. package/dist/{sqlite-C0jSdAfK.js → sqlite-BOrw_KhN.js} +4 -4
  275. package/dist/stable-node-path-BghYt81T.js +32 -0
  276. package/dist/{status-D3cIxG_a.js → status-DN8lRmcz.js} +40 -40
  277. package/dist/{status-pXeXDUup.js → status-DNPn0STZ.js} +1 -1
  278. package/dist/{status.update-DeJopD-c.js → status.update-Cd4sMxYz.js} +4 -4
  279. package/dist/store-D8F_4CRR.js +701 -0
  280. package/dist/{store-BgCLFtxS.js → store-DCoVH3mG.js} +2 -2
  281. package/dist/{subagent-registry-runtime-COKZwsHd.js → subagent-registry-runtime-Bt-LYyrB.js} +6 -6
  282. package/dist/subagent-registry-runtime-DVd9wO_D.js +119 -0
  283. package/dist/{subagent-registry-runtime-BlAI3eqU.js → subagent-registry-runtime-a7xfwPB8.js} +6 -6
  284. package/dist/{subsystem-Cfn2Pryx.js → subsystem-C6poMade.js} +2 -94
  285. package/dist/{system-cli-GQBIKMxE.js → system-cli-Zu5LiJFn.js} +25 -21
  286. package/dist/{system-run-command-ZDr-0-G2.js → system-run-command-Kw0jxir0.js} +1 -1
  287. package/dist/{systemd-hints-CLH4_-IK.js → systemd-hints-Da4Q7Orc.js} +5 -5
  288. package/dist/{systemd-linger-PnO8ebUK.js → systemd-linger-NLcFYPEu.js} +2 -2
  289. package/dist/{systemd-tpTWQ79a.js → systemd-tjVNbfBk.js} +2 -2
  290. package/dist/{table-D9z5aFl9.js → table-BP6N5EYA.js} +2 -2
  291. package/dist/{tables-Bb1hkkgV.js → tables-D4LxfXpk.js} +2 -2
  292. package/dist/{tailnet-B-wq8YXh.js → tailnet-CInGXmk9.js} +1 -1
  293. package/dist/{tailscale-DOG3cjSj.js → tailscale-DRFhBuh-.js} +1 -1
  294. package/dist/{target-errors-D41KLMCY.js → target-errors-CkcKdefZ.js} +2 -2
  295. package/dist/{tokens-g3GBx2U9.js → tokens-C3eENCf9.js} +1 -1
  296. package/dist/{tool-display-CpQNRadF.js → tool-display-qTfeZx-b.js} +2 -2
  297. package/dist/{tool-images-Bkv3er-8.js → tool-images-BwtNIRsT.js} +2 -2
  298. package/dist/{trash-ChZlaria.js → trash-DHZNy01S.js} +2 -2
  299. package/dist/{tui-BdX0dbMg.js → tui-CW9for1h.js} +18 -18
  300. package/dist/tui-cli-ChrtbCqc.js +91 -0
  301. package/dist/types.secrets-CpVqMFti.js +81 -0
  302. package/dist/{update-BLXj6ysD.js → update-Bb-g7rqr.js} +4 -4
  303. package/dist/{update-cli-lYpdoDyw.js → update-cli-DHGCFiKY.js} +155 -148
  304. package/dist/{update-runner-DtN1XGSv.js → update-runner-BDHtvoca.js} +6 -6
  305. package/dist/web-CCim-JL4.js +123 -0
  306. package/dist/{web-BEuMJbx-.js → web-CREcqhe9.js} +6 -6
  307. package/dist/{web-BvId86u4.js → web-IBqHOVI2.js} +6 -6
  308. package/dist/{webhooks-cli-CvPAdGDn.js → webhooks-cli-C32h-6dI.js} +21 -18
  309. package/dist/{whatsapp-actions-DSjBUB00.js → whatsapp-actions-BZRxKavO.js} +31 -28
  310. package/dist/{widearea-dns-Blh7W-0q.js → widearea-dns-9PZLZ6zk.js} +1 -1
  311. package/dist/{with-timeout-BVwCWUvY.js → with-timeout-DKgjtZv2.js} +6 -43
  312. package/dist/{workspace-BrC46nbq.js → workspace-CedZZfvJ.js} +5 -5
  313. package/dist/{workspace-dirs-Cb43onAl.js → workspace-dirs-BgwJ2Axm.js} +1 -1
  314. package/dist/{ws-ChEZbUss.js → ws-BwH2d97O.js} +2 -2
  315. package/docs/es/concepts/sessions.md +1 -1
  316. package/docs/pt-BR/concepts/sessions.md +1 -1
  317. package/extensions/acpx/package.json +1 -1
  318. package/extensions/bluebubbles/package.json +1 -1
  319. package/extensions/ci-fix-loop/package.json +1 -1
  320. package/extensions/continuous-learning/package.json +1 -1
  321. package/extensions/copilot-proxy/package.json +1 -1
  322. package/extensions/diagnostics-otel/package.json +1 -1
  323. package/extensions/diffs/package.json +1 -1
  324. package/extensions/discord/package.json +1 -1
  325. package/extensions/feishu/package.json +1 -1
  326. package/extensions/flow/package.json +1 -1
  327. package/extensions/google-antigravity-auth/package.json +1 -1
  328. package/extensions/google-gemini-cli-auth/package.json +1 -1
  329. package/extensions/googlechat/node_modules/.bin/openclaw +2 -2
  330. package/extensions/googlechat/package.json +2 -2
  331. package/extensions/imessage/package.json +1 -1
  332. package/extensions/irc/package.json +1 -1
  333. package/extensions/line/package.json +1 -1
  334. package/extensions/llm-task/package.json +1 -1
  335. package/extensions/lobster/package.json +1 -1
  336. package/extensions/matrix/CHANGELOG.md +5 -0
  337. package/extensions/matrix/package.json +1 -1
  338. package/extensions/mattermost/package.json +1 -1
  339. package/extensions/memory-core/node_modules/.bin/openclaw +2 -2
  340. package/extensions/memory-core/package.json +2 -2
  341. package/extensions/memory-lancedb/package.json +1 -1
  342. package/extensions/minimax-portal-auth/package.json +1 -1
  343. package/extensions/msteams/CHANGELOG.md +5 -0
  344. package/extensions/msteams/package.json +1 -1
  345. package/extensions/nextcloud-talk/package.json +1 -1
  346. package/extensions/nostr/CHANGELOG.md +5 -0
  347. package/extensions/nostr/package.json +1 -1
  348. package/extensions/open-prose/package.json +1 -1
  349. package/extensions/self-improvement/package.json +1 -1
  350. package/extensions/signal/package.json +1 -1
  351. package/extensions/slack/package.json +1 -1
  352. package/extensions/synology-chat/package.json +1 -1
  353. package/extensions/telegram/package.json +1 -1
  354. package/extensions/tlon/package.json +1 -1
  355. package/extensions/twitch/CHANGELOG.md +5 -0
  356. package/extensions/twitch/package.json +1 -1
  357. package/extensions/voice-call/CHANGELOG.md +5 -0
  358. package/extensions/voice-call/package.json +1 -1
  359. package/extensions/whatsapp/package.json +1 -1
  360. package/extensions/zalo/CHANGELOG.md +5 -0
  361. package/extensions/zalo/package.json +1 -1
  362. package/extensions/zalouser/CHANGELOG.md +5 -0
  363. package/extensions/zalouser/package.json +1 -1
  364. package/package.json +2 -2
  365. package/dist/audio-preflight-Bk3KZQei.js +0 -98
  366. package/dist/clawbot-cli-DpO-ZwmI.js +0 -32
  367. package/dist/cli-1p9b3pE_.js +0 -155
  368. package/dist/deliver-runtime-CESEQ4NM.js +0 -59
  369. package/dist/deps-send-discord.runtime-dTfY4NLn.js +0 -34
  370. package/dist/deps-send-imessage.runtime-Cm_XDGKz.js +0 -33
  371. package/dist/deps-send-signal.runtime-9WH9ir2Z.js +0 -32
  372. package/dist/deps-send-slack.runtime-Cx_x379p.js +0 -30
  373. package/dist/deps-send-telegram.runtime-BFHbiOeI.js +0 -36
  374. package/dist/deps-send-whatsapp.runtime-BeJLvpI1.js +0 -117
  375. package/dist/image-runtime-Bq51vNRb.js +0 -53
  376. package/dist/manager-runtime-D2MqM9iK.js +0 -24
  377. package/dist/node-commands-DYz_oQFz.js +0 -12
  378. package/dist/pi-model-discovery-runtime-IFYIuVfT.js +0 -17
  379. package/dist/register.configure-a0uTvfCu.js +0 -166
  380. package/dist/runtime-whatsapp-login.runtime-CQLsSWjA.js +0 -20
  381. package/dist/runtime-whatsapp-outbound.runtime-DoZi3gnM.js +0 -40
  382. package/dist/slash-commands.runtime-Ckcj6TnD.js +0 -25
  383. package/dist/slash-dispatch.runtime-B5ykjP8B.js +0 -112
  384. package/dist/slash-skill-commands.runtime-DbzbD-ZQ.js +0 -31
  385. package/dist/subagent-registry-runtime-Bjh1H1uK.js +0 -112
  386. package/dist/tui-cli-C9UujwTv.js +0 -86
  387. package/dist/web-C14E8nHS.js +0 -116
  388. /package/dist/{allow-from-Do0aB7F6.js → allow-from-D5r7UcQr.js} +0 -0
  389. /package/dist/{boolean-DtWR5bt3.js → boolean-ydSOedIP.js} +0 -0
  390. /package/dist/{brew-sUdeII-D.js → brew-Djs-Lc5s.js} +0 -0
  391. /package/dist/{chat-envelope-CrWMMV_a.js → chat-envelope-DVKDDTSu.js} +0 -0
  392. /package/dist/{cli-utils-DK6017OO.js → cli-utils-CCaEbxAz.js} +0 -0
  393. /package/dist/{command-format-CLEQe4bk.js → command-format-MESnUO9S.js} +0 -0
  394. /package/dist/{command-options-j8s8APBQ.js → command-options-ZvhOayEd.js} +0 -0
  395. /package/dist/{command-poll-backoff-Cse56OCv.js → command-poll-backoff-Dal4OaUV.js} +0 -0
  396. /package/dist/{constants-BgSj-mRP.js → constants-CkIxhEvX.js} +0 -0
  397. /package/dist/{context-window-guard-BgcfPYTd.js → context-window-guard-BUJ2pfYi.js} +0 -0
  398. /package/dist/{daemon-runtime-VfkpXuRu.js → daemon-runtime-CbyS9Xgu.js} +0 -0
  399. /package/dist/{dangerous-name-matching-BAJAZtyB.js → dangerous-name-matching-PRkNIyQj.js} +0 -0
  400. /package/dist/{dangerous-tools-DjOwyW3J.js → dangerous-tools-B9LIt3MU.js} +0 -0
  401. /package/dist/{entry-status-DVwZos2N.js → entry-status-4cDL0OcK.js} +0 -0
  402. /package/dist/{fetch-timeout-BL0dTnkh.js → fetch-timeout-EpWPz-Eu.js} +0 -0
  403. /package/dist/{format-C-890_pY.js → format-DVLB9DNB.js} +0 -0
  404. /package/dist/{format-duration-BvkrOKhT.js → format-duration-CrBESKOT.js} +0 -0
  405. /package/dist/{format-relative-8cNYQsqb.js → format-relative-BsYuWm-Q.js} +0 -0
  406. /package/dist/{health-format-CqfOHMzL.js → health-format-BIotQmMH.js} +0 -0
  407. /package/dist/{heartbeat-visibility-_K4bnQDH.js → heartbeat-visibility-C_P1yurK.js} +0 -0
  408. /package/dist/{help-format-ncfKj8zq.js → help-format-Ce4Xueed.js} +0 -0
  409. /package/dist/{helpers-5EH85AYF.js → helpers-CpIyUra4.js} +0 -0
  410. /package/dist/{input-provenance-ByYWugDu.js → input-provenance-qgaZGYuK.js} +0 -0
  411. /package/dist/{json-files-UKlMS7yU.js → json-files-BH1UBATr.js} +0 -0
  412. /package/dist/{kill-tree-CeEi7v61.js → kill-tree-W9BwtYuE.js} +0 -0
  413. /package/dist/{legacy-names-D3aIn6ij.js → legacy-names-DV-6rguu.js} +0 -0
  414. /package/dist/{load-options-CLMiD1a9.js → load-options-BuY2PXsl.js} +0 -0
  415. /package/dist/{logging-DRwtiLIS.js → logging-kuFzZMsG.js} +0 -0
  416. /package/dist/{model-param-b-NJsgH2EF.js → model-param-b-4PN786ZX.js} +0 -0
  417. /package/dist/{mutable-allowlist-detectors-DiZDtmlZ.js → mutable-allowlist-detectors-TCG6mnbz.js} +0 -0
  418. /package/dist/{node-resolve-C8bjtxQk.js → node-resolve-DSu0lzHd.js} +0 -0
  419. /package/dist/{onboard-config-DFLATNN1.js → onboard-config-YMJ1PLAF.js} +0 -0
  420. /package/dist/{onboard-provider-auth-flags-CpVNpwzI.js → onboard-provider-auth-flags-DHzbi9kj.js} +0 -0
  421. /package/dist/{openclaw-root-BFfBQ6FD.js → openclaw-root-T5G2ldGE.js} +0 -0
  422. /package/dist/{parse-log-line-DxFrnzNo.js → parse-log-line-BrrE4onI.js} +0 -0
  423. /package/dist/{parse-port-CboE2EQm.js → parse-port-DjjWDROB.js} +0 -0
  424. /package/dist/{parse-timeout-uTDpUWKR.js → parse-timeout-BS3EWcf6.js} +0 -0
  425. /package/dist/{polls-D86s6oEI.js → polls-QrTzhQf5.js} +0 -0
  426. /package/dist/{program-context-DQD9Uf8U.js → program-context-BqyLhTGk.js} +0 -0
  427. /package/dist/{prompt-style-C1jf_-k5.js → prompt-style-DB_OyH4q.js} +0 -0
  428. /package/dist/{prompts-GoDC3iAV.js → prompts-DomsZukd.js} +0 -0
  429. /package/dist/{provider-env-vars-D3-Jf8PX.js → provider-env-vars-DYZiYet-.js} +0 -0
  430. /package/dist/{proxy-BNFyBgvu.js → proxy-CUsDSClP.js} +0 -0
  431. /package/dist/{redact-BsCSVGmT.js → redact-B1GVGbib.js} +0 -0
  432. /package/dist/{render-scQFEkLe.js → render-CUAKPmvZ.js} +0 -0
  433. /package/dist/{run-with-concurrency-CzLnwXXV.js → run-with-concurrency-CLARJMM7.js} +0 -0
  434. /package/dist/{runtime-status-CL_bKfj_.js → runtime-status-Fmu5gNYW.js} +0 -0
  435. /package/dist/{secret-equal-DxKrAcRs.js → secret-equal-BN0idTaZ.js} +0 -0
  436. /package/dist/{secure-random-CruxVpoI.js → secure-random-B2UrD2xa.js} +0 -0
  437. /package/dist/{session-key-k6urs9r-.js → session-key-CC77ya0a.js} +0 -0
  438. /package/dist/{stagger-DW-U0kcV.js → stagger-Cek4Eizw.js} +0 -0
  439. /package/dist/{targets-CwCifSLG.js → targets-CD5AQXRB.js} +0 -0
  440. /package/dist/{targets-xSi-e-_L.js → targets-DPUt073v.js} +0 -0
  441. /package/dist/{text-format-CFm4X8Ze.js → text-format-DarxU3JH.js} +0 -0
  442. /package/dist/{thinking-RV_E8HFV.js → thinking-C0gzzPsv.js} +0 -0
  443. /package/dist/{timeouts-G9Yto-nj.js → timeouts-DEnpCqGd.js} +0 -0
  444. /package/dist/{tool-catalog-omkiks3D.js → tool-catalog-3w4XiWhy.js} +0 -0
  445. /package/dist/{transcript-events-CtWhopMu.js → transcript-events-CdWLIofg.js} +0 -0
  446. /package/dist/{usage-format-BMWvYDjj.js → usage-format-zuuFSdkg.js} +0 -0
  447. /package/dist/{utils-cwpAMi-t.js → utils-BnC3HGtm.js} +0 -0
  448. /package/dist/{version-DdJhsIqk.js → version-DT-JIO28.js} +0 -0
  449. /package/dist/{windows-spawn-CsdZOQMr.js → windows-spawn-CVnPunjY.js} +0 -0
  450. /package/dist/{wsl-Cx5T6MYb.js → wsl-DLw4LET-.js} +0 -0
@@ -0,0 +1,1436 @@
1
+ import { d as colorize, f as isRich, p as theme, s as setVerbose } from "./globals-d3aR1MYC.js";
2
+ import { g as resolveStateDir, t as CONFIG_PATH, u as resolveGatewayPort } from "./paths-BMo6kTge.js";
3
+ import { n as defaultRuntime } from "./runtime-CvdZtNmJ.js";
4
+ import { a as setConsoleSubsystemFilter, o as setConsoleTimestampPrefix, t as createSubsystemLogger } from "./subsystem-C6poMade.js";
5
+ import "./boolean-ydSOedIP.js";
6
+ import "./store-D8F_4CRR.js";
7
+ import { G as writeConfigFile, R as createConfigIO, V as readConfigFileSnapshot, z as loadConfig } from "./auth-profiles-BtxyXCZY.js";
8
+ import { t as formatCliCommand } from "./command-format-MESnUO9S.js";
9
+ import { A as resolveDefaultAgentWorkspaceDir, j as resolveWorkspaceTemplateDir } from "./agent-scope-BcruZHHR.js";
10
+ import { v as resolveUserPath, x as shortenHomePath } from "./utils-BnC3HGtm.js";
11
+ import "./openclaw-root-T5G2ldGE.js";
12
+ import "./logger-DyQjakwH.js";
13
+ import "./exec-B8Hv4Nkd.js";
14
+ import { a as hasConfiguredSecretInput } from "./types.secrets-CpVqMFti.js";
15
+ import "./github-copilot-token-BKQ4nXAw.js";
16
+ import "./manifest-registry-m_hXBIk-.js";
17
+ import "./version-DT-JIO28.js";
18
+ import "./registry-DnJ84ILp.js";
19
+ import "./ip-C7WWCRN7.js";
20
+ import "./dock-nMBfeGKa.js";
21
+ import "./tokens-C3eENCf9.js";
22
+ import "./compact-CuLMew-8.js";
23
+ import "./accounts-C04lw_uh.js";
24
+ import "./plugins-CCkC0dRo.js";
25
+ import "./logging-kuFzZMsG.js";
26
+ import "./send-CIW-foVz.js";
27
+ import "./send-CFNNbHEA.js";
28
+ import "./machine-name-BWZ0tBHk.js";
29
+ import "./deliver-Bge0HwrF.js";
30
+ import "./diagnostic-CXxZq_XY.js";
31
+ import "./restart-D97MOP8K.js";
32
+ import "./accounts-CtzU1wJb.js";
33
+ import "./image-ops-Bnk-bI_x.js";
34
+ import "./send-CZtdjq0Y.js";
35
+ import "./pi-model-discovery-6_opNECD.js";
36
+ import { g as GATEWAY_CLIENT_NAMES, h as GATEWAY_CLIENT_MODES } from "./message-channel-DOpIvru6.js";
37
+ import "./pi-embedded-helpers-CCkKNz_h.js";
38
+ import "./sandbox-DKscghPx.js";
39
+ import "./tool-catalog-3w4XiWhy.js";
40
+ import "./chrome-D4EfbMKb.js";
41
+ import "./tailscale-DRFhBuh-.js";
42
+ import { n as pickPrimaryTailnetIPv4 } from "./tailnet-CInGXmk9.js";
43
+ import "./ws-BwH2d97O.js";
44
+ import { a as resolveGatewayAuth } from "./auth-CWHo884l.js";
45
+ import "./server-context-CcW_Z5sB.js";
46
+ import "./frontmatter-B0viix_h.js";
47
+ import "./skills-Cp-zTGor.js";
48
+ import "./path-alias-guards-Bz8AnRb7.js";
49
+ import "./paths-BBXgPm_n.js";
50
+ import "./redact-B1GVGbib.js";
51
+ import { o as isErrno } from "./errors-ClLWB67m.js";
52
+ import "./fs-safe-CFIinCN2.js";
53
+ import "./proxy-env-a_fwG5uV.js";
54
+ import "./store-DCoVH3mG.js";
55
+ import { a as formatPortDiagnostics, n as inspectPortUsage, t as ensurePortAvailable } from "./ports-BxwhTkI2.js";
56
+ import "./ports-lsof-C-KFQ3hh.js";
57
+ import "./trash-DHZNy01S.js";
58
+ import "./server-middleware-BtyTo4hI.js";
59
+ import "./sessions-BkKVGWHa.js";
60
+ import "./accounts-BVV0eCmx.js";
61
+ import "./paths-gTdorMgW.js";
62
+ import "./chat-envelope-DVKDDTSu.js";
63
+ import "./tool-images-BwtNIRsT.js";
64
+ import "./thinking-C0gzzPsv.js";
65
+ import "./models-config-D_IvpQGa.js";
66
+ import "./exec-approvals-allowlist-dlIMsRq0.js";
67
+ import "./exec-safe-bin-runtime-policy-Ds-cMyOt.js";
68
+ import "./model-catalog-DtjVcDuN.js";
69
+ import "./fetch-BPh3R9xH.js";
70
+ import "./audio-transcription-runner-bvBQs8UB.js";
71
+ import "./fetch-guard-hL-C2yQz.js";
72
+ import "./image-m1GU1uco.js";
73
+ import "./tool-display-qTfeZx-b.js";
74
+ import "./api-key-rotation-C0toONXd.js";
75
+ import "./proxy-fetch-B-9MM6tH.js";
76
+ import "./ir-BjnGKA2N.js";
77
+ import "./render-CUAKPmvZ.js";
78
+ import "./target-errors-CkcKdefZ.js";
79
+ import "./commands-BoGUirwW.js";
80
+ import "./commands-registry-Dn_5_JYs.js";
81
+ import "./session-cost-usage-CBHvFXhD.js";
82
+ import "./sqlite-BOrw_KhN.js";
83
+ import "./device-identity-DtdLP7QQ.js";
84
+ import "./client-Bvvecv3V.js";
85
+ import { n as callGateway } from "./call-DL23sPxF.js";
86
+ import "./pairing-token-BIAdQuAM.js";
87
+ import "./fetch-DyJnPUwL.js";
88
+ import "./pairing-store-CXFEv3Gr.js";
89
+ import "./exec-approvals-Bh1osORd.js";
90
+ import "./nodes-screen-X8daVm8e.js";
91
+ import "./system-run-command-Kw0jxir0.js";
92
+ import "./session-utils-t4ZmEDMj.js";
93
+ import { n as formatTokenCount, r as formatUsd } from "./usage-format-zuuFSdkg.js";
94
+ import "./skill-commands-Dyi0nIIE.js";
95
+ import "./pi-tools.policy-U1G3dAzL.js";
96
+ import "./workspace-dirs-BgwJ2Axm.js";
97
+ import "./channel-activity-DItBzFyQ.js";
98
+ import "./tables-D4LxfXpk.js";
99
+ import "./server-lifecycle-DWK8vMXD.js";
100
+ import "./with-timeout-DKgjtZv2.js";
101
+ import "./stagger-Cek4Eizw.js";
102
+ import "./channel-selection-BnXQH0vV.js";
103
+ import "./plugin-auto-enable-3v7X3qMK.js";
104
+ import "./send-C2xEPjDg.js";
105
+ import "./outbound-attachment-Bm82Qbyl.js";
106
+ import "./delivery-queue-BVKd_xSI.js";
107
+ import "./send-BSbPEzn5.js";
108
+ import "./proxy-CUsDSClP.js";
109
+ import "./timeouts-DEnpCqGd.js";
110
+ import "./runtime-config-collectors-CML7zUqZ.js";
111
+ import "./command-secret-targets-C382v6Qd.js";
112
+ import { c as handleReset } from "./onboard-helpers-BkwNJPNU.js";
113
+ import "./prompt-style-DB_OyH4q.js";
114
+ import "./pairing-labels-B_3GjgjR.js";
115
+ import "./memory-cli-yvsbLFgi.js";
116
+ import "./manager-BVqjeGyT.js";
117
+ import { t as formatDocsLink } from "./links-DZZ9QxWA.js";
118
+ import { n as runCommandWithRuntime } from "./cli-utils-CCaEbxAz.js";
119
+ import { t as formatHelpExamples } from "./help-format-Ce4Xueed.js";
120
+ import { n as withProgress } from "./progress-DB5E2Y0L.js";
121
+ import "./skills-status-NIhVZfqm.js";
122
+ import "./path-env-CgmdxEc7.js";
123
+ import "./dangerous-tools-B9LIt3MU.js";
124
+ import { n as inheritOptionFromParent } from "./command-options-ZvhOayEd.js";
125
+ import "./agents.config-OuZqDEe6.js";
126
+ import "./install-safe-path-BxdyoAni.js";
127
+ import "./skill-scanner-C6efDeWr.js";
128
+ import "./issue-format-BMPYbT1P.js";
129
+ import "./status-DNPn0STZ.js";
130
+ import "./channels-status-issues-DXNaEL8i.js";
131
+ import "./redact-snapshot-DDgxiqE4.js";
132
+ import "./daemon-install-helpers-BtOiCRD1.js";
133
+ import "./runtime-guard-jpG1v0SY.js";
134
+ import "./gateway-install-token-olAkdWwV.js";
135
+ import "./systemd-tjVNbfBk.js";
136
+ import "./service-DnXLOpYd.js";
137
+ import "./lifecycle-core-fN_BonzB.js";
138
+ import "./systemd-hints-Da4Q7Orc.js";
139
+ import { t as parsePort$1 } from "./parse-port-DjjWDROB.js";
140
+ import { n as addGatewayServiceCommands } from "./daemon-cli-C6ZVajFI.js";
141
+ import { t as probeGateway } from "./probe-AK77B0YW.js";
142
+ import "./diagnostics-GQuagqCt.js";
143
+ import "./table-BP6N5EYA.js";
144
+ import { n as resolveWideAreaDiscoveryDomain } from "./widearea-dns-9PZLZ6zk.js";
145
+ import { i as toOptionString, n as extractGatewayMiskeys, r as maybeExplainGatewayServiceStop, t as describeUnknownError } from "./shared-DKj9yygb.js";
146
+ import { t as discoverGatewayBeacons } from "./bonjour-discovery-C1SH2QqR.js";
147
+ import { t as resolveConfiguredSecretInputString } from "./resolve-configured-secret-input-string-D9uWNIsN.js";
148
+ import { i as pickGatewaySelfPresence } from "./status-DN8lRmcz.js";
149
+ import { a as styleHealthChannelLine, t as formatHealthChannelLines } from "./health-Cs-k6kLT.js";
150
+ import { n as startGatewayServer } from "./server-CG9eco0N.js";
151
+ import "./control-ui-assets-Co9rmXkB.js";
152
+ import "./channel-account-context-DGbGZhGz.js";
153
+ import "./runtime-BBknab-X.js";
154
+ import "./onboarding.secret-input-BDId1_5K.js";
155
+ import "./onboarding-gbgi-zx9.js";
156
+ import { p as setGatewayWsLogStyle } from "./push-apns-D7Kl5IlU.js";
157
+ import "./gmail-setup-utils-DuoBM8ed.js";
158
+ import "./node-command-policy-CeKPGmlP.js";
159
+ import "./audit-BWNRwu8g.js";
160
+ import "./node-service-BLMp6VWJ.js";
161
+ import "./status.update-Cd4sMxYz.js";
162
+ import "./skills-install-LXdiRh5j.js";
163
+ import "./update-runner-BDHtvoca.js";
164
+ import { t as GatewayLockError } from "./gateway-lock-DNpln_70.js";
165
+ import "./workspace-CedZZfvJ.js";
166
+ import { n as forceFreePortAndWait, r as waitForPortBindable } from "./ports-BG0KrTF5.js";
167
+ import { t as runGatewayLoop } from "./run-loop-Zvh_699t.js";
168
+ import { spawn } from "node:child_process";
169
+ import os from "node:os";
170
+ import path from "node:path";
171
+ import fs from "node:fs";
172
+ import net from "node:net";
173
+
174
+ //#region src/infra/ssh-config.ts
175
+ function parsePort(value) {
176
+ if (!value) return;
177
+ const parsed = Number.parseInt(value, 10);
178
+ if (!Number.isFinite(parsed) || parsed <= 0) return;
179
+ return parsed;
180
+ }
181
+ function parseSshConfigOutput(output) {
182
+ const result = { identityFiles: [] };
183
+ const lines = output.split("\n");
184
+ for (const raw of lines) {
185
+ const line = raw.trim();
186
+ if (!line) continue;
187
+ const [key, ...rest] = line.split(/\s+/);
188
+ const value = rest.join(" ").trim();
189
+ if (!key || !value) continue;
190
+ switch (key) {
191
+ case "user":
192
+ result.user = value;
193
+ break;
194
+ case "hostname":
195
+ result.host = value;
196
+ break;
197
+ case "port":
198
+ result.port = parsePort(value);
199
+ break;
200
+ case "identityfile":
201
+ if (value !== "none") result.identityFiles.push(value);
202
+ break;
203
+ default: break;
204
+ }
205
+ }
206
+ return result;
207
+ }
208
+ async function resolveSshConfig(target, opts = {}) {
209
+ const sshPath = "/usr/bin/ssh";
210
+ const args = ["-G"];
211
+ if (target.port > 0 && target.port !== 22) args.push("-p", String(target.port));
212
+ if (opts.identity?.trim()) args.push("-i", opts.identity.trim());
213
+ const userHost = target.user ? `${target.user}@${target.host}` : target.host;
214
+ args.push("--", userHost);
215
+ return await new Promise((resolve) => {
216
+ const child = spawn(sshPath, args, { stdio: [
217
+ "ignore",
218
+ "pipe",
219
+ "ignore"
220
+ ] });
221
+ let stdout = "";
222
+ child.stdout?.setEncoding("utf8");
223
+ child.stdout?.on("data", (chunk) => {
224
+ stdout += String(chunk);
225
+ });
226
+ const timeoutMs = Math.max(200, opts.timeoutMs ?? 800);
227
+ const timer = setTimeout(() => {
228
+ try {
229
+ child.kill("SIGKILL");
230
+ } finally {
231
+ resolve(null);
232
+ }
233
+ }, timeoutMs);
234
+ child.once("error", () => {
235
+ clearTimeout(timer);
236
+ resolve(null);
237
+ });
238
+ child.once("exit", (code) => {
239
+ clearTimeout(timer);
240
+ if (code !== 0 || !stdout.trim()) {
241
+ resolve(null);
242
+ return;
243
+ }
244
+ resolve(parseSshConfigOutput(stdout));
245
+ });
246
+ });
247
+ }
248
+
249
+ //#endregion
250
+ //#region src/infra/ssh-tunnel.ts
251
+ function parseSshTarget(raw) {
252
+ const trimmed = raw.trim().replace(/^ssh\s+/, "");
253
+ if (!trimmed) return null;
254
+ const [userPart, hostPart] = trimmed.includes("@") ? (() => {
255
+ const idx = trimmed.indexOf("@");
256
+ const user = trimmed.slice(0, idx).trim();
257
+ const host = trimmed.slice(idx + 1).trim();
258
+ return [user || void 0, host];
259
+ })() : [void 0, trimmed];
260
+ const colonIdx = hostPart.lastIndexOf(":");
261
+ if (colonIdx > 0 && colonIdx < hostPart.length - 1) {
262
+ const host = hostPart.slice(0, colonIdx).trim();
263
+ const portRaw = hostPart.slice(colonIdx + 1).trim();
264
+ const port = Number.parseInt(portRaw, 10);
265
+ if (!host || !Number.isFinite(port) || port <= 0) return null;
266
+ if (host.startsWith("-")) return null;
267
+ return {
268
+ user: userPart,
269
+ host,
270
+ port
271
+ };
272
+ }
273
+ if (!hostPart) return null;
274
+ if (hostPart.startsWith("-")) return null;
275
+ return {
276
+ user: userPart,
277
+ host: hostPart,
278
+ port: 22
279
+ };
280
+ }
281
+ async function pickEphemeralPort() {
282
+ return await new Promise((resolve, reject) => {
283
+ const server = net.createServer();
284
+ server.once("error", reject);
285
+ server.listen(0, "127.0.0.1", () => {
286
+ const addr = server.address();
287
+ server.close(() => {
288
+ if (!addr || typeof addr === "string") {
289
+ reject(/* @__PURE__ */ new Error("failed to allocate a local port"));
290
+ return;
291
+ }
292
+ resolve(addr.port);
293
+ });
294
+ });
295
+ });
296
+ }
297
+ async function canConnectLocal(port) {
298
+ return await new Promise((resolve) => {
299
+ const socket = net.connect({
300
+ host: "127.0.0.1",
301
+ port
302
+ });
303
+ const done = (ok) => {
304
+ socket.removeAllListeners();
305
+ socket.destroy();
306
+ resolve(ok);
307
+ };
308
+ socket.once("connect", () => done(true));
309
+ socket.once("error", () => done(false));
310
+ socket.setTimeout(250, () => done(false));
311
+ });
312
+ }
313
+ async function waitForLocalListener(port, timeoutMs) {
314
+ const startedAt = Date.now();
315
+ while (Date.now() - startedAt < timeoutMs) {
316
+ if (await canConnectLocal(port)) return;
317
+ await new Promise((r) => setTimeout(r, 50));
318
+ }
319
+ throw new Error(`ssh tunnel did not start listening on localhost:${port}`);
320
+ }
321
+ async function startSshPortForward(opts) {
322
+ const parsed = parseSshTarget(opts.target);
323
+ if (!parsed) throw new Error(`invalid SSH target: ${opts.target}`);
324
+ let localPort = opts.localPortPreferred;
325
+ try {
326
+ await ensurePortAvailable(localPort);
327
+ } catch (err) {
328
+ if (isErrno(err) && err.code === "EADDRINUSE") localPort = await pickEphemeralPort();
329
+ else throw err;
330
+ }
331
+ const userHost = parsed.user ? `${parsed.user}@${parsed.host}` : parsed.host;
332
+ const args = [
333
+ "-N",
334
+ "-L",
335
+ `${localPort}:127.0.0.1:${opts.remotePort}`,
336
+ "-p",
337
+ String(parsed.port),
338
+ "-o",
339
+ "ExitOnForwardFailure=yes",
340
+ "-o",
341
+ "BatchMode=yes",
342
+ "-o",
343
+ "StrictHostKeyChecking=yes",
344
+ "-o",
345
+ "UpdateHostKeys=yes",
346
+ "-o",
347
+ "ConnectTimeout=5",
348
+ "-o",
349
+ "ServerAliveInterval=15",
350
+ "-o",
351
+ "ServerAliveCountMax=3"
352
+ ];
353
+ if (opts.identity?.trim()) args.push("-i", opts.identity.trim());
354
+ args.push("--", userHost);
355
+ const stderr = [];
356
+ const child = spawn("/usr/bin/ssh", args, { stdio: [
357
+ "ignore",
358
+ "ignore",
359
+ "pipe"
360
+ ] });
361
+ child.stderr?.setEncoding("utf8");
362
+ child.stderr?.on("data", (chunk) => {
363
+ const lines = String(chunk).split("\n").map((l) => l.trim()).filter(Boolean);
364
+ stderr.push(...lines);
365
+ });
366
+ const stop = async () => {
367
+ if (child.killed) return;
368
+ child.kill("SIGTERM");
369
+ await new Promise((resolve) => {
370
+ const t = setTimeout(() => {
371
+ try {
372
+ child.kill("SIGKILL");
373
+ } finally {
374
+ resolve();
375
+ }
376
+ }, 1500);
377
+ child.once("exit", () => {
378
+ clearTimeout(t);
379
+ resolve();
380
+ });
381
+ });
382
+ };
383
+ try {
384
+ await Promise.race([waitForLocalListener(localPort, Math.max(250, opts.timeoutMs)), new Promise((_, reject) => {
385
+ child.once("exit", (code, signal) => {
386
+ reject(/* @__PURE__ */ new Error(`ssh exited (${code ?? "null"}${signal ? `/${signal}` : ""})`));
387
+ });
388
+ })]);
389
+ } catch (err) {
390
+ await stop();
391
+ const suffix = stderr.length > 0 ? `\n${stderr.join("\n")}` : "";
392
+ throw new Error(`${err instanceof Error ? err.message : String(err)}${suffix}`, { cause: err });
393
+ }
394
+ return {
395
+ parsedTarget: parsed,
396
+ localPort,
397
+ remotePort: opts.remotePort,
398
+ pid: typeof child.pid === "number" ? child.pid : null,
399
+ stderr,
400
+ stop
401
+ };
402
+ }
403
+
404
+ //#endregion
405
+ //#region src/commands/gateway-status/helpers.ts
406
+ function parseIntOrNull(value) {
407
+ const s = typeof value === "string" ? value.trim() : typeof value === "number" || typeof value === "bigint" ? String(value) : "";
408
+ if (!s) return null;
409
+ const n = Number.parseInt(s, 10);
410
+ return Number.isFinite(n) ? n : null;
411
+ }
412
+ function parseTimeoutMs(raw, fallbackMs) {
413
+ const value = typeof raw === "string" ? raw.trim() : typeof raw === "number" || typeof raw === "bigint" ? String(raw) : "";
414
+ if (!value) return fallbackMs;
415
+ const parsed = Number.parseInt(value, 10);
416
+ if (!Number.isFinite(parsed) || parsed <= 0) throw new Error(`invalid --timeout: ${value}`);
417
+ return parsed;
418
+ }
419
+ function normalizeWsUrl(value) {
420
+ const trimmed = value.trim();
421
+ if (!trimmed) return null;
422
+ if (!trimmed.startsWith("ws://") && !trimmed.startsWith("wss://")) return null;
423
+ return trimmed;
424
+ }
425
+ function resolveTargets(cfg, explicitUrl) {
426
+ const targets = [];
427
+ const add = (t) => {
428
+ if (!targets.some((x) => x.url === t.url)) targets.push(t);
429
+ };
430
+ const explicit = typeof explicitUrl === "string" ? normalizeWsUrl(explicitUrl) : null;
431
+ if (explicit) add({
432
+ id: "explicit",
433
+ kind: "explicit",
434
+ url: explicit,
435
+ active: true
436
+ });
437
+ const remoteUrl = typeof cfg.gateway?.remote?.url === "string" ? normalizeWsUrl(cfg.gateway.remote.url) : null;
438
+ if (remoteUrl) add({
439
+ id: "configRemote",
440
+ kind: "configRemote",
441
+ url: remoteUrl,
442
+ active: cfg.gateway?.mode === "remote"
443
+ });
444
+ add({
445
+ id: "localLoopback",
446
+ kind: "localLoopback",
447
+ url: `ws://127.0.0.1:${resolveGatewayPort(cfg)}`,
448
+ active: cfg.gateway?.mode !== "remote"
449
+ });
450
+ return targets;
451
+ }
452
+ function resolveProbeBudgetMs(overallMs, kind) {
453
+ if (kind === "localLoopback") return Math.min(800, overallMs);
454
+ if (kind === "sshTunnel") return Math.min(2e3, overallMs);
455
+ return Math.min(1500, overallMs);
456
+ }
457
+ function sanitizeSshTarget(value) {
458
+ if (typeof value !== "string") return null;
459
+ const trimmed = value.trim();
460
+ if (!trimmed) return null;
461
+ return trimmed.replace(/^ssh\\s+/, "");
462
+ }
463
+ function readGatewayTokenEnv(env = process.env) {
464
+ return env.OPENCLAW_GATEWAY_TOKEN?.trim() || env.CLAWDBOT_GATEWAY_TOKEN?.trim() || void 0;
465
+ }
466
+ function readGatewayPasswordEnv(env = process.env) {
467
+ return env.OPENCLAW_GATEWAY_PASSWORD?.trim() || env.CLAWDBOT_GATEWAY_PASSWORD?.trim() || void 0;
468
+ }
469
+ async function resolveAuthForTarget(cfg, target, overrides) {
470
+ const tokenOverride = overrides.token?.trim() ? overrides.token.trim() : void 0;
471
+ const passwordOverride = overrides.password?.trim() ? overrides.password.trim() : void 0;
472
+ if (tokenOverride || passwordOverride) return {
473
+ token: tokenOverride,
474
+ password: passwordOverride
475
+ };
476
+ const diagnostics = [];
477
+ const authMode = cfg.gateway?.auth?.mode;
478
+ const tokenOnly = authMode === "token";
479
+ const passwordOnly = authMode === "password";
480
+ const resolveToken = async (value, path) => {
481
+ const tokenResolution = await resolveConfiguredSecretInputString({
482
+ config: cfg,
483
+ env: process.env,
484
+ value,
485
+ path,
486
+ unresolvedReasonStyle: "detailed"
487
+ });
488
+ if (tokenResolution.unresolvedRefReason) diagnostics.push(tokenResolution.unresolvedRefReason);
489
+ return tokenResolution.value;
490
+ };
491
+ const resolvePassword = async (value, path) => {
492
+ const passwordResolution = await resolveConfiguredSecretInputString({
493
+ config: cfg,
494
+ env: process.env,
495
+ value,
496
+ path,
497
+ unresolvedReasonStyle: "detailed"
498
+ });
499
+ if (passwordResolution.unresolvedRefReason) diagnostics.push(passwordResolution.unresolvedRefReason);
500
+ return passwordResolution.value;
501
+ };
502
+ if (target.kind === "configRemote" || target.kind === "sshTunnel") {
503
+ const remoteTokenValue = cfg.gateway?.remote?.token;
504
+ const remotePasswordValue = (cfg.gateway?.remote)?.password;
505
+ const token = await resolveToken(remoteTokenValue, "gateway.remote.token");
506
+ return {
507
+ token,
508
+ password: token ? void 0 : await resolvePassword(remotePasswordValue, "gateway.remote.password"),
509
+ ...diagnostics.length > 0 ? { diagnostics } : {}
510
+ };
511
+ }
512
+ if (authMode === "none" || authMode === "trusted-proxy") return {};
513
+ const envToken = readGatewayTokenEnv();
514
+ const envPassword = readGatewayPasswordEnv();
515
+ if (tokenOnly) {
516
+ if (envToken) return { token: envToken };
517
+ return {
518
+ token: await resolveToken(cfg.gateway?.auth?.token, "gateway.auth.token"),
519
+ ...diagnostics.length > 0 ? { diagnostics } : {}
520
+ };
521
+ }
522
+ if (passwordOnly) {
523
+ if (envPassword) return { password: envPassword };
524
+ return {
525
+ password: await resolvePassword(cfg.gateway?.auth?.password, "gateway.auth.password"),
526
+ ...diagnostics.length > 0 ? { diagnostics } : {}
527
+ };
528
+ }
529
+ if (envToken) return { token: envToken };
530
+ const token = await resolveToken(cfg.gateway?.auth?.token, "gateway.auth.token");
531
+ if (token) return {
532
+ token,
533
+ ...diagnostics.length > 0 ? { diagnostics } : {}
534
+ };
535
+ if (envPassword) return {
536
+ password: envPassword,
537
+ ...diagnostics.length > 0 ? { diagnostics } : {}
538
+ };
539
+ return {
540
+ token,
541
+ password: await resolvePassword(cfg.gateway?.auth?.password, "gateway.auth.password"),
542
+ ...diagnostics.length > 0 ? { diagnostics } : {}
543
+ };
544
+ }
545
+ function extractConfigSummary(snapshotUnknown) {
546
+ const snap = snapshotUnknown;
547
+ const path = typeof snap?.path === "string" ? snap.path : null;
548
+ const exists = Boolean(snap?.exists);
549
+ const valid = Boolean(snap?.valid);
550
+ const issuesRaw = Array.isArray(snap?.issues) ? snap.issues : [];
551
+ const legacyRaw = Array.isArray(snap?.legacyIssues) ? snap.legacyIssues : [];
552
+ const cfg = snap?.config ?? {};
553
+ const gateway = cfg.gateway ?? {};
554
+ const secretDefaults = (cfg.secrets ?? {}).defaults ?? void 0;
555
+ const wideArea = (cfg.discovery ?? {}).wideArea ?? {};
556
+ const remote = gateway.remote ?? {};
557
+ const auth = gateway.auth ?? {};
558
+ const controlUi = gateway.controlUi ?? {};
559
+ const tailscale = gateway.tailscale ?? {};
560
+ const authMode = typeof auth.mode === "string" ? auth.mode : null;
561
+ const authTokenConfigured = hasConfiguredSecretInput(auth.token, secretDefaults);
562
+ const authPasswordConfigured = hasConfiguredSecretInput(auth.password, secretDefaults);
563
+ const remoteUrl = typeof remote.url === "string" ? normalizeWsUrl(remote.url) : null;
564
+ const remoteTokenConfigured = hasConfiguredSecretInput(remote.token, secretDefaults);
565
+ const remotePasswordConfigured = hasConfiguredSecretInput(remote.password, secretDefaults);
566
+ const wideAreaEnabled = typeof wideArea.enabled === "boolean" ? wideArea.enabled : null;
567
+ return {
568
+ path,
569
+ exists,
570
+ valid,
571
+ issues: issuesRaw.filter((i) => Boolean(i && typeof i.path === "string" && typeof i.message === "string")).map((i) => ({
572
+ path: i.path,
573
+ message: i.message
574
+ })),
575
+ legacyIssues: legacyRaw.filter((i) => Boolean(i && typeof i.path === "string" && typeof i.message === "string")).map((i) => ({
576
+ path: i.path,
577
+ message: i.message
578
+ })),
579
+ gateway: {
580
+ mode: typeof gateway.mode === "string" ? gateway.mode : null,
581
+ bind: typeof gateway.bind === "string" ? gateway.bind : null,
582
+ port: parseIntOrNull(gateway.port),
583
+ controlUiEnabled: typeof controlUi.enabled === "boolean" ? controlUi.enabled : null,
584
+ controlUiBasePath: typeof controlUi.basePath === "string" ? controlUi.basePath : null,
585
+ authMode,
586
+ authTokenConfigured,
587
+ authPasswordConfigured,
588
+ remoteUrl,
589
+ remoteTokenConfigured,
590
+ remotePasswordConfigured,
591
+ tailscaleMode: typeof tailscale.mode === "string" ? tailscale.mode : null
592
+ },
593
+ discovery: { wideAreaEnabled }
594
+ };
595
+ }
596
+ function buildNetworkHints(cfg) {
597
+ const tailnetIPv4 = pickPrimaryTailnetIPv4();
598
+ const port = resolveGatewayPort(cfg);
599
+ return {
600
+ localLoopbackUrl: `ws://127.0.0.1:${port}`,
601
+ localTailnetUrl: tailnetIPv4 ? `ws://${tailnetIPv4}:${port}` : null,
602
+ tailnetIPv4: tailnetIPv4 ?? null
603
+ };
604
+ }
605
+ function renderTargetHeader(target, rich) {
606
+ const kindLabel = target.kind === "localLoopback" ? "Local loopback" : target.kind === "sshTunnel" ? "Remote over SSH" : target.kind === "configRemote" ? target.active ? "Remote (configured)" : "Remote (configured, inactive)" : "URL (explicit)";
607
+ return `${colorize(rich, theme.heading, kindLabel)} ${colorize(rich, theme.muted, target.url)}`;
608
+ }
609
+ function renderProbeSummaryLine(probe, rich) {
610
+ if (probe.ok) {
611
+ const latency = typeof probe.connectLatencyMs === "number" ? `${probe.connectLatencyMs}ms` : "unknown";
612
+ return `${colorize(rich, theme.success, "Connect: ok")} (${latency}) · ${colorize(rich, theme.success, "RPC: ok")}`;
613
+ }
614
+ const detail = probe.error ? ` - ${probe.error}` : "";
615
+ if (probe.connectLatencyMs != null) {
616
+ const latency = typeof probe.connectLatencyMs === "number" ? `${probe.connectLatencyMs}ms` : "unknown";
617
+ return `${colorize(rich, theme.success, "Connect: ok")} (${latency}) · ${colorize(rich, theme.error, "RPC: failed")}${detail}`;
618
+ }
619
+ return `${colorize(rich, theme.error, "Connect: failed")}${detail}`;
620
+ }
621
+
622
+ //#endregion
623
+ //#region src/commands/gateway-status.ts
624
+ async function gatewayStatusCommand(opts, runtime) {
625
+ const startedAt = Date.now();
626
+ const cfg = loadConfig();
627
+ const rich = isRich() && opts.json !== true;
628
+ const overallTimeoutMs = parseTimeoutMs(opts.timeout, 3e3);
629
+ const wideAreaDomain = resolveWideAreaDiscoveryDomain({ configDomain: cfg.discovery?.wideArea?.domain });
630
+ const baseTargets = resolveTargets(cfg, opts.url);
631
+ const network = buildNetworkHints(cfg);
632
+ const discoveryTimeoutMs = Math.min(1200, overallTimeoutMs);
633
+ const discoveryPromise = discoverGatewayBeacons({
634
+ timeoutMs: discoveryTimeoutMs,
635
+ wideAreaDomain
636
+ });
637
+ let sshTarget = sanitizeSshTarget(opts.ssh) ?? sanitizeSshTarget(cfg.gateway?.remote?.sshTarget);
638
+ let sshIdentity = sanitizeSshTarget(opts.sshIdentity) ?? sanitizeSshTarget(cfg.gateway?.remote?.sshIdentity);
639
+ const remotePort = resolveGatewayPort(cfg);
640
+ let sshTunnelError = null;
641
+ let sshTunnelStarted = false;
642
+ if (!sshTarget) sshTarget = inferSshTargetFromRemoteUrl(cfg.gateway?.remote?.url);
643
+ if (sshTarget) {
644
+ const resolved = await resolveSshTarget(sshTarget, sshIdentity, overallTimeoutMs);
645
+ if (resolved) {
646
+ sshTarget = resolved.target;
647
+ if (!sshIdentity && resolved.identity) sshIdentity = resolved.identity;
648
+ }
649
+ }
650
+ const { discovery, probed } = await withProgress({
651
+ label: "Inspecting gateways…",
652
+ indeterminate: true,
653
+ enabled: opts.json !== true
654
+ }, async () => {
655
+ const tryStartTunnel = async () => {
656
+ if (!sshTarget) return null;
657
+ try {
658
+ const tunnel = await startSshPortForward({
659
+ target: sshTarget,
660
+ identity: sshIdentity ?? void 0,
661
+ localPortPreferred: remotePort,
662
+ remotePort,
663
+ timeoutMs: Math.min(1500, overallTimeoutMs)
664
+ });
665
+ sshTunnelStarted = true;
666
+ return tunnel;
667
+ } catch (err) {
668
+ sshTunnelError = err instanceof Error ? err.message : String(err);
669
+ return null;
670
+ }
671
+ };
672
+ const discoveryTask = discoveryPromise.catch(() => []);
673
+ const tunnelTask = sshTarget ? tryStartTunnel() : Promise.resolve(null);
674
+ const [discovery, tunnelFirst] = await Promise.all([discoveryTask, tunnelTask]);
675
+ if (!sshTarget && opts.sshAuto) {
676
+ const user = process.env.USER?.trim() || "";
677
+ const candidates = discovery.map((b) => {
678
+ const host = b.tailnetDns || b.lanHost || b.host;
679
+ if (!host?.trim()) return null;
680
+ const sshPort = typeof b.sshPort === "number" && b.sshPort > 0 ? b.sshPort : 22;
681
+ const base = user ? `${user}@${host.trim()}` : host.trim();
682
+ return sshPort !== 22 ? `${base}:${sshPort}` : base;
683
+ }).filter((candidate) => Boolean(candidate && parseSshTarget(candidate)));
684
+ if (candidates.length > 0) sshTarget = candidates[0] ?? null;
685
+ }
686
+ const tunnel = tunnelFirst || (sshTarget && !sshTunnelStarted && !sshTunnelError ? await tryStartTunnel() : null);
687
+ const tunnelTarget = tunnel ? {
688
+ id: "sshTunnel",
689
+ kind: "sshTunnel",
690
+ url: `ws://127.0.0.1:${tunnel.localPort}`,
691
+ active: true,
692
+ tunnel: {
693
+ kind: "ssh",
694
+ target: sshTarget ?? "",
695
+ localPort: tunnel.localPort,
696
+ remotePort,
697
+ pid: tunnel.pid
698
+ }
699
+ } : null;
700
+ const targets = tunnelTarget ? [tunnelTarget, ...baseTargets.filter((t) => t.url !== tunnelTarget.url)] : baseTargets;
701
+ try {
702
+ return {
703
+ discovery,
704
+ probed: await Promise.all(targets.map(async (target) => {
705
+ const authResolution = await resolveAuthForTarget(cfg, target, {
706
+ token: typeof opts.token === "string" ? opts.token : void 0,
707
+ password: typeof opts.password === "string" ? opts.password : void 0
708
+ });
709
+ const auth = {
710
+ token: authResolution.token,
711
+ password: authResolution.password
712
+ };
713
+ const timeoutMs = resolveProbeBudgetMs(overallTimeoutMs, target.kind);
714
+ const probe = await probeGateway({
715
+ url: target.url,
716
+ auth,
717
+ timeoutMs
718
+ });
719
+ return {
720
+ target,
721
+ probe,
722
+ configSummary: probe.configSnapshot ? extractConfigSummary(probe.configSnapshot) : null,
723
+ self: pickGatewaySelfPresence(probe.presence),
724
+ authDiagnostics: authResolution.diagnostics ?? []
725
+ };
726
+ }))
727
+ };
728
+ } finally {
729
+ if (tunnel) try {
730
+ await tunnel.stop();
731
+ } catch {}
732
+ }
733
+ });
734
+ const reachable = probed.filter((p) => p.probe.ok);
735
+ const ok = reachable.length > 0;
736
+ const multipleGateways = reachable.length > 1;
737
+ const primary = reachable.find((p) => p.target.kind === "explicit") ?? reachable.find((p) => p.target.kind === "sshTunnel") ?? reachable.find((p) => p.target.kind === "configRemote") ?? reachable.find((p) => p.target.kind === "localLoopback") ?? null;
738
+ const warnings = [];
739
+ if (sshTarget && !sshTunnelStarted) warnings.push({
740
+ code: "ssh_tunnel_failed",
741
+ message: sshTunnelError ? `SSH tunnel failed: ${String(sshTunnelError)}` : "SSH tunnel failed to start; falling back to direct probes."
742
+ });
743
+ if (multipleGateways) warnings.push({
744
+ code: "multiple_gateways",
745
+ message: "Unconventional setup: multiple reachable gateways detected. Usually one gateway per network is recommended unless you intentionally run isolated profiles, like a rescue bot (see docs: /gateway#multiple-gateways-same-host).",
746
+ targetIds: reachable.map((p) => p.target.id)
747
+ });
748
+ for (const result of probed) {
749
+ if (result.authDiagnostics.length === 0) continue;
750
+ for (const diagnostic of result.authDiagnostics) warnings.push({
751
+ code: "auth_secretref_unresolved",
752
+ message: diagnostic,
753
+ targetIds: [result.target.id]
754
+ });
755
+ }
756
+ if (opts.json) {
757
+ runtime.log(JSON.stringify({
758
+ ok,
759
+ ts: Date.now(),
760
+ durationMs: Date.now() - startedAt,
761
+ timeoutMs: overallTimeoutMs,
762
+ primaryTargetId: primary?.target.id ?? null,
763
+ warnings,
764
+ network,
765
+ discovery: {
766
+ timeoutMs: discoveryTimeoutMs,
767
+ count: discovery.length,
768
+ beacons: discovery.map((b) => ({
769
+ instanceName: b.instanceName,
770
+ displayName: b.displayName ?? null,
771
+ domain: b.domain ?? null,
772
+ host: b.host ?? null,
773
+ lanHost: b.lanHost ?? null,
774
+ tailnetDns: b.tailnetDns ?? null,
775
+ gatewayPort: b.gatewayPort ?? null,
776
+ sshPort: b.sshPort ?? null,
777
+ wsUrl: (() => {
778
+ const host = b.tailnetDns || b.lanHost || b.host;
779
+ const port = b.gatewayPort ?? 18789;
780
+ return host ? `ws://${host}:${port}` : null;
781
+ })()
782
+ }))
783
+ },
784
+ targets: probed.map((p) => ({
785
+ id: p.target.id,
786
+ kind: p.target.kind,
787
+ url: p.target.url,
788
+ active: p.target.active,
789
+ tunnel: p.target.tunnel ?? null,
790
+ connect: {
791
+ ok: p.probe.ok,
792
+ latencyMs: p.probe.connectLatencyMs,
793
+ error: p.probe.error,
794
+ close: p.probe.close
795
+ },
796
+ self: p.self,
797
+ config: p.configSummary,
798
+ health: p.probe.health,
799
+ summary: p.probe.status,
800
+ presence: p.probe.presence
801
+ }))
802
+ }, null, 2));
803
+ if (!ok) runtime.exit(1);
804
+ return;
805
+ }
806
+ runtime.log(colorize(rich, theme.heading, "Gateway Status"));
807
+ runtime.log(ok ? `${colorize(rich, theme.success, "Reachable")}: yes` : `${colorize(rich, theme.error, "Reachable")}: no`);
808
+ runtime.log(colorize(rich, theme.muted, `Probe budget: ${overallTimeoutMs}ms`));
809
+ if (warnings.length > 0) {
810
+ runtime.log("");
811
+ runtime.log(colorize(rich, theme.warn, "Warning:"));
812
+ for (const w of warnings) runtime.log(`- ${w.message}`);
813
+ }
814
+ runtime.log("");
815
+ runtime.log(colorize(rich, theme.heading, "Discovery (this machine)"));
816
+ const discoveryDomains = wideAreaDomain ? `local. + ${wideAreaDomain}` : "local.";
817
+ runtime.log(discovery.length > 0 ? `Found ${discovery.length} gateway(s) via Bonjour (${discoveryDomains})` : `Found 0 gateways via Bonjour (${discoveryDomains})`);
818
+ if (discovery.length === 0) runtime.log(colorize(rich, theme.muted, "Tip: if the gateway is remote, mDNS won’t cross networks; use Wide-Area Bonjour (split DNS) or SSH tunnels."));
819
+ runtime.log("");
820
+ runtime.log(colorize(rich, theme.heading, "Targets"));
821
+ for (const p of probed) {
822
+ runtime.log(renderTargetHeader(p.target, rich));
823
+ runtime.log(` ${renderProbeSummaryLine(p.probe, rich)}`);
824
+ if (p.target.tunnel?.kind === "ssh") runtime.log(` ${colorize(rich, theme.muted, "ssh")}: ${colorize(rich, theme.command, p.target.tunnel.target)}`);
825
+ if (p.probe.ok && p.self) {
826
+ const host = p.self.host ?? "unknown";
827
+ const ip = p.self.ip ? ` (${p.self.ip})` : "";
828
+ const platform = p.self.platform ? ` · ${p.self.platform}` : "";
829
+ const version = p.self.version ? ` · app ${p.self.version}` : "";
830
+ runtime.log(` ${colorize(rich, theme.info, "Gateway")}: ${host}${ip}${platform}${version}`);
831
+ }
832
+ if (p.configSummary) {
833
+ const c = p.configSummary;
834
+ const wideArea = c.discovery.wideAreaEnabled === true ? "enabled" : c.discovery.wideAreaEnabled === false ? "disabled" : "unknown";
835
+ runtime.log(` ${colorize(rich, theme.info, "Wide-area discovery")}: ${wideArea}`);
836
+ }
837
+ runtime.log("");
838
+ }
839
+ if (!ok) runtime.exit(1);
840
+ }
841
+ function inferSshTargetFromRemoteUrl(rawUrl) {
842
+ if (typeof rawUrl !== "string") return null;
843
+ const trimmed = rawUrl.trim();
844
+ if (!trimmed) return null;
845
+ let host = null;
846
+ try {
847
+ host = new URL(trimmed).hostname || null;
848
+ } catch {
849
+ return null;
850
+ }
851
+ if (!host) return null;
852
+ const user = process.env.USER?.trim() || "";
853
+ return user ? `${user}@${host}` : host;
854
+ }
855
+ function buildSshTarget(input) {
856
+ const host = input.host?.trim() ?? "";
857
+ if (!host) return null;
858
+ const user = input.user?.trim() ?? "";
859
+ const base = user ? `${user}@${host}` : host;
860
+ const port = input.port ?? 22;
861
+ if (port && port !== 22) return `${base}:${port}`;
862
+ return base;
863
+ }
864
+ async function resolveSshTarget(rawTarget, identity, overallTimeoutMs) {
865
+ const parsed = parseSshTarget(rawTarget);
866
+ if (!parsed) return null;
867
+ const config = await resolveSshConfig(parsed, {
868
+ identity: identity ?? void 0,
869
+ timeoutMs: Math.min(800, overallTimeoutMs)
870
+ });
871
+ if (!config) return {
872
+ target: rawTarget,
873
+ identity: identity ?? void 0
874
+ };
875
+ const target = buildSshTarget({
876
+ user: config.user ?? parsed.user,
877
+ host: config.host ?? parsed.host,
878
+ port: config.port ?? parsed.port
879
+ });
880
+ if (!target) return {
881
+ target: rawTarget,
882
+ identity: identity ?? void 0
883
+ };
884
+ return {
885
+ target,
886
+ identity: identity ?? config.identityFiles.find((entry) => entry.trim().length > 0)?.trim() ?? void 0
887
+ };
888
+ }
889
+
890
+ //#endregion
891
+ //#region src/cli/gateway-cli/call.ts
892
+ const gatewayCallOpts = (cmd) => cmd.option("--url <url>", "Gateway WebSocket URL (defaults to gateway.remote.url when configured)").option("--token <token>", "Gateway token (if required)").option("--password <password>", "Gateway password (password auth)").option("--timeout <ms>", "Timeout in ms", "10000").option("--expect-final", "Wait for final response (agent)", false).option("--json", "Output JSON", false);
893
+ const callGatewayCli = async (method, opts, params) => withProgress({
894
+ label: `Gateway ${method}`,
895
+ indeterminate: true,
896
+ enabled: opts.json !== true
897
+ }, async () => await callGateway({
898
+ url: opts.url,
899
+ token: opts.token,
900
+ password: opts.password,
901
+ method,
902
+ params,
903
+ expectFinal: Boolean(opts.expectFinal),
904
+ timeoutMs: Number(opts.timeout ?? 1e4),
905
+ clientName: GATEWAY_CLIENT_NAMES.CLI,
906
+ mode: GATEWAY_CLIENT_MODES.CLI
907
+ }));
908
+
909
+ //#endregion
910
+ //#region src/cli/gateway-cli/discover.ts
911
+ function parseDiscoverTimeoutMs(raw, fallbackMs) {
912
+ if (raw === void 0 || raw === null) return fallbackMs;
913
+ const value = typeof raw === "string" ? raw.trim() : typeof raw === "number" || typeof raw === "bigint" ? String(raw) : null;
914
+ if (value === null) throw new Error("invalid --timeout");
915
+ if (!value) return fallbackMs;
916
+ const parsed = Number.parseInt(value, 10);
917
+ if (!Number.isFinite(parsed) || parsed <= 0) throw new Error(`invalid --timeout: ${value}`);
918
+ return parsed;
919
+ }
920
+ function pickBeaconHost(beacon) {
921
+ const host = beacon.host || beacon.tailnetDns || beacon.lanHost;
922
+ return host?.trim() ? host.trim() : null;
923
+ }
924
+ function pickGatewayPort(beacon) {
925
+ const port = beacon.port ?? beacon.gatewayPort ?? 18789;
926
+ return port > 0 ? port : 18789;
927
+ }
928
+ function dedupeBeacons(beacons) {
929
+ const out = [];
930
+ const seen = /* @__PURE__ */ new Set();
931
+ for (const b of beacons) {
932
+ const host = pickBeaconHost(b) ?? "";
933
+ const key = [
934
+ b.domain ?? "",
935
+ b.instanceName ?? "",
936
+ b.displayName ?? "",
937
+ host,
938
+ String(b.port ?? ""),
939
+ String(b.gatewayPort ?? "")
940
+ ].join("|");
941
+ if (seen.has(key)) continue;
942
+ seen.add(key);
943
+ out.push(b);
944
+ }
945
+ return out;
946
+ }
947
+ function renderBeaconLines(beacon, rich) {
948
+ const nameRaw = (beacon.displayName || beacon.instanceName || "Gateway").trim();
949
+ const domainRaw = (beacon.domain || "local.").trim();
950
+ const title = colorize(rich, theme.accentBright, nameRaw);
951
+ const domain = colorize(rich, theme.muted, domainRaw);
952
+ const host = pickBeaconHost(beacon);
953
+ const gatewayPort = pickGatewayPort(beacon);
954
+ const scheme = beacon.gatewayTls ? "wss" : "ws";
955
+ const wsUrl = host ? `${scheme}://${host}:${gatewayPort}` : null;
956
+ const lines = [`- ${title} ${domain}`];
957
+ if (beacon.tailnetDns) lines.push(` ${colorize(rich, theme.info, "tailnet")}: ${beacon.tailnetDns}`);
958
+ if (beacon.lanHost) lines.push(` ${colorize(rich, theme.info, "lan")}: ${beacon.lanHost}`);
959
+ if (beacon.host) lines.push(` ${colorize(rich, theme.info, "host")}: ${beacon.host}`);
960
+ if (wsUrl) lines.push(` ${colorize(rich, theme.muted, "ws")}: ${colorize(rich, theme.command, wsUrl)}`);
961
+ if (beacon.role) lines.push(` ${colorize(rich, theme.muted, "role")}: ${beacon.role}`);
962
+ if (beacon.transport) lines.push(` ${colorize(rich, theme.muted, "transport")}: ${beacon.transport}`);
963
+ if (beacon.gatewayTls) {
964
+ const fingerprint = beacon.gatewayTlsFingerprintSha256 ? `sha256 ${beacon.gatewayTlsFingerprintSha256}` : "enabled";
965
+ lines.push(` ${colorize(rich, theme.muted, "tls")}: ${fingerprint}`);
966
+ }
967
+ if (typeof beacon.sshPort === "number" && beacon.sshPort > 0 && host) {
968
+ const ssh = `ssh -N -L 18789:127.0.0.1:18789 <user>@${host} -p ${beacon.sshPort}`;
969
+ lines.push(` ${colorize(rich, theme.muted, "ssh")}: ${colorize(rich, theme.command, ssh)}`);
970
+ }
971
+ return lines;
972
+ }
973
+
974
+ //#endregion
975
+ //#region src/cli/gateway-cli/dev.ts
976
+ const DEV_IDENTITY_NAME = "C3-PO";
977
+ const DEV_IDENTITY_THEME = "protocol droid";
978
+ const DEV_IDENTITY_EMOJI = "🤖";
979
+ const DEV_AGENT_WORKSPACE_SUFFIX = "dev";
980
+ async function loadDevTemplate(name, fallback) {
981
+ try {
982
+ const templateDir = await resolveWorkspaceTemplateDir();
983
+ const raw = await fs.promises.readFile(path.join(templateDir, name), "utf-8");
984
+ if (!raw.startsWith("---")) return raw;
985
+ const endIndex = raw.indexOf("\n---", 3);
986
+ if (endIndex === -1) return raw;
987
+ return raw.slice(endIndex + 4).replace(/^\s+/, "");
988
+ } catch {
989
+ return fallback;
990
+ }
991
+ }
992
+ const resolveDevWorkspaceDir = (env = process.env) => {
993
+ const baseDir = resolveDefaultAgentWorkspaceDir(env, os.homedir);
994
+ if (env.OPENCLAW_PROFILE?.trim().toLowerCase() === "dev") return baseDir;
995
+ return `${baseDir}-${DEV_AGENT_WORKSPACE_SUFFIX}`;
996
+ };
997
+ async function writeFileIfMissing(filePath, content) {
998
+ try {
999
+ await fs.promises.writeFile(filePath, content, {
1000
+ encoding: "utf-8",
1001
+ flag: "wx"
1002
+ });
1003
+ } catch (err) {
1004
+ if (err.code !== "EEXIST") throw err;
1005
+ }
1006
+ }
1007
+ async function ensureDevWorkspace(dir) {
1008
+ const resolvedDir = resolveUserPath(dir);
1009
+ await fs.promises.mkdir(resolvedDir, { recursive: true });
1010
+ const [agents, soul, tools, identity, user] = await Promise.all([
1011
+ loadDevTemplate("AGENTS.dev.md", `# AGENTS.md - OpenClaw Dev Workspace\n\nDefault dev workspace for openclaw gateway --dev.\n`),
1012
+ loadDevTemplate("SOUL.dev.md", `# SOUL.md - Dev Persona\n\nProtocol droid for debugging and operations.\n`),
1013
+ loadDevTemplate("TOOLS.dev.md", `# TOOLS.md - User Tool Notes (editable)\n\nAdd your local tool notes here.\n`),
1014
+ loadDevTemplate("IDENTITY.dev.md", `# IDENTITY.md - Agent Identity\n\n- Name: ${DEV_IDENTITY_NAME}\n- Creature: protocol droid\n- Vibe: ${DEV_IDENTITY_THEME}\n- Emoji: ${DEV_IDENTITY_EMOJI}\n`),
1015
+ loadDevTemplate("USER.dev.md", `# USER.md - User Profile\n\n- Name:\n- Preferred address:\n- Notes:\n`)
1016
+ ]);
1017
+ await writeFileIfMissing(path.join(resolvedDir, "AGENTS.md"), agents);
1018
+ await writeFileIfMissing(path.join(resolvedDir, "SOUL.md"), soul);
1019
+ await writeFileIfMissing(path.join(resolvedDir, "TOOLS.md"), tools);
1020
+ await writeFileIfMissing(path.join(resolvedDir, "IDENTITY.md"), identity);
1021
+ await writeFileIfMissing(path.join(resolvedDir, "USER.md"), user);
1022
+ }
1023
+ async function ensureDevGatewayConfig(opts) {
1024
+ const workspace = resolveDevWorkspaceDir();
1025
+ if (opts.reset) await handleReset("full", workspace, defaultRuntime);
1026
+ const configPath = createConfigIO().configPath;
1027
+ const configExists = fs.existsSync(configPath);
1028
+ if (!opts.reset && configExists) return;
1029
+ await writeConfigFile({
1030
+ gateway: {
1031
+ mode: "local",
1032
+ bind: "loopback"
1033
+ },
1034
+ agents: {
1035
+ defaults: {
1036
+ workspace,
1037
+ skipBootstrap: true
1038
+ },
1039
+ list: [{
1040
+ id: "dev",
1041
+ default: true,
1042
+ workspace,
1043
+ identity: {
1044
+ name: DEV_IDENTITY_NAME,
1045
+ theme: DEV_IDENTITY_THEME,
1046
+ emoji: DEV_IDENTITY_EMOJI
1047
+ }
1048
+ }]
1049
+ }
1050
+ });
1051
+ await ensureDevWorkspace(workspace);
1052
+ defaultRuntime.log(`Dev config ready: ${shortenHomePath(configPath)}`);
1053
+ defaultRuntime.log(`Dev workspace ready: ${shortenHomePath(resolveUserPath(workspace))}`);
1054
+ }
1055
+
1056
+ //#endregion
1057
+ //#region src/cli/gateway-cli/run.ts
1058
+ const gatewayLog = createSubsystemLogger("gateway");
1059
+ const GATEWAY_RUN_VALUE_KEYS = [
1060
+ "port",
1061
+ "bind",
1062
+ "token",
1063
+ "auth",
1064
+ "password",
1065
+ "tailscale",
1066
+ "wsLog",
1067
+ "rawStreamPath"
1068
+ ];
1069
+ const GATEWAY_RUN_BOOLEAN_KEYS = [
1070
+ "tailscaleResetOnExit",
1071
+ "allowUnconfigured",
1072
+ "dev",
1073
+ "reset",
1074
+ "force",
1075
+ "verbose",
1076
+ "claudeCliLogs",
1077
+ "compact",
1078
+ "rawStream"
1079
+ ];
1080
+ const GATEWAY_AUTH_MODES = [
1081
+ "none",
1082
+ "token",
1083
+ "password",
1084
+ "trusted-proxy"
1085
+ ];
1086
+ const GATEWAY_TAILSCALE_MODES = [
1087
+ "off",
1088
+ "serve",
1089
+ "funnel"
1090
+ ];
1091
+ function parseEnumOption(raw, allowed) {
1092
+ if (!raw) return null;
1093
+ return allowed.includes(raw) ? raw : null;
1094
+ }
1095
+ function formatModeChoices(modes) {
1096
+ return modes.map((mode) => `"${mode}"`).join("|");
1097
+ }
1098
+ function formatModeErrorList(modes) {
1099
+ const quoted = modes.map((mode) => `"${mode}"`);
1100
+ if (quoted.length === 0) return "";
1101
+ if (quoted.length === 1) return quoted[0];
1102
+ if (quoted.length === 2) return `${quoted[0]} or ${quoted[1]}`;
1103
+ return `${quoted.slice(0, -1).join(", ")}, or ${quoted[quoted.length - 1]}`;
1104
+ }
1105
+ function resolveGatewayRunOptions(opts, command) {
1106
+ const resolved = { ...opts };
1107
+ for (const key of GATEWAY_RUN_VALUE_KEYS) {
1108
+ const inherited = inheritOptionFromParent(command, key);
1109
+ if (key === "wsLog") {
1110
+ resolved[key] = inherited ?? resolved[key];
1111
+ continue;
1112
+ }
1113
+ resolved[key] = resolved[key] ?? inherited;
1114
+ }
1115
+ for (const key of GATEWAY_RUN_BOOLEAN_KEYS) {
1116
+ const inherited = inheritOptionFromParent(command, key);
1117
+ resolved[key] = Boolean(resolved[key] || inherited);
1118
+ }
1119
+ return resolved;
1120
+ }
1121
+ async function runGatewayCommand$1(opts) {
1122
+ const isDevProfile = process.env.OPENCLAW_PROFILE?.trim().toLowerCase() === "dev";
1123
+ const devMode = Boolean(opts.dev) || isDevProfile;
1124
+ if (opts.reset && !devMode) {
1125
+ defaultRuntime.error("Use --reset with --dev.");
1126
+ defaultRuntime.exit(1);
1127
+ return;
1128
+ }
1129
+ setConsoleTimestampPrefix(true);
1130
+ setVerbose(Boolean(opts.verbose));
1131
+ if (opts.claudeCliLogs) {
1132
+ setConsoleSubsystemFilter(["agent/claude-cli"]);
1133
+ process.env.OPENCLAW_CLAUDE_CLI_LOG_OUTPUT = "1";
1134
+ }
1135
+ const wsLogRaw = opts.compact ? "compact" : opts.wsLog;
1136
+ const wsLogStyle = wsLogRaw === "compact" ? "compact" : wsLogRaw === "full" ? "full" : "auto";
1137
+ if (wsLogRaw !== void 0 && wsLogRaw !== "auto" && wsLogRaw !== "compact" && wsLogRaw !== "full") {
1138
+ defaultRuntime.error("Invalid --ws-log (use \"auto\", \"full\", \"compact\")");
1139
+ defaultRuntime.exit(1);
1140
+ }
1141
+ setGatewayWsLogStyle(wsLogStyle);
1142
+ if (opts.rawStream) process.env.OPENCLAW_RAW_STREAM = "1";
1143
+ const rawStreamPath = toOptionString(opts.rawStreamPath);
1144
+ if (rawStreamPath) process.env.OPENCLAW_RAW_STREAM_PATH = rawStreamPath;
1145
+ if (devMode) await ensureDevGatewayConfig({ reset: Boolean(opts.reset) });
1146
+ const cfg = loadConfig();
1147
+ const portOverride = parsePort$1(opts.port);
1148
+ if (opts.port !== void 0 && portOverride === null) {
1149
+ defaultRuntime.error("Invalid port");
1150
+ defaultRuntime.exit(1);
1151
+ }
1152
+ const port = portOverride ?? resolveGatewayPort(cfg);
1153
+ if (!Number.isFinite(port) || port <= 0) {
1154
+ defaultRuntime.error("Invalid port");
1155
+ defaultRuntime.exit(1);
1156
+ }
1157
+ const bindRaw = toOptionString(opts.bind) ?? cfg.gateway?.bind ?? "loopback";
1158
+ const bind = bindRaw === "loopback" || bindRaw === "lan" || bindRaw === "auto" || bindRaw === "custom" || bindRaw === "tailnet" ? bindRaw : null;
1159
+ if (!bind) {
1160
+ defaultRuntime.error("Invalid --bind (use \"loopback\", \"lan\", \"tailnet\", \"auto\", or \"custom\")");
1161
+ defaultRuntime.exit(1);
1162
+ return;
1163
+ }
1164
+ if (opts.force) try {
1165
+ const { killed, waitedMs, escalatedToSigkill } = await forceFreePortAndWait(port, {
1166
+ timeoutMs: 2e3,
1167
+ intervalMs: 100,
1168
+ sigtermTimeoutMs: 700
1169
+ });
1170
+ if (killed.length === 0) gatewayLog.info(`force: no listeners on port ${port}`);
1171
+ else {
1172
+ for (const proc of killed) gatewayLog.info(`force: killed pid ${proc.pid}${proc.command ? ` (${proc.command})` : ""} on port ${port}`);
1173
+ if (escalatedToSigkill) gatewayLog.info(`force: escalated to SIGKILL while freeing port ${port}`);
1174
+ if (waitedMs > 0) gatewayLog.info(`force: waited ${waitedMs}ms for port ${port} to free`);
1175
+ }
1176
+ const bindWaitMs = await waitForPortBindable(port, {
1177
+ timeoutMs: 3e3,
1178
+ intervalMs: 150,
1179
+ host: bind === "loopback" ? "127.0.0.1" : bind === "lan" ? "0.0.0.0" : bind === "custom" ? toOptionString(cfg.gateway?.customBindHost) : void 0
1180
+ });
1181
+ if (bindWaitMs > 0) gatewayLog.info(`force: waited ${bindWaitMs}ms for port ${port} to become bindable`);
1182
+ } catch (err) {
1183
+ defaultRuntime.error(`Force: ${String(err)}`);
1184
+ defaultRuntime.exit(1);
1185
+ return;
1186
+ }
1187
+ if (opts.token) {
1188
+ const token = toOptionString(opts.token);
1189
+ if (token) process.env.OPENCLAW_GATEWAY_TOKEN = token;
1190
+ }
1191
+ const authModeRaw = toOptionString(opts.auth);
1192
+ const authMode = parseEnumOption(authModeRaw, GATEWAY_AUTH_MODES);
1193
+ if (authModeRaw && !authMode) {
1194
+ defaultRuntime.error(`Invalid --auth (use ${formatModeErrorList(GATEWAY_AUTH_MODES)})`);
1195
+ defaultRuntime.exit(1);
1196
+ return;
1197
+ }
1198
+ const tailscaleRaw = toOptionString(opts.tailscale);
1199
+ const tailscaleMode = parseEnumOption(tailscaleRaw, GATEWAY_TAILSCALE_MODES);
1200
+ if (tailscaleRaw && !tailscaleMode) {
1201
+ defaultRuntime.error(`Invalid --tailscale (use ${formatModeErrorList(GATEWAY_TAILSCALE_MODES)})`);
1202
+ defaultRuntime.exit(1);
1203
+ return;
1204
+ }
1205
+ const passwordRaw = toOptionString(opts.password);
1206
+ const tokenRaw = toOptionString(opts.token);
1207
+ const snapshot = await readConfigFileSnapshot().catch(() => null);
1208
+ const configExists = snapshot?.exists ?? fs.existsSync(CONFIG_PATH);
1209
+ const configAuditPath = path.join(resolveStateDir(process.env), "logs", "config-audit.jsonl");
1210
+ const mode = cfg.gateway?.mode;
1211
+ if (!opts.allowUnconfigured && mode !== "local") {
1212
+ if (!configExists) defaultRuntime.error(`Missing config. Run \`${formatCliCommand("openclaw setup")}\` or set gateway.mode=local (or pass --allow-unconfigured).`);
1213
+ else {
1214
+ defaultRuntime.error(`Gateway start blocked: set gateway.mode=local (current: ${mode ?? "unset"}) or pass --allow-unconfigured.`);
1215
+ defaultRuntime.error(`Config write audit: ${configAuditPath}`);
1216
+ }
1217
+ defaultRuntime.exit(1);
1218
+ return;
1219
+ }
1220
+ const miskeys = extractGatewayMiskeys(snapshot?.parsed);
1221
+ const authOverride = authMode || passwordRaw || tokenRaw || authModeRaw ? {
1222
+ ...authMode ? { mode: authMode } : {},
1223
+ ...tokenRaw ? { token: tokenRaw } : {},
1224
+ ...passwordRaw ? { password: passwordRaw } : {}
1225
+ } : void 0;
1226
+ const resolvedAuth = resolveGatewayAuth({
1227
+ authConfig: cfg.gateway?.auth,
1228
+ authOverride,
1229
+ env: process.env,
1230
+ tailscaleMode: tailscaleMode ?? cfg.gateway?.tailscale?.mode ?? "off"
1231
+ });
1232
+ const resolvedAuthMode = resolvedAuth.mode;
1233
+ const tokenValue = resolvedAuth.token;
1234
+ const passwordValue = resolvedAuth.password;
1235
+ const hasToken = typeof tokenValue === "string" && tokenValue.trim().length > 0;
1236
+ const hasPassword = typeof passwordValue === "string" && passwordValue.trim().length > 0;
1237
+ const tokenConfigured = hasToken || hasConfiguredSecretInput(authOverride?.token ?? cfg.gateway?.auth?.token, cfg.secrets?.defaults);
1238
+ const passwordConfigured = hasPassword || hasConfiguredSecretInput(authOverride?.password ?? cfg.gateway?.auth?.password, cfg.secrets?.defaults);
1239
+ const hasSharedSecret = resolvedAuthMode === "token" && tokenConfigured || resolvedAuthMode === "password" && passwordConfigured;
1240
+ const canBootstrapToken = resolvedAuthMode === "token" && !tokenConfigured;
1241
+ const authHints = [];
1242
+ if (miskeys.hasGatewayToken) authHints.push("Found \"gateway.token\" in config. Use \"gateway.auth.token\" instead.");
1243
+ if (miskeys.hasRemoteToken) authHints.push("\"gateway.remote.token\" is for remote CLI calls; it does not enable local gateway auth.");
1244
+ if (resolvedAuthMode === "password" && !passwordConfigured) {
1245
+ defaultRuntime.error([
1246
+ "Gateway auth is set to password, but no password is configured.",
1247
+ "Set gateway.auth.password (or OPENCLAW_GATEWAY_PASSWORD), or pass --password.",
1248
+ ...authHints
1249
+ ].filter(Boolean).join("\n"));
1250
+ defaultRuntime.exit(1);
1251
+ return;
1252
+ }
1253
+ if (resolvedAuthMode === "none") gatewayLog.warn("Gateway auth mode=none explicitly configured; all gateway connections are unauthenticated.");
1254
+ if (bind !== "loopback" && !hasSharedSecret && !canBootstrapToken && resolvedAuthMode !== "trusted-proxy" && resolvedAuthMode !== "iam") {
1255
+ defaultRuntime.error([
1256
+ `Refusing to bind gateway to ${bind} without auth.`,
1257
+ "Set gateway.auth.token/password (or OPENCLAW_GATEWAY_TOKEN/OPENCLAW_GATEWAY_PASSWORD) or pass --token/--password.",
1258
+ ...authHints
1259
+ ].filter(Boolean).join("\n"));
1260
+ defaultRuntime.exit(1);
1261
+ return;
1262
+ }
1263
+ const tailscaleOverride = tailscaleMode || opts.tailscaleResetOnExit ? {
1264
+ ...tailscaleMode ? { mode: tailscaleMode } : {},
1265
+ ...opts.tailscaleResetOnExit ? { resetOnExit: true } : {}
1266
+ } : void 0;
1267
+ try {
1268
+ await runGatewayLoop({
1269
+ runtime: defaultRuntime,
1270
+ lockPort: port,
1271
+ start: async () => await startGatewayServer(port, {
1272
+ bind,
1273
+ auth: authOverride,
1274
+ tailscale: tailscaleOverride
1275
+ })
1276
+ });
1277
+ } catch (err) {
1278
+ if (err instanceof GatewayLockError || err && typeof err === "object" && err.name === "GatewayLockError") {
1279
+ const errMessage = describeUnknownError(err);
1280
+ defaultRuntime.error(`Gateway failed to start: ${errMessage}\nIf the gateway is supervised, stop it with: ${formatCliCommand("openclaw gateway stop")}`);
1281
+ try {
1282
+ const diagnostics = await inspectPortUsage(port);
1283
+ if (diagnostics.status === "busy") for (const line of formatPortDiagnostics(diagnostics)) defaultRuntime.error(line);
1284
+ } catch {}
1285
+ await maybeExplainGatewayServiceStop();
1286
+ defaultRuntime.exit(1);
1287
+ return;
1288
+ }
1289
+ defaultRuntime.error(`Gateway failed to start: ${String(err)}`);
1290
+ defaultRuntime.exit(1);
1291
+ }
1292
+ }
1293
+ function addGatewayRunCommand(cmd) {
1294
+ return cmd.option("--port <port>", "Port for the gateway WebSocket").option("--bind <mode>", "Bind mode (\"loopback\"|\"lan\"|\"tailnet\"|\"auto\"|\"custom\"). Defaults to config gateway.bind (or loopback).").option("--token <token>", "Shared token required in connect.params.auth.token (default: OPENCLAW_GATEWAY_TOKEN env if set)").option("--auth <mode>", `Gateway auth mode (${formatModeChoices(GATEWAY_AUTH_MODES)})`).option("--password <password>", "Password for auth mode=password").option("--tailscale <mode>", `Tailscale exposure mode (${formatModeChoices(GATEWAY_TAILSCALE_MODES)})`).option("--tailscale-reset-on-exit", "Reset Tailscale serve/funnel configuration on shutdown", false).option("--allow-unconfigured", "Allow gateway start without gateway.mode=local in config", false).option("--dev", "Create a dev config + workspace if missing (no BOOTSTRAP.md)", false).option("--reset", "Reset dev config + credentials + sessions + workspace (requires --dev)", false).option("--force", "Kill any existing listener on the target port before starting", false).option("--verbose", "Verbose logging to stdout/stderr", false).option("--claude-cli-logs", "Only show claude-cli logs in the console (includes stdout/stderr)", false).option("--ws-log <style>", "WebSocket log style (\"auto\"|\"full\"|\"compact\")", "auto").option("--compact", "Alias for \"--ws-log compact\"", false).option("--raw-stream", "Log raw model stream events to jsonl", false).option("--raw-stream-path <path>", "Raw stream jsonl path").action(async (opts, command) => {
1295
+ await runGatewayCommand$1(resolveGatewayRunOptions(opts, command));
1296
+ });
1297
+ }
1298
+
1299
+ //#endregion
1300
+ //#region src/cli/gateway-cli/register.ts
1301
+ function runGatewayCommand(action, label) {
1302
+ return runCommandWithRuntime(defaultRuntime, action, (err) => {
1303
+ const message = String(err);
1304
+ defaultRuntime.error(label ? `${label}: ${message}` : message);
1305
+ defaultRuntime.exit(1);
1306
+ });
1307
+ }
1308
+ function parseDaysOption(raw, fallback = 30) {
1309
+ if (typeof raw === "number" && Number.isFinite(raw)) return Math.max(1, Math.floor(raw));
1310
+ if (typeof raw === "string" && raw.trim() !== "") {
1311
+ const parsed = Number(raw);
1312
+ if (Number.isFinite(parsed)) return Math.max(1, Math.floor(parsed));
1313
+ }
1314
+ return fallback;
1315
+ }
1316
+ function resolveGatewayRpcOptions(opts, command) {
1317
+ const parentToken = inheritOptionFromParent(command, "token");
1318
+ const parentPassword = inheritOptionFromParent(command, "password");
1319
+ return {
1320
+ ...opts,
1321
+ token: opts.token ?? parentToken,
1322
+ password: opts.password ?? parentPassword
1323
+ };
1324
+ }
1325
+ function renderCostUsageSummary(summary, days, rich) {
1326
+ const totalCost = formatUsd(summary.totals.totalCost) ?? "$0.00";
1327
+ const totalTokens = formatTokenCount(summary.totals.totalTokens) ?? "0";
1328
+ const lines = [colorize(rich, theme.heading, `Usage cost (${days} days)`), `${colorize(rich, theme.muted, "Total:")} ${totalCost} · ${totalTokens} tokens`];
1329
+ if (summary.totals.missingCostEntries > 0) lines.push(`${colorize(rich, theme.muted, "Missing entries:")} ${summary.totals.missingCostEntries}`);
1330
+ const latest = summary.daily.at(-1);
1331
+ if (latest) {
1332
+ const latestCost = formatUsd(latest.totalCost) ?? "$0.00";
1333
+ const latestTokens = formatTokenCount(latest.totalTokens) ?? "0";
1334
+ lines.push(`${colorize(rich, theme.muted, "Latest day:")} ${latest.date} · ${latestCost} · ${latestTokens} tokens`);
1335
+ }
1336
+ return lines;
1337
+ }
1338
+ function registerGatewayCli(program) {
1339
+ const gateway = addGatewayRunCommand(program.command("gateway").description("Run, inspect, and query the WebSocket Gateway").addHelpText("after", () => `\n${theme.heading("Examples:")}\n${formatHelpExamples([
1340
+ ["openclaw gateway run", "Run the gateway in the foreground."],
1341
+ ["openclaw gateway status", "Show service status and probe reachability."],
1342
+ ["openclaw gateway discover", "Find local and wide-area gateway beacons."],
1343
+ ["openclaw gateway call health", "Call a gateway RPC method directly."]
1344
+ ])}\n\n${theme.muted("Docs:")} ${formatDocsLink("/cli/gateway", "docs.openclaw.ai/cli/gateway")}\n`));
1345
+ addGatewayRunCommand(gateway.command("run").description("Run the WebSocket Gateway (foreground)"));
1346
+ addGatewayServiceCommands(gateway, { statusDescription: "Show gateway service status + probe the Gateway" });
1347
+ gatewayCallOpts(gateway.command("call").description("Call a Gateway method").argument("<method>", "Method name (health/status/system-presence/cron.*)").option("--params <json>", "JSON object string for params", "{}").action(async (method, opts, command) => {
1348
+ await runGatewayCommand(async () => {
1349
+ const rpcOpts = resolveGatewayRpcOptions(opts, command);
1350
+ const result = await callGatewayCli(method, rpcOpts, JSON.parse(String(opts.params ?? "{}")));
1351
+ if (rpcOpts.json) {
1352
+ defaultRuntime.log(JSON.stringify(result, null, 2));
1353
+ return;
1354
+ }
1355
+ const rich = isRich();
1356
+ defaultRuntime.log(`${colorize(rich, theme.heading, "Gateway call")}: ${colorize(rich, theme.muted, String(method))}`);
1357
+ defaultRuntime.log(JSON.stringify(result, null, 2));
1358
+ }, "Gateway call failed");
1359
+ }));
1360
+ gatewayCallOpts(gateway.command("usage-cost").description("Fetch usage cost summary from session logs").option("--days <days>", "Number of days to include", "30").action(async (opts, command) => {
1361
+ await runGatewayCommand(async () => {
1362
+ const rpcOpts = resolveGatewayRpcOptions(opts, command);
1363
+ const days = parseDaysOption(opts.days);
1364
+ const result = await callGatewayCli("usage.cost", rpcOpts, { days });
1365
+ if (rpcOpts.json) {
1366
+ defaultRuntime.log(JSON.stringify(result, null, 2));
1367
+ return;
1368
+ }
1369
+ const rich = isRich();
1370
+ const summary = result;
1371
+ for (const line of renderCostUsageSummary(summary, days, rich)) defaultRuntime.log(line);
1372
+ }, "Gateway usage cost failed");
1373
+ }));
1374
+ gatewayCallOpts(gateway.command("health").description("Fetch Gateway health").action(async (opts, command) => {
1375
+ await runGatewayCommand(async () => {
1376
+ const rpcOpts = resolveGatewayRpcOptions(opts, command);
1377
+ const result = await callGatewayCli("health", rpcOpts);
1378
+ if (rpcOpts.json) {
1379
+ defaultRuntime.log(JSON.stringify(result, null, 2));
1380
+ return;
1381
+ }
1382
+ const rich = isRich();
1383
+ const obj = result && typeof result === "object" ? result : {};
1384
+ const durationMs = typeof obj.durationMs === "number" ? obj.durationMs : null;
1385
+ defaultRuntime.log(colorize(rich, theme.heading, "Gateway Health"));
1386
+ defaultRuntime.log(`${colorize(rich, theme.success, "OK")}${durationMs != null ? ` (${durationMs}ms)` : ""}`);
1387
+ if (obj.channels && typeof obj.channels === "object") for (const line of formatHealthChannelLines(obj)) defaultRuntime.log(styleHealthChannelLine(line, rich));
1388
+ });
1389
+ }));
1390
+ gateway.command("probe").description("Show gateway reachability + discovery + health + status summary (local + remote)").option("--url <url>", "Explicit Gateway WebSocket URL (still probes localhost)").option("--ssh <target>", "SSH target for remote gateway tunnel (user@host or user@host:port)").option("--ssh-identity <path>", "SSH identity file path").option("--ssh-auto", "Try to derive an SSH target from Bonjour discovery", false).option("--token <token>", "Gateway token (applies to all probes)").option("--password <password>", "Gateway password (applies to all probes)").option("--timeout <ms>", "Overall probe budget in ms", "3000").option("--json", "Output JSON", false).action(async (opts, command) => {
1391
+ await runGatewayCommand(async () => {
1392
+ await gatewayStatusCommand(resolveGatewayRpcOptions(opts, command), defaultRuntime);
1393
+ });
1394
+ });
1395
+ gateway.command("discover").description("Discover gateways via Bonjour (local + wide-area if configured)").option("--timeout <ms>", "Per-command timeout in ms", "2000").option("--json", "Output JSON", false).action(async (opts) => {
1396
+ await runGatewayCommand(async () => {
1397
+ const wideAreaDomain = resolveWideAreaDiscoveryDomain({ configDomain: loadConfig().discovery?.wideArea?.domain });
1398
+ const timeoutMs = parseDiscoverTimeoutMs(opts.timeout, 2e3);
1399
+ const domains = ["local.", ...wideAreaDomain ? [wideAreaDomain] : []];
1400
+ const deduped = dedupeBeacons(await withProgress({
1401
+ label: "Scanning for gateways…",
1402
+ indeterminate: true,
1403
+ enabled: opts.json !== true,
1404
+ delayMs: 0
1405
+ }, async () => await discoverGatewayBeacons({
1406
+ timeoutMs,
1407
+ wideAreaDomain
1408
+ }))).toSorted((a, b) => String(a.displayName || a.instanceName).localeCompare(String(b.displayName || b.instanceName)));
1409
+ if (opts.json) {
1410
+ const enriched = deduped.map((b) => {
1411
+ const host = pickBeaconHost(b);
1412
+ const port = pickGatewayPort(b);
1413
+ return {
1414
+ ...b,
1415
+ wsUrl: host ? `ws://${host}:${port}` : null
1416
+ };
1417
+ });
1418
+ defaultRuntime.log(JSON.stringify({
1419
+ timeoutMs,
1420
+ domains,
1421
+ count: enriched.length,
1422
+ beacons: enriched
1423
+ }, null, 2));
1424
+ return;
1425
+ }
1426
+ const rich = isRich();
1427
+ defaultRuntime.log(colorize(rich, theme.heading, "Gateway Discovery"));
1428
+ defaultRuntime.log(colorize(rich, theme.muted, `Found ${deduped.length} gateway(s) · domains: ${domains.join(", ")}`));
1429
+ if (deduped.length === 0) return;
1430
+ for (const beacon of deduped) for (const line of renderBeaconLines(beacon, rich)) defaultRuntime.log(line);
1431
+ }, "gateway discover failed");
1432
+ });
1433
+ }
1434
+
1435
+ //#endregion
1436
+ export { registerGatewayCli };