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,414 @@
1
+ # Agim · 阿吉姆
2
+
3
+ [English](README.md)
4
+
5
+ **IM 到 AI Agent 的万能桥梁** — 将微信 / 飞书 / 钉钉 / Telegram / Discord 接入 Claude Code / Codex / Copilot / OpenCode,或通过 ACP 接入任意自定义 Agent。单 Node.js 进程,无需 Docker / Redis。
6
+
7
+ > **品牌**:英文名 **Agim**(取自 Agent + IM,也有 agile 敏捷的感觉),中文名 **阿吉姆**。
8
+ > npm 包名 **`agim-cli`**(短名 `agim` 被 npm 反 typo-squat 保留),装完后**命令**还是 **`agim`**,
9
+ > 日常打的就是这个。老命令 `im-hub-pro` 也保留为别名,老的 systemd 单元和 shell 别名不会断。
10
+ > 配置目录新装默认 **`~/.agim/`**,已有 **`~/.im-hub/`** 的老用户会被自动识别继续沿用。
11
+ > 环境变量(`IMHUB_*`)、HTTP 头(`X-IM-Hub-Token`)、systemd 单元 `im-hub.service` 都保留
12
+ > 原名以兼容 0.x 部署——详见 [迁移](#迁移)。
13
+
14
+ ## 亮点
15
+
16
+ - **5 种 IM + 邮件,4+ 种 Agent** — 微信(图片 / 文件 / 语音)、飞书、钉钉(图片 / 语音,自带服务端 ASR)、Telegram、Discord、Email(SMTP);Claude Code、Codex、Copilot、OpenCode,以及任意 ACP 端点
17
+ - **`/remind` 提醒子系统** — 一次性 + 定期(`每天8点喝水`);非 slash 消息 LLM 自动识别意图;LLM 润色投递文本;Agent MCP 工具直接创建;Web `/reminders` 管理页;邮件 + IM 双通道投递
18
+ - **`/memo` 5W1H 持久记忆库** — 通用「what / who / when / where / how / why」记事本,可选 GPS(浏览器地理定位 H5 + 百度地理编码);默认永久保存,临时类(停车、当天会议)单独走 24h 桶;Agent 通过 MCP 工具自动落库 + 检索,闲聊里提到的地点 / 生日 / 待办都能记下
19
+ - **浏览器控制台** — 对话界面、任务面板(Jobs / 调度 / 审批 / 健康 / 文件 / 审计)、提醒面板、设置页含工作区 CRUD
20
+ - **工具调用人审(HITL)** — Claude 调用工具时暂停,IM 回复 `y`/`n` 或在页面点卡片审批;全平台一致
21
+ - **微信 / Telegram / 钉钉 富媒体** — 接收图片、文件、视频;语音消息按平台走最佳转写链路:微信 STT、钉钉服务端 ASR、OpenAI Whisper、whisper.cpp
22
+ - **智能路由** — 意图分类(中英文)、Sticky 会话、断路器、限流器
23
+ - **多租户工作区** — 按工作区隔离 Agent 白名单、限流、命令级 ACL
24
+ - **持久化任务与定时** — SQLite 落地,重启不丢,30 天自动修剪
25
+ - **可观测** — 结构化日志(pino + traceId)、Prometheus 指标、审计日志
26
+ - **安全** — 常量时鉴权、SSRF 防护、凭证文件权限、审批 socket 熵值
27
+
28
+ 完整版本历史见 [CHANGELOG.md](CHANGELOG.md)。
29
+
30
+ ## 快速开始
31
+
32
+ ```bash
33
+ npm install -g agim-cli # 需要 Node.js ≥ 18(推荐 ≥ 22 LTS)
34
+
35
+ # 配置至少一个 IM
36
+ agim # 交互式向导(推荐)—— 双语,方向键选语言后逐项配置
37
+ # 也可以走老的子命令:
38
+ agim config wechat # 扫码登录
39
+ agim config feishu # 飞书 App ID + Secret,无需 webhook
40
+ agim config dingtalk # 钉钉 ClientID + ClientSecret(Stream 模式机器人)
41
+ agim config telegram # @BotFather 拿 Token
42
+ agim config discord # Bot Token,详见 docs/discord-setup.md
43
+
44
+ # (可选)通过 ACP 接入远端自定义 Agent
45
+ agim config agent
46
+
47
+ # 启动
48
+ agim start
49
+ ```
50
+
51
+ 浏览器访问 `http://localhost:3000` — 对话 `/`、任务 `/tasks`、设置 `/settings`。
52
+
53
+ ### 迁移
54
+
55
+ #### 从原 `im-hub` 迁移
56
+ ```bash
57
+ npm uninstall -g im-hub
58
+ npm install -g agim-cli
59
+ agim start # 配置、环境变量、Header 全部不变
60
+ ```
61
+
62
+ #### 从 `im-hub-pro`(0.x → 1.0)迁移
63
+ ```bash
64
+ npm uninstall -g im-hub-pro
65
+ npm install -g agim-cli
66
+ agim start # 配置目录、环境变量、Header 全部不变
67
+ ```
68
+
69
+ npm 包名是 `agim-cli`(短名 `agim` 被 npm 反 typo-squat 保留了);安装后**命令**还是 `agim`,
70
+ 日常打命令就是 `agim …`。`im-hub-pro` 命令也保留为别名,原有的 systemd 单元和别名脚本不用动。
71
+
72
+ ## 功能一览
73
+
74
+ | 分类 | 内容 |
75
+ |------|------|
76
+ | **IM 通道** | 微信(iLink — 图片 / 文件 / 语音 / 视频)、飞书(WebSocket)、钉钉(Stream 模式 — 图片 / 语音,自带服务端 ASR)、Telegram(grammy — 图片 / 语音 / 音频)、Discord(discord.js)、Email(SMTP,仅推送) |
77
+ | **Agent** | Claude Code、Codex、Copilot、OpenCode(统一 `AgentBase`);任何 HTTP Agent 通过 ACP 接入 |
78
+ | **提醒** | `/remind` slash、LLM 意图识别、LLM 润色投递、Agent MCP 工具(claude-code + opencode)、Web `/reminders` 页面 |
79
+ | **Web 控制台** | 流式对话、三态主题(浅 / 深 / 跟随系统)、中英双语、SSE 实时仪表盘 |
80
+ | **工具人审** | IM 端 + 页面内审批卡;Claude MCP sidecar |
81
+ | **任务** | SQLite 持久化 Job Board + cron 调度;批量操作;后台任务读取 |
82
+ | **路由** | 意图分类、断路器、限流、Sticky 会话、LLM 兜底 |
83
+ | **工作区** | 多租户;Agent 白名单 + 限流;命令级 ACL |
84
+ | **可观测** | pino 结构化日志、traceId、Prometheus `/api/metrics`、SQLite 审计 |
85
+ | **ACP** | 客户端(连接远端 Agent)+ 服务端(阿吉姆自身作为 ACP Agent) |
86
+
87
+ ## CLI 命令
88
+
89
+ ```
90
+ agim # 交互式向导(双语,推荐入口)
91
+ agim start # 启动桥接 + Web 界面(前台)
92
+ agim start --bg # 后台守护进程模式
93
+ agim status # 查看服务状态(systemd / bg / fg)
94
+ agim restart # 重启正在运行的服务
95
+ agim stop # 停止服务
96
+ agim uninstall # 卸载(保留 ~/.im-hub-workspaces/)
97
+ agim config wechat # 配置微信
98
+ agim config feishu # 配置飞书
99
+ agim config dingtalk # 配置钉钉(Stream 模式企业内部应用)
100
+ agim config telegram # 配置 Telegram
101
+ agim config discord # 配置 Discord
102
+ agim config claude # 配置 Claude Code
103
+ agim config agent # 接入自定义 ACP Agent
104
+ agim agents # 列出可用 Agent
105
+ agim messengers # 列出可用 IM
106
+ # (`im-hub-pro …` 作为别名继续可用)
107
+ ```
108
+
109
+ ## 聊天命令
110
+
111
+ | 命令 | 含义 |
112
+ |------|------|
113
+ | 任意文本 | 路由到 Agent(Sticky 会话 + 意图分类) |
114
+ | `/<agent> <内容>` | 切换 Agent — `/cc`、`/oc`、`/cx`、`/co` |
115
+ | `/new` | 开新会话(清空历史) |
116
+ | `/model [provider/model]` | 查看或切换模型 |
117
+ | `/think on\|off` | 切换深度思考模式 |
118
+ | `/remind …` | 提醒子系统 — 详见 [提醒](#提醒) |
119
+ | `/memo …` | 5W1H 持久记忆库 — 详见 [备忘](#备忘)(别名 `/记`、`/note`)|
120
+ | `/job`、`/cron`、`/audit`、`/stats` | 管理任务、定时、审计、统计(`/schedule` 仍是 `/cron` 别名,v0.4.0 移除) |
121
+ | `/router status\|explain` | 查看路由策略 |
122
+ | `y` / `n` / `批准` / `拒绝` | 同意 / 拒绝(工具调用 或 提醒确认卡片) |
123
+
124
+ ## 工具调用人审
125
+
126
+ 当 Claude 尝试调用工具时,阿吉姆会暂停并发送审批卡:
127
+
128
+ ```
129
+ 🔐 工具调用审批请求
130
+ 工具:Bash
131
+ 入参:{"command":"rm -rf node_modules"}
132
+ 回复 y 批准 / n 拒绝(5 分钟内未操作将自动拒绝)
133
+ ```
134
+
135
+ 在 IM 回复 `y` / `n`,或在 Web 界面点 Allow / Deny。微信、Telegram、飞书、钉钉、Discord 行为一致。`IMHUB_APPROVAL_DISABLED=1` 可关闭。
136
+
137
+ ## 提醒
138
+
139
+ 内置 `/remind` 子系统——一次性 / 定期,三种创建路径,三种投递增强。
140
+
141
+ ```bash
142
+ # 一次性
143
+ /remind 2m 喝水
144
+ /remind 40秒喝水
145
+ /remind 下午6点下班
146
+ /remind 18:30 出门
147
+
148
+ # 定期 🔁
149
+ /remind 每5分钟看屏幕外
150
+ /remind 每天早上8点喝水
151
+ /remind 每周一三五9点站会
152
+ /remind 每个工作日18:00下班
153
+
154
+ # 邮件 ✉️ (需要 SMTP 配置——见 [配置](#配置))
155
+ /remind email me@x.com 8:00 早安
156
+ /remind bindemail me@x.com # 绑定默认邮箱 → /remind email 每天8点 早安
157
+ /remind unbindemail
158
+
159
+ # 管理
160
+ /remind list
161
+ /remind cancel <id>
162
+ /remind clear
163
+ /remind snooze <id> 5m
164
+ /remind aiwatch on|off # 切换 LLM 意图识别
165
+
166
+ # 关掉某条提醒的 LLM 润色
167
+ /remind literal 每5分钟 喝水
168
+ ```
169
+
170
+ **三种创建路径**(最终都落到同一个 `~/.im-hub/reminders.db`):
171
+
172
+ 1. **`/remind` slash** — 显式、结构化输入
173
+ 2. **LLM 意图识别**(默认开启)— 直接说"明天早上8点提醒我开会",机器人弹"要不要为这件事设个提醒?"卡片,回复 `y` 创建
174
+ 3. **Agent MCP 工具** — 在 claude-code / opencode (stdio) 会话里聊到未来事件时,agent 自动调 `create_reminder`。opencode (http) 走单用户 agent-asserted context 路径
175
+
176
+ **两种投递增强**:
177
+
178
+ - **LLM 润色**(默认开启):触发时由当前 agent 把字面文本重写成自然提醒("早上好,记得喝杯水")。系统约束:**不献媚、不过度幽默、不夸大**。Agent 失败 / 超时时回退字面文本
179
+ - **延迟投递标记**:超过 1 小时未投递的提醒前缀加 `⏰ 延迟投递`,让用户知道 bot 离线过
180
+
181
+ Web 界面 `/reminders` 可视化管理(状态筛选、延后、取消)。
182
+
183
+ 完整设计:[`docs/architecture/reminders.md`](docs/architecture/reminders.md)。
184
+
185
+ ## 备忘
186
+
187
+ `/memo` 是一个 5W1H 持久记忆库。每条 memo 都可以挂上 `what` / `who` / `when_at` / `where (lat/lng/label)` / `how` / `why` 任意子集,外加可选的 `expires_at` 生命周期。位置只是其中一个轴 —— 同一个工具也能记「我爸生日 5月8日」「苹果发了 AVP2」。
188
+
189
+ ```bash
190
+ # Slash
191
+ /memo # 搜索提示 + 最近的 memo
192
+ /memo list # 最近 10 条
193
+ /memo show <id>
194
+ /memo delete <id>
195
+ /memo search 茶馆
196
+ /memo here [备注] # 一次性 HTTPS 链接 → 浏览器抓 GPS
197
+ /memo 39.9,116.4 家 # 直接给坐标 + label
198
+
199
+ # 别名:/记、/note
200
+ ```
201
+
202
+ Agent(claude-code / opencode)能看到 5 个 MCP 工具,遇到值得记的内容**自动调用**——不用打 slash:
203
+
204
+ - `save_memo` —— 从自然语言里抽 5W1H 落库;`address` 参数走百度地理编码补全坐标
205
+ - `request_location_capture` —— 返回一次性 H5 链接让用户在 IM 内置浏览器授权 GPS
206
+ - `search_memos` —— 多字段 AND-combined 检索("我的车在哪")
207
+ - `update_memo` —— patch 已有 memo(比如后补 `where_*`,或传 `address` 让后端 geocode)
208
+ - `delete_memo`
209
+
210
+ **生命周期分层**:默认所有 memo 永久;agent 判定为临时性内容("我把车停这了" / "今天下午3点开会")才 set `expires_in_hours`,后台每 5 分钟跑一次 sweep 删掉到期行。
211
+
212
+ **时区**:所有时间按 Asia/Shanghai (UTC+8) 解读,存为不带 `Z` / 偏移的 `YYYY-MM-DD HH:MM:SS`。其他时区部署设 `IMHUB_TZ_OFFSET_HOURS` 即可。
213
+
214
+ **浏览器 GPS 抓取**:`/memo here` 和 `request_location_capture` 都会发一个 10 分钟有效的一次性 HTTPS 链接,默认 base 是 `https://agent.iclaw.host`(公共托管入口)。自己有 HTTPS 域名的用户设 `IMHUB_LOC_BASE_URL=https://your-host` 让链接走自己的域。
215
+
216
+ **地址转坐标(可选)**:设 `IMHUB_BAIDU_MAP_AK` 一个百度地图 AK 之后,agent 在 `save_memo` / `update_memo` 里就能直接传 `address: "中关村大街27号"` 让后端 geocode 出坐标。不设的话该路径返回「geocoding not configured」,但**直接传坐标 + 浏览器抓 GPS 这两条路径都不受影响**。免费申请:[lbsyun.baidu.com](https://lbsyun.baidu.com/) → 控制台 → 应用管理 → 创建应用 → 服务端 API。默认无需 SN 签名;如启用 SN校验,详见 `src/core/locations.ts` 头注释。
217
+
218
+ ## 配置
219
+
220
+ ### 配置文件
221
+ `~/.im-hub/config.json`(启动时 zod 校验):
222
+
223
+ ```json
224
+ {
225
+ "messengers": ["wechat-ilink", "telegram"],
226
+ "agents": ["claude-code", "opencode"],
227
+ "defaultAgent": "claude-code",
228
+ "telegram": { "botToken": "***" },
229
+ "acpAgents": [
230
+ {
231
+ "name": "my-agent",
232
+ "endpoint": "https://api.example.com",
233
+ "auth": { "type": "bearer", "token": "***" }
234
+ }
235
+ ],
236
+ "workspaces": [
237
+ {
238
+ "id": "team-data",
239
+ "name": "数据团队",
240
+ "agents": ["opencode", "my-agent"],
241
+ "members": ["user-123"],
242
+ "rateLimit": { "rate": 30, "intervalSec": 60, "burst": 60 }
243
+ }
244
+ ]
245
+ }
246
+ ```
247
+
248
+ ### 邮件提醒(SMTP)
249
+
250
+ 要启用 `/remind email …`,启动前设置以下环境变量:
251
+
252
+ ```bash
253
+ # 必填
254
+ export IMHUB_SMTP_HOST=smtp.gmail.com
255
+ export IMHUB_SMTP_USER=you@gmail.com
256
+ export IMHUB_SMTP_PASS=<16位应用专用密码> # 不是登录密码
257
+
258
+ # 可选
259
+ export IMHUB_SMTP_PORT=465 # 默认 465
260
+ export IMHUB_SMTP_FROM=you@gmail.com # 默认 = USER
261
+ export IMHUB_SMTP_SECURE=auto # auto | true | false
262
+ ```
263
+
264
+ **常见邮箱配置参考**:
265
+
266
+ | 服务商 | HOST | PORT | 备注 |
267
+ |-------|------|------|------|
268
+ | Gmail | `smtp.gmail.com` | 465 | 用 [应用专用密码](https://myaccount.google.com/apppasswords),需先开两步验证 |
269
+ | QQ 邮箱 | `smtp.qq.com` | 465 | 设置 → 账号 → POP3/SMTP 服务 → 授权码 |
270
+ | 163 邮箱 | `smtp.163.com` | 465 | 设置 → POP3/SMTP/IMAP → 授权码 |
271
+ | Outlook | `smtp-mail.outlook.com` | 587 | 设 `IMHUB_SMTP_SECURE=false`(STARTTLS) |
272
+ | 企业邮箱 | 厂商提供 | 任意 | `SECURE` 按厂商文档设 |
273
+
274
+ 不设这些环境变量也不会启动失败——邮件 adapter 仍会注册,但 `/remind email …` 会返回"Email adapter not configured",IM 提醒不受影响。
275
+
276
+ systemd 部署示例:
277
+ ```ini
278
+ [Service]
279
+ Environment="IMHUB_SMTP_HOST=smtp.gmail.com"
280
+ Environment="IMHUB_SMTP_USER=you@gmail.com"
281
+ Environment="IMHUB_SMTP_PASS=xxxxxxxxxxxxxxxx"
282
+ ```
283
+
284
+ ### 其他环境变量
285
+
286
+ | 变量 | 默认值 | 作用 |
287
+ |------|--------|------|
288
+ | `IMHUB_WEB_BIND` | `127.0.0.1` | Web UI 监听地址(设 `0.0.0.0` 对外暴露,建议前面挂 HTTPS 反代) |
289
+ | `IMHUB_APPROVAL_DISABLED` | 未设 | 设 `=1` 跳过工具调用人审 |
290
+ | `IMHUB_OPENCODE_DRIVER` | `stdio` | 设 `http` 启用 HTTP driver(更快,但 reminder MCP 路径会走单用户 agent-asserted context) |
291
+ | `IMHUB_OPENCODE_GATE` | `medium` | `strict` / `loose` / `none` — opencode 权限闸 |
292
+ | `IM_HUB_LLM_JUDGE_AGENT` | 未设 | 路由分类失败时用作兜底的 LLM judge agent 名 |
293
+ | `OPENAI_API_KEY` | 未设 | 启用 OpenAI Whisper 做语音转写 |
294
+ | `IMHUB_WHISPERCPP_BIN` + `IMHUB_WHISPERCPP_MODEL` | 未设 | 本地 Whisper.cpp 转写(不走云) |
295
+ | `IMHUB_BAIDU_MAP_AK` | 未设 | 百度地图 AK;启用 `/memo` 地址→坐标 geocoding 路径。不设置时直接给坐标和浏览器抓 GPS 不受影响。 |
296
+ | `IMHUB_LOC_BASE_URL` | `https://agent.iclaw.host` | `/memo here` H5 抓 GPS 链接的公开 HTTPS 域名。自托管时改成自己的域。 |
297
+ | `IMHUB_TZ_OFFSET_HOURS` | `8` | memo 时间戳的 UTC 偏移(默认 Asia/Shanghai)。仅当部署在其他时区时调整。 |
298
+ | `IMHUB_TELEGRAM_COORDS_GCJ02` | 未设 | 设 `1` 对 Telegram 原生位置/venue 消息做 GCJ-02 → WGS-84 转换。默认关(直通),适合 Telegram Desktop / Android-without-China-GMS / 海外用户。如果你的 Telegram 客户端是国内 iOS 设备(Core Location 会加 GCJ 偏移),打开它。 |
299
+ | `IMHUB_H5_COORDS_GCJ02` | 未设 | 设 `1` 对 `/memo here` H5 抓 GPS 的坐标做 GCJ-02 → WGS-84 转换。默认关(直通),匹配微信 X5 / Android Chrome 直给 WGS-84 的常见情况。如果你的用户主要在 iOS Safari / iOS WebKit 国内打开 H5 链接(Apple 会加 GCJ 偏移),打开它。完整每平台策略见 [`src/core/coord-systems.ts`](src/core/coord-systems.ts)。 |
300
+ | `AGIM_HOME` | 自动 | 用户级配置/数据目录。全新安装默认 `~/.agim/`;从 0.x 升级则自动用现有的 `~/.im-hub/`。如果想固定到具体位置(多机共享、测试场景),显式设置即可。也认旧的 `IMHUB_HOME`。 |
301
+ | `AGIM_WORKSPACES` | 自动 | per-agent 工作区目录。与 `AGIM_HOME` 一样的双探测(优先 `~/.agim-workspaces/`,存在 `~/.im-hub-workspaces/` 时用它)。也认 `IMHUB_WORKSPACES`。 |
302
+
303
+ ## 架构
304
+
305
+ ```
306
+ ┌─ IM 入口 ────────────────────────────────────────┐
307
+ │ 微信 iLink (长轮询 + 图片/语音/文件) │
308
+ │ Telegram (grammy + 图片/语音/音频) │
309
+ │ 飞书 (Lark SDK WebSocket) │
310
+ │ 钉钉 (Stream WebSocket + 服务端 ASR) │
311
+ │ Discord (discord.js Gateway) │
312
+ │ Web Chat (浏览器 WebSocket) │
313
+ └───────────────────────┬──────────────────────────┘
314
+ │ MessageContext
315
+
316
+ ┌── 路由前置 gates ─────────────────┐
317
+ │ workspace · 限流器 · traceId │
318
+ └────────────────┬──────────────────┘
319
+
320
+ ┌── 意图路由 ───────────────────────┐
321
+ │ 命令 → 内置处理 │
322
+ │ /agent → 显式切换 │
323
+ │ 默认 → 分类(正则/关键词/ │
324
+ │ Sticky/LLM 兜底) │
325
+ └────────────────┬──────────────────┘
326
+
327
+ ┌── Agent 调用 ─────────────────────┐
328
+ │ 断路器 + spawn stream │
329
+ └───┬──────┬──────┬──────┬──────┬───┘
330
+ ▼ ▼ ▼ ▼ ▼
331
+ claude opencode codex copilot ACP
332
+
333
+ ▼ (工具审批)
334
+ MCP sidecar → approvalBus → IM 会话
335
+
336
+ ┌─ Cross-cutting ──────────────────────────────────┐
337
+ │ SQLite(审计 · 任务 · 调度) │
338
+ │ 会话(append-only JSONL) │
339
+ │ Prometheus 指标 · pino 结构化日志 │
340
+ └──────────────────────────────────────────────────┘
341
+ ```
342
+
343
+ 单进程,零外部依赖——SQLite + 会话文件就是全部持久化层。
344
+
345
+ 深入架构详见 [`docs/architecture/current.md`](docs/architecture/current.md)。
346
+
347
+ ## 环境要求
348
+
349
+ - **Node.js ≥ 18**(推荐 ≥ 22 LTS)
350
+ - 至少一个 Agent CLI 或 ACP 端点:
351
+ - `npm i -g @anthropic-ai/claude-code`
352
+ - `npm i -g @openai/codex`
353
+ - `npm i -g @github/copilot`
354
+ - `npm i -g opencode-ai`
355
+
356
+ ## 开发
357
+
358
+ ```bash
359
+ git clone https://github.com/benking007/imhub.git && cd imhub
360
+ npm install
361
+ npm run build # tsc + 拷贝 public/
362
+ npm run dev # tsc --watch
363
+ npm test # bun test
364
+ npm run lint # biome lint
365
+ npm run typecheck # tsc --noEmit
366
+ ```
367
+
368
+ ## 部署
369
+
370
+ systemd、Docker、nginx、监控与升级详见 [`docs/deployment.md`](docs/deployment.md)。
371
+
372
+ ## 路线图
373
+
374
+ ### 已完成
375
+
376
+ | 版本 | 主题 |
377
+ |------|------|
378
+ | v0.1.x | MVP — 微信 + 4 种 Agent + 命令路由 |
379
+ | v0.2.0 | 多 IM — 飞书、Telegram、会话持久化、ACP |
380
+ | v0.2.13 | 基础设施 — 日志、审计、意图、任务、指标、工作区 |
381
+ | v0.2.14 | 工具调用人审(HITL) |
382
+ | v0.2.15 | Discord 适配器 + 任务面板 |
383
+ | v0.2.16–17 | 安全收口 + 可观测 |
384
+ | v0.2.18–19 | IM 重连退避、Codex sandbox、仪表盘过滤 |
385
+ | v0.2.20–23 | Web 控制台 — 主题、审批、SSE、文件、批量操作 |
386
+ | v0.2.30 | 生产硬化 — 会话隔离、WS 串行、回环监听 |
387
+ | v0.2.35 | 微信和 Telegram 富媒体 — 图片 / 文件 / 语音 / 视频 |
388
+ | v0.2.37 | 提醒子系统 — `/remind`、LLM 意图识别 + 润色、Agent MCP 工具、邮件通道、Web `/reminders`、微信 context_token 持久化 |
389
+ | v0.3.0 | `/memo` 5W1H 持久记忆库 — `/location` → `/memo` 改名、地址 geocoding 接百度地图、opencode HTTP driver SSE 修复 |
390
+ | v0.3.1 | Telegram + 飞书原生位置消息接入、所有渠道 GCJ-02 → WGS-84 修正、`memo` 列保存原话 + LLM/启发式 `what` 提取 |
391
+ | v0.4.0 | codex 接入完整 imhub MCP 工具表(reminder + memo);Telegram + 飞书位置消息改走 agent-driven 决策(对齐微信 H5 架构) |
392
+ | v0.5.0–0.5.2 | `agim` 双语方向键向导(当时叫 `im-hub-pro`);按渠道独立配置(微信扫码、飞书 / Telegram / Discord 凭据输入;agent CLI 安装态实时探测);systemd unit env fallback;完整服务生命周期命令(`status / start --bg / restart / stop / uninstall`) |
393
+ | v0.6.0 | 钉钉 Stream 模式适配器——WebSocket 双向桥、图片消息(`messageFiles/download` → claude-code 多模态 Read)、语音消息(钉钉服务端 ASR `recognition`,whisper.cpp 兜底) |
394
+ | v0.6.3 | 各平台原生位置消息的坐标系按来源处理(Telegram 改为 WGS 直通;H5 改为 WGS 直通解决微信 X5 的偏移;钉钉 link 中的百度地图 URL 走 BD-09→WGS) |
395
+ | **v1.0.0** | 品牌升级为 **Agim · 阿吉姆**。新主命令 `agim`,老命令 `im-hub-pro` 保留为废弃别名。配置目录 / 环境变量 / HTTP 头 / systemd 单元名都保留以兼容 0.x 部署。 |
396
+
397
+ ### v1.1.0(下一版)
398
+
399
+ - [ ] Slack 适配器
400
+ - [ ] 飞书 / 钉钉 / Discord 卡片按钮版审批
401
+ - [ ] 多实例事件总线(Redis Streams / NATS)
402
+ - [ ] 工作区成员选择 UI
403
+
404
+ ## 社区
405
+
406
+ <p align="center">
407
+ <a href="https://deepseek.club/community/imhub">
408
+ <img src="https://deepseek.club/assets/logo-DH6LfKkF.png" style="width: 150px; height: auto;" alt="DeepSeek">
409
+ </a>
410
+ </p>
411
+
412
+ ## 许可证
413
+
414
+ MIT
@@ -0,0 +1,11 @@
1
+ export declare function cmdStatus(): void;
2
+ /**
3
+ * Foreground start is the legacy `program.command('start').action(...)`
4
+ * path in cli.ts — we DON'T re-implement it here, just delegate. For
5
+ * background, we re-spawn ourselves detached.
6
+ */
7
+ export declare function cmdStart(bg: boolean, runForegroundStart: () => Promise<void>): Promise<void>;
8
+ export declare function cmdStop(): Promise<void>;
9
+ export declare function cmdRestart(): Promise<void>;
10
+ export declare function cmdUninstall(): Promise<void>;
11
+ //# sourceMappingURL=cmd-handlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cmd-handlers.d.ts","sourceRoot":"","sources":["../../src/cli-ui/cmd-handlers.ts"],"names":[],"mappings":"AA0DA,wBAAgB,SAAS,IAAI,IAAI,CA+BhC;AAID;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,EAAE,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAiClG;AAID,wBAAsB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAkB7C;AAID,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAyBhD;AAID,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAoDlD"}
@@ -0,0 +1,240 @@
1
+ // cli-ui/cmd-handlers.ts — implementations of the 5 service-management
2
+ // commands. Each handler reads the persisted language preference, prints
3
+ // status / outcomes in that language, and shells out to systemctl / npm /
4
+ // rm where appropriate.
5
+ import { execSync, spawn } from 'node:child_process';
6
+ import { unlinkSync, existsSync, readFileSync } from 'node:fs';
7
+ import { dirname } from 'node:path';
8
+ import { fileURLToPath } from 'node:url';
9
+ import { homedir } from 'node:os';
10
+ import { join } from 'node:path';
11
+ import { detectService, spawnBackground, stopService, formatUptime, readWebEndpoint, PID_FILE, LOG_FILE, } from './service.js';
12
+ import { yesNo } from './prompts.js';
13
+ import { pickLang } from './lang-picker.js';
14
+ import { readSavedLang, t } from './i18n.js';
15
+ import { CONFIG_FILE, WORKSPACES_DIR } from './paths.js';
16
+ import { ENV_FILE, removeEnvFile } from './env-file.js';
17
+ /** Candidate paths for the systemd unit; v1.0 prefers `agim.service`,
18
+ * pre-v1.0 wrote `im-hub.service`. Resolved at runtime by `findSystemdUnit()`
19
+ * so we operate on whichever exists. */
20
+ const SYSTEMD_UNIT_CANDIDATES = [
21
+ '/etc/systemd/system/agim.service',
22
+ '/etc/systemd/system/im-hub.service',
23
+ ];
24
+ function findSystemdUnit() {
25
+ for (const path of SYSTEMD_UNIT_CANDIDATES) {
26
+ if (existsSync(path)) {
27
+ return { path, name: path.split('/').pop() ?? '' };
28
+ }
29
+ }
30
+ return null;
31
+ }
32
+ /** Path of the unit file, if any exists, for compat with code that
33
+ * references this constant. Resolved lazily so cleanup can drop it. */
34
+ function systemdUnitPath() {
35
+ return findSystemdUnit()?.path ?? null;
36
+ }
37
+ /** Pick whichever language is already saved, falling back to 'zh'. We
38
+ * don't re-prompt for language inside per-command handlers — they
39
+ * shouldn't disrupt scripted flows. */
40
+ function quietLang() {
41
+ return readSavedLang() ?? 'zh';
42
+ }
43
+ // ─── status ──────────────────────────────────────────────────────────
44
+ export function cmdStatus() {
45
+ const lang = quietLang();
46
+ console.log();
47
+ console.log(t(lang, 'svc.status.title'));
48
+ console.log('─'.repeat(50));
49
+ const st = detectService();
50
+ switch (st.mode) {
51
+ case 'systemd':
52
+ console.log(' ' + t(lang, 'svc.status.systemd_active', { pid: st.pid ?? '?' }));
53
+ break;
54
+ case 'background':
55
+ console.log(' ' + t(lang, 'svc.status.bg_running', { pid: st.pid ?? '?', log: LOG_FILE }));
56
+ break;
57
+ case 'foreground':
58
+ console.log(' ' + t(lang, 'svc.status.fg_running', { pid: st.pid ?? '?' }));
59
+ break;
60
+ case 'none':
61
+ console.log(' ' + t(lang, 'svc.status.not_running'));
62
+ if (systemdUnitPath()) {
63
+ console.log(' ' + t(lang, 'svc.status.systemd_inactive'));
64
+ }
65
+ return;
66
+ }
67
+ if (typeof st.uptimeSec === 'number') {
68
+ console.log(' ' + t(lang, 'svc.status.uptime', { duration: formatUptime(st.uptimeSec) }));
69
+ }
70
+ const web = readWebEndpoint();
71
+ if (web) {
72
+ console.log(' ' + t(lang, 'svc.status.web', { bind: web.bind, port: web.port }));
73
+ }
74
+ console.log();
75
+ }
76
+ // ─── start ───────────────────────────────────────────────────────────
77
+ /**
78
+ * Foreground start is the legacy `program.command('start').action(...)`
79
+ * path in cli.ts — we DON'T re-implement it here, just delegate. For
80
+ * background, we re-spawn ourselves detached.
81
+ */
82
+ export async function cmdStart(bg, runForegroundStart) {
83
+ const lang = quietLang();
84
+ const st = detectService();
85
+ if (st.mode === 'systemd') {
86
+ console.log(t(lang, 'svc.start.systemd_managed'));
87
+ return;
88
+ }
89
+ if (st.mode !== 'none') {
90
+ console.log(t(lang, 'svc.start.already_running', { pid: st.pid ?? '?' }));
91
+ return;
92
+ }
93
+ if (bg) {
94
+ console.log(t(lang, 'svc.start.starting_bg'));
95
+ // Re-exec self detached. Use the same node + cli.js paths so global vs
96
+ // local install both work.
97
+ const __dirname = dirname(fileURLToPath(import.meta.url));
98
+ const cliJs = join(__dirname, '..', 'cli.js');
99
+ const { pid } = spawnBackground(process.execPath, [cliJs, 'start']);
100
+ // Tiny wait so the child has a chance to either bind ports or crash;
101
+ // status check picks up the latter.
102
+ await new Promise(r => setTimeout(r, 1500));
103
+ const after = detectService();
104
+ if (after.mode === 'background' && after.pid === pid) {
105
+ console.log(t(lang, 'svc.start.bg_ready', { pid, log: LOG_FILE }));
106
+ console.log(t(lang, 'svc.start.bg_hint'));
107
+ }
108
+ else {
109
+ console.log('⚠️ Background daemon may have failed to bind ports — check log:');
110
+ console.log(` tail -n 40 ${LOG_FILE}`);
111
+ }
112
+ return;
113
+ }
114
+ console.log(t(lang, 'svc.start.starting_fg'));
115
+ await runForegroundStart();
116
+ }
117
+ // ─── stop ────────────────────────────────────────────────────────────
118
+ export async function cmdStop() {
119
+ const lang = quietLang();
120
+ const st = detectService();
121
+ if (st.mode === 'none') {
122
+ console.log(t(lang, 'svc.stop.not_running'));
123
+ return;
124
+ }
125
+ if (st.mode === 'systemd') {
126
+ console.log(t(lang, 'svc.stop.stopping_systemd'));
127
+ }
128
+ else if (st.mode === 'background') {
129
+ console.log(t(lang, 'svc.stop.stopping_bg', { pid: st.pid ?? '?' }));
130
+ }
131
+ else if (st.mode === 'foreground') {
132
+ console.log('⚠️ ' + (lang === 'zh'
133
+ ? '检测到前台进程在跑。会发 SIGTERM,但建议你回那个 shell 里 Ctrl-C。'
134
+ : 'Foreground process detected. Sending SIGTERM — but Ctrl-C in the owning shell is cleaner.'));
135
+ }
136
+ await stopService();
137
+ console.log(t(lang, 'svc.stop.stopped'));
138
+ }
139
+ // ─── restart ─────────────────────────────────────────────────────────
140
+ export async function cmdRestart() {
141
+ const lang = quietLang();
142
+ const st = detectService();
143
+ if (st.mode === 'systemd') {
144
+ console.log(t(lang, 'svc.restart.systemd'));
145
+ const unit = findSystemdUnit();
146
+ if (unit)
147
+ execSync(`systemctl restart ${unit.name}`, { stdio: 'inherit' });
148
+ console.log(t(lang, 'svc.restart.done'));
149
+ return;
150
+ }
151
+ if (st.mode === 'foreground') {
152
+ console.log(t(lang, 'svc.restart.fg_warning'));
153
+ return;
154
+ }
155
+ if (st.mode === 'background' || st.mode === 'none') {
156
+ console.log(t(lang, 'svc.restart.bg'));
157
+ if (st.mode === 'background')
158
+ await stopService();
159
+ // Re-spawn detached.
160
+ const __dirname = dirname(fileURLToPath(import.meta.url));
161
+ const cliJs = join(__dirname, '..', 'cli.js');
162
+ const { pid } = spawnBackground(process.execPath, [cliJs, 'start']);
163
+ await new Promise(r => setTimeout(r, 1500));
164
+ console.log(t(lang, 'svc.start.bg_ready', { pid, log: LOG_FILE }));
165
+ console.log(t(lang, 'svc.restart.done'));
166
+ }
167
+ }
168
+ // ─── uninstall ───────────────────────────────────────────────────────
169
+ export async function cmdUninstall() {
170
+ const lang = await pickLang();
171
+ // Path interpolations — match whatever AGIM_HOME / AGIM_WORKSPACES
172
+ // resolved to so the prompts reflect the actual on-disk layout (the
173
+ // legacy ~/.im-hub/ on upgraded systems, the new ~/.agim/ on fresh).
174
+ const pathVars = { config: CONFIG_FILE, workspaces: WORKSPACES_DIR };
175
+ console.log();
176
+ console.log(t(lang, 'svc.uninstall.confirm', pathVars));
177
+ console.log();
178
+ const ok = await yesNo({ message: t(lang, 'confirm'), default: false });
179
+ if (!ok) {
180
+ console.log(t(lang, 'svc.uninstall.cancelled'));
181
+ return;
182
+ }
183
+ // 1. Stop any running instance.
184
+ console.log(t(lang, 'svc.uninstall.stopping'));
185
+ await stopService();
186
+ // 2. Remove systemd unit if present (requires root). Both `agim.service`
187
+ // (v1.0+) and the legacy `im-hub.service` are cleaned up so an upgrade
188
+ // across the rename doesn't leave a stale unit behind.
189
+ for (const unitPath of SYSTEMD_UNIT_CANDIDATES) {
190
+ if (!existsSync(unitPath))
191
+ continue;
192
+ const unitName = unitPath.split('/').pop() ?? '';
193
+ console.log(t(lang, 'svc.uninstall.removing_unit'));
194
+ try {
195
+ execSync(`systemctl disable ${unitName}`, { stdio: 'ignore' });
196
+ }
197
+ catch { /* ok if not enabled */ }
198
+ try {
199
+ unlinkSync(unitPath);
200
+ }
201
+ catch (err) {
202
+ console.warn(`⚠️ Could not remove ${unitPath}: ${err instanceof Error ? err.message : String(err)} — try \`sudo rm ${unitPath}\` manually.`);
203
+ }
204
+ }
205
+ try {
206
+ execSync('systemctl daemon-reload', { stdio: 'ignore' });
207
+ }
208
+ catch { /* ok */ }
209
+ // 3. Remove config + env (but KEEP workspaces).
210
+ console.log(t(lang, 'svc.uninstall.removing_config', pathVars));
211
+ try {
212
+ unlinkSync(CONFIG_FILE);
213
+ }
214
+ catch { /* missing is fine */ }
215
+ removeEnvFile();
216
+ try {
217
+ unlinkSync(PID_FILE);
218
+ }
219
+ catch { /* missing is fine */ }
220
+ // 4. Uninstall npm package globally.
221
+ console.log(t(lang, 'svc.uninstall.removing_npm'));
222
+ try {
223
+ // Best-effort uninstall the current package `agim-cli` plus the
224
+ // legacy npm names `im-hub-pro` and `im-hub` so a user who upgraded
225
+ // across the rename(s) doesn't end up with stale dangling bins.
226
+ execSync('npm uninstall -g agim-cli im-hub-pro im-hub', { stdio: 'inherit' });
227
+ }
228
+ catch (err) {
229
+ console.warn(`⚠️ npm uninstall failed: ${err instanceof Error ? err.message : String(err)} — run \`npm uninstall -g agim-cli\` manually.`);
230
+ }
231
+ console.log();
232
+ console.log(t(lang, 'svc.uninstall.workspaces_kept', pathVars));
233
+ console.log(t(lang, 'svc.uninstall.done'));
234
+ }
235
+ // Suppress unused imports linters for now — spawn is referenced via spawnBackground.
236
+ void spawn;
237
+ void readFileSync;
238
+ void homedir;
239
+ void ENV_FILE;
240
+ //# sourceMappingURL=cmd-handlers.js.map