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
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// OpenCode CLI agent adapter — stdio (JSONL) driver.
|
|
2
|
+
// Uses `opencode run --format json` for programmatic interaction.
|
|
3
|
+
//
|
|
4
|
+
// Two flavors of multi-turn continuity, mirroring the claude-code adapter:
|
|
5
|
+
//
|
|
6
|
+
// First turn — no opts.agentSessionId yet. Spawn `opencode run …` plain.
|
|
7
|
+
// The adapter watches for `sessionID` on the very first event
|
|
8
|
+
// and reports it back via opts.onAgentSessionId so cli can
|
|
9
|
+
// persist it on the im-hub Session row.
|
|
10
|
+
// Later turns — opts.agentSessionId is the captured ses_… id. We pass
|
|
11
|
+
// `--session <id>` so opencode reads the conversation from
|
|
12
|
+
// its own DB instead of relying on im-hub stitching the
|
|
13
|
+
// history into the prompt. router.callAgentWithHistory
|
|
14
|
+
// honours this by zeroing out `effectiveHistory` whenever
|
|
15
|
+
// `agentSessionResume` is true.
|
|
16
|
+
//
|
|
17
|
+
// Cost accounting: opencode emits `cost` and `tokens.{input,output}` in
|
|
18
|
+
// `step_finish` events. We forward those as opts.onUsage deltas so /stats
|
|
19
|
+
// reflects opencode reality (it had been hard-coded to 0 before).
|
|
20
|
+
//
|
|
21
|
+
// Known limitation (the reason OpenCodeHttpAdapter exists): `opencode run`'s
|
|
22
|
+
// stdout JSON stream does NOT emit `permission.asked`, and its inline auto-
|
|
23
|
+
// reject logic occasionally fails to release the prompt deferred. Result:
|
|
24
|
+
// process hangs until the 30-min hard timeout fires. The HTTP driver fixes
|
|
25
|
+
// this at the root by driving opencode via its REST + SSE API instead.
|
|
26
|
+
import { AgentBase } from '../../../core/agent-base.js';
|
|
27
|
+
import { resolveAgentCwd } from '../../../core/agent-cwd.js';
|
|
28
|
+
export class OpenCodeAdapter extends AgentBase {
|
|
29
|
+
name = 'opencode';
|
|
30
|
+
aliases = ['oc', 'opencodeai'];
|
|
31
|
+
buildArgs(prompt, opts) {
|
|
32
|
+
const args = ['run', '--format', 'json'];
|
|
33
|
+
if (opts.agentSessionId)
|
|
34
|
+
args.push('--session', opts.agentSessionId);
|
|
35
|
+
if (opts.model)
|
|
36
|
+
args.push('--model', opts.model);
|
|
37
|
+
if (opts.variant)
|
|
38
|
+
args.push('--variant', opts.variant);
|
|
39
|
+
// planMode → opencode's built-in `plan` agent. Its policy denies edit/
|
|
40
|
+
// write outside .opencode/plans/*.md and allows the LLM to call
|
|
41
|
+
// `plan_exit` when it's done — but we intentionally do NOT auto-flip
|
|
42
|
+
// session.planMode on plan_exit (see docs/architecture/plan-mode.md);
|
|
43
|
+
// the user keeps control of the toggle via /plan off.
|
|
44
|
+
if (opts.planMode)
|
|
45
|
+
args.push('--agent', 'plan');
|
|
46
|
+
args.push(prompt);
|
|
47
|
+
return args;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* opencode keys its per-project AGENTS.md and memory off the spawn cwd,
|
|
51
|
+
* so for IM calls we pin to ~/.im-hub-workspaces/opencode/. Non-IM calls
|
|
52
|
+
* (web/scheduler) keep cwd undefined and inherit im-hub's cwd, preserving
|
|
53
|
+
* the prior behavior. See agent-cwd.ts for full rationale.
|
|
54
|
+
*/
|
|
55
|
+
async prepareCommand(prompt, opts) {
|
|
56
|
+
return {
|
|
57
|
+
args: this.buildArgs(prompt, opts),
|
|
58
|
+
cwd: resolveAgentCwd(this.name, opts),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
extractText(event) {
|
|
62
|
+
const e = event;
|
|
63
|
+
if (e.type === 'text' && e.part?.text)
|
|
64
|
+
return e.part.text;
|
|
65
|
+
if (e.type === 'content' && e.content)
|
|
66
|
+
return e.content;
|
|
67
|
+
return '';
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Pull metadata out of every event:
|
|
71
|
+
* - `sessionID` on any event → bubble up via opts.onAgentSessionId so cli
|
|
72
|
+
* can persist it. Idempotent (the callback handles dedup).
|
|
73
|
+
* - `cost` / `tokens` on `step_finish` → bubble up via opts.onUsage so
|
|
74
|
+
* callAgentWithHistory can roll into /stats.
|
|
75
|
+
*/
|
|
76
|
+
inspectEvent(event, opts) {
|
|
77
|
+
const e = event;
|
|
78
|
+
if (e.sessionID && opts.onAgentSessionId) {
|
|
79
|
+
try {
|
|
80
|
+
opts.onAgentSessionId(e.sessionID);
|
|
81
|
+
}
|
|
82
|
+
catch { /* don't let userland callbacks kill the stream */ }
|
|
83
|
+
}
|
|
84
|
+
if (e.type === 'step_finish' && opts.onUsage) {
|
|
85
|
+
// cost / tokens are NESTED inside event.part, not on the event itself.
|
|
86
|
+
const part = e.part;
|
|
87
|
+
const delta = {};
|
|
88
|
+
if (typeof part?.cost === 'number' && Number.isFinite(part.cost))
|
|
89
|
+
delta.costUsd = part.cost;
|
|
90
|
+
if (typeof part?.tokens?.input === 'number')
|
|
91
|
+
delta.tokensInput = part.tokens.input;
|
|
92
|
+
if (typeof part?.tokens?.output === 'number')
|
|
93
|
+
delta.tokensOutput = part.tokens.output;
|
|
94
|
+
if (delta.costUsd !== undefined || delta.tokensInput !== undefined || delta.tokensOutput !== undefined) {
|
|
95
|
+
try {
|
|
96
|
+
opts.onUsage(delta);
|
|
97
|
+
}
|
|
98
|
+
catch { /* same — user callback safety */ }
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=opencode-stdio-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencode-stdio-adapter.js","sourceRoot":"","sources":["../../../../src/plugins/agents/opencode/opencode-stdio-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface ServeOptions {
|
|
2
|
+
/** Port to bind. Default: env IMHUB_OPENCODE_PORT or 14199. */
|
|
3
|
+
port?: number;
|
|
4
|
+
/** Host to bind. Default: 127.0.0.1. */
|
|
5
|
+
hostname?: string;
|
|
6
|
+
/** cwd for the spawn. Has no effect on per-session directory (sessions are
|
|
7
|
+
* created with their own directory) but determines where opencode looks
|
|
8
|
+
* for its global config. Default: process.cwd(). */
|
|
9
|
+
cwd?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare class OpencodeServeManager {
|
|
12
|
+
private child;
|
|
13
|
+
private baseUrl;
|
|
14
|
+
private startPromise;
|
|
15
|
+
private readonly opts;
|
|
16
|
+
constructor(opts?: ServeOptions);
|
|
17
|
+
/** Start the daemon if needed and return the base URL once ready. Idempotent. */
|
|
18
|
+
ensureRunning(): Promise<string>;
|
|
19
|
+
isRunning(): boolean;
|
|
20
|
+
getBaseUrl(): string | null;
|
|
21
|
+
/** Stop the daemon. Used by tests and on im-hub shutdown. */
|
|
22
|
+
stop(): Promise<void>;
|
|
23
|
+
private spawnAndWait;
|
|
24
|
+
}
|
|
25
|
+
/** Process-wide singleton. Tests can `new OpencodeServeManager()` on their own. */
|
|
26
|
+
export declare const opencodeServe: OpencodeServeManager;
|
|
27
|
+
//# sourceMappingURL=serve-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve-manager.d.ts","sourceRoot":"","sources":["../../../../src/plugins/agents/opencode/serve-manager.ts"],"names":[],"mappings":"AA2BA,MAAM,WAAW,YAAY;IAC3B,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;yDAEqD;IACrD,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,KAAK,CAA4B;IACzC,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,YAAY,CAA+B;IACnD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAkE;gBAE3E,IAAI,GAAE,YAAiB;IASnC,iFAAiF;IACjF,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAWhC,SAAS,IAAI,OAAO;IAIpB,UAAU,IAAI,MAAM,GAAG,IAAI;IAE3B,6DAA6D;IACvD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAiBb,YAAY;CAiG3B;AAuBD,mFAAmF;AACnF,eAAO,MAAM,aAAa,sBAA6B,CAAA"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
// OpencodeServeManager — lazy-launches and supervises a single
|
|
2
|
+
// `opencode serve` daemon that the HTTP adapter and the IM permission
|
|
3
|
+
// bridge talk to.
|
|
4
|
+
//
|
|
5
|
+
// Design notes:
|
|
6
|
+
// - Singleton per im-hub process. Multiple IM threads share one daemon —
|
|
7
|
+
// opencode's session model is per-session anyway, so collisions don't
|
|
8
|
+
// happen on the wire.
|
|
9
|
+
// - First call to ensureRunning() starts the child; readiness is detected
|
|
10
|
+
// by watching stderr for "listening on http://…" (the line opencode emits
|
|
11
|
+
// unconditionally) and falling back to an HTTP probe if that's missed.
|
|
12
|
+
// - If the child dies, the next ensureRunning() respawns. We don't
|
|
13
|
+
// auto-restart in the background — silent restart loops hide problems.
|
|
14
|
+
// - Bound to 127.0.0.1 by default. The server warns about
|
|
15
|
+
// OPENCODE_SERVER_PASSWORD being unset; we silence that intentionally
|
|
16
|
+
// since the surface is loopback only. Set it via env if you expose the
|
|
17
|
+
// port off-host.
|
|
18
|
+
import { crossSpawn } from '../../../utils/cross-platform.js';
|
|
19
|
+
import { logger as rootLogger } from '../../../core/logger.js';
|
|
20
|
+
const log = rootLogger.child({ component: 'opencode.serve' });
|
|
21
|
+
const READY_TIMEOUT_MS = 15_000;
|
|
22
|
+
const READY_REGEX = /listening on (https?:\/\/[^\s]+)/i;
|
|
23
|
+
export class OpencodeServeManager {
|
|
24
|
+
child = null;
|
|
25
|
+
baseUrl = null;
|
|
26
|
+
startPromise = null;
|
|
27
|
+
opts;
|
|
28
|
+
constructor(opts = {}) {
|
|
29
|
+
const envPort = process.env.IMHUB_OPENCODE_PORT;
|
|
30
|
+
this.opts = {
|
|
31
|
+
port: opts.port ?? (envPort ? parseInt(envPort, 10) : 14199),
|
|
32
|
+
hostname: opts.hostname ?? '127.0.0.1',
|
|
33
|
+
cwd: opts.cwd,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/** Start the daemon if needed and return the base URL once ready. Idempotent. */
|
|
37
|
+
ensureRunning() {
|
|
38
|
+
if (this.baseUrl && this.child && !this.child.killed) {
|
|
39
|
+
return Promise.resolve(this.baseUrl);
|
|
40
|
+
}
|
|
41
|
+
if (this.startPromise)
|
|
42
|
+
return this.startPromise;
|
|
43
|
+
this.startPromise = this.spawnAndWait().finally(() => {
|
|
44
|
+
this.startPromise = null;
|
|
45
|
+
});
|
|
46
|
+
return this.startPromise;
|
|
47
|
+
}
|
|
48
|
+
isRunning() {
|
|
49
|
+
return this.child !== null && !this.child.killed && this.baseUrl !== null;
|
|
50
|
+
}
|
|
51
|
+
getBaseUrl() { return this.baseUrl; }
|
|
52
|
+
/** Stop the daemon. Used by tests and on im-hub shutdown. */
|
|
53
|
+
async stop() {
|
|
54
|
+
const child = this.child;
|
|
55
|
+
if (!child)
|
|
56
|
+
return;
|
|
57
|
+
this.child = null;
|
|
58
|
+
this.baseUrl = null;
|
|
59
|
+
return new Promise((resolve) => {
|
|
60
|
+
const kill = setTimeout(() => {
|
|
61
|
+
try {
|
|
62
|
+
child.kill('SIGKILL');
|
|
63
|
+
}
|
|
64
|
+
catch { /* ignore */ }
|
|
65
|
+
}, 2000);
|
|
66
|
+
child.once('close', () => {
|
|
67
|
+
clearTimeout(kill);
|
|
68
|
+
resolve();
|
|
69
|
+
});
|
|
70
|
+
try {
|
|
71
|
+
child.kill('SIGTERM');
|
|
72
|
+
}
|
|
73
|
+
catch { /* ignore */ }
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
async spawnAndWait() {
|
|
77
|
+
const { port, hostname, cwd } = this.opts;
|
|
78
|
+
const candidateUrl = `http://${hostname}:${port}`;
|
|
79
|
+
// Probe before spawn: a previous im-hub run (or our own restart) may have
|
|
80
|
+
// left a healthy `opencode serve` on the same port. Spawning a second one
|
|
81
|
+
// would just bind-fail with code=1 and break the next user message — we
|
|
82
|
+
// saw exactly that in audit row 309 on 2026-05-04. If the port answers
|
|
83
|
+
// and the response looks like opencode, reuse it instead.
|
|
84
|
+
if (await probeOpencodeServe(candidateUrl)) {
|
|
85
|
+
this.baseUrl = candidateUrl;
|
|
86
|
+
log.info({ event: 'opencode.serve.reused', baseUrl: candidateUrl }, 'reusing existing opencode serve on configured port');
|
|
87
|
+
return candidateUrl;
|
|
88
|
+
}
|
|
89
|
+
log.info({ event: 'opencode.serve.starting', port, hostname }, 'starting opencode serve');
|
|
90
|
+
const child = crossSpawn('opencode', ['serve', '--port', String(port), '--hostname', hostname], {
|
|
91
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
92
|
+
cwd,
|
|
93
|
+
env: process.env,
|
|
94
|
+
});
|
|
95
|
+
this.child = child;
|
|
96
|
+
let resolved = false;
|
|
97
|
+
const ready = new Promise((resolve, reject) => {
|
|
98
|
+
const timer = setTimeout(() => {
|
|
99
|
+
if (resolved)
|
|
100
|
+
return;
|
|
101
|
+
resolved = true;
|
|
102
|
+
log.error({ event: 'opencode.serve.timeout' }, 'opencode serve did not become ready in time');
|
|
103
|
+
try {
|
|
104
|
+
child.kill('SIGTERM');
|
|
105
|
+
}
|
|
106
|
+
catch { /* ignore */ }
|
|
107
|
+
reject(new Error('opencode serve did not become ready within ' + READY_TIMEOUT_MS + 'ms'));
|
|
108
|
+
}, READY_TIMEOUT_MS);
|
|
109
|
+
const onLine = (line) => {
|
|
110
|
+
const m = line.match(READY_REGEX);
|
|
111
|
+
if (m && !resolved) {
|
|
112
|
+
resolved = true;
|
|
113
|
+
clearTimeout(timer);
|
|
114
|
+
this.baseUrl = m[1].replace(/\/+$/, '');
|
|
115
|
+
log.info({ event: 'opencode.serve.ready', baseUrl: this.baseUrl }, 'opencode serve ready');
|
|
116
|
+
resolve(this.baseUrl);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
const stderr = child.stderr;
|
|
120
|
+
const stdout = child.stdout;
|
|
121
|
+
let stderrBuf = '';
|
|
122
|
+
let stdoutBuf = '';
|
|
123
|
+
stderr?.on('data', (data) => {
|
|
124
|
+
stderrBuf += data.toString('utf8');
|
|
125
|
+
let nl;
|
|
126
|
+
while ((nl = stderrBuf.indexOf('\n')) !== -1) {
|
|
127
|
+
const line = stderrBuf.slice(0, nl);
|
|
128
|
+
stderrBuf = stderrBuf.slice(nl + 1);
|
|
129
|
+
if (line.trim())
|
|
130
|
+
onLine(line);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
stdout?.on('data', (data) => {
|
|
134
|
+
stdoutBuf += data.toString('utf8');
|
|
135
|
+
let nl;
|
|
136
|
+
while ((nl = stdoutBuf.indexOf('\n')) !== -1) {
|
|
137
|
+
const line = stdoutBuf.slice(0, nl);
|
|
138
|
+
stdoutBuf = stdoutBuf.slice(nl + 1);
|
|
139
|
+
if (line.trim())
|
|
140
|
+
onLine(line);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
child.on('error', (err) => {
|
|
144
|
+
if (resolved)
|
|
145
|
+
return;
|
|
146
|
+
resolved = true;
|
|
147
|
+
clearTimeout(timer);
|
|
148
|
+
reject(err);
|
|
149
|
+
});
|
|
150
|
+
child.on('close', (code, signal) => {
|
|
151
|
+
log.warn({ event: 'opencode.serve.exited', code, signal }, 'opencode serve exited');
|
|
152
|
+
if (this.child === child) {
|
|
153
|
+
this.child = null;
|
|
154
|
+
this.baseUrl = null;
|
|
155
|
+
}
|
|
156
|
+
if (!resolved) {
|
|
157
|
+
resolved = true;
|
|
158
|
+
clearTimeout(timer);
|
|
159
|
+
reject(new Error(`opencode serve exited before ready (code=${code}, signal=${signal})`));
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
return ready;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Probe a candidate URL: if `GET /` returns 2xx within ~500ms, treat the
|
|
168
|
+
* port as already serving an opencode instance we can reuse. We don't try
|
|
169
|
+
* to fingerprint the response body — the localhost-only attack surface
|
|
170
|
+
* doesn't justify it; if some other service happens to listen on the
|
|
171
|
+
* configured port the reuse path will fail later when /event is hit and
|
|
172
|
+
* the adapter surfaces a clear error to the user.
|
|
173
|
+
*/
|
|
174
|
+
async function probeOpencodeServe(baseUrl) {
|
|
175
|
+
const controller = new AbortController();
|
|
176
|
+
const timer = setTimeout(() => controller.abort(), 500);
|
|
177
|
+
try {
|
|
178
|
+
const res = await fetch(baseUrl + '/', { signal: controller.signal });
|
|
179
|
+
return res.ok;
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
finally {
|
|
185
|
+
clearTimeout(timer);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/** Process-wide singleton. Tests can `new OpencodeServeManager()` on their own. */
|
|
189
|
+
export const opencodeServe = new OpencodeServeManager();
|
|
190
|
+
//# sourceMappingURL=serve-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve-manager.js","sourceRoot":"","sources":["../../../../src/plugins/agents/opencode/serve-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { MessengerAdapter, MessageContext } from '../../../core/types.js';
|
|
2
|
+
export declare class DiscordAdapter implements MessengerAdapter {
|
|
3
|
+
readonly name = "discord";
|
|
4
|
+
private client;
|
|
5
|
+
private config;
|
|
6
|
+
private messageHandler?;
|
|
7
|
+
private isRunning;
|
|
8
|
+
private typingIntervals;
|
|
9
|
+
/** L7: companion AbortController per typing thread. Lets the periodic
|
|
10
|
+
* refresh callback bail BEFORE invoking sendTyping when stop() has
|
|
11
|
+
* fired, instead of racing against client.destroy(). */
|
|
12
|
+
private typingAbortControllers;
|
|
13
|
+
start(): Promise<void>;
|
|
14
|
+
stop(): Promise<void>;
|
|
15
|
+
onMessage(handler: (ctx: MessageContext) => Promise<void>): void;
|
|
16
|
+
sendMessage(threadId: string, text: string): Promise<void>;
|
|
17
|
+
sendTyping(threadId: string, isTyping: boolean): Promise<void>;
|
|
18
|
+
private fetchSendableChannel;
|
|
19
|
+
private handleDiscordMessage;
|
|
20
|
+
}
|
|
21
|
+
export declare const discordAdapter: DiscordAdapter;
|
|
22
|
+
//# sourceMappingURL=discord-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discord-adapter.d.ts","sourceRoot":"","sources":["../../../../src/plugins/messengers/discord/discord-adapter.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAW,MAAM,wBAAwB,CAAA;AAWvF,qBAAa,cAAe,YAAW,gBAAgB;IACrD,QAAQ,CAAC,IAAI,aAAY;IACzB,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,cAAc,CAAC,CAAwC;IAC/D,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,eAAe,CAAoD;IAC3E;;6DAEyD;IACzD,OAAO,CAAC,sBAAsB,CAAqC;IAE7D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA2DtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAyB3B,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAI1D,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsB1D,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;YA4DtD,oBAAoB;YAcpB,oBAAoB;CAyDnC;AAGD,eAAO,MAAM,cAAc,gBAAuB,CAAA"}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
// Discord Bot API Adapter using discord.js
|
|
2
|
+
// Implements MessengerAdapter interface with typing indicator support
|
|
3
|
+
import { Client, GatewayIntentBits, Partials, ChannelType, } from 'discord.js';
|
|
4
|
+
import { markdownToDiscord } from './markdown-to-discord.js';
|
|
5
|
+
import { splitMessage } from '../../../utils/message-split.js';
|
|
6
|
+
import { logger as rootLogger } from '../../../core/logger.js';
|
|
7
|
+
const log = rootLogger.child({ component: 'discord' });
|
|
8
|
+
// Discord message limit is 2000 characters
|
|
9
|
+
const DISCORD_MAX_LENGTH = 2000;
|
|
10
|
+
export class DiscordAdapter {
|
|
11
|
+
name = 'discord';
|
|
12
|
+
client = null;
|
|
13
|
+
config = null;
|
|
14
|
+
messageHandler;
|
|
15
|
+
isRunning = false;
|
|
16
|
+
typingIntervals = new Map();
|
|
17
|
+
/** L7: companion AbortController per typing thread. Lets the periodic
|
|
18
|
+
* refresh callback bail BEFORE invoking sendTyping when stop() has
|
|
19
|
+
* fired, instead of racing against client.destroy(). */
|
|
20
|
+
typingAbortControllers = new Map();
|
|
21
|
+
async start() {
|
|
22
|
+
// Load config
|
|
23
|
+
const { readFile } = await import('fs/promises');
|
|
24
|
+
const { homedir } = await import('os');
|
|
25
|
+
const { join } = await import('path');
|
|
26
|
+
const configPath = join(homedir(), '.im-hub', 'config.json');
|
|
27
|
+
try {
|
|
28
|
+
const data = await readFile(configPath, 'utf-8');
|
|
29
|
+
const config = JSON.parse(data);
|
|
30
|
+
this.config = config.discord;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
throw new Error('Discord config not found. Run "im-hub config discord" first.');
|
|
34
|
+
}
|
|
35
|
+
if (!this.config?.botToken) {
|
|
36
|
+
throw new Error('Discord bot token not configured. Run "im-hub config discord" first.');
|
|
37
|
+
}
|
|
38
|
+
// Initialize Discord client with required intents
|
|
39
|
+
this.client = new Client({
|
|
40
|
+
intents: [
|
|
41
|
+
GatewayIntentBits.Guilds,
|
|
42
|
+
GatewayIntentBits.GuildMessages,
|
|
43
|
+
GatewayIntentBits.MessageContent, // Privileged intent - must enable in Developer Portal
|
|
44
|
+
GatewayIntentBits.DirectMessages, // For DM support
|
|
45
|
+
],
|
|
46
|
+
partials: [
|
|
47
|
+
Partials.Channel, // Required for DM support
|
|
48
|
+
Partials.Message,
|
|
49
|
+
],
|
|
50
|
+
});
|
|
51
|
+
// Ready event
|
|
52
|
+
this.client.on('ready', (client) => {
|
|
53
|
+
log.info({ user: client.user.tag, guilds: client.guilds.cache.size }, `Discord bot logged in as ${client.user.tag}`);
|
|
54
|
+
});
|
|
55
|
+
// Set up message handler
|
|
56
|
+
this.client.on('messageCreate', async (message) => {
|
|
57
|
+
await this.handleDiscordMessage(message);
|
|
58
|
+
});
|
|
59
|
+
// Error handling
|
|
60
|
+
this.client.on('error', (error) => {
|
|
61
|
+
log.error({ err: error.message }, 'Discord client error');
|
|
62
|
+
});
|
|
63
|
+
this.client.on('warn', (warning) => {
|
|
64
|
+
log.warn({ warning }, 'Discord client warning');
|
|
65
|
+
});
|
|
66
|
+
// Login to Discord
|
|
67
|
+
await this.client.login(this.config.botToken);
|
|
68
|
+
this.isRunning = true;
|
|
69
|
+
log.info('Discord adapter started');
|
|
70
|
+
}
|
|
71
|
+
async stop() {
|
|
72
|
+
this.isRunning = false;
|
|
73
|
+
// L7: abort first (signal in-flight refresh callbacks to bail) then
|
|
74
|
+
// clearInterval (prevent new ticks). Doing it in the other order would
|
|
75
|
+
// leave one tick that already entered the callback racing with
|
|
76
|
+
// client.destroy(); even though sendTyping errors are caught, the
|
|
77
|
+
// log line is noise and the API call wastes a request.
|
|
78
|
+
for (const ac of this.typingAbortControllers.values()) {
|
|
79
|
+
ac.abort();
|
|
80
|
+
}
|
|
81
|
+
this.typingAbortControllers.clear();
|
|
82
|
+
for (const interval of this.typingIntervals.values()) {
|
|
83
|
+
clearInterval(interval);
|
|
84
|
+
}
|
|
85
|
+
this.typingIntervals.clear();
|
|
86
|
+
if (this.client) {
|
|
87
|
+
this.client.destroy();
|
|
88
|
+
this.client = null;
|
|
89
|
+
}
|
|
90
|
+
log.info('Discord adapter stopped');
|
|
91
|
+
}
|
|
92
|
+
onMessage(handler) {
|
|
93
|
+
this.messageHandler = handler;
|
|
94
|
+
}
|
|
95
|
+
async sendMessage(threadId, text) {
|
|
96
|
+
if (!this.client) {
|
|
97
|
+
throw new Error('Discord adapter not started');
|
|
98
|
+
}
|
|
99
|
+
const channel = await this.fetchSendableChannel(threadId);
|
|
100
|
+
if (!channel) {
|
|
101
|
+
throw new Error(`Channel ${threadId} not found or not text-based`);
|
|
102
|
+
}
|
|
103
|
+
// Convert markdown and split into chunks
|
|
104
|
+
const discordText = markdownToDiscord(text);
|
|
105
|
+
const chunks = splitMessage(discordText, {
|
|
106
|
+
maxLength: DISCORD_MAX_LENGTH,
|
|
107
|
+
addContinuationMarker: false,
|
|
108
|
+
});
|
|
109
|
+
for (const chunk of chunks) {
|
|
110
|
+
await channel.send(chunk);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
async sendTyping(threadId, isTyping) {
|
|
114
|
+
if (!this.client) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
if (isTyping) {
|
|
118
|
+
const channel = await this.fetchSendableChannel(threadId);
|
|
119
|
+
if (!channel) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
// Send initial typing indicator
|
|
123
|
+
try {
|
|
124
|
+
await channel.sendTyping();
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
// Ignore errors during typing
|
|
128
|
+
}
|
|
129
|
+
// Clear any existing interval + abort signal — both per-thread.
|
|
130
|
+
const existing = this.typingIntervals.get(threadId);
|
|
131
|
+
if (existing)
|
|
132
|
+
clearInterval(existing);
|
|
133
|
+
const existingAc = this.typingAbortControllers.get(threadId);
|
|
134
|
+
if (existingAc)
|
|
135
|
+
existingAc.abort();
|
|
136
|
+
// Discord typing indicator lasts ~10 seconds, refresh every 8 seconds.
|
|
137
|
+
// L7: AbortController gates each tick — when stop() (or a subsequent
|
|
138
|
+
// sendTyping(false)) aborts, in-flight callbacks bail early instead
|
|
139
|
+
// of racing client.destroy().
|
|
140
|
+
const ac = new AbortController();
|
|
141
|
+
const interval = setInterval(async () => {
|
|
142
|
+
if (ac.signal.aborted)
|
|
143
|
+
return;
|
|
144
|
+
try {
|
|
145
|
+
await channel.sendTyping();
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
// Ignore errors during typing refresh
|
|
149
|
+
}
|
|
150
|
+
}, 8000);
|
|
151
|
+
this.typingIntervals.set(threadId, interval);
|
|
152
|
+
this.typingAbortControllers.set(threadId, ac);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
// Clear the refresh interval + abort signal
|
|
156
|
+
const interval = this.typingIntervals.get(threadId);
|
|
157
|
+
if (interval) {
|
|
158
|
+
clearInterval(interval);
|
|
159
|
+
this.typingIntervals.delete(threadId);
|
|
160
|
+
}
|
|
161
|
+
const ac = this.typingAbortControllers.get(threadId);
|
|
162
|
+
if (ac) {
|
|
163
|
+
ac.abort();
|
|
164
|
+
this.typingAbortControllers.delete(threadId);
|
|
165
|
+
}
|
|
166
|
+
// Note: Discord has no "cancel typing" API - it just expires naturally
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// ============================================
|
|
170
|
+
// Internal methods
|
|
171
|
+
// ============================================
|
|
172
|
+
async fetchSendableChannel(threadId) {
|
|
173
|
+
if (!this.client)
|
|
174
|
+
return null;
|
|
175
|
+
const channel = await this.client.channels.fetch(threadId).catch(() => null);
|
|
176
|
+
if (!channel)
|
|
177
|
+
return null;
|
|
178
|
+
if (channel.type === ChannelType.GuildText || channel.type === ChannelType.DM) {
|
|
179
|
+
return channel;
|
|
180
|
+
}
|
|
181
|
+
// Also support announcement/thread channels
|
|
182
|
+
if (channel.isTextBased() && 'send' in channel) {
|
|
183
|
+
return channel;
|
|
184
|
+
}
|
|
185
|
+
return null;
|
|
186
|
+
}
|
|
187
|
+
async handleDiscordMessage(message) {
|
|
188
|
+
// Ignore bot messages (including our own)
|
|
189
|
+
if (message.author.bot) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
// Guild whitelist filter
|
|
193
|
+
if (this.config?.allowedGuilds?.length && message.guildId) {
|
|
194
|
+
if (!this.config.allowedGuilds.includes(message.guildId)) {
|
|
195
|
+
log.debug({ guildId: message.guildId }, 'Message from non-whitelisted guild, ignoring');
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
// Channel whitelist filter
|
|
200
|
+
if (this.config?.allowedChannels?.length) {
|
|
201
|
+
if (!this.config.allowedChannels.includes(message.channelId)) {
|
|
202
|
+
log.debug({ channelId: message.channelId }, 'Message from non-whitelisted channel, ignoring');
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
// Skip empty messages (e.g. image-only, embed-only)
|
|
207
|
+
if (!message.content && !message.attachments.size) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
if (!this.messageHandler) {
|
|
211
|
+
log.debug('No message handler registered');
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
try {
|
|
215
|
+
const msg = {
|
|
216
|
+
id: message.id,
|
|
217
|
+
threadId: message.channelId,
|
|
218
|
+
userId: message.author.id,
|
|
219
|
+
text: message.content || '',
|
|
220
|
+
timestamp: message.createdAt,
|
|
221
|
+
channelId: this.config?.channelId || 'default',
|
|
222
|
+
};
|
|
223
|
+
const msgCtx = {
|
|
224
|
+
message: msg,
|
|
225
|
+
platform: 'discord',
|
|
226
|
+
channelId: this.config?.channelId || 'default',
|
|
227
|
+
};
|
|
228
|
+
log.debug({ threadId: msg.threadId, userId: msg.userId }, 'Calling message handler');
|
|
229
|
+
await this.messageHandler(msgCtx);
|
|
230
|
+
log.debug({ threadId: msg.threadId }, 'Message handler completed');
|
|
231
|
+
}
|
|
232
|
+
catch (err) {
|
|
233
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
234
|
+
const stack = err instanceof Error ? err.stack : undefined;
|
|
235
|
+
log.error({ err: errMsg, stack }, 'Error in message handler');
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// Singleton instance
|
|
240
|
+
export const discordAdapter = new DiscordAdapter();
|
|
241
|
+
//# sourceMappingURL=discord-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discord-adapter.js","sourceRoot":"","sources":["../../../../src/plugins/messengers/discord/discord-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discord-adapter.test.d.ts","sourceRoot":"","sources":["../../../../src/plugins/messengers/discord/discord-adapter.test.ts"],"names":[],"mappings":""}
|