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,75 @@
|
|
|
1
|
+
// /plan [on|off] — toggle plan mode for the active agent
|
|
2
|
+
//
|
|
3
|
+
// Plan mode is a per-session flag the router forwards to the agent adapter:
|
|
4
|
+
// • claude-code → spawns with `--permission-mode plan` (read-only)
|
|
5
|
+
// • opencode → routes through the built-in `plan` agent
|
|
6
|
+
// • codex → spawns with `-s read-only` sandbox (OS-level write fence;
|
|
7
|
+
// not a true approval gate, see codex/index.ts header)
|
|
8
|
+
// • other agents → ignore the flag (no-op)
|
|
9
|
+
//
|
|
10
|
+
// Persisted on session.planMode so it survives across turns and across the
|
|
11
|
+
// /oc ↔ /cc agent switch (intent travels with the conversation, not with
|
|
12
|
+
// the chosen CLI).
|
|
13
|
+
//
|
|
14
|
+
// Emergency kill switch: `IMHUB_DISABLE_PLAN_MODE=1` makes /plan return a
|
|
15
|
+
// "disabled" message without touching session state. Useful for ops to roll
|
|
16
|
+
// back the feature without redeploying.
|
|
17
|
+
import { sessionManager } from '../session.js';
|
|
18
|
+
const ON_TOKENS = new Set(['on', 'enter', 'start', 'enable', '开', '开启']);
|
|
19
|
+
const OFF_TOKENS = new Set(['off', 'exit', 'stop', 'disable', '关', '关闭']);
|
|
20
|
+
/** Agents that genuinely honor session.planMode at adapter level.
|
|
21
|
+
* - claude-code: --permission-mode plan
|
|
22
|
+
* - opencode: --agent plan
|
|
23
|
+
* - codex: -s read-only sandbox (sandbox-level "safety floor" — see
|
|
24
|
+
* plugins/agents/codex/index.ts header for the caveat) */
|
|
25
|
+
const PLAN_CAPABLE_AGENTS = new Set(['claude-code', 'opencode', 'codex']);
|
|
26
|
+
export async function handlePlanCommand(args, ctx) {
|
|
27
|
+
if (process.env.IMHUB_DISABLE_PLAN_MODE === '1') {
|
|
28
|
+
return '🚫 Plan 模式已通过 IMHUB_DISABLE_PLAN_MODE 全局禁用,请联系运维。';
|
|
29
|
+
}
|
|
30
|
+
const token = args.trim().toLowerCase();
|
|
31
|
+
const existing = await sessionManager.getExistingSession(ctx.platform, ctx.channelId, ctx.threadId);
|
|
32
|
+
if (!token) {
|
|
33
|
+
const cur = existing?.planMode ? 'on' : 'off';
|
|
34
|
+
const agent = existing?.agent || ctx.defaultAgent;
|
|
35
|
+
const capable = PLAN_CAPABLE_AGENTS.has(agent);
|
|
36
|
+
const agentNote = capable
|
|
37
|
+
? ''
|
|
38
|
+
: `\n\n⚠️ 当前 agent **${agent}** 暂未对接 plan 模式 —— /plan 会改 session 标志位,但 ${agent} 不读它。要规划-only 行为请用 ${agent} 自身的只读模式,或 /cc / /oc 切到对接版本。`;
|
|
39
|
+
return `📐 Plan 模式: \`${cur}\`(当前 agent: ${agent})
|
|
40
|
+
|
|
41
|
+
/plan on 开启
|
|
42
|
+
- claude-code: --permission-mode plan(只读规划)
|
|
43
|
+
- opencode: 切到 plan agent
|
|
44
|
+
- codex: -s read-only 沙盒(OS 层强制只读)
|
|
45
|
+
/plan off 关闭,恢复正常执行模式
|
|
46
|
+
|
|
47
|
+
plan 模式下文件不会被修改,适合先讨论方案再动手。${agentNote}`;
|
|
48
|
+
}
|
|
49
|
+
// Ensure a session exists so the patch is durable. Defer to the active
|
|
50
|
+
// sticky agent if one exists, else the configured default.
|
|
51
|
+
await sessionManager.getOrCreateSession(ctx.platform, ctx.channelId, ctx.threadId, existing?.agent || ctx.defaultAgent);
|
|
52
|
+
// Warn (don't refuse) when the active agent doesn't honor plan mode —
|
|
53
|
+
// the user might intentionally pre-set the flag before /cc-switching to
|
|
54
|
+
// a capable agent. Surface, then proceed.
|
|
55
|
+
const activeAgent = existing?.agent || ctx.defaultAgent;
|
|
56
|
+
const capabilityNote = PLAN_CAPABLE_AGENTS.has(activeAgent)
|
|
57
|
+
? ''
|
|
58
|
+
: `\n\n⚠️ 当前 agent **${activeAgent}** 不读 planMode 标志位(claude-code / opencode 才支持)。标志会保存,但要切到上述 agent 才会生效。`;
|
|
59
|
+
if (ON_TOKENS.has(token)) {
|
|
60
|
+
if (existing?.planMode)
|
|
61
|
+
return '✅ Plan 模式已开启(无变化)。' + capabilityNote;
|
|
62
|
+
await sessionManager.patchSession(ctx.platform, ctx.channelId, ctx.threadId, { planMode: true });
|
|
63
|
+
return '✅ Plan 模式已开启 — 接下来 agent 只规划不动手。/plan off 恢复。' + capabilityNote;
|
|
64
|
+
}
|
|
65
|
+
if (OFF_TOKENS.has(token)) {
|
|
66
|
+
if (!existing?.planMode)
|
|
67
|
+
return 'ℹ️ Plan 模式本来就是关闭状态。';
|
|
68
|
+
await sessionManager.patchSession(ctx.platform, ctx.channelId, ctx.threadId, { planMode: false });
|
|
69
|
+
return '✅ Plan 模式已关闭 — 恢复正常执行模式。';
|
|
70
|
+
}
|
|
71
|
+
return `⚠️ 无效参数: \`${token}\`
|
|
72
|
+
|
|
73
|
+
/plan on | off`;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../../src/core/commands/plan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.test.d.ts","sourceRoot":"","sources":["../../../src/core/commands/plan.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// /plan command — toggle plan mode for the active session.
|
|
2
|
+
//
|
|
3
|
+
// Drives sessionManager via the real public API (writes hit
|
|
4
|
+
// ~/.im-hub/sessions disk-backed) but uses a unique platform tag so we can
|
|
5
|
+
// scrub our own files in afterEach without colliding with real sessions.
|
|
6
|
+
import { describe, it, expect, afterEach } from 'bun:test';
|
|
7
|
+
import { homedir } from 'os';
|
|
8
|
+
import { join } from 'path';
|
|
9
|
+
import { unlink, readdir, readFile } from 'fs/promises';
|
|
10
|
+
import { sessionManager } from '../session.js';
|
|
11
|
+
import { handlePlanCommand } from './plan.js';
|
|
12
|
+
const PLATFORM = 'plantest';
|
|
13
|
+
const SESSIONS_DIR = join(homedir(), '.im-hub', 'sessions');
|
|
14
|
+
function uid() { return Math.random().toString(36).slice(2, 10); }
|
|
15
|
+
async function cleanupTestSessions() {
|
|
16
|
+
let names;
|
|
17
|
+
try {
|
|
18
|
+
names = await readdir(SESSIONS_DIR);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
for (const name of names) {
|
|
24
|
+
if (!name.endsWith('.json'))
|
|
25
|
+
continue;
|
|
26
|
+
try {
|
|
27
|
+
const raw = await readFile(join(SESSIONS_DIR, name), 'utf-8');
|
|
28
|
+
const parsed = JSON.parse(raw);
|
|
29
|
+
if (parsed.platform === PLATFORM) {
|
|
30
|
+
await unlink(join(SESSIONS_DIR, name)).catch(() => { });
|
|
31
|
+
await unlink(join(SESSIONS_DIR, name.replace(/\.json$/, '.log'))).catch(() => { });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch { /* ignore */ }
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function makeCtx(channelId, threadId) {
|
|
38
|
+
return {
|
|
39
|
+
channelId, threadId, platform: PLATFORM,
|
|
40
|
+
defaultAgent: 'claude-code', traceId: 't',
|
|
41
|
+
logger: { info: () => { }, warn: () => { }, error: () => { }, debug: () => { }, child: () => ({}) },
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
afterEach(async () => {
|
|
45
|
+
delete process.env.IMHUB_DISABLE_PLAN_MODE;
|
|
46
|
+
await cleanupTestSessions();
|
|
47
|
+
});
|
|
48
|
+
describe('handlePlanCommand', () => {
|
|
49
|
+
it('shows current state (off) and usage when invoked with no args on a fresh session', async () => {
|
|
50
|
+
const ctx = makeCtx(uid(), uid());
|
|
51
|
+
// Pre-create the session so the status query has something to read.
|
|
52
|
+
await sessionManager.getOrCreateSession(ctx.platform, ctx.channelId, ctx.threadId, 'claude-code');
|
|
53
|
+
const out = await handlePlanCommand('', ctx);
|
|
54
|
+
expect(out).toContain('Plan 模式');
|
|
55
|
+
expect(out).toContain('off');
|
|
56
|
+
expect(out).toContain('/plan on');
|
|
57
|
+
expect(out).toContain('/plan off');
|
|
58
|
+
});
|
|
59
|
+
it('/plan on flips planMode true and persists it', async () => {
|
|
60
|
+
const ctx = makeCtx(uid(), uid());
|
|
61
|
+
const out = await handlePlanCommand('on', ctx);
|
|
62
|
+
expect(out).toContain('已开启');
|
|
63
|
+
const session = await sessionManager.getExistingSession(ctx.platform, ctx.channelId, ctx.threadId);
|
|
64
|
+
expect(session?.planMode).toBe(true);
|
|
65
|
+
});
|
|
66
|
+
it('/plan off clears planMode', async () => {
|
|
67
|
+
const ctx = makeCtx(uid(), uid());
|
|
68
|
+
await handlePlanCommand('on', ctx);
|
|
69
|
+
const out = await handlePlanCommand('off', ctx);
|
|
70
|
+
expect(out).toContain('已关闭');
|
|
71
|
+
const session = await sessionManager.getExistingSession(ctx.platform, ctx.channelId, ctx.threadId);
|
|
72
|
+
expect(session?.planMode).toBeUndefined();
|
|
73
|
+
});
|
|
74
|
+
it('/plan on twice is idempotent (no error, friendly message)', async () => {
|
|
75
|
+
const ctx = makeCtx(uid(), uid());
|
|
76
|
+
await handlePlanCommand('on', ctx);
|
|
77
|
+
const out = await handlePlanCommand('on', ctx);
|
|
78
|
+
expect(out).toContain('无变化');
|
|
79
|
+
});
|
|
80
|
+
it('/plan off when already off says so without churning', async () => {
|
|
81
|
+
const ctx = makeCtx(uid(), uid());
|
|
82
|
+
await sessionManager.getOrCreateSession(ctx.platform, ctx.channelId, ctx.threadId, 'claude-code');
|
|
83
|
+
const out = await handlePlanCommand('off', ctx);
|
|
84
|
+
expect(out).toContain('本来就是关闭');
|
|
85
|
+
});
|
|
86
|
+
it('rejects unknown subcommands with usage hint', async () => {
|
|
87
|
+
const ctx = makeCtx(uid(), uid());
|
|
88
|
+
const out = await handlePlanCommand('maybe', ctx);
|
|
89
|
+
expect(out).toContain('无效参数');
|
|
90
|
+
expect(out).toContain('on');
|
|
91
|
+
expect(out).toContain('off');
|
|
92
|
+
});
|
|
93
|
+
it('honours alias tokens (enter / exit)', async () => {
|
|
94
|
+
const ctx = makeCtx(uid(), uid());
|
|
95
|
+
await handlePlanCommand('enter', ctx);
|
|
96
|
+
let session = await sessionManager.getExistingSession(ctx.platform, ctx.channelId, ctx.threadId);
|
|
97
|
+
expect(session?.planMode).toBe(true);
|
|
98
|
+
await handlePlanCommand('exit', ctx);
|
|
99
|
+
session = await sessionManager.getExistingSession(ctx.platform, ctx.channelId, ctx.threadId);
|
|
100
|
+
expect(session?.planMode).toBeUndefined();
|
|
101
|
+
});
|
|
102
|
+
it('honours Chinese alias tokens (开/关)', async () => {
|
|
103
|
+
const ctx = makeCtx(uid(), uid());
|
|
104
|
+
await handlePlanCommand('开', ctx);
|
|
105
|
+
let session = await sessionManager.getExistingSession(ctx.platform, ctx.channelId, ctx.threadId);
|
|
106
|
+
expect(session?.planMode).toBe(true);
|
|
107
|
+
await handlePlanCommand('关', ctx);
|
|
108
|
+
session = await sessionManager.getExistingSession(ctx.platform, ctx.channelId, ctx.threadId);
|
|
109
|
+
expect(session?.planMode).toBeUndefined();
|
|
110
|
+
});
|
|
111
|
+
it('IMHUB_DISABLE_PLAN_MODE=1 short-circuits without touching session state', async () => {
|
|
112
|
+
const ctx = makeCtx(uid(), uid());
|
|
113
|
+
process.env.IMHUB_DISABLE_PLAN_MODE = '1';
|
|
114
|
+
const out = await handlePlanCommand('on', ctx);
|
|
115
|
+
expect(out).toContain('已通过');
|
|
116
|
+
expect(out).toContain('禁用');
|
|
117
|
+
// No session should have been created or mutated.
|
|
118
|
+
const session = await sessionManager.getExistingSession(ctx.platform, ctx.channelId, ctx.threadId);
|
|
119
|
+
expect(session?.planMode).toBeUndefined();
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
//# sourceMappingURL=plan.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.test.js","sourceRoot":"","sources":["../../../src/core/commands/plan.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../../src/core/commands/router.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAMhD,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,YAAY,GAChB,OAAO,CAAC,MAAM,CAAC,CAsEjB"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// /router commands — inspect and debug routing decisions
|
|
2
|
+
import { classifyIntent } from '../intent.js';
|
|
3
|
+
import { circuitBreaker } from '../circuit-breaker.js';
|
|
4
|
+
import { registry } from '../registry.js';
|
|
5
|
+
import { sessionManager } from '../session.js';
|
|
6
|
+
export async function handleRouterCommand(args, ctx) {
|
|
7
|
+
const parts = args.trim().split(/\s+/).filter(Boolean);
|
|
8
|
+
const subcommand = parts[0] || 'status';
|
|
9
|
+
const rest = parts.slice(1).join(' ');
|
|
10
|
+
switch (subcommand) {
|
|
11
|
+
case 'status':
|
|
12
|
+
case 's': {
|
|
13
|
+
const agents = registry.listAgents();
|
|
14
|
+
const lines = agents.map(a => {
|
|
15
|
+
const breaker = circuitBreaker.getStatus(a);
|
|
16
|
+
const icon = breaker.open ? '⛔' : '✅';
|
|
17
|
+
const extra = breaker.open
|
|
18
|
+
? ` (blocked: ${breaker.failures} failures)`
|
|
19
|
+
: breaker.failures > 0
|
|
20
|
+
? ` (${breaker.failures} recent failures)`
|
|
21
|
+
: '';
|
|
22
|
+
return `${icon} ${a}${extra}`;
|
|
23
|
+
});
|
|
24
|
+
return `📊 **Router Status**\n\n${lines.join('\n')}\n\n/router policy 查看路由策略\n/router explain <message> 预测路由去向`;
|
|
25
|
+
}
|
|
26
|
+
case 'policy':
|
|
27
|
+
case 'p': {
|
|
28
|
+
return `📋 **路由策略 (Phase 2 · 规则引擎)**
|
|
29
|
+
|
|
30
|
+
1. 显式命令 — /<agent> 直接切换
|
|
31
|
+
2. Sticky 会话 — 继续使用上一轮的 agent (+3 权重)
|
|
32
|
+
3. 主题规则 — git/test/sql/review 等关键词映射到专用 agent (+2)
|
|
33
|
+
4. 关键词匹配 — agent 画像关键词权重 (+0.5~1.2 每匹配)
|
|
34
|
+
5. 兜底 — 默认 agent 或首家可用
|
|
35
|
+
|
|
36
|
+
断路保护: 连续 3 次失败 → 5 分钟冷却
|
|
37
|
+
`;
|
|
38
|
+
}
|
|
39
|
+
case 'explain':
|
|
40
|
+
case 'e': {
|
|
41
|
+
if (!rest)
|
|
42
|
+
return '用法: /router explain <消息内容>\n\n预测该消息会被路由到哪个 agent';
|
|
43
|
+
const session = await sessionManager.getExistingSession(ctx.platform, ctx.channelId, ctx.threadId);
|
|
44
|
+
const sticky = session?.agent;
|
|
45
|
+
const result = classifyIntent(rest, sticky, ctx.logger);
|
|
46
|
+
return `🔍 **路由预测**
|
|
47
|
+
|
|
48
|
+
消息: "${rest.substring(0, 80)}${rest.length > 80 ? '...' : ''}"
|
|
49
|
+
|
|
50
|
+
→ Agent: **${result.agent}** (score: ${result.score})
|
|
51
|
+
触发: ${result.triggeredBy}
|
|
52
|
+
原因: ${result.reason}
|
|
53
|
+
|
|
54
|
+
当前 sticky: ${sticky || '无'}`;
|
|
55
|
+
}
|
|
56
|
+
case 'reset': {
|
|
57
|
+
// /router reset → clear all breakers
|
|
58
|
+
// /router reset <agent> → clear one agent's breaker
|
|
59
|
+
const target = parts[1];
|
|
60
|
+
if (target) {
|
|
61
|
+
circuitBreaker.reset(target);
|
|
62
|
+
return `✅ Cleared circuit breaker for "${target}".`;
|
|
63
|
+
}
|
|
64
|
+
circuitBreaker.reset();
|
|
65
|
+
return '✅ Cleared all circuit breakers.';
|
|
66
|
+
}
|
|
67
|
+
default:
|
|
68
|
+
return `用法: /router [status|policy|explain <msg>|reset [<agent>]]`;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../../src/core/commands/router.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule.d.ts","sourceRoot":"","sources":["../../../src/core/commands/schedule.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAQhD,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,YAAY,GAChB,OAAO,CAAC,MAAM,CAAC,CA2GjB"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
// /schedule command — manage cron-driven scheduled prompts (P2-F).
|
|
2
|
+
//
|
|
3
|
+
// /schedule list list all schedules
|
|
4
|
+
// /schedule create <name> <agent> <cron> <prompt> create
|
|
5
|
+
// /schedule delete <id> delete
|
|
6
|
+
// /schedule enable <id> enable
|
|
7
|
+
// /schedule disable <id> disable
|
|
8
|
+
// /schedule check <id> show details
|
|
9
|
+
//
|
|
10
|
+
// Cron expression is the standard 5-field POSIX format ("min hour dom mon dow").
|
|
11
|
+
import { createSchedule, listSchedules, getSchedule, deleteSchedule, setEnabled, } from '../schedule.js';
|
|
12
|
+
import { parseCron, nextOccurrence } from '../cron.js';
|
|
13
|
+
import { registry } from '../registry.js';
|
|
14
|
+
import { workspaceRegistry } from '../workspace.js';
|
|
15
|
+
export async function handleScheduleCommand(args, ctx) {
|
|
16
|
+
const parts = args.trim().split(/\s+/).filter(Boolean);
|
|
17
|
+
const sub = parts[0] || 'list';
|
|
18
|
+
// Same per-user scoping rule as /job. ctx.userId set → see only own rows;
|
|
19
|
+
// ctx.userId unset → unrestricted (back-compat for non-IM callers).
|
|
20
|
+
const ownerOpts = ctx.userId ? { creatorId: ctx.userId } : {};
|
|
21
|
+
switch (sub) {
|
|
22
|
+
case 'list':
|
|
23
|
+
case 'ls': {
|
|
24
|
+
const all = listSchedules(50, ownerOpts);
|
|
25
|
+
if (!all.length)
|
|
26
|
+
return '🗓️ 暂无定时任务。\n\n用法: /schedule create <name> <agent> "<cron>" <prompt>';
|
|
27
|
+
const lines = all.map((s) => {
|
|
28
|
+
const flag = s.enabled ? '✅' : '⏸️';
|
|
29
|
+
return `${flag} #${s.id} **${s.name}** (${s.agent})\n cron: \`${s.cron}\`\n 下次: ${s.next_run}`;
|
|
30
|
+
});
|
|
31
|
+
return `🗓️ **定时任务** (${all.length})\n\n${lines.join('\n\n')}\n\n/schedule check <id> 详情\n/schedule enable/disable <id> 启停\n/schedule delete <id> 删除`;
|
|
32
|
+
}
|
|
33
|
+
case 'create':
|
|
34
|
+
case 'c': {
|
|
35
|
+
// /schedule create <name> <agent> "<cron>" <prompt...>
|
|
36
|
+
if (parts.length < 5) {
|
|
37
|
+
return '用法: /schedule create <name> <agent> "<cron expr>" <prompt>\n\n例如: /schedule create daily-report opencode "0 9 * * 1-5" 生成今天的销售日报';
|
|
38
|
+
}
|
|
39
|
+
const name = parts[1];
|
|
40
|
+
const agentName = parts[2];
|
|
41
|
+
// The cron expression may be quoted — try to extract.
|
|
42
|
+
const restJoined = parts.slice(3).join(' ');
|
|
43
|
+
let cron;
|
|
44
|
+
let prompt;
|
|
45
|
+
const quoted = restJoined.match(/^"([^"]+)"\s+(.+)$/) || restJoined.match(/^'([^']+)'\s+(.+)$/);
|
|
46
|
+
if (quoted) {
|
|
47
|
+
cron = quoted[1];
|
|
48
|
+
prompt = quoted[2];
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
// Best effort: assume the next 5 tokens are the cron expression
|
|
52
|
+
const tokens = parts.slice(3);
|
|
53
|
+
if (tokens.length < 6)
|
|
54
|
+
return '用法: /schedule create <name> <agent> "<cron expr>" <prompt>';
|
|
55
|
+
cron = tokens.slice(0, 5).join(' ');
|
|
56
|
+
prompt = tokens.slice(5).join(' ');
|
|
57
|
+
}
|
|
58
|
+
// M6: workspace whitelist + agent existence check before we touch SQL.
|
|
59
|
+
const agent = registry.findAgent(agentName);
|
|
60
|
+
if (!agent)
|
|
61
|
+
return `❌ Agent "${agentName}" not found.`;
|
|
62
|
+
const ws = workspaceRegistry.resolve(ctx.userId || 'unknown');
|
|
63
|
+
if (!ws.hasAgent(agent.name)) {
|
|
64
|
+
return `❌ Agent "${agent.name}" 不在 workspace "${ws.name}" 的白名单内。`;
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
// Validate before insert so we get a clean error.
|
|
68
|
+
parseCron(cron);
|
|
69
|
+
const id = createSchedule({
|
|
70
|
+
name, agent: agent.name, cron, prompt,
|
|
71
|
+
creatorId: ctx.userId || '',
|
|
72
|
+
workspaceId: ws.id,
|
|
73
|
+
});
|
|
74
|
+
const next = nextOccurrence(parseCron(cron));
|
|
75
|
+
return `✅ 定时任务 #${id} 已创建\n\nName: ${name}\nAgent: ${agent.name}\nCron: \`${cron}\`\n下次执行: ${next?.toISOString() || 'unknown'}`;
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
79
|
+
return `❌ 创建失败: ${msg}`;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
case 'delete':
|
|
83
|
+
case 'rm': {
|
|
84
|
+
const id = parseInt(parts[1] || '', 10);
|
|
85
|
+
if (!Number.isFinite(id))
|
|
86
|
+
return '用法: /schedule delete <id>';
|
|
87
|
+
return deleteSchedule(id, ownerOpts)
|
|
88
|
+
? `✅ 定时任务 #${id} 已删除。`
|
|
89
|
+
: `❌ 未找到 #${id},或不是你创建的。`;
|
|
90
|
+
}
|
|
91
|
+
case 'enable':
|
|
92
|
+
case 'on': {
|
|
93
|
+
const id = parseInt(parts[1] || '', 10);
|
|
94
|
+
if (!Number.isFinite(id))
|
|
95
|
+
return '用法: /schedule enable <id>';
|
|
96
|
+
return setEnabled(id, true, ownerOpts)
|
|
97
|
+
? `✅ 定时任务 #${id} 已启用。`
|
|
98
|
+
: `❌ 未找到 #${id},或不是你创建的。`;
|
|
99
|
+
}
|
|
100
|
+
case 'disable':
|
|
101
|
+
case 'off': {
|
|
102
|
+
const id = parseInt(parts[1] || '', 10);
|
|
103
|
+
if (!Number.isFinite(id))
|
|
104
|
+
return '用法: /schedule disable <id>';
|
|
105
|
+
return setEnabled(id, false, ownerOpts)
|
|
106
|
+
? `⏸️ 定时任务 #${id} 已暂停。`
|
|
107
|
+
: `❌ 未找到 #${id},或不是你创建的。`;
|
|
108
|
+
}
|
|
109
|
+
case 'check':
|
|
110
|
+
case 'show': {
|
|
111
|
+
const id = parseInt(parts[1] || '', 10);
|
|
112
|
+
if (!Number.isFinite(id))
|
|
113
|
+
return '用法: /schedule check <id>';
|
|
114
|
+
const s = getSchedule(id, ownerOpts);
|
|
115
|
+
if (!s)
|
|
116
|
+
return `❌ 未找到 #${id}。`;
|
|
117
|
+
return `🗓️ **定时任务 #${s.id}** (${s.name})\n\nAgent: ${s.agent}\n状态: ${s.enabled ? '✅ 启用' : '⏸️ 已暂停'}\nCron: \`${s.cron}\`\n下次执行: ${s.next_run}\n上次执行: ${s.last_run || '从未'}\n通知 URL: ${s.notify_url || '无'}\n\nPrompt: ${s.prompt}`;
|
|
118
|
+
}
|
|
119
|
+
default:
|
|
120
|
+
return '用法: /schedule [list|create|delete|enable|disable|check]';
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=schedule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule.js","sourceRoot":"","sources":["../../../src/core/commands/schedule.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../../src/core/commands/sessions.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAmDhD,wBAAsB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAkC9F"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// /sessions — list recent opencode sessions from a separate dashboard
|
|
2
|
+
//
|
|
3
|
+
// Talks to an external (non-im-hub) "dashboard" service that maintains
|
|
4
|
+
// the opencode session catalog. The URL is configurable via the
|
|
5
|
+
// IM_HUB_DASHBOARD_URL env var so deployments without the dashboard get
|
|
6
|
+
// a clear "not configured" message instead of a confusing connection
|
|
7
|
+
// refused.
|
|
8
|
+
import http from 'http';
|
|
9
|
+
import https from 'https';
|
|
10
|
+
import { URL } from 'url';
|
|
11
|
+
const DEFAULT_DASHBOARD_URL = 'http://127.0.0.1:8001';
|
|
12
|
+
const REQUEST_TIMEOUT_MS = 5_000;
|
|
13
|
+
function dashboardUrl() {
|
|
14
|
+
return process.env.IM_HUB_DASHBOARD_URL || DEFAULT_DASHBOARD_URL;
|
|
15
|
+
}
|
|
16
|
+
function fetchJson(url) {
|
|
17
|
+
return new Promise((resolve, reject) => {
|
|
18
|
+
const u = new URL(url);
|
|
19
|
+
const lib = u.protocol === 'https:' ? https : http;
|
|
20
|
+
let settled = false;
|
|
21
|
+
const finish = (fn) => {
|
|
22
|
+
if (settled)
|
|
23
|
+
return;
|
|
24
|
+
settled = true;
|
|
25
|
+
clearTimeout(timer);
|
|
26
|
+
fn();
|
|
27
|
+
};
|
|
28
|
+
const timer = setTimeout(() => {
|
|
29
|
+
finish(() => {
|
|
30
|
+
try {
|
|
31
|
+
req.destroy(new Error('timeout'));
|
|
32
|
+
}
|
|
33
|
+
catch { /* ignore */ }
|
|
34
|
+
reject(new Error('timeout'));
|
|
35
|
+
});
|
|
36
|
+
}, REQUEST_TIMEOUT_MS);
|
|
37
|
+
const req = lib.get(url, (res) => {
|
|
38
|
+
let body = '';
|
|
39
|
+
res.on('data', (c) => { body += c.toString(); });
|
|
40
|
+
res.on('end', () => finish(() => {
|
|
41
|
+
try {
|
|
42
|
+
resolve(JSON.parse(body));
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
reject(new Error('invalid JSON'));
|
|
46
|
+
}
|
|
47
|
+
}));
|
|
48
|
+
res.on('error', (err) => finish(() => reject(err)));
|
|
49
|
+
});
|
|
50
|
+
req.on('error', (err) => finish(() => reject(err)));
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
export async function handleSessionsCommand(_args, _ctx) {
|
|
54
|
+
const base = dashboardUrl().replace(/\/+$/, '');
|
|
55
|
+
const url = `${base}/api/sessions/list?limit=10`;
|
|
56
|
+
let data;
|
|
57
|
+
try {
|
|
58
|
+
data = await fetchJson(url);
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
62
|
+
if (msg.includes('ECONNREFUSED') || msg.includes('connect')) {
|
|
63
|
+
return `⚠️ 无法连接 dashboard (${base})。\n\n确认 dashboard 服务已启动,或设置 \`IM_HUB_DASHBOARD_URL\` 环境变量指向正确的地址。`;
|
|
64
|
+
}
|
|
65
|
+
if (msg === 'timeout') {
|
|
66
|
+
return `⚠️ Dashboard 响应超时 (${REQUEST_TIMEOUT_MS}ms): ${base}`;
|
|
67
|
+
}
|
|
68
|
+
if (msg === 'invalid JSON') {
|
|
69
|
+
return `⚠️ Dashboard 返回了非 JSON 响应:${base}`;
|
|
70
|
+
}
|
|
71
|
+
return `⚠️ Dashboard 调用失败: ${msg}`;
|
|
72
|
+
}
|
|
73
|
+
if (!data.sessions?.length)
|
|
74
|
+
return '📋 暂无活跃会话。';
|
|
75
|
+
let msg = '📋 最近 10 个会话:\n\n';
|
|
76
|
+
data.sessions.forEach((s, i) => {
|
|
77
|
+
const time = s.created
|
|
78
|
+
? new Date(s.created).toLocaleString('zh-CN', { month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' })
|
|
79
|
+
: '?';
|
|
80
|
+
const age = typeof s.ageHours === 'number'
|
|
81
|
+
? (s.ageHours < 1 ? '<1h' : s.ageHours < 24 ? Math.round(s.ageHours) + 'h' : Math.round(s.ageHours / 24) + 'd')
|
|
82
|
+
: '?';
|
|
83
|
+
msg += `${i + 1}. ${s.title || '(无标题)'}\n ${time} · ${s.msgCount || 0}条 · ${age}前\n`;
|
|
84
|
+
});
|
|
85
|
+
msg += '\n当前微信对话的 opencode 会话 6h 内有效,无需手动加载。';
|
|
86
|
+
return msg;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=sessions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../../src/core/commands/sessions.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,EAAE;AACF,uEAAuE;AACvE,gEAAgE;AAChE,wEAAwE;AACxE,qEAAqE;AACrE,WAAW;AAEX,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAGzB,MAAM,qBAAqB,GAAG,uBAAuB,CAAA;AACrD,MAAM,kBAAkB,GAAG,KAAK,CAAA;AAahC,SAAS,YAAY;IACnB,OAAO,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,qBAAqB,CAAA;AAClE,CAAC;AAED,SAAS,SAAS,CAAC,GAAW;IAC5B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;QACtB,MAAM,GAAG,GAAG,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAA;QAClD,IAAI,OAAO,GAAG,KAAK,CAAA;QACnB,MAAM,MAAM,GAAG,CAAC,EAAc,EAAQ,EAAE;YACtC,IAAI,OAAO;gBAAE,OAAM;YACnB,OAAO,GAAG,IAAI,CAAA;YACd,YAAY,CAAC,KAAK,CAAC,CAAA;YACnB,EAAE,EAAE,CAAA;QACN,CAAC,CAAA;QACD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,MAAM,CAAC,GAAG,EAAE;gBACV,IAAI,CAAC;oBAAC,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC,CAAA;gBAAC,CAAC;gBAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;gBAChE,MAAM,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC,CAAA;YAC9B,CAAC,CAAC,CAAA;QACJ,CAAC,EAAE,kBAAkB,CAAC,CAAA;QAEtB,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE;YAC/B,IAAI,IAAI,GAAG,EAAE,CAAA;YACb,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAA,CAAC,CAAC,CAAC,CAAA;YACvD,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE;gBAC9B,IAAI,CAAC;oBAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;gBAAC,CAAC;gBACjC,MAAM,CAAC;oBAAC,MAAM,CAAC,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC,CAAA;gBAAC,CAAC;YAC7C,CAAC,CAAC,CAAC,CAAA;YACH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;QACrD,CAAC,CAAC,CAAA;QACF,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;IACrD,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,KAAa,EAAE,IAAkB;IAC3E,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IAC/C,MAAM,GAAG,GAAG,GAAG,IAAI,6BAA6B,CAAA;IAChD,IAAI,IAAuB,CAAA;IAC3B,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,CAAA;IAC7B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAC5D,IAAI,GAAG,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YAC5D,OAAO,sBAAsB,IAAI,oEAAoE,CAAA;QACvG,CAAC;QACD,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,OAAO,sBAAsB,kBAAkB,QAAQ,IAAI,EAAE,CAAA;QAC/D,CAAC;QACD,IAAI,GAAG,KAAK,cAAc,EAAE,CAAC;YAC3B,OAAO,6BAA6B,IAAI,EAAE,CAAA;QAC5C,CAAC;QACD,OAAO,sBAAsB,GAAG,EAAE,CAAA;IACpC,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM;QAAE,OAAO,YAAY,CAAA;IAE/C,IAAI,GAAG,GAAG,mBAAmB,CAAA;IAC7B,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC7B,MAAM,IAAI,GAAG,CAAC,CAAC,OAAO;YACpB,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;YACvH,CAAC,CAAC,GAAG,CAAA;QACP,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ;YACxC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC;YAC/G,CAAC,CAAC,GAAG,CAAA;QACP,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,OAAO,QAAQ,IAAI,MAAM,CAAC,CAAC,QAAQ,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;IACxF,CAAC,CAAC,CAAA;IACF,GAAG,IAAI,sCAAsC,CAAA;IAC7C,OAAO,GAAG,CAAA;AACZ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../../src/core/commands/stats.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AA4BhD,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAgC1F"}
|