hyperclaw 5.4.0 → 5.4.2

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