im-hub-pro 0.2.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (384) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +497 -0
  3. package/README.zh-CN.md +496 -0
  4. package/dist/cli.d.ts +3 -0
  5. package/dist/cli.d.ts.map +1 -0
  6. package/dist/cli.js +921 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/core/acp-server.d.ts +8 -0
  9. package/dist/core/acp-server.d.ts.map +1 -0
  10. package/dist/core/acp-server.js +266 -0
  11. package/dist/core/acp-server.js.map +1 -0
  12. package/dist/core/agent-base.d.ts +94 -0
  13. package/dist/core/agent-base.d.ts.map +1 -0
  14. package/dist/core/agent-base.js +374 -0
  15. package/dist/core/agent-base.js.map +1 -0
  16. package/dist/core/agent-cwd.d.ts +45 -0
  17. package/dist/core/agent-cwd.d.ts.map +1 -0
  18. package/dist/core/agent-cwd.js +178 -0
  19. package/dist/core/agent-cwd.js.map +1 -0
  20. package/dist/core/agent-cwd.test.d.ts +2 -0
  21. package/dist/core/agent-cwd.test.d.ts.map +1 -0
  22. package/dist/core/agent-cwd.test.js +149 -0
  23. package/dist/core/agent-cwd.test.js.map +1 -0
  24. package/dist/core/approval-bus.d.ts +232 -0
  25. package/dist/core/approval-bus.d.ts.map +1 -0
  26. package/dist/core/approval-bus.js +703 -0
  27. package/dist/core/approval-bus.js.map +1 -0
  28. package/dist/core/approval-bus.synthetic.test.d.ts +2 -0
  29. package/dist/core/approval-bus.synthetic.test.d.ts.map +1 -0
  30. package/dist/core/approval-bus.synthetic.test.js +182 -0
  31. package/dist/core/approval-bus.synthetic.test.js.map +1 -0
  32. package/dist/core/approval-bus.test.d.ts +2 -0
  33. package/dist/core/approval-bus.test.d.ts.map +1 -0
  34. package/dist/core/approval-bus.test.js +537 -0
  35. package/dist/core/approval-bus.test.js.map +1 -0
  36. package/dist/core/approval-router.d.ts +95 -0
  37. package/dist/core/approval-router.d.ts.map +1 -0
  38. package/dist/core/approval-router.js +450 -0
  39. package/dist/core/approval-router.js.map +1 -0
  40. package/dist/core/approval-router.test.d.ts +2 -0
  41. package/dist/core/approval-router.test.d.ts.map +1 -0
  42. package/dist/core/approval-router.test.js +413 -0
  43. package/dist/core/approval-router.test.js.map +1 -0
  44. package/dist/core/audit-log.d.ts +55 -0
  45. package/dist/core/audit-log.d.ts.map +1 -0
  46. package/dist/core/audit-log.js +203 -0
  47. package/dist/core/audit-log.js.map +1 -0
  48. package/dist/core/bgjob-reader.d.ts +65 -0
  49. package/dist/core/bgjob-reader.d.ts.map +1 -0
  50. package/dist/core/bgjob-reader.js +212 -0
  51. package/dist/core/bgjob-reader.js.map +1 -0
  52. package/dist/core/bgjob-reader.test.d.ts +2 -0
  53. package/dist/core/bgjob-reader.test.d.ts.map +1 -0
  54. package/dist/core/bgjob-reader.test.js +178 -0
  55. package/dist/core/bgjob-reader.test.js.map +1 -0
  56. package/dist/core/circuit-breaker.d.ts +37 -0
  57. package/dist/core/circuit-breaker.d.ts.map +1 -0
  58. package/dist/core/circuit-breaker.js +115 -0
  59. package/dist/core/circuit-breaker.js.map +1 -0
  60. package/dist/core/commands/agent.d.ts +4 -0
  61. package/dist/core/commands/agent.d.ts.map +1 -0
  62. package/dist/core/commands/agent.js +21 -0
  63. package/dist/core/commands/agent.js.map +1 -0
  64. package/dist/core/commands/approval.d.ts +3 -0
  65. package/dist/core/commands/approval.d.ts.map +1 -0
  66. package/dist/core/commands/approval.js +44 -0
  67. package/dist/core/commands/approval.js.map +1 -0
  68. package/dist/core/commands/approval.test.d.ts +2 -0
  69. package/dist/core/commands/approval.test.d.ts.map +1 -0
  70. package/dist/core/commands/approval.test.js +85 -0
  71. package/dist/core/commands/approval.test.js.map +1 -0
  72. package/dist/core/commands/audit.d.ts +3 -0
  73. package/dist/core/commands/audit.d.ts.map +1 -0
  74. package/dist/core/commands/audit.js +84 -0
  75. package/dist/core/commands/audit.js.map +1 -0
  76. package/dist/core/commands/builtin.d.ts +3 -0
  77. package/dist/core/commands/builtin.d.ts.map +1 -0
  78. package/dist/core/commands/builtin.js +26 -0
  79. package/dist/core/commands/builtin.js.map +1 -0
  80. package/dist/core/commands/job.d.ts +3 -0
  81. package/dist/core/commands/job.d.ts.map +1 -0
  82. package/dist/core/commands/job.js +195 -0
  83. package/dist/core/commands/job.js.map +1 -0
  84. package/dist/core/commands/model.d.ts +9 -0
  85. package/dist/core/commands/model.d.ts.map +1 -0
  86. package/dist/core/commands/model.js +183 -0
  87. package/dist/core/commands/model.js.map +1 -0
  88. package/dist/core/commands/plan.d.ts +3 -0
  89. package/dist/core/commands/plan.d.ts.map +1 -0
  90. package/dist/core/commands/plan.js +75 -0
  91. package/dist/core/commands/plan.js.map +1 -0
  92. package/dist/core/commands/plan.test.d.ts +2 -0
  93. package/dist/core/commands/plan.test.d.ts.map +1 -0
  94. package/dist/core/commands/plan.test.js +122 -0
  95. package/dist/core/commands/plan.test.js.map +1 -0
  96. package/dist/core/commands/router.d.ts +3 -0
  97. package/dist/core/commands/router.d.ts.map +1 -0
  98. package/dist/core/commands/router.js +71 -0
  99. package/dist/core/commands/router.js.map +1 -0
  100. package/dist/core/commands/schedule.d.ts +3 -0
  101. package/dist/core/commands/schedule.d.ts.map +1 -0
  102. package/dist/core/commands/schedule.js +123 -0
  103. package/dist/core/commands/schedule.js.map +1 -0
  104. package/dist/core/commands/sessions.d.ts +3 -0
  105. package/dist/core/commands/sessions.d.ts.map +1 -0
  106. package/dist/core/commands/sessions.js +88 -0
  107. package/dist/core/commands/sessions.js.map +1 -0
  108. package/dist/core/commands/stats.d.ts +3 -0
  109. package/dist/core/commands/stats.d.ts.map +1 -0
  110. package/dist/core/commands/stats.js +73 -0
  111. package/dist/core/commands/stats.js.map +1 -0
  112. package/dist/core/commands/think.d.ts +3 -0
  113. package/dist/core/commands/think.d.ts.map +1 -0
  114. package/dist/core/commands/think.js +28 -0
  115. package/dist/core/commands/think.js.map +1 -0
  116. package/dist/core/commands/workspaces.d.ts +3 -0
  117. package/dist/core/commands/workspaces.d.ts.map +1 -0
  118. package/dist/core/commands/workspaces.js +47 -0
  119. package/dist/core/commands/workspaces.js.map +1 -0
  120. package/dist/core/config-schema.d.ts +58 -0
  121. package/dist/core/config-schema.d.ts.map +1 -0
  122. package/dist/core/config-schema.js +63 -0
  123. package/dist/core/config-schema.js.map +1 -0
  124. package/dist/core/cron.d.ts +29 -0
  125. package/dist/core/cron.d.ts.map +1 -0
  126. package/dist/core/cron.js +184 -0
  127. package/dist/core/cron.js.map +1 -0
  128. package/dist/core/event-bus.d.ts +80 -0
  129. package/dist/core/event-bus.d.ts.map +1 -0
  130. package/dist/core/event-bus.js +62 -0
  131. package/dist/core/event-bus.js.map +1 -0
  132. package/dist/core/intent-llm.d.ts +27 -0
  133. package/dist/core/intent-llm.d.ts.map +1 -0
  134. package/dist/core/intent-llm.js +170 -0
  135. package/dist/core/intent-llm.js.map +1 -0
  136. package/dist/core/intent.d.ts +12 -0
  137. package/dist/core/intent.d.ts.map +1 -0
  138. package/dist/core/intent.js +187 -0
  139. package/dist/core/intent.js.map +1 -0
  140. package/dist/core/job-board.d.ts +84 -0
  141. package/dist/core/job-board.d.ts.map +1 -0
  142. package/dist/core/job-board.js +379 -0
  143. package/dist/core/job-board.js.map +1 -0
  144. package/dist/core/logger.d.ts +6 -0
  145. package/dist/core/logger.d.ts.map +1 -0
  146. package/dist/core/logger.js +54 -0
  147. package/dist/core/logger.js.map +1 -0
  148. package/dist/core/metrics.d.ts +55 -0
  149. package/dist/core/metrics.d.ts.map +1 -0
  150. package/dist/core/metrics.js +291 -0
  151. package/dist/core/metrics.js.map +1 -0
  152. package/dist/core/onboarding.d.ts +94 -0
  153. package/dist/core/onboarding.d.ts.map +1 -0
  154. package/dist/core/onboarding.js +426 -0
  155. package/dist/core/onboarding.js.map +1 -0
  156. package/dist/core/onboarding.test.d.ts +2 -0
  157. package/dist/core/onboarding.test.d.ts.map +1 -0
  158. package/dist/core/onboarding.test.js +112 -0
  159. package/dist/core/onboarding.test.js.map +1 -0
  160. package/dist/core/rate-limiter.d.ts +44 -0
  161. package/dist/core/rate-limiter.d.ts.map +1 -0
  162. package/dist/core/rate-limiter.js +115 -0
  163. package/dist/core/rate-limiter.js.map +1 -0
  164. package/dist/core/registry.d.ts +32 -0
  165. package/dist/core/registry.d.ts.map +1 -0
  166. package/dist/core/registry.js +122 -0
  167. package/dist/core/registry.js.map +1 -0
  168. package/dist/core/router.d.ts +41 -0
  169. package/dist/core/router.d.ts.map +1 -0
  170. package/dist/core/router.js +431 -0
  171. package/dist/core/router.js.map +1 -0
  172. package/dist/core/schedule.d.ts +65 -0
  173. package/dist/core/schedule.d.ts.map +1 -0
  174. package/dist/core/schedule.js +316 -0
  175. package/dist/core/schedule.js.map +1 -0
  176. package/dist/core/session-subtasks.test.d.ts +2 -0
  177. package/dist/core/session-subtasks.test.d.ts.map +1 -0
  178. package/dist/core/session-subtasks.test.js +88 -0
  179. package/dist/core/session-subtasks.test.js.map +1 -0
  180. package/dist/core/session.d.ts +182 -0
  181. package/dist/core/session.d.ts.map +1 -0
  182. package/dist/core/session.js +774 -0
  183. package/dist/core/session.js.map +1 -0
  184. package/dist/core/sqlite-helper.d.ts +37 -0
  185. package/dist/core/sqlite-helper.d.ts.map +1 -0
  186. package/dist/core/sqlite-helper.js +79 -0
  187. package/dist/core/sqlite-helper.js.map +1 -0
  188. package/dist/core/transcribe.d.ts +25 -0
  189. package/dist/core/transcribe.d.ts.map +1 -0
  190. package/dist/core/transcribe.js +217 -0
  191. package/dist/core/transcribe.js.map +1 -0
  192. package/dist/core/transcribe.test.d.ts +2 -0
  193. package/dist/core/transcribe.test.d.ts.map +1 -0
  194. package/dist/core/transcribe.test.js +163 -0
  195. package/dist/core/transcribe.test.js.map +1 -0
  196. package/dist/core/types.d.ts +352 -0
  197. package/dist/core/types.d.ts.map +1 -0
  198. package/dist/core/types.js +3 -0
  199. package/dist/core/types.js.map +1 -0
  200. package/dist/core/workspace.d.ts +67 -0
  201. package/dist/core/workspace.d.ts.map +1 -0
  202. package/dist/core/workspace.js +113 -0
  203. package/dist/core/workspace.js.map +1 -0
  204. package/dist/index.d.ts +5 -0
  205. package/dist/index.d.ts.map +1 -0
  206. package/dist/index.js +6 -0
  207. package/dist/index.js.map +1 -0
  208. package/dist/plugins/agents/acp/acp-adapter.d.ts +16 -0
  209. package/dist/plugins/agents/acp/acp-adapter.d.ts.map +1 -0
  210. package/dist/plugins/agents/acp/acp-adapter.js +49 -0
  211. package/dist/plugins/agents/acp/acp-adapter.js.map +1 -0
  212. package/dist/plugins/agents/acp/acp-client.d.ts +32 -0
  213. package/dist/plugins/agents/acp/acp-client.d.ts.map +1 -0
  214. package/dist/plugins/agents/acp/acp-client.js +175 -0
  215. package/dist/plugins/agents/acp/acp-client.js.map +1 -0
  216. package/dist/plugins/agents/acp/discovery.d.ts +19 -0
  217. package/dist/plugins/agents/acp/discovery.d.ts.map +1 -0
  218. package/dist/plugins/agents/acp/discovery.js +109 -0
  219. package/dist/plugins/agents/acp/discovery.js.map +1 -0
  220. package/dist/plugins/agents/acp/index.d.ts +4 -0
  221. package/dist/plugins/agents/acp/index.d.ts.map +1 -0
  222. package/dist/plugins/agents/acp/index.js +4 -0
  223. package/dist/plugins/agents/acp/index.js.map +1 -0
  224. package/dist/plugins/agents/acp/types.d.ts +62 -0
  225. package/dist/plugins/agents/acp/types.d.ts.map +1 -0
  226. package/dist/plugins/agents/acp/types.js +5 -0
  227. package/dist/plugins/agents/acp/types.js.map +1 -0
  228. package/dist/plugins/agents/claude-code/adapter.test.d.ts +2 -0
  229. package/dist/plugins/agents/claude-code/adapter.test.d.ts.map +1 -0
  230. package/dist/plugins/agents/claude-code/adapter.test.js +195 -0
  231. package/dist/plugins/agents/claude-code/adapter.test.js.map +1 -0
  232. package/dist/plugins/agents/claude-code/index.d.ts +25 -0
  233. package/dist/plugins/agents/claude-code/index.d.ts.map +1 -0
  234. package/dist/plugins/agents/claude-code/index.js +184 -0
  235. package/dist/plugins/agents/claude-code/index.js.map +1 -0
  236. package/dist/plugins/agents/claude-code/mcp-approval-server.d.ts +42 -0
  237. package/dist/plugins/agents/claude-code/mcp-approval-server.d.ts.map +1 -0
  238. package/dist/plugins/agents/claude-code/mcp-approval-server.js +235 -0
  239. package/dist/plugins/agents/claude-code/mcp-approval-server.js.map +1 -0
  240. package/dist/plugins/agents/claude-code/mcp-approval-server.test.d.ts +2 -0
  241. package/dist/plugins/agents/claude-code/mcp-approval-server.test.d.ts.map +1 -0
  242. package/dist/plugins/agents/claude-code/mcp-approval-server.test.js +188 -0
  243. package/dist/plugins/agents/claude-code/mcp-approval-server.test.js.map +1 -0
  244. package/dist/plugins/agents/codex/adapter.test.d.ts +2 -0
  245. package/dist/plugins/agents/codex/adapter.test.d.ts.map +1 -0
  246. package/dist/plugins/agents/codex/adapter.test.js +192 -0
  247. package/dist/plugins/agents/codex/adapter.test.js.map +1 -0
  248. package/dist/plugins/agents/codex/index.d.ts +37 -0
  249. package/dist/plugins/agents/codex/index.d.ts.map +1 -0
  250. package/dist/plugins/agents/codex/index.js +254 -0
  251. package/dist/plugins/agents/codex/index.js.map +1 -0
  252. package/dist/plugins/agents/copilot/index.d.ts +35 -0
  253. package/dist/plugins/agents/copilot/index.d.ts.map +1 -0
  254. package/dist/plugins/agents/copilot/index.js +182 -0
  255. package/dist/plugins/agents/copilot/index.js.map +1 -0
  256. package/dist/plugins/agents/opencode/adapter.test.d.ts +2 -0
  257. package/dist/plugins/agents/opencode/adapter.test.d.ts.map +1 -0
  258. package/dist/plugins/agents/opencode/adapter.test.js +139 -0
  259. package/dist/plugins/agents/opencode/adapter.test.js.map +1 -0
  260. package/dist/plugins/agents/opencode/http-adapter.test.d.ts +2 -0
  261. package/dist/plugins/agents/opencode/http-adapter.test.d.ts.map +1 -0
  262. package/dist/plugins/agents/opencode/http-adapter.test.js +492 -0
  263. package/dist/plugins/agents/opencode/http-adapter.test.js.map +1 -0
  264. package/dist/plugins/agents/opencode/index.d.ts +5 -0
  265. package/dist/plugins/agents/opencode/index.d.ts.map +1 -0
  266. package/dist/plugins/agents/opencode/index.js +30 -0
  267. package/dist/plugins/agents/opencode/index.js.map +1 -0
  268. package/dist/plugins/agents/opencode/opencode-http-adapter.d.ts +138 -0
  269. package/dist/plugins/agents/opencode/opencode-http-adapter.d.ts.map +1 -0
  270. package/dist/plugins/agents/opencode/opencode-http-adapter.js +549 -0
  271. package/dist/plugins/agents/opencode/opencode-http-adapter.js.map +1 -0
  272. package/dist/plugins/agents/opencode/opencode-stdio-adapter.d.ts +24 -0
  273. package/dist/plugins/agents/opencode/opencode-stdio-adapter.d.ts.map +1 -0
  274. package/dist/plugins/agents/opencode/opencode-stdio-adapter.js +103 -0
  275. package/dist/plugins/agents/opencode/opencode-stdio-adapter.js.map +1 -0
  276. package/dist/plugins/agents/opencode/serve-manager.d.ts +27 -0
  277. package/dist/plugins/agents/opencode/serve-manager.d.ts.map +1 -0
  278. package/dist/plugins/agents/opencode/serve-manager.js +190 -0
  279. package/dist/plugins/agents/opencode/serve-manager.js.map +1 -0
  280. package/dist/plugins/messengers/discord/discord-adapter.d.ts +22 -0
  281. package/dist/plugins/messengers/discord/discord-adapter.d.ts.map +1 -0
  282. package/dist/plugins/messengers/discord/discord-adapter.js +241 -0
  283. package/dist/plugins/messengers/discord/discord-adapter.js.map +1 -0
  284. package/dist/plugins/messengers/discord/discord-adapter.test.d.ts +2 -0
  285. package/dist/plugins/messengers/discord/discord-adapter.test.d.ts.map +1 -0
  286. package/dist/plugins/messengers/discord/discord-adapter.test.js +332 -0
  287. package/dist/plugins/messengers/discord/discord-adapter.test.js.map +1 -0
  288. package/dist/plugins/messengers/discord/index.d.ts +4 -0
  289. package/dist/plugins/messengers/discord/index.d.ts.map +1 -0
  290. package/dist/plugins/messengers/discord/index.js +4 -0
  291. package/dist/plugins/messengers/discord/index.js.map +1 -0
  292. package/dist/plugins/messengers/discord/markdown-to-discord.d.ts +11 -0
  293. package/dist/plugins/messengers/discord/markdown-to-discord.d.ts.map +1 -0
  294. package/dist/plugins/messengers/discord/markdown-to-discord.js +59 -0
  295. package/dist/plugins/messengers/discord/markdown-to-discord.js.map +1 -0
  296. package/dist/plugins/messengers/discord/types.d.ts +9 -0
  297. package/dist/plugins/messengers/discord/types.d.ts.map +1 -0
  298. package/dist/plugins/messengers/discord/types.js +3 -0
  299. package/dist/plugins/messengers/discord/types.js.map +1 -0
  300. package/dist/plugins/messengers/feishu/card-builder.d.ts +23 -0
  301. package/dist/plugins/messengers/feishu/card-builder.d.ts.map +1 -0
  302. package/dist/plugins/messengers/feishu/card-builder.js +89 -0
  303. package/dist/plugins/messengers/feishu/card-builder.js.map +1 -0
  304. package/dist/plugins/messengers/feishu/feishu-adapter.d.ts +33 -0
  305. package/dist/plugins/messengers/feishu/feishu-adapter.d.ts.map +1 -0
  306. package/dist/plugins/messengers/feishu/feishu-adapter.js +195 -0
  307. package/dist/plugins/messengers/feishu/feishu-adapter.js.map +1 -0
  308. package/dist/plugins/messengers/feishu/feishu-client.d.ts +44 -0
  309. package/dist/plugins/messengers/feishu/feishu-client.d.ts.map +1 -0
  310. package/dist/plugins/messengers/feishu/feishu-client.js +120 -0
  311. package/dist/plugins/messengers/feishu/feishu-client.js.map +1 -0
  312. package/dist/plugins/messengers/feishu/feishu-dedup.test.d.ts +2 -0
  313. package/dist/plugins/messengers/feishu/feishu-dedup.test.d.ts.map +1 -0
  314. package/dist/plugins/messengers/feishu/feishu-dedup.test.js +70 -0
  315. package/dist/plugins/messengers/feishu/feishu-dedup.test.js.map +1 -0
  316. package/dist/plugins/messengers/feishu/index.d.ts +4 -0
  317. package/dist/plugins/messengers/feishu/index.d.ts.map +1 -0
  318. package/dist/plugins/messengers/feishu/index.js +4 -0
  319. package/dist/plugins/messengers/feishu/index.js.map +1 -0
  320. package/dist/plugins/messengers/feishu/types.d.ts +113 -0
  321. package/dist/plugins/messengers/feishu/types.d.ts.map +1 -0
  322. package/dist/plugins/messengers/feishu/types.js +4 -0
  323. package/dist/plugins/messengers/feishu/types.js.map +1 -0
  324. package/dist/plugins/messengers/telegram/index.d.ts +4 -0
  325. package/dist/plugins/messengers/telegram/index.d.ts.map +1 -0
  326. package/dist/plugins/messengers/telegram/index.js +4 -0
  327. package/dist/plugins/messengers/telegram/index.js.map +1 -0
  328. package/dist/plugins/messengers/telegram/markdown-to-html.d.ts +5 -0
  329. package/dist/plugins/messengers/telegram/markdown-to-html.d.ts.map +1 -0
  330. package/dist/plugins/messengers/telegram/markdown-to-html.js +186 -0
  331. package/dist/plugins/messengers/telegram/markdown-to-html.js.map +1 -0
  332. package/dist/plugins/messengers/telegram/media-download.d.ts +51 -0
  333. package/dist/plugins/messengers/telegram/media-download.d.ts.map +1 -0
  334. package/dist/plugins/messengers/telegram/media-download.js +224 -0
  335. package/dist/plugins/messengers/telegram/media-download.js.map +1 -0
  336. package/dist/plugins/messengers/telegram/media-download.test.d.ts +2 -0
  337. package/dist/plugins/messengers/telegram/media-download.test.d.ts.map +1 -0
  338. package/dist/plugins/messengers/telegram/media-download.test.js +125 -0
  339. package/dist/plugins/messengers/telegram/media-download.test.js.map +1 -0
  340. package/dist/plugins/messengers/telegram/telegram-adapter.d.ts +62 -0
  341. package/dist/plugins/messengers/telegram/telegram-adapter.d.ts.map +1 -0
  342. package/dist/plugins/messengers/telegram/telegram-adapter.js +653 -0
  343. package/dist/plugins/messengers/telegram/telegram-adapter.js.map +1 -0
  344. package/dist/plugins/messengers/telegram/types.d.ts +47 -0
  345. package/dist/plugins/messengers/telegram/types.d.ts.map +1 -0
  346. package/dist/plugins/messengers/telegram/types.js +3 -0
  347. package/dist/plugins/messengers/telegram/types.js.map +1 -0
  348. package/dist/plugins/messengers/wechat/ilink-adapter.d.ts +68 -0
  349. package/dist/plugins/messengers/wechat/ilink-adapter.d.ts.map +1 -0
  350. package/dist/plugins/messengers/wechat/ilink-adapter.js +483 -0
  351. package/dist/plugins/messengers/wechat/ilink-adapter.js.map +1 -0
  352. package/dist/plugins/messengers/wechat/ilink-client.d.ts +66 -0
  353. package/dist/plugins/messengers/wechat/ilink-client.d.ts.map +1 -0
  354. package/dist/plugins/messengers/wechat/ilink-client.js +288 -0
  355. package/dist/plugins/messengers/wechat/ilink-client.js.map +1 -0
  356. package/dist/plugins/messengers/wechat/ilink-types.d.ts +173 -0
  357. package/dist/plugins/messengers/wechat/ilink-types.d.ts.map +1 -0
  358. package/dist/plugins/messengers/wechat/ilink-types.js +12 -0
  359. package/dist/plugins/messengers/wechat/ilink-types.js.map +1 -0
  360. package/dist/utils/backoff.d.ts +35 -0
  361. package/dist/utils/backoff.d.ts.map +1 -0
  362. package/dist/utils/backoff.js +59 -0
  363. package/dist/utils/backoff.js.map +1 -0
  364. package/dist/utils/cross-platform.d.ts +26 -0
  365. package/dist/utils/cross-platform.d.ts.map +1 -0
  366. package/dist/utils/cross-platform.js +58 -0
  367. package/dist/utils/cross-platform.js.map +1 -0
  368. package/dist/utils/message-split.d.ts +14 -0
  369. package/dist/utils/message-split.d.ts.map +1 -0
  370. package/dist/utils/message-split.js +65 -0
  371. package/dist/utils/message-split.js.map +1 -0
  372. package/dist/utils/safe-equal.d.ts +2 -0
  373. package/dist/utils/safe-equal.d.ts.map +1 -0
  374. package/dist/utils/safe-equal.js +11 -0
  375. package/dist/utils/safe-equal.js.map +1 -0
  376. package/dist/web/public/_app.js +196 -0
  377. package/dist/web/public/index.html +935 -0
  378. package/dist/web/public/settings.html +1181 -0
  379. package/dist/web/public/tasks.html +1827 -0
  380. package/dist/web/server.d.ts +11 -0
  381. package/dist/web/server.d.ts.map +1 -0
  382. package/dist/web/server.js +1820 -0
  383. package/dist/web/server.js.map +1 -0
  384. package/package.json +73 -0
@@ -0,0 +1,178 @@
1
+ // bgjob-reader tests — work entirely against temp dirs we lay out to mimic
2
+ // the real wrapper's on-disk layout. We never touch ~/.claude or
3
+ // ~/.config/opencode and never spawn the wrapper.
4
+ import { describe, it, expect, beforeEach, afterEach } from 'bun:test';
5
+ import { mkdtemp, mkdir, writeFile, rm } from 'fs/promises';
6
+ import { tmpdir } from 'os';
7
+ import { join } from 'path';
8
+ import { resolveRoots, listJobsForRoot, getJobDetail, listAllJobs, findRoot, } from './bgjob-reader.js';
9
+ let tmp;
10
+ const ORIGINAL_ENV = process.env.IMHUB_BGJOB_ROOTS;
11
+ async function writeJob(root, id, meta, log) {
12
+ const dir = join(root, id);
13
+ await mkdir(dir, { recursive: true });
14
+ await writeFile(join(dir, 'meta.json'), JSON.stringify(meta));
15
+ if (log !== undefined)
16
+ await writeFile(join(dir, 'log.txt'), log);
17
+ }
18
+ beforeEach(async () => {
19
+ tmp = await mkdtemp(join(tmpdir(), 'bgjob-reader-test-'));
20
+ });
21
+ afterEach(async () => {
22
+ if (ORIGINAL_ENV === undefined)
23
+ delete process.env.IMHUB_BGJOB_ROOTS;
24
+ else
25
+ process.env.IMHUB_BGJOB_ROOTS = ORIGINAL_ENV;
26
+ await rm(tmp, { recursive: true, force: true });
27
+ });
28
+ describe('resolveRoots', () => {
29
+ it('returns defaults when env unset', () => {
30
+ delete process.env.IMHUB_BGJOB_ROOTS;
31
+ const roots = resolveRoots();
32
+ expect(roots.length).toBe(3);
33
+ expect(roots.map((r) => r.id).sort()).toEqual(['claude', 'codex', 'opencode']);
34
+ });
35
+ it('parses comma-separated absolute paths from env, with id= prefix', () => {
36
+ process.env.IMHUB_BGJOB_ROOTS = `c=${tmp}/a,o=${tmp}/b`;
37
+ const roots = resolveRoots();
38
+ expect(roots.map((r) => r.id)).toEqual(['c', 'o']);
39
+ expect(roots[0].path).toBe(join(tmp, 'a'));
40
+ });
41
+ it('falls back to default when env contains no valid entries', () => {
42
+ process.env.IMHUB_BGJOB_ROOTS = 'relative/path';
43
+ const roots = resolveRoots();
44
+ expect(roots.length).toBe(3); // back to defaults
45
+ });
46
+ it('uses basename as id when no id= prefix', () => {
47
+ process.env.IMHUB_BGJOB_ROOTS = `${tmp}/myroot`;
48
+ const roots = resolveRoots();
49
+ expect(roots[0].id).toBe('myroot');
50
+ });
51
+ });
52
+ describe('listJobsForRoot', () => {
53
+ it('reads jobs from index.json + each meta.json', async () => {
54
+ await writeFile(join(tmp, 'index.json'), JSON.stringify({
55
+ jobs: [
56
+ { id: 'j1', name: 'task-a', started_at: '2026-05-01T10:00:00+08:00' },
57
+ { id: 'j2', name: 'task-b', started_at: '2026-05-01T11:00:00+08:00' },
58
+ ],
59
+ }));
60
+ await writeJob(tmp, 'j1', {
61
+ id: 'j1', name: 'task-a', status: 'completed', pid: 100,
62
+ started_at: '2026-05-01T10:00:00+08:00',
63
+ ended_at: '2026-05-01T10:05:00+08:00',
64
+ exit_code: 0,
65
+ });
66
+ await writeJob(tmp, 'j2', {
67
+ id: 'j2', name: 'task-b', status: 'running', pid: 200,
68
+ started_at: '2026-05-01T11:00:00+08:00',
69
+ ended_at: null, exit_code: null,
70
+ });
71
+ const root = { id: 'test', path: tmp, label: 'test' };
72
+ const jobs = await listJobsForRoot(root);
73
+ expect(jobs.length).toBe(2);
74
+ // newest-first
75
+ expect(jobs[0].id).toBe('j2');
76
+ expect(jobs[0].status).toBe('running');
77
+ expect(jobs[1].status).toBe('completed');
78
+ expect(jobs[1].exit_code).toBe(0);
79
+ expect(jobs.every((j) => j.rootId === 'test')).toBe(true);
80
+ });
81
+ it('falls back to directory scan when index.json is missing', async () => {
82
+ await writeJob(tmp, '20260501-jobx-abcd', {
83
+ id: '20260501-jobx-abcd', name: 'jobx', status: 'failed',
84
+ pid: null, started_at: '2026-05-01T09:00:00+08:00',
85
+ ended_at: '2026-05-01T09:01:00+08:00', exit_code: 1,
86
+ });
87
+ const root = { id: 'test', path: tmp, label: 'test' };
88
+ const jobs = await listJobsForRoot(root);
89
+ expect(jobs.length).toBe(1);
90
+ expect(jobs[0].id).toBe('20260501-jobx-abcd');
91
+ expect(jobs[0].status).toBe('failed');
92
+ });
93
+ it('returns [] when root does not exist', async () => {
94
+ const root = { id: 'nope', path: join(tmp, 'does-not-exist'), label: 'x' };
95
+ const jobs = await listJobsForRoot(root);
96
+ expect(jobs).toEqual([]);
97
+ });
98
+ it('skips jobs whose meta.json is missing or unparseable', async () => {
99
+ await writeFile(join(tmp, 'index.json'), JSON.stringify({
100
+ jobs: [{ id: 'good' }, { id: 'broken' }, { id: 'missing' }],
101
+ }));
102
+ await writeJob(tmp, 'good', { id: 'good', name: 'g', status: 'running' });
103
+ await mkdir(join(tmp, 'broken'), { recursive: true });
104
+ await writeFile(join(tmp, 'broken', 'meta.json'), '{not json');
105
+ const root = { id: 't', path: tmp, label: 't' };
106
+ const jobs = await listJobsForRoot(root);
107
+ expect(jobs.length).toBe(1);
108
+ expect(jobs[0].id).toBe('good');
109
+ });
110
+ it('rejects path-traversal IDs from a malformed index.json', async () => {
111
+ await writeFile(join(tmp, 'index.json'), JSON.stringify({
112
+ jobs: [{ id: '../../etc/passwd' }, { id: 'real' }],
113
+ }));
114
+ await writeJob(tmp, 'real', { id: 'real', name: 'r', status: 'running' });
115
+ const jobs = await listJobsForRoot({ id: 't', path: tmp, label: 't' });
116
+ expect(jobs.length).toBe(1);
117
+ expect(jobs[0].id).toBe('real');
118
+ });
119
+ });
120
+ describe('getJobDetail', () => {
121
+ it('returns full meta + log tail', async () => {
122
+ await writeJob(tmp, 'j1', {
123
+ id: 'j1', name: 'task-a', status: 'completed',
124
+ cmd: ['/usr/bin/python3', '-m', 'foo'],
125
+ workdir: '/tmp/work',
126
+ out_dir: '/tmp/work/out',
127
+ pid: 100, exit_code: 0,
128
+ started_at: '2026-05-01T10:00:00+08:00',
129
+ ended_at: '2026-05-01T10:05:00+08:00',
130
+ restart_generation: 2,
131
+ resources: { cpu_time: 1.5, rss_kb: 8192, state: 'S' },
132
+ }, 'line1\nline2\nline3\nline4\n');
133
+ const detail = await getJobDetail({ id: 't', path: tmp, label: 't' }, 'j1', 2);
134
+ expect(detail).not.toBeNull();
135
+ expect(detail.cmd).toEqual(['/usr/bin/python3', '-m', 'foo']);
136
+ expect(detail.workdir).toBe('/tmp/work');
137
+ expect(detail.restart_generation).toBe(2);
138
+ expect(detail.log_tail).toBe('line3\nline4');
139
+ expect(detail.resources?.rss_kb).toBe(8192);
140
+ });
141
+ it('returns null when log file is missing', async () => {
142
+ await writeJob(tmp, 'j1', { id: 'j1', name: 'x', status: 'running' });
143
+ const detail = await getJobDetail({ id: 't', path: tmp, label: 't' }, 'j1');
144
+ expect(detail).not.toBeNull();
145
+ expect(detail.log_tail).toBeNull();
146
+ });
147
+ it('returns null for unknown id', async () => {
148
+ const detail = await getJobDetail({ id: 't', path: tmp, label: 't' }, 'no-such');
149
+ expect(detail).toBeNull();
150
+ });
151
+ it('rejects path-traversal id without reading anything', async () => {
152
+ const detail = await getJobDetail({ id: 't', path: tmp, label: 't' }, '../etc');
153
+ expect(detail).toBeNull();
154
+ });
155
+ });
156
+ describe('listAllJobs + findRoot', () => {
157
+ it('groups jobs by root with isolation between roots', async () => {
158
+ const a = join(tmp, 'a');
159
+ const b = join(tmp, 'b');
160
+ await mkdir(a, { recursive: true });
161
+ await mkdir(b, { recursive: true });
162
+ await writeJob(a, 'jA', { id: 'jA', name: 'a-only', status: 'running' });
163
+ await writeJob(b, 'jB', { id: 'jB', name: 'b-only', status: 'completed' });
164
+ process.env.IMHUB_BGJOB_ROOTS = `aa=${a},bb=${b}`;
165
+ const all = await listAllJobs();
166
+ expect(all.length).toBe(2);
167
+ const byId = Object.fromEntries(all.map((g) => [g.root.id, g.jobs]));
168
+ expect(byId['aa'].length).toBe(1);
169
+ expect(byId['aa'][0].id).toBe('jA');
170
+ expect(byId['bb'][0].id).toBe('jB');
171
+ });
172
+ it('findRoot returns null for unknown id', () => {
173
+ process.env.IMHUB_BGJOB_ROOTS = `aa=${tmp}`;
174
+ expect(findRoot('aa')?.path).toBe(tmp);
175
+ expect(findRoot('zz')).toBeNull();
176
+ });
177
+ });
178
+ //# sourceMappingURL=bgjob-reader.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bgjob-reader.test.js","sourceRoot":"","sources":["../../src/core/bgjob-reader.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ type BreakerPhase = 'closed' | 'open' | 'half-open';
2
+ declare class CircuitBreaker {
3
+ private states;
4
+ private threshold;
5
+ private baseCooldownMs;
6
+ constructor(threshold?: number, cooldownMs?: number);
7
+ /** Record a failed invocation. Returns true if the breaker just opened. */
8
+ recordFailure(agent: string): boolean;
9
+ /** Record a successful invocation. Closes the breaker, resets counters. */
10
+ recordSuccess(agent: string): void;
11
+ /**
12
+ * Check if an agent is currently blocked (breaker open AND cooldown still
13
+ * active). After cooldown elapses we transition to half-open and *return
14
+ * false for the first caller only* — that caller becomes the probe.
15
+ */
16
+ isOpen(agent: string): boolean;
17
+ /** Get status for display / debug. */
18
+ getStatus(agent: string): {
19
+ failures: number;
20
+ open: boolean;
21
+ phase: BreakerPhase;
22
+ openedAt: number | null;
23
+ cooldownMs: number;
24
+ };
25
+ /** List all agents currently blocked (open or half-open with active probe). */
26
+ listOpen(): string[];
27
+ /**
28
+ * Manually clear breaker state. Pass an agent name to reset just that
29
+ * one, or no argument to reset everything. Useful for an operator
30
+ * `/router reset <agent>` command.
31
+ */
32
+ reset(agent?: string): void;
33
+ private get;
34
+ }
35
+ export declare const circuitBreaker: CircuitBreaker;
36
+ export {};
37
+ //# sourceMappingURL=circuit-breaker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circuit-breaker.d.ts","sourceRoot":"","sources":["../../src/core/circuit-breaker.ts"],"names":[],"mappings":"AAkBA,KAAK,YAAY,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAA;AAUnD,cAAM,cAAc;IAClB,OAAO,CAAC,MAAM,CAAkC;IAChD,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,cAAc,CAAQ;gBAElB,SAAS,SAAoB,EAAE,UAAU,SAAsB;IAK3E,2EAA2E;IAC3E,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAoBrC,2EAA2E;IAC3E,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAIlC;;;;OAIG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAkB9B,sCAAsC;IACtC,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,YAAY,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE;IAW/H,+EAA+E;IAC/E,QAAQ,IAAI,MAAM,EAAE;IAQpB;;;;OAIG;IACH,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAQ3B,OAAO,CAAC,GAAG;CAQZ;AAED,eAAO,MAAM,cAAc,gBAAuB,CAAA"}
@@ -0,0 +1,115 @@
1
+ // Circuit breaker for agent invocations
2
+ //
3
+ // Tracks consecutive failures per agent. State machine:
4
+ // closed → recordFailure ≥ threshold → open
5
+ // open → cooldown elapsed → half-open (1 trial slot)
6
+ // half-open → recordSuccess → closed (failures reset)
7
+ // half-open → recordFailure → open (cooldown × 2, capped)
8
+ //
9
+ // The half-open state is the meaningful upgrade over the previous design,
10
+ // which silently re-closed the breaker on cooldown — a cooldown elapsed
11
+ // AND the next request slipping through were both required for any signal,
12
+ // but if every request hammered through immediately the breaker only
13
+ // briefly hesitated. The new flow grants exactly one probe.
14
+ const DEFAULT_THRESHOLD = 3; // consecutive failures to open
15
+ const DEFAULT_COOLDOWN_MS = 300_000; // 5 minutes
16
+ const MAX_COOLDOWN_MS = 60 * 60_000; // 1 hour cap on exponential backoff
17
+ class CircuitBreaker {
18
+ states = new Map();
19
+ threshold;
20
+ baseCooldownMs;
21
+ constructor(threshold = DEFAULT_THRESHOLD, cooldownMs = DEFAULT_COOLDOWN_MS) {
22
+ this.threshold = threshold;
23
+ this.baseCooldownMs = cooldownMs;
24
+ }
25
+ /** Record a failed invocation. Returns true if the breaker just opened. */
26
+ recordFailure(agent) {
27
+ const s = this.get(agent);
28
+ if (s.phase === 'half-open') {
29
+ // Probe failed → re-open with double cooldown (capped).
30
+ s.phase = 'open';
31
+ s.openedAt = Date.now();
32
+ s.cooldownMs = Math.min(s.cooldownMs * 2, MAX_COOLDOWN_MS);
33
+ // failures count is preserved as a quality signal for /router status
34
+ return true;
35
+ }
36
+ s.failures++;
37
+ if (s.failures >= this.threshold && s.phase === 'closed') {
38
+ s.phase = 'open';
39
+ s.openedAt = Date.now();
40
+ s.cooldownMs = this.baseCooldownMs;
41
+ return true;
42
+ }
43
+ return false;
44
+ }
45
+ /** Record a successful invocation. Closes the breaker, resets counters. */
46
+ recordSuccess(agent) {
47
+ this.states.delete(agent);
48
+ }
49
+ /**
50
+ * Check if an agent is currently blocked (breaker open AND cooldown still
51
+ * active). After cooldown elapses we transition to half-open and *return
52
+ * false for the first caller only* — that caller becomes the probe.
53
+ */
54
+ isOpen(agent) {
55
+ const s = this.states.get(agent);
56
+ if (!s || s.phase === 'closed')
57
+ return false;
58
+ if (s.phase === 'half-open') {
59
+ // Probe slot already granted — block everyone else until the probe
60
+ // returns success or failure.
61
+ return true;
62
+ }
63
+ // phase === 'open'
64
+ if (s.openedAt !== null && Date.now() - s.openedAt > s.cooldownMs) {
65
+ // Cooldown elapsed → grant a single probe. Return false (allow) for
66
+ // this caller, but flip phase so concurrent callers see open.
67
+ s.phase = 'half-open';
68
+ return false;
69
+ }
70
+ return true;
71
+ }
72
+ /** Get status for display / debug. */
73
+ getStatus(agent) {
74
+ const s = this.get(agent);
75
+ return {
76
+ failures: s.failures,
77
+ open: s.phase !== 'closed',
78
+ phase: s.phase,
79
+ openedAt: s.openedAt,
80
+ cooldownMs: s.cooldownMs,
81
+ };
82
+ }
83
+ /** List all agents currently blocked (open or half-open with active probe). */
84
+ listOpen() {
85
+ const open = [];
86
+ for (const [agent, s] of this.states) {
87
+ if (s.phase === 'open' || s.phase === 'half-open')
88
+ open.push(agent);
89
+ }
90
+ return open;
91
+ }
92
+ /**
93
+ * Manually clear breaker state. Pass an agent name to reset just that
94
+ * one, or no argument to reset everything. Useful for an operator
95
+ * `/router reset <agent>` command.
96
+ */
97
+ reset(agent) {
98
+ if (agent === undefined) {
99
+ this.states.clear();
100
+ }
101
+ else {
102
+ this.states.delete(agent);
103
+ }
104
+ }
105
+ get(agent) {
106
+ let s = this.states.get(agent);
107
+ if (!s) {
108
+ s = { phase: 'closed', failures: 0, openedAt: null, cooldownMs: this.baseCooldownMs };
109
+ this.states.set(agent, s);
110
+ }
111
+ return s;
112
+ }
113
+ }
114
+ export const circuitBreaker = new CircuitBreaker();
115
+ //# sourceMappingURL=circuit-breaker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circuit-breaker.js","sourceRoot":"","sources":["../../src/core/circuit-breaker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { RouteContext } from '../router.js';
2
+ import { callAgentWithHistory } from '../router.js';
3
+ export declare function handleAgentCommand(command: string, prompt: string, ctx: RouteContext): Promise<string | ReturnType<typeof callAgentWithHistory>>;
4
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../src/core/commands/agent.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAIhD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AAEnD,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,YAAY,GAChB,OAAO,CAAC,MAAM,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAmB3D"}
@@ -0,0 +1,21 @@
1
+ // Agent commands: /test /review /commit /push /diff /shell /bug /explain
2
+ // These are forwarded to the active agent with the command prefix
3
+ import { registry } from '../registry.js';
4
+ import { sessionManager } from '../session.js';
5
+ import { isAgentAvailableCached, formatAgentNotAvailableError } from '../onboarding.js';
6
+ import { callAgentWithHistory } from '../router.js';
7
+ export async function handleAgentCommand(command, prompt, ctx) {
8
+ const existingSession = await sessionManager.getExistingSession(ctx.platform, ctx.channelId, ctx.threadId);
9
+ const agentName = existingSession?.agent || ctx.defaultAgent;
10
+ const agent = registry.findAgent(agentName);
11
+ if (!agent) {
12
+ return `❌ Agent "${agentName}" not found. Use /agents to see available agents.`;
13
+ }
14
+ if (!(await isAgentAvailableCached(agent.name))) {
15
+ return formatAgentNotAvailableError(agent.name);
16
+ }
17
+ const fullPrompt = `/${command} ${prompt}`.trim();
18
+ const session = await sessionManager.getOrCreateSession(ctx.platform, ctx.channelId, ctx.threadId, agent.name);
19
+ return callAgentWithHistory(agent, session.id, fullPrompt, session.messages, ctx, session.model, session.variant, session.planMode);
20
+ }
21
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../../src/core/commands/agent.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,kEAAkE;AAGlE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,sBAAsB,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAA;AACvF,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AAEnD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAe,EACf,MAAc,EACd,GAAiB;IAEjB,MAAM,eAAe,GAAG,MAAM,cAAc,CAAC,kBAAkB,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAA;IAC1G,MAAM,SAAS,GAAG,eAAe,EAAE,KAAK,IAAI,GAAG,CAAC,YAAY,CAAA;IAE5D,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,SAAS,CAAC,CAAA;IAC3C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,YAAY,SAAS,mDAAmD,CAAA;IACjF,CAAC;IAED,IAAI,CAAC,CAAC,MAAM,sBAAsB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QAChD,OAAO,4BAA4B,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACjD,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,OAAO,IAAI,MAAM,EAAE,CAAC,IAAI,EAAE,CAAA;IAEjD,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,kBAAkB,CACrD,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,CACtD,CAAA;IACD,OAAO,oBAAoB,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAA;AACrI,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { RouteContext } from '../router.js';
2
+ export declare function handleApprovalCommand(args: string, ctx: RouteContext): Promise<string>;
3
+ //# sourceMappingURL=approval.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval.d.ts","sourceRoot":"","sources":["../../../src/core/commands/approval.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAYhD,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,YAAY,GAChB,OAAO,CAAC,MAAM,CAAC,CA0BjB"}
@@ -0,0 +1,44 @@
1
+ // /approval command — list or clear in-session auto-approval rules.
2
+ //
3
+ // /approval — list current auto-allow rules for this thread
4
+ // /approval clear — drop every auto-allow rule for this thread
5
+ //
6
+ // Rules are scoped per (platform, channelId, threadId) — same key the
7
+ // approval-bus uses internally.
8
+ import { approvalBus } from '../approval-bus.js';
9
+ function formatRuleKey(key) {
10
+ // Keys are stored as `${toolName}::${prefix}` — split for prettier rendering.
11
+ const sep = key.indexOf('::');
12
+ if (sep < 0)
13
+ return key;
14
+ const tool = key.slice(0, sep);
15
+ const prefix = key.slice(sep + 2);
16
+ return `• ${tool} 前缀 "${prefix}"`;
17
+ }
18
+ export async function handleApprovalCommand(args, ctx) {
19
+ const sub = args.trim().toLowerCase();
20
+ if (sub === 'clear' || sub === 'reset') {
21
+ const before = approvalBus.getAutoAllowKeys(ctx.threadId);
22
+ approvalBus.clearAutoAllowForThread(ctx.threadId);
23
+ if (before.length === 0)
24
+ return '🧹 当前没有自动放行规则,无需清空。';
25
+ return `🧹 已清空本会话的 ${before.length} 条自动放行规则。`;
26
+ }
27
+ const keys = approvalBus.getAutoAllowKeys(ctx.threadId);
28
+ if (keys.length === 0) {
29
+ return [
30
+ '📋 本会话当前没有自动放行规则。',
31
+ '',
32
+ '在审批提示出现时回复 all(或 全部 / 总是)即可启用:',
33
+ '将以 (工具, 入参前 5 字符) 为粒度,命中后 5s 内自动放行。',
34
+ ].join('\n');
35
+ }
36
+ return [
37
+ `📋 本会话自动放行规则 (${keys.length})`,
38
+ '',
39
+ ...keys.map(formatRuleKey),
40
+ '',
41
+ '撤销:触发审批后回 n(仅撤销该条规则) / /approval clear(全部清空)',
42
+ ].join('\n');
43
+ }
44
+ //# sourceMappingURL=approval.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval.js","sourceRoot":"","sources":["../../../src/core/commands/approval.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,EAAE;AACF,oEAAoE;AACpE,iEAAiE;AACjE,EAAE;AACF,sEAAsE;AACtE,gCAAgC;AAGhC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAEhD,SAAS,aAAa,CAAC,GAAW;IAChC,8EAA8E;IAC9E,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IAC7B,IAAI,GAAG,GAAG,CAAC;QAAE,OAAO,GAAG,CAAA;IACvB,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IAC9B,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAA;IACjC,OAAO,KAAK,IAAI,SAAS,MAAM,GAAG,CAAA;AACpC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,IAAY,EACZ,GAAiB;IAEjB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IAErC,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,WAAW,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QACzD,WAAW,CAAC,uBAAuB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QACjD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,qBAAqB,CAAA;QACrD,OAAO,cAAc,MAAM,CAAC,MAAM,WAAW,CAAA;IAC/C,CAAC;IAED,MAAM,IAAI,GAAG,WAAW,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACvD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO;YACL,mBAAmB;YACnB,EAAE;YACF,gCAAgC;YAChC,qCAAqC;SACtC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACd,CAAC;IACD,OAAO;QACL,iBAAiB,IAAI,CAAC,MAAM,GAAG;QAC/B,EAAE;QACF,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC;QAC1B,EAAE;QACF,8CAA8C;KAC/C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACd,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=approval.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval.test.d.ts","sourceRoot":"","sources":["../../../src/core/commands/approval.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,85 @@
1
+ // /approval command — list / clear in-session auto-allow rules.
2
+ import { describe, it, expect, beforeEach, afterEach } from 'bun:test';
3
+ import { createConnection } from 'net';
4
+ import { tmpdir } from 'os';
5
+ import { join } from 'path';
6
+ import { randomBytes } from 'crypto';
7
+ import { approvalBus } from '../approval-bus.js';
8
+ import { handleApprovalCommand } from './approval.js';
9
+ const RUN_CTX = { threadId: 'thread-X', platform: 'feishu', userId: 'u', channelId: 'c' };
10
+ function makeRouteCtx() {
11
+ return {
12
+ channelId: 'c', threadId: 'thread-X', platform: 'feishu',
13
+ defaultAgent: 'claude-code', traceId: 't',
14
+ logger: { info: () => { }, warn: () => { }, error: () => { }, debug: () => { }, child: () => ({}) },
15
+ };
16
+ }
17
+ function uniqueSocketPath() {
18
+ return join(tmpdir(), `imhub-approval-cmd-test-${process.pid}-${randomBytes(4).toString('hex')}.sock`);
19
+ }
20
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
21
+ async function seedRule(socketPath, runId, reqId, toolName, command) {
22
+ const sock = await new Promise((resolve, reject) => {
23
+ const s = createConnection(socketPath);
24
+ s.once('error', reject);
25
+ s.once('connect', () => resolve(s));
26
+ });
27
+ sock.setEncoding('utf8');
28
+ sock.on('data', () => { });
29
+ sock.write(JSON.stringify({
30
+ v: 1, type: 'approval', runId, reqId, toolName,
31
+ input: { command }, toolUseId: 'tu-' + reqId,
32
+ }) + '\n');
33
+ await sleep(20);
34
+ approvalBus.resolvePending('thread-X', { behavior: 'allow', autoAllowFurther: true });
35
+ return sock;
36
+ }
37
+ describe('handleApprovalCommand', () => {
38
+ let path;
39
+ beforeEach(async () => {
40
+ path = uniqueSocketPath();
41
+ await approvalBus.start(path);
42
+ approvalBus.registerRun('run-X', RUN_CTX);
43
+ approvalBus.setNotifier(async () => { });
44
+ });
45
+ afterEach(async () => {
46
+ approvalBus.clearAutoAllowForThread('thread-X');
47
+ await approvalBus.stop();
48
+ });
49
+ it('reports an empty list when no rules exist', async () => {
50
+ const out = await handleApprovalCommand('', makeRouteCtx());
51
+ expect(out).toContain('没有自动放行规则');
52
+ expect(out).toContain('all');
53
+ });
54
+ it('lists active rules with tool + prefix', async () => {
55
+ const sock1 = await seedRule(path, 'run-X', 'r1', 'Bash', 'git status -s');
56
+ const sock2 = await seedRule(path, 'run-X', 'r2', 'Bash', 'rm -rf /tmp/x');
57
+ // M13: AUTO_ALLOW_PREFIX_LEN bumped 5 → 10 so the rule keys carry
58
+ // 10 characters of the input. `git status -s` is 13 chars, prefix10
59
+ // is `git status`; `rm -rf /tmp/x` is 13 chars, prefix10 is
60
+ // `rm -rf /tm`.
61
+ expect(approvalBus.getAutoAllowKeys('thread-X').sort()).toEqual([
62
+ 'Bash::git status', 'Bash::rm -rf /tm',
63
+ ]);
64
+ const out = await handleApprovalCommand('', makeRouteCtx());
65
+ expect(out).toContain('本会话自动放行规则 (2)');
66
+ expect(out).toContain('Bash');
67
+ expect(out).toContain('git status');
68
+ expect(out).toContain('rm -rf');
69
+ sock1.end();
70
+ sock2.end();
71
+ });
72
+ it('clear on an empty thread reports "no rules to clear"', async () => {
73
+ const out = await handleApprovalCommand('clear', makeRouteCtx());
74
+ expect(out).toContain('当前没有自动放行规则');
75
+ });
76
+ it('clear drops every rule for this thread', async () => {
77
+ const sock = await seedRule(path, 'run-X', 'rc', 'Bash', 'docker ps');
78
+ expect(approvalBus.getAutoAllowKeys('thread-X').length).toBe(1);
79
+ const out = await handleApprovalCommand('clear', makeRouteCtx());
80
+ expect(out).toContain('已清空本会话的 1 条自动放行规则');
81
+ expect(approvalBus.getAutoAllowKeys('thread-X')).toEqual([]);
82
+ sock.end();
83
+ });
84
+ });
85
+ //# sourceMappingURL=approval.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval.test.js","sourceRoot":"","sources":["../../../src/core/commands/approval.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { RouteContext } from '../router.js';
2
+ export declare function handleAuditCommand(args: string, ctx: RouteContext): Promise<string>;
3
+ //# sourceMappingURL=audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../../src/core/commands/audit.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAehD,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,YAAY,GAChB,OAAO,CAAC,MAAM,CAAC,CAmEjB"}