im-hub-pro 0.2.29

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 (384) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +497 -0
  3. package/README.zh-CN.md +496 -0
  4. package/dist/cli.d.ts +3 -0
  5. package/dist/cli.d.ts.map +1 -0
  6. package/dist/cli.js +921 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/core/acp-server.d.ts +8 -0
  9. package/dist/core/acp-server.d.ts.map +1 -0
  10. package/dist/core/acp-server.js +266 -0
  11. package/dist/core/acp-server.js.map +1 -0
  12. package/dist/core/agent-base.d.ts +94 -0
  13. package/dist/core/agent-base.d.ts.map +1 -0
  14. package/dist/core/agent-base.js +374 -0
  15. package/dist/core/agent-base.js.map +1 -0
  16. package/dist/core/agent-cwd.d.ts +45 -0
  17. package/dist/core/agent-cwd.d.ts.map +1 -0
  18. package/dist/core/agent-cwd.js +178 -0
  19. package/dist/core/agent-cwd.js.map +1 -0
  20. package/dist/core/agent-cwd.test.d.ts +2 -0
  21. package/dist/core/agent-cwd.test.d.ts.map +1 -0
  22. package/dist/core/agent-cwd.test.js +149 -0
  23. package/dist/core/agent-cwd.test.js.map +1 -0
  24. package/dist/core/approval-bus.d.ts +232 -0
  25. package/dist/core/approval-bus.d.ts.map +1 -0
  26. package/dist/core/approval-bus.js +703 -0
  27. package/dist/core/approval-bus.js.map +1 -0
  28. package/dist/core/approval-bus.synthetic.test.d.ts +2 -0
  29. package/dist/core/approval-bus.synthetic.test.d.ts.map +1 -0
  30. package/dist/core/approval-bus.synthetic.test.js +182 -0
  31. package/dist/core/approval-bus.synthetic.test.js.map +1 -0
  32. package/dist/core/approval-bus.test.d.ts +2 -0
  33. package/dist/core/approval-bus.test.d.ts.map +1 -0
  34. package/dist/core/approval-bus.test.js +537 -0
  35. package/dist/core/approval-bus.test.js.map +1 -0
  36. package/dist/core/approval-router.d.ts +95 -0
  37. package/dist/core/approval-router.d.ts.map +1 -0
  38. package/dist/core/approval-router.js +450 -0
  39. package/dist/core/approval-router.js.map +1 -0
  40. package/dist/core/approval-router.test.d.ts +2 -0
  41. package/dist/core/approval-router.test.d.ts.map +1 -0
  42. package/dist/core/approval-router.test.js +413 -0
  43. package/dist/core/approval-router.test.js.map +1 -0
  44. package/dist/core/audit-log.d.ts +55 -0
  45. package/dist/core/audit-log.d.ts.map +1 -0
  46. package/dist/core/audit-log.js +203 -0
  47. package/dist/core/audit-log.js.map +1 -0
  48. package/dist/core/bgjob-reader.d.ts +65 -0
  49. package/dist/core/bgjob-reader.d.ts.map +1 -0
  50. package/dist/core/bgjob-reader.js +212 -0
  51. package/dist/core/bgjob-reader.js.map +1 -0
  52. package/dist/core/bgjob-reader.test.d.ts +2 -0
  53. package/dist/core/bgjob-reader.test.d.ts.map +1 -0
  54. package/dist/core/bgjob-reader.test.js +178 -0
  55. package/dist/core/bgjob-reader.test.js.map +1 -0
  56. package/dist/core/circuit-breaker.d.ts +37 -0
  57. package/dist/core/circuit-breaker.d.ts.map +1 -0
  58. package/dist/core/circuit-breaker.js +115 -0
  59. package/dist/core/circuit-breaker.js.map +1 -0
  60. package/dist/core/commands/agent.d.ts +4 -0
  61. package/dist/core/commands/agent.d.ts.map +1 -0
  62. package/dist/core/commands/agent.js +21 -0
  63. package/dist/core/commands/agent.js.map +1 -0
  64. package/dist/core/commands/approval.d.ts +3 -0
  65. package/dist/core/commands/approval.d.ts.map +1 -0
  66. package/dist/core/commands/approval.js +44 -0
  67. package/dist/core/commands/approval.js.map +1 -0
  68. package/dist/core/commands/approval.test.d.ts +2 -0
  69. package/dist/core/commands/approval.test.d.ts.map +1 -0
  70. package/dist/core/commands/approval.test.js +85 -0
  71. package/dist/core/commands/approval.test.js.map +1 -0
  72. package/dist/core/commands/audit.d.ts +3 -0
  73. package/dist/core/commands/audit.d.ts.map +1 -0
  74. package/dist/core/commands/audit.js +84 -0
  75. package/dist/core/commands/audit.js.map +1 -0
  76. package/dist/core/commands/builtin.d.ts +3 -0
  77. package/dist/core/commands/builtin.d.ts.map +1 -0
  78. package/dist/core/commands/builtin.js +26 -0
  79. package/dist/core/commands/builtin.js.map +1 -0
  80. package/dist/core/commands/job.d.ts +3 -0
  81. package/dist/core/commands/job.d.ts.map +1 -0
  82. package/dist/core/commands/job.js +195 -0
  83. package/dist/core/commands/job.js.map +1 -0
  84. package/dist/core/commands/model.d.ts +9 -0
  85. package/dist/core/commands/model.d.ts.map +1 -0
  86. package/dist/core/commands/model.js +183 -0
  87. package/dist/core/commands/model.js.map +1 -0
  88. package/dist/core/commands/plan.d.ts +3 -0
  89. package/dist/core/commands/plan.d.ts.map +1 -0
  90. package/dist/core/commands/plan.js +75 -0
  91. package/dist/core/commands/plan.js.map +1 -0
  92. package/dist/core/commands/plan.test.d.ts +2 -0
  93. package/dist/core/commands/plan.test.d.ts.map +1 -0
  94. package/dist/core/commands/plan.test.js +122 -0
  95. package/dist/core/commands/plan.test.js.map +1 -0
  96. package/dist/core/commands/router.d.ts +3 -0
  97. package/dist/core/commands/router.d.ts.map +1 -0
  98. package/dist/core/commands/router.js +71 -0
  99. package/dist/core/commands/router.js.map +1 -0
  100. package/dist/core/commands/schedule.d.ts +3 -0
  101. package/dist/core/commands/schedule.d.ts.map +1 -0
  102. package/dist/core/commands/schedule.js +123 -0
  103. package/dist/core/commands/schedule.js.map +1 -0
  104. package/dist/core/commands/sessions.d.ts +3 -0
  105. package/dist/core/commands/sessions.d.ts.map +1 -0
  106. package/dist/core/commands/sessions.js +88 -0
  107. package/dist/core/commands/sessions.js.map +1 -0
  108. package/dist/core/commands/stats.d.ts +3 -0
  109. package/dist/core/commands/stats.d.ts.map +1 -0
  110. package/dist/core/commands/stats.js +73 -0
  111. package/dist/core/commands/stats.js.map +1 -0
  112. package/dist/core/commands/think.d.ts +3 -0
  113. package/dist/core/commands/think.d.ts.map +1 -0
  114. package/dist/core/commands/think.js +28 -0
  115. package/dist/core/commands/think.js.map +1 -0
  116. package/dist/core/commands/workspaces.d.ts +3 -0
  117. package/dist/core/commands/workspaces.d.ts.map +1 -0
  118. package/dist/core/commands/workspaces.js +47 -0
  119. package/dist/core/commands/workspaces.js.map +1 -0
  120. package/dist/core/config-schema.d.ts +58 -0
  121. package/dist/core/config-schema.d.ts.map +1 -0
  122. package/dist/core/config-schema.js +63 -0
  123. package/dist/core/config-schema.js.map +1 -0
  124. package/dist/core/cron.d.ts +29 -0
  125. package/dist/core/cron.d.ts.map +1 -0
  126. package/dist/core/cron.js +184 -0
  127. package/dist/core/cron.js.map +1 -0
  128. package/dist/core/event-bus.d.ts +80 -0
  129. package/dist/core/event-bus.d.ts.map +1 -0
  130. package/dist/core/event-bus.js +62 -0
  131. package/dist/core/event-bus.js.map +1 -0
  132. package/dist/core/intent-llm.d.ts +27 -0
  133. package/dist/core/intent-llm.d.ts.map +1 -0
  134. package/dist/core/intent-llm.js +170 -0
  135. package/dist/core/intent-llm.js.map +1 -0
  136. package/dist/core/intent.d.ts +12 -0
  137. package/dist/core/intent.d.ts.map +1 -0
  138. package/dist/core/intent.js +187 -0
  139. package/dist/core/intent.js.map +1 -0
  140. package/dist/core/job-board.d.ts +84 -0
  141. package/dist/core/job-board.d.ts.map +1 -0
  142. package/dist/core/job-board.js +379 -0
  143. package/dist/core/job-board.js.map +1 -0
  144. package/dist/core/logger.d.ts +6 -0
  145. package/dist/core/logger.d.ts.map +1 -0
  146. package/dist/core/logger.js +54 -0
  147. package/dist/core/logger.js.map +1 -0
  148. package/dist/core/metrics.d.ts +55 -0
  149. package/dist/core/metrics.d.ts.map +1 -0
  150. package/dist/core/metrics.js +291 -0
  151. package/dist/core/metrics.js.map +1 -0
  152. package/dist/core/onboarding.d.ts +94 -0
  153. package/dist/core/onboarding.d.ts.map +1 -0
  154. package/dist/core/onboarding.js +426 -0
  155. package/dist/core/onboarding.js.map +1 -0
  156. package/dist/core/onboarding.test.d.ts +2 -0
  157. package/dist/core/onboarding.test.d.ts.map +1 -0
  158. package/dist/core/onboarding.test.js +112 -0
  159. package/dist/core/onboarding.test.js.map +1 -0
  160. package/dist/core/rate-limiter.d.ts +44 -0
  161. package/dist/core/rate-limiter.d.ts.map +1 -0
  162. package/dist/core/rate-limiter.js +115 -0
  163. package/dist/core/rate-limiter.js.map +1 -0
  164. package/dist/core/registry.d.ts +32 -0
  165. package/dist/core/registry.d.ts.map +1 -0
  166. package/dist/core/registry.js +122 -0
  167. package/dist/core/registry.js.map +1 -0
  168. package/dist/core/router.d.ts +41 -0
  169. package/dist/core/router.d.ts.map +1 -0
  170. package/dist/core/router.js +431 -0
  171. package/dist/core/router.js.map +1 -0
  172. package/dist/core/schedule.d.ts +65 -0
  173. package/dist/core/schedule.d.ts.map +1 -0
  174. package/dist/core/schedule.js +316 -0
  175. package/dist/core/schedule.js.map +1 -0
  176. package/dist/core/session-subtasks.test.d.ts +2 -0
  177. package/dist/core/session-subtasks.test.d.ts.map +1 -0
  178. package/dist/core/session-subtasks.test.js +88 -0
  179. package/dist/core/session-subtasks.test.js.map +1 -0
  180. package/dist/core/session.d.ts +182 -0
  181. package/dist/core/session.d.ts.map +1 -0
  182. package/dist/core/session.js +774 -0
  183. package/dist/core/session.js.map +1 -0
  184. package/dist/core/sqlite-helper.d.ts +37 -0
  185. package/dist/core/sqlite-helper.d.ts.map +1 -0
  186. package/dist/core/sqlite-helper.js +79 -0
  187. package/dist/core/sqlite-helper.js.map +1 -0
  188. package/dist/core/transcribe.d.ts +25 -0
  189. package/dist/core/transcribe.d.ts.map +1 -0
  190. package/dist/core/transcribe.js +217 -0
  191. package/dist/core/transcribe.js.map +1 -0
  192. package/dist/core/transcribe.test.d.ts +2 -0
  193. package/dist/core/transcribe.test.d.ts.map +1 -0
  194. package/dist/core/transcribe.test.js +163 -0
  195. package/dist/core/transcribe.test.js.map +1 -0
  196. package/dist/core/types.d.ts +352 -0
  197. package/dist/core/types.d.ts.map +1 -0
  198. package/dist/core/types.js +3 -0
  199. package/dist/core/types.js.map +1 -0
  200. package/dist/core/workspace.d.ts +67 -0
  201. package/dist/core/workspace.d.ts.map +1 -0
  202. package/dist/core/workspace.js +113 -0
  203. package/dist/core/workspace.js.map +1 -0
  204. package/dist/index.d.ts +5 -0
  205. package/dist/index.d.ts.map +1 -0
  206. package/dist/index.js +6 -0
  207. package/dist/index.js.map +1 -0
  208. package/dist/plugins/agents/acp/acp-adapter.d.ts +16 -0
  209. package/dist/plugins/agents/acp/acp-adapter.d.ts.map +1 -0
  210. package/dist/plugins/agents/acp/acp-adapter.js +49 -0
  211. package/dist/plugins/agents/acp/acp-adapter.js.map +1 -0
  212. package/dist/plugins/agents/acp/acp-client.d.ts +32 -0
  213. package/dist/plugins/agents/acp/acp-client.d.ts.map +1 -0
  214. package/dist/plugins/agents/acp/acp-client.js +175 -0
  215. package/dist/plugins/agents/acp/acp-client.js.map +1 -0
  216. package/dist/plugins/agents/acp/discovery.d.ts +19 -0
  217. package/dist/plugins/agents/acp/discovery.d.ts.map +1 -0
  218. package/dist/plugins/agents/acp/discovery.js +109 -0
  219. package/dist/plugins/agents/acp/discovery.js.map +1 -0
  220. package/dist/plugins/agents/acp/index.d.ts +4 -0
  221. package/dist/plugins/agents/acp/index.d.ts.map +1 -0
  222. package/dist/plugins/agents/acp/index.js +4 -0
  223. package/dist/plugins/agents/acp/index.js.map +1 -0
  224. package/dist/plugins/agents/acp/types.d.ts +62 -0
  225. package/dist/plugins/agents/acp/types.d.ts.map +1 -0
  226. package/dist/plugins/agents/acp/types.js +5 -0
  227. package/dist/plugins/agents/acp/types.js.map +1 -0
  228. package/dist/plugins/agents/claude-code/adapter.test.d.ts +2 -0
  229. package/dist/plugins/agents/claude-code/adapter.test.d.ts.map +1 -0
  230. package/dist/plugins/agents/claude-code/adapter.test.js +195 -0
  231. package/dist/plugins/agents/claude-code/adapter.test.js.map +1 -0
  232. package/dist/plugins/agents/claude-code/index.d.ts +25 -0
  233. package/dist/plugins/agents/claude-code/index.d.ts.map +1 -0
  234. package/dist/plugins/agents/claude-code/index.js +184 -0
  235. package/dist/plugins/agents/claude-code/index.js.map +1 -0
  236. package/dist/plugins/agents/claude-code/mcp-approval-server.d.ts +42 -0
  237. package/dist/plugins/agents/claude-code/mcp-approval-server.d.ts.map +1 -0
  238. package/dist/plugins/agents/claude-code/mcp-approval-server.js +235 -0
  239. package/dist/plugins/agents/claude-code/mcp-approval-server.js.map +1 -0
  240. package/dist/plugins/agents/claude-code/mcp-approval-server.test.d.ts +2 -0
  241. package/dist/plugins/agents/claude-code/mcp-approval-server.test.d.ts.map +1 -0
  242. package/dist/plugins/agents/claude-code/mcp-approval-server.test.js +188 -0
  243. package/dist/plugins/agents/claude-code/mcp-approval-server.test.js.map +1 -0
  244. package/dist/plugins/agents/codex/adapter.test.d.ts +2 -0
  245. package/dist/plugins/agents/codex/adapter.test.d.ts.map +1 -0
  246. package/dist/plugins/agents/codex/adapter.test.js +192 -0
  247. package/dist/plugins/agents/codex/adapter.test.js.map +1 -0
  248. package/dist/plugins/agents/codex/index.d.ts +37 -0
  249. package/dist/plugins/agents/codex/index.d.ts.map +1 -0
  250. package/dist/plugins/agents/codex/index.js +254 -0
  251. package/dist/plugins/agents/codex/index.js.map +1 -0
  252. package/dist/plugins/agents/copilot/index.d.ts +35 -0
  253. package/dist/plugins/agents/copilot/index.d.ts.map +1 -0
  254. package/dist/plugins/agents/copilot/index.js +182 -0
  255. package/dist/plugins/agents/copilot/index.js.map +1 -0
  256. package/dist/plugins/agents/opencode/adapter.test.d.ts +2 -0
  257. package/dist/plugins/agents/opencode/adapter.test.d.ts.map +1 -0
  258. package/dist/plugins/agents/opencode/adapter.test.js +139 -0
  259. package/dist/plugins/agents/opencode/adapter.test.js.map +1 -0
  260. package/dist/plugins/agents/opencode/http-adapter.test.d.ts +2 -0
  261. package/dist/plugins/agents/opencode/http-adapter.test.d.ts.map +1 -0
  262. package/dist/plugins/agents/opencode/http-adapter.test.js +492 -0
  263. package/dist/plugins/agents/opencode/http-adapter.test.js.map +1 -0
  264. package/dist/plugins/agents/opencode/index.d.ts +5 -0
  265. package/dist/plugins/agents/opencode/index.d.ts.map +1 -0
  266. package/dist/plugins/agents/opencode/index.js +30 -0
  267. package/dist/plugins/agents/opencode/index.js.map +1 -0
  268. package/dist/plugins/agents/opencode/opencode-http-adapter.d.ts +138 -0
  269. package/dist/plugins/agents/opencode/opencode-http-adapter.d.ts.map +1 -0
  270. package/dist/plugins/agents/opencode/opencode-http-adapter.js +549 -0
  271. package/dist/plugins/agents/opencode/opencode-http-adapter.js.map +1 -0
  272. package/dist/plugins/agents/opencode/opencode-stdio-adapter.d.ts +24 -0
  273. package/dist/plugins/agents/opencode/opencode-stdio-adapter.d.ts.map +1 -0
  274. package/dist/plugins/agents/opencode/opencode-stdio-adapter.js +103 -0
  275. package/dist/plugins/agents/opencode/opencode-stdio-adapter.js.map +1 -0
  276. package/dist/plugins/agents/opencode/serve-manager.d.ts +27 -0
  277. package/dist/plugins/agents/opencode/serve-manager.d.ts.map +1 -0
  278. package/dist/plugins/agents/opencode/serve-manager.js +190 -0
  279. package/dist/plugins/agents/opencode/serve-manager.js.map +1 -0
  280. package/dist/plugins/messengers/discord/discord-adapter.d.ts +22 -0
  281. package/dist/plugins/messengers/discord/discord-adapter.d.ts.map +1 -0
  282. package/dist/plugins/messengers/discord/discord-adapter.js +241 -0
  283. package/dist/plugins/messengers/discord/discord-adapter.js.map +1 -0
  284. package/dist/plugins/messengers/discord/discord-adapter.test.d.ts +2 -0
  285. package/dist/plugins/messengers/discord/discord-adapter.test.d.ts.map +1 -0
  286. package/dist/plugins/messengers/discord/discord-adapter.test.js +332 -0
  287. package/dist/plugins/messengers/discord/discord-adapter.test.js.map +1 -0
  288. package/dist/plugins/messengers/discord/index.d.ts +4 -0
  289. package/dist/plugins/messengers/discord/index.d.ts.map +1 -0
  290. package/dist/plugins/messengers/discord/index.js +4 -0
  291. package/dist/plugins/messengers/discord/index.js.map +1 -0
  292. package/dist/plugins/messengers/discord/markdown-to-discord.d.ts +11 -0
  293. package/dist/plugins/messengers/discord/markdown-to-discord.d.ts.map +1 -0
  294. package/dist/plugins/messengers/discord/markdown-to-discord.js +59 -0
  295. package/dist/plugins/messengers/discord/markdown-to-discord.js.map +1 -0
  296. package/dist/plugins/messengers/discord/types.d.ts +9 -0
  297. package/dist/plugins/messengers/discord/types.d.ts.map +1 -0
  298. package/dist/plugins/messengers/discord/types.js +3 -0
  299. package/dist/plugins/messengers/discord/types.js.map +1 -0
  300. package/dist/plugins/messengers/feishu/card-builder.d.ts +23 -0
  301. package/dist/plugins/messengers/feishu/card-builder.d.ts.map +1 -0
  302. package/dist/plugins/messengers/feishu/card-builder.js +89 -0
  303. package/dist/plugins/messengers/feishu/card-builder.js.map +1 -0
  304. package/dist/plugins/messengers/feishu/feishu-adapter.d.ts +33 -0
  305. package/dist/plugins/messengers/feishu/feishu-adapter.d.ts.map +1 -0
  306. package/dist/plugins/messengers/feishu/feishu-adapter.js +195 -0
  307. package/dist/plugins/messengers/feishu/feishu-adapter.js.map +1 -0
  308. package/dist/plugins/messengers/feishu/feishu-client.d.ts +44 -0
  309. package/dist/plugins/messengers/feishu/feishu-client.d.ts.map +1 -0
  310. package/dist/plugins/messengers/feishu/feishu-client.js +120 -0
  311. package/dist/plugins/messengers/feishu/feishu-client.js.map +1 -0
  312. package/dist/plugins/messengers/feishu/feishu-dedup.test.d.ts +2 -0
  313. package/dist/plugins/messengers/feishu/feishu-dedup.test.d.ts.map +1 -0
  314. package/dist/plugins/messengers/feishu/feishu-dedup.test.js +70 -0
  315. package/dist/plugins/messengers/feishu/feishu-dedup.test.js.map +1 -0
  316. package/dist/plugins/messengers/feishu/index.d.ts +4 -0
  317. package/dist/plugins/messengers/feishu/index.d.ts.map +1 -0
  318. package/dist/plugins/messengers/feishu/index.js +4 -0
  319. package/dist/plugins/messengers/feishu/index.js.map +1 -0
  320. package/dist/plugins/messengers/feishu/types.d.ts +113 -0
  321. package/dist/plugins/messengers/feishu/types.d.ts.map +1 -0
  322. package/dist/plugins/messengers/feishu/types.js +4 -0
  323. package/dist/plugins/messengers/feishu/types.js.map +1 -0
  324. package/dist/plugins/messengers/telegram/index.d.ts +4 -0
  325. package/dist/plugins/messengers/telegram/index.d.ts.map +1 -0
  326. package/dist/plugins/messengers/telegram/index.js +4 -0
  327. package/dist/plugins/messengers/telegram/index.js.map +1 -0
  328. package/dist/plugins/messengers/telegram/markdown-to-html.d.ts +5 -0
  329. package/dist/plugins/messengers/telegram/markdown-to-html.d.ts.map +1 -0
  330. package/dist/plugins/messengers/telegram/markdown-to-html.js +186 -0
  331. package/dist/plugins/messengers/telegram/markdown-to-html.js.map +1 -0
  332. package/dist/plugins/messengers/telegram/media-download.d.ts +51 -0
  333. package/dist/plugins/messengers/telegram/media-download.d.ts.map +1 -0
  334. package/dist/plugins/messengers/telegram/media-download.js +224 -0
  335. package/dist/plugins/messengers/telegram/media-download.js.map +1 -0
  336. package/dist/plugins/messengers/telegram/media-download.test.d.ts +2 -0
  337. package/dist/plugins/messengers/telegram/media-download.test.d.ts.map +1 -0
  338. package/dist/plugins/messengers/telegram/media-download.test.js +125 -0
  339. package/dist/plugins/messengers/telegram/media-download.test.js.map +1 -0
  340. package/dist/plugins/messengers/telegram/telegram-adapter.d.ts +62 -0
  341. package/dist/plugins/messengers/telegram/telegram-adapter.d.ts.map +1 -0
  342. package/dist/plugins/messengers/telegram/telegram-adapter.js +653 -0
  343. package/dist/plugins/messengers/telegram/telegram-adapter.js.map +1 -0
  344. package/dist/plugins/messengers/telegram/types.d.ts +47 -0
  345. package/dist/plugins/messengers/telegram/types.d.ts.map +1 -0
  346. package/dist/plugins/messengers/telegram/types.js +3 -0
  347. package/dist/plugins/messengers/telegram/types.js.map +1 -0
  348. package/dist/plugins/messengers/wechat/ilink-adapter.d.ts +68 -0
  349. package/dist/plugins/messengers/wechat/ilink-adapter.d.ts.map +1 -0
  350. package/dist/plugins/messengers/wechat/ilink-adapter.js +483 -0
  351. package/dist/plugins/messengers/wechat/ilink-adapter.js.map +1 -0
  352. package/dist/plugins/messengers/wechat/ilink-client.d.ts +66 -0
  353. package/dist/plugins/messengers/wechat/ilink-client.d.ts.map +1 -0
  354. package/dist/plugins/messengers/wechat/ilink-client.js +288 -0
  355. package/dist/plugins/messengers/wechat/ilink-client.js.map +1 -0
  356. package/dist/plugins/messengers/wechat/ilink-types.d.ts +173 -0
  357. package/dist/plugins/messengers/wechat/ilink-types.d.ts.map +1 -0
  358. package/dist/plugins/messengers/wechat/ilink-types.js +12 -0
  359. package/dist/plugins/messengers/wechat/ilink-types.js.map +1 -0
  360. package/dist/utils/backoff.d.ts +35 -0
  361. package/dist/utils/backoff.d.ts.map +1 -0
  362. package/dist/utils/backoff.js +59 -0
  363. package/dist/utils/backoff.js.map +1 -0
  364. package/dist/utils/cross-platform.d.ts +26 -0
  365. package/dist/utils/cross-platform.d.ts.map +1 -0
  366. package/dist/utils/cross-platform.js +58 -0
  367. package/dist/utils/cross-platform.js.map +1 -0
  368. package/dist/utils/message-split.d.ts +14 -0
  369. package/dist/utils/message-split.d.ts.map +1 -0
  370. package/dist/utils/message-split.js +65 -0
  371. package/dist/utils/message-split.js.map +1 -0
  372. package/dist/utils/safe-equal.d.ts +2 -0
  373. package/dist/utils/safe-equal.d.ts.map +1 -0
  374. package/dist/utils/safe-equal.js +11 -0
  375. package/dist/utils/safe-equal.js.map +1 -0
  376. package/dist/web/public/_app.js +196 -0
  377. package/dist/web/public/index.html +935 -0
  378. package/dist/web/public/settings.html +1181 -0
  379. package/dist/web/public/tasks.html +1827 -0
  380. package/dist/web/server.d.ts +11 -0
  381. package/dist/web/server.d.ts.map +1 -0
  382. package/dist/web/server.js +1820 -0
  383. package/dist/web/server.js.map +1 -0
  384. package/package.json +73 -0
@@ -0,0 +1,103 @@
1
+ // OpenCode CLI agent adapter — stdio (JSONL) driver.
2
+ // Uses `opencode run --format json` for programmatic interaction.
3
+ //
4
+ // Two flavors of multi-turn continuity, mirroring the claude-code adapter:
5
+ //
6
+ // First turn — no opts.agentSessionId yet. Spawn `opencode run …` plain.
7
+ // The adapter watches for `sessionID` on the very first event
8
+ // and reports it back via opts.onAgentSessionId so cli can
9
+ // persist it on the im-hub Session row.
10
+ // Later turns — opts.agentSessionId is the captured ses_… id. We pass
11
+ // `--session <id>` so opencode reads the conversation from
12
+ // its own DB instead of relying on im-hub stitching the
13
+ // history into the prompt. router.callAgentWithHistory
14
+ // honours this by zeroing out `effectiveHistory` whenever
15
+ // `agentSessionResume` is true.
16
+ //
17
+ // Cost accounting: opencode emits `cost` and `tokens.{input,output}` in
18
+ // `step_finish` events. We forward those as opts.onUsage deltas so /stats
19
+ // reflects opencode reality (it had been hard-coded to 0 before).
20
+ //
21
+ // Known limitation (the reason OpenCodeHttpAdapter exists): `opencode run`'s
22
+ // stdout JSON stream does NOT emit `permission.asked`, and its inline auto-
23
+ // reject logic occasionally fails to release the prompt deferred. Result:
24
+ // process hangs until the 30-min hard timeout fires. The HTTP driver fixes
25
+ // this at the root by driving opencode via its REST + SSE API instead.
26
+ import { AgentBase } from '../../../core/agent-base.js';
27
+ import { resolveAgentCwd } from '../../../core/agent-cwd.js';
28
+ export class OpenCodeAdapter extends AgentBase {
29
+ name = 'opencode';
30
+ aliases = ['oc', 'opencodeai'];
31
+ buildArgs(prompt, opts) {
32
+ const args = ['run', '--format', 'json'];
33
+ if (opts.agentSessionId)
34
+ args.push('--session', opts.agentSessionId);
35
+ if (opts.model)
36
+ args.push('--model', opts.model);
37
+ if (opts.variant)
38
+ args.push('--variant', opts.variant);
39
+ // planMode → opencode's built-in `plan` agent. Its policy denies edit/
40
+ // write outside .opencode/plans/*.md and allows the LLM to call
41
+ // `plan_exit` when it's done — but we intentionally do NOT auto-flip
42
+ // session.planMode on plan_exit (see docs/architecture/plan-mode.md);
43
+ // the user keeps control of the toggle via /plan off.
44
+ if (opts.planMode)
45
+ args.push('--agent', 'plan');
46
+ args.push(prompt);
47
+ return args;
48
+ }
49
+ /**
50
+ * opencode keys its per-project AGENTS.md and memory off the spawn cwd,
51
+ * so for IM calls we pin to ~/.im-hub-workspaces/opencode/. Non-IM calls
52
+ * (web/scheduler) keep cwd undefined and inherit im-hub's cwd, preserving
53
+ * the prior behavior. See agent-cwd.ts for full rationale.
54
+ */
55
+ async prepareCommand(prompt, opts) {
56
+ return {
57
+ args: this.buildArgs(prompt, opts),
58
+ cwd: resolveAgentCwd(this.name, opts),
59
+ };
60
+ }
61
+ extractText(event) {
62
+ const e = event;
63
+ if (e.type === 'text' && e.part?.text)
64
+ return e.part.text;
65
+ if (e.type === 'content' && e.content)
66
+ return e.content;
67
+ return '';
68
+ }
69
+ /**
70
+ * Pull metadata out of every event:
71
+ * - `sessionID` on any event → bubble up via opts.onAgentSessionId so cli
72
+ * can persist it. Idempotent (the callback handles dedup).
73
+ * - `cost` / `tokens` on `step_finish` → bubble up via opts.onUsage so
74
+ * callAgentWithHistory can roll into /stats.
75
+ */
76
+ inspectEvent(event, opts) {
77
+ const e = event;
78
+ if (e.sessionID && opts.onAgentSessionId) {
79
+ try {
80
+ opts.onAgentSessionId(e.sessionID);
81
+ }
82
+ catch { /* don't let userland callbacks kill the stream */ }
83
+ }
84
+ if (e.type === 'step_finish' && opts.onUsage) {
85
+ // cost / tokens are NESTED inside event.part, not on the event itself.
86
+ const part = e.part;
87
+ const delta = {};
88
+ if (typeof part?.cost === 'number' && Number.isFinite(part.cost))
89
+ delta.costUsd = part.cost;
90
+ if (typeof part?.tokens?.input === 'number')
91
+ delta.tokensInput = part.tokens.input;
92
+ if (typeof part?.tokens?.output === 'number')
93
+ delta.tokensOutput = part.tokens.output;
94
+ if (delta.costUsd !== undefined || delta.tokensInput !== undefined || delta.tokensOutput !== undefined) {
95
+ try {
96
+ opts.onUsage(delta);
97
+ }
98
+ catch { /* same — user callback safety */ }
99
+ }
100
+ }
101
+ }
102
+ }
103
+ //# sourceMappingURL=opencode-stdio-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencode-stdio-adapter.js","sourceRoot":"","sources":["../../../../src/plugins/agents/opencode/opencode-stdio-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ export interface ServeOptions {
2
+ /** Port to bind. Default: env IMHUB_OPENCODE_PORT or 14199. */
3
+ port?: number;
4
+ /** Host to bind. Default: 127.0.0.1. */
5
+ hostname?: string;
6
+ /** cwd for the spawn. Has no effect on per-session directory (sessions are
7
+ * created with their own directory) but determines where opencode looks
8
+ * for its global config. Default: process.cwd(). */
9
+ cwd?: string;
10
+ }
11
+ export declare class OpencodeServeManager {
12
+ private child;
13
+ private baseUrl;
14
+ private startPromise;
15
+ private readonly opts;
16
+ constructor(opts?: ServeOptions);
17
+ /** Start the daemon if needed and return the base URL once ready. Idempotent. */
18
+ ensureRunning(): Promise<string>;
19
+ isRunning(): boolean;
20
+ getBaseUrl(): string | null;
21
+ /** Stop the daemon. Used by tests and on im-hub shutdown. */
22
+ stop(): Promise<void>;
23
+ private spawnAndWait;
24
+ }
25
+ /** Process-wide singleton. Tests can `new OpencodeServeManager()` on their own. */
26
+ export declare const opencodeServe: OpencodeServeManager;
27
+ //# sourceMappingURL=serve-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve-manager.d.ts","sourceRoot":"","sources":["../../../../src/plugins/agents/opencode/serve-manager.ts"],"names":[],"mappings":"AA2BA,MAAM,WAAW,YAAY;IAC3B,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;yDAEqD;IACrD,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,KAAK,CAA4B;IACzC,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,YAAY,CAA+B;IACnD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAkE;gBAE3E,IAAI,GAAE,YAAiB;IASnC,iFAAiF;IACjF,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAWhC,SAAS,IAAI,OAAO;IAIpB,UAAU,IAAI,MAAM,GAAG,IAAI;IAE3B,6DAA6D;IACvD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAiBb,YAAY;CAiG3B;AAuBD,mFAAmF;AACnF,eAAO,MAAM,aAAa,sBAA6B,CAAA"}
@@ -0,0 +1,190 @@
1
+ // OpencodeServeManager — lazy-launches and supervises a single
2
+ // `opencode serve` daemon that the HTTP adapter and the IM permission
3
+ // bridge talk to.
4
+ //
5
+ // Design notes:
6
+ // - Singleton per im-hub process. Multiple IM threads share one daemon —
7
+ // opencode's session model is per-session anyway, so collisions don't
8
+ // happen on the wire.
9
+ // - First call to ensureRunning() starts the child; readiness is detected
10
+ // by watching stderr for "listening on http://…" (the line opencode emits
11
+ // unconditionally) and falling back to an HTTP probe if that's missed.
12
+ // - If the child dies, the next ensureRunning() respawns. We don't
13
+ // auto-restart in the background — silent restart loops hide problems.
14
+ // - Bound to 127.0.0.1 by default. The server warns about
15
+ // OPENCODE_SERVER_PASSWORD being unset; we silence that intentionally
16
+ // since the surface is loopback only. Set it via env if you expose the
17
+ // port off-host.
18
+ import { crossSpawn } from '../../../utils/cross-platform.js';
19
+ import { logger as rootLogger } from '../../../core/logger.js';
20
+ const log = rootLogger.child({ component: 'opencode.serve' });
21
+ const READY_TIMEOUT_MS = 15_000;
22
+ const READY_REGEX = /listening on (https?:\/\/[^\s]+)/i;
23
+ export class OpencodeServeManager {
24
+ child = null;
25
+ baseUrl = null;
26
+ startPromise = null;
27
+ opts;
28
+ constructor(opts = {}) {
29
+ const envPort = process.env.IMHUB_OPENCODE_PORT;
30
+ this.opts = {
31
+ port: opts.port ?? (envPort ? parseInt(envPort, 10) : 14199),
32
+ hostname: opts.hostname ?? '127.0.0.1',
33
+ cwd: opts.cwd,
34
+ };
35
+ }
36
+ /** Start the daemon if needed and return the base URL once ready. Idempotent. */
37
+ ensureRunning() {
38
+ if (this.baseUrl && this.child && !this.child.killed) {
39
+ return Promise.resolve(this.baseUrl);
40
+ }
41
+ if (this.startPromise)
42
+ return this.startPromise;
43
+ this.startPromise = this.spawnAndWait().finally(() => {
44
+ this.startPromise = null;
45
+ });
46
+ return this.startPromise;
47
+ }
48
+ isRunning() {
49
+ return this.child !== null && !this.child.killed && this.baseUrl !== null;
50
+ }
51
+ getBaseUrl() { return this.baseUrl; }
52
+ /** Stop the daemon. Used by tests and on im-hub shutdown. */
53
+ async stop() {
54
+ const child = this.child;
55
+ if (!child)
56
+ return;
57
+ this.child = null;
58
+ this.baseUrl = null;
59
+ return new Promise((resolve) => {
60
+ const kill = setTimeout(() => {
61
+ try {
62
+ child.kill('SIGKILL');
63
+ }
64
+ catch { /* ignore */ }
65
+ }, 2000);
66
+ child.once('close', () => {
67
+ clearTimeout(kill);
68
+ resolve();
69
+ });
70
+ try {
71
+ child.kill('SIGTERM');
72
+ }
73
+ catch { /* ignore */ }
74
+ });
75
+ }
76
+ async spawnAndWait() {
77
+ const { port, hostname, cwd } = this.opts;
78
+ const candidateUrl = `http://${hostname}:${port}`;
79
+ // Probe before spawn: a previous im-hub run (or our own restart) may have
80
+ // left a healthy `opencode serve` on the same port. Spawning a second one
81
+ // would just bind-fail with code=1 and break the next user message — we
82
+ // saw exactly that in audit row 309 on 2026-05-04. If the port answers
83
+ // and the response looks like opencode, reuse it instead.
84
+ if (await probeOpencodeServe(candidateUrl)) {
85
+ this.baseUrl = candidateUrl;
86
+ log.info({ event: 'opencode.serve.reused', baseUrl: candidateUrl }, 'reusing existing opencode serve on configured port');
87
+ return candidateUrl;
88
+ }
89
+ log.info({ event: 'opencode.serve.starting', port, hostname }, 'starting opencode serve');
90
+ const child = crossSpawn('opencode', ['serve', '--port', String(port), '--hostname', hostname], {
91
+ stdio: ['ignore', 'pipe', 'pipe'],
92
+ cwd,
93
+ env: process.env,
94
+ });
95
+ this.child = child;
96
+ let resolved = false;
97
+ const ready = new Promise((resolve, reject) => {
98
+ const timer = setTimeout(() => {
99
+ if (resolved)
100
+ return;
101
+ resolved = true;
102
+ log.error({ event: 'opencode.serve.timeout' }, 'opencode serve did not become ready in time');
103
+ try {
104
+ child.kill('SIGTERM');
105
+ }
106
+ catch { /* ignore */ }
107
+ reject(new Error('opencode serve did not become ready within ' + READY_TIMEOUT_MS + 'ms'));
108
+ }, READY_TIMEOUT_MS);
109
+ const onLine = (line) => {
110
+ const m = line.match(READY_REGEX);
111
+ if (m && !resolved) {
112
+ resolved = true;
113
+ clearTimeout(timer);
114
+ this.baseUrl = m[1].replace(/\/+$/, '');
115
+ log.info({ event: 'opencode.serve.ready', baseUrl: this.baseUrl }, 'opencode serve ready');
116
+ resolve(this.baseUrl);
117
+ }
118
+ };
119
+ const stderr = child.stderr;
120
+ const stdout = child.stdout;
121
+ let stderrBuf = '';
122
+ let stdoutBuf = '';
123
+ stderr?.on('data', (data) => {
124
+ stderrBuf += data.toString('utf8');
125
+ let nl;
126
+ while ((nl = stderrBuf.indexOf('\n')) !== -1) {
127
+ const line = stderrBuf.slice(0, nl);
128
+ stderrBuf = stderrBuf.slice(nl + 1);
129
+ if (line.trim())
130
+ onLine(line);
131
+ }
132
+ });
133
+ stdout?.on('data', (data) => {
134
+ stdoutBuf += data.toString('utf8');
135
+ let nl;
136
+ while ((nl = stdoutBuf.indexOf('\n')) !== -1) {
137
+ const line = stdoutBuf.slice(0, nl);
138
+ stdoutBuf = stdoutBuf.slice(nl + 1);
139
+ if (line.trim())
140
+ onLine(line);
141
+ }
142
+ });
143
+ child.on('error', (err) => {
144
+ if (resolved)
145
+ return;
146
+ resolved = true;
147
+ clearTimeout(timer);
148
+ reject(err);
149
+ });
150
+ child.on('close', (code, signal) => {
151
+ log.warn({ event: 'opencode.serve.exited', code, signal }, 'opencode serve exited');
152
+ if (this.child === child) {
153
+ this.child = null;
154
+ this.baseUrl = null;
155
+ }
156
+ if (!resolved) {
157
+ resolved = true;
158
+ clearTimeout(timer);
159
+ reject(new Error(`opencode serve exited before ready (code=${code}, signal=${signal})`));
160
+ }
161
+ });
162
+ });
163
+ return ready;
164
+ }
165
+ }
166
+ /**
167
+ * Probe a candidate URL: if `GET /` returns 2xx within ~500ms, treat the
168
+ * port as already serving an opencode instance we can reuse. We don't try
169
+ * to fingerprint the response body — the localhost-only attack surface
170
+ * doesn't justify it; if some other service happens to listen on the
171
+ * configured port the reuse path will fail later when /event is hit and
172
+ * the adapter surfaces a clear error to the user.
173
+ */
174
+ async function probeOpencodeServe(baseUrl) {
175
+ const controller = new AbortController();
176
+ const timer = setTimeout(() => controller.abort(), 500);
177
+ try {
178
+ const res = await fetch(baseUrl + '/', { signal: controller.signal });
179
+ return res.ok;
180
+ }
181
+ catch {
182
+ return false;
183
+ }
184
+ finally {
185
+ clearTimeout(timer);
186
+ }
187
+ }
188
+ /** Process-wide singleton. Tests can `new OpencodeServeManager()` on their own. */
189
+ export const opencodeServe = new OpencodeServeManager();
190
+ //# sourceMappingURL=serve-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve-manager.js","sourceRoot":"","sources":["../../../../src/plugins/agents/opencode/serve-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { MessengerAdapter, MessageContext } from '../../../core/types.js';
2
+ export declare class DiscordAdapter implements MessengerAdapter {
3
+ readonly name = "discord";
4
+ private client;
5
+ private config;
6
+ private messageHandler?;
7
+ private isRunning;
8
+ private typingIntervals;
9
+ /** L7: companion AbortController per typing thread. Lets the periodic
10
+ * refresh callback bail BEFORE invoking sendTyping when stop() has
11
+ * fired, instead of racing against client.destroy(). */
12
+ private typingAbortControllers;
13
+ start(): Promise<void>;
14
+ stop(): Promise<void>;
15
+ onMessage(handler: (ctx: MessageContext) => Promise<void>): void;
16
+ sendMessage(threadId: string, text: string): Promise<void>;
17
+ sendTyping(threadId: string, isTyping: boolean): Promise<void>;
18
+ private fetchSendableChannel;
19
+ private handleDiscordMessage;
20
+ }
21
+ export declare const discordAdapter: DiscordAdapter;
22
+ //# sourceMappingURL=discord-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discord-adapter.d.ts","sourceRoot":"","sources":["../../../../src/plugins/messengers/discord/discord-adapter.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAW,MAAM,wBAAwB,CAAA;AAWvF,qBAAa,cAAe,YAAW,gBAAgB;IACrD,QAAQ,CAAC,IAAI,aAAY;IACzB,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,cAAc,CAAC,CAAwC;IAC/D,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,eAAe,CAAoD;IAC3E;;6DAEyD;IACzD,OAAO,CAAC,sBAAsB,CAAqC;IAE7D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA2DtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAyB3B,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAI1D,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsB1D,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;YA4DtD,oBAAoB;YAcpB,oBAAoB;CAyDnC;AAGD,eAAO,MAAM,cAAc,gBAAuB,CAAA"}
@@ -0,0 +1,241 @@
1
+ // Discord Bot API Adapter using discord.js
2
+ // Implements MessengerAdapter interface with typing indicator support
3
+ import { Client, GatewayIntentBits, Partials, ChannelType, } from 'discord.js';
4
+ import { markdownToDiscord } from './markdown-to-discord.js';
5
+ import { splitMessage } from '../../../utils/message-split.js';
6
+ import { logger as rootLogger } from '../../../core/logger.js';
7
+ const log = rootLogger.child({ component: 'discord' });
8
+ // Discord message limit is 2000 characters
9
+ const DISCORD_MAX_LENGTH = 2000;
10
+ export class DiscordAdapter {
11
+ name = 'discord';
12
+ client = null;
13
+ config = null;
14
+ messageHandler;
15
+ isRunning = false;
16
+ typingIntervals = new Map();
17
+ /** L7: companion AbortController per typing thread. Lets the periodic
18
+ * refresh callback bail BEFORE invoking sendTyping when stop() has
19
+ * fired, instead of racing against client.destroy(). */
20
+ typingAbortControllers = new Map();
21
+ async start() {
22
+ // Load config
23
+ const { readFile } = await import('fs/promises');
24
+ const { homedir } = await import('os');
25
+ const { join } = await import('path');
26
+ const configPath = join(homedir(), '.im-hub', 'config.json');
27
+ try {
28
+ const data = await readFile(configPath, 'utf-8');
29
+ const config = JSON.parse(data);
30
+ this.config = config.discord;
31
+ }
32
+ catch {
33
+ throw new Error('Discord config not found. Run "im-hub config discord" first.');
34
+ }
35
+ if (!this.config?.botToken) {
36
+ throw new Error('Discord bot token not configured. Run "im-hub config discord" first.');
37
+ }
38
+ // Initialize Discord client with required intents
39
+ this.client = new Client({
40
+ intents: [
41
+ GatewayIntentBits.Guilds,
42
+ GatewayIntentBits.GuildMessages,
43
+ GatewayIntentBits.MessageContent, // Privileged intent - must enable in Developer Portal
44
+ GatewayIntentBits.DirectMessages, // For DM support
45
+ ],
46
+ partials: [
47
+ Partials.Channel, // Required for DM support
48
+ Partials.Message,
49
+ ],
50
+ });
51
+ // Ready event
52
+ this.client.on('ready', (client) => {
53
+ log.info({ user: client.user.tag, guilds: client.guilds.cache.size }, `Discord bot logged in as ${client.user.tag}`);
54
+ });
55
+ // Set up message handler
56
+ this.client.on('messageCreate', async (message) => {
57
+ await this.handleDiscordMessage(message);
58
+ });
59
+ // Error handling
60
+ this.client.on('error', (error) => {
61
+ log.error({ err: error.message }, 'Discord client error');
62
+ });
63
+ this.client.on('warn', (warning) => {
64
+ log.warn({ warning }, 'Discord client warning');
65
+ });
66
+ // Login to Discord
67
+ await this.client.login(this.config.botToken);
68
+ this.isRunning = true;
69
+ log.info('Discord adapter started');
70
+ }
71
+ async stop() {
72
+ this.isRunning = false;
73
+ // L7: abort first (signal in-flight refresh callbacks to bail) then
74
+ // clearInterval (prevent new ticks). Doing it in the other order would
75
+ // leave one tick that already entered the callback racing with
76
+ // client.destroy(); even though sendTyping errors are caught, the
77
+ // log line is noise and the API call wastes a request.
78
+ for (const ac of this.typingAbortControllers.values()) {
79
+ ac.abort();
80
+ }
81
+ this.typingAbortControllers.clear();
82
+ for (const interval of this.typingIntervals.values()) {
83
+ clearInterval(interval);
84
+ }
85
+ this.typingIntervals.clear();
86
+ if (this.client) {
87
+ this.client.destroy();
88
+ this.client = null;
89
+ }
90
+ log.info('Discord adapter stopped');
91
+ }
92
+ onMessage(handler) {
93
+ this.messageHandler = handler;
94
+ }
95
+ async sendMessage(threadId, text) {
96
+ if (!this.client) {
97
+ throw new Error('Discord adapter not started');
98
+ }
99
+ const channel = await this.fetchSendableChannel(threadId);
100
+ if (!channel) {
101
+ throw new Error(`Channel ${threadId} not found or not text-based`);
102
+ }
103
+ // Convert markdown and split into chunks
104
+ const discordText = markdownToDiscord(text);
105
+ const chunks = splitMessage(discordText, {
106
+ maxLength: DISCORD_MAX_LENGTH,
107
+ addContinuationMarker: false,
108
+ });
109
+ for (const chunk of chunks) {
110
+ await channel.send(chunk);
111
+ }
112
+ }
113
+ async sendTyping(threadId, isTyping) {
114
+ if (!this.client) {
115
+ return;
116
+ }
117
+ if (isTyping) {
118
+ const channel = await this.fetchSendableChannel(threadId);
119
+ if (!channel) {
120
+ return;
121
+ }
122
+ // Send initial typing indicator
123
+ try {
124
+ await channel.sendTyping();
125
+ }
126
+ catch {
127
+ // Ignore errors during typing
128
+ }
129
+ // Clear any existing interval + abort signal — both per-thread.
130
+ const existing = this.typingIntervals.get(threadId);
131
+ if (existing)
132
+ clearInterval(existing);
133
+ const existingAc = this.typingAbortControllers.get(threadId);
134
+ if (existingAc)
135
+ existingAc.abort();
136
+ // Discord typing indicator lasts ~10 seconds, refresh every 8 seconds.
137
+ // L7: AbortController gates each tick — when stop() (or a subsequent
138
+ // sendTyping(false)) aborts, in-flight callbacks bail early instead
139
+ // of racing client.destroy().
140
+ const ac = new AbortController();
141
+ const interval = setInterval(async () => {
142
+ if (ac.signal.aborted)
143
+ return;
144
+ try {
145
+ await channel.sendTyping();
146
+ }
147
+ catch {
148
+ // Ignore errors during typing refresh
149
+ }
150
+ }, 8000);
151
+ this.typingIntervals.set(threadId, interval);
152
+ this.typingAbortControllers.set(threadId, ac);
153
+ }
154
+ else {
155
+ // Clear the refresh interval + abort signal
156
+ const interval = this.typingIntervals.get(threadId);
157
+ if (interval) {
158
+ clearInterval(interval);
159
+ this.typingIntervals.delete(threadId);
160
+ }
161
+ const ac = this.typingAbortControllers.get(threadId);
162
+ if (ac) {
163
+ ac.abort();
164
+ this.typingAbortControllers.delete(threadId);
165
+ }
166
+ // Note: Discord has no "cancel typing" API - it just expires naturally
167
+ }
168
+ }
169
+ // ============================================
170
+ // Internal methods
171
+ // ============================================
172
+ async fetchSendableChannel(threadId) {
173
+ if (!this.client)
174
+ return null;
175
+ const channel = await this.client.channels.fetch(threadId).catch(() => null);
176
+ if (!channel)
177
+ return null;
178
+ if (channel.type === ChannelType.GuildText || channel.type === ChannelType.DM) {
179
+ return channel;
180
+ }
181
+ // Also support announcement/thread channels
182
+ if (channel.isTextBased() && 'send' in channel) {
183
+ return channel;
184
+ }
185
+ return null;
186
+ }
187
+ async handleDiscordMessage(message) {
188
+ // Ignore bot messages (including our own)
189
+ if (message.author.bot) {
190
+ return;
191
+ }
192
+ // Guild whitelist filter
193
+ if (this.config?.allowedGuilds?.length && message.guildId) {
194
+ if (!this.config.allowedGuilds.includes(message.guildId)) {
195
+ log.debug({ guildId: message.guildId }, 'Message from non-whitelisted guild, ignoring');
196
+ return;
197
+ }
198
+ }
199
+ // Channel whitelist filter
200
+ if (this.config?.allowedChannels?.length) {
201
+ if (!this.config.allowedChannels.includes(message.channelId)) {
202
+ log.debug({ channelId: message.channelId }, 'Message from non-whitelisted channel, ignoring');
203
+ return;
204
+ }
205
+ }
206
+ // Skip empty messages (e.g. image-only, embed-only)
207
+ if (!message.content && !message.attachments.size) {
208
+ return;
209
+ }
210
+ if (!this.messageHandler) {
211
+ log.debug('No message handler registered');
212
+ return;
213
+ }
214
+ try {
215
+ const msg = {
216
+ id: message.id,
217
+ threadId: message.channelId,
218
+ userId: message.author.id,
219
+ text: message.content || '',
220
+ timestamp: message.createdAt,
221
+ channelId: this.config?.channelId || 'default',
222
+ };
223
+ const msgCtx = {
224
+ message: msg,
225
+ platform: 'discord',
226
+ channelId: this.config?.channelId || 'default',
227
+ };
228
+ log.debug({ threadId: msg.threadId, userId: msg.userId }, 'Calling message handler');
229
+ await this.messageHandler(msgCtx);
230
+ log.debug({ threadId: msg.threadId }, 'Message handler completed');
231
+ }
232
+ catch (err) {
233
+ const errMsg = err instanceof Error ? err.message : String(err);
234
+ const stack = err instanceof Error ? err.stack : undefined;
235
+ log.error({ err: errMsg, stack }, 'Error in message handler');
236
+ }
237
+ }
238
+ }
239
+ // Singleton instance
240
+ export const discordAdapter = new DiscordAdapter();
241
+ //# sourceMappingURL=discord-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discord-adapter.js","sourceRoot":"","sources":["../../../../src/plugins/messengers/discord/discord-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=discord-adapter.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discord-adapter.test.d.ts","sourceRoot":"","sources":["../../../../src/plugins/messengers/discord/discord-adapter.test.ts"],"names":[],"mappings":""}