botmux 是一个薄编排层,把「飞书事件」翻译成「CLI 进程的输入/输出」。
进程模型
飞书 (Lark) 长连接事件
│
▼
┌──────────┐ 每个 bot 一个独立 daemon 进程
│ daemon │ 监听消息、路由、管理会话生命周期
└────┬─────┘
│ 每个话题 spawn 一个
▼
┌──────────┐ 通过适配器拉起 CLI,挂在 PTY / tmux 后端上
│ worker │ 读终端输出 → 渲染卡片;收飞书消息 → 写入 CLI
└────┬─────┘
│
▼
┌──────────┐
│ CLI 进程 │ Claude Code / Codex / ...(完整运行时)
└──────────┘
要点:
- 生产形态是一个 bot 一个 daemon 进程。多机器人 = 多 daemon,进程完全隔离,互不干扰。
- 每个话题 spawn 一个 worker:worker 通过适配器管理 CLI,负责飞书消息与终端 I/O 的双向桥接。
进程模型与生命周期的源码分析见 daemon-worker,会话模型见 session-model。
模块结构
| 模块 | 职责 |
|---|---|
daemon.ts | 薄编排层,组装各模块并启动 |
worker.ts | Worker 子进程,通过适配器管理 CLI + PTY |
server.ts | Web 终端 HTTP 服务(xterm.js) |
bot-registry.ts | 多机器人配置加载 + 状态管理 |
adapters/cli/ | CLI 适配器(参数构建、输入写入、Skill 目录),每种 CLI 一个文件 |
adapters/backend/ | 会话后端:PtyBackend、TmuxPipeBackend |
im/lark/ | 飞书:事件路由、卡片构建/处理、API client、消息解析 |
core/ | worker-pool、command-handler、session-manager、cost-calculator、scheduler |
skills/ | 开箱即用 Skill(botmux-send / botmux-schedule / botmux-bots / botmux-history / botmux-quoted) |
utils/ | idle-detector(CLI 空闲检测)、terminal-renderer(xterm.js 截屏)、logger |
对应源码分析:适配器 adapters、飞书消息路由 im-routing、卡片流式渲染 card-streaming、Skill 系统 skills。
数据流
- 飞书推送
im.message.receive_v1→ event-dispatcher 解析、判断归属(@mention / 话题 / 群权限)。 - command-handler 拦截
/xxx斜杠命令;非命令消息交给会话。 - 新话题 → worker-pool spawn 一个 worker;已有会话 → 复用,把消息写进 CLI stdin。
- worker 持续读 PTY 输出,经 terminal-renderer 转成 Markdown,更新流式卡片。
- CLI 通过注入的
botmux send等 Skill / 命令主动往话题发消息。
命令拦截语义见 slash-commands,卡片机制见 cards。
关键设计:worker 与 CLI 经后端解耦
worker 与 CLI 通过后端(PTY 或 tmux)解耦。tmux 后端下,daemon/worker 重启时 CLI 进程仍在 tmux 里活着,下次消息自动 re-attach,无需 --resume 重载上下文。详见 tmux。