hyperclaw 5.3.45 → 5.4.1

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 (438) hide show
  1. package/README.md +1 -0
  2. package/dist/a2ui-protocol-CibzbTxL.js +75 -0
  3. package/dist/a2ui-protocol-Dtb8zlog.js +75 -0
  4. package/dist/a2ui-protocol-ORP2Etw0.js +75 -0
  5. package/dist/a2ui-protocol-whRZHdBk.js +75 -0
  6. package/dist/abort-controller-B55O1IgK.js +47995 -0
  7. package/dist/agents-routing-Ai2BQVpU.js +7 -0
  8. package/dist/agents-routing-B0RBl1B8.js +424 -0
  9. package/dist/agents-routing-BSUaOpce.js +7 -0
  10. package/dist/agents-routing-C4PVN8G6.js +7 -0
  11. package/dist/agents-routing-Dcr29-JV.js +424 -0
  12. package/dist/agents-routing-EwzORQQv.js +424 -0
  13. package/dist/agents-routing-Fd-uQ4R_.js +7 -0
  14. package/dist/agents-routing-eLjVYBAk.js +424 -0
  15. package/dist/api-key-validation-BANgbsfO.js +66 -0
  16. package/dist/api-key-validation-Bnz-0MMK.js +66 -0
  17. package/dist/api-key-validation-D_fMCaO5.js +66 -0
  18. package/dist/api-key-validation-Db7rG3JU.js +66 -0
  19. package/dist/api-keys-guide-B6AJ1V5D.js +149 -0
  20. package/dist/api-keys-guide-C75JQOdH.js +149 -0
  21. package/dist/api-keys-guide-CFJPrgsL.js +149 -0
  22. package/dist/api-keys-guide-DDz08BJQ.js +149 -0
  23. package/dist/audit-BLMB8qp7.js +445 -0
  24. package/dist/audit-Cb2TvqYZ.js +445 -0
  25. package/dist/audit-D7koAKvj.js +445 -0
  26. package/dist/audit-xP_175jB.js +445 -0
  27. package/dist/backup-7l3iovkX.js +86 -0
  28. package/dist/backup-BKLTHh62.js +86 -0
  29. package/dist/backup-CspxXk78.js +86 -0
  30. package/dist/backup-D8dFYDXV.js +86 -0
  31. package/dist/banner-B2Qo91lq.js +143 -0
  32. package/dist/banner-CZ2BfvQq.js +143 -0
  33. package/dist/banner-CjTRWmks.js +7 -0
  34. package/dist/banner-CmNA9NKE.js +7 -0
  35. package/dist/banner-D3-Ik5d2.js +143 -0
  36. package/dist/banner-D3X8tQ-0.js +7 -0
  37. package/dist/banner-Dpygks0H.js +143 -0
  38. package/dist/banner-ZX1WLr44.js +7 -0
  39. package/dist/bounty-tools-Cq-oC9gk.js +211 -0
  40. package/dist/bounty-tools-DZ-WtRdE.js +211 -0
  41. package/dist/bounty-tools-DhpmjF5Y.js +211 -0
  42. package/dist/bounty-tools-NGuBWI55.js +211 -0
  43. package/dist/browser-tools-5Fl1hP_2.js +5 -0
  44. package/dist/browser-tools-Ay-wU_a4.js +5 -0
  45. package/dist/browser-tools-BMgBB2fK.js +179 -0
  46. package/dist/browser-tools-kcViDwk5.js +179 -0
  47. package/dist/chat-BGD9AWhr.js +523 -0
  48. package/dist/chat-BUa1oGqj.js +528 -0
  49. package/dist/chat-CiuT-GTs.js +528 -0
  50. package/dist/chat-D8wFNN4z.js +523 -0
  51. package/dist/chat-DfI8uOzF.js +528 -0
  52. package/dist/chat-Dz5rmUSs.js +528 -0
  53. package/dist/chat-RTmX1F16.js +528 -0
  54. package/dist/claw-tasks-Cio1Q7eA.js +80 -0
  55. package/dist/claw-tasks-DzxNWVcz.js +80 -0
  56. package/dist/claw-tasks-L7vQSGlt.js +80 -0
  57. package/dist/claw-tasks-dndWneZW.js +80 -0
  58. package/dist/config-B-W-Mz4X.js +7 -0
  59. package/dist/config-BAwkTUJC.js +261 -0
  60. package/dist/config-CYPw2v4l.js +261 -0
  61. package/dist/config-DN9fdLL3.js +261 -0
  62. package/dist/config-FejpHHTz.js +261 -0
  63. package/dist/config-Tq_GJHf7.js +7 -0
  64. package/dist/config-n4qy5jIy.js +7 -0
  65. package/dist/config-qJUYRMzx.js +7 -0
  66. package/dist/connector-CwT7KZm2.js +309 -0
  67. package/dist/connector-DX4k-lGd.js +442 -0
  68. package/dist/cost-tracker-C2q5zKic.js +103 -0
  69. package/dist/cost-tracker-CsRQAOEr.js +103 -0
  70. package/dist/cost-tracker-DAXWN5YT.js +103 -0
  71. package/dist/cost-tracker-bySvehH6.js +103 -0
  72. package/dist/credentials-store-BAW87r6f.js +7 -0
  73. package/dist/credentials-store-BHtk7_H_.js +7 -0
  74. package/dist/credentials-store-CESgFvFU.js +89 -0
  75. package/dist/credentials-store-CR4WSDGl.js +7 -0
  76. package/dist/credentials-store-CXq4kZub.js +89 -0
  77. package/dist/credentials-store-DUp8dtaS.js +89 -0
  78. package/dist/credentials-store-hiSga8qn.js +89 -0
  79. package/dist/credentials-store-kLdrmqSt.js +7 -0
  80. package/dist/cron-tasks-BFsaCKxE.js +89 -0
  81. package/dist/cron-tasks-BelA2aUW.js +89 -0
  82. package/dist/cron-tasks-D1T9fWAb.js +89 -0
  83. package/dist/cron-tasks-f_ieXSG2.js +89 -0
  84. package/dist/daemon-BTYhQvD_.js +7 -0
  85. package/dist/daemon-BoaFnmdF.js +421 -0
  86. package/dist/daemon-BrHxr4ut.js +421 -0
  87. package/dist/daemon-BzdeLgON.js +421 -0
  88. package/dist/daemon-BzqWIC4v.js +7 -0
  89. package/dist/daemon-C3OczPR1.js +7 -0
  90. package/dist/daemon-D-klsy3i.js +7 -0
  91. package/dist/daemon-D57KIIA3.js +421 -0
  92. package/dist/daemon-D8uyH9et.js +7 -0
  93. package/dist/daemon-DBTtYx6E.js +421 -0
  94. package/dist/daemon-D_bYfHgn.js +421 -0
  95. package/dist/daemon-DcE6vcjH.js +421 -0
  96. package/dist/daemon-NFwpuo3L.js +7 -0
  97. package/dist/daemon-srcdhzUG.js +7 -0
  98. package/dist/delivery-Bt0xW6L9.js +4 -0
  99. package/dist/delivery-C2sAERN7.js +4 -0
  100. package/dist/delivery-CF2Q4hb1.js +95 -0
  101. package/dist/delivery-CfMljOwk.js +95 -0
  102. package/dist/delivery-DP0d4_A4.js +95 -0
  103. package/dist/delivery-DXYt4aMO.js +4 -0
  104. package/dist/delivery-DXxP2UL4.js +4 -0
  105. package/dist/delivery-jT2UIDlU.js +95 -0
  106. package/dist/destructive-gate-5LYh6brt.js +116 -0
  107. package/dist/destructive-gate-B_hNKtu6.js +116 -0
  108. package/dist/destructive-gate-DvxPSDMR.js +116 -0
  109. package/dist/destructive-gate-Qd2y7x1B.js +116 -0
  110. package/dist/dist-B1qvBUax.js +30541 -0
  111. package/dist/engine-B7Q4Vx-C.js +7 -0
  112. package/dist/engine-BBJlKpMP.js +7 -0
  113. package/dist/engine-BNygJfCo.js +335 -0
  114. package/dist/engine-C-G3G-U7.js +7 -0
  115. package/dist/engine-DB4MBzki.js +7 -0
  116. package/dist/engine-DPi9fhMl.js +332 -0
  117. package/dist/engine-DRpy9Y5O.js +327 -0
  118. package/dist/engine-DeaqDcaT.js +7 -0
  119. package/dist/engine-DetHi9LP.js +327 -0
  120. package/dist/engine-DuvXJrUP.js +335 -0
  121. package/dist/engine-HkyTC_xl.js +332 -0
  122. package/dist/engine-JysunhPR.js +7 -0
  123. package/dist/engine-MzEUw7qb.js +7 -0
  124. package/dist/engine-j9Yaqt_-.js +332 -0
  125. package/dist/env-resolve--MaE2kFF.js +167 -0
  126. package/dist/env-resolve-BYWG94tK.js +11 -0
  127. package/dist/env-resolve-Bop7KbNq.js +167 -0
  128. package/dist/env-resolve-Buos635Y.js +167 -0
  129. package/dist/env-resolve-D3dP1-Xt.js +11 -0
  130. package/dist/env-resolve-DvsbhPKl.js +11 -0
  131. package/dist/env-resolve-NNM3F6Eo.js +167 -0
  132. package/dist/env-resolve-dTjn-g8X.js +11 -0
  133. package/dist/extraction-tools-Bh5F0ENP.js +91 -0
  134. package/dist/extraction-tools-BjzXD9LW.js +5 -0
  135. package/dist/extraction-tools-D1lrDYhe.js +5 -0
  136. package/dist/extraction-tools-FBwtT2Bx.js +91 -0
  137. package/dist/fileFromPath-CodL6KXh.js +85 -0
  138. package/dist/gmail-watch-setup--eQ8raeb.js +42 -0
  139. package/dist/gmail-watch-setup-9t14gy1B.js +42 -0
  140. package/dist/gmail-watch-setup-B9fx_OLg.js +42 -0
  141. package/dist/gmail-watch-setup-DP3kDRx1.js +42 -0
  142. package/dist/heartbeat-engine-5iOlL7Dj.js +89 -0
  143. package/dist/heartbeat-engine-Bu4q18GH.js +89 -0
  144. package/dist/heartbeat-engine-CF_JjNJ4.js +89 -0
  145. package/dist/heartbeat-engine-CLADYZxE.js +89 -0
  146. package/dist/hub-CZeGrS20.js +6 -0
  147. package/dist/hub-DAkEVTEy.js +545 -0
  148. package/dist/hyperclawbot-BqyZr2GM.js +516 -0
  149. package/dist/hyperclawbot-CNVUtvYC.js +516 -0
  150. package/dist/hyperclawbot-D5ofLNgm.js +516 -0
  151. package/dist/hyperclawbot-D61zVMyQ.js +516 -0
  152. package/dist/hyperclawbot-DTzP20Up.js +516 -0
  153. package/dist/hyperclawbot-DwScttSx.js +516 -0
  154. package/dist/hyperclawbot-v65eL2U0.js +516 -0
  155. package/dist/inference-BEvs7s3c.js +2854 -0
  156. package/dist/inference-C4b9YqXk.js +8 -0
  157. package/dist/inference-CRF6HyyH.js +2854 -0
  158. package/dist/inference-CfhTACI8.js +2854 -0
  159. package/dist/inference-DGsy36Ru.js +8 -0
  160. package/dist/inference-Da7Hw4J3.js +8 -0
  161. package/dist/inference-DhJ-SHZn.js +8 -0
  162. package/dist/inference-K7Jrnzre.js +2854 -0
  163. package/dist/isFile-CSxoSB8X.js +2274 -0
  164. package/dist/knowledge-graph-BdsJ5KEL.js +134 -0
  165. package/dist/knowledge-graph-CFRBepzr.js +134 -0
  166. package/dist/knowledge-graph-CeDeahui.js +134 -0
  167. package/dist/knowledge-graph-DoYFZnUr.js +134 -0
  168. package/dist/loader-C2qtNbtF.js +6 -0
  169. package/dist/loader-D6yjBYo4.js +410 -0
  170. package/dist/loader-DBO6yRNh.js +6 -0
  171. package/dist/loader-DUhmG3V9.js +410 -0
  172. package/dist/loader-Dl8LNycw.js +6 -0
  173. package/dist/loader-UpOYxgZv.js +6 -0
  174. package/dist/loader-hXv2mZjK.js +410 -0
  175. package/dist/loader-nDBcv3Tm.js +410 -0
  176. package/dist/logger-BD316YbA.js +86 -0
  177. package/dist/logger-BnXZkfsp.js +86 -0
  178. package/dist/logger-CmphFNmW.js +86 -0
  179. package/dist/logger-DkHzhh56.js +86 -0
  180. package/dist/manager-3-q8zuAW.js +250 -0
  181. package/dist/manager-BkMzc-EJ.js +250 -0
  182. package/dist/manager-Bq5LApdR.js +6 -0
  183. package/dist/manager-CNgdJunf.js +250 -0
  184. package/dist/manager-CozyZSDG.js +250 -0
  185. package/dist/manager-D4mDWXph.js +120 -0
  186. package/dist/manager-DuS-WQhZ.js +120 -0
  187. package/dist/manager-Dz2eKYqo.js +116 -0
  188. package/dist/manager-R0TlRMZy.js +120 -0
  189. package/dist/manager-aJfY7rt6.js +120 -0
  190. package/dist/mcp-BH7HtOQ8.js +142 -0
  191. package/dist/mcp-CAJSA_ee.js +142 -0
  192. package/dist/mcp-CD-iIQa2.js +142 -0
  193. package/dist/mcp-DGo37Ifb.js +142 -0
  194. package/dist/mcp-loader-BAGRKfJz.js +93 -0
  195. package/dist/mcp-loader-Ct1NQKnX.js +93 -0
  196. package/dist/mcp-loader-D1T6UX73.js +93 -0
  197. package/dist/mcp-loader-DJk6MEof.js +93 -0
  198. package/dist/mcp-loader-DdXvU63s.js +93 -0
  199. package/dist/mcp-loader-Dt64EewT.js +93 -0
  200. package/dist/mcp-loader-gMliiJ7R.js +93 -0
  201. package/dist/memory-CyonlkTy.js +6 -0
  202. package/dist/memory-DPSWQBc0.js +276 -0
  203. package/dist/memory-auto-B0QOqaUD.js +306 -0
  204. package/dist/memory-auto-BSxYJugl.js +5 -0
  205. package/dist/memory-auto-CcFRxMj-.js +306 -0
  206. package/dist/memory-auto-CifT5aj_.js +5 -0
  207. package/dist/memory-auto-Cp2Jwx3Y.js +306 -0
  208. package/dist/memory-auto-DjK_D8CA.js +306 -0
  209. package/dist/memory-auto-N57dp4Do.js +5 -0
  210. package/dist/memory-auto-n0kOcU7F.js +5 -0
  211. package/dist/memory-integration-D8shLJwp.js +91 -0
  212. package/dist/memory-integration-DLmzJ62L.js +91 -0
  213. package/dist/memory-integration-DMXDbMIL.js +91 -0
  214. package/dist/memory-integration-Dgr-mjue.js +91 -0
  215. package/dist/moltbook-CIeOshK6.js +81 -0
  216. package/dist/moltbook-CX5XWn06.js +81 -0
  217. package/dist/moltbook-DUfiE4NY.js +81 -0
  218. package/dist/moltbook-YEiNI8Cm.js +81 -0
  219. package/dist/multi-agent-tools-jzfvT4zP.js +87 -0
  220. package/dist/multimodal-zZdwqISl.js +77 -0
  221. package/dist/node-BYrxELx2.js +251 -0
  222. package/dist/node-CLWgPlAk.js +251 -0
  223. package/dist/node-Czz8Y85D.js +251 -0
  224. package/dist/node-Du2H2Ddi.js +226 -0
  225. package/dist/node-domexception-v89b0Nwz.js +21 -0
  226. package/dist/node-pending-queue-DUXCbYkp.js +32 -0
  227. package/dist/node-pending-queue-DZp7cdfo.js +32 -0
  228. package/dist/node-pending-queue-iYpoWqxe.js +32 -0
  229. package/dist/nodes-registry-BTy7Sc7D.js +52 -0
  230. package/dist/nodes-registry-BYjmmJBU.js +52 -0
  231. package/dist/nodes-registry-C8GeEGq0.js +52 -0
  232. package/dist/nodes-registry-Du6Klz0l.js +52 -0
  233. package/dist/oauth-flow-BA0yMrHx.js +148 -0
  234. package/dist/oauth-flow-C4QSMsbl.js +148 -0
  235. package/dist/oauth-flow-CIuDBDsp.js +148 -0
  236. package/dist/oauth-flow-CniM4jlJ.js +148 -0
  237. package/dist/oauth-provider-BA4GVFKg.js +111 -0
  238. package/dist/oauth-provider-Bnul5A_Z.js +111 -0
  239. package/dist/oauth-provider-DqPXPiiC.js +111 -0
  240. package/dist/oauth-provider-MEgHjij2.js +111 -0
  241. package/dist/observability-0spm7MPz.js +89 -0
  242. package/dist/observability-BOMYgHUh.js +89 -0
  243. package/dist/observability-CDqHr-_o.js +89 -0
  244. package/dist/observability-ah2a7sh1.js +89 -0
  245. package/dist/onboard-32d2Gsuy.js +14 -0
  246. package/dist/onboard-BJ78s3NT.js +3854 -0
  247. package/dist/onboard-C55YXd_e.js +14 -0
  248. package/dist/onboard-CNnm4yYp.js +3841 -0
  249. package/dist/onboard-CXSVPnP7.js +3854 -0
  250. package/dist/onboard-Cgj_CIrq.js +3812 -0
  251. package/dist/onboard-ChnsqU5z.js +14 -0
  252. package/dist/onboard-CjzqTYq3.js +3812 -0
  253. package/dist/onboard-CwvXXOR1.js +14 -0
  254. package/dist/onboard-CxlIsNhX.js +3854 -0
  255. package/dist/onboard-DPmufMqX.js +14 -0
  256. package/dist/onboard-F9lKA2ie.js +14 -0
  257. package/dist/onboard-UTQXzlPD.js +3854 -0
  258. package/dist/onboard-hK098kjl.js +14 -0
  259. package/dist/openai-CrdtuLxw.js +6292 -0
  260. package/dist/orchestrator-5M-6MB7r.js +6 -0
  261. package/dist/orchestrator-B3BjP1dy.js +6 -0
  262. package/dist/orchestrator-BZS62iDS.js +6 -0
  263. package/dist/orchestrator-Bcj7uc1F.js +189 -0
  264. package/dist/orchestrator-C7oLWNFW.js +6 -0
  265. package/dist/orchestrator-CTMbjgH_.js +6 -0
  266. package/dist/orchestrator-Crn4fgbI.js +189 -0
  267. package/dist/orchestrator-Cs6s-QmS.js +189 -0
  268. package/dist/orchestrator-Cuyqncql.js +189 -0
  269. package/dist/orchestrator-CxlEm5li.js +6 -0
  270. package/dist/orchestrator-DGqwsLmO.js +189 -0
  271. package/dist/orchestrator-UUHsFKiH.js +6 -0
  272. package/dist/orchestrator-oa7HbCnF.js +189 -0
  273. package/dist/orchestrator-tUKag7pG.js +189 -0
  274. package/dist/osint-ADgw_Gkd.js +283 -0
  275. package/dist/osint-B5j3IuJK.js +283 -0
  276. package/dist/osint-BJvOCmVk.js +283 -0
  277. package/dist/osint-CK9xVUUm.js +283 -0
  278. package/dist/osint-D6vQXCWh.js +283 -0
  279. package/dist/osint-DLYZsp1k.js +283 -0
  280. package/dist/osint-cAAdO-cx.js +283 -0
  281. package/dist/osint-chat-B0lc0Y6r.js +789 -0
  282. package/dist/osint-chat-BUhiSpf9.js +789 -0
  283. package/dist/osint-chat-BbH6eW8z.js +789 -0
  284. package/dist/osint-chat-C-9FVAkU.js +789 -0
  285. package/dist/osint-chat-CWET8Fno.js +789 -0
  286. package/dist/osint-chat-Cgdzg3lh.js +789 -0
  287. package/dist/osint-chat-xRP672b-.js +789 -0
  288. package/dist/pc-access-BCaF5mRs.js +858 -0
  289. package/dist/pc-access-BOcXappE.js +858 -0
  290. package/dist/pc-access-BgZNmAdB.js +8 -0
  291. package/dist/pc-access-CAoM6WN4.js +8 -0
  292. package/dist/pc-access-D2HdoziZ.js +8 -0
  293. package/dist/pc-access-D4g0fjQb.js +858 -0
  294. package/dist/pending-approval-CJPyt8U5.js +22 -0
  295. package/dist/pending-approval-CzMNCTfZ.js +22 -0
  296. package/dist/pending-approval-DaXi7otO.js +22 -0
  297. package/dist/pending-approval-KcyeiifE.js +22 -0
  298. package/dist/providers-DrZP0NeR.js +5 -0
  299. package/dist/providers-dHhpJo9j.js +1120 -0
  300. package/dist/reminders-store-B58LldEG.js +58 -0
  301. package/dist/reminders-store-C4gWckLa.js +58 -0
  302. package/dist/reminders-store-DT0o6a60.js +58 -0
  303. package/dist/renderer-B8c22rbg.js +228 -0
  304. package/dist/renderer-BS0ETL20.js +228 -0
  305. package/dist/renderer-Cg3c41A5.js +228 -0
  306. package/dist/renderer-UoPcgaAd.js +228 -0
  307. package/dist/rules-D0v5nuSE.js +106 -0
  308. package/dist/rules-DCKPgwLb.js +106 -0
  309. package/dist/rules-Zn9j4PnO.js +106 -0
  310. package/dist/rules-oAgOSPHC.js +106 -0
  311. package/dist/run-main.js +457 -131
  312. package/dist/runner-BaZ2V27T.js +1307 -0
  313. package/dist/runner-Bgl7UTbV.js +1307 -0
  314. package/dist/runner-DOKp3-v5.js +1307 -0
  315. package/dist/runner-voYdfM_f.js +1307 -0
  316. package/dist/search-tools-BBwMa8VX.js +107 -0
  317. package/dist/search-tools-CEUOO9Jf.js +107 -0
  318. package/dist/search-tools-VHP3xVyC.js +107 -0
  319. package/dist/search-tools-w_zT7-dr.js +107 -0
  320. package/dist/server-6TIyu0mb.js +4 -0
  321. package/dist/server-BAdJwMM9.js +4 -0
  322. package/dist/server-BD9FLc7S.js +1384 -0
  323. package/dist/server-BlqWBbS7.js +4 -0
  324. package/dist/server-BzwPvTbD.js +1447 -0
  325. package/dist/server-CBvSfG4w.js +4 -0
  326. package/dist/server-CbNBcB41.js +4 -0
  327. package/dist/server-DPTXaJJF.js +4 -0
  328. package/dist/server-Da_jSrfS.js +4 -0
  329. package/dist/server-Dv2zHHy-.js +1447 -0
  330. package/dist/server-MDmdWHob.js +1447 -0
  331. package/dist/server-N9LnLQCS.js +1447 -0
  332. package/dist/server-gai_RW1u.js +1356 -0
  333. package/dist/server-vbYKep6r.js +1356 -0
  334. package/dist/session-store-C6Otslf9.js +5 -0
  335. package/dist/session-store-Cmfnvuw9.js +141 -0
  336. package/dist/session-store-CuR9DgRf.js +5 -0
  337. package/dist/session-store-Cx1RMBhS.js +5 -0
  338. package/dist/session-store-DPPHkJBn.js +5 -0
  339. package/dist/session-store-DWLCWQFS.js +141 -0
  340. package/dist/session-store-qGufR_m5.js +141 -0
  341. package/dist/session-store-sUpA509O.js +141 -0
  342. package/dist/sessions-tools-9Z8TtdmP.js +5 -0
  343. package/dist/sessions-tools-BAZnoQLp.js +95 -0
  344. package/dist/sessions-tools-Bb_zF947.js +95 -0
  345. package/dist/sessions-tools-ClrKqLII.js +131 -0
  346. package/dist/sessions-tools-DFe23ZDD.js +5 -0
  347. package/dist/sessions-tools-JHSZ6Bns.js +5 -0
  348. package/dist/sessions-tools-TsRdeFb7.js +95 -0
  349. package/dist/sessions-tools-nYP3Agfs.js +5 -0
  350. package/dist/skill-loader-9jg876RH.js +160 -0
  351. package/dist/skill-loader-CM4KWQ7_.js +160 -0
  352. package/dist/skill-loader-CS3OP4Lr.js +160 -0
  353. package/dist/skill-loader-CnJDLNbY.js +7 -0
  354. package/dist/skill-loader-DRLgt5V2.js +160 -0
  355. package/dist/skill-loader-DVpEgYV2.js +7 -0
  356. package/dist/skill-loader-Df5T_UFl.js +7 -0
  357. package/dist/skill-loader-DxE-gZkT.js +7 -0
  358. package/dist/skill-runtime-8Xh5874w.js +104 -0
  359. package/dist/skill-runtime-B3aUdWKh.js +104 -0
  360. package/dist/skill-runtime-BKyhYvpW.js +5 -0
  361. package/dist/skill-runtime-BP0kZfmM.js +5 -0
  362. package/dist/skill-runtime-CHQT7c1k.js +5 -0
  363. package/dist/skill-runtime-CLK5HTVE.js +5 -0
  364. package/dist/skill-runtime-COyc3Bci.js +104 -0
  365. package/dist/skill-runtime-Cfd0OLkP.js +104 -0
  366. package/dist/skill-runtime-CvDXX7wN.js +5 -0
  367. package/dist/skill-runtime-D4REZnhY.js +104 -0
  368. package/dist/skill-runtime-DQRi9sIf.js +5 -0
  369. package/dist/skill-runtime-DRd56NWK.js +104 -0
  370. package/dist/skill-runtime-Dr0fimDf.js +5 -0
  371. package/dist/skill-runtime-DtO4i9vK.js +104 -0
  372. package/dist/src-9GyYED0T.js +63 -0
  373. package/dist/src-B9L6qb-Z.js +462 -0
  374. package/dist/src-BEjIVOmq.js +63 -0
  375. package/dist/src-BY3On_zO.js +462 -0
  376. package/dist/src-BdgKAlMQ.js +20 -0
  377. package/dist/src-C52A3OwC.js +301 -0
  378. package/dist/src-C8cbfjat.js +173 -0
  379. package/dist/src-CDLnbsLp.js +458 -0
  380. package/dist/src-CQ2lZvdF.js +462 -0
  381. package/dist/src-Cdwn9xpG.js +462 -0
  382. package/dist/src-CyCLoqIP.js +63 -0
  383. package/dist/src-D-OND_62.js +301 -0
  384. package/dist/src-D4VRanxB.js +458 -0
  385. package/dist/src-DFo8lVfV.js +300 -0
  386. package/dist/src-DJbpP4Gs.js +462 -0
  387. package/dist/src-DK-ayUx7.js +63 -0
  388. package/dist/src-DPfnArdr.js +300 -0
  389. package/dist/src-DTft7Qvt.js +63 -0
  390. package/dist/src-DgvFah8g.js +153 -0
  391. package/dist/src-H1I7JC2E.js +63 -0
  392. package/dist/src-TYvV_oFO.js +63 -0
  393. package/dist/src-lltU5gkh.js +20 -0
  394. package/dist/sub-agent-tools-BoMCZ6jz.js +39 -0
  395. package/dist/sub-agent-tools-CE8pVUdb.js +39 -0
  396. package/dist/sub-agent-tools-CQWNfYn_.js +39 -0
  397. package/dist/sub-agent-tools-CViiqebO.js +39 -0
  398. package/dist/sub-agent-tools-DgT4jUHC.js +39 -0
  399. package/dist/sub-agent-tools-Dla3ZB5N.js +39 -0
  400. package/dist/sub-agent-tools-Lbin_4S3.js +39 -0
  401. package/dist/tool-policy-1EBdJkSG.js +190 -0
  402. package/dist/tool-policy-B1bL0X-E.js +189 -0
  403. package/dist/tool-policy-NLbucl5-.js +189 -0
  404. package/dist/tool-policy-yNVTLNDY.js +189 -0
  405. package/dist/tts-elevenlabs-Bk24wQ2V.js +64 -0
  406. package/dist/tts-elevenlabs-CHrJZuNW.js +64 -0
  407. package/dist/tts-elevenlabs-DHqQsqMz.js +64 -0
  408. package/dist/tts-elevenlabs-TUKPkSV2.js +64 -0
  409. package/dist/vision-CW1YCKed.js +167 -0
  410. package/dist/vision-DPLmrwUA.js +167 -0
  411. package/dist/vision-Q4EOcBS6.js +167 -0
  412. package/dist/vision-XyAGO5La.js +167 -0
  413. package/dist/vision-tools-B5DNR28M.js +5 -0
  414. package/dist/vision-tools-CC9HSuvN.js +51 -0
  415. package/dist/vision-tools-Ca3OhtdX.js +51 -0
  416. package/dist/vision-tools-CpU2fSRv.js +51 -0
  417. package/dist/vision-tools-Ct52djW8.js +51 -0
  418. package/dist/vision-tools-DF7N2DDI.js +5 -0
  419. package/dist/vision-tools-DyP6lRA5.js +5 -0
  420. package/dist/vision-tools-RIVKEUeY.js +5 -0
  421. package/dist/voice-transcription-Bz2y0nPK.js +170 -0
  422. package/dist/voice-transcription-CVFcHpPF.js +170 -0
  423. package/dist/voice-transcription-CvQuWPYK.js +170 -0
  424. package/dist/voice-transcription-YqndiLA7.js +170 -0
  425. package/dist/website-watch-tools-B036Y8OQ.js +176 -0
  426. package/dist/website-watch-tools-B8CHie8v.js +5 -0
  427. package/dist/website-watch-tools-Brk5oIEv.js +176 -0
  428. package/dist/website-watch-tools-CJqRj_GB.js +5 -0
  429. package/dist/website-watch-tools-CSSEu3Qy.js +5 -0
  430. package/dist/website-watch-tools-D92dkYZa.js +176 -0
  431. package/dist/website-watch-tools-Du_a8lXq.js +176 -0
  432. package/dist/website-watch-tools-UdTBGgRk.js +5 -0
  433. package/package.json +147 -143
  434. package/scripts/fix-mojibake.mjs +166 -0
  435. package/static/web/assets/{index-BeAuHLb2.js → index-8bDizzaq.js} +2 -2
  436. package/static/web/assets/index-B5N1LHGR.css +1 -0
  437. package/static/web/index.html +2 -2
  438. package/static/web/assets/index-D2RfO0dG.css +0 -1
@@ -0,0 +1,1356 @@
1
+ const require_chunk = require('./chunk-jS-bbMI5.js');
2
+ const chalk = require_chunk.__toESM(require("chalk"));
3
+ const fs_extra = require_chunk.__toESM(require("fs-extra"));
4
+ const path = require_chunk.__toESM(require("path"));
5
+ const os = require_chunk.__toESM(require("os"));
6
+ const crypto = require_chunk.__toESM(require("crypto"));
7
+ const ws = require_chunk.__toESM(require("ws"));
8
+ const child_process = require_chunk.__toESM(require("child_process"));
9
+ const http = require_chunk.__toESM(require("http"));
10
+
11
+ //#region packages/gateway/src/server.ts
12
+ let activeServer = null;
13
+ const PUBLIC_API_PATHS = new Set(["/api/v1/check", "/api/status"]);
14
+ /**
15
+ * Thrown when the gateway cannot bind its WebSocket port.
16
+ *
17
+ * Most common cause: another gateway instance is already running on the same
18
+ * port (EADDRINUSE). The OS releases the port automatically on any exit,
19
+ * including crashes and SIGKILL — no separate lock file or cleanup is needed.
20
+ *
21
+ * To run a second gateway on the same host, use an isolated profile and a
22
+ * unique port (leave at least 20 ports between base ports):
23
+ * hyperclaw --profile rescue gateway --port 19001
24
+ */
25
+ var GatewayLockError = class extends Error {
26
+ code;
27
+ constructor(message, code = "GATEWAY_LOCK") {
28
+ super(message);
29
+ this.name = "GatewayLockError";
30
+ this.code = code;
31
+ }
32
+ };
33
+ var GatewayServer = class {
34
+ wss = null;
35
+ httpServer = null;
36
+ sessions = /* @__PURE__ */ new Map();
37
+ transcripts = /* @__PURE__ */ new Map();
38
+ sessionStore = null;
39
+ config;
40
+ startedAt = "";
41
+ stopCron = null;
42
+ channelRunner = null;
43
+ configWatcher = null;
44
+ configReloadDebounce = null;
45
+ constructor(config) {
46
+ this.config = config;
47
+ }
48
+ /** Start watching the config file for changes and hot-apply safe settings. */
49
+ startConfigWatcher() {
50
+ const mode = this.config.reloadMode ?? "hybrid";
51
+ if (mode === "off") return;
52
+ const configPath = this.config.deps.getConfigPath?.() ?? "";
53
+ if (!configPath) return;
54
+ const fsNode = require("fs");
55
+ const debounceMs = this.config.reloadDebounceMs ?? 300;
56
+ const tryWatch = () => {
57
+ try {
58
+ const watcher = fsNode.watch(configPath, { persistent: false }, (_event) => {
59
+ if (this.configReloadDebounce) clearTimeout(this.configReloadDebounce);
60
+ this.configReloadDebounce = setTimeout(() => void this.hotReloadConfig(), debounceMs);
61
+ });
62
+ this.configWatcher = watcher;
63
+ console.log(chalk.default.gray(` ⚙ Config watcher active (mode: ${mode}) — ${configPath}`));
64
+ } catch {
65
+ const dir = require("path").dirname(configPath);
66
+ try {
67
+ const dirWatcher = fsNode.watch(dir, { persistent: false }, (_event, filename) => {
68
+ if (filename && configPath.endsWith(filename) && fsNode.existsSync(configPath)) {
69
+ dirWatcher.close();
70
+ tryWatch();
71
+ }
72
+ });
73
+ } catch {}
74
+ }
75
+ };
76
+ tryWatch();
77
+ }
78
+ /** Hot-apply safe config changes without restarting. */
79
+ async hotReloadConfig() {
80
+ try {
81
+ const fs$1 = require("fs-extra");
82
+ const configPath = this.config.deps.getConfigPath?.() ?? "";
83
+ if (!configPath) return;
84
+ const raw = await fs$1.readJson(configPath).catch(() => null);
85
+ if (!raw) return;
86
+ const restartRequired = raw.gateway?.port !== this.config.port || raw.gateway?.bind !== this.config.bind;
87
+ if (restartRequired) {
88
+ console.log(chalk.default.yellow("\n ⚙ Config change requires gateway restart — restarting...\n"));
89
+ for (const s of this.sessions.values()) if (s.socket.readyState === 1) s.socket.send(JSON.stringify({
90
+ type: "gateway:reloading",
91
+ reason: "config-change"
92
+ }));
93
+ if (typeof this.config.deps.restartDaemon === "function") try {
94
+ await this.config.deps.restartDaemon();
95
+ } catch {}
96
+ else console.log(chalk.default.yellow(" ⚠ restartDaemon not available — restart manually: hyperclaw daemon restart\n"));
97
+ return;
98
+ }
99
+ if (raw.gateway?.hooks !== void 0) this.config.hooks = raw.gateway.hooks;
100
+ if (raw.gateway?.enabledChannels !== void 0) this.config.enabledChannels = raw.gateway.enabledChannels;
101
+ const newDm = raw.gateway?.dmScope ?? raw.session?.dmScope;
102
+ if (newDm !== void 0) this.config.dmScope = newDm === "main" ? "global" : newDm === "per-peer" ? "per-channel" : newDm;
103
+ if (typeof this.config.deps.onConfigReloaded === "function") this.config.deps.onConfigReloaded(raw);
104
+ const reloadMsg = JSON.stringify({
105
+ type: "gateway:config-reloaded",
106
+ ts: (/* @__PURE__ */ new Date()).toISOString()
107
+ });
108
+ for (const s of this.sessions.values()) if (s.socket.readyState === 1) s.socket.send(reloadMsg);
109
+ console.log(chalk.default.green(" ⚙ Config hot-reloaded (no restart needed)"));
110
+ } catch (e) {
111
+ console.log(chalk.default.yellow(` ⚙ Config reload failed: ${e.message}`));
112
+ }
113
+ }
114
+ async start() {
115
+ this.httpServer = http.default.createServer((req, res) => {
116
+ this.handleHttp(req, res);
117
+ });
118
+ this.wss = new ws.WebSocketServer({ server: this.httpServer });
119
+ this.wss.on("connection", this.handleConnection.bind(this));
120
+ await new Promise((resolve, reject) => {
121
+ this.httpServer.on("error", (err) => {
122
+ if (err.code === "EADDRINUSE") reject(new GatewayLockError(`another gateway instance is already listening on ws://${this.config.bind}:${this.config.port}`, "EADDRINUSE"));
123
+ else reject(new GatewayLockError(`failed to bind gateway socket on ws://${this.config.bind}:${this.config.port}: ${err.message}`, err.code || "BIND_ERROR"));
124
+ });
125
+ this.httpServer.listen(this.config.port, this.config.bind, () => resolve());
126
+ });
127
+ this.startedAt = (/* @__PURE__ */ new Date()).toISOString();
128
+ activeServer = this;
129
+ try {
130
+ this.sessionStore = await this.config.deps.createSessionStore(this.config.deps.getHyperClawDir());
131
+ } catch (_) {
132
+ this.sessionStore = null;
133
+ }
134
+ const icon = this.config.daemonMode ? "🩸" : "🦅";
135
+ const color = this.config.daemonMode ? chalk.default.red.bind(chalk.default) : chalk.default.hex("#06b6d4");
136
+ console.log(color(`\n ${icon} Gateway started: ws://${this.config.bind}:${this.config.port}\n`));
137
+ this.channelRunner = await this.config.deps.startChannelRunners({
138
+ port: this.config.port,
139
+ bind: this.config.bind,
140
+ authToken: this.config.deps.resolveGatewayToken(this.config.authToken)
141
+ });
142
+ if (this.config.hooks && this.config.deps.createHookLoader) {
143
+ const loader = this.config.deps.createHookLoader();
144
+ loader.execute("gateway:start", {}).catch(() => {});
145
+ this.stopCron = loader.startCronScheduler();
146
+ }
147
+ this.startConfigWatcher();
148
+ }
149
+ async stop() {
150
+ if (this.configWatcher) {
151
+ this.configWatcher.close();
152
+ this.configWatcher = null;
153
+ }
154
+ if (this.configReloadDebounce) clearTimeout(this.configReloadDebounce);
155
+ if (this.channelRunner) {
156
+ await this.channelRunner.stop();
157
+ this.channelRunner = null;
158
+ }
159
+ if (this.stopCron) {
160
+ this.stopCron();
161
+ this.stopCron = null;
162
+ }
163
+ for (const s of this.sessions.values()) s.socket.close(1001, "Gateway shutting down");
164
+ this.sessions.clear();
165
+ this.wss?.close();
166
+ await new Promise((resolve) => this.httpServer?.close(() => resolve()));
167
+ activeServer = null;
168
+ }
169
+ /** Returns false and sends 401 if auth required but missing/invalid. */
170
+ async requireAuth(req, res) {
171
+ const token = this.config.deps.resolveGatewayToken(this.config.authToken);
172
+ const auth = req.headers.authorization;
173
+ if (!token && !auth) return true;
174
+ if (!auth || !auth.startsWith("Bearer ")) {
175
+ res.writeHead(401, { "Content-Type": "application/json" });
176
+ res.end(JSON.stringify({
177
+ error: "Unauthorized",
178
+ hint: "Authorization: Bearer <gateway_token_or_developer_key>"
179
+ }));
180
+ return false;
181
+ }
182
+ const bearer = auth.slice(7);
183
+ if (token && bearer === token) return true;
184
+ if (this.config.deps.validateApiAuth) {
185
+ const ok = await this.config.deps.validateApiAuth(bearer);
186
+ if (ok) return true;
187
+ }
188
+ res.writeHead(401, { "Content-Type": "application/json" });
189
+ res.end(JSON.stringify({
190
+ error: "Unauthorized",
191
+ hint: "Authorization: Bearer <gateway_token_or_developer_key>"
192
+ }));
193
+ return false;
194
+ }
195
+ /** Resolve real client IP, honouring X-Forwarded-For only when the socket peer is a trusted proxy. */
196
+ resolveClientIp(req) {
197
+ const socketIp = req.socket.remoteAddress ?? "127.0.0.1";
198
+ const trusted = this.config.trustedProxies ?? [];
199
+ if (trusted.length === 0) return socketIp;
200
+ const isTrusted = trusted.some((proxy) => {
201
+ if (proxy === socketIp) return true;
202
+ if (proxy.includes("/")) try {
203
+ const [base, bits] = proxy.split("/");
204
+ const mask = ~((1 << 32 - parseInt(bits, 10)) - 1);
205
+ const ipToNum = (ip) => ip.split(".").reduce((acc, octet) => (acc << 8) + parseInt(octet, 10), 0);
206
+ return (ipToNum(socketIp) & mask) === (ipToNum(base) & mask);
207
+ } catch {
208
+ return false;
209
+ }
210
+ return false;
211
+ });
212
+ if (!isTrusted) return socketIp;
213
+ const xff = req.headers["x-forwarded-for"];
214
+ return xff ? xff.split(",")[0].trim() : socketIp;
215
+ }
216
+ configRpcRateLimit = /* @__PURE__ */ new Map();
217
+ CONFIG_RPC_MAX = 3;
218
+ CONFIG_RPC_WINDOW_MS = 6e4;
219
+ checkConfigRpcRateLimit(key) {
220
+ const now = Date.now();
221
+ let entry = this.configRpcRateLimit.get(key);
222
+ if (!entry || now - entry.windowStart > this.CONFIG_RPC_WINDOW_MS) entry = {
223
+ count: 0,
224
+ windowStart: now
225
+ };
226
+ entry.count++;
227
+ this.configRpcRateLimit.set(key, entry);
228
+ if (entry.count > this.CONFIG_RPC_MAX) {
229
+ const retryAfterMs = this.CONFIG_RPC_WINDOW_MS - (now - entry.windowStart);
230
+ return {
231
+ ok: false,
232
+ retryAfterMs
233
+ };
234
+ }
235
+ return { ok: true };
236
+ }
237
+ isProtectedApiPath(pathname) {
238
+ return pathname.startsWith("/api/") && !PUBLIC_API_PATHS.has(pathname);
239
+ }
240
+ resolveWebhookChannelId(pathname) {
241
+ if (!pathname.startsWith("/webhook/")) return null;
242
+ const parts = pathname.split("/").filter(Boolean);
243
+ if (parts.length !== 2) return null;
244
+ const channelId = parts[1] ?? "";
245
+ return /^[a-z0-9-]+$/i.test(channelId) ? channelId : null;
246
+ }
247
+ async handleHttp(req, res) {
248
+ const requestUrl = new URL(req.url || "/", "http://localhost");
249
+ const pathname = requestUrl.pathname;
250
+ res.setHeader("Access-Control-Allow-Origin", "*");
251
+ res.setHeader("Content-Type", "application/json");
252
+ if (req.method === "OPTIONS") {
253
+ res.writeHead(204);
254
+ res.end();
255
+ return;
256
+ }
257
+ if (this.isProtectedApiPath(pathname) && !await this.requireAuth(req, res)) return;
258
+ if (pathname === "/api/v1/check") {
259
+ res.writeHead(200);
260
+ res.end(JSON.stringify({
261
+ ok: true,
262
+ service: "hyperclaw",
263
+ version: "5.4.0"
264
+ }));
265
+ return;
266
+ }
267
+ if ((pathname === "/api/v1/config/apply" || pathname === "/api/v1/config/patch") && req.method === "POST") {
268
+ const clientIp = this.resolveClientIp(req);
269
+ const deviceId = req.headers["x-hyperclaw-device"] || "anon";
270
+ const rlKey = `${deviceId}:${clientIp}`;
271
+ const rl = this.checkConfigRpcRateLimit(rlKey);
272
+ if (!rl.ok) {
273
+ res.writeHead(429, { "Retry-After": String(Math.ceil((rl.retryAfterMs ?? 6e4) / 1e3)) });
274
+ res.end(JSON.stringify({
275
+ error: "UNAVAILABLE",
276
+ retryAfterMs: rl.retryAfterMs,
277
+ hint: "Config RPC is rate-limited to 3 requests per 60 seconds."
278
+ }));
279
+ return;
280
+ }
281
+ let body = "";
282
+ req.on("data", (c) => body += c);
283
+ req.on("end", async () => {
284
+ try {
285
+ const payload = JSON.parse(body || "{}");
286
+ const configPath = this.config.deps.getConfigPath();
287
+ const current = await fs_extra.default.readJson(configPath).catch(() => ({}));
288
+ let next;
289
+ if (pathname.endsWith("/apply")) next = payload;
290
+ else next = {
291
+ ...current,
292
+ ...payload
293
+ };
294
+ await fs_extra.default.writeJson(configPath, next, { spaces: 2 });
295
+ res.writeHead(200);
296
+ res.end(JSON.stringify({
297
+ ok: true,
298
+ action: pathname.endsWith("/apply") ? "apply" : "patch"
299
+ }));
300
+ } catch (e) {
301
+ res.writeHead(400);
302
+ res.end(JSON.stringify({ error: e.message }));
303
+ }
304
+ });
305
+ return;
306
+ }
307
+ if (pathname === "/api/v1/pi" && req.method === "POST") {
308
+ let body = "";
309
+ req.on("data", (c) => body += c);
310
+ req.on("end", async () => {
311
+ try {
312
+ const handler = this.config.deps.createPiRPCHandler((msg, opts) => this.callAgent(msg, {
313
+ currentSessionId: opts?.currentSessionId,
314
+ source: opts?.source
315
+ }), () => this.getSessionsList());
316
+ const rpcReq = JSON.parse(body || "{}");
317
+ const rpcRes = await handler(rpcReq);
318
+ res.writeHead(200);
319
+ res.end(JSON.stringify(rpcRes));
320
+ } catch (e) {
321
+ res.writeHead(500);
322
+ res.end(JSON.stringify({
323
+ jsonrpc: "2.0",
324
+ error: {
325
+ code: -32700,
326
+ message: e.message || "Parse error"
327
+ }
328
+ }));
329
+ }
330
+ });
331
+ return;
332
+ }
333
+ if (pathname === "/api/status") {
334
+ const cfg = this.loadConfig();
335
+ res.writeHead(200);
336
+ res.end(JSON.stringify({
337
+ running: true,
338
+ port: this.config.port,
339
+ channels: this.config.enabledChannels,
340
+ model: cfg?.provider?.modelId || "unknown",
341
+ agentName: cfg?.identity?.agentName || "Hyper",
342
+ sessions: this.sessions.size,
343
+ uptime: this.startedAt ? `${Math.round((Date.now() - new Date(this.startedAt).getTime()) / 1e3)}s` : "0s",
344
+ daemonMode: this.config.daemonMode ?? false
345
+ }));
346
+ return;
347
+ }
348
+ if (pathname === "/api/traces" && req.method === "GET") {
349
+ (async () => {
350
+ const params = requestUrl.searchParams;
351
+ const limit = Math.min(100, parseInt(params.get("limit") || "50", 10) || 50);
352
+ try {
353
+ const traces = this.config.deps.listTraces ? await this.config.deps.listTraces(this.config.deps.getHyperClawDir(), limit) : [];
354
+ res.writeHead(200);
355
+ res.end(JSON.stringify({ traces }));
356
+ } catch {
357
+ res.writeHead(500);
358
+ res.end(JSON.stringify({ error: "Failed to list traces" }));
359
+ }
360
+ })();
361
+ return;
362
+ }
363
+ if (pathname === "/api/costs" && req.method === "GET") {
364
+ (async () => {
365
+ const params = requestUrl.searchParams;
366
+ const sessionId = params.get("sessionId");
367
+ const hcDir = this.config.deps.getHyperClawDir();
368
+ try {
369
+ if (sessionId && this.config.deps.getSessionSummary) {
370
+ const summary = await this.config.deps.getSessionSummary(hcDir, sessionId);
371
+ res.writeHead(200);
372
+ res.end(JSON.stringify({
373
+ sessionId,
374
+ summary
375
+ }));
376
+ } else if (this.config.deps.getGlobalSummary) {
377
+ const summary = await this.config.deps.getGlobalSummary(this.config.deps.getHyperClawDir());
378
+ res.writeHead(200);
379
+ res.end(JSON.stringify({ summary }));
380
+ }
381
+ } catch (e) {
382
+ res.writeHead(500);
383
+ res.end(JSON.stringify({ error: e.message }));
384
+ }
385
+ })();
386
+ return;
387
+ }
388
+ if (pathname === "/api/remote/restart" && req.method === "POST") {
389
+ (async () => {
390
+ const hcDir = this.config.deps.getHyperClawDir();
391
+ const pidFile = path.default.join(hcDir, "gateway.pid");
392
+ let didSpawn = false;
393
+ try {
394
+ if (await fs_extra.default.pathExists(pidFile)) {
395
+ const storedPid = parseInt(await fs_extra.default.readFile(pidFile, "utf8"), 10);
396
+ if (storedPid === process.pid && this.config.daemonMode) {
397
+ const runMainPath = this.config.deps.getRunMainPath?.() || process.argv[1] || require.main?.filename || path.default.resolve(process.cwd(), "dist/run-main.js");
398
+ const child = (0, child_process.spawn)(process.execPath, [
399
+ runMainPath,
400
+ "daemon",
401
+ "restart"
402
+ ], {
403
+ detached: true,
404
+ stdio: "ignore",
405
+ env: process.env,
406
+ cwd: process.cwd()
407
+ });
408
+ child.unref();
409
+ didSpawn = true;
410
+ }
411
+ }
412
+ } catch (e) {
413
+ if (process.env.DEBUG) console.error("[gateway] daemon restart spawn:", e?.message);
414
+ }
415
+ res.writeHead(200);
416
+ res.end(JSON.stringify({
417
+ accepted: true,
418
+ message: didSpawn ? "Restarting daemon..." : "Gateway does not run as daemon. Run: hyperclaw daemon start, or from remote: ssh user@host \"hyperclaw daemon restart\"",
419
+ restarted: didSpawn
420
+ }));
421
+ })();
422
+ return;
423
+ }
424
+ if (pathname === "/api/v1/tts" && req.method === "POST") {
425
+ let body = "";
426
+ req.on("data", (c) => body += c);
427
+ req.on("end", async () => {
428
+ try {
429
+ const { text } = JSON.parse(body || "{}");
430
+ const cfg = this.loadConfig();
431
+ const apiKey = cfg?.talkMode?.apiKey || process.env.ELEVENLABS_API_KEY;
432
+ if (!apiKey || !text) {
433
+ res.writeHead(400);
434
+ res.end(JSON.stringify({ error: "Missing text or ELEVENLABS_API_KEY" }));
435
+ return;
436
+ }
437
+ const audio = this.config.deps.textToSpeech ? await this.config.deps.textToSpeech(text.slice(0, 4e3), {
438
+ apiKey,
439
+ voiceId: cfg?.talkMode?.voiceId,
440
+ modelId: cfg?.talkMode?.modelId
441
+ }) : null;
442
+ if (!audio) {
443
+ res.writeHead(502);
444
+ res.end(JSON.stringify({ error: "TTS failed" }));
445
+ return;
446
+ }
447
+ res.writeHead(200, { "Content-Type": "application/json" });
448
+ res.end(JSON.stringify({
449
+ format: "mp3",
450
+ data: audio
451
+ }));
452
+ } catch (e) {
453
+ res.writeHead(500);
454
+ res.end(JSON.stringify({ error: e.message }));
455
+ }
456
+ });
457
+ return;
458
+ }
459
+ if (pathname === "/api/nodes" && req.method === "GET") {
460
+ try {
461
+ const NR = this.config.deps.NodeRegistry;
462
+ const nodes = NR ? NR.getNodes().map((n) => ({
463
+ nodeId: n.nodeId,
464
+ platform: n.platform,
465
+ capabilities: n.capabilities,
466
+ deviceName: n.deviceName,
467
+ connectedAt: n.connectedAt,
468
+ lastSeenAt: n.lastSeenAt
469
+ })) : [];
470
+ res.writeHead(200);
471
+ res.end(JSON.stringify({ nodes }));
472
+ } catch (e) {
473
+ res.writeHead(500);
474
+ res.end(JSON.stringify({ error: e.message }));
475
+ }
476
+ return;
477
+ }
478
+ if (pathname === "/api/terminal" && req.method === "POST") {
479
+ let body = "";
480
+ req.on("data", (c) => body += c);
481
+ req.on("end", () => {
482
+ try {
483
+ const parsed = JSON.parse(body || "{}");
484
+ const command = typeof parsed.command === "string" ? parsed.command.trim() : "";
485
+ if (!command || command.length > 500) {
486
+ res.writeHead(400);
487
+ res.end(JSON.stringify({ error: "Invalid command" }));
488
+ return;
489
+ }
490
+ const shell = process.platform === "win32" ? process.env.COMSPEC || "cmd.exe" : process.env.SHELL || "/bin/bash";
491
+ const args = process.platform === "win32" ? [
492
+ "/d",
493
+ "/s",
494
+ "/c",
495
+ command
496
+ ] : ["-lc", command];
497
+ const cwd = process.cwd();
498
+ const child = (0, child_process.spawn)(shell, args, {
499
+ cwd,
500
+ env: process.env
501
+ });
502
+ let stdout = "";
503
+ let stderr = "";
504
+ child.stdout.on("data", (chunk) => {
505
+ stdout += chunk.toString();
506
+ if (stdout.length > 16e3) stdout = stdout.slice(-16e3);
507
+ });
508
+ child.stderr.on("data", (chunk) => {
509
+ stderr += chunk.toString();
510
+ if (stderr.length > 8e3) stderr = stderr.slice(-8e3);
511
+ });
512
+ child.on("error", (e) => {
513
+ res.writeHead(500);
514
+ res.end(JSON.stringify({ error: e.message || "Failed to start shell" }));
515
+ });
516
+ child.on("close", (code) => {
517
+ try {
518
+ res.writeHead(200);
519
+ res.end(JSON.stringify({
520
+ ok: code === 0,
521
+ code,
522
+ stdout,
523
+ stderr,
524
+ user: os.default.userInfo().username,
525
+ hostname: os.default.hostname(),
526
+ cwd
527
+ }));
528
+ } catch {}
529
+ });
530
+ } catch (e) {
531
+ res.writeHead(500);
532
+ res.end(JSON.stringify({ error: e.message || "Failed to run command" }));
533
+ }
534
+ });
535
+ return;
536
+ }
537
+ if (pathname === "/api/chat" && req.method === "POST") {
538
+ let body = "";
539
+ req.on("data", (c) => body += c);
540
+ req.on("end", async () => {
541
+ try {
542
+ const parsed = JSON.parse(body);
543
+ const { message } = parsed;
544
+ const agentId = parsed.agentId;
545
+ const sessionKey = parsed.sessionKey;
546
+ const source = req.headers["x-hyperclaw-source"] || "unknown";
547
+ const response = await this.callAgent(message, {
548
+ source,
549
+ agentId,
550
+ sessionKey
551
+ });
552
+ res.writeHead(200);
553
+ res.end(JSON.stringify({ response }));
554
+ } catch (e) {
555
+ res.writeHead(500);
556
+ res.end(JSON.stringify({ error: e.message }));
557
+ }
558
+ });
559
+ return;
560
+ }
561
+ if (pathname === "/api/webhook/inbound" && req.method === "POST") {
562
+ let body = "";
563
+ req.on("data", (c) => body += c);
564
+ req.on("end", async () => {
565
+ try {
566
+ const parsed = typeof body === "string" ? JSON.parse(body || "{}") : {};
567
+ const message = parsed.message || parsed.text || parsed.prompt || String(parsed);
568
+ if (!message || typeof message !== "string") {
569
+ res.writeHead(400);
570
+ res.end(JSON.stringify({ error: "Body must include \"message\" or \"text\" or \"prompt\"" }));
571
+ return;
572
+ }
573
+ const response = await this.callAgent(message, { source: "webhook:inbound" });
574
+ res.writeHead(200);
575
+ res.end(JSON.stringify({
576
+ ok: true,
577
+ response
578
+ }));
579
+ } catch (e) {
580
+ res.writeHead(500);
581
+ res.end(JSON.stringify({ error: e.message }));
582
+ }
583
+ });
584
+ return;
585
+ }
586
+ if (pathname === "/api/canvas/state" && req.method === "GET") {
587
+ const getState = this.config.deps.getCanvasState;
588
+ if (getState) getState().then((canvas) => {
589
+ res.writeHead(200, { "Content-Type": "application/json" });
590
+ res.end(JSON.stringify(canvas));
591
+ }).catch((e) => {
592
+ res.writeHead(500);
593
+ res.end(JSON.stringify({ error: e.message }));
594
+ });
595
+ else Promise.resolve().then(() => require("./renderer-B1ToXngl.js")).then(({ CanvasRenderer }) => {
596
+ const renderer = new CanvasRenderer();
597
+ renderer.getOrCreate().then((canvas) => {
598
+ res.writeHead(200, { "Content-Type": "application/json" });
599
+ res.end(JSON.stringify(canvas));
600
+ }).catch((e) => {
601
+ res.writeHead(500);
602
+ res.end(JSON.stringify({ error: e.message }));
603
+ });
604
+ }).catch((e) => {
605
+ res.writeHead(500);
606
+ res.end(JSON.stringify({ error: e.message }));
607
+ });
608
+ return;
609
+ }
610
+ if (pathname === "/api/canvas/a2ui" && req.method === "GET") {
611
+ const getA2UI = this.config.deps.getCanvasA2UI;
612
+ if (getA2UI) getA2UI().then((jsonl) => {
613
+ res.setHeader("Content-Type", "application/x-ndjson");
614
+ res.setHeader("Cache-Control", "no-cache");
615
+ res.writeHead(200);
616
+ res.end(jsonl + "\n");
617
+ }).catch((e) => {
618
+ res.writeHead(500);
619
+ res.end(JSON.stringify({ error: e.message }));
620
+ });
621
+ else Promise.resolve().then(() => require("./renderer-B1ToXngl.js")).then(({ CanvasRenderer }) => {
622
+ Promise.resolve().then(() => require("./a2ui-protocol-DEsfqO7h.js")).then(({ toBeginRendering, toJSONL }) => {
623
+ const renderer = new CanvasRenderer();
624
+ renderer.getOrCreate().then((canvas) => {
625
+ const msg = toBeginRendering(canvas);
626
+ res.setHeader("Content-Type", "application/x-ndjson");
627
+ res.setHeader("Cache-Control", "no-cache");
628
+ res.writeHead(200);
629
+ res.end(toJSONL([msg]) + "\n");
630
+ }).catch((e) => {
631
+ res.writeHead(500);
632
+ res.end(JSON.stringify({ error: e.message }));
633
+ });
634
+ });
635
+ }).catch((e) => {
636
+ res.writeHead(500);
637
+ res.end(JSON.stringify({ error: e.message }));
638
+ });
639
+ return;
640
+ }
641
+ if (pathname === "/chat" || pathname === "/chat/") {
642
+ res.setHeader("Content-Type", "text/html");
643
+ const staticDir = path.default.resolve(__dirname, "..", "static");
644
+ const fp = path.default.join(staticDir, "chat.html");
645
+ if (fs_extra.default.pathExistsSync(fp)) res.end(fs_extra.default.readFileSync(fp, "utf8"));
646
+ else res.end("<!DOCTYPE html><html><body><p>Chat UI not found. Run from package root or reinstall hyperclaw.</p></body></html>");
647
+ return;
648
+ }
649
+ if (pathname === "/dashboard" || pathname === "/dashboard/") {
650
+ res.setHeader("Content-Type", "text/html");
651
+ const staticDir = path.default.resolve(__dirname, "..", "static");
652
+ const fp = path.default.join(staticDir, "dashboard.html");
653
+ if (fs_extra.default.pathExistsSync(fp)) res.end(fs_extra.default.readFileSync(fp, "utf8"));
654
+ else res.end("<!DOCTYPE html><html><body><p>Dashboard: <a href=\"/api/status\">status</a></p></body></html>");
655
+ return;
656
+ }
657
+ if (pathname === "/" || pathname === "") {
658
+ res.writeHead(302, { Location: "/dashboard" });
659
+ res.end();
660
+ return;
661
+ }
662
+ if (pathname.startsWith("/webhook/")) {
663
+ const channelId = this.resolveWebhookChannelId(pathname);
664
+ if (!channelId || !this.channelRunner?.hasWebhookChannel?.(channelId)) {
665
+ res.writeHead(404);
666
+ res.end(JSON.stringify({ error: "Webhook channel not found" }));
667
+ return;
668
+ }
669
+ if (req.method === "GET") {
670
+ const params = requestUrl.searchParams;
671
+ if (channelId === "twitter") {
672
+ const crcToken = params.get("crc_token");
673
+ if (crcToken) {
674
+ const verified$1 = this.channelRunner?.verifyWebhook?.(channelId, "crc", crcToken, "");
675
+ if (verified$1) {
676
+ res.writeHead(200, { "Content-Type": "application/json" });
677
+ res.end(verified$1);
678
+ return;
679
+ }
680
+ res.writeHead(403);
681
+ res.end(JSON.stringify({ error: "Webhook verification failed" }));
682
+ return;
683
+ }
684
+ }
685
+ const mode = (params.get("hub.mode") || "").slice(0, 64);
686
+ const token = (params.get("hub.verify_token") || "").slice(0, 512);
687
+ const rawChallenge = params.get("hub.challenge") || "";
688
+ const challenge = rawChallenge.length > 0 && rawChallenge.length <= 512 && /^[\x20-\x7e]*$/.test(rawChallenge) ? rawChallenge : "";
689
+ const verified = this.channelRunner?.verifyWebhook?.(channelId, mode, token, challenge);
690
+ if (verified !== null && verified !== void 0 && typeof verified === "string") {
691
+ res.writeHead(200, { "Content-Type": "text/plain" });
692
+ res.end(verified);
693
+ } else {
694
+ res.writeHead(403);
695
+ res.end(JSON.stringify({ error: "Webhook verification failed" }));
696
+ }
697
+ return;
698
+ }
699
+ if (req.method === "POST") {
700
+ let body = "";
701
+ req.on("data", (c) => body += c);
702
+ req.on("end", async () => {
703
+ const host = req.headers["host"] || "localhost";
704
+ const baseUrl = `${req.headers["x-forwarded-proto"] === "https" ? "https" : "http"}://${host}`;
705
+ let opts;
706
+ if (channelId === "slack") opts = {
707
+ signature: req.headers["x-slack-signature"] || "",
708
+ timestamp: req.headers["x-slack-request-timestamp"] || ""
709
+ };
710
+ else if (channelId === "line") opts = { signature: req.headers["x-line-signature"] || "" };
711
+ else if (channelId === "sms") opts = {
712
+ twilioSignature: req.headers["x-twilio-signature"] || "",
713
+ webhookUrl: `${baseUrl}${req.url}`
714
+ };
715
+ else if (channelId === "instagram" || channelId === "messenger") opts = { signature: req.headers["x-hub-signature-256"] || "" };
716
+ else if (channelId === "viber") opts = { signature: req.headers["x-viber-signature"] || "" };
717
+ let challenge = void 0;
718
+ try {
719
+ if (this.channelRunner?.handleWebhook) challenge = await this.channelRunner.handleWebhook(channelId, body, opts);
720
+ } catch {
721
+ res.writeHead(403);
722
+ res.end(JSON.stringify({ error: "Webhook rejected" }));
723
+ return;
724
+ }
725
+ this.broadcast({
726
+ type: "webhook:received",
727
+ channelId,
728
+ payload: body
729
+ });
730
+ if (typeof challenge === "string") {
731
+ const contentType = challenge.trim().startsWith("{") ? "application/json" : "text/plain";
732
+ res.writeHead(200, { "Content-Type": contentType });
733
+ res.end(challenge);
734
+ } else {
735
+ res.writeHead(200);
736
+ res.end(JSON.stringify({ ok: true }));
737
+ }
738
+ });
739
+ return;
740
+ }
741
+ }
742
+ res.writeHead(404);
743
+ res.end(JSON.stringify({ error: "Not found" }));
744
+ }
745
+ handleConnection(ws$1, req) {
746
+ const id = crypto.default.randomBytes(8).toString("hex");
747
+ const source = req.headers["x-hyperclaw-source"] || "unknown";
748
+ const authToken = this.config.deps.resolveGatewayToken(this.config.authToken);
749
+ const session = {
750
+ id,
751
+ socket: ws$1,
752
+ authenticated: !authToken,
753
+ source,
754
+ connectedAt: (/* @__PURE__ */ new Date()).toISOString(),
755
+ lastActiveAt: (/* @__PURE__ */ new Date()).toISOString()
756
+ };
757
+ this.sessions.set(id, session);
758
+ this.broadcast({
759
+ type: "presence:join",
760
+ sessionId: id,
761
+ source
762
+ }, id);
763
+ console.log(chalk.default.gray(` [gateway] +connect ${source} ${id}`));
764
+ if (authToken && !session.authenticated) this.send(session, {
765
+ type: "connect.challenge",
766
+ sessionId: id
767
+ });
768
+ else {
769
+ this.send(session, {
770
+ type: "connect.ok",
771
+ sessionId: id,
772
+ version: "5.3.45",
773
+ heartbeatInterval: 3e4
774
+ });
775
+ if (this.config.hooks && this.config.deps.createHookLoader) this.config.deps.createHookLoader().execute("session:start", { sessionId: id }).catch(() => {});
776
+ }
777
+ ws$1.on("message", (data) => {
778
+ session.lastActiveAt = (/* @__PURE__ */ new Date()).toISOString();
779
+ try {
780
+ this.handleMessage(session, JSON.parse(data.toString()));
781
+ } catch {
782
+ this.send(session, {
783
+ type: "error",
784
+ message: "Invalid JSON"
785
+ });
786
+ }
787
+ });
788
+ ws$1.on("close", () => {
789
+ const s = this.sessions.get(id);
790
+ if (s?.nodeId && this.config.deps.NodeRegistry) {
791
+ this.config.deps.NodeRegistry.unregister(s.nodeId);
792
+ console.log(chalk.default.gray(` [gateway] -node ${s.nodeId}`));
793
+ }
794
+ if (this.config.hooks && !s?.nodeId && this.config.deps.createHookLoader) {
795
+ const turnCount = this.transcripts.get(id)?.length ?? 0;
796
+ this.config.deps.createHookLoader().execute("session:end", {
797
+ sessionId: id,
798
+ turnCount
799
+ }).catch(() => {});
800
+ }
801
+ this.transcripts.delete(id);
802
+ this.sessions.delete(id);
803
+ this.broadcast({
804
+ type: "presence:leave",
805
+ sessionId: id
806
+ });
807
+ console.log(chalk.default.gray(` [gateway] -disconnect ${id}`));
808
+ });
809
+ ws$1.on("error", (e) => console.log(chalk.default.yellow(` [gateway] error ${id}: ${e.message}`)));
810
+ }
811
+ handleMessage(session, msg) {
812
+ if (msg.type === "node_register") {
813
+ const nodeId = msg.nodeId || `node-${session.id}`;
814
+ const platform = msg.platform === "ios" || msg.platform === "android" ? msg.platform : "ios";
815
+ const capabilities = msg.capabilities || {};
816
+ const authToken = this.config.deps.resolveGatewayToken(this.config.authToken);
817
+ if (authToken && msg.token !== authToken) {
818
+ this.send(session, {
819
+ type: "node:error",
820
+ message: "Invalid token"
821
+ });
822
+ session.socket.close(4001, "Unauthorized");
823
+ return;
824
+ }
825
+ const NR = this.config.deps.NodeRegistry;
826
+ if (!NR) {
827
+ this.send(session, {
828
+ type: "node:error",
829
+ message: "Node registry not available"
830
+ });
831
+ return;
832
+ }
833
+ const cmdIdToResolve = /* @__PURE__ */ new Map();
834
+ session._nodePending = cmdIdToResolve;
835
+ const node = {
836
+ nodeId,
837
+ platform,
838
+ capabilities,
839
+ deviceName: msg.deviceName,
840
+ connectedAt: (/* @__PURE__ */ new Date()).toISOString(),
841
+ lastSeenAt: (/* @__PURE__ */ new Date()).toISOString(),
842
+ send: async (cmd) => {
843
+ return new Promise((resolve) => {
844
+ const timeout = setTimeout(() => {
845
+ cmdIdToResolve.delete(cmd.id);
846
+ resolve({
847
+ ok: false,
848
+ error: "Timeout"
849
+ });
850
+ }, 3e4);
851
+ cmdIdToResolve.set(cmd.id, { resolve: (r) => {
852
+ clearTimeout(timeout);
853
+ resolve(r);
854
+ } });
855
+ this.send(session, {
856
+ type: "node:command",
857
+ id: cmd.id,
858
+ command: cmd.type,
859
+ params: cmd.params
860
+ });
861
+ });
862
+ }
863
+ };
864
+ const protocolVersion = msg.protocolVersion ?? 1;
865
+ NR.register(node);
866
+ session.nodeId = nodeId;
867
+ session.authenticated = true;
868
+ session.source = `node:${platform}`;
869
+ this.send(session, {
870
+ type: "node:registered",
871
+ nodeId,
872
+ sessionId: session.id,
873
+ protocolVersion: Math.min(protocolVersion, 2),
874
+ heartbeatInterval: 3e4,
875
+ capabilities: Object.keys(capabilities)
876
+ });
877
+ console.log(chalk.default.gray(` [gateway] +node ${nodeId} (${platform})`));
878
+ return;
879
+ }
880
+ if (msg.type === "node:unregister" && session.nodeId && this.config.deps.NodeRegistry) {
881
+ this.config.deps.NodeRegistry.unregister(session.nodeId);
882
+ session.nodeId = void 0;
883
+ this.send(session, { type: "node:unregistered" });
884
+ return;
885
+ }
886
+ if (msg.type === "node:command_response" && session._nodePending) {
887
+ const r = session._nodePending.get(msg.id);
888
+ if (r) {
889
+ session._nodePending.delete(msg.id);
890
+ r.resolve({
891
+ ok: msg.ok,
892
+ data: msg.data,
893
+ error: msg.error
894
+ });
895
+ }
896
+ return;
897
+ }
898
+ if (msg.type === "session:restore" && (msg.restoreKey ?? msg.previousSessionId)) {
899
+ const key = String(msg.restoreKey ?? msg.previousSessionId);
900
+ session.restoreKey = key;
901
+ if (this.sessionStore) this.sessionStore.get(key).then((state) => {
902
+ if (state?.transcript?.length) {
903
+ const arr = this.transcripts.get(session.id) || [];
904
+ for (const t of state.transcript) if (!arr.some((x) => x.role === t.role && x.content === t.content)) arr.push(t);
905
+ if (arr.length > 100) arr.splice(0, arr.length - 80);
906
+ this.transcripts.set(session.id, arr);
907
+ this.send(session, {
908
+ type: "session:restored",
909
+ transcript: state.transcript
910
+ });
911
+ }
912
+ }).catch(() => {});
913
+ return;
914
+ }
915
+ if (msg.type === "auth") {
916
+ const resolved = this.config.deps.resolveGatewayToken(this.config.authToken);
917
+ if (resolved && msg.token === resolved) {
918
+ session.authenticated = true;
919
+ this.send(session, {
920
+ type: "auth.ok",
921
+ sessionId: session.id
922
+ });
923
+ } else session.socket.close(4001, "Unauthorized");
924
+ return;
925
+ }
926
+ if (!session.authenticated) {
927
+ this.send(session, {
928
+ type: "error",
929
+ message: "Not authenticated"
930
+ });
931
+ return;
932
+ }
933
+ switch (msg.type) {
934
+ case "ping": {
935
+ if (session.nodeId && this.config.deps.NodeRegistry) this.config.deps.NodeRegistry.updateLastSeen?.(session.nodeId);
936
+ this.send(session, {
937
+ type: "pong",
938
+ ts: Date.now()
939
+ });
940
+ break;
941
+ }
942
+ case "talk:enable":
943
+ session.talkMode = true;
944
+ this.send(session, {
945
+ type: "talk:ok",
946
+ enabled: true
947
+ });
948
+ break;
949
+ case "talk:disable":
950
+ session.talkMode = false;
951
+ this.send(session, {
952
+ type: "talk:ok",
953
+ enabled: false
954
+ });
955
+ break;
956
+ case "elevated:enable": {
957
+ const cfg = this.loadConfig();
958
+ const allowFrom = (cfg?.tools?.elevated)?.allowFrom ?? [];
959
+ const enabled = (cfg?.tools?.elevated)?.enabled === true;
960
+ if (!enabled) {
961
+ this.send(session, {
962
+ type: "error",
963
+ message: "Elevated mode disabled in config"
964
+ });
965
+ break;
966
+ }
967
+ if (allowFrom.length && !allowFrom.includes(session.source) && !allowFrom.includes("*")) {
968
+ this.send(session, {
969
+ type: "error",
970
+ message: "Source not in elevated allowFrom"
971
+ });
972
+ break;
973
+ }
974
+ session.elevated = true;
975
+ this.send(session, {
976
+ type: "elevated:ok",
977
+ enabled: true
978
+ });
979
+ break;
980
+ }
981
+ case "elevated:disable":
982
+ session.elevated = false;
983
+ this.send(session, {
984
+ type: "elevated:ok",
985
+ enabled: false
986
+ });
987
+ break;
988
+ case "chat:message": {
989
+ const content = typeof msg.content === "string" ? msg.content : String(msg.content ?? "");
990
+ if (this.config.hooks && this.config.deps.createHookLoader) this.config.deps.createHookLoader().execute("message:received", { sessionId: session.id }).catch(() => {});
991
+ const onDone = (response) => {
992
+ this.send(session, {
993
+ type: "chat:response",
994
+ content: response
995
+ });
996
+ if (session.talkMode && response) this.synthesizeAndSendAudio(session, response).catch(() => {});
997
+ if (this.config.hooks && this.config.deps.createHookLoader) this.config.deps.createHookLoader().execute("message:sent", {
998
+ sessionId: session.id,
999
+ message: content,
1000
+ response
1001
+ }).catch(() => {});
1002
+ };
1003
+ this.callAgent(content, {
1004
+ currentSessionId: session.id,
1005
+ onToken: (token) => this.send(session, {
1006
+ type: "chat:chunk",
1007
+ content: token
1008
+ }),
1009
+ onDone
1010
+ }).catch((e) => this.send(session, {
1011
+ type: "chat:response",
1012
+ content: `Error: ${e.message}`
1013
+ }));
1014
+ break;
1015
+ }
1016
+ case "gateway:status":
1017
+ this.send(session, {
1018
+ type: "gateway:status",
1019
+ sessions: this.sessions.size,
1020
+ uptime: this.startedAt
1021
+ });
1022
+ break;
1023
+ case "presence:list":
1024
+ this.send(session, {
1025
+ type: "presence:list",
1026
+ sessions: Array.from(this.sessions.entries()).map(([sid, s]) => ({
1027
+ id: sid,
1028
+ source: s.source
1029
+ }))
1030
+ });
1031
+ break;
1032
+ case "config:get":
1033
+ this.send(session, {
1034
+ type: "config:data",
1035
+ config: this.scrubConfig(this.loadConfig())
1036
+ });
1037
+ break;
1038
+ }
1039
+ }
1040
+ async callAgent(message, opts) {
1041
+ const sid = opts?.currentSessionId;
1042
+ const sess = sid ? this.sessions.get(sid) : void 0;
1043
+ const confirmTriggers = [
1044
+ "confirm",
1045
+ "yes",
1046
+ "ok",
1047
+ "elevate"
1048
+ ];
1049
+ if (sid && confirmTriggers.includes(message.trim().toLowerCase())) {
1050
+ const getPending = this.config.deps.getPending;
1051
+ const clearPending = this.config.deps.clearPending;
1052
+ if (getPending && clearPending) {
1053
+ const pending = getPending(sid);
1054
+ if (pending) {
1055
+ clearPending(sid);
1056
+ try {
1057
+ const result$1 = await pending.execute();
1058
+ opts?.onDone?.(result$1);
1059
+ return result$1;
1060
+ } catch (e) {
1061
+ const err = `Error: ${e.message}`;
1062
+ opts?.onDone?.(err);
1063
+ return err;
1064
+ }
1065
+ }
1066
+ }
1067
+ }
1068
+ const cfg = this.loadConfig();
1069
+ const elevated = sess?.elevated && (cfg?.tools?.elevated)?.enabled === true;
1070
+ const source = opts?.source || sess?.source;
1071
+ const hcDir = this.config.deps.getHyperClawDir();
1072
+ const effectiveKey = opts?.sessionKey || sid;
1073
+ const runOpts = {
1074
+ sessionId: sid,
1075
+ source,
1076
+ elevated,
1077
+ onToken: opts?.onToken,
1078
+ onDone: opts?.onDone,
1079
+ daemonMode: this.config.daemonMode,
1080
+ appendTranscript: (key, role, content, src) => this.appendTranscript(key, role, content, src),
1081
+ activeServer: activeServer ?? this,
1082
+ agentId: opts?.agentId,
1083
+ sessionKey: opts?.sessionKey,
1084
+ ...effectiveKey && this.sessionStore ? { getTranscript: async (k) => {
1085
+ const s = await this.sessionStore.get(k);
1086
+ return s?.transcript ?? null;
1087
+ } } : {}
1088
+ };
1089
+ if ((cfg?.observability)?.traces && this.config.deps.createRunTracer && this.config.deps.writeTraceToFile) {
1090
+ const tracer = this.config.deps.createRunTracer(sid, source);
1091
+ runOpts.onToolCall = tracer.onToolCall;
1092
+ runOpts.onToolResult = tracer.onToolResult;
1093
+ runOpts.onRunEnd = (usage, err) => {
1094
+ tracer.onRunEnd(usage, err);
1095
+ this.config.deps.writeTraceToFile(hcDir, tracer.trace).catch(() => {});
1096
+ };
1097
+ }
1098
+ const baseOnRunEnd = runOpts.onRunEnd;
1099
+ const recordUsage = this.config.deps.recordUsage;
1100
+ runOpts.onRunEnd = (usage, err) => {
1101
+ baseOnRunEnd?.(usage, err);
1102
+ const recordId = effectiveKey || sid;
1103
+ if (recordId && usage && recordUsage) recordUsage(hcDir, recordId, usage, {
1104
+ source,
1105
+ model: cfg?.provider?.modelId ?? void 0
1106
+ }).catch(() => {});
1107
+ };
1108
+ const result = await this.config.deps.runAgentEngine(message, runOpts);
1109
+ return result.text;
1110
+ }
1111
+ appendTranscript(sessionId, role, content, sourceOverride) {
1112
+ let arr = this.transcripts.get(sessionId);
1113
+ if (!arr) {
1114
+ arr = [];
1115
+ this.transcripts.set(sessionId, arr);
1116
+ }
1117
+ arr.push({
1118
+ role,
1119
+ content
1120
+ });
1121
+ if (arr.length > 100) arr.splice(0, arr.length - 80);
1122
+ const sess = this.sessions.get(sessionId);
1123
+ const storeKey = sess?.restoreKey || sessionId;
1124
+ const source = sourceOverride ?? sess?.source;
1125
+ if (this.sessionStore) this.sessionStore.append(storeKey, role, content, source).catch(() => {});
1126
+ }
1127
+ getSessionsList() {
1128
+ return Array.from(this.sessions.entries()).map(([id, s]) => ({
1129
+ id,
1130
+ source: s.source,
1131
+ connectedAt: s.connectedAt
1132
+ }));
1133
+ }
1134
+ sendToSession(sessionId, msg) {
1135
+ const s = this.sessions.get(sessionId);
1136
+ if (!s || s.socket.readyState !== ws.WebSocket.OPEN) return false;
1137
+ this.send(s, msg);
1138
+ return true;
1139
+ }
1140
+ getSessionHistory(sessionId, limit = 20) {
1141
+ const arr = this.transcripts.get(sessionId) ?? [];
1142
+ return arr.slice(-limit);
1143
+ }
1144
+ send(session, msg) {
1145
+ if (session.socket.readyState === ws.WebSocket.OPEN) session.socket.send(JSON.stringify(msg));
1146
+ }
1147
+ broadcast(msg, excludeId) {
1148
+ for (const [id, s] of this.sessions) if (id !== excludeId && s.authenticated) this.send(s, msg);
1149
+ }
1150
+ async synthesizeAndSendAudio(session, text) {
1151
+ const cfg = this.loadConfig();
1152
+ const talk = cfg?.talkMode;
1153
+ const apiKey = talk?.apiKey || process.env.ELEVENLABS_API_KEY;
1154
+ if (!apiKey) return;
1155
+ const textToSpeech = this.config.deps.textToSpeech;
1156
+ if (!textToSpeech) return;
1157
+ const audio = await textToSpeech(text.slice(0, 4e3), {
1158
+ apiKey,
1159
+ voiceId: talk?.voiceId,
1160
+ modelId: talk?.modelId || "eleven_multilingual_v2"
1161
+ });
1162
+ if (audio) this.send(session, {
1163
+ type: "chat:audio",
1164
+ format: "mp3",
1165
+ data: audio
1166
+ });
1167
+ }
1168
+ loadConfig() {
1169
+ if (this.config.deps.loadConfig) return this.config.deps.loadConfig();
1170
+ try {
1171
+ return fs_extra.default.readJsonSync(this.config.deps.getConfigPath());
1172
+ } catch {
1173
+ return null;
1174
+ }
1175
+ }
1176
+ scrubConfig(cfg) {
1177
+ if (!cfg) return null;
1178
+ const s = JSON.parse(JSON.stringify(cfg));
1179
+ if (s.provider?.apiKey) s.provider.apiKey = "***";
1180
+ if (s.gateway?.authToken) s.gateway.authToken = "***";
1181
+ return s;
1182
+ }
1183
+ getStatus() {
1184
+ return {
1185
+ running: true,
1186
+ port: this.config.port,
1187
+ sessions: this.sessions.size,
1188
+ startedAt: this.startedAt
1189
+ };
1190
+ }
1191
+ };
1192
+ const DEFAULT_PORT = 18789;
1193
+ async function startGateway(opts) {
1194
+ const deps = opts.deps;
1195
+ let base;
1196
+ let fullCfg = {};
1197
+ try {
1198
+ fullCfg = fs_extra.default.readJsonSync(deps.getConfigPath());
1199
+ base = fullCfg.gateway ?? {};
1200
+ } catch {
1201
+ base = {
1202
+ port: DEFAULT_PORT,
1203
+ bind: "127.0.0.1",
1204
+ authToken: "",
1205
+ runtime: "node",
1206
+ enabledChannels: [],
1207
+ hooks: true
1208
+ };
1209
+ }
1210
+ const portEnv = process.env.PORT || process.env.HYPERCLAW_PORT;
1211
+ const port = portEnv ? parseInt(portEnv, 10) || base.port : base.port;
1212
+ const sessionDm = fullCfg?.session?.dmScope;
1213
+ const gwDm = base.dmScope ?? sessionDm;
1214
+ const dmScope = gwDm === "main" ? "global" : gwDm === "per-peer" ? "per-channel" : gwDm;
1215
+ const cfg = {
1216
+ ...base,
1217
+ port: port ?? DEFAULT_PORT,
1218
+ bind: base.bind ?? "127.0.0.1",
1219
+ authToken: deps.resolveGatewayToken(base.authToken ?? "") ?? base.authToken ?? "",
1220
+ runtime: base.runtime ?? "node",
1221
+ enabledChannels: base.enabledChannels ?? [],
1222
+ hooks: base.hooks ?? true,
1223
+ dmScope: dmScope ?? base.dmScope,
1224
+ daemonMode: opts.daemonMode,
1225
+ deps
1226
+ };
1227
+ const server = new GatewayServer(cfg);
1228
+ await server.start();
1229
+ return server;
1230
+ }
1231
+ function getActiveServer() {
1232
+ return activeServer;
1233
+ }
1234
+ GatewayServer.prototype.getSessionsList = function() {
1235
+ const out = [];
1236
+ for (const [id, s] of this.sessions) out.push({
1237
+ id,
1238
+ source: s.source,
1239
+ connectedAt: s.connectedAt,
1240
+ lastActiveAt: s.lastActiveAt,
1241
+ talkMode: s.talkMode ?? false,
1242
+ nodeId: s.nodeId ?? null
1243
+ });
1244
+ return out;
1245
+ };
1246
+ GatewayServer.prototype.sendToSession = function(id, msg) {
1247
+ const session = this.sessions.get(id);
1248
+ if (!session || session.socket.readyState !== 1) return false;
1249
+ try {
1250
+ session.socket.send(JSON.stringify(msg));
1251
+ return true;
1252
+ } catch {
1253
+ return false;
1254
+ }
1255
+ };
1256
+ GatewayServer.prototype.getSessionHistory = function(id, limit) {
1257
+ const history = this.transcripts.get(id);
1258
+ if (!history) return [];
1259
+ return history.slice(-limit);
1260
+ };
1261
+
1262
+ //#endregion
1263
+ //#region src/gateway/deps-provider.ts
1264
+ async function createDefaultGatewayDeps() {
1265
+ const [paths, envResolve, sessionStore, channelRunner, hookLoader, core, devKeys, pendingApproval, observability, costTracker, tts, nodesRegistry, canvasRenderer, a2ui, daemon] = await Promise.all([
1266
+ Promise.resolve().then(() => require("./paths-D-QecARF.js")),
1267
+ Promise.resolve().then(() => require("./env-resolve-pIETNTpQ.js")),
1268
+ Promise.resolve().then(() => require("./session-store-7sEPyV16.js")),
1269
+ Promise.resolve().then(() => require("./runner-Cr1_mwnU.js")),
1270
+ Promise.resolve().then(() => require("./loader-Dq_cDlOW.js")),
1271
+ Promise.resolve().then(() => require("./src-H1I7JC2E.js")),
1272
+ Promise.resolve().then(() => require("./developer-keys-CzDxVczE.js")),
1273
+ Promise.resolve().then(() => require("./pending-approval-C4ZaHHWl.js")),
1274
+ Promise.resolve().then(() => require("./observability-BtLyuxcz.js")),
1275
+ Promise.resolve().then(() => require("./cost-tracker-DCXDUzBI.js")),
1276
+ Promise.resolve().then(() => require("./tts-elevenlabs-y6HGWWDS.js")),
1277
+ Promise.resolve().then(() => require("./nodes-registry-DLUZhEMS.js")),
1278
+ Promise.resolve().then(() => require("./renderer-B1ToXngl.js")),
1279
+ Promise.resolve().then(() => require("./a2ui-protocol-DEsfqO7h.js")),
1280
+ Promise.resolve().then(() => require("./daemon-D-klsy3i.js"))
1281
+ ]);
1282
+ const createSessionStore = async (baseDir) => {
1283
+ const store = await sessionStore.createFileSessionStore(baseDir);
1284
+ return store;
1285
+ };
1286
+ const createHookLoader = () => new hookLoader.HookLoader();
1287
+ const getCanvasState = async () => {
1288
+ const renderer = new canvasRenderer.CanvasRenderer();
1289
+ const canvas = await renderer.getOrCreate();
1290
+ return canvas;
1291
+ };
1292
+ const getCanvasA2UI = async () => {
1293
+ const renderer = new canvasRenderer.CanvasRenderer();
1294
+ const canvas = await renderer.getOrCreate();
1295
+ const msg = a2ui.toBeginRendering(canvas);
1296
+ return a2ui.toJSONL([msg]);
1297
+ };
1298
+ return {
1299
+ getHyperClawDir: paths.getHyperClawDir,
1300
+ getConfigPath: paths.getConfigPath,
1301
+ resolveGatewayToken: envResolve.resolveGatewayToken,
1302
+ validateApiAuth: async (bearer) => (await devKeys.validateDeveloperKey(bearer)).valid,
1303
+ createSessionStore,
1304
+ startChannelRunners: channelRunner.startChannelRunners,
1305
+ createHookLoader,
1306
+ runAgentEngine: core.runAgentEngine,
1307
+ createPiRPCHandler: core.createPiRPCHandler,
1308
+ listTraces: observability.listTraces,
1309
+ getSessionSummary: costTracker.getSessionSummary,
1310
+ getGlobalSummary: costTracker.getGlobalSummary,
1311
+ recordUsage: costTracker.recordUsage,
1312
+ textToSpeech: tts.textToSpeech,
1313
+ getPending: pendingApproval.getPending,
1314
+ clearPending: pendingApproval.clearPending,
1315
+ createRunTracer: observability.createRunTracer,
1316
+ writeTraceToFile: observability.writeTraceToFile,
1317
+ NodeRegistry: nodesRegistry.NodeRegistry,
1318
+ getCanvasState,
1319
+ getCanvasA2UI,
1320
+ restartDaemon: async () => {
1321
+ const dm = new daemon.DaemonManager();
1322
+ await dm.restart?.();
1323
+ }
1324
+ };
1325
+ }
1326
+
1327
+ //#endregion
1328
+ //#region src/gateway/server.ts
1329
+ /** Start gateway with default deps (paths, channels, hooks, etc.). */
1330
+ async function startGateway$1(opts) {
1331
+ const deps = await createDefaultGatewayDeps();
1332
+ return startGateway({
1333
+ ...opts,
1334
+ deps
1335
+ });
1336
+ }
1337
+
1338
+ //#endregion
1339
+ Object.defineProperty(exports, 'GatewayServer', {
1340
+ enumerable: true,
1341
+ get: function () {
1342
+ return GatewayServer;
1343
+ }
1344
+ });
1345
+ Object.defineProperty(exports, 'getActiveServer', {
1346
+ enumerable: true,
1347
+ get: function () {
1348
+ return getActiveServer;
1349
+ }
1350
+ });
1351
+ Object.defineProperty(exports, 'startGateway', {
1352
+ enumerable: true,
1353
+ get: function () {
1354
+ return startGateway$1;
1355
+ }
1356
+ });