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,374 @@
1
+ // AgentBase — base class for CLI-based agent adapters
2
+ //
3
+ // Provides a unified streaming JSONL invocation pipeline:
4
+ // sendPrompt — true AsyncGenerator that yields chunks live
5
+ // spawnAndCollect — Promise<string> wrapper for job-board / sync calls
6
+ // isAvailable — `--version` probe
7
+ // buildContextualPrompt / buildArgs / extractText — subclass hooks
8
+ //
9
+ // Subclasses must implement: buildArgs(), extractText().
10
+ // Optional override: handleError(), notAvailableMessage(), commandName.
11
+ import { StringDecoder } from 'string_decoder';
12
+ import { crossSpawn } from '../utils/cross-platform.js';
13
+ import { logger as rootLogger } from './logger.js';
14
+ const DEFAULT_TIMEOUT_MS = 30 * 60 * 1000;
15
+ /** Resolve per-agent timeout: env var AGENT_TIMEOUT_MS or class default */
16
+ function resolveTimeout(envKey, fallback) {
17
+ const raw = process.env[envKey];
18
+ if (raw) {
19
+ const n = parseInt(raw, 10);
20
+ if (Number.isFinite(n) && n > 0)
21
+ return n;
22
+ rootLogger.warn({ event: 'agent.timeout.invalid', raw, envKey, fallback }, `Invalid timeout env "${envKey}=${raw}", using default ${Math.round(fallback / 60000)}min`);
23
+ }
24
+ return fallback;
25
+ }
26
+ /**
27
+ * Buffer line splitter that respects UTF-8 multi-byte boundaries.
28
+ *
29
+ * Holds a single `partial` string of bytes seen so far without a newline
30
+ * boundary. push(chunk) returns any complete lines found in
31
+ * partial+chunk, and resets partial to the remainder.
32
+ *
33
+ * Implementation notes:
34
+ * - Uses StringDecoder so a 3-byte CJK codepoint split across chunks
35
+ * stays whole (no U+FFFD).
36
+ * - Skips the partial+chunk concat when the chunk has no newline AND
37
+ * partial is empty (the common case for tiny chunks).
38
+ * - Walks via indexOf + slice instead of String.split so we avoid
39
+ * allocating an intermediate array of every line just to pop the
40
+ * last one back into partial.
41
+ */
42
+ class LineBuffer {
43
+ decoder = new StringDecoder('utf8');
44
+ partial = '';
45
+ push(chunk) {
46
+ const decoded = this.decoder.write(chunk);
47
+ if (!decoded)
48
+ return [];
49
+ if (decoded.indexOf('\n') === -1) {
50
+ // No newline in this chunk — extend partial. V8 ropes strings, so
51
+ // the concat is amortized O(1) here.
52
+ this.partial += decoded;
53
+ return [];
54
+ }
55
+ const data = this.partial.length === 0 ? decoded : this.partial + decoded;
56
+ const out = [];
57
+ let start = 0;
58
+ let nl;
59
+ while ((nl = data.indexOf('\n', start)) !== -1) {
60
+ out.push(data.slice(start, nl));
61
+ start = nl + 1;
62
+ }
63
+ this.partial = start < data.length ? data.slice(start) : '';
64
+ return out;
65
+ }
66
+ flush() {
67
+ const tail = this.decoder.end();
68
+ const data = this.partial.length === 0 ? tail : this.partial + tail;
69
+ this.partial = '';
70
+ if (data.length === 0)
71
+ return [];
72
+ const out = [];
73
+ let start = 0;
74
+ let nl;
75
+ while ((nl = data.indexOf('\n', start)) !== -1) {
76
+ if (nl > start)
77
+ out.push(data.slice(start, nl));
78
+ start = nl + 1;
79
+ }
80
+ if (start < data.length)
81
+ out.push(data.slice(start));
82
+ return out;
83
+ }
84
+ }
85
+ export class AgentBase {
86
+ /** Binary name to check for isAvailable */
87
+ get commandName() { return this.name; }
88
+ /**
89
+ * Returns a complete spawn plan. Default implementation just wraps
90
+ * buildArgs(). Subclasses needing per-call temp resources (mcp-config
91
+ * file, registered run id, etc.) should override and put ALL derived
92
+ * state inside the returned plan / closure — never on `this`, since
93
+ * concurrent spawns would race.
94
+ */
95
+ async prepareCommand(prompt, opts) {
96
+ return { args: this.buildArgs(prompt, opts) };
97
+ }
98
+ /**
99
+ * Optional side-channel hook fired for every parsed JSONL event before
100
+ * extractText. Default no-op. Used by adapters whose CLI surfaces metadata
101
+ * (session id, cost, token counts) inline with content events — they
102
+ * dispatch back to the caller via `opts.onAgentSessionId` / `opts.onUsage`.
103
+ *
104
+ * Keep it cheap: this runs on the hot stdout path. No network or disk.
105
+ */
106
+ inspectEvent(_event, _opts) { }
107
+ /** Optional: transform error info into a user-friendly message string (resolved instead of rejected). */
108
+ handleError(_code, _stderr, _errorMessage) {
109
+ return null; // default: reject
110
+ }
111
+ /** Optional: return user-friendly unavailable message. */
112
+ notAvailableMessage() {
113
+ return `${this.name} CLI not found. Please install it.`;
114
+ }
115
+ async isAvailable() {
116
+ return new Promise((resolve) => {
117
+ const proc = crossSpawn(this.commandName, ['--version'], { stdio: 'ignore' });
118
+ proc.on('close', (code) => resolve(code === 0));
119
+ proc.on('error', () => resolve(false));
120
+ });
121
+ }
122
+ /** Lightweight health probe (same as isAvailable for CLI agents). */
123
+ async healthCheck() {
124
+ const start = Date.now();
125
+ const ok = await this.isAvailable();
126
+ return { ok, latencyMs: Date.now() - start };
127
+ }
128
+ /**
129
+ * Stream JSONL chunks live. Yields each `extractText` result as it
130
+ * arrives; on non-zero exit, yields the friendly error tail (if any) and
131
+ * returns.
132
+ */
133
+ async *sendPrompt(_sessionId, prompt, history, opts) {
134
+ rootLogger.info({ component: `agent.${this.name}`, agent: this.name, historyLen: history?.length || 0 }, `[${this.name}] sendPrompt`);
135
+ const contextualPrompt = this.buildContextualPrompt(prompt, history);
136
+ yield* this.spawnStream(contextualPrompt, undefined, opts || {});
137
+ }
138
+ /**
139
+ * Build prompt with conversation history context.
140
+ * Subclasses may override for custom formatting.
141
+ */
142
+ buildContextualPrompt(prompt, history) {
143
+ if (!history || history.length === 0) {
144
+ return prompt;
145
+ }
146
+ const historyText = history
147
+ .map(msg => `[${msg.role === 'user' ? 'User' : 'Assistant'}]: ${msg.content}`)
148
+ .join('\n\n');
149
+ return `Previous conversation context:\n${historyText}\n\nCurrent request: ${prompt}`;
150
+ }
151
+ /** Per-agent timeout in ms. Override or set env var (upper-case name + _TIMEOUT_MS). */
152
+ get timeoutMs() {
153
+ return resolveTimeout(`${this.name.toUpperCase()}_TIMEOUT_MS`, DEFAULT_TIMEOUT_MS);
154
+ }
155
+ /**
156
+ * Sync convenience wrapper: drain the streaming generator into a single
157
+ * string. Used by Job Board where the caller wants the final result.
158
+ */
159
+ async spawnAndCollect(prompt, signal) {
160
+ let acc = '';
161
+ for await (const chunk of this.spawnStream(prompt, signal, {})) {
162
+ acc += chunk;
163
+ }
164
+ return acc;
165
+ }
166
+ /**
167
+ * Core streaming pipeline: spawn the CLI, parse JSONL line-by-line, yield
168
+ * each extracted text fragment. Handles timeout, abort, and process exit
169
+ * with cleanup of all timers and listeners.
170
+ */
171
+ async *spawnStream(prompt, signal, opts = {}) {
172
+ const timeout = this.timeoutMs;
173
+ // prepareCommand returns a self-contained plan — args, optional extra env,
174
+ // optional cleanup. No instance state involved, so concurrent spawnStream
175
+ // calls cannot race each other. (Previously setupSpawn() would mutate
176
+ // this.mcpConfigPath etc. between awaits, leading to two parallel claude
177
+ // runs sharing one mcp.json and the second one finding it already deleted.)
178
+ let plan;
179
+ try {
180
+ plan = await this.prepareCommand(prompt, opts);
181
+ }
182
+ catch (err) {
183
+ throw err;
184
+ }
185
+ const proc = crossSpawn(this.commandName, plan.args, {
186
+ stdio: ['ignore', 'pipe', 'pipe'],
187
+ env: plan.extraEnv ? { ...process.env, ...plan.extraEnv } : undefined,
188
+ cwd: plan.cwd,
189
+ });
190
+ const buf = new LineBuffer();
191
+ const stderrBuf = new LineBuffer();
192
+ let stderrAccum = '';
193
+ let errorMessage = '';
194
+ let pendingChunks = [];
195
+ let closed = false;
196
+ let exitCode = null;
197
+ let spawnError = null;
198
+ let timedOut = false;
199
+ let aborted = false;
200
+ // Each `notify` resolves the current poll cycle; the consumer awaits a
201
+ // promise that flips whenever new state is available.
202
+ let notify = null;
203
+ const wait = () => new Promise((resolve) => { notify = resolve; });
204
+ const ping = () => { const n = notify; notify = null; n?.(); };
205
+ const timer = setTimeout(() => {
206
+ timedOut = true;
207
+ try {
208
+ proc.kill('SIGTERM');
209
+ }
210
+ catch { /* ignore */ }
211
+ ping();
212
+ }, timeout);
213
+ let killTimer = null;
214
+ const scheduleKill = () => {
215
+ if (killTimer)
216
+ return;
217
+ killTimer = setTimeout(() => {
218
+ try {
219
+ proc.kill('SIGKILL');
220
+ }
221
+ catch { /* ignore */ }
222
+ }, 5000);
223
+ };
224
+ const onAbort = () => {
225
+ aborted = true;
226
+ try {
227
+ proc.kill('SIGTERM');
228
+ }
229
+ catch { /* ignore */ }
230
+ scheduleKill();
231
+ ping();
232
+ };
233
+ if (signal) {
234
+ if (signal.aborted) {
235
+ onAbort();
236
+ }
237
+ else {
238
+ signal.addEventListener('abort', onAbort, { once: true });
239
+ }
240
+ }
241
+ proc.stdout?.on('data', (data) => {
242
+ const lines = buf.push(data);
243
+ for (const line of lines) {
244
+ if (!line.trim())
245
+ continue;
246
+ try {
247
+ const event = JSON.parse(line);
248
+ if (event && typeof event === 'object' && event.type === 'error') {
249
+ const e = event;
250
+ errorMessage = e.error || e.message || 'error event';
251
+ // Don't yield error event content alongside extractText
252
+ continue;
253
+ }
254
+ this.inspectEvent(event, opts);
255
+ const text = this.extractText(event);
256
+ if (text)
257
+ pendingChunks.push(text);
258
+ }
259
+ catch {
260
+ // Non-JSON line — pass through verbatim with newline preserved
261
+ pendingChunks.push(line + '\n');
262
+ }
263
+ }
264
+ if (pendingChunks.length > 0)
265
+ ping();
266
+ });
267
+ proc.stderr?.on('data', (data) => {
268
+ stderrAccum += data.toString();
269
+ // Surface to root logger as warn — pino-aware, no console.error noise
270
+ for (const line of stderrBuf.push(data)) {
271
+ if (line.trim()) {
272
+ rootLogger.warn({ component: `agent.${this.name}`, agent: this.name, stderr: line }, `[${this.name}] stderr`);
273
+ }
274
+ }
275
+ });
276
+ proc.on('error', (err) => {
277
+ spawnError = err;
278
+ closed = true;
279
+ ping();
280
+ });
281
+ proc.on('close', (code) => {
282
+ exitCode = code;
283
+ closed = true;
284
+ // Flush any remaining stderr line
285
+ for (const line of stderrBuf.flush()) {
286
+ if (line.trim()) {
287
+ rootLogger.warn({ component: `agent.${this.name}`, agent: this.name, stderr: line }, `[${this.name}] stderr`);
288
+ }
289
+ }
290
+ // Flush any non-newline-terminated tail in stdout buffer
291
+ for (const line of buf.flush()) {
292
+ try {
293
+ const event = JSON.parse(line);
294
+ const text = this.extractText(event);
295
+ if (text)
296
+ pendingChunks.push(text);
297
+ }
298
+ catch {
299
+ pendingChunks.push(line);
300
+ }
301
+ }
302
+ ping();
303
+ });
304
+ try {
305
+ while (!closed || pendingChunks.length > 0) {
306
+ if (pendingChunks.length === 0) {
307
+ await wait();
308
+ if (aborted)
309
+ break;
310
+ if (timedOut)
311
+ break;
312
+ }
313
+ // Drain whatever has accumulated this cycle
314
+ const out = pendingChunks;
315
+ pendingChunks = [];
316
+ for (const c of out)
317
+ yield c;
318
+ }
319
+ if (timedOut) {
320
+ const mins = Math.round(timeout / 60000);
321
+ rootLogger.warn({ component: `agent.${this.name}`, agent: this.name, timeoutMs: timeout }, `[${this.name}] timeout after ${mins}min`);
322
+ yield `\n\n⚠️ 处理超时(已超过 ${mins} 分钟)`;
323
+ return;
324
+ }
325
+ if (aborted) {
326
+ rootLogger.info({ component: `agent.${this.name}`, agent: this.name }, `[${this.name}] cancelled via signal`);
327
+ yield '\n\n🚫 任务已被取消。';
328
+ return;
329
+ }
330
+ if (spawnError) {
331
+ throw spawnError;
332
+ }
333
+ rootLogger.info({
334
+ component: `agent.${this.name}`,
335
+ agent: this.name,
336
+ exitCode,
337
+ }, `[${this.name}] process closed`);
338
+ if (exitCode !== null && exitCode !== 0) {
339
+ const friendly = this.handleError(exitCode, stderrAccum, errorMessage);
340
+ if (friendly !== null) {
341
+ yield friendly;
342
+ return;
343
+ }
344
+ let detail = '';
345
+ if (errorMessage)
346
+ detail = errorMessage;
347
+ if (!detail && stderrAccum.trim() && stderrAccum.trim().length < 200) {
348
+ detail = stderrAccum.trim();
349
+ }
350
+ yield `${this.name} failed (exit ${exitCode})${detail ? ': ' + detail : ''}`;
351
+ }
352
+ }
353
+ finally {
354
+ clearTimeout(timer);
355
+ if (killTimer)
356
+ clearTimeout(killTimer);
357
+ if (signal)
358
+ signal.removeEventListener('abort', onAbort);
359
+ if (plan.cleanup) {
360
+ try {
361
+ await plan.cleanup();
362
+ }
363
+ catch (err) {
364
+ // L13: surface to /api/metrics in addition to pino so ops can
365
+ // alert on cumulative cleanup failures (orphan tmpdir leakage).
366
+ const { recordAgentCleanupFailure } = await import('./metrics.js');
367
+ recordAgentCleanupFailure();
368
+ rootLogger.warn({ component: `agent.${this.name}`, agent: this.name, err: String(err) }, `[${this.name}] cleanup hook threw`);
369
+ }
370
+ }
371
+ }
372
+ }
373
+ }
374
+ //# sourceMappingURL=agent-base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-base.js","sourceRoot":"","sources":["../../src/core/agent-base.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import type { AgentSendOpts } from './types.js';
2
+ /** Root for all per-agent IM workspaces. Kept stable so memory persists. */
3
+ export declare function imhubWorkspacesRoot(): string;
4
+ /** Default cwd for a given agent under the workspaces root. */
5
+ export declare function defaultAgentCwd(agentName: string): string;
6
+ /**
7
+ * Resolve the cwd to spawn an agent CLI in.
8
+ *
9
+ * Decision order:
10
+ * 1. Env override `IMHUB_<AGENT>_CWD` always wins.
11
+ * 2. If we're in an IM context (threadId + platform both present), pin to
12
+ * `~/.im-hub-workspaces/<agent>/`.
13
+ * 3. Otherwise return undefined → adapter inherits im-hub's cwd. This
14
+ * keeps web/scheduler/intent-llm judge paths exactly as they were.
15
+ */
16
+ export declare function resolveAgentCwd(agentName: string, opts: AgentSendOpts): string | undefined;
17
+ /**
18
+ * Idempotent: create the workspace dir and seed initial CLAUDE.md / AGENTS.md
19
+ * if they don't exist. Existing files are NEVER overwritten — the user is free
20
+ * to evolve them by hand or have the agent itself rewrite them via
21
+ * auto-memory.
22
+ *
23
+ * Honors IMHUB_<AGENT>_CWD overrides — if set, we bootstrap THAT path
24
+ * instead. Skips bootstrapping when the override is empty / unset and we
25
+ * compute it from defaultAgentCwd; either way the resolved path is what
26
+ * spawnStream will pass as cwd.
27
+ */
28
+ export declare function ensureAgentWorkspace(agentName: string, seed: {
29
+ filename: string;
30
+ content: string;
31
+ }): Promise<string>;
32
+ /**
33
+ * Bootstrap the workspaces for the two built-in CLI agents we ship by
34
+ * default. Safe to call multiple times. Returns a summary suitable for
35
+ * logging.
36
+ *
37
+ * Other agents (codex, copilot, ACP-imported) don't need cwd isolation
38
+ * either because they don't have per-cwd memory, or because they're
39
+ * remote — they'll pass through with cwd undefined like before.
40
+ */
41
+ export declare function bootstrapAgentWorkspaces(): Promise<Array<{
42
+ agent: string;
43
+ dir: string;
44
+ }>>;
45
+ //# sourceMappingURL=agent-cwd.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-cwd.d.ts","sourceRoot":"","sources":["../../src/core/agent-cwd.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/C,4EAA4E;AAC5E,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED,+DAA+D;AAC/D,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEzD;AAQD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,MAAM,GAAG,SAAS,CAS1F;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC1C,OAAO,CAAC,MAAM,CAAC,CAcjB;AAED;;;;;;;;GAQG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CA8F/F"}
@@ -0,0 +1,178 @@
1
+ // Per-agent working directory resolution for the IM context.
2
+ //
3
+ // Both Claude Code and opencode key their per-project memory / history off
4
+ // the spawned process's cwd. When im-hub runs as a systemd service, that cwd
5
+ // is "/" — so every IM thread, every direct-terminal session, and every
6
+ // background scheduler tick all share the SAME global memory bucket. This
7
+ // is the root cause of:
8
+ //
9
+ // - The IM-only Claude not being able to carry a distinct CLAUDE.md role
10
+ // - The user's terminal MEMORY.md getting polluted by IM auto-saves
11
+ // - opencode's AGENTS.md being unable to differ between IM and terminal
12
+ //
13
+ // Fix: when we detect we're in an IM call (threadId + platform both set),
14
+ // pin the agent into a stable per-agent workspace under
15
+ // `~/.im-hub-workspaces/<agent>/`. Non-IM calls (web UI, scheduler,
16
+ // intent-llm judge) keep the inherited cwd, preserving prior behavior.
17
+ //
18
+ // Override path: `IMHUB_<AGENT>_CWD` env var beats everything (e.g.
19
+ // `IMHUB_CLAUDE_CODE_CWD=/srv/foo`). Useful for migration tests and for
20
+ // future per-tenant deployments.
21
+ import { homedir } from 'os';
22
+ import { join } from 'path';
23
+ import { mkdir, writeFile, access } from 'fs/promises';
24
+ /** Root for all per-agent IM workspaces. Kept stable so memory persists. */
25
+ export function imhubWorkspacesRoot() {
26
+ return process.env.IMHUB_WORKSPACES_ROOT || join(homedir(), '.im-hub-workspaces');
27
+ }
28
+ /** Default cwd for a given agent under the workspaces root. */
29
+ export function defaultAgentCwd(agentName) {
30
+ return join(imhubWorkspacesRoot(), agentName);
31
+ }
32
+ /** Env var name for an explicit override on a given agent. */
33
+ function envKeyFor(agentName) {
34
+ // claude-code -> IMHUB_CLAUDE_CODE_CWD
35
+ return `IMHUB_${agentName.replace(/-/g, '_').toUpperCase()}_CWD`;
36
+ }
37
+ /**
38
+ * Resolve the cwd to spawn an agent CLI in.
39
+ *
40
+ * Decision order:
41
+ * 1. Env override `IMHUB_<AGENT>_CWD` always wins.
42
+ * 2. If we're in an IM context (threadId + platform both present), pin to
43
+ * `~/.im-hub-workspaces/<agent>/`.
44
+ * 3. Otherwise return undefined → adapter inherits im-hub's cwd. This
45
+ * keeps web/scheduler/intent-llm judge paths exactly as they were.
46
+ */
47
+ export function resolveAgentCwd(agentName, opts) {
48
+ const explicit = process.env[envKeyFor(agentName)];
49
+ if (explicit)
50
+ return explicit;
51
+ if (opts.threadId && opts.platform) {
52
+ return defaultAgentCwd(agentName);
53
+ }
54
+ return undefined;
55
+ }
56
+ /**
57
+ * Idempotent: create the workspace dir and seed initial CLAUDE.md / AGENTS.md
58
+ * if they don't exist. Existing files are NEVER overwritten — the user is free
59
+ * to evolve them by hand or have the agent itself rewrite them via
60
+ * auto-memory.
61
+ *
62
+ * Honors IMHUB_<AGENT>_CWD overrides — if set, we bootstrap THAT path
63
+ * instead. Skips bootstrapping when the override is empty / unset and we
64
+ * compute it from defaultAgentCwd; either way the resolved path is what
65
+ * spawnStream will pass as cwd.
66
+ */
67
+ export async function ensureAgentWorkspace(agentName, seed) {
68
+ const explicit = process.env[envKeyFor(agentName)];
69
+ const dir = explicit || defaultAgentCwd(agentName);
70
+ await mkdir(dir, { recursive: true });
71
+ const seedPath = join(dir, seed.filename);
72
+ try {
73
+ await access(seedPath);
74
+ // already exists — leave the user's customizations alone
75
+ }
76
+ catch {
77
+ await writeFile(seedPath, seed.content, 'utf8');
78
+ }
79
+ return dir;
80
+ }
81
+ /**
82
+ * Bootstrap the workspaces for the two built-in CLI agents we ship by
83
+ * default. Safe to call multiple times. Returns a summary suitable for
84
+ * logging.
85
+ *
86
+ * Other agents (codex, copilot, ACP-imported) don't need cwd isolation
87
+ * either because they don't have per-cwd memory, or because they're
88
+ * remote — they'll pass through with cwd undefined like before.
89
+ */
90
+ export async function bootstrapAgentWorkspaces() {
91
+ const result = [];
92
+ const claudeSeed = `# Claude Code — IM 入口工作区
93
+
94
+ > 这是 im-hub 通过 IM 唤起 Claude Code 时的专用工作目录。
95
+ > 与你直接在终端里跑 \`claude\` 时使用的全局配置 (~/.claude/CLAUDE.md) 隔离。
96
+ >
97
+ > 文件位置:${defaultAgentCwd('claude-code')}/CLAUDE.md
98
+
99
+ ## 角色
100
+
101
+ 你是被 IM 入口(微信 / Telegram / Feishu / Discord 等)唤起的 Claude Code。
102
+ 回复要简洁、可在 IM 里阅读,避免大段代码块除非用户明确要求代码。
103
+
104
+ ## 长期项目记忆
105
+
106
+ - 你自己的 auto-memory 落在本目录的 \`memory/MEMORY.md\`
107
+ - 长期项目档案手写在本目录下,由 Claude 自己读取与维护
108
+ - 与终端里的 Claude 互不干扰,可以分头记录不同侧重
109
+
110
+ ## 注意
111
+
112
+ - 当前 cwd 不是真正的代码仓库;要查代码请去 /root/workspace/...
113
+ - IM 单条消息的硬超时是 30 分钟(im-hub 层),长任务必须走 bgjob
114
+ `;
115
+ result.push({
116
+ agent: 'claude-code',
117
+ dir: await ensureAgentWorkspace('claude-code', { filename: 'CLAUDE.md', content: claudeSeed }),
118
+ });
119
+ const opencodeSeed = `# OpenCode — IM 入口工作区
120
+
121
+ > 这是 im-hub 通过 IM 唤起 opencode 时的专用工作目录。
122
+ > 与你直接在终端里跑 \`opencode\` 时使用的全局配置 (~/.config/opencode/AGENTS.md) 隔离。
123
+ >
124
+ > 文件位置:${defaultAgentCwd('opencode')}/AGENTS.md
125
+
126
+ ## 角色
127
+
128
+ 你是被 IM 入口(微信 / Telegram / Feishu / Discord 等)唤起的 opencode。
129
+ 回复要简洁、可在 IM 里阅读,避免大段代码块除非用户明确要求代码。
130
+
131
+ ## 长期项目记忆
132
+
133
+ - 长期项目档案手写在本目录下的 PROJECT.md,由 opencode 自己读取与维护
134
+ - 与终端里的 opencode 互不干扰,可以分头记录不同侧重
135
+
136
+ ## 注意
137
+
138
+ - 当前 cwd 不是真正的代码仓库;要查代码请去 /root/workspace/...
139
+ - IM 单条消息的硬超时是 30 分钟(im-hub 层),长任务必须走 bgjob
140
+ `;
141
+ result.push({
142
+ agent: 'opencode',
143
+ dir: await ensureAgentWorkspace('opencode', { filename: 'AGENTS.md', content: opencodeSeed }),
144
+ });
145
+ const codexSeed = `# Codex — IM 入口工作区
146
+
147
+ > 这是 im-hub 通过 IM 唤起 OpenAI Codex CLI 时的专用工作目录。
148
+ > 与你直接在终端里跑 \`codex\` 时使用的全局配置 (~/.codex/config.toml) 隔离。
149
+ >
150
+ > 文件位置:${defaultAgentCwd('codex')}/AGENTS.md
151
+
152
+ ## 角色
153
+
154
+ 你是被 IM 入口(微信 / Telegram / Feishu / Discord 等)唤起的 Codex。
155
+ 回复要简洁、可在 IM 里阅读,避免大段代码块除非用户明确要求代码。
156
+
157
+ ## 长期项目记忆
158
+
159
+ - 长期项目档案手写在本目录下(PROJECT.md 或自定义文件名)
160
+ - 本目录下的 \`memory/\` 目录用于手写笔记,与 Claude / opencode 工作区互不干扰
161
+ - 与终端里的 codex 互不干扰,可以分头记录不同侧重
162
+
163
+ ## 注意
164
+
165
+ - 当前 cwd 不是真正的代码仓库;要查代码请去 /root/workspace/...
166
+ - IM 单条消息的硬超时是 30 分钟(im-hub 层),长任务必须走 bgjob
167
+ - bgjob 数据目录:~/.codex/bgjobs/(与 claude / opencode 隔离)
168
+ 使用方式:\`/root/.codex/scripts/bgjob start <name> -- <cmd...>\`
169
+ - AGENTS.md 与 opencode 同名但工作区分离 —— codex 只读本目录的 AGENTS.md,
170
+ 不会读 ~/.im-hub-workspaces/opencode/AGENTS.md
171
+ `;
172
+ result.push({
173
+ agent: 'codex',
174
+ dir: await ensureAgentWorkspace('codex', { filename: 'AGENTS.md', content: codexSeed }),
175
+ });
176
+ return result;
177
+ }
178
+ //# sourceMappingURL=agent-cwd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-cwd.js","sourceRoot":"","sources":["../../src/core/agent-cwd.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=agent-cwd.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-cwd.test.d.ts","sourceRoot":"","sources":["../../src/core/agent-cwd.test.ts"],"names":[],"mappings":""}