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,149 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'bun:test';
|
|
2
|
+
import { mkdtemp, readFile, writeFile, rm, access } from 'fs/promises';
|
|
3
|
+
import { tmpdir } from 'os';
|
|
4
|
+
import { join } from 'path';
|
|
5
|
+
import { resolveAgentCwd, defaultAgentCwd, imhubWorkspacesRoot, ensureAgentWorkspace, bootstrapAgentWorkspaces, } from './agent-cwd.js';
|
|
6
|
+
const FULL_IM_OPTS = { threadId: 'thread-A', platform: 'feishu', channelId: 'chan-1', userId: 'u1' };
|
|
7
|
+
const NO_IM_OPTS = { model: 'sonnet' };
|
|
8
|
+
describe('resolveAgentCwd', () => {
|
|
9
|
+
let tmpRoot;
|
|
10
|
+
let prevRoot;
|
|
11
|
+
let prevClaudeOverride;
|
|
12
|
+
let prevOpencodeOverride;
|
|
13
|
+
beforeEach(async () => {
|
|
14
|
+
tmpRoot = await mkdtemp(join(tmpdir(), 'imhub-cwdtest-'));
|
|
15
|
+
prevRoot = process.env.IMHUB_WORKSPACES_ROOT;
|
|
16
|
+
prevClaudeOverride = process.env.IMHUB_CLAUDE_CODE_CWD;
|
|
17
|
+
prevOpencodeOverride = process.env.IMHUB_OPENCODE_CWD;
|
|
18
|
+
process.env.IMHUB_WORKSPACES_ROOT = tmpRoot;
|
|
19
|
+
delete process.env.IMHUB_CLAUDE_CODE_CWD;
|
|
20
|
+
delete process.env.IMHUB_OPENCODE_CWD;
|
|
21
|
+
});
|
|
22
|
+
afterEach(async () => {
|
|
23
|
+
if (prevRoot === undefined)
|
|
24
|
+
delete process.env.IMHUB_WORKSPACES_ROOT;
|
|
25
|
+
else
|
|
26
|
+
process.env.IMHUB_WORKSPACES_ROOT = prevRoot;
|
|
27
|
+
if (prevClaudeOverride === undefined)
|
|
28
|
+
delete process.env.IMHUB_CLAUDE_CODE_CWD;
|
|
29
|
+
else
|
|
30
|
+
process.env.IMHUB_CLAUDE_CODE_CWD = prevClaudeOverride;
|
|
31
|
+
if (prevOpencodeOverride === undefined)
|
|
32
|
+
delete process.env.IMHUB_OPENCODE_CWD;
|
|
33
|
+
else
|
|
34
|
+
process.env.IMHUB_OPENCODE_CWD = prevOpencodeOverride;
|
|
35
|
+
await rm(tmpRoot, { recursive: true, force: true });
|
|
36
|
+
});
|
|
37
|
+
it('returns default workspace dir when full IM context is present', () => {
|
|
38
|
+
expect(resolveAgentCwd('claude-code', FULL_IM_OPTS)).toBe(join(tmpRoot, 'claude-code'));
|
|
39
|
+
});
|
|
40
|
+
it('returns undefined for non-IM call (web/scheduler), preserving inherited cwd', () => {
|
|
41
|
+
expect(resolveAgentCwd('claude-code', NO_IM_OPTS)).toBeUndefined();
|
|
42
|
+
});
|
|
43
|
+
it('returns undefined when only one of threadId/platform is set', () => {
|
|
44
|
+
expect(resolveAgentCwd('claude-code', { threadId: 't1' })).toBeUndefined();
|
|
45
|
+
expect(resolveAgentCwd('claude-code', { platform: 'feishu' })).toBeUndefined();
|
|
46
|
+
});
|
|
47
|
+
it('env override beats default IM dir', () => {
|
|
48
|
+
process.env.IMHUB_CLAUDE_CODE_CWD = '/srv/explicit';
|
|
49
|
+
expect(resolveAgentCwd('claude-code', FULL_IM_OPTS)).toBe('/srv/explicit');
|
|
50
|
+
});
|
|
51
|
+
it('env override also wins for non-IM calls (admin escape hatch)', () => {
|
|
52
|
+
process.env.IMHUB_CLAUDE_CODE_CWD = '/srv/explicit';
|
|
53
|
+
expect(resolveAgentCwd('claude-code', NO_IM_OPTS)).toBe('/srv/explicit');
|
|
54
|
+
});
|
|
55
|
+
it('env key respects per-agent naming (hyphen to underscore, uppercase)', () => {
|
|
56
|
+
process.env.IMHUB_OPENCODE_CWD = '/srv/oc';
|
|
57
|
+
expect(resolveAgentCwd('opencode', FULL_IM_OPTS)).toBe('/srv/oc');
|
|
58
|
+
expect(resolveAgentCwd('claude-code', FULL_IM_OPTS)).toBe(join(tmpRoot, 'claude-code'));
|
|
59
|
+
});
|
|
60
|
+
it('IMHUB_WORKSPACES_ROOT moves the default for every agent at once', () => {
|
|
61
|
+
expect(imhubWorkspacesRoot()).toBe(tmpRoot);
|
|
62
|
+
expect(defaultAgentCwd('claude-code')).toBe(join(tmpRoot, 'claude-code'));
|
|
63
|
+
expect(defaultAgentCwd('opencode')).toBe(join(tmpRoot, 'opencode'));
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
describe('ensureAgentWorkspace', () => {
|
|
67
|
+
let tmpRoot;
|
|
68
|
+
let prevRoot;
|
|
69
|
+
beforeEach(async () => {
|
|
70
|
+
tmpRoot = await mkdtemp(join(tmpdir(), 'imhub-cwdtest-'));
|
|
71
|
+
prevRoot = process.env.IMHUB_WORKSPACES_ROOT;
|
|
72
|
+
process.env.IMHUB_WORKSPACES_ROOT = tmpRoot;
|
|
73
|
+
});
|
|
74
|
+
afterEach(async () => {
|
|
75
|
+
if (prevRoot === undefined)
|
|
76
|
+
delete process.env.IMHUB_WORKSPACES_ROOT;
|
|
77
|
+
else
|
|
78
|
+
process.env.IMHUB_WORKSPACES_ROOT = prevRoot;
|
|
79
|
+
await rm(tmpRoot, { recursive: true, force: true });
|
|
80
|
+
});
|
|
81
|
+
it('creates the dir and seed file when missing', async () => {
|
|
82
|
+
const dir = await ensureAgentWorkspace('claude-code', { filename: 'CLAUDE.md', content: '# seed' });
|
|
83
|
+
expect(dir).toBe(join(tmpRoot, 'claude-code'));
|
|
84
|
+
expect(await readFile(join(dir, 'CLAUDE.md'), 'utf8')).toBe('# seed');
|
|
85
|
+
});
|
|
86
|
+
it('does NOT overwrite an existing seed file', async () => {
|
|
87
|
+
const dir = join(tmpRoot, 'claude-code');
|
|
88
|
+
await ensureAgentWorkspace('claude-code', { filename: 'CLAUDE.md', content: '# seed' });
|
|
89
|
+
await writeFile(join(dir, 'CLAUDE.md'), 'USER EDITED', 'utf8');
|
|
90
|
+
await ensureAgentWorkspace('claude-code', { filename: 'CLAUDE.md', content: '# new seed' });
|
|
91
|
+
expect(await readFile(join(dir, 'CLAUDE.md'), 'utf8')).toBe('USER EDITED');
|
|
92
|
+
});
|
|
93
|
+
it('is fully idempotent across many calls', async () => {
|
|
94
|
+
for (let i = 0; i < 5; i++) {
|
|
95
|
+
await ensureAgentWorkspace('opencode', { filename: 'AGENTS.md', content: '# x' });
|
|
96
|
+
}
|
|
97
|
+
expect(await readFile(join(tmpRoot, 'opencode', 'AGENTS.md'), 'utf8')).toBe('# x');
|
|
98
|
+
});
|
|
99
|
+
it('honors IMHUB_<AGENT>_CWD override and bootstraps THAT path instead', async () => {
|
|
100
|
+
const altDir = join(tmpRoot, 'custom-spot');
|
|
101
|
+
process.env.IMHUB_CLAUDE_CODE_CWD = altDir;
|
|
102
|
+
try {
|
|
103
|
+
const dir = await ensureAgentWorkspace('claude-code', { filename: 'CLAUDE.md', content: '# alt' });
|
|
104
|
+
expect(dir).toBe(altDir);
|
|
105
|
+
expect(await readFile(join(altDir, 'CLAUDE.md'), 'utf8')).toBe('# alt');
|
|
106
|
+
let defaultExists = false;
|
|
107
|
+
try {
|
|
108
|
+
await access(join(tmpRoot, 'claude-code'));
|
|
109
|
+
defaultExists = true;
|
|
110
|
+
}
|
|
111
|
+
catch { /* expected */ }
|
|
112
|
+
expect(defaultExists).toBe(false);
|
|
113
|
+
}
|
|
114
|
+
finally {
|
|
115
|
+
delete process.env.IMHUB_CLAUDE_CODE_CWD;
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
describe('bootstrapAgentWorkspaces', () => {
|
|
120
|
+
let tmpRoot;
|
|
121
|
+
let prevRoot;
|
|
122
|
+
beforeEach(async () => {
|
|
123
|
+
tmpRoot = await mkdtemp(join(tmpdir(), 'imhub-cwdtest-'));
|
|
124
|
+
prevRoot = process.env.IMHUB_WORKSPACES_ROOT;
|
|
125
|
+
process.env.IMHUB_WORKSPACES_ROOT = tmpRoot;
|
|
126
|
+
});
|
|
127
|
+
afterEach(async () => {
|
|
128
|
+
if (prevRoot === undefined)
|
|
129
|
+
delete process.env.IMHUB_WORKSPACES_ROOT;
|
|
130
|
+
else
|
|
131
|
+
process.env.IMHUB_WORKSPACES_ROOT = prevRoot;
|
|
132
|
+
await rm(tmpRoot, { recursive: true, force: true });
|
|
133
|
+
});
|
|
134
|
+
it('creates both built-in agent workspaces with their canonical seed files', async () => {
|
|
135
|
+
const result = await bootstrapAgentWorkspaces();
|
|
136
|
+
const byAgent = Object.fromEntries(result.map((r) => [r.agent, r.dir]));
|
|
137
|
+
expect(byAgent['claude-code']).toBe(join(tmpRoot, 'claude-code'));
|
|
138
|
+
expect(byAgent['opencode']).toBe(join(tmpRoot, 'opencode'));
|
|
139
|
+
expect(await readFile(join(tmpRoot, 'claude-code', 'CLAUDE.md'), 'utf8')).toContain('Claude Code');
|
|
140
|
+
expect(await readFile(join(tmpRoot, 'opencode', 'AGENTS.md'), 'utf8')).toContain('OpenCode');
|
|
141
|
+
});
|
|
142
|
+
it('safe to run twice and does not stomp user edits', async () => {
|
|
143
|
+
await bootstrapAgentWorkspaces();
|
|
144
|
+
await writeFile(join(tmpRoot, 'claude-code', 'CLAUDE.md'), 'USER', 'utf8');
|
|
145
|
+
await bootstrapAgentWorkspaces();
|
|
146
|
+
expect(await readFile(join(tmpRoot, 'claude-code', 'CLAUDE.md'), 'utf8')).toBe('USER');
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
//# sourceMappingURL=agent-cwd.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-cwd.test.js","sourceRoot":"","sources":["../../src/core/agent-cwd.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
export interface RunContext {
|
|
2
|
+
threadId: string;
|
|
3
|
+
platform: string;
|
|
4
|
+
userId: string;
|
|
5
|
+
channelId: string;
|
|
6
|
+
}
|
|
7
|
+
/** Wire-format decision sent back to the sidecar. `autoAllowFurther` is
|
|
8
|
+
* internal-only — `sendDecision` strips it before serializing. */
|
|
9
|
+
export type Decision = {
|
|
10
|
+
behavior: 'allow';
|
|
11
|
+
updatedInput?: Record<string, unknown>;
|
|
12
|
+
autoAllowFurther?: boolean;
|
|
13
|
+
} | {
|
|
14
|
+
behavior: 'deny';
|
|
15
|
+
message?: string;
|
|
16
|
+
};
|
|
17
|
+
export interface ApprovalNotification {
|
|
18
|
+
runId: string;
|
|
19
|
+
reqId: string;
|
|
20
|
+
toolName: string;
|
|
21
|
+
input: Record<string, unknown>;
|
|
22
|
+
toolUseId: string;
|
|
23
|
+
ctx: RunContext;
|
|
24
|
+
/** Present iff this request matched a per-thread auto-allow rule. The
|
|
25
|
+
* notifier should render a softer prompt ("⏱ 自动放行中, 5s 内回 n 可拒绝")
|
|
26
|
+
* instead of the regular y/n one — the bus will allow on timer expiry,
|
|
27
|
+
* unless the user actively denies first. */
|
|
28
|
+
autoAllow?: {
|
|
29
|
+
graceMs: number;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/** Notifier 只负责"通知 IM 推卡片/消息"。不要在这里返回决策;决策走 resolvePending。 */
|
|
33
|
+
export type ApprovalNotifier = (n: ApprovalNotification) => Promise<void>;
|
|
34
|
+
/** Snapshot returned by {@link ApprovalBus.resolvePending} so the router can
|
|
35
|
+
* send the user a confirmation receipt ("✅ 已批准并启用自动放行 …" or
|
|
36
|
+
* "❌ 已拒绝并撤销自动放行 …") without re-scanning bus internals. */
|
|
37
|
+
export interface ResolvedInfo {
|
|
38
|
+
runId: string;
|
|
39
|
+
threadId: string;
|
|
40
|
+
platform: string;
|
|
41
|
+
toolName: string;
|
|
42
|
+
/** Same fingerprint the bus uses for the auto-allow rule key. */
|
|
43
|
+
fingerprint: string;
|
|
44
|
+
/** True iff the resolved pending had been created in auto-allow grace
|
|
45
|
+
* mode — i.e. matched an existing rule. Lets the router distinguish
|
|
46
|
+
* "user denied a normal prompt" from "user denied an auto-allow prompt
|
|
47
|
+
* (which also revoked the rule)". */
|
|
48
|
+
wasAutoAllow: boolean;
|
|
49
|
+
}
|
|
50
|
+
/** Why an approval was resolved. Used by ResolutionListener consumers (e.g.
|
|
51
|
+
* approval-router) to decide whether to edit a UI card to "expired" — only
|
|
52
|
+
* non-`user` causes need cleanup, since the user-driven path (button click /
|
|
53
|
+
* text reply) edits the card itself before the listener fires. */
|
|
54
|
+
export type ResolutionCause = 'user' | 'timeout' | 'sidecar-disconnect' | 'run-terminated' | 'shutdown' | 'notifier-error';
|
|
55
|
+
/** Fired exactly once per pending when it transitions from pending → resolved.
|
|
56
|
+
* Mirrors the wire decision sent to sidecar/dispatch but adds context (cause,
|
|
57
|
+
* threadId, platform) so listeners can route side-effects without scanning
|
|
58
|
+
* bus internals. Synchronous; listener errors are logged + swallowed. */
|
|
59
|
+
export interface ResolutionEvent {
|
|
60
|
+
reqId: string;
|
|
61
|
+
runId: string;
|
|
62
|
+
threadId: string;
|
|
63
|
+
platform: string;
|
|
64
|
+
toolName: string;
|
|
65
|
+
fingerprint: string;
|
|
66
|
+
decision: Decision;
|
|
67
|
+
wasAutoAllow: boolean;
|
|
68
|
+
cause: ResolutionCause;
|
|
69
|
+
}
|
|
70
|
+
export type ResolutionListener = (e: ResolutionEvent) => void;
|
|
71
|
+
export interface ApprovalBusOptions {
|
|
72
|
+
approvalTimeoutMs?: number;
|
|
73
|
+
/** Window between sending the auto-allow notice and auto-resolving as
|
|
74
|
+
* allow (when the user doesn't actively deny in the meantime). */
|
|
75
|
+
autoAllowGraceMs?: number;
|
|
76
|
+
}
|
|
77
|
+
export declare class ApprovalBus {
|
|
78
|
+
private server;
|
|
79
|
+
private socketPath;
|
|
80
|
+
private readonly approvalTimeoutMs;
|
|
81
|
+
private readonly autoAllowGraceMs;
|
|
82
|
+
private runContexts;
|
|
83
|
+
private pendingById;
|
|
84
|
+
private pendingByThread;
|
|
85
|
+
private connections;
|
|
86
|
+
private notifier;
|
|
87
|
+
private resolutionListener;
|
|
88
|
+
/** threadId → set of `${toolName}::${prefix}` keys the user has marked
|
|
89
|
+
* as auto-allow within this conversation. Cleared by clearAutoAllowForThread
|
|
90
|
+
* (called from session.resetConversation) and on stop(). */
|
|
91
|
+
private autoAllowByThread;
|
|
92
|
+
/**
|
|
93
|
+
* Lifetime counters surfaced via {@link getMetrics}. Help ops detect
|
|
94
|
+
* leaks (pending growing unbounded), spikes (totalRequests rate), and
|
|
95
|
+
* approval skew (deny:allow ratio). Reset on stop() so the gauge for a
|
|
96
|
+
* fresh process starts at zero.
|
|
97
|
+
*/
|
|
98
|
+
private metricsSnapshot;
|
|
99
|
+
constructor(opts?: ApprovalBusOptions);
|
|
100
|
+
/** 注入"通知 IM 推送"的回调。messenger 层启动时调一次。 */
|
|
101
|
+
setNotifier(n: ApprovalNotifier | null): void;
|
|
102
|
+
/** Subscribe to resolution events. Replaces any previous listener.
|
|
103
|
+
* approval-router uses this to keep its UI cards in sync with bus-side
|
|
104
|
+
* cancellations (timeout / sidecar disconnect / run terminated). The
|
|
105
|
+
* user-driven path (button or y/n text) already edits its own card; the
|
|
106
|
+
* listener still fires there with cause='user' so consumers can dedup. */
|
|
107
|
+
setResolutionListener(l: ResolutionListener | null): void;
|
|
108
|
+
/** 启动 unix socket 服务。返回最终使用的 socket 路径。 */
|
|
109
|
+
start(socketPath?: string): Promise<string>;
|
|
110
|
+
stop(): Promise<void>;
|
|
111
|
+
registerRun(runId: string, ctx: RunContext): void;
|
|
112
|
+
/** 进程结束时调。pending 全 deny,runContext 清掉。 */
|
|
113
|
+
unregisterRun(runId: string): void;
|
|
114
|
+
hasPendingFor(threadId: string): boolean;
|
|
115
|
+
/** True iff a notifier has been installed (i.e. messenger layer has wired
|
|
116
|
+
* the bus into IM). Callers that have a fallback path (e.g. the opencode
|
|
117
|
+
* HTTP adapter) check this before registerSyntheticPending so they can
|
|
118
|
+
* short-circuit when the bus is dormant — mostly relevant in tests and in
|
|
119
|
+
* non-IM call paths (web, scheduler). */
|
|
120
|
+
hasNotifier(): boolean;
|
|
121
|
+
/**
|
|
122
|
+
* 由 messenger.onMessage 拦截层调用。把 thread 队列头部的 pending 用
|
|
123
|
+
* 给定决策 resolve 掉。返回被 resolve 的 pending 描述(platform / tool /
|
|
124
|
+
* fingerprint / 是否处于 auto-allow grace 模式);router 用这些信息发回执。
|
|
125
|
+
* 没有 pending 时返回 null。
|
|
126
|
+
*
|
|
127
|
+
* Auto-allow side-effect: a user-initiated deny against a pending that
|
|
128
|
+
* was running in auto-allow mode revokes the matching rule (the user is
|
|
129
|
+
* signaling "stop auto-approving this"). Revocation is intentionally
|
|
130
|
+
* scoped to this user-path so sidecar disconnects / shutdown / run-
|
|
131
|
+
* terminated denies don't accidentally clear rules the user still wants.
|
|
132
|
+
*/
|
|
133
|
+
resolvePending(threadId: string, decision: Decision): ResolvedInfo | null;
|
|
134
|
+
/** Drop every auto-allow rule registered for this thread. Called from
|
|
135
|
+
* session.resetConversation so `/new` truly returns to "ask every time". */
|
|
136
|
+
clearAutoAllowForThread(threadId: string): void;
|
|
137
|
+
/** Test/diagnostic helper — current rule keys for a thread. */
|
|
138
|
+
getAutoAllowKeys(threadId: string): string[];
|
|
139
|
+
/** 测试用:当前 socket 路径。 */
|
|
140
|
+
getSocketPath(): string | null;
|
|
141
|
+
/**
|
|
142
|
+
* Operational metrics snapshot used by /api/metrics (M14). `pending` is
|
|
143
|
+
* a live count; the totals are lifetime counters that monotonically
|
|
144
|
+
* increase until stop(). The three result buckets (allowed / denied /
|
|
145
|
+
* timedOut) are mutually exclusive and sum to totalResolved — see
|
|
146
|
+
* cancelPending for the bucketing rule. Cheap to call — no allocations
|
|
147
|
+
* beyond the returned object.
|
|
148
|
+
*/
|
|
149
|
+
getMetrics(): {
|
|
150
|
+
pending: number;
|
|
151
|
+
totalRequests: number;
|
|
152
|
+
totalResolved: number;
|
|
153
|
+
totalAllowed: number;
|
|
154
|
+
totalDenied: number;
|
|
155
|
+
totalTimedOut: number;
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* Snapshot of every currently-pending approval, sanitized for surface
|
|
159
|
+
* to the operator dashboard. Used by the web `/api/approvals` endpoint
|
|
160
|
+
* (and any future ops tooling). Returns a stable JSON shape — input
|
|
161
|
+
* is included verbatim so the UI can render the same preview the
|
|
162
|
+
* IM-side card would; sockets / dispatch closures / timer handles are
|
|
163
|
+
* intentionally omitted.
|
|
164
|
+
*
|
|
165
|
+
* Sorted oldest-first so the queue head is at index 0 (matches the
|
|
166
|
+
* head-of-thread queue semantics used by resolvePending).
|
|
167
|
+
*/
|
|
168
|
+
listPending(): Array<{
|
|
169
|
+
reqId: string;
|
|
170
|
+
runId: string;
|
|
171
|
+
threadId: string;
|
|
172
|
+
platform: string;
|
|
173
|
+
toolName: string;
|
|
174
|
+
input: Record<string, unknown>;
|
|
175
|
+
fingerprint: string;
|
|
176
|
+
autoAllow: boolean;
|
|
177
|
+
registeredAt: number;
|
|
178
|
+
ageMs: number;
|
|
179
|
+
}>;
|
|
180
|
+
private handleConnection;
|
|
181
|
+
private handleLine;
|
|
182
|
+
private handleApproval;
|
|
183
|
+
/**
|
|
184
|
+
* Register an approval request that did NOT come from the unix-socket
|
|
185
|
+
* sidecar. Used by the opencode HTTP bridge (P2): SSE event from opencode
|
|
186
|
+
* → bridge calls this with a `dispatch` callback that POSTs the decision
|
|
187
|
+
* back to opencode's REST API.
|
|
188
|
+
*
|
|
189
|
+
* Behavior is identical to the socket path — same notifier, same timeout,
|
|
190
|
+
* same auto-allow rules — just the delivery channel differs. The
|
|
191
|
+
* `dispatch` is invoked with the final Decision exactly once, on:
|
|
192
|
+
* - user reply via {@link resolvePending}
|
|
193
|
+
* - timeout (deny in normal mode, allow in auto-allow mode)
|
|
194
|
+
* - {@link unregisterRun} (deny: "run terminated")
|
|
195
|
+
* - {@link stop} (deny: "approval-bus shutting down")
|
|
196
|
+
*
|
|
197
|
+
* dispatch errors are logged and swallowed — the bus must not crash on
|
|
198
|
+
* a misbehaving callback.
|
|
199
|
+
*
|
|
200
|
+
* Idempotent on duplicate reqId: returns silently without firing notify
|
|
201
|
+
* (matches the socket path's "duplicate reqId" handling, minus the wire
|
|
202
|
+
* deny since the synthetic caller has no socket to deny on).
|
|
203
|
+
*
|
|
204
|
+
* Throws synchronously only when the caller's bus state is invalid (no
|
|
205
|
+
* notifier installed). The caller should avoid registering the synthetic
|
|
206
|
+
* pending in that case and fall back to its own deny path.
|
|
207
|
+
*/
|
|
208
|
+
registerSyntheticPending(input: {
|
|
209
|
+
runId: string;
|
|
210
|
+
reqId: string;
|
|
211
|
+
toolName: string;
|
|
212
|
+
input: Record<string, unknown>;
|
|
213
|
+
/** Optional — used by Claude's MCP path; defaults to '' for synthetic. */
|
|
214
|
+
toolUseId?: string;
|
|
215
|
+
ctx: RunContext;
|
|
216
|
+
dispatch: (decision: Decision) => void;
|
|
217
|
+
}): Promise<void>;
|
|
218
|
+
/**
|
|
219
|
+
* Shared register-and-notify pipeline used by both the socket path and the
|
|
220
|
+
* synthetic path. Builds the PendingApproval, wires the timer, fires the
|
|
221
|
+
* notifier, and ensures the timer is cleared if the notifier itself throws.
|
|
222
|
+
*/
|
|
223
|
+
private _registerPending;
|
|
224
|
+
private cancelPending;
|
|
225
|
+
private addAutoAllowRule;
|
|
226
|
+
private removeAutoAllowRule;
|
|
227
|
+
private removePending;
|
|
228
|
+
private sendDecision;
|
|
229
|
+
}
|
|
230
|
+
/** 进程级单例。im-hub 启动时 await approvalBus.start() 一次。 */
|
|
231
|
+
export declare const approvalBus: ApprovalBus;
|
|
232
|
+
//# sourceMappingURL=approval-bus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval-bus.d.ts","sourceRoot":"","sources":["../../src/core/approval-bus.ts"],"names":[],"mappings":"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"}
|