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,409 @@
1
+ // DingTalk (钉钉) messenger adapter — implements MessengerAdapter
2
+ // against the official `dingtalk-stream` SDK in Stream mode.
3
+ //
4
+ // Stream mode characteristics that shaped this adapter:
5
+ // * No public webhook needed — DingTalk pushes events over WebSocket.
6
+ // The SDK handles reconnect/heartbeat/access-token rotation.
7
+ // * Inbound only fires when the user @-mentions the bot in a group,
8
+ // or sends a 1:1 message. DingTalk strips the @ prefix server-side.
9
+ // * Bot can only send back to (a) the user who messaged it (1:1) or
10
+ // (b) the group conversation the message came from. There is no
11
+ // concept of "DM any user without being messaged first" outside of
12
+ // proactive workflow messages, which we don't use.
13
+ // * threadId encoding: `user:<senderStaffId>` for 1:1, `group:<convId>`
14
+ // for groups. This lets sendMessage route to the right OpenAPI
15
+ // endpoint without consulting external state.
16
+ // * Inbound type is `text` only — DingTalk Stream doesn't deliver
17
+ // image / voice / location messages to bots. /memo coordinate flow
18
+ // therefore needs the user to type coords (no native location msg).
19
+ import { readFile } from 'node:fs/promises';
20
+ import { join } from 'node:path';
21
+ import { logger as rootLogger } from '../../../core/logger.js';
22
+ import { setLocationContext } from '../../../core/location-context.js';
23
+ import { normalizeIncomingCoords } from '../../../core/coord-systems.js';
24
+ import { detectProvider, transcribe, TranscribeError } from '../../../core/transcribe.js';
25
+ import { AGIM_HOME } from '../../../core/agim-paths.js';
26
+ import { DingTalkClient } from './dingtalk-client.js';
27
+ import { tryExtractLatLng } from './link-coords.js';
28
+ import { pickDingTalkExtension, saveDingTalkMedia } from './media-store.js';
29
+ const log = rootLogger.child({ component: 'dingtalk' });
30
+ const CONFIG_FILE = join(AGIM_HOME, 'config.json');
31
+ // Match Feishu's dedup window — DingTalk's gateway also re-delivers if
32
+ // the ack races the next reconnect.
33
+ const DEDUP_TTL_MS = 10 * 60 * 1000;
34
+ const DEDUP_MAX = 2000;
35
+ export class DingTalkAdapter {
36
+ name = 'dingtalk';
37
+ client = null;
38
+ config = null;
39
+ messageHandler;
40
+ seenMessages = new Map();
41
+ async start() {
42
+ try {
43
+ const raw = await readFile(CONFIG_FILE, 'utf-8');
44
+ const full = JSON.parse(raw);
45
+ this.config = full.dingtalk ?? null;
46
+ }
47
+ catch {
48
+ throw new Error('DingTalk config not found. Run `agim` → Configure → DingTalk first.');
49
+ }
50
+ if (!this.config?.clientId || !this.config?.clientSecret) {
51
+ throw new Error('DingTalk ClientID or ClientSecret missing. Re-run the configure flow.');
52
+ }
53
+ this.client = new DingTalkClient(this.config);
54
+ this.client.onMessage(async (msg) => { await this.handleInbound(msg); });
55
+ await this.client.start();
56
+ log.info('DingTalk adapter started (WebSocket Stream mode, no webhook needed)');
57
+ }
58
+ async stop() {
59
+ if (this.client) {
60
+ await this.client.stop();
61
+ this.client = null;
62
+ }
63
+ log.info('DingTalk adapter stopped');
64
+ }
65
+ onMessage(handler) {
66
+ this.messageHandler = handler;
67
+ }
68
+ async sendMessage(threadId, text) {
69
+ if (!this.client)
70
+ throw new Error('DingTalk adapter not started');
71
+ await this.client.sendMessage(threadId, text);
72
+ }
73
+ // No sendTyping / sendThinking — DingTalk doesn't expose a typing
74
+ // indicator API for stream-mode bots, and the client UI already shows
75
+ // a "正在输入" hint when a message is being processed in 1:1 chats.
76
+ // Group chats get nothing; the agent's first chunk is the user's signal.
77
+ // ─── inbound ─────────────────────────────────────────────────────────
78
+ /** Returns true on duplicate; otherwise records and prunes. Same shape
79
+ * as the Feishu adapter's dedup helper. */
80
+ isDuplicate(msgId) {
81
+ const now = Date.now();
82
+ const seenAt = this.seenMessages.get(msgId);
83
+ if (seenAt !== undefined && now - seenAt < DEDUP_TTL_MS)
84
+ return true;
85
+ this.seenMessages.set(msgId, now);
86
+ if (this.seenMessages.size > DEDUP_MAX) {
87
+ const cutoff = now - DEDUP_TTL_MS;
88
+ for (const [k, t] of this.seenMessages) {
89
+ if (t < cutoff)
90
+ this.seenMessages.delete(k);
91
+ if (this.seenMessages.size <= DEDUP_MAX * 0.8)
92
+ break;
93
+ }
94
+ while (this.seenMessages.size > DEDUP_MAX) {
95
+ const oldest = this.seenMessages.keys().next().value;
96
+ if (!oldest)
97
+ break;
98
+ this.seenMessages.delete(oldest);
99
+ }
100
+ }
101
+ return false;
102
+ }
103
+ /** Build the threadId we expose to the rest of im-hub. 1:1 routes by
104
+ * sender staffId; group chats route by openConversationId so any
105
+ * member triggers a shared session in that group. */
106
+ threadIdFor(msg) {
107
+ return msg.conversationType === '2'
108
+ ? `group:${msg.conversationId}`
109
+ : `user:${msg.senderStaffId}`;
110
+ }
111
+ async handleInbound(msg) {
112
+ if (!this.messageHandler) {
113
+ log.debug('no message handler registered');
114
+ return;
115
+ }
116
+ if (msg.msgId && this.isDuplicate(msg.msgId)) {
117
+ log.info({ messageId: msg.msgId, event: 'dingtalk.dedup.skip' }, 'dropping replayed msgId');
118
+ return;
119
+ }
120
+ const channelId = this.config?.channelId || 'default';
121
+ const threadId = this.threadIdFor(msg);
122
+ // ─── text / markdown — the happy path ────────────────────────────
123
+ // Markdown messages from DingTalk also carry `text.content`; treat
124
+ // them like plain text since the agent already speaks markdown.
125
+ if (msg.msgtype === 'text' || msg.msgtype === 'markdown') {
126
+ const text = msg.text?.content?.trim() ?? '';
127
+ if (!text) {
128
+ log.debug('empty text in dingtalk message — ignored');
129
+ return;
130
+ }
131
+ await this.dispatchText(msg, text, threadId, channelId);
132
+ return;
133
+ }
134
+ // ─── link — could be a shared location, a deep link, etc. ────────
135
+ // We log the full link block and try to recognise common GPS-bearing
136
+ // URL shapes (amap, qmap, baidu, dingtalk map mini-app). When we
137
+ // find lat/lng we feed location-context so cli.ts can annotate the
138
+ // user's next text turn — same architecture as Telegram / Feishu
139
+ // native location sharing.
140
+ if (msg.msgtype === 'link') {
141
+ log.info({
142
+ event: 'dingtalk.inbound.link',
143
+ messageId: msg.msgId,
144
+ link: msg.link,
145
+ threadId,
146
+ }, 'received link msgtype');
147
+ const coords = msg.link?.messageUrl ? tryExtractLatLng(msg.link.messageUrl) : null;
148
+ if (coords) {
149
+ // Apply the right coord-system conversion based on which map
150
+ // provider's URL we just parsed (amap/qq=GCJ-02, baidu=BD-09).
151
+ // See core/coord-systems.ts for the full per-source policy.
152
+ const norm = normalizeIncomingCoords(coords.source, coords.lat, coords.lng);
153
+ const threadKey = `dingtalk:${channelId}:${threadId}`;
154
+ setLocationContext(threadKey, {
155
+ lat: norm.lat,
156
+ lng: norm.lng,
157
+ venueLabel: msg.link?.title || undefined,
158
+ venueAddress: msg.link?.text || undefined,
159
+ });
160
+ log.info({
161
+ event: 'dingtalk.location_context.set',
162
+ source: coords.source,
163
+ raw_lat: coords.lat, raw_lng: coords.lng,
164
+ wgs_lat: norm.lat, wgs_lng: norm.lng,
165
+ applied: norm.applied,
166
+ });
167
+ if (this.client) {
168
+ await this.client.sendMessage(threadId, `📍 已收到位置${msg.link?.title ? `「${msg.link.title}」` : ''}。告诉我要做什么(例如 /memo 食堂、记下、提醒我下次来)。`)
169
+ .catch(err => log.warn({ err: err instanceof Error ? err.message : String(err) }, 'failed to ack dingtalk location'));
170
+ }
171
+ return;
172
+ }
173
+ // Not a recognised map URL — fall through to "tell user we can't"
174
+ // by sending a generic hint and stop here.
175
+ if (this.client) {
176
+ await this.client.sendMessage(threadId, '👁 链接已收到,但我只能阅读文本——请把要做的事情用文字告诉我。')
177
+ .catch(() => undefined);
178
+ }
179
+ return;
180
+ }
181
+ // ─── picture — download via messageFiles/download → save → enrich ──
182
+ // (msgtype is 'picture' on the wire — community docs say 'image' but
183
+ // empirically DingTalk delivers 'picture'.)
184
+ if (msg.msgtype === 'picture') {
185
+ await this.handleImageInbound(msg, threadId, channelId);
186
+ return;
187
+ }
188
+ // ─── audio — DingTalk includes server-side ASR ─────────────────────
189
+ // (msgtype is 'audio' on the wire — community docs say 'voice'.)
190
+ // Inbound `content.recognition` carries the transcript already; we
191
+ // prefer it over re-running whisper locally for two reasons:
192
+ // 1. accuracy: DingTalk's Mandarin ASR is generally better than the
193
+ // ggml-base whisper.cpp model on the same clip.
194
+ // 2. latency: zero round-trip vs. 5-30 s on CPU.
195
+ // We still pull the audio file when we have a downloadCode so the
196
+ // agent can replay / archive the source recording.
197
+ if (msg.msgtype === 'audio') {
198
+ await this.handleVoiceInbound(msg, threadId, channelId);
199
+ return;
200
+ }
201
+ // ─── file — out of scope for now; ack only ───────────────────────
202
+ // Files can be PDFs / Word / spreadsheets etc. — multimodal agent
203
+ // handling is a separate effort. Acknowledge so user knows we saw it.
204
+ if (msg.msgtype === 'file') {
205
+ log.info({
206
+ event: 'dingtalk.inbound.file',
207
+ messageId: msg.msgId,
208
+ msgtype: msg.msgtype,
209
+ threadId,
210
+ content: msg.content,
211
+ }, 'received file msgtype — currently no handler');
212
+ if (this.client) {
213
+ await this.client.sendMessage(threadId, '📎 文件收到了,但我暂时还不能解析文件内容——请打字告诉我或上传图片。')
214
+ .catch(() => undefined);
215
+ }
216
+ return;
217
+ }
218
+ // ─── unknown msgtype — dump full payload for diagnosis ──────────
219
+ // This is the fallback for things like "user shared a native
220
+ // location" (msgtype undocumented). The dump lets us inspect the
221
+ // real shape in journalctl and teach the adapter next iteration.
222
+ log.warn({
223
+ event: 'dingtalk.inbound.unknown_msgtype',
224
+ messageId: msg.msgId,
225
+ msgtype: msg.msgtype,
226
+ threadId,
227
+ fullPayload: msg,
228
+ }, 'unknown dingtalk msgtype — full payload logged for analysis');
229
+ if (this.client) {
230
+ await this.client.sendMessage(threadId, `❓ 收到一条 \`${msg.msgtype}\` 类型消息,我还不认得这种格式,已记录到日志便于调试。请打字告诉我要做什么。`)
231
+ .catch(() => undefined);
232
+ }
233
+ }
234
+ /** Image inbound: exchange downloadCode → CDN bytes → save under
235
+ * ~/.im-hub/media/dingtalk/<thread>/, then dispatch a Message whose
236
+ * text contains an `[图片附件:<path>]` marker. claude-code's Read
237
+ * tool already understands that marker — it'll fetch the file off
238
+ * disk and pass it to the multimodal model the user is talking to.
239
+ *
240
+ * On download failure we still dispatch (with a `[图片附件下载失败]`
241
+ * marker) so the user's interaction isn't silently dropped. */
242
+ async handleImageInbound(msg, threadId, channelId) {
243
+ // DingTalk picture inbound carries TWO codes. Empirically only the
244
+ // generic `downloadCode` is accepted by /v1.0/robot/messageFiles/download
245
+ // — `pictureDownloadCode` returns 500 "unknownError" (it's reserved for
246
+ // a different endpoint we don't use). Picture's `downloadCode` resolves
247
+ // to a high-resolution version, not a thumbnail, despite the field
248
+ // name overlap with what the wire format calls a "thumb code". Confirmed
249
+ // 2026-05-11 via real msg dumps.
250
+ const downloadCode = msg.content?.downloadCode ?? msg.content?.pictureDownloadCode;
251
+ if (!downloadCode) {
252
+ log.warn({ event: 'dingtalk.image.no_download_code', messageId: msg.msgId, content: msg.content }, 'image msg arrived without downloadCode — falling back to ack hint');
253
+ if (this.client) {
254
+ await this.client.sendMessage(threadId, '🖼 图片收到了但我没拿到下载凭据,没法看。请重发或打字描述。')
255
+ .catch(() => undefined);
256
+ }
257
+ return;
258
+ }
259
+ const subPath = this.subPathFor(msg);
260
+ let attachmentLine;
261
+ try {
262
+ if (!this.client)
263
+ throw new Error('client not ready');
264
+ const dl = await this.client.downloadMessageFile(downloadCode);
265
+ if (!dl)
266
+ throw new Error('messageFiles/download returned null');
267
+ const ext = pickDingTalkExtension(dl.contentType, undefined);
268
+ const path = await saveDingTalkMedia(dl.buffer, subPath, `${this.safeFilenameStem(msg.msgId)}.${ext}`);
269
+ attachmentLine = `[图片附件:${path}]`;
270
+ log.info({ event: 'dingtalk.image.saved', path, bytes: dl.buffer.length }, 'dingtalk image saved');
271
+ }
272
+ catch (err) {
273
+ const reason = err instanceof Error ? err.message : String(err);
274
+ log.warn({ event: 'dingtalk.image.download_failed', err: reason, messageId: msg.msgId }, 'image download/save failed');
275
+ attachmentLine = `[图片附件下载失败:${reason}]`;
276
+ }
277
+ await this.dispatchText(msg, attachmentLine, threadId, channelId);
278
+ }
279
+ /** Voice inbound: download AMR (or whatever the CDN serves) → transcribe
280
+ * via the shared whisper provider → dispatch the transcript as the
281
+ * user's text. The saved source file path is appended so the agent can
282
+ * reference it (replay, archive, etc.) — same shape as the Telegram
283
+ * voice path so claude-code's prompts work uniformly.
284
+ *
285
+ * Surfaces failures inline so the user gets feedback:
286
+ * - no downloadCode → `[语音附件无下载凭据]`
287
+ * - download failed → `[语音附件下载失败:…]`
288
+ * - no provider set → `[语音附件未转写(未配置 OPENAI_API_KEY 或 IMHUB_WHISPERCPP_BIN):path]`
289
+ * - transcribe threw → `[语音转写失败(provider: reason)\n源文件:path]` */
290
+ async handleVoiceInbound(msg, threadId, channelId) {
291
+ const recognition = (msg.content?.recognition ?? '').trim();
292
+ const downloadCode = msg.content?.downloadCode;
293
+ const durationRaw = msg.content?.duration;
294
+ const durationSec = typeof durationRaw === 'number'
295
+ ? durationRaw
296
+ : typeof durationRaw === 'string' && durationRaw
297
+ ? parseInt(durationRaw, 10)
298
+ : undefined;
299
+ // Try to grab the source audio file so the agent can reference /
300
+ // replay it. Best-effort: a missing or failed download doesn't
301
+ // block the conversation when DingTalk's server-side ASR already
302
+ // gave us the transcript text.
303
+ let savedPath = null;
304
+ let downloadErr = null;
305
+ if (downloadCode) {
306
+ try {
307
+ if (!this.client)
308
+ throw new Error('client not ready');
309
+ const dl = await this.client.downloadMessageFile(downloadCode);
310
+ if (!dl)
311
+ throw new Error('messageFiles/download returned null');
312
+ const ext = pickDingTalkExtension(dl.contentType, undefined);
313
+ savedPath = await saveDingTalkMedia(dl.buffer, this.subPathFor(msg), `${this.safeFilenameStem(msg.msgId)}.${ext}`);
314
+ log.info({ event: 'dingtalk.voice.saved', path: savedPath, bytes: dl.buffer.length }, 'dingtalk voice saved');
315
+ }
316
+ catch (err) {
317
+ downloadErr = err instanceof Error ? err.message : String(err);
318
+ log.warn({ event: 'dingtalk.voice.download_failed', err: downloadErr, messageId: msg.msgId }, 'voice download/save failed (transcript may still be available via DingTalk ASR)');
319
+ }
320
+ }
321
+ // Resolve a transcript. Priority order:
322
+ // 1. DingTalk server-side ASR (msg.content.recognition) — accurate
323
+ // for Mandarin, zero latency on our side.
324
+ // 2. Local whisper.cpp / OpenAI Whisper on the downloaded audio,
325
+ // if the platform ASR is missing AND we have the source file.
326
+ // 3. Failure markers so the agent + user both see something.
327
+ let voiceLine;
328
+ if (recognition) {
329
+ const dur = durationSec != null ? `${durationSec}s, ` : '';
330
+ const sourceTail = savedPath ? `\n源文件:${savedPath}]`
331
+ : downloadErr ? `\n源文件下载失败:${downloadErr}]`
332
+ : ']';
333
+ voiceLine = `[语音转写(${dur}provider=dingtalk-asr):\n${recognition}${sourceTail}`;
334
+ }
335
+ else if (!savedPath) {
336
+ voiceLine = `[语音附件下载失败:${downloadErr ?? '钉钉未提供 downloadCode'}]`;
337
+ }
338
+ else if (detectProvider() === 'none') {
339
+ voiceLine = `[语音附件未转写(钉钉未返回 recognition,且本地未配置 OPENAI_API_KEY 或 IMHUB_WHISPERCPP_BIN):${savedPath}]`;
340
+ }
341
+ else {
342
+ try {
343
+ const result = await transcribe(savedPath, { language: 'zh' });
344
+ const dur = durationSec != null ? `${durationSec}s, ` : '';
345
+ voiceLine = [
346
+ `[语音转写(${dur}provider=${result.provider}, ${result.elapsedMs}ms):`,
347
+ result.text || '(空)',
348
+ `源文件:${savedPath}]`,
349
+ ].join('\n');
350
+ }
351
+ catch (err) {
352
+ const reason = err instanceof TranscribeError
353
+ ? `${err.provider}: ${err.reason}`
354
+ : err instanceof Error ? err.message : String(err);
355
+ voiceLine = `[语音转写失败(${reason})\n源文件:${savedPath}]`;
356
+ }
357
+ }
358
+ await this.dispatchText(msg, voiceLine, threadId, channelId);
359
+ }
360
+ /** Build a filesystem-safe sub-path under MEDIA_ROOT/dingtalk/.
361
+ * Uses senderStaffId for 1:1 and openConversationId for groups; both
362
+ * are alphanumeric+`=` from DingTalk so we sanitise the `=` (and any
363
+ * other path-unsafe chars) to `_` to avoid surprises on Windows ports
364
+ * or shell quoting. */
365
+ subPathFor(msg) {
366
+ const raw = msg.conversationType === '2' ? msg.conversationId : msg.senderStaffId;
367
+ return (raw || 'unknown').replace(/[^A-Za-z0-9_-]/g, '_');
368
+ }
369
+ /** DingTalk msgIds are base64-shaped (`msgABC/DEF+xyz==`) and contain
370
+ * `/` + `+` + `=` — all reserved for path or shell quoting. Replace
371
+ * every non-[A-Za-z0-9_-] char with `_` so the resulting filename
372
+ * passes saveDingTalkMedia's safety check and is portable. */
373
+ safeFilenameStem(msgId) {
374
+ return (msgId || 'unknown').replace(/[^A-Za-z0-9_-]/g, '_');
375
+ }
376
+ /** Shared text-dispatch path used by text / markdown msgtypes. */
377
+ async dispatchText(msg, text, threadId, channelId) {
378
+ const out = {
379
+ id: msg.msgId,
380
+ threadId,
381
+ userId: msg.senderStaffId || 'unknown',
382
+ text,
383
+ timestamp: msg.createAt ? new Date(msg.createAt) : new Date(),
384
+ channelId,
385
+ };
386
+ const ctx = {
387
+ message: out,
388
+ platform: 'dingtalk',
389
+ channelId,
390
+ };
391
+ try {
392
+ await this.messageHandler(ctx);
393
+ }
394
+ catch (err) {
395
+ log.error({
396
+ err: err instanceof Error ? err.message : String(err),
397
+ stack: err instanceof Error ? err.stack : undefined,
398
+ }, 'error in dingtalk message handler');
399
+ }
400
+ }
401
+ }
402
+ // tryExtractLatLng + MapUrlSource live in ./link-coords.ts so tests for
403
+ // the URL classifier can import them without pulling in this adapter's
404
+ // heavy side-effecting transitive deps (media-store, dingtalk-stream,
405
+ // transcribe, …). Re-exported here for any external callers that import
406
+ // from the adapter module.
407
+ export { tryExtractLatLng } from './link-coords.js';
408
+ export const dingtalkAdapter = new DingTalkAdapter();
409
+ //# sourceMappingURL=dingtalk-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dingtalk-adapter.js","sourceRoot":"","sources":["../../../../src/plugins/messengers/dingtalk/dingtalk-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import type { DingTalkConfig, DingTalkInboundMessage } from './types.js';
2
+ type MessageHandler = (msg: DingTalkInboundMessage) => Promise<void>;
3
+ export declare class DingTalkClient {
4
+ private dw;
5
+ private config;
6
+ private messageHandler?;
7
+ /** Cached robotCode from the most recent inbound (== clientId for
8
+ * stream-mode internal apps, but we read it from messages so we're
9
+ * tolerant of multi-bot setups in one app). */
10
+ private lastSeenRobotCode;
11
+ constructor(config: DingTalkConfig);
12
+ onMessage(handler: MessageHandler): void;
13
+ start(): Promise<void>;
14
+ stop(): Promise<void>;
15
+ /** Send a plain-text message to a thread we previously received from
16
+ * (encoded as `user:<staffId>` for 1:1, `group:<convId>` for groups).
17
+ * Uses OpenAPI under the bot's access token. */
18
+ sendMessage(threadId: string, text: string): Promise<void>;
19
+ /** Send a markdown-formatted message. DingTalk's `sampleMarkdown` only
20
+ * takes `title` + `text`; we derive title from the first line so the
21
+ * user sees something meaningful in the notification preview. */
22
+ sendMarkdown(threadId: string, text: string, title?: string): Promise<void>;
23
+ /** Download an inbound image / voice / file message's binary payload.
24
+ *
25
+ * DingTalk hands the bot a short-lived `downloadCode` in each media
26
+ * inbound; we trade it (plus our robotCode) for a presigned downloadUrl
27
+ * on alibaba CDN, then GET that URL and return the bytes.
28
+ *
29
+ * Returns null on any error (caller surfaces a "[download failed:...]"
30
+ * marker instead of silently dropping the user's message). MAX cap is
31
+ * enforced; oversize payloads throw before allocating the buffer.
32
+ *
33
+ * Reference: POST /v1.0/robot/messageFiles/download
34
+ * { downloadCode, robotCode }
35
+ * header: x-acs-dingtalk-access-token
36
+ * response: { downloadUrl } (sometimes nested under .data)
37
+ */
38
+ downloadMessageFile(downloadCode: string): Promise<{
39
+ buffer: Buffer;
40
+ contentType: string;
41
+ } | null>;
42
+ /** Shared POST path. msgKey + msgParam (stringified inner object) is
43
+ * DingTalk's "templated message" convention — covers text, markdown,
44
+ * cards via the same endpoint. */
45
+ private sendTemplated;
46
+ }
47
+ export {};
48
+ //# sourceMappingURL=dingtalk-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dingtalk-client.d.ts","sourceRoot":"","sources":["../../../../src/plugins/messengers/dingtalk/dingtalk-client.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAcxE,KAAK,cAAc,GAAG,CAAC,GAAG,EAAE,sBAAsB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAoBpE,qBAAa,cAAc;IACzB,OAAO,CAAC,EAAE,CAAU;IACpB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,cAAc,CAAC,CAAgB;IACvC;;oDAEgD;IAChD,OAAO,CAAC,iBAAiB,CAAQ;gBAErB,MAAM,EAAE,cAAc;IAYlC,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAIlC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA8BtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAO3B;;qDAEiD;IAC3C,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhE;;sEAEkE;IAC5D,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQjF;;;;;;;;;;;;;;OAcG;IACG,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CACtD;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAC/C;IA6ED;;uCAEmC;YACrB,aAAa;CAyC5B"}