@johpaz/hive-agents 0.0.34 → 0.0.36

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 (466) hide show
  1. package/README.md +64 -39
  2. package/dist/hive.js +4539 -4586
  3. package/dist/ui/assets/AgentCreateForm-tJZv9FZC.js +1 -0
  4. package/dist/ui/assets/AgentDetailPage-Du-mRcAX.js +1 -0
  5. package/dist/ui/assets/AgentNewPage-DIFYd_Ys.js +1 -0
  6. package/dist/ui/assets/{AgentsPage-DhCjvDNa.js → AgentsPage-YvSgWRiw.js} +7 -7
  7. package/dist/ui/assets/CanvasPage-DtMwGvxf.js +33 -0
  8. package/dist/ui/assets/ChannelsPage-BdBXWHjj.js +8 -0
  9. package/dist/ui/assets/DashboardPage-ghl1ZguH.js +6 -0
  10. package/dist/ui/assets/{LoginPage-B30OrEBy.js → LoginPage-CAmSI9Vy.js} +1 -1
  11. package/dist/ui/assets/LogsPage-DAPBHkwK.js +1 -0
  12. package/dist/ui/assets/MeetingPage-WjjGOqqU.js +1 -0
  13. package/dist/ui/assets/{NotFound-HD1Yp9yK.js → NotFound-BMeQSGcG.js} +1 -1
  14. package/dist/ui/assets/ProvidersPage-Ct6HsAi1.js +1 -0
  15. package/dist/ui/assets/{RecoverPage-CLF6buGP.js → RecoverPage-DpW3l-yv.js} +1 -1
  16. package/dist/ui/assets/SettingsPage-DBJ7_E6C.js +9 -0
  17. package/dist/ui/assets/SetupPage-DKmLVUaj.js +1 -0
  18. package/dist/ui/assets/{WebChatPage-Um3VANzn.js → WebChatPage-CVRcKept.js} +2 -2
  19. package/dist/ui/assets/accordion-C5d5Rm5z.js +1 -0
  20. package/dist/ui/assets/{activity-SfJ6UDF2.js → activity-c3pNngT_.js} +1 -1
  21. package/dist/ui/assets/alert-C-NE-P3s.js +1 -0
  22. package/dist/ui/assets/{alert-dialog-M893TdvF.js → alert-dialog-C5mzbHdP.js} +1 -1
  23. package/dist/ui/assets/arrow-left-CBcbX5EZ.js +1 -0
  24. package/dist/ui/assets/badge-ChpACfWO.js +1 -0
  25. package/dist/ui/assets/{calendar-CMMeWsP-.js → calendar-B-KZ9RQO.js} +1 -1
  26. package/dist/ui/assets/{card-C7P3W6_y.js → card-CNf6BS2e.js} +1 -1
  27. package/dist/ui/assets/chevron-left-D4U-5A27.js +1 -0
  28. package/dist/ui/assets/chevron-right-CR4Skrf3.js +1 -0
  29. package/dist/ui/assets/chevron-up-BYhk0K2J.js +1 -0
  30. package/dist/ui/assets/{circle-alert-7koABcbO.js → circle-alert-CyHDwUj8.js} +1 -1
  31. package/dist/ui/assets/circle-check-Bb54Ebmu.js +1 -0
  32. package/dist/ui/assets/{cpu-mBJgRJzM.js → cpu-Cdgc_B1K.js} +1 -1
  33. package/dist/ui/assets/dialog-QnZ0ad8O.js +1 -0
  34. package/dist/ui/assets/{download-oaofq4K1.js → download-C3ifGMjJ.js} +1 -1
  35. package/dist/ui/assets/dropdown-menu-BK-CO3Od.js +1 -0
  36. package/dist/ui/assets/{es-eUrU2hyB.js → es-NQNoaWDx.js} +1 -1
  37. package/dist/ui/assets/{external-link-SkkF2Z7B.js → external-link-BvxYeTP1.js} +1 -1
  38. package/dist/ui/assets/{eye-B8lq7sWG.js → eye-DqNTU_GD.js} +1 -1
  39. package/dist/ui/assets/{file-text-0oYol8Bb.js → file-text-BT_9S9SM.js} +1 -1
  40. package/dist/ui/assets/{folder-open-DVYu2lgk.js → folder-open-BhH8y9ac.js} +1 -1
  41. package/dist/ui/assets/gauge-D_TMa4i9.js +1 -0
  42. package/dist/ui/assets/{globe-BVPd5DRa.js → globe-DeCQTCDJ.js} +1 -1
  43. package/dist/ui/assets/{hexagon-BIAFUAlQ.js → hexagon-DsGOUl-H.js} +1 -1
  44. package/dist/ui/assets/{history-BUAnaMQo.js → history-BSG-Ypqf.js} +1 -1
  45. package/dist/ui/assets/index-B2fCYtTS.css +2 -0
  46. package/dist/ui/assets/index-DMCjjdqf.js +116 -0
  47. package/dist/ui/assets/{info-DWioleen.js → info-NwLoa2Mj.js} +1 -1
  48. package/dist/ui/assets/{key-BCGwSKKc.js → key-3EP0dhkT.js} +1 -1
  49. package/dist/ui/assets/label-D2H1IR_J.js +1 -0
  50. package/dist/ui/assets/loader-circle-CZNax6kS.js +1 -0
  51. package/dist/ui/assets/{lock-D7PCO7GC.js → lock-Ei1_J-Nq.js} +1 -1
  52. package/dist/ui/assets/{pause-CI1JFH6r.js → pause-BUqah9Bi.js} +1 -1
  53. package/dist/ui/assets/play-NcZ4swwL.js +1 -0
  54. package/dist/ui/assets/plus-CX1xyhp5.js +1 -0
  55. package/dist/ui/assets/progress-BherYzY6.js +1 -0
  56. package/dist/ui/assets/{refresh-cw-BLmKlO4J.js → refresh-cw-DaYdjQFk.js} +1 -1
  57. package/dist/ui/assets/{save-M1nv6H3P.js → save-CUdYyHNy.js} +1 -1
  58. package/dist/ui/assets/scroll-area-DkeyX32e.js +1 -0
  59. package/dist/ui/assets/{send-ijRfR0gp.js → send-B0H5SEIE.js} +1 -1
  60. package/dist/ui/assets/{settings-BvXhlJCF.js → settings-Ds4SqD8s.js} +1 -1
  61. package/dist/ui/assets/{slider-DrDFLwXh.js → slider-CsiUDxc3.js} +1 -1
  62. package/dist/ui/assets/{sparkles-C4MACMbE.js → sparkles-yUEb-7oH.js} +1 -1
  63. package/dist/ui/assets/{square-D_-gRT1l.js → square-BD81nFtN.js} +1 -1
  64. package/dist/ui/assets/switch-BDwN8RYV.js +1 -0
  65. package/dist/ui/assets/{table-DWEJJiuF.js → table-CSc8ubon.js} +1 -1
  66. package/dist/ui/assets/terminal-DN38Q456.js +1 -0
  67. package/dist/ui/assets/{textarea-CwPvQVAG.js → textarea-CXgXWKrT.js} +1 -1
  68. package/dist/ui/assets/{trash-2-Blkv31Dz.js → trash-2-CNjMkoq6.js} +1 -1
  69. package/dist/ui/assets/{triangle-alert-BKgbd30k.js → triangle-alert-C9Y8Ub4X.js} +1 -1
  70. package/dist/ui/assets/useProviders-C6_QHsEi.js +1 -0
  71. package/dist/ui/assets/{vendor-radix-JY4ncZrD.js → vendor-radix-cw1bQaVC.js} +4 -4
  72. package/dist/ui/assets/{vendor-react-CscwQerf.js → vendor-react-D4s9E-zj.js} +1 -1
  73. package/dist/ui/assets/{volume-2-BiUgObeI.js → volume-2-CeSXNDv4.js} +1 -1
  74. package/dist/ui/assets/{zap-CpyuQJEC.js → zap-hlXjpSeA.js} +1 -1
  75. package/dist/ui/dist/assets/AgentCreateForm-tJZv9FZC.js +1 -0
  76. package/dist/ui/dist/assets/AgentDetailPage-Du-mRcAX.js +1 -0
  77. package/dist/ui/dist/assets/AgentNewPage-DIFYd_Ys.js +1 -0
  78. package/dist/ui/dist/assets/AgentsPage-YvSgWRiw.js +10 -0
  79. package/dist/ui/dist/assets/CanvasPage-DtMwGvxf.js +33 -0
  80. package/dist/ui/dist/assets/ChannelsPage-BdBXWHjj.js +8 -0
  81. package/dist/ui/dist/assets/DashboardPage-ghl1ZguH.js +6 -0
  82. package/dist/ui/dist/assets/LoginPage-CAmSI9Vy.js +1 -0
  83. package/dist/ui/dist/assets/LogsPage-DAPBHkwK.js +1 -0
  84. package/dist/ui/dist/assets/MeetingPage-WjjGOqqU.js +1 -0
  85. package/dist/ui/dist/assets/NotFound-BMeQSGcG.js +1 -0
  86. package/dist/ui/dist/assets/ProvidersPage-Ct6HsAi1.js +1 -0
  87. package/dist/ui/dist/assets/RecoverPage-DpW3l-yv.js +1 -0
  88. package/dist/ui/dist/assets/SettingsPage-DBJ7_E6C.js +9 -0
  89. package/dist/ui/dist/assets/SetupPage-DKmLVUaj.js +1 -0
  90. package/dist/ui/dist/assets/WebChatPage-CVRcKept.js +16 -0
  91. package/dist/ui/dist/assets/accordion-C5d5Rm5z.js +1 -0
  92. package/dist/ui/dist/assets/activity-c3pNngT_.js +1 -0
  93. package/dist/ui/dist/assets/alert-C-NE-P3s.js +1 -0
  94. package/dist/ui/dist/assets/alert-dialog-C5mzbHdP.js +1 -0
  95. package/dist/ui/dist/assets/arrow-left-CBcbX5EZ.js +1 -0
  96. package/dist/ui/dist/assets/badge-ChpACfWO.js +1 -0
  97. package/dist/ui/dist/assets/calendar-B-KZ9RQO.js +1 -0
  98. package/dist/ui/dist/assets/card-CNf6BS2e.js +1 -0
  99. package/dist/ui/dist/assets/chevron-left-D4U-5A27.js +1 -0
  100. package/dist/ui/dist/assets/chevron-right-CR4Skrf3.js +1 -0
  101. package/dist/ui/dist/assets/chevron-up-BYhk0K2J.js +1 -0
  102. package/dist/ui/dist/assets/circle-alert-CyHDwUj8.js +1 -0
  103. package/dist/ui/dist/assets/circle-check-Bb54Ebmu.js +1 -0
  104. package/dist/ui/dist/assets/cpu-Cdgc_B1K.js +1 -0
  105. package/dist/ui/dist/assets/dialog-QnZ0ad8O.js +1 -0
  106. package/dist/ui/dist/assets/download-C3ifGMjJ.js +1 -0
  107. package/dist/ui/dist/assets/dropdown-menu-BK-CO3Od.js +1 -0
  108. package/dist/ui/dist/assets/es-NQNoaWDx.js +1 -0
  109. package/dist/ui/dist/assets/external-link-BvxYeTP1.js +1 -0
  110. package/dist/ui/dist/assets/eye-DqNTU_GD.js +1 -0
  111. package/dist/ui/dist/assets/file-text-BT_9S9SM.js +1 -0
  112. package/dist/ui/dist/assets/folder-open-BhH8y9ac.js +1 -0
  113. package/dist/ui/dist/assets/format-GVHeOyWI.js +1 -0
  114. package/dist/ui/dist/assets/gateway-url-COCbW0IR.js +1 -0
  115. package/dist/ui/dist/assets/gauge-D_TMa4i9.js +1 -0
  116. package/dist/ui/dist/assets/globe-DeCQTCDJ.js +1 -0
  117. package/dist/ui/dist/assets/hexagon-DsGOUl-H.js +1 -0
  118. package/dist/ui/dist/assets/history-BSG-Ypqf.js +1 -0
  119. package/dist/ui/dist/assets/index-B2fCYtTS.css +2 -0
  120. package/dist/ui/dist/assets/index-DMCjjdqf.js +116 -0
  121. package/dist/ui/dist/assets/info-NwLoa2Mj.js +1 -0
  122. package/dist/ui/dist/assets/key-3EP0dhkT.js +1 -0
  123. package/dist/ui/dist/assets/label-D2H1IR_J.js +1 -0
  124. package/dist/ui/dist/assets/loader-circle-CZNax6kS.js +1 -0
  125. package/dist/ui/dist/assets/lock-Ei1_J-Nq.js +1 -0
  126. package/dist/ui/dist/assets/pause-BUqah9Bi.js +1 -0
  127. package/dist/ui/dist/assets/play-NcZ4swwL.js +1 -0
  128. package/dist/ui/dist/assets/plus-CX1xyhp5.js +1 -0
  129. package/dist/ui/dist/assets/progress-BherYzY6.js +1 -0
  130. package/dist/ui/dist/assets/refresh-cw-DaYdjQFk.js +1 -0
  131. package/dist/ui/dist/assets/rolldown-runtime-S-ySWqyJ.js +1 -0
  132. package/dist/ui/dist/assets/save-CUdYyHNy.js +1 -0
  133. package/dist/ui/dist/assets/scroll-area-DkeyX32e.js +1 -0
  134. package/dist/ui/dist/assets/send-B0H5SEIE.js +1 -0
  135. package/dist/ui/dist/assets/settings-Ds4SqD8s.js +1 -0
  136. package/dist/ui/dist/assets/slider-CsiUDxc3.js +14 -0
  137. package/dist/ui/dist/assets/sparkles-yUEb-7oH.js +1 -0
  138. package/dist/ui/dist/assets/square-BD81nFtN.js +1 -0
  139. package/dist/ui/dist/assets/switch-BDwN8RYV.js +1 -0
  140. package/dist/ui/dist/assets/table-CSc8ubon.js +1 -0
  141. package/dist/ui/dist/assets/terminal-DN38Q456.js +1 -0
  142. package/dist/ui/dist/assets/textarea-CXgXWKrT.js +1 -0
  143. package/dist/ui/dist/assets/trash-2-CNjMkoq6.js +1 -0
  144. package/dist/ui/dist/assets/triangle-alert-C9Y8Ub4X.js +1 -0
  145. package/dist/ui/dist/assets/useProviders-C6_QHsEi.js +1 -0
  146. package/dist/ui/dist/assets/utils-3pnRFmFe.js +1 -0
  147. package/dist/ui/dist/assets/vendor-charts-Bu2lyBKP.js +65 -0
  148. package/dist/ui/dist/assets/vendor-query-DsWPbQdG.js +1 -0
  149. package/dist/ui/dist/assets/vendor-radix-cw1bQaVC.js +63 -0
  150. package/dist/ui/dist/assets/vendor-react-D4s9E-zj.js +1 -0
  151. package/dist/ui/dist/assets/vendor-router-C9pIYwbJ.js +3 -0
  152. package/dist/ui/dist/assets/volume-2-CeSXNDv4.js +1 -0
  153. package/dist/ui/dist/assets/zap-hlXjpSeA.js +1 -0
  154. package/dist/ui/dist/favicon.ico +0 -0
  155. package/dist/ui/dist/index.html +40 -0
  156. package/dist/ui/dist/placeholder.svg +1 -0
  157. package/dist/ui/index.html +7 -11
  158. package/package.json +137 -15
  159. package/packages/cli/src/adapters/binary.ts +461 -0
  160. package/packages/cli/src/adapters/bun-global.ts +378 -0
  161. package/packages/cli/src/adapters/config.ts +314 -0
  162. package/packages/cli/src/adapters/docker.ts +308 -0
  163. package/packages/cli/src/adapters/factory.ts +168 -0
  164. package/packages/cli/src/adapters/index.ts +80 -0
  165. package/packages/cli/src/adapters/types.ts +218 -0
  166. package/packages/cli/src/commands/agent-run.ts +168 -0
  167. package/packages/cli/src/commands/agents.ts +398 -0
  168. package/packages/cli/src/commands/chat.ts +142 -0
  169. package/packages/cli/src/commands/config.ts +49 -0
  170. package/packages/cli/src/commands/cron.ts +487 -0
  171. package/packages/cli/src/commands/dev.ts +58 -0
  172. package/packages/cli/src/commands/doctor.ts +320 -0
  173. package/packages/cli/src/commands/gateway.ts +719 -0
  174. package/packages/cli/src/commands/logs.ts +57 -0
  175. package/packages/cli/src/commands/mcp.ts +175 -0
  176. package/packages/cli/src/commands/message.ts +77 -0
  177. package/packages/cli/src/commands/migrate.ts +90 -0
  178. package/packages/cli/src/commands/onboard.ts +1656 -0
  179. package/packages/cli/src/commands/security.ts +144 -0
  180. package/packages/cli/src/commands/service.ts +50 -0
  181. package/packages/cli/src/commands/sessions.ts +116 -0
  182. package/packages/cli/src/commands/skills.ts +215 -0
  183. package/packages/cli/src/commands/update.ts +203 -0
  184. package/packages/cli/src/index.ts +210 -0
  185. package/packages/cli/src/ui-bundle.generated.ts +3 -0
  186. package/packages/cli/src/utils/token.ts +6 -0
  187. package/packages/core/src/agent/agent-loop.ts +691 -0
  188. package/packages/core/src/agent/compaction.ts +240 -0
  189. package/packages/core/src/agent/context-compiler.ts +467 -0
  190. package/packages/core/src/agent/context-guard.ts +91 -0
  191. package/packages/core/src/agent/conversation-store.ts +244 -0
  192. package/packages/core/src/agent/curator.ts +158 -0
  193. package/packages/core/src/agent/hooks.ts +166 -0
  194. package/packages/core/src/agent/llm-client.ts +167 -0
  195. package/packages/core/src/agent/llm-providers/anthropic.ts +212 -0
  196. package/packages/core/src/agent/llm-providers/deepseek.ts +8 -0
  197. package/packages/core/src/agent/llm-providers/gemini.ts +215 -0
  198. package/packages/core/src/agent/llm-providers/groq.ts +5 -0
  199. package/packages/core/src/agent/llm-providers/interface.ts +195 -0
  200. package/packages/core/src/agent/llm-providers/kimi.ts +8 -0
  201. package/packages/core/src/agent/llm-providers/local-llama.ts +37 -0
  202. package/packages/core/src/agent/llm-providers/mistral.ts +5 -0
  203. package/packages/core/src/agent/llm-providers/nvidia.ts +5 -0
  204. package/packages/core/src/agent/llm-providers/ollama.ts +175 -0
  205. package/packages/core/src/agent/llm-providers/openai-compat-base.ts +379 -0
  206. package/packages/core/src/agent/llm-providers/openai.ts +5 -0
  207. package/packages/core/src/agent/llm-providers/openrouter.ts +5 -0
  208. package/packages/core/src/agent/llm-providers/qwen.ts +5 -0
  209. package/packages/core/src/agent/native-tools.ts +31 -0
  210. package/packages/core/src/agent/playbook-selector.ts +147 -0
  211. package/packages/core/src/agent/prompt-builder.ts +169 -0
  212. package/packages/core/src/agent/providers/index.ts +204 -0
  213. package/packages/core/src/agent/providers.ts +1 -0
  214. package/packages/core/src/agent/reflector.ts +200 -0
  215. package/packages/core/src/agent/service.ts +267 -0
  216. package/packages/core/src/agent/skill-selector.ts +479 -0
  217. package/packages/core/src/agent/stuck-loop.ts +133 -0
  218. package/packages/core/src/agent/tool-selector.ts +569 -0
  219. package/packages/core/src/agent/tracer.ts +100 -0
  220. package/packages/core/src/auth/auth.ts +108 -0
  221. package/packages/core/src/auth/index.ts +1 -0
  222. package/packages/core/src/canvas/a2ui-tools.ts +255 -0
  223. package/packages/core/src/canvas/canvas-manager.ts +390 -0
  224. package/packages/core/src/canvas/canvas-tools.ts +448 -0
  225. package/packages/core/src/canvas/emitter.ts +149 -0
  226. package/packages/core/src/canvas/index.ts +3 -0
  227. package/packages/core/src/channels/base.ts +154 -0
  228. package/packages/core/src/channels/discord.ts +273 -0
  229. package/packages/core/src/channels/index.ts +7 -0
  230. package/packages/core/src/channels/manager.ts +450 -0
  231. package/packages/core/src/channels/slack.ts +323 -0
  232. package/packages/core/src/channels/telegram.ts +612 -0
  233. package/packages/core/src/channels/webchat.ts +139 -0
  234. package/packages/core/src/channels/whatsapp.ts +548 -0
  235. package/packages/core/src/config/index.ts +12 -0
  236. package/packages/core/src/config/loader.ts +569 -0
  237. package/packages/core/src/events/agent-bus.ts +460 -0
  238. package/packages/core/src/events/event-bus.ts +169 -0
  239. package/packages/core/src/gateway/channel-notify.ts +64 -0
  240. package/packages/core/src/gateway/helpers/cors.ts +32 -0
  241. package/packages/core/src/gateway/helpers/index.ts +4 -0
  242. package/packages/core/src/gateway/helpers/narration.ts +57 -0
  243. package/packages/core/src/gateway/helpers/path.ts +13 -0
  244. package/packages/core/src/gateway/helpers/redact.ts +61 -0
  245. package/packages/core/src/gateway/index.ts +5 -0
  246. package/packages/core/src/gateway/initializer.ts +363 -0
  247. package/packages/core/src/gateway/lane-queue.ts +169 -0
  248. package/packages/core/src/gateway/llm-local/client.ts +94 -0
  249. package/packages/core/src/gateway/llm-local/detector.ts +321 -0
  250. package/packages/core/src/gateway/llm-local/downloader.ts +216 -0
  251. package/packages/core/src/gateway/llm-local/index.ts +34 -0
  252. package/packages/core/src/gateway/llm-local/manager.ts +186 -0
  253. package/packages/core/src/gateway/llm-local/models.ts +149 -0
  254. package/packages/core/src/gateway/llm-local/server.ts +179 -0
  255. package/packages/core/src/gateway/resolver.ts +108 -0
  256. package/packages/core/src/gateway/router.ts +124 -0
  257. package/packages/core/src/gateway/routes/agents.ts +210 -0
  258. package/packages/core/src/gateway/routes/auth.ts +244 -0
  259. package/packages/core/src/gateway/routes/channels.ts +484 -0
  260. package/packages/core/src/gateway/routes/chat.ts +241 -0
  261. package/packages/core/src/gateway/routes/config.ts +12 -0
  262. package/packages/core/src/gateway/routes/cron-api.ts +544 -0
  263. package/packages/core/src/gateway/routes/ethics.ts +46 -0
  264. package/packages/core/src/gateway/routes/llm-local.ts +271 -0
  265. package/packages/core/src/gateway/routes/mcp.ts +319 -0
  266. package/packages/core/src/gateway/routes/meeting.ts +232 -0
  267. package/packages/core/src/gateway/routes/models.ts +163 -0
  268. package/packages/core/src/gateway/routes/multimodal.ts +93 -0
  269. package/packages/core/src/gateway/routes/providers.ts +220 -0
  270. package/packages/core/src/gateway/routes/setup.ts +441 -0
  271. package/packages/core/src/gateway/routes/skills.ts +115 -0
  272. package/packages/core/src/gateway/routes/system.ts +469 -0
  273. package/packages/core/src/gateway/routes/tasks.ts +44 -0
  274. package/packages/core/src/gateway/routes/tools.ts +59 -0
  275. package/packages/core/src/gateway/routes/tts-local.ts +388 -0
  276. package/packages/core/src/gateway/routes/users.ts +122 -0
  277. package/packages/core/src/gateway/routes/voice.ts +189 -0
  278. package/packages/core/src/gateway/routes/workspace.ts +281 -0
  279. package/packages/core/src/gateway/server.ts +2744 -0
  280. package/packages/core/src/gateway/session.ts +95 -0
  281. package/packages/core/src/gateway/slash-commands.ts +207 -0
  282. package/packages/core/src/gateway/tts/README.md +94 -0
  283. package/packages/core/src/gateway/tts/package.json +25 -0
  284. package/packages/core/src/gateway/tts/src/client.ts +59 -0
  285. package/packages/core/src/gateway/tts/src/detect.ts +42 -0
  286. package/packages/core/src/gateway/tts/src/index.ts +15 -0
  287. package/packages/core/src/gateway/tts/src/install.ts +129 -0
  288. package/packages/core/src/gateway/tts/src/models.ts +50 -0
  289. package/packages/core/src/gateway/tts/src/server.ts +252 -0
  290. package/packages/core/src/gateway/tts/voices/.gitkeep +0 -0
  291. package/packages/core/src/heartbeat/index.ts +157 -0
  292. package/packages/core/src/index.ts +56 -0
  293. package/packages/core/src/mcp/hot-reload.ts +148 -0
  294. package/packages/core/src/mcp/singleton.ts +21 -0
  295. package/packages/core/src/mcp/tool-sync.ts +176 -0
  296. package/packages/core/src/multimodal/index.ts +2 -0
  297. package/packages/core/src/multimodal/types.ts +28 -0
  298. package/packages/core/src/multimodal/vision-service.ts +283 -0
  299. package/packages/core/src/plugins/api.ts +128 -0
  300. package/packages/core/src/plugins/index.ts +2 -0
  301. package/packages/core/src/plugins/loader.ts +365 -0
  302. package/packages/core/src/resilience/circuit-breaker.ts +225 -0
  303. package/packages/core/src/scheduler/CronScheduler.ts +699 -0
  304. package/packages/core/src/scheduler/dag/AgentExecutor.ts +53 -0
  305. package/packages/core/src/scheduler/dag/DAGScheduler.ts +250 -0
  306. package/packages/core/src/scheduler/dag/EventBridge.ts +122 -0
  307. package/packages/core/src/scheduler/dag/TaskGraph.ts +192 -0
  308. package/packages/core/src/scheduler/dag/TaskNode.ts +97 -0
  309. package/packages/core/src/scheduler/dag/TaskResult.ts +22 -0
  310. package/packages/core/src/scheduler/dag/errors.ts +37 -0
  311. package/packages/core/src/scheduler/dag/index.ts +26 -0
  312. package/packages/core/src/scheduler/dag/presets/ResearchPreset.ts +97 -0
  313. package/packages/core/src/scheduler/dag/strategies/ParallelStrategy.ts +21 -0
  314. package/packages/core/src/scheduler/dag/strategies/PriorityStrategy.ts +46 -0
  315. package/packages/core/src/scheduler/index.ts +22 -0
  316. package/packages/core/src/scheduler/integration.ts +237 -0
  317. package/packages/core/src/scheduler/types.ts +164 -0
  318. package/packages/core/src/security/google-chat.ts +269 -0
  319. package/packages/core/src/security/index.ts +192 -0
  320. package/packages/core/src/security/pairing.ts +250 -0
  321. package/packages/core/src/security/rate-limit.ts +270 -0
  322. package/packages/core/src/security/signal.ts +321 -0
  323. package/packages/core/src/state/store.ts +312 -0
  324. package/packages/core/src/storage/crypto.ts +197 -0
  325. package/packages/core/src/storage/migrate.ts +147 -0
  326. package/packages/core/src/storage/onboarding.ts +1506 -0
  327. package/packages/core/src/storage/schema.ts +666 -0
  328. package/packages/core/src/storage/seed.ts +628 -0
  329. package/packages/core/src/storage/sqlite.ts +407 -0
  330. package/packages/core/src/storage/usage.ts +374 -0
  331. package/packages/core/src/tool-runtime/index.ts +476 -0
  332. package/packages/core/src/tool-runtime/tool-worker.ts +125 -0
  333. package/packages/core/src/tools/agents/get-available-models.ts +118 -0
  334. package/packages/core/src/tools/agents/index.ts +610 -0
  335. package/packages/core/src/tools/canvas/index.ts +420 -0
  336. package/packages/core/src/tools/cli/index.ts +142 -0
  337. package/packages/core/src/tools/core/index.ts +478 -0
  338. package/packages/core/src/tools/cron/index.ts +635 -0
  339. package/packages/core/src/tools/filesystem/fs-delete.ts +78 -0
  340. package/packages/core/src/tools/filesystem/fs-edit.ts +106 -0
  341. package/packages/core/src/tools/filesystem/fs-exists.ts +63 -0
  342. package/packages/core/src/tools/filesystem/fs-glob.ts +108 -0
  343. package/packages/core/src/tools/filesystem/fs-list.ts +129 -0
  344. package/packages/core/src/tools/filesystem/fs-read.ts +72 -0
  345. package/packages/core/src/tools/filesystem/fs-write.ts +67 -0
  346. package/packages/core/src/tools/filesystem/index.ts +34 -0
  347. package/packages/core/src/tools/filesystem/workspace-guard.ts +62 -0
  348. package/packages/core/src/tools/index.ts +197 -0
  349. package/packages/core/src/tools/meeting/index.ts +363 -0
  350. package/packages/core/src/tools/office/index.ts +47 -0
  351. package/packages/core/src/tools/office/office-escribir-docx.ts +192 -0
  352. package/packages/core/src/tools/office/office-escribir-pdf.ts +172 -0
  353. package/packages/core/src/tools/office/office-escribir-pptx.ts +174 -0
  354. package/packages/core/src/tools/office/office-escribir-xlsx.ts +116 -0
  355. package/packages/core/src/tools/office/office-leer-docx.ts +93 -0
  356. package/packages/core/src/tools/office/office-leer-pdf.ts +114 -0
  357. package/packages/core/src/tools/office/office-leer-pptx.ts +136 -0
  358. package/packages/core/src/tools/office/office-leer-xlsx.ts +124 -0
  359. package/packages/core/src/tools/types.ts +39 -0
  360. package/packages/core/src/tools/voice/index.ts +104 -0
  361. package/packages/core/src/tools/web/browser-click.ts +78 -0
  362. package/packages/core/src/tools/web/browser-extract.ts +139 -0
  363. package/packages/core/src/tools/web/browser-navigate.ts +106 -0
  364. package/packages/core/src/tools/web/browser-screenshot.ts +87 -0
  365. package/packages/core/src/tools/web/browser-script.ts +88 -0
  366. package/packages/core/src/tools/web/browser-service.ts +554 -0
  367. package/packages/core/src/tools/web/browser-type.ts +101 -0
  368. package/packages/core/src/tools/web/browser-wait.ts +136 -0
  369. package/packages/core/src/tools/web/index.ts +41 -0
  370. package/packages/core/src/tools/web/web-fetch.ts +78 -0
  371. package/packages/core/src/tools/web/web-search.ts +123 -0
  372. package/packages/core/src/utils/benchmark.ts +80 -0
  373. package/packages/core/src/utils/crypto.ts +73 -0
  374. package/packages/core/src/utils/date.ts +42 -0
  375. package/packages/core/src/utils/index.ts +5 -0
  376. package/packages/core/src/utils/logger.ts +389 -0
  377. package/packages/core/src/utils/retry.ts +70 -0
  378. package/packages/core/src/utils/toon.ts +253 -0
  379. package/packages/core/src/voice/index.ts +643 -0
  380. package/packages/mcp/src/config.ts +13 -0
  381. package/packages/mcp/src/index.ts +1 -0
  382. package/packages/mcp/src/logger.ts +47 -0
  383. package/packages/mcp/src/manager.ts +439 -0
  384. package/packages/mcp/src/transports/index.ts +67 -0
  385. package/packages/mcp/src/transports/sse.ts +238 -0
  386. package/packages/mcp/src/transports/websocket.ts +159 -0
  387. package/packages/skills/src/bundled/agents/agent_spawner/SKILL.md +167 -0
  388. package/packages/skills/src/bundled/agents/code_delegator/SKILL.md +156 -0
  389. package/packages/skills/src/bundled/agents/memory_manager/SKILL.md +143 -0
  390. package/packages/skills/src/bundled/agents/research_and_remember/SKILL.md +139 -0
  391. package/packages/skills/src/bundled/agents/task_orchestrator/SKILL.md +198 -0
  392. package/packages/skills/src/bundled/canvas/a2ui_dashboard/SKILL.md +176 -0
  393. package/packages/skills/src/bundled/canvas/a2ui_form/SKILL.md +202 -0
  394. package/packages/skills/src/bundled/canvas/a2ui_interactive/SKILL.md +206 -0
  395. package/packages/skills/src/bundled/canvas/canvas_dashboard/SKILL.md +146 -0
  396. package/packages/skills/src/bundled/canvas/canvas_interact/SKILL.md +148 -0
  397. package/packages/skills/src/bundled/canvas/canvas_report/SKILL.md +146 -0
  398. package/packages/skills/src/bundled/cli/cli_pipeline/SKILL.md +136 -0
  399. package/packages/skills/src/bundled/cli/cli_safe_exec/SKILL.md +125 -0
  400. package/packages/skills/src/bundled/cron_manager/SKILL.md +188 -0
  401. package/packages/skills/src/bundled/cron_reminder/SKILL.md +112 -0
  402. package/packages/skills/src/bundled/filesystem/file_manager/SKILL.md +118 -0
  403. package/packages/skills/src/bundled/filesystem/file_read_and_summarize/SKILL.md +108 -0
  404. package/packages/skills/src/bundled/filesystem/file_writer/SKILL.md +135 -0
  405. package/packages/skills/src/bundled/meeting/meeting_transcription/SKILL.md +213 -0
  406. package/packages/skills/src/bundled/office/office_document_manager/SKILL.md +262 -0
  407. package/packages/skills/src/bundled/search_knowledge/busqueda_fts5/SKILL.md +74 -0
  408. package/packages/skills/src/bundled/voice/voice_assistant/SKILL.md +174 -0
  409. package/packages/skills/src/bundled/voice/voice_input/SKILL.md +146 -0
  410. package/packages/skills/src/bundled/voice/voice_output/SKILL.md +151 -0
  411. package/packages/skills/src/bundled/web/browser_automate/SKILL.md +120 -0
  412. package/packages/skills/src/bundled/web/browser_scrape/SKILL.md +109 -0
  413. package/packages/skills/src/bundled/web/web_monitor/SKILL.md +127 -0
  414. package/packages/skills/src/bundled/web/web_research/SKILL.md +119 -0
  415. package/packages/skills/src/bundled-data.generated.ts +1964 -0
  416. package/packages/skills/src/index.ts +1 -0
  417. package/packages/skills/src/loader.ts +388 -0
  418. package/dist/ui/assets/AgentCreateForm-DS6yXjGV.js +0 -1
  419. package/dist/ui/assets/AgentDetailPage-Ud552U7_.js +0 -1
  420. package/dist/ui/assets/AgentNewPage-DWWs1P7s.js +0 -1
  421. package/dist/ui/assets/BridgePage-BD93aBKM.js +0 -1
  422. package/dist/ui/assets/CanvasPage-CM35yj0Q.js +0 -33
  423. package/dist/ui/assets/ChannelsPage-CtsWtJdc.js +0 -8
  424. package/dist/ui/assets/DashboardPage-BpiwR5Jg.js +0 -6
  425. package/dist/ui/assets/LogsPage-DqUsG3MW.js +0 -1
  426. package/dist/ui/assets/MeetingPage-C5B8-IzE.js +0 -1
  427. package/dist/ui/assets/ProjectsPage-zic2sjUf.js +0 -1
  428. package/dist/ui/assets/ProvidersPage-BxyIGKzh.js +0 -1
  429. package/dist/ui/assets/SettingsPage-CNFm3nun.js +0 -9
  430. package/dist/ui/assets/SetupPage-RBcjQtv7.js +0 -1
  431. package/dist/ui/assets/accordion-BEVqJf2A.js +0 -1
  432. package/dist/ui/assets/alert-BeGcM0nb.js +0 -1
  433. package/dist/ui/assets/api-q5Ax-vD2.js +0 -63
  434. package/dist/ui/assets/arrow-left-B_jlw8X_.js +0 -1
  435. package/dist/ui/assets/badge-pNhtItyt.js +0 -1
  436. package/dist/ui/assets/chevron-down-B16UVNlu.js +0 -1
  437. package/dist/ui/assets/chevron-left-_8ly7Fz0.js +0 -1
  438. package/dist/ui/assets/chevron-right-yzZLjezG.js +0 -1
  439. package/dist/ui/assets/chevron-up-CxKDQEE5.js +0 -1
  440. package/dist/ui/assets/circle-CFKiO9Ds.js +0 -1
  441. package/dist/ui/assets/circle-check-E2u7ZS2r.js +0 -1
  442. package/dist/ui/assets/circle-minus-1-TZF2pu.js +0 -1
  443. package/dist/ui/assets/circle-x-Cm3Sr-xb.js +0 -1
  444. package/dist/ui/assets/dialog-BaJbZsQF.js +0 -1
  445. package/dist/ui/assets/dist-DB-fE0Co.js +0 -1
  446. package/dist/ui/assets/dropdown-menu-DJoOchfz.js +0 -1
  447. package/dist/ui/assets/gauge-BTpFKuAj.js +0 -1
  448. package/dist/ui/assets/index-BN0875JH.css +0 -2
  449. package/dist/ui/assets/index-D4pdc0Uw.js +0 -54
  450. package/dist/ui/assets/label-C6tqnnKd.js +0 -1
  451. package/dist/ui/assets/loader-circle-CK3qRV3f.js +0 -1
  452. package/dist/ui/assets/pencil-BF2_XX-i.js +0 -1
  453. package/dist/ui/assets/play-DidATMfT.js +0 -1
  454. package/dist/ui/assets/plus-DXm1XDhQ.js +0 -1
  455. package/dist/ui/assets/progress-B1HC9cB_.js +0 -1
  456. package/dist/ui/assets/scroll-area-DKNpYkRA.js +0 -1
  457. package/dist/ui/assets/search-Co6mulZS.js +0 -1
  458. package/dist/ui/assets/switch-7AuR7x2g.js +0 -1
  459. package/dist/ui/assets/terminal-CjZu0OZ0.js +0 -1
  460. package/dist/ui/assets/useProviders-Bxsnav4y.js +0 -1
  461. package/dist/ui/assets/useWebSocketStore-ZCW_Nt1w.js +0 -1
  462. package/dist/ui/assets/x-5cXW_1ZS.js +0 -1
  463. /package/dist/ui/assets/{format-C0EOLKvf.js → format-GVHeOyWI.js} +0 -0
  464. /package/dist/ui/assets/{gateway-url-OqLaEDK-.js → gateway-url-COCbW0IR.js} +0 -0
  465. /package/dist/ui/assets/{utils-_qMjiZaF.js → utils-3pnRFmFe.js} +0 -0
  466. /package/dist/ui/assets/{vendor-router-DhLEd920.js → vendor-router-C9pIYwbJ.js} +0 -0
@@ -0,0 +1,139 @@
1
+ import type { ServerWebSocket } from "bun";
2
+ import { BaseChannel, type ChannelConfig, type IncomingMessage, type OutboundMessage } from "./base.ts";
3
+ import { logger } from "../utils/logger.ts";
4
+ import { resolveUserId } from "../storage/onboarding";
5
+
6
+ export interface WebChatConfig extends ChannelConfig {
7
+ accountId?: string;
8
+ // WebChat doesn't need extra config, it's served from the gateway
9
+ }
10
+
11
+ interface WebSocketData {
12
+ sessionId: string;
13
+ peerId: string;
14
+ authenticatedAt: number;
15
+ }
16
+
17
+ export class WebChatChannel extends BaseChannel {
18
+ name = "webchat";
19
+ accountId: string;
20
+ config: WebChatConfig;
21
+
22
+ private connections: Map<string, ServerWebSocket<WebSocketData>> = new Map();
23
+ private log = logger.child("webchat");
24
+
25
+ constructor(config: WebChatConfig) {
26
+ super();
27
+ this.config = config;
28
+ // Resolve accountId from database (single user) or use fallback
29
+ this.accountId = config.accountId || resolveUserId({}) || "webchat";
30
+ }
31
+
32
+ async start(): Promise<void> {
33
+ this.running = true;
34
+ this.log.info("WebChat channel ready");
35
+ }
36
+
37
+ async stop(): Promise<void> {
38
+ this.connections.clear();
39
+ this.running = false;
40
+ this.log.info("WebChat channel stopped");
41
+ }
42
+
43
+ registerConnection(ws: ServerWebSocket<WebSocketData>): void {
44
+ const data = ws.data as WebSocketData;
45
+ this.connections.set(data.sessionId, ws);
46
+ this.log.debug(`WebChat connection registered: ${data.sessionId}`);
47
+ }
48
+
49
+ unregisterConnection(sessionId: string): void {
50
+ this.connections.delete(sessionId);
51
+ this.log.debug(`WebChat connection unregistered: ${sessionId}`);
52
+ }
53
+
54
+ /** Returns the first active WebChat session ID, or undefined if no one is connected */
55
+ getAnyActiveSession(): string | undefined {
56
+ return this.connections.keys().next().value;
57
+ }
58
+
59
+ hasSession(sessionId: string): boolean {
60
+ return this.connections.has(sessionId);
61
+ }
62
+
63
+ async startTyping(sessionId: string): Promise<void> {
64
+ const ws = this.connections.get(sessionId);
65
+ if (!ws) return;
66
+
67
+ try {
68
+ ws.send(JSON.stringify({ type: "typing", isTyping: true }));
69
+ } catch {
70
+ // Connection closed
71
+ }
72
+ }
73
+
74
+ async stopTyping(sessionId: string): Promise<void> {
75
+ const ws = this.connections.get(sessionId);
76
+ if (!ws) return;
77
+
78
+ try {
79
+ ws.send(JSON.stringify({ type: "typing", isTyping: false }));
80
+ } catch {
81
+ // Connection closed
82
+ }
83
+ }
84
+
85
+ async send(sessionId: string, message: OutboundMessage): Promise<void> {
86
+ const ws = this.connections.get(sessionId);
87
+
88
+ if (!ws) {
89
+ this.log.warn(`No WebChat connection for session: ${sessionId}`);
90
+ return;
91
+ }
92
+
93
+ try {
94
+ ws.send(JSON.stringify(message));
95
+ } catch (error) {
96
+ this.log.error(`Failed to send WebChat message: ${(error as Error).message}`);
97
+ }
98
+ }
99
+
100
+ async sendAudio(sessionId: string, audio: Buffer, mimeType: string): Promise<void> {
101
+ const ws = this.connections.get(sessionId);
102
+
103
+ if (!ws) {
104
+ this.log.warn(`No WebChat connection for session: ${sessionId}`);
105
+ return;
106
+ }
107
+
108
+ try {
109
+ const base64Audio = audio.toString("base64");
110
+ ws.send(JSON.stringify({
111
+ type: "audio",
112
+ sessionId,
113
+ audio: base64Audio,
114
+ mimeType,
115
+ }));
116
+ } catch (error) {
117
+ this.log.error(`Failed to send WebChat audio: ${(error as Error).message}`);
118
+ }
119
+ }
120
+
121
+ createIncomingMessage(
122
+ sessionId: string,
123
+ content: string,
124
+ peerId: string
125
+ ): IncomingMessage {
126
+ return {
127
+ sessionId,
128
+ channel: "webchat",
129
+ accountId: this.accountId,
130
+ peerId,
131
+ peerKind: "direct",
132
+ content,
133
+ };
134
+ }
135
+ }
136
+
137
+ export function createWebChatChannel(config: WebChatConfig): WebChatChannel {
138
+ return new WebChatChannel(config);
139
+ }
@@ -0,0 +1,548 @@
1
+ import makeWASocket, {
2
+ DisconnectReason,
3
+ useMultiFileAuthState,
4
+ fetchLatestBaileysVersion,
5
+ downloadMediaMessage,
6
+ type WASocket,
7
+ type ConnectionState,
8
+ type WAMessage,
9
+ } from "@whiskeysockets/baileys";
10
+ import type { ChannelConfig, IncomingMessage, OutboundMessage } from "./base.ts";
11
+ import { BaseChannel } from "./base.ts";
12
+ import { existsSync, mkdirSync, rmSync } from "node:fs";
13
+ import * as path from "node:path";
14
+ import { logger } from "../utils/logger.ts";
15
+ import { getDb } from "../storage/sqlite.ts";
16
+ // @ts-ignore — no type definitions for qrcode-terminal
17
+ import qrcodeTerminal from "qrcode-terminal";
18
+
19
+ // Baileys uses the `ws` npm package which triggers "[bun] Warning: ws.WebSocket 'upgrade'
20
+ // event is not implemented in bun" etc. Bun writes these directly to stderr from native
21
+ // code, bypassing process.emitWarning. Patch process.stderr.write to filter them out.
22
+ const _origStderrWrite = process.stderr.write.bind(process.stderr);
23
+ (process.stderr as any).write = function (chunk: string | Buffer, ...args: unknown[]) {
24
+ const str = typeof chunk === "string" ? chunk : Buffer.isBuffer(chunk) ? chunk.toString() : "";
25
+ if (str.includes("[bun] Warning:") && str.includes("not implemented in bun")) return true;
26
+ return _origStderrWrite(chunk, ...(args as any[]));
27
+ };
28
+
29
+ export interface WhatsAppConfig extends ChannelConfig {
30
+ accountId: string;
31
+ agentId: string;
32
+ acceptGroups?: boolean;
33
+ selfMessagesOnly?: boolean;
34
+ reconnectMaxAttempts?: number;
35
+ reconnectBaseDelayMs?: number;
36
+ }
37
+
38
+ export interface WhatsAppConnectionState {
39
+ status: "connecting" | "connected" | "disconnected" | "qr" | "error";
40
+ qrCode?: string;
41
+ lastConnected?: Date;
42
+ reconnectAttempts: number;
43
+ error?: string;
44
+ phoneNumber?: string;
45
+ waVersion?: string;
46
+ }
47
+
48
+ export class WhatsAppChannel extends BaseChannel {
49
+ name = "whatsapp";
50
+ accountId: string;
51
+ config: WhatsAppConfig;
52
+
53
+ private socket: WASocket | null = null;
54
+ private connectionState: WhatsAppConnectionState = {
55
+ status: "disconnected",
56
+ reconnectAttempts: 0,
57
+ };
58
+ private authPath: string;
59
+ private reconnectTimeout: Timer | null = null;
60
+ private log: ReturnType<typeof logger.child>;
61
+ private jidCache: Map<string, string> = new Map();
62
+
63
+ constructor(config: WhatsAppConfig) {
64
+ super();
65
+ this.config = config;
66
+ this.accountId = config.accountId;
67
+ this.authPath = this.getAuthPath(config.agentId, config.accountId);
68
+ this.log = logger.child("whatsapp");
69
+ }
70
+
71
+ private getAuthPath(agentId: string, accountId: string): string {
72
+ const baseDir = process.env.HOME ?? "";
73
+ const authDir = path.join(baseDir, ".hive", "agents", agentId, "whatsapp", accountId);
74
+
75
+ if (!existsSync(authDir)) {
76
+ mkdirSync(authDir, { recursive: true });
77
+ }
78
+
79
+ return authDir;
80
+ }
81
+
82
+ async start(): Promise<void> {
83
+ this.running = true;
84
+ await this.connect();
85
+ }
86
+
87
+ async stop(): Promise<void> {
88
+ this.running = false;
89
+
90
+ if (this.reconnectTimeout) {
91
+ clearTimeout(this.reconnectTimeout);
92
+ this.reconnectTimeout = null;
93
+ }
94
+
95
+ if (this.socket) {
96
+ try {
97
+ await this.socket.end(undefined);
98
+ } catch {
99
+ // Ignore close errors
100
+ }
101
+ this.socket = null;
102
+ }
103
+
104
+ this.connectionState.status = "disconnected";
105
+ this.log.info("WhatsApp channel stopped");
106
+ }
107
+
108
+ private async connect(): Promise<void> {
109
+ if (!this.running) return;
110
+
111
+ this.connectionState.status = "connecting";
112
+ this.log.info("Connecting to WhatsApp...");
113
+
114
+ try {
115
+ const { state, saveCreds } = await useMultiFileAuthState(this.authPath);
116
+ const { version } = await fetchLatestBaileysVersion();
117
+ this.connectionState.waVersion = version.join(".");
118
+ this.log.info(`Using WhatsApp Web v${version.join(".")}`);
119
+
120
+ this.socket = makeWASocket({
121
+ version,
122
+ auth: state,
123
+ printQRInTerminal: false,
124
+ syncFullHistory: false,
125
+ getMessage: async () => ({ conversation: "" }),
126
+ });
127
+
128
+ this.socket.ev.on("connection.update", async (update) => {
129
+ await this.handleConnectionUpdate(update, saveCreds);
130
+ });
131
+
132
+ this.socket.ev.on("messages.upsert", async (update) => {
133
+ await this.handleMessages(update);
134
+ });
135
+
136
+ this.socket.ev.on("creds.update", saveCreds);
137
+
138
+ // Baileys v7: handle LID ↔ phone-number mapping updates
139
+ this.socket.ev.on("lid-mapping.update" as any, () => {
140
+ // LID mappings are persisted automatically via useMultiFileAuthState
141
+ });
142
+
143
+ } catch (error) {
144
+ this.connectionState.status = "error";
145
+ this.connectionState.error = (error as Error).message;
146
+ this.log.error(`WhatsApp connection error: ${(error as Error).message}`);
147
+ this.scheduleReconnect();
148
+ }
149
+ }
150
+
151
+ private async handleConnectionUpdate(
152
+ update: Partial<ConnectionState>,
153
+ saveCreds: () => Promise<void>
154
+ ): Promise<void> {
155
+ const { connection, lastDisconnect, qr } = update;
156
+
157
+ if (qr) {
158
+ this.connectionState.status = "qr";
159
+ this.connectionState.qrCode = qr;
160
+ this.printQR(qr);
161
+ this.log.info("Scan the QR code above with WhatsApp");
162
+ }
163
+
164
+ if (connection === "close") {
165
+ const statusCode = (lastDisconnect?.error as { output?: { statusCode: number } })?.output?.statusCode;
166
+ const shouldReconnect = statusCode !== DisconnectReason.loggedOut;
167
+
168
+ this.connectionState.status = "disconnected";
169
+ this.log.warn(`WhatsApp disconnected: ${statusCode}`);
170
+
171
+ try {
172
+ getDb().query(`UPDATE channels SET status = ? WHERE id = ?`)
173
+ .run(shouldReconnect ? "connecting" : "disconnected", this.accountId);
174
+ } catch { /* ignore DB errors */ }
175
+
176
+ const needsSessionClear =
177
+ statusCode === DisconnectReason.loggedOut ||
178
+ statusCode === DisconnectReason.badSession;
179
+ // NOTE: 515 (restartRequired) is sent by WhatsApp AFTER a successful pairing
180
+ // to signal Baileys to reconnect with the new credentials — do NOT clear session.
181
+
182
+ if (needsSessionClear) {
183
+ this.log.info("Clearing WhatsApp session files for fresh QR scan.");
184
+ rmSync(this.authPath, { recursive: true, force: true });
185
+ mkdirSync(this.authPath, { recursive: true });
186
+ }
187
+
188
+ if (shouldReconnect && this.running) {
189
+ this.scheduleReconnect();
190
+ }
191
+ }
192
+
193
+ if (connection === "open") {
194
+ this.connectionState.status = "connected";
195
+ this.connectionState.lastConnected = new Date();
196
+ this.connectionState.reconnectAttempts = 0;
197
+ this.connectionState.qrCode = undefined;
198
+ void saveCreds();
199
+ this.log.info("WhatsApp connected successfully");
200
+
201
+ // Extract phone number from socket user ID
202
+ const rawUserId = this.socket?.user?.id ?? "";
203
+ if (rawUserId) {
204
+ const phoneNumber = rawUserId.split(":")[0]?.replace("@s.whatsapp.net", "") ?? "";
205
+ this.connectionState.phoneNumber = phoneNumber;
206
+ this.log.info(`Linked phone: ${phoneNumber}`);
207
+ }
208
+
209
+ try {
210
+ getDb().query(`UPDATE channels SET status = 'connected', last_active = ? WHERE id = ?`)
211
+ .run(Date.now(), this.accountId);
212
+ } catch { /* ignore DB errors */ }
213
+ }
214
+ }
215
+
216
+ hasCredentials(): boolean {
217
+ const credsFile = path.join(this.authPath, "creds.json");
218
+ return existsSync(credsFile);
219
+ }
220
+
221
+ getConnectionState(): WhatsAppConnectionState {
222
+ return { ...this.connectionState };
223
+ }
224
+
225
+ private printQR(qr: string): void {
226
+ this.log.info("\n" + "=".repeat(50));
227
+ this.log.info(" WHATSAPP QR CODE - Scan with your phone");
228
+ this.log.info("=".repeat(50) + "\n");
229
+
230
+ qrcodeTerminal.generate(qr, { small: false }, (qrString: string) => {
231
+ this.log.info(qrString);
232
+ });
233
+
234
+ this.log.info("\n" + "=".repeat(50));
235
+ this.log.info(" Open WhatsApp > Settings > Linked Devices");
236
+ this.log.info("=".repeat(50) + "\n");
237
+ }
238
+
239
+ private async handleMessages(update: { messages: unknown[]; type: string }): Promise<void> {
240
+ if (update.type !== "notify") return;
241
+
242
+ for (const msg of update.messages) {
243
+ const typedMsg = msg as {
244
+ key: { fromMe?: boolean; remoteJid?: string; id?: string };
245
+ message?: Record<string, unknown>;
246
+ messageTimestamp?: number;
247
+ pushName?: string;
248
+ };
249
+
250
+ const from = typedMsg.key.remoteJid;
251
+ if (!from) continue;
252
+
253
+ const isGroup = from.includes("@g.us");
254
+
255
+ if (isGroup && !this.config.acceptGroups) {
256
+ this.log.info(`[filter] Group message skipped (acceptGroups=false): ${from}`);
257
+ continue;
258
+ }
259
+
260
+ const selfMessagesOnly = this.config.selfMessagesOnly !== false;
261
+
262
+ if (!isGroup) {
263
+ const fromNumber = from.split("@")[0];
264
+ const ownJid = this.socket?.user?.id ?? "";
265
+ const ownLid = this.socket?.user?.lid ?? "";
266
+ const ownNumber = ownJid.split(":")[0].split("@")[0];
267
+ const ownLidNumber = ownLid.split(":")[0].split("@")[0];
268
+ const isToSelf = fromNumber === ownNumber || fromNumber === ownLidNumber;
269
+ const isSelfMessage = !!typedMsg.key.fromMe && isToSelf;
270
+
271
+ this.log.info(`[filter] DM from=${fromNumber} ownNumber=${ownNumber} ownLid=${ownLidNumber} fromMe=${typedMsg.key.fromMe} selfMessagesOnly=${selfMessagesOnly} isSelfMessage=${isSelfMessage}`);
272
+
273
+ if (selfMessagesOnly) {
274
+ if (!isSelfMessage) {
275
+ this.log.info(`[filter] DM skipped (selfMessagesOnly=true, not self)`);
276
+ continue;
277
+ }
278
+ } else {
279
+ if (!isSelfMessage && !this.isUserAllowed(fromNumber)) {
280
+ this.log.info(`[filter] DM skipped (not in allowlist): ${fromNumber}`);
281
+ continue;
282
+ }
283
+ }
284
+ }
285
+
286
+ const { content, hasAudio, hasImage, hasDocument } = this.extractMessageContent(typedMsg.message);
287
+ if (!content && !hasAudio && !hasImage && !hasDocument) continue;
288
+
289
+ let audioBuffer: Buffer | null = null;
290
+ let imageBuffer: Buffer | null = null;
291
+ let documentBuffer: Buffer | null = null;
292
+ let imageMime: string | undefined;
293
+ let documentMime: string | undefined;
294
+ let documentName: string | undefined;
295
+ let imageCaption: string | undefined;
296
+
297
+ if (hasAudio && this.socket) {
298
+ try {
299
+ audioBuffer = await downloadMediaMessage(
300
+ typedMsg as unknown as WAMessage,
301
+ "buffer",
302
+ {},
303
+ { reuploadRequest: this.socket.updateMediaMessage, logger: this.log as any }
304
+ ) as Buffer;
305
+ } catch (err) {
306
+ this.log.warn(`Failed to download WhatsApp audio: ${(err as Error).message}`);
307
+ }
308
+ }
309
+
310
+ if (hasImage && this.socket) {
311
+ try {
312
+ imageBuffer = await downloadMediaMessage(
313
+ typedMsg as unknown as WAMessage,
314
+ "buffer",
315
+ {},
316
+ { reuploadRequest: this.socket.updateMediaMessage, logger: this.log as any }
317
+ ) as Buffer;
318
+ const imgMsg = typedMsg.message?.imageMessage as { mimetype?: string; caption?: string } | undefined;
319
+ imageMime = imgMsg?.mimetype || "image/jpeg";
320
+ imageCaption = imgMsg?.caption || undefined;
321
+ } catch (err) {
322
+ this.log.warn(`Failed to download WhatsApp image: ${(err as Error).message}`);
323
+ }
324
+ }
325
+
326
+ if (hasDocument && this.socket) {
327
+ try {
328
+ documentBuffer = await downloadMediaMessage(
329
+ typedMsg as unknown as WAMessage,
330
+ "buffer",
331
+ {},
332
+ { reuploadRequest: this.socket.updateMediaMessage, logger: this.log as any }
333
+ ) as Buffer;
334
+ const docMsg = typedMsg.message?.documentMessage as { mimetype?: string; fileName?: string } | undefined;
335
+ documentMime = docMsg?.mimetype || "application/pdf";
336
+ documentName = docMsg?.fileName || undefined;
337
+ } catch (err) {
338
+ this.log.warn(`Failed to download WhatsApp document: ${(err as Error).message}`);
339
+ }
340
+ }
341
+
342
+ const peerId = isGroup ? from : from.replace("@s.whatsapp.net", "");
343
+
344
+ const incoming: IncomingMessage = {
345
+ sessionId: this.formatSessionId(peerId, isGroup ? "group" : "direct"),
346
+ channel: "whatsapp",
347
+ accountId: this.accountId,
348
+ peerId,
349
+ peerKind: isGroup ? "group" : "direct",
350
+ content: content || (hasAudio ? "[Audio message]" : ""),
351
+ audio: audioBuffer ? { buffer: audioBuffer, mimeType: "audio/ogg" } : undefined,
352
+ image: imageBuffer ? { buffer: imageBuffer, mimeType: imageMime, caption: imageCaption } : undefined,
353
+ document: documentBuffer ? { buffer: documentBuffer, mimeType: documentMime || "application/octet-stream", fileName: documentName } : undefined,
354
+ metadata: {
355
+ messageId: typedMsg.key.id,
356
+ timestamp: typedMsg.messageTimestamp,
357
+ pushName: typedMsg.pushName,
358
+ },
359
+ };
360
+
361
+ await this.handleMessage(incoming);
362
+ }
363
+ }
364
+
365
+ private extractMessageContent(message?: Record<string, unknown>): { content: string | null; hasAudio: boolean; hasImage: boolean; hasDocument: boolean } {
366
+ if (!message) return { content: null, hasAudio: false, hasImage: false, hasDocument: false };
367
+
368
+ if (message.conversation) {
369
+ return { content: message.conversation as string, hasAudio: false, hasImage: false, hasDocument: false };
370
+ }
371
+
372
+ const extendedText = message.extendedTextMessage as { text?: string } | undefined;
373
+ if (extendedText?.text) {
374
+ return { content: extendedText.text, hasAudio: false, hasImage: false, hasDocument: false };
375
+ }
376
+
377
+ const imageMsg = message.imageMessage as { caption?: string } | undefined;
378
+ if (imageMsg) {
379
+ return { content: imageMsg.caption || "", hasAudio: false, hasImage: true, hasDocument: false };
380
+ }
381
+
382
+ const videoMsg = message.videoMessage as { caption?: string } | undefined;
383
+ if (videoMsg?.caption) {
384
+ return { content: `[Video] ${videoMsg.caption}`, hasAudio: false, hasImage: false, hasDocument: false };
385
+ }
386
+
387
+ const docMsg = message.documentMessage as { caption?: string } | undefined;
388
+ if (docMsg) {
389
+ return { content: docMsg.caption || "", hasAudio: false, hasImage: false, hasDocument: true };
390
+ }
391
+
392
+ if (message.audioMessage) {
393
+ return { content: null, hasAudio: true, hasImage: false, hasDocument: false };
394
+ }
395
+
396
+ return { content: null, hasAudio: false, hasImage: false, hasDocument: false };
397
+ }
398
+
399
+ private scheduleReconnect(): void {
400
+ if (!this.running) return;
401
+
402
+ const maxAttempts = this.config.reconnectMaxAttempts ?? 10;
403
+ const baseDelay = this.config.reconnectBaseDelayMs ?? 5000;
404
+ const attempts = this.connectionState.reconnectAttempts;
405
+
406
+ if (attempts >= maxAttempts) {
407
+ this.log.error(`Max reconnection attempts (${maxAttempts}) reached`);
408
+ this.connectionState.status = "error";
409
+ this.connectionState.error = "Max reconnection attempts reached";
410
+ return;
411
+ }
412
+
413
+ const delay = Math.min(baseDelay * Math.pow(2, attempts), 60000);
414
+ this.connectionState.reconnectAttempts++;
415
+
416
+ this.log.info(`Reconnecting in ${delay / 1000}s (attempt ${attempts + 1}/${maxAttempts})`);
417
+
418
+ this.reconnectTimeout = setTimeout(async () => {
419
+ await this.connect();
420
+ }, delay);
421
+ }
422
+
423
+ private getJid(sessionId: string): string {
424
+ const cached = this.jidCache.get(sessionId);
425
+ if (cached) return cached;
426
+
427
+ const peerId = this.extractPeerId(sessionId);
428
+ const jid = peerId.includes("@") ? peerId : `${peerId}@s.whatsapp.net`;
429
+ this.jidCache.set(sessionId, jid);
430
+ return jid;
431
+ }
432
+
433
+ async startTyping(sessionId: string): Promise<void> {
434
+ if (!this.socket || this.connectionState.status !== "connected") return;
435
+
436
+ const jid = this.getJid(sessionId);
437
+ try {
438
+ await this.socket.sendPresenceUpdate("composing", jid);
439
+ } catch {
440
+ // Ignore typing errors
441
+ }
442
+ }
443
+
444
+ async stopTyping(sessionId: string): Promise<void> {
445
+ if (!this.socket || this.connectionState.status !== "connected") return;
446
+
447
+ const jid = this.getJid(sessionId);
448
+ try {
449
+ await this.socket.sendPresenceUpdate("paused", jid);
450
+ } catch {
451
+ // Ignore typing errors
452
+ }
453
+ }
454
+
455
+ async markAsRead(sessionId: string, messageId?: string): Promise<void> {
456
+ if (!this.socket || this.connectionState.status !== "connected") return;
457
+ if (!messageId) return;
458
+
459
+ const jid = this.getJid(sessionId);
460
+ try {
461
+ await this.socket.readMessages([
462
+ { remoteJid: jid, id: messageId, fromMe: false }
463
+ ]);
464
+ } catch {
465
+ // Ignore read receipt errors
466
+ }
467
+ }
468
+
469
+ async send(sessionId: string, message: OutboundMessage): Promise<void> {
470
+ if (!this.socket || this.connectionState.status !== "connected") {
471
+ throw new Error("WhatsApp not connected");
472
+ }
473
+
474
+ await this.stopTyping(sessionId);
475
+
476
+ const text = message.content ?? message.chunk ?? "";
477
+ if (!text) return;
478
+
479
+ const jid = this.getJid(sessionId);
480
+
481
+ await this.socket.sendMessage(jid, { text });
482
+ this.log.debug(`Sent message to ${jid}`);
483
+ }
484
+
485
+ async sendAudio(sessionId: string, audio: Buffer, mimeType: string): Promise<void> {
486
+ if (!this.socket || this.connectionState.status !== "connected") {
487
+ throw new Error("WhatsApp not connected");
488
+ }
489
+
490
+ const jid = this.getJid(sessionId);
491
+
492
+ try {
493
+ await this.socket.sendMessage(jid, {
494
+ audio: audio,
495
+ mimetype: mimeType,
496
+ });
497
+ this.log.debug(`Sent audio to ${jid}`);
498
+ } catch (error) {
499
+ this.log.error(`Failed to send WhatsApp audio: ${(error as Error).message}`);
500
+ throw error;
501
+ }
502
+ }
503
+
504
+ private extractPeerId(sessionId: string): string {
505
+ const parts = sessionId.split(":");
506
+ return parts[parts.length - 1] ?? "";
507
+ }
508
+
509
+ getState(): WhatsAppConnectionState {
510
+ return { ...this.connectionState };
511
+ }
512
+
513
+ getConfig(): WhatsAppConfig {
514
+ return { ...this.config };
515
+ }
516
+
517
+ async disconnect(clearSession: boolean = false): Promise<void> {
518
+ this.running = false;
519
+
520
+ if (this.reconnectTimeout) {
521
+ clearTimeout(this.reconnectTimeout);
522
+ this.reconnectTimeout = null;
523
+ }
524
+
525
+ if (this.socket) {
526
+ try {
527
+ await this.socket.end(undefined);
528
+ } catch {
529
+ // Ignore close errors
530
+ }
531
+ this.socket = null;
532
+ }
533
+
534
+ this.connectionState.status = "disconnected";
535
+ this.connectionState.phoneNumber = undefined;
536
+ this.log.info("WhatsApp channel disconnected");
537
+
538
+ if (clearSession) {
539
+ this.log.info("Clearing WhatsApp session files.");
540
+ rmSync(this.authPath, { recursive: true, force: true });
541
+ mkdirSync(this.authPath, { recursive: true });
542
+ }
543
+ }
544
+ }
545
+
546
+ export function createWhatsAppChannel(config: WhatsAppConfig): WhatsAppChannel {
547
+ return new WhatsAppChannel(config);
548
+ }
@@ -0,0 +1,12 @@
1
+ export {
2
+ getHiveDir,
3
+ loadConfig,
4
+ expandConfigPath,
5
+ expandPath,
6
+ type Config,
7
+ type ProviderConfig,
8
+ type MCPServerConfig,
9
+ type AgentEntry,
10
+ type Binding,
11
+ type UserConfig as ConfigUserConfig
12
+ } from "./loader.ts";