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.
- package/LICENSE +21 -0
- package/README.md +497 -0
- package/README.zh-CN.md +496 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +921 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/acp-server.d.ts +8 -0
- package/dist/core/acp-server.d.ts.map +1 -0
- package/dist/core/acp-server.js +266 -0
- package/dist/core/acp-server.js.map +1 -0
- package/dist/core/agent-base.d.ts +94 -0
- package/dist/core/agent-base.d.ts.map +1 -0
- package/dist/core/agent-base.js +374 -0
- package/dist/core/agent-base.js.map +1 -0
- package/dist/core/agent-cwd.d.ts +45 -0
- package/dist/core/agent-cwd.d.ts.map +1 -0
- package/dist/core/agent-cwd.js +178 -0
- package/dist/core/agent-cwd.js.map +1 -0
- package/dist/core/agent-cwd.test.d.ts +2 -0
- package/dist/core/agent-cwd.test.d.ts.map +1 -0
- package/dist/core/agent-cwd.test.js +149 -0
- package/dist/core/agent-cwd.test.js.map +1 -0
- package/dist/core/approval-bus.d.ts +232 -0
- package/dist/core/approval-bus.d.ts.map +1 -0
- package/dist/core/approval-bus.js +703 -0
- package/dist/core/approval-bus.js.map +1 -0
- package/dist/core/approval-bus.synthetic.test.d.ts +2 -0
- package/dist/core/approval-bus.synthetic.test.d.ts.map +1 -0
- package/dist/core/approval-bus.synthetic.test.js +182 -0
- package/dist/core/approval-bus.synthetic.test.js.map +1 -0
- package/dist/core/approval-bus.test.d.ts +2 -0
- package/dist/core/approval-bus.test.d.ts.map +1 -0
- package/dist/core/approval-bus.test.js +537 -0
- package/dist/core/approval-bus.test.js.map +1 -0
- package/dist/core/approval-router.d.ts +95 -0
- package/dist/core/approval-router.d.ts.map +1 -0
- package/dist/core/approval-router.js +450 -0
- package/dist/core/approval-router.js.map +1 -0
- package/dist/core/approval-router.test.d.ts +2 -0
- package/dist/core/approval-router.test.d.ts.map +1 -0
- package/dist/core/approval-router.test.js +413 -0
- package/dist/core/approval-router.test.js.map +1 -0
- package/dist/core/audit-log.d.ts +55 -0
- package/dist/core/audit-log.d.ts.map +1 -0
- package/dist/core/audit-log.js +203 -0
- package/dist/core/audit-log.js.map +1 -0
- package/dist/core/bgjob-reader.d.ts +65 -0
- package/dist/core/bgjob-reader.d.ts.map +1 -0
- package/dist/core/bgjob-reader.js +212 -0
- package/dist/core/bgjob-reader.js.map +1 -0
- package/dist/core/bgjob-reader.test.d.ts +2 -0
- package/dist/core/bgjob-reader.test.d.ts.map +1 -0
- package/dist/core/bgjob-reader.test.js +178 -0
- package/dist/core/bgjob-reader.test.js.map +1 -0
- package/dist/core/circuit-breaker.d.ts +37 -0
- package/dist/core/circuit-breaker.d.ts.map +1 -0
- package/dist/core/circuit-breaker.js +115 -0
- package/dist/core/circuit-breaker.js.map +1 -0
- package/dist/core/commands/agent.d.ts +4 -0
- package/dist/core/commands/agent.d.ts.map +1 -0
- package/dist/core/commands/agent.js +21 -0
- package/dist/core/commands/agent.js.map +1 -0
- package/dist/core/commands/approval.d.ts +3 -0
- package/dist/core/commands/approval.d.ts.map +1 -0
- package/dist/core/commands/approval.js +44 -0
- package/dist/core/commands/approval.js.map +1 -0
- package/dist/core/commands/approval.test.d.ts +2 -0
- package/dist/core/commands/approval.test.d.ts.map +1 -0
- package/dist/core/commands/approval.test.js +85 -0
- package/dist/core/commands/approval.test.js.map +1 -0
- package/dist/core/commands/audit.d.ts +3 -0
- package/dist/core/commands/audit.d.ts.map +1 -0
- package/dist/core/commands/audit.js +84 -0
- package/dist/core/commands/audit.js.map +1 -0
- package/dist/core/commands/builtin.d.ts +3 -0
- package/dist/core/commands/builtin.d.ts.map +1 -0
- package/dist/core/commands/builtin.js +26 -0
- package/dist/core/commands/builtin.js.map +1 -0
- package/dist/core/commands/job.d.ts +3 -0
- package/dist/core/commands/job.d.ts.map +1 -0
- package/dist/core/commands/job.js +195 -0
- package/dist/core/commands/job.js.map +1 -0
- package/dist/core/commands/model.d.ts +9 -0
- package/dist/core/commands/model.d.ts.map +1 -0
- package/dist/core/commands/model.js +183 -0
- package/dist/core/commands/model.js.map +1 -0
- package/dist/core/commands/plan.d.ts +3 -0
- package/dist/core/commands/plan.d.ts.map +1 -0
- package/dist/core/commands/plan.js +75 -0
- package/dist/core/commands/plan.js.map +1 -0
- package/dist/core/commands/plan.test.d.ts +2 -0
- package/dist/core/commands/plan.test.d.ts.map +1 -0
- package/dist/core/commands/plan.test.js +122 -0
- package/dist/core/commands/plan.test.js.map +1 -0
- package/dist/core/commands/router.d.ts +3 -0
- package/dist/core/commands/router.d.ts.map +1 -0
- package/dist/core/commands/router.js +71 -0
- package/dist/core/commands/router.js.map +1 -0
- package/dist/core/commands/schedule.d.ts +3 -0
- package/dist/core/commands/schedule.d.ts.map +1 -0
- package/dist/core/commands/schedule.js +123 -0
- package/dist/core/commands/schedule.js.map +1 -0
- package/dist/core/commands/sessions.d.ts +3 -0
- package/dist/core/commands/sessions.d.ts.map +1 -0
- package/dist/core/commands/sessions.js +88 -0
- package/dist/core/commands/sessions.js.map +1 -0
- package/dist/core/commands/stats.d.ts +3 -0
- package/dist/core/commands/stats.d.ts.map +1 -0
- package/dist/core/commands/stats.js +73 -0
- package/dist/core/commands/stats.js.map +1 -0
- package/dist/core/commands/think.d.ts +3 -0
- package/dist/core/commands/think.d.ts.map +1 -0
- package/dist/core/commands/think.js +28 -0
- package/dist/core/commands/think.js.map +1 -0
- package/dist/core/commands/workspaces.d.ts +3 -0
- package/dist/core/commands/workspaces.d.ts.map +1 -0
- package/dist/core/commands/workspaces.js +47 -0
- package/dist/core/commands/workspaces.js.map +1 -0
- package/dist/core/config-schema.d.ts +58 -0
- package/dist/core/config-schema.d.ts.map +1 -0
- package/dist/core/config-schema.js +63 -0
- package/dist/core/config-schema.js.map +1 -0
- package/dist/core/cron.d.ts +29 -0
- package/dist/core/cron.d.ts.map +1 -0
- package/dist/core/cron.js +184 -0
- package/dist/core/cron.js.map +1 -0
- package/dist/core/event-bus.d.ts +80 -0
- package/dist/core/event-bus.d.ts.map +1 -0
- package/dist/core/event-bus.js +62 -0
- package/dist/core/event-bus.js.map +1 -0
- package/dist/core/intent-llm.d.ts +27 -0
- package/dist/core/intent-llm.d.ts.map +1 -0
- package/dist/core/intent-llm.js +170 -0
- package/dist/core/intent-llm.js.map +1 -0
- package/dist/core/intent.d.ts +12 -0
- package/dist/core/intent.d.ts.map +1 -0
- package/dist/core/intent.js +187 -0
- package/dist/core/intent.js.map +1 -0
- package/dist/core/job-board.d.ts +84 -0
- package/dist/core/job-board.d.ts.map +1 -0
- package/dist/core/job-board.js +379 -0
- package/dist/core/job-board.js.map +1 -0
- package/dist/core/logger.d.ts +6 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +54 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/metrics.d.ts +55 -0
- package/dist/core/metrics.d.ts.map +1 -0
- package/dist/core/metrics.js +291 -0
- package/dist/core/metrics.js.map +1 -0
- package/dist/core/onboarding.d.ts +94 -0
- package/dist/core/onboarding.d.ts.map +1 -0
- package/dist/core/onboarding.js +426 -0
- package/dist/core/onboarding.js.map +1 -0
- package/dist/core/onboarding.test.d.ts +2 -0
- package/dist/core/onboarding.test.d.ts.map +1 -0
- package/dist/core/onboarding.test.js +112 -0
- package/dist/core/onboarding.test.js.map +1 -0
- package/dist/core/rate-limiter.d.ts +44 -0
- package/dist/core/rate-limiter.d.ts.map +1 -0
- package/dist/core/rate-limiter.js +115 -0
- package/dist/core/rate-limiter.js.map +1 -0
- package/dist/core/registry.d.ts +32 -0
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/core/registry.js +122 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/core/router.d.ts +41 -0
- package/dist/core/router.d.ts.map +1 -0
- package/dist/core/router.js +431 -0
- package/dist/core/router.js.map +1 -0
- package/dist/core/schedule.d.ts +65 -0
- package/dist/core/schedule.d.ts.map +1 -0
- package/dist/core/schedule.js +316 -0
- package/dist/core/schedule.js.map +1 -0
- package/dist/core/session-subtasks.test.d.ts +2 -0
- package/dist/core/session-subtasks.test.d.ts.map +1 -0
- package/dist/core/session-subtasks.test.js +88 -0
- package/dist/core/session-subtasks.test.js.map +1 -0
- package/dist/core/session.d.ts +182 -0
- package/dist/core/session.d.ts.map +1 -0
- package/dist/core/session.js +774 -0
- package/dist/core/session.js.map +1 -0
- package/dist/core/sqlite-helper.d.ts +37 -0
- package/dist/core/sqlite-helper.d.ts.map +1 -0
- package/dist/core/sqlite-helper.js +79 -0
- package/dist/core/sqlite-helper.js.map +1 -0
- package/dist/core/transcribe.d.ts +25 -0
- package/dist/core/transcribe.d.ts.map +1 -0
- package/dist/core/transcribe.js +217 -0
- package/dist/core/transcribe.js.map +1 -0
- package/dist/core/transcribe.test.d.ts +2 -0
- package/dist/core/transcribe.test.d.ts.map +1 -0
- package/dist/core/transcribe.test.js +163 -0
- package/dist/core/transcribe.test.js.map +1 -0
- package/dist/core/types.d.ts +352 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +3 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/workspace.d.ts +67 -0
- package/dist/core/workspace.d.ts.map +1 -0
- package/dist/core/workspace.js +113 -0
- package/dist/core/workspace.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/plugins/agents/acp/acp-adapter.d.ts +16 -0
- package/dist/plugins/agents/acp/acp-adapter.d.ts.map +1 -0
- package/dist/plugins/agents/acp/acp-adapter.js +49 -0
- package/dist/plugins/agents/acp/acp-adapter.js.map +1 -0
- package/dist/plugins/agents/acp/acp-client.d.ts +32 -0
- package/dist/plugins/agents/acp/acp-client.d.ts.map +1 -0
- package/dist/plugins/agents/acp/acp-client.js +175 -0
- package/dist/plugins/agents/acp/acp-client.js.map +1 -0
- package/dist/plugins/agents/acp/discovery.d.ts +19 -0
- package/dist/plugins/agents/acp/discovery.d.ts.map +1 -0
- package/dist/plugins/agents/acp/discovery.js +109 -0
- package/dist/plugins/agents/acp/discovery.js.map +1 -0
- package/dist/plugins/agents/acp/index.d.ts +4 -0
- package/dist/plugins/agents/acp/index.d.ts.map +1 -0
- package/dist/plugins/agents/acp/index.js +4 -0
- package/dist/plugins/agents/acp/index.js.map +1 -0
- package/dist/plugins/agents/acp/types.d.ts +62 -0
- package/dist/plugins/agents/acp/types.d.ts.map +1 -0
- package/dist/plugins/agents/acp/types.js +5 -0
- package/dist/plugins/agents/acp/types.js.map +1 -0
- package/dist/plugins/agents/claude-code/adapter.test.d.ts +2 -0
- package/dist/plugins/agents/claude-code/adapter.test.d.ts.map +1 -0
- package/dist/plugins/agents/claude-code/adapter.test.js +195 -0
- package/dist/plugins/agents/claude-code/adapter.test.js.map +1 -0
- package/dist/plugins/agents/claude-code/index.d.ts +25 -0
- package/dist/plugins/agents/claude-code/index.d.ts.map +1 -0
- package/dist/plugins/agents/claude-code/index.js +184 -0
- package/dist/plugins/agents/claude-code/index.js.map +1 -0
- package/dist/plugins/agents/claude-code/mcp-approval-server.d.ts +42 -0
- package/dist/plugins/agents/claude-code/mcp-approval-server.d.ts.map +1 -0
- package/dist/plugins/agents/claude-code/mcp-approval-server.js +235 -0
- package/dist/plugins/agents/claude-code/mcp-approval-server.js.map +1 -0
- package/dist/plugins/agents/claude-code/mcp-approval-server.test.d.ts +2 -0
- package/dist/plugins/agents/claude-code/mcp-approval-server.test.d.ts.map +1 -0
- package/dist/plugins/agents/claude-code/mcp-approval-server.test.js +188 -0
- package/dist/plugins/agents/claude-code/mcp-approval-server.test.js.map +1 -0
- package/dist/plugins/agents/codex/adapter.test.d.ts +2 -0
- package/dist/plugins/agents/codex/adapter.test.d.ts.map +1 -0
- package/dist/plugins/agents/codex/adapter.test.js +192 -0
- package/dist/plugins/agents/codex/adapter.test.js.map +1 -0
- package/dist/plugins/agents/codex/index.d.ts +37 -0
- package/dist/plugins/agents/codex/index.d.ts.map +1 -0
- package/dist/plugins/agents/codex/index.js +254 -0
- package/dist/plugins/agents/codex/index.js.map +1 -0
- package/dist/plugins/agents/copilot/index.d.ts +35 -0
- package/dist/plugins/agents/copilot/index.d.ts.map +1 -0
- package/dist/plugins/agents/copilot/index.js +182 -0
- package/dist/plugins/agents/copilot/index.js.map +1 -0
- package/dist/plugins/agents/opencode/adapter.test.d.ts +2 -0
- package/dist/plugins/agents/opencode/adapter.test.d.ts.map +1 -0
- package/dist/plugins/agents/opencode/adapter.test.js +139 -0
- package/dist/plugins/agents/opencode/adapter.test.js.map +1 -0
- package/dist/plugins/agents/opencode/http-adapter.test.d.ts +2 -0
- package/dist/plugins/agents/opencode/http-adapter.test.d.ts.map +1 -0
- package/dist/plugins/agents/opencode/http-adapter.test.js +492 -0
- package/dist/plugins/agents/opencode/http-adapter.test.js.map +1 -0
- package/dist/plugins/agents/opencode/index.d.ts +5 -0
- package/dist/plugins/agents/opencode/index.d.ts.map +1 -0
- package/dist/plugins/agents/opencode/index.js +30 -0
- package/dist/plugins/agents/opencode/index.js.map +1 -0
- package/dist/plugins/agents/opencode/opencode-http-adapter.d.ts +138 -0
- package/dist/plugins/agents/opencode/opencode-http-adapter.d.ts.map +1 -0
- package/dist/plugins/agents/opencode/opencode-http-adapter.js +549 -0
- package/dist/plugins/agents/opencode/opencode-http-adapter.js.map +1 -0
- package/dist/plugins/agents/opencode/opencode-stdio-adapter.d.ts +24 -0
- package/dist/plugins/agents/opencode/opencode-stdio-adapter.d.ts.map +1 -0
- package/dist/plugins/agents/opencode/opencode-stdio-adapter.js +103 -0
- package/dist/plugins/agents/opencode/opencode-stdio-adapter.js.map +1 -0
- package/dist/plugins/agents/opencode/serve-manager.d.ts +27 -0
- package/dist/plugins/agents/opencode/serve-manager.d.ts.map +1 -0
- package/dist/plugins/agents/opencode/serve-manager.js +190 -0
- package/dist/plugins/agents/opencode/serve-manager.js.map +1 -0
- package/dist/plugins/messengers/discord/discord-adapter.d.ts +22 -0
- package/dist/plugins/messengers/discord/discord-adapter.d.ts.map +1 -0
- package/dist/plugins/messengers/discord/discord-adapter.js +241 -0
- package/dist/plugins/messengers/discord/discord-adapter.js.map +1 -0
- package/dist/plugins/messengers/discord/discord-adapter.test.d.ts +2 -0
- package/dist/plugins/messengers/discord/discord-adapter.test.d.ts.map +1 -0
- package/dist/plugins/messengers/discord/discord-adapter.test.js +332 -0
- package/dist/plugins/messengers/discord/discord-adapter.test.js.map +1 -0
- package/dist/plugins/messengers/discord/index.d.ts +4 -0
- package/dist/plugins/messengers/discord/index.d.ts.map +1 -0
- package/dist/plugins/messengers/discord/index.js +4 -0
- package/dist/plugins/messengers/discord/index.js.map +1 -0
- package/dist/plugins/messengers/discord/markdown-to-discord.d.ts +11 -0
- package/dist/plugins/messengers/discord/markdown-to-discord.d.ts.map +1 -0
- package/dist/plugins/messengers/discord/markdown-to-discord.js +59 -0
- package/dist/plugins/messengers/discord/markdown-to-discord.js.map +1 -0
- package/dist/plugins/messengers/discord/types.d.ts +9 -0
- package/dist/plugins/messengers/discord/types.d.ts.map +1 -0
- package/dist/plugins/messengers/discord/types.js +3 -0
- package/dist/plugins/messengers/discord/types.js.map +1 -0
- package/dist/plugins/messengers/feishu/card-builder.d.ts +23 -0
- package/dist/plugins/messengers/feishu/card-builder.d.ts.map +1 -0
- package/dist/plugins/messengers/feishu/card-builder.js +89 -0
- package/dist/plugins/messengers/feishu/card-builder.js.map +1 -0
- package/dist/plugins/messengers/feishu/feishu-adapter.d.ts +33 -0
- package/dist/plugins/messengers/feishu/feishu-adapter.d.ts.map +1 -0
- package/dist/plugins/messengers/feishu/feishu-adapter.js +195 -0
- package/dist/plugins/messengers/feishu/feishu-adapter.js.map +1 -0
- package/dist/plugins/messengers/feishu/feishu-client.d.ts +44 -0
- package/dist/plugins/messengers/feishu/feishu-client.d.ts.map +1 -0
- package/dist/plugins/messengers/feishu/feishu-client.js +120 -0
- package/dist/plugins/messengers/feishu/feishu-client.js.map +1 -0
- package/dist/plugins/messengers/feishu/feishu-dedup.test.d.ts +2 -0
- package/dist/plugins/messengers/feishu/feishu-dedup.test.d.ts.map +1 -0
- package/dist/plugins/messengers/feishu/feishu-dedup.test.js +70 -0
- package/dist/plugins/messengers/feishu/feishu-dedup.test.js.map +1 -0
- package/dist/plugins/messengers/feishu/index.d.ts +4 -0
- package/dist/plugins/messengers/feishu/index.d.ts.map +1 -0
- package/dist/plugins/messengers/feishu/index.js +4 -0
- package/dist/plugins/messengers/feishu/index.js.map +1 -0
- package/dist/plugins/messengers/feishu/types.d.ts +113 -0
- package/dist/plugins/messengers/feishu/types.d.ts.map +1 -0
- package/dist/plugins/messengers/feishu/types.js +4 -0
- package/dist/plugins/messengers/feishu/types.js.map +1 -0
- package/dist/plugins/messengers/telegram/index.d.ts +4 -0
- package/dist/plugins/messengers/telegram/index.d.ts.map +1 -0
- package/dist/plugins/messengers/telegram/index.js +4 -0
- package/dist/plugins/messengers/telegram/index.js.map +1 -0
- package/dist/plugins/messengers/telegram/markdown-to-html.d.ts +5 -0
- package/dist/plugins/messengers/telegram/markdown-to-html.d.ts.map +1 -0
- package/dist/plugins/messengers/telegram/markdown-to-html.js +186 -0
- package/dist/plugins/messengers/telegram/markdown-to-html.js.map +1 -0
- package/dist/plugins/messengers/telegram/media-download.d.ts +51 -0
- package/dist/plugins/messengers/telegram/media-download.d.ts.map +1 -0
- package/dist/plugins/messengers/telegram/media-download.js +224 -0
- package/dist/plugins/messengers/telegram/media-download.js.map +1 -0
- package/dist/plugins/messengers/telegram/media-download.test.d.ts +2 -0
- package/dist/plugins/messengers/telegram/media-download.test.d.ts.map +1 -0
- package/dist/plugins/messengers/telegram/media-download.test.js +125 -0
- package/dist/plugins/messengers/telegram/media-download.test.js.map +1 -0
- package/dist/plugins/messengers/telegram/telegram-adapter.d.ts +62 -0
- package/dist/plugins/messengers/telegram/telegram-adapter.d.ts.map +1 -0
- package/dist/plugins/messengers/telegram/telegram-adapter.js +653 -0
- package/dist/plugins/messengers/telegram/telegram-adapter.js.map +1 -0
- package/dist/plugins/messengers/telegram/types.d.ts +47 -0
- package/dist/plugins/messengers/telegram/types.d.ts.map +1 -0
- package/dist/plugins/messengers/telegram/types.js +3 -0
- package/dist/plugins/messengers/telegram/types.js.map +1 -0
- package/dist/plugins/messengers/wechat/ilink-adapter.d.ts +68 -0
- package/dist/plugins/messengers/wechat/ilink-adapter.d.ts.map +1 -0
- package/dist/plugins/messengers/wechat/ilink-adapter.js +483 -0
- package/dist/plugins/messengers/wechat/ilink-adapter.js.map +1 -0
- package/dist/plugins/messengers/wechat/ilink-client.d.ts +66 -0
- package/dist/plugins/messengers/wechat/ilink-client.d.ts.map +1 -0
- package/dist/plugins/messengers/wechat/ilink-client.js +288 -0
- package/dist/plugins/messengers/wechat/ilink-client.js.map +1 -0
- package/dist/plugins/messengers/wechat/ilink-types.d.ts +173 -0
- package/dist/plugins/messengers/wechat/ilink-types.d.ts.map +1 -0
- package/dist/plugins/messengers/wechat/ilink-types.js +12 -0
- package/dist/plugins/messengers/wechat/ilink-types.js.map +1 -0
- package/dist/utils/backoff.d.ts +35 -0
- package/dist/utils/backoff.d.ts.map +1 -0
- package/dist/utils/backoff.js +59 -0
- package/dist/utils/backoff.js.map +1 -0
- package/dist/utils/cross-platform.d.ts +26 -0
- package/dist/utils/cross-platform.d.ts.map +1 -0
- package/dist/utils/cross-platform.js +58 -0
- package/dist/utils/cross-platform.js.map +1 -0
- package/dist/utils/message-split.d.ts +14 -0
- package/dist/utils/message-split.d.ts.map +1 -0
- package/dist/utils/message-split.js +65 -0
- package/dist/utils/message-split.js.map +1 -0
- package/dist/utils/safe-equal.d.ts +2 -0
- package/dist/utils/safe-equal.d.ts.map +1 -0
- package/dist/utils/safe-equal.js +11 -0
- package/dist/utils/safe-equal.js.map +1 -0
- package/dist/web/public/_app.js +196 -0
- package/dist/web/public/index.html +935 -0
- package/dist/web/public/settings.html +1181 -0
- package/dist/web/public/tasks.html +1827 -0
- package/dist/web/server.d.ts +11 -0
- package/dist/web/server.d.ts.map +1 -0
- package/dist/web/server.js +1820 -0
- package/dist/web/server.js.map +1 -0
- package/package.json +73 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-2026 Jerry
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,497 @@
|
|
|
1
|
+
# im-hub-pro
|
|
2
|
+
|
|
3
|
+
[中文文档](README.zh-CN.md)
|
|
4
|
+
|
|
5
|
+
**Universal messenger-to-agent bridge** — connect WeChat / Feishu / Telegram / **Discord** to Claude Code / Codex / Copilot / OpenCode, **or any custom agent via ACP**. Single Node.js process, no Docker, no Redis. Browser dashboard, persistent jobs, multi-tenant workspaces, and real human-in-the-loop tool approval over IM.
|
|
6
|
+
|
|
7
|
+
> Productized fork of the original [`im-hub`](https://www.npmjs.com/package/im-hub). On-disk config (`~/.im-hub/`), env vars (`IMHUB_*`), and HTTP headers (`X-IM-Hub-Token`) are unchanged — drop-in compatible. See [Migrating from `im-hub`](#migrating-from-im-hub) below.
|
|
8
|
+
|
|
9
|
+
## What's new in v0.2.13 → v0.2.23
|
|
10
|
+
|
|
11
|
+
- **Discord adapter** (Gateway WebSocket via `discord.js`)
|
|
12
|
+
- **Human-in-the-loop tool approval** — Claude pauses on tool calls; you reply `y`/`n` in the same IM thread, **or click an in-page card from the web chat**
|
|
13
|
+
- **Tasks dashboard** at `/tasks` with **Jobs · Background · Subtasks · Schedules · Approvals · Health · Files · Audit** tabs (per-agent filtering, multi-select batch ops, real-time SSE updates)
|
|
14
|
+
- **Multi-tenant workspaces** — per-workspace agent whitelist + rate limits, **with full CRUD UI in /settings**, plus command-level ACL on `/job` `/schedule` `/audit` (each user only sees their own)
|
|
15
|
+
- **ACP server mode** — im-hub-pro itself is an ACP-compatible agent (`POST /tasks` sync + SSE)
|
|
16
|
+
- **Persistent Job Board** + cron scheduler (SQLite, survives restarts) with 30-day retention sweep
|
|
17
|
+
- **Smart routing**: intent classifier (CJK + ASCII), circuit breaker, sticky sessions
|
|
18
|
+
- **Structured logging** (`pino`) with `traceId` end-to-end + audit log + Prometheus `/api/metrics`
|
|
19
|
+
- **Three-state theme** (light / dark / system) on every page — applied before first paint to avoid flash
|
|
20
|
+
- **v0.2.16 — Security hardening (P0 + P1)**: timing-safe token compare, Schedule `notify_url` SSRF guard, secret redaction in logs, approval-socket entropy + perms, `Session.addMessage` per-key mutex
|
|
21
|
+
- **v0.2.17 — Observability & IM polish (P2 + P3)**: static-page CSP / `X-Frame-Options` / `X-Content-Type-Options`, WebSocket connection cap + backpressure, Prometheus label-cardinality whitelist, new counters (`im_hub_audit_prune_failed_total` / `im_hub_agent_cleanup_failed_total` / `im_hub_approval_*`), UTF-16 surrogate-safe message split, auto-allow fingerprint 5→10 chars, SQLite WAL clean checkpoint on SIGINT
|
|
22
|
+
- **v0.2.18 — IM reconnect backoff (M9)**: shared `Backoff` helper (exponential + ±50% jitter) replaces fixed 2s / 5s reconnect delays in Telegram + WeChat polling; defeats thundering-herd on shared network recovery
|
|
23
|
+
- **v0.2.19 — Codex sandbox-mode plan + Dashboard filter / Audit tab**: codex now honors `session.planMode` (default sandbox switched to explicit `-s workspace-write`); jobs / subtasks / schedules tabs gain per-agent filter; new Audit tab pulls the SQLite audit log into the dashboard
|
|
24
|
+
- **v0.2.20 — Web console PR-A**: three-state theme manager + global error boundary + in-page approval cards (click Allow / Deny / Allow + Auto from the chat UI itself)
|
|
25
|
+
- **v0.2.21 — Web console PR-B**: Health tab (per-agent breaker / rate-limiter / latency p50/95/99 / sparkline) + Approvals tab (browse and resolve every pending HITL approval from the dashboard)
|
|
26
|
+
- **v0.2.22 — Web console PR-C**: SSE event stream (`/events`) replaces polling for audit / approval / job / metrics events; full Workspace CRUD UI in /settings
|
|
27
|
+
- **v0.2.23 — Web console PR-D**: Files tab — read-only browser of `~/.im-hub-workspaces/<agent>/`; Jobs tab gains multi-select + batch cancel / run; settings page header / container restyled
|
|
28
|
+
|
|
29
|
+
See [CHANGELOG.md](CHANGELOG.md) and [docs/code-review-2026-05-06-main.md](docs/code-review-2026-05-06-main.md) for the full list.
|
|
30
|
+
|
|
31
|
+
## Web Chat & Tasks Dashboard
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
im-hub-pro start # Web UI at http://localhost:3000
|
|
35
|
+
# / chat (with in-page approval cards)
|
|
36
|
+
# /tasks jobs · background · subtasks · schedules
|
|
37
|
+
# · approvals · health · files · audit
|
|
38
|
+
# /settings agents · messengers · ACP · workspaces
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
- Real-time streaming via WebSocket; **dashboard pushed via SSE `/events`** (audit / approval / job / metrics)
|
|
42
|
+
- Agent switching and chat history
|
|
43
|
+
- **Three-state theme** (light / dark / system) with per-tab persistence + global error boundary
|
|
44
|
+
- Bilingual UI (English / 中文) — auto-detects browser language
|
|
45
|
+
- `/tasks` surfaces persistent jobs, cron schedules, **`~/.claude/bgjobs`** + **`~/.config/opencode/bgjobs`** + **`~/.codex/bgjobs`** background tasks (override via `IMHUB_BGJOB_ROOTS`), every subtask in every session, agent health (breaker · rate-limiter · p50/95/99 · sparkline), pending HITL approvals (resolve from the browser), and a read-only file browser into `~/.im-hub-workspaces/<agent>/`
|
|
46
|
+
|
|
47
|
+
## Features
|
|
48
|
+
|
|
49
|
+
- **Universal multiplexer** — one instance, multiple messengers, multiple agents
|
|
50
|
+
- **Custom agent support** — connect any agent via [ACP](https://agentcommunicationprotocol.dev) with `im-hub-pro config agent`, or auto-discover via `/.well-known/acp`
|
|
51
|
+
- **Built-in IMs** — WeChat (iLink), Feishu (WebSocket long-poll), Telegram (grammy), **Discord** (discord.js)
|
|
52
|
+
- **Built-in CLI agents** — Claude Code, Codex, Copilot, OpenCode (all via shared `AgentBase` adapter)
|
|
53
|
+
- **Plugin architecture** — easy to add new messengers / agents
|
|
54
|
+
- **TypeScript native** — no Go, no Docker, no Redis
|
|
55
|
+
- **JSONL streaming** — real-time agent responses with multi-byte UTF-8 safety
|
|
56
|
+
|
|
57
|
+
## Installation
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npm install -g im-hub-pro
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Requires **Node.js ≥ 18** (production deployments use ≥ 22 LTS — see [`docs/deployment.md`](docs/deployment.md)).
|
|
64
|
+
|
|
65
|
+
### Migrating from `im-hub`
|
|
66
|
+
|
|
67
|
+
Your `~/.im-hub/` config dir, `IMHUB_*` env vars, `X-IM-Hub-Token` header, and ACP wire identifiers (`im-hub-gateway`) are unchanged — this is a brand rename only.
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
npm uninstall -g im-hub
|
|
71
|
+
npm install -g im-hub-pro
|
|
72
|
+
im-hub-pro start
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Quick Start
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# 1. Configure at least one messenger
|
|
79
|
+
im-hub-pro config wechat # QR-code login
|
|
80
|
+
im-hub-pro config feishu # App ID + Secret (no webhook needed)
|
|
81
|
+
im-hub-pro config telegram # @BotFather token
|
|
82
|
+
im-hub-pro config discord # Bot token; see docs/discord-setup.md
|
|
83
|
+
|
|
84
|
+
# 2. (Optional) Configure a CLI agent — most are auto-detected
|
|
85
|
+
im-hub-pro config claude
|
|
86
|
+
|
|
87
|
+
# 3. (Optional) Connect a custom remote agent over ACP
|
|
88
|
+
im-hub-pro config agent
|
|
89
|
+
|
|
90
|
+
# 4. Start the bridge
|
|
91
|
+
im-hub-pro start
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Feishu (WebSocket Long Polling)
|
|
95
|
+
|
|
96
|
+
- ✅ No webhook configuration needed
|
|
97
|
+
- ✅ No public IP or domain required
|
|
98
|
+
- ✅ No ngrok or similar tools needed
|
|
99
|
+
- ✅ Works directly from localhost
|
|
100
|
+
|
|
101
|
+
### Discord
|
|
102
|
+
|
|
103
|
+
See [`docs/discord-setup.md`](docs/discord-setup.md) for the full bot-token / intents / OAuth flow.
|
|
104
|
+
|
|
105
|
+
### Connect Your Own Agent
|
|
106
|
+
|
|
107
|
+
im-hub-pro speaks **ACP (Agent Communication Protocol)**, so you can plug in any agent that exposes a standard HTTP endpoint — your own business bots, internal tools, cloud services, anything.
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
im-hub-pro config agent
|
|
111
|
+
# Interactive setup: name, endpoint URL, auth (none / Bearer / API key)
|
|
112
|
+
# Connection is validated automatically; /.well-known/acp is auto-discovered
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
After setup, chat with it the same way as built-in agents:
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
/myagent analyze the Q1 sales report
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Use im-hub-pro *as* an agent
|
|
122
|
+
|
|
123
|
+
im-hub-pro also exposes an ACP server — point any ACP-compliant client at `POST http://localhost:3000/tasks` (sync) or with `?mode=stream` (SSE). Auth is the same `Authorization: Bearer <web-token>`.
|
|
124
|
+
|
|
125
|
+
## CLI Commands
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
im-hub-pro # Same as 'start'
|
|
129
|
+
im-hub-pro start # Start the bridge + web UI
|
|
130
|
+
im-hub-pro config wechat # Configure WeChat
|
|
131
|
+
im-hub-pro config feishu # Configure Feishu
|
|
132
|
+
im-hub-pro config telegram # Configure Telegram
|
|
133
|
+
im-hub-pro config discord # Configure Discord
|
|
134
|
+
im-hub-pro config claude # Configure Claude Code
|
|
135
|
+
im-hub-pro config agent # Connect a custom ACP agent
|
|
136
|
+
im-hub-pro agents # List available agents
|
|
137
|
+
im-hub-pro messengers # List available messengers
|
|
138
|
+
im-hub-pro help
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Chat Commands
|
|
142
|
+
|
|
143
|
+
Send these as messages to the bot. Responses are streamed back in the same thread.
|
|
144
|
+
|
|
145
|
+
| Command | What it does |
|
|
146
|
+
|---|---|
|
|
147
|
+
| (any text) | Route to the agent (sticky session, intent-classified) |
|
|
148
|
+
| `/<agent> <prompt>` | Switch agent and send (e.g. `/cc explain this`, `/oc`, `/cx`, `/co`) |
|
|
149
|
+
| `/help` | Show available commands |
|
|
150
|
+
| `/agents` | List available agents |
|
|
151
|
+
| `/status` | Show connection status |
|
|
152
|
+
| `/new` | Start a new conversation (clear context) |
|
|
153
|
+
| `/router status\|policy\|explain\|reset` | Inspect routing decisions, predict where a message would go |
|
|
154
|
+
| `/audit [n]` | Recent invocations from the audit log |
|
|
155
|
+
| `/job ...` | Inspect / cancel persistent jobs |
|
|
156
|
+
| `/schedule ...` | List / add / remove cron schedules |
|
|
157
|
+
| `/sessions` | List recent sessions for this thread |
|
|
158
|
+
| `/model [provider/model]` | View or change the session's model |
|
|
159
|
+
| `/models` | List models the current agent supports |
|
|
160
|
+
| `/think on\|off\|...` | Toggle "think harder" / extended-thinking modes |
|
|
161
|
+
| `/stats` | Per-agent invocation / latency / error stats |
|
|
162
|
+
| `y` / `n` / `批准` / `拒绝` | Approve or deny a pending Claude tool call (HITL) |
|
|
163
|
+
|
|
164
|
+
## Human-in-the-loop Tool Approval
|
|
165
|
+
|
|
166
|
+
When a Claude run launched from IM tries to use a tool, im-hub-pro pauses it and posts an approval card to the same IM thread:
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
🔐 Tool approval request
|
|
170
|
+
Tool: Bash
|
|
171
|
+
Input: {"command":"rm -rf node_modules"}
|
|
172
|
+
Reply y to approve / n to deny (auto-deny in 5 min)
|
|
173
|
+
req: a3f1c0d2
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Reply `y`, `n`, `批准`, `拒绝`, etc. — the decision flows back through an MCP sidecar to Claude, which resumes (or aborts) accordingly. The same chain works for WeChat, Telegram, Feishu, and Discord with no per-platform changes. Disable with `IMHUB_APPROVAL_DISABLED=1`.
|
|
177
|
+
|
|
178
|
+
## Architecture
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
┌─── External triggers ───┐
|
|
182
|
+
│ cron 30s tick │
|
|
183
|
+
│ webhook → /api/notify │
|
|
184
|
+
│ REST → /api/invoke │
|
|
185
|
+
│ ACP → /tasks (sync/SSE)│
|
|
186
|
+
└────────────┬─────────────┘
|
|
187
|
+
┌─ IM ingress ──────────────────────┼───────────────────┐
|
|
188
|
+
│ WeChat iLink (long-poll + heartbeat) │
|
|
189
|
+
│ Telegram (grammy) │
|
|
190
|
+
│ Feishu (Lark SDK WebSocket) │
|
|
191
|
+
│ Discord (discord.js Gateway) │
|
|
192
|
+
│ Web Chat (browser WebSocket) │
|
|
193
|
+
└────────────────────────────────┬──────────────────────┘
|
|
194
|
+
│ MessageContext
|
|
195
|
+
▼
|
|
196
|
+
┌── Pre-route gates ────────────────┐
|
|
197
|
+
│ workspace.resolve(userId) │
|
|
198
|
+
│ rateLimiter.allow(userKey) │
|
|
199
|
+
│ traceId + pino child logger │
|
|
200
|
+
└────────────────┬───────────────────┘
|
|
201
|
+
▼
|
|
202
|
+
┌── parseMessage + Intent ──────────┐
|
|
203
|
+
│ /<cmd> → builtin sub-command │
|
|
204
|
+
│ /<agent> → explicit switch │
|
|
205
|
+
│ default → classifyIntent │
|
|
206
|
+
│ ├ topic regex (CJK + ASCII) │
|
|
207
|
+
│ ├ keyword profile │
|
|
208
|
+
│ ├ sticky session bias │
|
|
209
|
+
│ └ LLM judge (opt-in fallback) │
|
|
210
|
+
└────────────────┬───────────────────┘
|
|
211
|
+
▼
|
|
212
|
+
┌── Agent invocation ───────────────┐
|
|
213
|
+
│ workspace whitelist + circuit │
|
|
214
|
+
│ breaker + isAvailable cache │
|
|
215
|
+
│ AgentBase.sendPrompt → spawnStream │
|
|
216
|
+
│ (LineBuffer · true streaming · │
|
|
217
|
+
│ abort/timeout · UTF-8 safe) │
|
|
218
|
+
└────────────────┬───────────────────┘
|
|
219
|
+
┌──────┬───────┼────────┬─────────┐
|
|
220
|
+
▼ ▼ ▼ ▼ ▼
|
|
221
|
+
opencode claude codex copilot ACP remote
|
|
222
|
+
│
|
|
223
|
+
▼ (if a tool needs approval)
|
|
224
|
+
MCP sidecar ─ unix socket ─ approvalBus
|
|
225
|
+
└─ approvalRouter → IM thread
|
|
226
|
+
|
|
227
|
+
┌─ Cross-cutting ───────────────────────────────────────┐
|
|
228
|
+
│ audit-log (SQLite, 30-day retention) │
|
|
229
|
+
│ job-board (SQLite, persistent + AbortController) │
|
|
230
|
+
│ scheduler (30s tick → cron → enqueue jobs) │
|
|
231
|
+
│ workspaces (per-tenant agent whitelist + limits) │
|
|
232
|
+
│ metrics (Prometheus text via /api/metrics) │
|
|
233
|
+
│ session (~/.im-hub/sessions/, append-only JSONL) │
|
|
234
|
+
│ pino (traceId end-to-end, JSON in production) │
|
|
235
|
+
└───────────────────────────────────────────────────────┘
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Single-process, single-instance: SQLite (`audit.db` / `jobs.db` / `schedules.db`) plus a session file tree is the entire persistence layer. No Redis, no MQ.
|
|
239
|
+
|
|
240
|
+
For the full deep-dive see [`docs/architecture/current.md`](docs/architecture/current.md).
|
|
241
|
+
|
|
242
|
+
## Project Structure
|
|
243
|
+
|
|
244
|
+
```
|
|
245
|
+
im-hub-pro/
|
|
246
|
+
├── src/
|
|
247
|
+
│ ├── core/
|
|
248
|
+
│ │ ├── types.ts # Plugin interfaces
|
|
249
|
+
│ │ ├── registry.ts # Plugin registration
|
|
250
|
+
│ │ ├── router.ts # Message routing
|
|
251
|
+
│ │ ├── session.ts # Session manager (append-only JSONL)
|
|
252
|
+
│ │ ├── workspace.ts # Multi-tenant workspaces
|
|
253
|
+
│ │ ├── intent.ts # Intent classifier
|
|
254
|
+
│ │ ├── intent-llm.ts # LLM judge fallback (LRU cached)
|
|
255
|
+
│ │ ├── circuit-breaker.ts # Per-agent breaker
|
|
256
|
+
│ │ ├── rate-limiter.ts # Token-bucket
|
|
257
|
+
│ │ ├── job-board.ts # Persistent jobs + cancel
|
|
258
|
+
│ │ ├── schedule.ts # Cron tick → job enqueue
|
|
259
|
+
│ │ ├── audit-log.ts # SQLite audit
|
|
260
|
+
│ │ ├── metrics.ts # Prometheus quantiles
|
|
261
|
+
│ │ ├── acp-server.ts # /tasks ACP server
|
|
262
|
+
│ │ ├── approval-bus.ts # Tool-approval pub/sub
|
|
263
|
+
│ │ ├── approval-router.ts # Approval ↔ IM bridge
|
|
264
|
+
│ │ ├── bgjob-reader.ts # ~/.claude + ~/.config/opencode bgjobs
|
|
265
|
+
│ │ ├── agent-base.ts # Shared spawn-stream for CLI agents
|
|
266
|
+
│ │ ├── config-schema.ts # Zod schema
|
|
267
|
+
│ │ ├── logger.ts # pino + traceId
|
|
268
|
+
│ │ ├── sqlite-helper.ts # Shared prepare/PRAGMA cache
|
|
269
|
+
│ │ └── commands/ # /audit /router /job /schedule /model …
|
|
270
|
+
│ ├── plugins/
|
|
271
|
+
│ │ ├── messengers/
|
|
272
|
+
│ │ │ ├── wechat/ # iLink long-poll
|
|
273
|
+
│ │ │ ├── feishu/ # Lark SDK WebSocket
|
|
274
|
+
│ │ │ ├── telegram/ # grammy
|
|
275
|
+
│ │ │ └── discord/ # discord.js
|
|
276
|
+
│ │ └── agents/
|
|
277
|
+
│ │ ├── claude-code/ # + MCP approval sidecar
|
|
278
|
+
│ │ ├── codex/
|
|
279
|
+
│ │ ├── copilot/
|
|
280
|
+
│ │ ├── opencode/
|
|
281
|
+
│ │ └── acp/ # ACP client + /.well-known discovery
|
|
282
|
+
│ ├── index.ts
|
|
283
|
+
│ ├── cli.ts
|
|
284
|
+
│ └── web/
|
|
285
|
+
│ ├── server.ts # HTTP + WS + REST + ACP server
|
|
286
|
+
│ └── public/
|
|
287
|
+
│ ├── index.html # Chat UI
|
|
288
|
+
│ ├── tasks.html # Tasks dashboard
|
|
289
|
+
│ └── settings.html # Settings UI
|
|
290
|
+
├── docs/
|
|
291
|
+
│ ├── architecture/{current,target}.md
|
|
292
|
+
│ ├── adr/{0001,0002,0003}-*.md
|
|
293
|
+
│ ├── deployment.md
|
|
294
|
+
│ ├── discord-setup.md
|
|
295
|
+
│ └── upgrade-plan.md
|
|
296
|
+
├── package.json
|
|
297
|
+
├── tsconfig.json
|
|
298
|
+
└── README.md
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
## Configuration
|
|
302
|
+
|
|
303
|
+
Config file: `~/.im-hub/config.json`
|
|
304
|
+
|
|
305
|
+
```json
|
|
306
|
+
{
|
|
307
|
+
"messengers": ["wechat", "discord"],
|
|
308
|
+
"agents": ["claude-code", "opencode"],
|
|
309
|
+
"defaultAgent": "claude-code",
|
|
310
|
+
"discord": {
|
|
311
|
+
"botToken": "***",
|
|
312
|
+
"allowedGuilds": [],
|
|
313
|
+
"allowedChannels": []
|
|
314
|
+
},
|
|
315
|
+
"acpAgents": [
|
|
316
|
+
{
|
|
317
|
+
"name": "my-agent",
|
|
318
|
+
"aliases": ["ma"],
|
|
319
|
+
"endpoint": "https://api.example.com",
|
|
320
|
+
"auth": { "type": "bearer", "token": "***" },
|
|
321
|
+
"enabled": true
|
|
322
|
+
}
|
|
323
|
+
],
|
|
324
|
+
"workspaces": [
|
|
325
|
+
{
|
|
326
|
+
"id": "team-data",
|
|
327
|
+
"name": "Data team",
|
|
328
|
+
"agents": ["opencode", "my-agent"],
|
|
329
|
+
"members": ["user-123"],
|
|
330
|
+
"rateLimit": { "rate": 30, "intervalSec": 60, "burst": 60 }
|
|
331
|
+
}
|
|
332
|
+
]
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
The schema is enforced by `zod` at startup and on every PUT `/api/config` — bad configs reject loudly instead of silently breaking the bridge.
|
|
337
|
+
|
|
338
|
+
## Requirements
|
|
339
|
+
|
|
340
|
+
- **Node.js 18+** (≥ 22 LTS recommended for production)
|
|
341
|
+
- **At least one Agent CLI** (or an ACP remote endpoint):
|
|
342
|
+
- `npm i -g @anthropic-ai/claude-code`
|
|
343
|
+
- `npm i -g @openai/codex`
|
|
344
|
+
- `npm i -g @github/copilot`
|
|
345
|
+
- `npm i -g opencode-ai`
|
|
346
|
+
|
|
347
|
+
## Development
|
|
348
|
+
|
|
349
|
+
```bash
|
|
350
|
+
git clone https://github.com/benking007/imhub.git
|
|
351
|
+
cd imhub
|
|
352
|
+
npm install
|
|
353
|
+
npm run build # tsc + copy public/
|
|
354
|
+
npm run dev # tsc --watch
|
|
355
|
+
npm test # bun test
|
|
356
|
+
npm run typecheck # tsc --noEmit (src + tests)
|
|
357
|
+
npm start
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
## Roadmap
|
|
361
|
+
|
|
362
|
+
### v0.1.x (MVP)
|
|
363
|
+
- [x] WeChat adapter with QR login
|
|
364
|
+
- [x] Claude Code, Codex, Copilot, OpenCode agents
|
|
365
|
+
- [x] Basic command routing
|
|
366
|
+
|
|
367
|
+
### v0.2.0 — Multi-IM
|
|
368
|
+
- [x] Feishu adapter
|
|
369
|
+
- [x] Telegram adapter
|
|
370
|
+
- [x] Session persistence with conversation history
|
|
371
|
+
- [x] ACP custom agent support
|
|
372
|
+
|
|
373
|
+
### v0.2.x — Web & UI
|
|
374
|
+
- [x] Web Chat UI with streaming
|
|
375
|
+
- [x] Settings page
|
|
376
|
+
- [x] Bilingual UI (EN / 中文)
|
|
377
|
+
|
|
378
|
+
### v0.2.13 — Foundations
|
|
379
|
+
- [x] Structured logging (pino) + traceId
|
|
380
|
+
- [x] Zod config schema validation
|
|
381
|
+
- [x] AgentBase abstraction + healthCheck cache
|
|
382
|
+
- [x] Audit log (SQLite) + `/audit`
|
|
383
|
+
- [x] Intent classifier + circuit breaker + rate limiter
|
|
384
|
+
- [x] ACP server mode (`POST /tasks` sync + SSE)
|
|
385
|
+
- [x] `/.well-known/acp` discovery
|
|
386
|
+
- [x] Multi-tenant workspaces + agent whitelist
|
|
387
|
+
- [x] Persistent Job Board + cron scheduler
|
|
388
|
+
- [x] Web `/tasks` panel + REST jobs API
|
|
389
|
+
- [x] Prometheus metrics
|
|
390
|
+
|
|
391
|
+
### v0.2.14 — Tool approval
|
|
392
|
+
- [x] Human-in-the-loop tool approval over IM
|
|
393
|
+
- [x] MCP approval sidecar (claude-code adapter)
|
|
394
|
+
|
|
395
|
+
### v0.2.15 — Discord & Dashboard
|
|
396
|
+
- [x] Discord messenger adapter
|
|
397
|
+
- [x] Tasks dashboard surfaces Claude / opencode bgjobs
|
|
398
|
+
- [x] Flattened subtasks tab
|
|
399
|
+
|
|
400
|
+
### v0.2.16 — Security hardening (P0 + P1)
|
|
401
|
+
- [x] Timing-safe REST + WS token compare (shared `safe-equal`)
|
|
402
|
+
- [x] Schedule `notify_url` SSRF gate (http(s) only, RFC1918 / loopback / IPv6 ULA blocked) + 10s fetch timeout + redirect:'manual'
|
|
403
|
+
- [x] HTML token injection: `JSON.stringify` instead of single-quote splice
|
|
404
|
+
- [x] Telegram bot-token redaction in logs (pino `redact.paths` + adapter-level scrub)
|
|
405
|
+
- [x] WeChat credential file `0o600` + parent dir `0o700`
|
|
406
|
+
- [x] Approval socket path uses 128-bit random + post-listen `chmod 0o600` + stat verification
|
|
407
|
+
- [x] Job result size cap (`IMHUB_JOB_RESULT_MAX_BYTES`, default 1 MiB) + UTF-8/JSON safe truncation
|
|
408
|
+
- [x] Job-board retention + 6h sweep + `creator_id` / `workspace_id` schema migration
|
|
409
|
+
- [x] Multi-tenant ACL on `/job` `/schedule` `/audit` commands (each user sees only their own rows; legacy ownerless rows stay visible for safe upgrades)
|
|
410
|
+
- [x] Workspace whitelist enforced on direct command paths, not just routing
|
|
411
|
+
- [x] Rate-limiter opportunistic auto-cleanup (no setInterval timer)
|
|
412
|
+
- [x] `Session.addMessage` per-key mutex (defeats concurrent read-modify-write race)
|
|
413
|
+
|
|
414
|
+
### v0.2.17 — Observability & IM polish (P2 + P3)
|
|
415
|
+
- [x] Static-page security headers (`X-Frame-Options` / `X-Content-Type-Options` / `Referrer-Policy` / CSP)
|
|
416
|
+
- [x] `/api/health` declared public (k8s liveness friendly)
|
|
417
|
+
- [x] WebSocket connection cap (`IMHUB_MAX_WS_CLIENTS`, default 100) + `bufferedAmount` backpressure (4 MiB highwater)
|
|
418
|
+
- [x] Prometheus label-cardinality whitelist (`intent` / `platform` → `'other'` for unknowns)
|
|
419
|
+
- [x] New counters: `im_hub_audit_prune_failed_total`, `im_hub_agent_cleanup_failed_total`, `im_hub_approval_pending` / `im_hub_approval_requests_total` / `im_hub_approval_resolved_total{result=allow|deny|timeout}`
|
|
420
|
+
- [x] `intent-llm` cache key SHA-256 + 256-char prompt cap (defeats LRU memory bloat)
|
|
421
|
+
- [x] Auto-allow fingerprint 5 → 10 chars (`git status` ≠ `git stash` ≠ `git submo`)
|
|
422
|
+
- [x] UTF-16 surrogate-safe message split (emoji at boundary no longer renders as `□`)
|
|
423
|
+
- [x] Telegram HTML escape covers `'` / `"` (approval-card `<a href="...">` safety)
|
|
424
|
+
- [x] approval-bus over-cap deny instead of silent socket destroy
|
|
425
|
+
- [x] SQLite WAL clean checkpoint on SIGINT
|
|
426
|
+
- [x] traceId 12 hex → 16 hex (`~2^48` → `~2^64`)
|
|
427
|
+
- [x] WeChat ilink-client fetch timeouts on remaining 4 callsites
|
|
428
|
+
- [x] Discord typing interval companion `AbortController` (no race with `client.destroy()`)
|
|
429
|
+
- [x] WeChat `contextTokens` periodic cleanup on heartbeat tick
|
|
430
|
+
- [x] CI lockfile fix (Tencent mirror URLs → `https://registry.npmjs.org/`)
|
|
431
|
+
|
|
432
|
+
### v0.2.18 — IM reconnect backoff (M9)
|
|
433
|
+
- [x] Shared `Backoff` helper (exponential + ±jitter, RNG-injectable for tests)
|
|
434
|
+
- [x] Telegram `runPollingLoop`: fixed 2s / 5s setTimeouts → `Backoff(2s, 60s, 0.5)`; 30s healthy-run threshold resets backoff
|
|
435
|
+
- [x] WeChat ilink `pollLoop`: inline `Math.pow(2,n-1)` → `Backoff(2s, 30s, 0.5)`; success path resets
|
|
436
|
+
|
|
437
|
+
### v0.2.19 — Codex sandbox + Dashboard filter / Audit tab
|
|
438
|
+
- [x] Codex now honors `session.planMode`; default sandbox `--full-auto` → explicit `-s workspace-write`
|
|
439
|
+
- [x] Per-agent filter on Jobs / Subtasks / Schedules tabs (`OwnerOpts.agent` plumbed through)
|
|
440
|
+
- [x] New Audit tab in `/tasks` pulling SQLite audit log + `GET /api/audit?agent=&days=&user=&intent=`
|
|
441
|
+
|
|
442
|
+
### v0.2.20 — Web console PR-A: theme + error boundary + in-page approval
|
|
443
|
+
- [x] Three-state theme (light / dark / system) applied synchronously in `<head>` to defeat flash
|
|
444
|
+
- [x] `_app.js` shared utility: `window.imhub.{theme,i18n,api,showError}` + auto-installed error boundary
|
|
445
|
+
- [x] In-chat approval cards on `/` (Allow / Deny / Allow + Auto), routed through the same `approvalBus.resolvePending()` path as Telegram
|
|
446
|
+
- [x] `approval-router` `bindButtonHandlerForPlatform(platform)` exported so late-registered messengers (web is one) can wire their button handler
|
|
447
|
+
|
|
448
|
+
### v0.2.21 — Web console PR-B: Health + Approvals tabs
|
|
449
|
+
- [x] Health tab: per-agent breaker phase (closed/open/half-open) + rate-limiter remaining + p50/95/99 latency + invocations / success rate / cost / cooldown + 60-poll p95 sparkline
|
|
450
|
+
- [x] Approvals tab: list every pending HITL approval (reqId / threadId / tool / age / registeredAt) with browser-side Allow / Deny / Allow + Auto buttons
|
|
451
|
+
- [x] Backend: `GET /api/agent-health` / `GET /api/approvals` / `POST /api/approvals/:reqId/resolve`
|
|
452
|
+
- [x] `approval-bus.PendingApproval` now carries `input` + `registeredAt`; emits `'approval'` events for SSE
|
|
453
|
+
|
|
454
|
+
### v0.2.22 — Web console PR-C: SSE event stream + Workspace CRUD UI
|
|
455
|
+
- [x] `src/core/event-bus.ts` — typed publish/subscribe (audit / approval / job / metrics) with 200-entry replay ring buffer
|
|
456
|
+
- [x] `GET /events` SSE endpoint — token via `?token=`, 25s heartbeat, listener-error swallow
|
|
457
|
+
- [x] Dashboard `EventSource('/events?token=...')` refreshes only the visible tab; polling kept as fallback; `approval requested` flashes the tab badge
|
|
458
|
+
- [x] Settings page Workspace card — list + create / edit / delete (id locked on edit; default row uneditable + undeletable)
|
|
459
|
+
- [x] Backend `GET/POST/PATCH/DELETE /api/workspaces` + `WorkspaceRegistry.{remove(id), listFull()}`; mutations persisted back to `~/.im-hub/config.json`
|
|
460
|
+
|
|
461
|
+
### v0.2.23 — Web console PR-D: Files tab + Jobs batch ops + settings polish
|
|
462
|
+
- [x] Files tab — read-only browse of `~/.im-hub-workspaces/<agent>/`, two-pane (dir tree + content), 1 MiB cap, NUL-byte binary detect → base64
|
|
463
|
+
- [x] Path-traversal defense: agent name whitelisted against `registry.listAgents()`; resolved path must equal or live below `defaultAgentCwd(agent)`
|
|
464
|
+
- [x] Jobs tab multi-select + select-all + hidden-until-needed batch toolbar; selection state survives refresh
|
|
465
|
+
- [x] `POST /api/jobs/batch-cancel` / `batch-run` accept `{ ids: number[] }` (max 100); per-id failures don't fail the whole request
|
|
466
|
+
- [x] Settings header restyle (`.brand` + `.controls` flex groups) — fixes language `<select>` stretching across the bar; container 720→880, sticky header, theme-aware toast / `.btn-danger:hover`
|
|
467
|
+
|
|
468
|
+
### v0.3.0
|
|
469
|
+
- [ ] DingTalk adapter
|
|
470
|
+
- [ ] Slack adapter
|
|
471
|
+
- [ ] Approval cards (Feishu/Discord buttons) instead of plain text
|
|
472
|
+
- [ ] Cron `nextOccurrence` internal UTC normalization (DST safety, M5 from CR-2026-05-06)
|
|
473
|
+
- [ ] Multi-instance event bus (Redis Streams / NATS) so SSE works across replicas
|
|
474
|
+
- [ ] Workspace member picker UI (current CSV input is ops-friendly but error-prone)
|
|
475
|
+
|
|
476
|
+
## Community <a name="wechat-group"></a>
|
|
477
|
+
|
|
478
|
+
Questions? Feel free to reach out on [X](https://x.com/lijieisme) or join the Discord.
|
|
479
|
+
|
|
480
|
+
<p align="center">
|
|
481
|
+
<a href="https://discord.gg/R83CXYz5">
|
|
482
|
+
<img src="https://img.shields.io/badge/Join_Discord-5865F2?style=for-the-badge&logo=discord&logoColor=white" alt="Join Discord">
|
|
483
|
+
</a>
|
|
484
|
+
|
|
485
|
+
<a href="https://x.com/lijieisme">
|
|
486
|
+
<img src="https://img.shields.io/badge/Follow_on_X-000000?style=for-the-badge&logo=x&logoColor=white" alt="X">
|
|
487
|
+
</a>
|
|
488
|
+
</p>
|
|
489
|
+
|
|
490
|
+
<p align="center">
|
|
491
|
+
<img src="assets/wechat-group" alt="Original author WeChat" width="180"><br>
|
|
492
|
+
<sub><i>Original author's contact</i></sub>
|
|
493
|
+
</p>
|
|
494
|
+
|
|
495
|
+
## License
|
|
496
|
+
|
|
497
|
+
MIT
|