agim-cli 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (453) hide show
  1. package/CHANGELOG.md +1234 -0
  2. package/LICENSE +21 -0
  3. package/README.md +422 -0
  4. package/README.zh-CN.md +414 -0
  5. package/dist/cli-ui/cmd-handlers.d.ts +11 -0
  6. package/dist/cli-ui/cmd-handlers.d.ts.map +1 -0
  7. package/dist/cli-ui/cmd-handlers.js +240 -0
  8. package/dist/cli-ui/cmd-handlers.js.map +1 -0
  9. package/dist/cli-ui/config-wizard.d.ts +3 -0
  10. package/dist/cli-ui/config-wizard.d.ts.map +1 -0
  11. package/dist/cli-ui/config-wizard.js +851 -0
  12. package/dist/cli-ui/config-wizard.js.map +1 -0
  13. package/dist/cli-ui/entry-menu.d.ts +28 -0
  14. package/dist/cli-ui/entry-menu.d.ts.map +1 -0
  15. package/dist/cli-ui/entry-menu.js +50 -0
  16. package/dist/cli-ui/entry-menu.js.map +1 -0
  17. package/dist/cli-ui/env-file.d.ts +35 -0
  18. package/dist/cli-ui/env-file.d.ts.map +1 -0
  19. package/dist/cli-ui/env-file.js +163 -0
  20. package/dist/cli-ui/env-file.js.map +1 -0
  21. package/dist/cli-ui/i18n.d.ts +204 -0
  22. package/dist/cli-ui/i18n.d.ts.map +1 -0
  23. package/dist/cli-ui/i18n.js +455 -0
  24. package/dist/cli-ui/i18n.js.map +1 -0
  25. package/dist/cli-ui/lang-picker.d.ts +10 -0
  26. package/dist/cli-ui/lang-picker.d.ts.map +1 -0
  27. package/dist/cli-ui/lang-picker.js +33 -0
  28. package/dist/cli-ui/lang-picker.js.map +1 -0
  29. package/dist/cli-ui/paths.d.ts +4 -0
  30. package/dist/cli-ui/paths.d.ts.map +1 -0
  31. package/dist/cli-ui/paths.js +11 -0
  32. package/dist/cli-ui/paths.js.map +1 -0
  33. package/dist/cli-ui/prompts.d.ts +65 -0
  34. package/dist/cli-ui/prompts.d.ts.map +1 -0
  35. package/dist/cli-ui/prompts.js +125 -0
  36. package/dist/cli-ui/prompts.js.map +1 -0
  37. package/dist/cli-ui/service.d.ts +41 -0
  38. package/dist/cli-ui/service.d.ts.map +1 -0
  39. package/dist/cli-ui/service.js +241 -0
  40. package/dist/cli-ui/service.js.map +1 -0
  41. package/dist/cli.d.ts +3 -0
  42. package/dist/cli.d.ts.map +1 -0
  43. package/dist/cli.js +1143 -0
  44. package/dist/cli.js.map +1 -0
  45. package/dist/core/acp-server.d.ts +8 -0
  46. package/dist/core/acp-server.d.ts.map +1 -0
  47. package/dist/core/acp-server.js +266 -0
  48. package/dist/core/acp-server.js.map +1 -0
  49. package/dist/core/agent-base.d.ts +94 -0
  50. package/dist/core/agent-base.d.ts.map +1 -0
  51. package/dist/core/agent-base.js +373 -0
  52. package/dist/core/agent-base.js.map +1 -0
  53. package/dist/core/agent-cwd.d.ts +48 -0
  54. package/dist/core/agent-cwd.d.ts.map +1 -0
  55. package/dist/core/agent-cwd.js +181 -0
  56. package/dist/core/agent-cwd.js.map +1 -0
  57. package/dist/core/agent-helper.d.ts +65 -0
  58. package/dist/core/agent-helper.d.ts.map +1 -0
  59. package/dist/core/agent-helper.js +150 -0
  60. package/dist/core/agent-helper.js.map +1 -0
  61. package/dist/core/agim-paths.d.ts +10 -0
  62. package/dist/core/agim-paths.d.ts.map +1 -0
  63. package/dist/core/agim-paths.js +64 -0
  64. package/dist/core/agim-paths.js.map +1 -0
  65. package/dist/core/approval-bus.d.ts +300 -0
  66. package/dist/core/approval-bus.d.ts.map +1 -0
  67. package/dist/core/approval-bus.js +990 -0
  68. package/dist/core/approval-bus.js.map +1 -0
  69. package/dist/core/approval-router.d.ts +101 -0
  70. package/dist/core/approval-router.d.ts.map +1 -0
  71. package/dist/core/approval-router.js +540 -0
  72. package/dist/core/approval-router.js.map +1 -0
  73. package/dist/core/audit-log.d.ts +55 -0
  74. package/dist/core/audit-log.d.ts.map +1 -0
  75. package/dist/core/audit-log.js +203 -0
  76. package/dist/core/audit-log.js.map +1 -0
  77. package/dist/core/bgjob-reader.d.ts +65 -0
  78. package/dist/core/bgjob-reader.d.ts.map +1 -0
  79. package/dist/core/bgjob-reader.js +212 -0
  80. package/dist/core/bgjob-reader.js.map +1 -0
  81. package/dist/core/circuit-breaker.d.ts +37 -0
  82. package/dist/core/circuit-breaker.d.ts.map +1 -0
  83. package/dist/core/circuit-breaker.js +115 -0
  84. package/dist/core/circuit-breaker.js.map +1 -0
  85. package/dist/core/commands/agent.d.ts +4 -0
  86. package/dist/core/commands/agent.d.ts.map +1 -0
  87. package/dist/core/commands/agent.js +40 -0
  88. package/dist/core/commands/agent.js.map +1 -0
  89. package/dist/core/commands/approval.d.ts +3 -0
  90. package/dist/core/commands/approval.d.ts.map +1 -0
  91. package/dist/core/commands/approval.js +85 -0
  92. package/dist/core/commands/approval.js.map +1 -0
  93. package/dist/core/commands/audit.d.ts +3 -0
  94. package/dist/core/commands/audit.d.ts.map +1 -0
  95. package/dist/core/commands/audit.js +84 -0
  96. package/dist/core/commands/audit.js.map +1 -0
  97. package/dist/core/commands/builtin.d.ts +3 -0
  98. package/dist/core/commands/builtin.d.ts.map +1 -0
  99. package/dist/core/commands/builtin.js +304 -0
  100. package/dist/core/commands/builtin.js.map +1 -0
  101. package/dist/core/commands/cron.d.ts +3 -0
  102. package/dist/core/commands/cron.d.ts.map +1 -0
  103. package/dist/core/commands/cron.js +128 -0
  104. package/dist/core/commands/cron.js.map +1 -0
  105. package/dist/core/commands/job.d.ts +3 -0
  106. package/dist/core/commands/job.d.ts.map +1 -0
  107. package/dist/core/commands/job.js +195 -0
  108. package/dist/core/commands/job.js.map +1 -0
  109. package/dist/core/commands/memo.d.ts +3 -0
  110. package/dist/core/commands/memo.d.ts.map +1 -0
  111. package/dist/core/commands/memo.js +151 -0
  112. package/dist/core/commands/memo.js.map +1 -0
  113. package/dist/core/commands/model.d.ts +9 -0
  114. package/dist/core/commands/model.d.ts.map +1 -0
  115. package/dist/core/commands/model.js +183 -0
  116. package/dist/core/commands/model.js.map +1 -0
  117. package/dist/core/commands/plan.d.ts +3 -0
  118. package/dist/core/commands/plan.d.ts.map +1 -0
  119. package/dist/core/commands/plan.js +75 -0
  120. package/dist/core/commands/plan.js.map +1 -0
  121. package/dist/core/commands/remind.d.ts +3 -0
  122. package/dist/core/commands/remind.d.ts.map +1 -0
  123. package/dist/core/commands/remind.js +271 -0
  124. package/dist/core/commands/remind.js.map +1 -0
  125. package/dist/core/commands/router.d.ts +3 -0
  126. package/dist/core/commands/router.d.ts.map +1 -0
  127. package/dist/core/commands/router.js +71 -0
  128. package/dist/core/commands/router.js.map +1 -0
  129. package/dist/core/commands/sessions.d.ts +3 -0
  130. package/dist/core/commands/sessions.d.ts.map +1 -0
  131. package/dist/core/commands/sessions.js +88 -0
  132. package/dist/core/commands/sessions.js.map +1 -0
  133. package/dist/core/commands/stats.d.ts +3 -0
  134. package/dist/core/commands/stats.d.ts.map +1 -0
  135. package/dist/core/commands/stats.js +73 -0
  136. package/dist/core/commands/stats.js.map +1 -0
  137. package/dist/core/commands/think.d.ts +3 -0
  138. package/dist/core/commands/think.d.ts.map +1 -0
  139. package/dist/core/commands/think.js +28 -0
  140. package/dist/core/commands/think.js.map +1 -0
  141. package/dist/core/commands/workspaces.d.ts +3 -0
  142. package/dist/core/commands/workspaces.d.ts.map +1 -0
  143. package/dist/core/commands/workspaces.js +47 -0
  144. package/dist/core/commands/workspaces.js.map +1 -0
  145. package/dist/core/config-schema.d.ts +60 -0
  146. package/dist/core/config-schema.d.ts.map +1 -0
  147. package/dist/core/config-schema.js +75 -0
  148. package/dist/core/config-schema.js.map +1 -0
  149. package/dist/core/coord-systems.d.ts +65 -0
  150. package/dist/core/coord-systems.d.ts.map +1 -0
  151. package/dist/core/coord-systems.js +229 -0
  152. package/dist/core/coord-systems.js.map +1 -0
  153. package/dist/core/cron.d.ts +29 -0
  154. package/dist/core/cron.d.ts.map +1 -0
  155. package/dist/core/cron.js +184 -0
  156. package/dist/core/cron.js.map +1 -0
  157. package/dist/core/event-bus.d.ts +80 -0
  158. package/dist/core/event-bus.d.ts.map +1 -0
  159. package/dist/core/event-bus.js +62 -0
  160. package/dist/core/event-bus.js.map +1 -0
  161. package/dist/core/intent-llm.d.ts +27 -0
  162. package/dist/core/intent-llm.d.ts.map +1 -0
  163. package/dist/core/intent-llm.js +170 -0
  164. package/dist/core/intent-llm.js.map +1 -0
  165. package/dist/core/intent.d.ts +12 -0
  166. package/dist/core/intent.d.ts.map +1 -0
  167. package/dist/core/intent.js +187 -0
  168. package/dist/core/intent.js.map +1 -0
  169. package/dist/core/job-board.d.ts +82 -0
  170. package/dist/core/job-board.d.ts.map +1 -0
  171. package/dist/core/job-board.js +379 -0
  172. package/dist/core/job-board.js.map +1 -0
  173. package/dist/core/location-context.d.ts +32 -0
  174. package/dist/core/location-context.d.ts.map +1 -0
  175. package/dist/core/location-context.js +69 -0
  176. package/dist/core/location-context.js.map +1 -0
  177. package/dist/core/location-token.d.ts +57 -0
  178. package/dist/core/location-token.d.ts.map +1 -0
  179. package/dist/core/location-token.js +128 -0
  180. package/dist/core/location-token.js.map +1 -0
  181. package/dist/core/logger.d.ts +6 -0
  182. package/dist/core/logger.d.ts.map +1 -0
  183. package/dist/core/logger.js +54 -0
  184. package/dist/core/logger.js.map +1 -0
  185. package/dist/core/memo-rpc.d.ts +13 -0
  186. package/dist/core/memo-rpc.d.ts.map +1 -0
  187. package/dist/core/memo-rpc.js +288 -0
  188. package/dist/core/memo-rpc.js.map +1 -0
  189. package/dist/core/memos.d.ts +163 -0
  190. package/dist/core/memos.d.ts.map +1 -0
  191. package/dist/core/memos.js +502 -0
  192. package/dist/core/memos.js.map +1 -0
  193. package/dist/core/metrics.d.ts +55 -0
  194. package/dist/core/metrics.d.ts.map +1 -0
  195. package/dist/core/metrics.js +291 -0
  196. package/dist/core/metrics.js.map +1 -0
  197. package/dist/core/onboarding.d.ts +99 -0
  198. package/dist/core/onboarding.d.ts.map +1 -0
  199. package/dist/core/onboarding.js +426 -0
  200. package/dist/core/onboarding.js.map +1 -0
  201. package/dist/core/pending-reminder.d.ts +25 -0
  202. package/dist/core/pending-reminder.d.ts.map +1 -0
  203. package/dist/core/pending-reminder.js +53 -0
  204. package/dist/core/pending-reminder.js.map +1 -0
  205. package/dist/core/rate-limiter.d.ts +44 -0
  206. package/dist/core/rate-limiter.d.ts.map +1 -0
  207. package/dist/core/rate-limiter.js +115 -0
  208. package/dist/core/rate-limiter.js.map +1 -0
  209. package/dist/core/registry.d.ts +32 -0
  210. package/dist/core/registry.d.ts.map +1 -0
  211. package/dist/core/registry.js +126 -0
  212. package/dist/core/registry.js.map +1 -0
  213. package/dist/core/remind-intent.d.ts +25 -0
  214. package/dist/core/remind-intent.d.ts.map +1 -0
  215. package/dist/core/remind-intent.js +196 -0
  216. package/dist/core/remind-intent.js.map +1 -0
  217. package/dist/core/reminder-rpc.d.ts +17 -0
  218. package/dist/core/reminder-rpc.d.ts.map +1 -0
  219. package/dist/core/reminder-rpc.js +169 -0
  220. package/dist/core/reminder-rpc.js.map +1 -0
  221. package/dist/core/reminders.d.ts +159 -0
  222. package/dist/core/reminders.d.ts.map +1 -0
  223. package/dist/core/reminders.js +977 -0
  224. package/dist/core/reminders.js.map +1 -0
  225. package/dist/core/router.d.ts +55 -0
  226. package/dist/core/router.d.ts.map +1 -0
  227. package/dist/core/router.js +497 -0
  228. package/dist/core/router.js.map +1 -0
  229. package/dist/core/schedule.d.ts +65 -0
  230. package/dist/core/schedule.d.ts.map +1 -0
  231. package/dist/core/schedule.js +323 -0
  232. package/dist/core/schedule.js.map +1 -0
  233. package/dist/core/session.d.ts +182 -0
  234. package/dist/core/session.d.ts.map +1 -0
  235. package/dist/core/session.js +807 -0
  236. package/dist/core/session.js.map +1 -0
  237. package/dist/core/sqlite-helper.d.ts +37 -0
  238. package/dist/core/sqlite-helper.d.ts.map +1 -0
  239. package/dist/core/sqlite-helper.js +79 -0
  240. package/dist/core/sqlite-helper.js.map +1 -0
  241. package/dist/core/transcribe.d.ts +25 -0
  242. package/dist/core/transcribe.d.ts.map +1 -0
  243. package/dist/core/transcribe.js +217 -0
  244. package/dist/core/transcribe.js.map +1 -0
  245. package/dist/core/types.d.ts +360 -0
  246. package/dist/core/types.d.ts.map +1 -0
  247. package/dist/core/types.js +3 -0
  248. package/dist/core/types.js.map +1 -0
  249. package/dist/core/workspace.d.ts +67 -0
  250. package/dist/core/workspace.d.ts.map +1 -0
  251. package/dist/core/workspace.js +113 -0
  252. package/dist/core/workspace.js.map +1 -0
  253. package/dist/index.d.ts +5 -0
  254. package/dist/index.d.ts.map +1 -0
  255. package/dist/index.js +6 -0
  256. package/dist/index.js.map +1 -0
  257. package/dist/plugins/agents/acp/acp-adapter.d.ts +16 -0
  258. package/dist/plugins/agents/acp/acp-adapter.d.ts.map +1 -0
  259. package/dist/plugins/agents/acp/acp-adapter.js +49 -0
  260. package/dist/plugins/agents/acp/acp-adapter.js.map +1 -0
  261. package/dist/plugins/agents/acp/acp-client.d.ts +32 -0
  262. package/dist/plugins/agents/acp/acp-client.d.ts.map +1 -0
  263. package/dist/plugins/agents/acp/acp-client.js +177 -0
  264. package/dist/plugins/agents/acp/acp-client.js.map +1 -0
  265. package/dist/plugins/agents/acp/discovery.d.ts +19 -0
  266. package/dist/plugins/agents/acp/discovery.d.ts.map +1 -0
  267. package/dist/plugins/agents/acp/discovery.js +111 -0
  268. package/dist/plugins/agents/acp/discovery.js.map +1 -0
  269. package/dist/plugins/agents/acp/index.d.ts +4 -0
  270. package/dist/plugins/agents/acp/index.d.ts.map +1 -0
  271. package/dist/plugins/agents/acp/index.js +4 -0
  272. package/dist/plugins/agents/acp/index.js.map +1 -0
  273. package/dist/plugins/agents/acp/types.d.ts +62 -0
  274. package/dist/plugins/agents/acp/types.d.ts.map +1 -0
  275. package/dist/plugins/agents/acp/types.js +5 -0
  276. package/dist/plugins/agents/acp/types.js.map +1 -0
  277. package/dist/plugins/agents/claude-code/index.d.ts +25 -0
  278. package/dist/plugins/agents/claude-code/index.d.ts.map +1 -0
  279. package/dist/plugins/agents/claude-code/index.js +184 -0
  280. package/dist/plugins/agents/claude-code/index.js.map +1 -0
  281. package/dist/plugins/agents/claude-code/mcp-approval-server.d.ts +59 -0
  282. package/dist/plugins/agents/claude-code/mcp-approval-server.d.ts.map +1 -0
  283. package/dist/plugins/agents/claude-code/mcp-approval-server.js +645 -0
  284. package/dist/plugins/agents/claude-code/mcp-approval-server.js.map +1 -0
  285. package/dist/plugins/agents/codex/build-mcp-cli-args.d.ts +28 -0
  286. package/dist/plugins/agents/codex/build-mcp-cli-args.d.ts.map +1 -0
  287. package/dist/plugins/agents/codex/build-mcp-cli-args.js +74 -0
  288. package/dist/plugins/agents/codex/build-mcp-cli-args.js.map +1 -0
  289. package/dist/plugins/agents/codex/index.d.ts +53 -0
  290. package/dist/plugins/agents/codex/index.d.ts.map +1 -0
  291. package/dist/plugins/agents/codex/index.js +341 -0
  292. package/dist/plugins/agents/codex/index.js.map +1 -0
  293. package/dist/plugins/agents/copilot/index.d.ts +35 -0
  294. package/dist/plugins/agents/copilot/index.d.ts.map +1 -0
  295. package/dist/plugins/agents/copilot/index.js +182 -0
  296. package/dist/plugins/agents/copilot/index.js.map +1 -0
  297. package/dist/plugins/agents/opencode/ensure-mcp-config.d.ts +11 -0
  298. package/dist/plugins/agents/opencode/ensure-mcp-config.d.ts.map +1 -0
  299. package/dist/plugins/agents/opencode/ensure-mcp-config.js +100 -0
  300. package/dist/plugins/agents/opencode/ensure-mcp-config.js.map +1 -0
  301. package/dist/plugins/agents/opencode/index.d.ts +5 -0
  302. package/dist/plugins/agents/opencode/index.d.ts.map +1 -0
  303. package/dist/plugins/agents/opencode/index.js +30 -0
  304. package/dist/plugins/agents/opencode/index.js.map +1 -0
  305. package/dist/plugins/agents/opencode/opencode-http-adapter.d.ts +166 -0
  306. package/dist/plugins/agents/opencode/opencode-http-adapter.d.ts.map +1 -0
  307. package/dist/plugins/agents/opencode/opencode-http-adapter.js +682 -0
  308. package/dist/plugins/agents/opencode/opencode-http-adapter.js.map +1 -0
  309. package/dist/plugins/agents/opencode/opencode-stdio-adapter.d.ts +32 -0
  310. package/dist/plugins/agents/opencode/opencode-stdio-adapter.d.ts.map +1 -0
  311. package/dist/plugins/agents/opencode/opencode-stdio-adapter.js +137 -0
  312. package/dist/plugins/agents/opencode/opencode-stdio-adapter.js.map +1 -0
  313. package/dist/plugins/agents/opencode/serve-manager.d.ts +27 -0
  314. package/dist/plugins/agents/opencode/serve-manager.d.ts.map +1 -0
  315. package/dist/plugins/agents/opencode/serve-manager.js +194 -0
  316. package/dist/plugins/agents/opencode/serve-manager.js.map +1 -0
  317. package/dist/plugins/messengers/dingtalk/dingtalk-adapter.d.ts +57 -0
  318. package/dist/plugins/messengers/dingtalk/dingtalk-adapter.d.ts.map +1 -0
  319. package/dist/plugins/messengers/dingtalk/dingtalk-adapter.js +409 -0
  320. package/dist/plugins/messengers/dingtalk/dingtalk-adapter.js.map +1 -0
  321. package/dist/plugins/messengers/dingtalk/dingtalk-client.d.ts +48 -0
  322. package/dist/plugins/messengers/dingtalk/dingtalk-client.d.ts.map +1 -0
  323. package/dist/plugins/messengers/dingtalk/dingtalk-client.js +236 -0
  324. package/dist/plugins/messengers/dingtalk/dingtalk-client.js.map +1 -0
  325. package/dist/plugins/messengers/dingtalk/index.d.ts +3 -0
  326. package/dist/plugins/messengers/dingtalk/index.d.ts.map +1 -0
  327. package/dist/plugins/messengers/dingtalk/index.js +3 -0
  328. package/dist/plugins/messengers/dingtalk/index.js.map +1 -0
  329. package/dist/plugins/messengers/dingtalk/link-coords.d.ts +23 -0
  330. package/dist/plugins/messengers/dingtalk/link-coords.d.ts.map +1 -0
  331. package/dist/plugins/messengers/dingtalk/link-coords.js +89 -0
  332. package/dist/plugins/messengers/dingtalk/link-coords.js.map +1 -0
  333. package/dist/plugins/messengers/dingtalk/media-store.d.ts +16 -0
  334. package/dist/plugins/messengers/dingtalk/media-store.d.ts.map +1 -0
  335. package/dist/plugins/messengers/dingtalk/media-store.js +77 -0
  336. package/dist/plugins/messengers/dingtalk/media-store.js.map +1 -0
  337. package/dist/plugins/messengers/dingtalk/types.d.ts +82 -0
  338. package/dist/plugins/messengers/dingtalk/types.d.ts.map +1 -0
  339. package/dist/plugins/messengers/dingtalk/types.js +14 -0
  340. package/dist/plugins/messengers/dingtalk/types.js.map +1 -0
  341. package/dist/plugins/messengers/discord/discord-adapter.d.ts +21 -0
  342. package/dist/plugins/messengers/discord/discord-adapter.d.ts.map +1 -0
  343. package/dist/plugins/messengers/discord/discord-adapter.js +238 -0
  344. package/dist/plugins/messengers/discord/discord-adapter.js.map +1 -0
  345. package/dist/plugins/messengers/discord/index.d.ts +4 -0
  346. package/dist/plugins/messengers/discord/index.d.ts.map +1 -0
  347. package/dist/plugins/messengers/discord/index.js +4 -0
  348. package/dist/plugins/messengers/discord/index.js.map +1 -0
  349. package/dist/plugins/messengers/discord/markdown-to-discord.d.ts +11 -0
  350. package/dist/plugins/messengers/discord/markdown-to-discord.d.ts.map +1 -0
  351. package/dist/plugins/messengers/discord/markdown-to-discord.js +59 -0
  352. package/dist/plugins/messengers/discord/markdown-to-discord.js.map +1 -0
  353. package/dist/plugins/messengers/discord/types.d.ts +9 -0
  354. package/dist/plugins/messengers/discord/types.d.ts.map +1 -0
  355. package/dist/plugins/messengers/discord/types.js +3 -0
  356. package/dist/plugins/messengers/discord/types.js.map +1 -0
  357. package/dist/plugins/messengers/email/email-adapter.d.ts +33 -0
  358. package/dist/plugins/messengers/email/email-adapter.d.ts.map +1 -0
  359. package/dist/plugins/messengers/email/email-adapter.js +137 -0
  360. package/dist/plugins/messengers/email/email-adapter.js.map +1 -0
  361. package/dist/plugins/messengers/feishu/card-builder.d.ts +23 -0
  362. package/dist/plugins/messengers/feishu/card-builder.d.ts.map +1 -0
  363. package/dist/plugins/messengers/feishu/card-builder.js +89 -0
  364. package/dist/plugins/messengers/feishu/card-builder.js.map +1 -0
  365. package/dist/plugins/messengers/feishu/feishu-adapter.d.ts +23 -0
  366. package/dist/plugins/messengers/feishu/feishu-adapter.d.ts.map +1 -0
  367. package/dist/plugins/messengers/feishu/feishu-adapter.js +250 -0
  368. package/dist/plugins/messengers/feishu/feishu-adapter.js.map +1 -0
  369. package/dist/plugins/messengers/feishu/feishu-client.d.ts +43 -0
  370. package/dist/plugins/messengers/feishu/feishu-client.d.ts.map +1 -0
  371. package/dist/plugins/messengers/feishu/feishu-client.js +118 -0
  372. package/dist/plugins/messengers/feishu/feishu-client.js.map +1 -0
  373. package/dist/plugins/messengers/feishu/index.d.ts +4 -0
  374. package/dist/plugins/messengers/feishu/index.d.ts.map +1 -0
  375. package/dist/plugins/messengers/feishu/index.js +4 -0
  376. package/dist/plugins/messengers/feishu/index.js.map +1 -0
  377. package/dist/plugins/messengers/feishu/types.d.ts +113 -0
  378. package/dist/plugins/messengers/feishu/types.d.ts.map +1 -0
  379. package/dist/plugins/messengers/feishu/types.js +4 -0
  380. package/dist/plugins/messengers/feishu/types.js.map +1 -0
  381. package/dist/plugins/messengers/telegram/index.d.ts +4 -0
  382. package/dist/plugins/messengers/telegram/index.d.ts.map +1 -0
  383. package/dist/plugins/messengers/telegram/index.js +4 -0
  384. package/dist/plugins/messengers/telegram/index.js.map +1 -0
  385. package/dist/plugins/messengers/telegram/markdown-to-html.d.ts +5 -0
  386. package/dist/plugins/messengers/telegram/markdown-to-html.d.ts.map +1 -0
  387. package/dist/plugins/messengers/telegram/markdown-to-html.js +186 -0
  388. package/dist/plugins/messengers/telegram/markdown-to-html.js.map +1 -0
  389. package/dist/plugins/messengers/telegram/media-download.d.ts +59 -0
  390. package/dist/plugins/messengers/telegram/media-download.d.ts.map +1 -0
  391. package/dist/plugins/messengers/telegram/media-download.js +228 -0
  392. package/dist/plugins/messengers/telegram/media-download.js.map +1 -0
  393. package/dist/plugins/messengers/telegram/telegram-adapter.d.ts +77 -0
  394. package/dist/plugins/messengers/telegram/telegram-adapter.d.ts.map +1 -0
  395. package/dist/plugins/messengers/telegram/telegram-adapter.js +880 -0
  396. package/dist/plugins/messengers/telegram/telegram-adapter.js.map +1 -0
  397. package/dist/plugins/messengers/telegram/types.d.ts +47 -0
  398. package/dist/plugins/messengers/telegram/types.d.ts.map +1 -0
  399. package/dist/plugins/messengers/telegram/types.js +3 -0
  400. package/dist/plugins/messengers/telegram/types.js.map +1 -0
  401. package/dist/plugins/messengers/wechat/context-store.d.ts +18 -0
  402. package/dist/plugins/messengers/wechat/context-store.d.ts.map +1 -0
  403. package/dist/plugins/messengers/wechat/context-store.js +105 -0
  404. package/dist/plugins/messengers/wechat/context-store.js.map +1 -0
  405. package/dist/plugins/messengers/wechat/ilink-adapter.d.ts +71 -0
  406. package/dist/plugins/messengers/wechat/ilink-adapter.d.ts.map +1 -0
  407. package/dist/plugins/messengers/wechat/ilink-adapter.js +664 -0
  408. package/dist/plugins/messengers/wechat/ilink-adapter.js.map +1 -0
  409. package/dist/plugins/messengers/wechat/ilink-client.d.ts +75 -0
  410. package/dist/plugins/messengers/wechat/ilink-client.d.ts.map +1 -0
  411. package/dist/plugins/messengers/wechat/ilink-client.js +331 -0
  412. package/dist/plugins/messengers/wechat/ilink-client.js.map +1 -0
  413. package/dist/plugins/messengers/wechat/ilink-types.d.ts +181 -0
  414. package/dist/plugins/messengers/wechat/ilink-types.d.ts.map +1 -0
  415. package/dist/plugins/messengers/wechat/ilink-types.js +22 -0
  416. package/dist/plugins/messengers/wechat/ilink-types.js.map +1 -0
  417. package/dist/plugins/messengers/wechat/media-download.d.ts +32 -0
  418. package/dist/plugins/messengers/wechat/media-download.d.ts.map +1 -0
  419. package/dist/plugins/messengers/wechat/media-download.js +78 -0
  420. package/dist/plugins/messengers/wechat/media-download.js.map +1 -0
  421. package/dist/scripts/migrate-gcj02-to-wgs84.d.ts +3 -0
  422. package/dist/scripts/migrate-gcj02-to-wgs84.d.ts.map +1 -0
  423. package/dist/scripts/migrate-gcj02-to-wgs84.js +52 -0
  424. package/dist/scripts/migrate-gcj02-to-wgs84.js.map +1 -0
  425. package/dist/utils/backoff.d.ts +35 -0
  426. package/dist/utils/backoff.d.ts.map +1 -0
  427. package/dist/utils/backoff.js +59 -0
  428. package/dist/utils/backoff.js.map +1 -0
  429. package/dist/utils/cross-platform.d.ts +26 -0
  430. package/dist/utils/cross-platform.d.ts.map +1 -0
  431. package/dist/utils/cross-platform.js +58 -0
  432. package/dist/utils/cross-platform.js.map +1 -0
  433. package/dist/utils/message-split.d.ts +14 -0
  434. package/dist/utils/message-split.d.ts.map +1 -0
  435. package/dist/utils/message-split.js +65 -0
  436. package/dist/utils/message-split.js.map +1 -0
  437. package/dist/utils/safe-equal.d.ts +2 -0
  438. package/dist/utils/safe-equal.d.ts.map +1 -0
  439. package/dist/utils/safe-equal.js +11 -0
  440. package/dist/utils/safe-equal.js.map +1 -0
  441. package/dist/web/public/_app.js +196 -0
  442. package/dist/web/public/index.html +936 -0
  443. package/dist/web/public/loc.html +305 -0
  444. package/dist/web/public/login.html +106 -0
  445. package/dist/web/public/memos.html +271 -0
  446. package/dist/web/public/reminders.html +234 -0
  447. package/dist/web/public/settings.html +1355 -0
  448. package/dist/web/public/tasks.html +1835 -0
  449. package/dist/web/server.d.ts +12 -0
  450. package/dist/web/server.d.ts.map +1 -0
  451. package/dist/web/server.js +2399 -0
  452. package/dist/web/server.js.map +1 -0
  453. package/package.json +92 -0
@@ -0,0 +1,238 @@
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
+ typingIntervals = new Map();
16
+ /** L7: companion AbortController per typing thread. Lets the periodic
17
+ * refresh callback bail BEFORE invoking sendTyping when stop() has
18
+ * fired, instead of racing against client.destroy(). */
19
+ typingAbortControllers = new Map();
20
+ async start() {
21
+ // Load config
22
+ const { readFile } = await import('node:fs/promises');
23
+ const { join } = await import('node:path');
24
+ const { AGIM_HOME } = await import('../../../core/agim-paths.js');
25
+ const configPath = join(AGIM_HOME, 'config.json');
26
+ try {
27
+ const data = await readFile(configPath, 'utf-8');
28
+ const config = JSON.parse(data);
29
+ this.config = config.discord;
30
+ }
31
+ catch {
32
+ throw new Error('Discord config not found. Run "im-hub config discord" first.');
33
+ }
34
+ if (!this.config?.botToken) {
35
+ throw new Error('Discord bot token not configured. Run "im-hub config discord" first.');
36
+ }
37
+ // Initialize Discord client with required intents
38
+ this.client = new Client({
39
+ intents: [
40
+ GatewayIntentBits.Guilds,
41
+ GatewayIntentBits.GuildMessages,
42
+ GatewayIntentBits.MessageContent, // Privileged intent - must enable in Developer Portal
43
+ GatewayIntentBits.DirectMessages, // For DM support
44
+ ],
45
+ partials: [
46
+ Partials.Channel, // Required for DM support
47
+ Partials.Message,
48
+ ],
49
+ });
50
+ // Ready event
51
+ this.client.on('ready', (client) => {
52
+ log.info({ user: client.user.tag, guilds: client.guilds.cache.size }, `Discord bot logged in as ${client.user.tag}`);
53
+ });
54
+ // Set up message handler
55
+ this.client.on('messageCreate', async (message) => {
56
+ await this.handleDiscordMessage(message);
57
+ });
58
+ // Error handling
59
+ this.client.on('error', (error) => {
60
+ log.error({ err: error.message }, 'Discord client error');
61
+ });
62
+ this.client.on('warn', (warning) => {
63
+ log.warn({ warning }, 'Discord client warning');
64
+ });
65
+ // Login to Discord
66
+ await this.client.login(this.config.botToken);
67
+ log.info('Discord adapter started');
68
+ }
69
+ async stop() {
70
+ // L7: abort first (signal in-flight refresh callbacks to bail) then
71
+ // clearInterval (prevent new ticks). Doing it in the other order would
72
+ // leave one tick that already entered the callback racing with
73
+ // client.destroy(); even though sendTyping errors are caught, the
74
+ // log line is noise and the API call wastes a request.
75
+ for (const ac of this.typingAbortControllers.values()) {
76
+ ac.abort();
77
+ }
78
+ this.typingAbortControllers.clear();
79
+ for (const interval of this.typingIntervals.values()) {
80
+ clearInterval(interval);
81
+ }
82
+ this.typingIntervals.clear();
83
+ if (this.client) {
84
+ this.client.destroy();
85
+ this.client = null;
86
+ }
87
+ log.info('Discord adapter stopped');
88
+ }
89
+ onMessage(handler) {
90
+ this.messageHandler = handler;
91
+ }
92
+ async sendMessage(threadId, text) {
93
+ if (!this.client) {
94
+ throw new Error('Discord adapter not started');
95
+ }
96
+ const channel = await this.fetchSendableChannel(threadId);
97
+ if (!channel) {
98
+ throw new Error(`Channel ${threadId} not found or not text-based`);
99
+ }
100
+ // Convert markdown and split into chunks
101
+ const discordText = markdownToDiscord(text);
102
+ const chunks = splitMessage(discordText, {
103
+ maxLength: DISCORD_MAX_LENGTH,
104
+ addContinuationMarker: false,
105
+ });
106
+ for (const chunk of chunks) {
107
+ await channel.send(chunk);
108
+ }
109
+ }
110
+ async sendTyping(threadId, isTyping) {
111
+ if (!this.client) {
112
+ return;
113
+ }
114
+ if (isTyping) {
115
+ const channel = await this.fetchSendableChannel(threadId);
116
+ if (!channel) {
117
+ return;
118
+ }
119
+ // Send initial typing indicator
120
+ try {
121
+ await channel.sendTyping();
122
+ }
123
+ catch {
124
+ // Ignore errors during typing
125
+ }
126
+ // Clear any existing interval + abort signal — both per-thread.
127
+ const existing = this.typingIntervals.get(threadId);
128
+ if (existing)
129
+ clearInterval(existing);
130
+ const existingAc = this.typingAbortControllers.get(threadId);
131
+ if (existingAc)
132
+ existingAc.abort();
133
+ // Discord typing indicator lasts ~10 seconds, refresh every 8 seconds.
134
+ // L7: AbortController gates each tick — when stop() (or a subsequent
135
+ // sendTyping(false)) aborts, in-flight callbacks bail early instead
136
+ // of racing client.destroy().
137
+ const ac = new AbortController();
138
+ const interval = setInterval(async () => {
139
+ if (ac.signal.aborted)
140
+ return;
141
+ try {
142
+ await channel.sendTyping();
143
+ }
144
+ catch {
145
+ // Ignore errors during typing refresh
146
+ }
147
+ }, 8000);
148
+ this.typingIntervals.set(threadId, interval);
149
+ this.typingAbortControllers.set(threadId, ac);
150
+ }
151
+ else {
152
+ // Clear the refresh interval + abort signal
153
+ const interval = this.typingIntervals.get(threadId);
154
+ if (interval) {
155
+ clearInterval(interval);
156
+ this.typingIntervals.delete(threadId);
157
+ }
158
+ const ac = this.typingAbortControllers.get(threadId);
159
+ if (ac) {
160
+ ac.abort();
161
+ this.typingAbortControllers.delete(threadId);
162
+ }
163
+ // Note: Discord has no "cancel typing" API - it just expires naturally
164
+ }
165
+ }
166
+ // ============================================
167
+ // Internal methods
168
+ // ============================================
169
+ async fetchSendableChannel(threadId) {
170
+ if (!this.client)
171
+ return null;
172
+ const channel = await this.client.channels.fetch(threadId).catch(() => null);
173
+ if (!channel)
174
+ return null;
175
+ if (channel.type === ChannelType.GuildText || channel.type === ChannelType.DM) {
176
+ return channel;
177
+ }
178
+ // Also support announcement/thread channels
179
+ if (channel.isTextBased() && 'send' in channel) {
180
+ return channel;
181
+ }
182
+ return null;
183
+ }
184
+ async handleDiscordMessage(message) {
185
+ // Ignore bot messages (including our own)
186
+ if (message.author.bot) {
187
+ return;
188
+ }
189
+ // Guild whitelist filter
190
+ if (this.config?.allowedGuilds?.length && message.guildId) {
191
+ if (!this.config.allowedGuilds.includes(message.guildId)) {
192
+ log.debug({ guildId: message.guildId }, 'Message from non-whitelisted guild, ignoring');
193
+ return;
194
+ }
195
+ }
196
+ // Channel whitelist filter
197
+ if (this.config?.allowedChannels?.length) {
198
+ if (!this.config.allowedChannels.includes(message.channelId)) {
199
+ log.debug({ channelId: message.channelId }, 'Message from non-whitelisted channel, ignoring');
200
+ return;
201
+ }
202
+ }
203
+ // Skip empty messages (e.g. image-only, embed-only)
204
+ if (!message.content && !message.attachments.size) {
205
+ return;
206
+ }
207
+ if (!this.messageHandler) {
208
+ log.debug('No message handler registered');
209
+ return;
210
+ }
211
+ try {
212
+ const msg = {
213
+ id: message.id,
214
+ threadId: message.channelId,
215
+ userId: message.author.id,
216
+ text: message.content || '',
217
+ timestamp: message.createdAt,
218
+ channelId: this.config?.channelId || 'default',
219
+ };
220
+ const msgCtx = {
221
+ message: msg,
222
+ platform: 'discord',
223
+ channelId: this.config?.channelId || 'default',
224
+ };
225
+ log.debug({ threadId: msg.threadId, userId: msg.userId }, 'Calling message handler');
226
+ await this.messageHandler(msgCtx);
227
+ log.debug({ threadId: msg.threadId }, 'Message handler completed');
228
+ }
229
+ catch (err) {
230
+ const errMsg = err instanceof Error ? err.message : String(err);
231
+ const stack = err instanceof Error ? err.stack : undefined;
232
+ log.error({ err: errMsg, stack }, 'Error in message handler');
233
+ }
234
+ }
235
+ }
236
+ // Singleton instance
237
+ export const discordAdapter = new DiscordAdapter();
238
+ //# 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,4 @@
1
+ export { DiscordAdapter, discordAdapter } from './discord-adapter.js';
2
+ export type { DiscordConfig } from './types.js';
3
+ export { markdownToDiscord } from './markdown-to-discord.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/plugins/messengers/discord/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA"}
@@ -0,0 +1,4 @@
1
+ // Discord adapter exports
2
+ export { DiscordAdapter, discordAdapter } from './discord-adapter.js';
3
+ export { markdownToDiscord } from './markdown-to-discord.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/plugins/messengers/discord/index.ts"],"names":[],"mappings":"AAAA,0BAA0B;AAE1B,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAErE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Convert standard Markdown to Discord-compatible Markdown.
3
+ *
4
+ * Discord already supports most GFM, so the main job here is:
5
+ * 1. Strip unsupported HTML tags (Discord ignores them)
6
+ * 2. Convert <b>/<i>/<s> to Discord markdown equivalents
7
+ * 3. Ensure code blocks are preserved
8
+ * 4. Convert headings to bold (Discord doesn't render # in regular messages)
9
+ */
10
+ export declare function markdownToDiscord(markdown: string): string;
11
+ //# sourceMappingURL=markdown-to-discord.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-to-discord.d.ts","sourceRoot":"","sources":["../../../../src/plugins/messengers/discord/markdown-to-discord.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CA4D1D"}
@@ -0,0 +1,59 @@
1
+ // Markdown to Discord format converter
2
+ // Discord natively supports: **bold**, *italic*, ~~strikethrough~~, `code`, ```code blocks```, > blockquote
3
+ // For long messages, we can use Embeds for richer formatting
4
+ /**
5
+ * Convert standard Markdown to Discord-compatible Markdown.
6
+ *
7
+ * Discord already supports most GFM, so the main job here is:
8
+ * 1. Strip unsupported HTML tags (Discord ignores them)
9
+ * 2. Convert <b>/<i>/<s> to Discord markdown equivalents
10
+ * 3. Ensure code blocks are preserved
11
+ * 4. Convert headings to bold (Discord doesn't render # in regular messages)
12
+ */
13
+ export function markdownToDiscord(markdown) {
14
+ let result = markdown;
15
+ // Convert HTML bold/strong to Discord **bold**
16
+ result = result.replace(/<\/?(?:b|strong)>/gi, '**');
17
+ // Convert HTML italic/em to Discord *italic*
18
+ result = result.replace(/<\/?(?:i|em)>/gi, '*');
19
+ // Convert HTML strikethrough to Discord ~~strike~~
20
+ result = result.replace(/<\/?(?:s|del|strike)>/gi, '~~');
21
+ // Convert HTML underline to Discord __underline__
22
+ result = result.replace(/<\/?(?:u|ins)>/gi, '__');
23
+ // Convert HTML code to Discord `code`
24
+ result = result.replace(/<code>([^<]*)<\/code>/gi, '`$1`');
25
+ // Convert HTML links to Discord links
26
+ result = result.replace(/<a[^>]*href="([^"]*)"[^>]*>([^<]*)<\/a>/gi, '[$2]($1)');
27
+ // Convert HTML lists to plain text bullets
28
+ result = result.replace(/<ul[^>]*>([\s\S]*?)<\/ul>/gi, '\n$1');
29
+ result = result.replace(/<ol[^>]*>([\s\S]*?)<\/ol>/gi, '\n$1');
30
+ result = result.replace(/<li[^>]*>([\s\S]*?)<\/li>/gi, '- $1\n');
31
+ // Convert HTML blockquotes to Discord > blockquote
32
+ result = result.replace(/<blockquote[^>]*>([\s\S]*?)<\/blockquote>/gi, (_match, content) => {
33
+ return content
34
+ .split('\n')
35
+ .map((line) => `> ${line}`)
36
+ .join('\n');
37
+ });
38
+ // Convert headings (# syntax) to bold text for regular messages
39
+ // (Discord doesn't render heading syntax in normal messages)
40
+ result = result.replace(/^(#{1,6})\s+(.+)$/gm, (_match, _hashes, text) => {
41
+ return `**${text}**`;
42
+ });
43
+ // Convert <hr> to separator
44
+ result = result.replace(/<hr\s*\/?>/gi, '\n---\n');
45
+ // Convert <br> to newline
46
+ result = result.replace(/<br\s*\/?>/gi, '\n');
47
+ // Strip remaining HTML tags
48
+ result = result.replace(/<\/?[a-zA-Z][^>]*>/g, '');
49
+ // Decode common HTML entities
50
+ result = result.replace(/&amp;/g, '&');
51
+ result = result.replace(/&lt;/g, '<');
52
+ result = result.replace(/&gt;/g, '>');
53
+ result = result.replace(/&quot;/g, '"');
54
+ result = result.replace(/&#39;/g, "'");
55
+ // Clean up excess blank lines
56
+ result = result.replace(/\n{3,}/g, '\n\n');
57
+ return result.trim();
58
+ }
59
+ //# sourceMappingURL=markdown-to-discord.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-to-discord.js","sourceRoot":"","sources":["../../../../src/plugins/messengers/discord/markdown-to-discord.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,4GAA4G;AAC5G,6DAA6D;AAE7D;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,IAAI,MAAM,GAAG,QAAQ,CAAA;IAErB,+CAA+C;IAC/C,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,qBAAqB,EAAE,IAAI,CAAC,CAAA;IAEpD,6CAA6C;IAC7C,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAA;IAE/C,mDAAmD;IACnD,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,yBAAyB,EAAE,IAAI,CAAC,CAAA;IAExD,kDAAkD;IAClD,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAA;IAEjD,sCAAsC;IACtC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,yBAAyB,EAAE,MAAM,CAAC,CAAA;IAE1D,sCAAsC;IACtC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,2CAA2C,EAAE,UAAU,CAAC,CAAA;IAEhF,2CAA2C;IAC3C,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,6BAA6B,EAAE,MAAM,CAAC,CAAA;IAC9D,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,6BAA6B,EAAE,MAAM,CAAC,CAAA;IAC9D,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,6BAA6B,EAAE,QAAQ,CAAC,CAAA;IAEhE,mDAAmD;IACnD,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,6CAA6C,EAAE,CAAC,MAAM,EAAE,OAAe,EAAE,EAAE;QACjG,OAAO,OAAO;aACX,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC;aAClC,IAAI,CAAC,IAAI,CAAC,CAAA;IACf,CAAC,CAAC,CAAA;IAEF,gEAAgE;IAChE,6DAA6D;IAC7D,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;QACvE,OAAO,KAAK,IAAI,IAAI,CAAA;IACtB,CAAC,CAAC,CAAA;IAEF,4BAA4B;IAC5B,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,cAAc,EAAE,SAAS,CAAC,CAAA;IAElD,0BAA0B;IAC1B,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,CAAA;IAE7C,4BAA4B;IAC5B,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAA;IAElD,8BAA8B;IAC9B,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;IACtC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;IACrC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;IACrC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAA;IACvC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;IAEtC,8BAA8B;IAC9B,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;IAE1C,OAAO,MAAM,CAAC,IAAI,EAAE,CAAA;AACtB,CAAC"}
@@ -0,0 +1,9 @@
1
+ export interface DiscordConfig {
2
+ botToken: string;
3
+ channelId?: string;
4
+ /** Only respond in these guilds (server IDs). Empty = all guilds. */
5
+ allowedGuilds?: string[];
6
+ /** Only respond in these channels. Empty = all channels. */
7
+ allowedChannels?: string[];
8
+ }
9
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/plugins/messengers/discord/types.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,qEAAqE;IACrE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,4DAA4D;IAC5D,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;CAC3B"}
@@ -0,0 +1,3 @@
1
+ // Discord adapter types
2
+ export {};
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/plugins/messengers/discord/types.ts"],"names":[],"mappings":"AAAA,wBAAwB"}
@@ -0,0 +1,33 @@
1
+ import { type Transporter } from 'nodemailer';
2
+ import type { MessengerAdapter, MessageContext } from '../../../core/types.js';
3
+ interface SmtpConfig {
4
+ host: string;
5
+ port: number;
6
+ secure: boolean;
7
+ user: string;
8
+ pass: string;
9
+ from: string;
10
+ }
11
+ export declare class EmailAdapter implements MessengerAdapter {
12
+ readonly name = "email";
13
+ private transporter;
14
+ private config;
15
+ private started;
16
+ start(): Promise<void>;
17
+ stop(): Promise<void>;
18
+ onMessage(_handler: (ctx: MessageContext) => Promise<void>): void;
19
+ /**
20
+ * Send the message body to the email address in `threadId`. Subject is
21
+ * derived from the first line (capped at 100 chars). When SMTP isn't
22
+ * configured we throw a clear "not configured" error so the reminder
23
+ * engine writes it as the failure reason.
24
+ */
25
+ sendMessage(threadId: string, text: string): Promise<void>;
26
+ /** Test/inspection hook — used by unit tests to verify env reading. */
27
+ getEffectiveConfig(): SmtpConfig | null;
28
+ /** Test hook — inject a mocked transporter to bypass SMTP. */
29
+ _setTransporterForTest(t: Transporter, cfg: SmtpConfig): void;
30
+ }
31
+ export declare const emailAdapter: EmailAdapter;
32
+ export {};
33
+ //# sourceMappingURL=email-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-adapter.d.ts","sourceRoot":"","sources":["../../../../src/plugins/messengers/email/email-adapter.ts"],"names":[],"mappings":"AAmBA,OAAmB,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AACzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAK9E,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,OAAO,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb;AAwBD,qBAAa,YAAa,YAAW,gBAAgB;IACnD,QAAQ,CAAC,IAAI,WAAU;IACvB,OAAO,CAAC,WAAW,CAA2B;IAC9C,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,OAAO,CAAQ;IAEjB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAuCtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAW3B,SAAS,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAIjE;;;;;OAKG;IACG,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBhE,uEAAuE;IACvE,kBAAkB,IAAI,UAAU,GAAG,IAAI;IAIvC,8DAA8D;IAC9D,sBAAsB,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,UAAU,GAAG,IAAI;CAK9D;AAED,eAAO,MAAM,YAAY,cAAqB,CAAA"}
@@ -0,0 +1,137 @@
1
+ // Email messenger adapter (push-only).
2
+ //
3
+ // Purpose: deliver reminders / notifications to an email address. This
4
+ // adapter never receives messages — onMessage is a no-op — so /remind etc.
5
+ // addressed to an email arrive as a one-way notification.
6
+ //
7
+ // SMTP config is read from env at start():
8
+ // IMHUB_SMTP_HOST SMTP server (required)
9
+ // IMHUB_SMTP_PORT Port (default: 465 if secure else 587)
10
+ // IMHUB_SMTP_USER Auth username (required)
11
+ // IMHUB_SMTP_PASS Auth password / app-password (required)
12
+ // IMHUB_SMTP_FROM From address (default: USER value)
13
+ // IMHUB_SMTP_SECURE '1'/'true' for TLS-from-start (port 465); else
14
+ // STARTTLS on port 587. Default: secure if port 465.
15
+ //
16
+ // If any of HOST/USER/PASS are missing, start() does NOT throw; the adapter
17
+ // stays "registered but disabled" and sendMessage will throw a clear error
18
+ // at call time. Same fail-soft model as wechat-credentials.
19
+ import nodemailer from 'nodemailer';
20
+ import { logger as rootLogger } from '../../../core/logger.js';
21
+ const log = rootLogger.child({ component: 'email' });
22
+ function readSmtpConfig() {
23
+ const host = process.env.IMHUB_SMTP_HOST?.trim();
24
+ const user = process.env.IMHUB_SMTP_USER?.trim();
25
+ const pass = process.env.IMHUB_SMTP_PASS;
26
+ if (!host || !user || !pass)
27
+ return null;
28
+ const portRaw = process.env.IMHUB_SMTP_PORT?.trim();
29
+ const port = portRaw ? Number.parseInt(portRaw, 10) : 465;
30
+ if (!Number.isFinite(port) || port <= 0 || port > 65535) {
31
+ log.warn({ portRaw }, 'IMHUB_SMTP_PORT invalid, falling back to 465');
32
+ }
33
+ const validPort = Number.isFinite(port) && port > 0 && port <= 65535 ? port : 465;
34
+ // Default secure: yes for 465 (SMTPS), no for 587/25 (STARTTLS).
35
+ const secureRaw = process.env.IMHUB_SMTP_SECURE?.trim().toLowerCase();
36
+ const secure = secureRaw !== undefined
37
+ ? (secureRaw === '1' || secureRaw === 'true' || secureRaw === 'yes')
38
+ : validPort === 465;
39
+ const from = process.env.IMHUB_SMTP_FROM?.trim() || user;
40
+ return { host, port: validPort, secure, user, pass, from };
41
+ }
42
+ const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
43
+ export class EmailAdapter {
44
+ name = 'email';
45
+ transporter = null;
46
+ config = null;
47
+ started = false;
48
+ async start() {
49
+ this.config = readSmtpConfig();
50
+ if (!this.config) {
51
+ log.warn({
52
+ event: 'email.disabled',
53
+ hint: 'set IMHUB_SMTP_HOST / IMHUB_SMTP_USER / IMHUB_SMTP_PASS to enable',
54
+ }, 'Email adapter disabled — SMTP env vars not set');
55
+ this.started = true;
56
+ return;
57
+ }
58
+ this.transporter = nodemailer.createTransport({
59
+ host: this.config.host,
60
+ port: this.config.port,
61
+ secure: this.config.secure,
62
+ auth: { user: this.config.user, pass: this.config.pass },
63
+ });
64
+ // Verify connection eagerly so misconfig surfaces at startup instead of
65
+ // at first send. Failure is logged but doesn't block startup — same
66
+ // fail-soft contract as the wechat credentials check.
67
+ try {
68
+ await this.transporter.verify();
69
+ log.info({
70
+ event: 'email.ready',
71
+ host: this.config.host,
72
+ port: this.config.port,
73
+ secure: this.config.secure,
74
+ from: this.config.from,
75
+ }, 'Email adapter ready');
76
+ }
77
+ catch (err) {
78
+ log.warn({
79
+ event: 'email.verify_failed',
80
+ err: err instanceof Error ? err.message : String(err),
81
+ }, 'SMTP verify failed — sends will likely fail until config is fixed');
82
+ }
83
+ this.started = true;
84
+ }
85
+ async stop() {
86
+ if (this.transporter) {
87
+ this.transporter.close();
88
+ this.transporter = null;
89
+ }
90
+ this.started = false;
91
+ }
92
+ // onMessage is required by the MessengerAdapter interface, but email is a
93
+ // push-only channel — we never poll an inbox, so the handler is intentionally
94
+ // discarded. The signature is preserved for interface conformance.
95
+ onMessage(_handler) {
96
+ // no-op
97
+ }
98
+ /**
99
+ * Send the message body to the email address in `threadId`. Subject is
100
+ * derived from the first line (capped at 100 chars). When SMTP isn't
101
+ * configured we throw a clear "not configured" error so the reminder
102
+ * engine writes it as the failure reason.
103
+ */
104
+ async sendMessage(threadId, text) {
105
+ if (!this.started)
106
+ throw new Error('email adapter not started');
107
+ if (!this.transporter || !this.config) {
108
+ throw new Error('Email adapter not configured (set IMHUB_SMTP_HOST / USER / PASS)');
109
+ }
110
+ const to = threadId.trim();
111
+ if (!EMAIL_RE.test(to)) {
112
+ throw new Error(`Invalid email address: "${to}"`);
113
+ }
114
+ // Subject = first non-empty line, stripped of bot icon prefixes, capped.
115
+ const firstLine = text.split('\n').map((s) => s.trim()).find((s) => s.length > 0) || 'im-hub 通知';
116
+ const subject = firstLine.replace(/^(?:🔔|🔁|⏰)\s*/u, '').slice(0, 100);
117
+ await this.transporter.sendMail({
118
+ from: this.config.from,
119
+ to,
120
+ subject,
121
+ text,
122
+ });
123
+ log.info({ event: 'email.sent', to, subjectLen: subject.length, bodyLen: text.length }, 'email delivered');
124
+ }
125
+ /** Test/inspection hook — used by unit tests to verify env reading. */
126
+ getEffectiveConfig() {
127
+ return this.config;
128
+ }
129
+ /** Test hook — inject a mocked transporter to bypass SMTP. */
130
+ _setTransporterForTest(t, cfg) {
131
+ this.transporter = t;
132
+ this.config = cfg;
133
+ this.started = true;
134
+ }
135
+ }
136
+ export const emailAdapter = new EmailAdapter();
137
+ //# sourceMappingURL=email-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-adapter.js","sourceRoot":"","sources":["../../../../src/plugins/messengers/email/email-adapter.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,EAAE;AACF,uEAAuE;AACvE,2EAA2E;AAC3E,0DAA0D;AAC1D,EAAE;AACF,2CAA2C;AAC3C,iDAAiD;AACjD,iEAAiE;AACjE,mDAAmD;AACnD,kEAAkE;AAClE,6DAA6D;AAC7D,yEAAyE;AACzE,6EAA6E;AAC7E,EAAE;AACF,4EAA4E;AAC5E,2EAA2E;AAC3E,4DAA4D;AAE5D,OAAO,UAAgC,MAAM,YAAY,CAAA;AAEzD,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,yBAAyB,CAAA;AAE9D,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAA;AAWpD,SAAS,cAAc;IACrB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,CAAA;IAChD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,CAAA;IAChD,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAA;IACxC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAA;IACxC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,CAAA;IACnD,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;IACzD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;QACxD,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,8CAA8C,CAAC,CAAA;IACvE,CAAC;IACD,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAA;IACjF,iEAAiE;IACjE,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IACrE,MAAM,MAAM,GAAG,SAAS,KAAK,SAAS;QACpC,CAAC,CAAC,CAAC,SAAS,KAAK,GAAG,IAAI,SAAS,KAAK,MAAM,IAAI,SAAS,KAAK,KAAK,CAAC;QACpE,CAAC,CAAC,SAAS,KAAK,GAAG,CAAA;IACrB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,IAAI,IAAI,CAAA;IACxD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;AAC5D,CAAC;AAED,MAAM,QAAQ,GAAG,4BAA4B,CAAA;AAE7C,MAAM,OAAO,YAAY;IACd,IAAI,GAAG,OAAO,CAAA;IACf,WAAW,GAAuB,IAAI,CAAA;IACtC,MAAM,GAAsB,IAAI,CAAA;IAChC,OAAO,GAAG,KAAK,CAAA;IAEvB,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,MAAM,GAAG,cAAc,EAAE,CAAA;QAC9B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,GAAG,CAAC,IAAI,CAAC;gBACP,KAAK,EAAE,gBAAgB;gBACvB,IAAI,EAAE,mEAAmE;aAC1E,EAAE,gDAAgD,CAAC,CAAA;YACpD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;YACnB,OAAM;QACR,CAAC;QAED,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC,eAAe,CAAC;YAC5C,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;YACtB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;YACtB,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM;YAC1B,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;SACzD,CAAC,CAAA;QAEF,wEAAwE;QACxE,oEAAoE;QACpE,sDAAsD;QACtD,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAA;YAC/B,GAAG,CAAC,IAAI,CAAC;gBACP,KAAK,EAAE,aAAa;gBACpB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;gBACtB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;gBACtB,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM;gBAC1B,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;aACvB,EAAE,qBAAqB,CAAC,CAAA;QAC3B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,IAAI,CAAC;gBACP,KAAK,EAAE,qBAAqB;gBAC5B,GAAG,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACtD,EAAE,mEAAmE,CAAC,CAAA;QACzE,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;IACrB,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAA;YACxB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAA;QACzB,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;IACtB,CAAC;IAED,0EAA0E;IAC1E,8EAA8E;IAC9E,mEAAmE;IACnE,SAAS,CAAC,QAAgD;QACxD,QAAQ;IACV,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,WAAW,CAAC,QAAgB,EAAE,IAAY;QAC9C,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAA;QAC/D,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAA;QACrF,CAAC;QACD,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAA;QAC1B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,2BAA2B,EAAE,GAAG,CAAC,CAAA;QACnD,CAAC;QAED,yEAAyE;QACzE,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,WAAW,CAAA;QAChG,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;QAEvE,MAAM,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC;YAC9B,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;YACtB,EAAE;YACF,OAAO;YACP,IAAI;SACL,CAAC,CAAA;QACF,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,EACpF,iBAAiB,CAAC,CAAA;IACtB,CAAC;IAED,uEAAuE;IACvE,kBAAkB;QAChB,OAAO,IAAI,CAAC,MAAM,CAAA;IACpB,CAAC;IAED,8DAA8D;IAC9D,sBAAsB,CAAC,CAAc,EAAE,GAAe;QACpD,IAAI,CAAC,WAAW,GAAG,CAAC,CAAA;QACpB,IAAI,CAAC,MAAM,GAAG,GAAG,CAAA;QACjB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;IACrB,CAAC;CACF;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAA"}
@@ -0,0 +1,23 @@
1
+ import type { FeishuCard } from './types.js';
2
+ export declare class CardBuilder {
3
+ private header;
4
+ private elements;
5
+ withHeader(title: string, template?: string): this;
6
+ addMarkdown(content: string): this;
7
+ addDiv(text: string): this;
8
+ addCode(code: string, language?: string): this;
9
+ addDivider(): this;
10
+ addButtons(buttons: Array<{
11
+ text: string;
12
+ type: 'primary' | 'default' | 'danger';
13
+ value: Record<string, string>;
14
+ }>): this;
15
+ addAgentBadge(agent: string): this;
16
+ build(): FeishuCard;
17
+ }
18
+ /**
19
+ * Convert markdown text to Feishu-compatible format
20
+ * Feishu supports most standard markdown in the markdown element
21
+ */
22
+ export declare function markdownToFeishu(text: string): string;
23
+ //# sourceMappingURL=card-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"card-builder.d.ts","sourceRoot":"","sources":["../../../../src/plugins/messengers/feishu/card-builder.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAuC,MAAM,YAAY,CAAA;AAEjF,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,QAAQ,CAA0B;IAE1C,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IAQlD,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAQlC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAQ1B,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IAS9C,UAAU,IAAI,IAAI;IAKlB,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC;QACxB,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAA;QACtC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAC9B,CAAC,GAAG,IAAI;IAeT,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAmBlC,KAAK,IAAI,UAAU;CAUpB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIrD"}