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