每轮对话生成一张实时更新的飞书卡片,是在手机 / 飞书上感知并操控 CLI 的主窗口。渲染与推送的源码链路见 card-streaming。

渲染机制

  • 终端画面实时截图刷新到卡片:xterm 无头渲染成图,原样还原 CLI 的 TUI(边框、配色都在),不再把输出转成 Markdown。可一键「显示 / 隐藏输出」「导出文字」「上 / 下半屏」。
  • 卡片正文是图片,不是文本渲染:正文即终端画面的实时截图。

状态指示

卡片头部颜色即状态(用飞书卡片 template 实现,不是正文里的 emoji 圆点):

  • 启动中…(黄)→ 工作中(蓝)→ 等待输入(绿)
  • 额度用满标 限额已达(红),可重试时变 可重试(绿)

与 session-model 中的会话状态机一一对应。

卡片上的操作

  • 打开 Web 终端、🔑 获取操作链接、关闭会话;额度可重试时还有「🔁 重发上一条任务」。
  • 打开终端 = 只读:主按钮「🖥️ 打开 Web 终端」只读查看;要可写操作点「🔑 获取操作链接」。操作链接私密投递:普通平铺群优先发一张群内「仅你可见」的 ephemeral 卡(不用离开会话),话题 / 线程或私聊、以及 ephemeral 失败时才走私聊 DM。
  • 「🔄 重启」「接管配置」等管理按钮在会话卡上,不在每轮的流式卡上。
  • Web 终端的完整能力(移动端悬浮快捷键等)见 web-terminal。

每轮一张新卡片

  • 上一轮卡片冻结存档,对话历史清晰可回溯。
  • 会话用 /relay 搬到别的群后,原卡片自动冻结为存档(移除按钮),见 session-handoff。
  • 关闭时给「可恢复」卡片:带「▶️ 恢复会话」按钮随时点回来继续;若该 CLI 支持原生 resume(adapter 实现了 buildResumeCommand 且有原生 session id),还会附上原生命令(如 claude --resume <id>)方便手动恢复;不支持时只给 botmux 的恢复按钮 + 一句提示。adapter 能力差异见 adapters。

打断 / 纠偏正在跑的一轮

想中途叫停或纠偏,别等它跑完:截图模式下卡片底部带一排快捷键——Esc、^C、Tab、Space、Enter、方向键、⇞ 上半屏 / ⇟ 下半屏。点 Esc 会把 ESC 字节直接写进那个活着的终端(等同在本地按 Esc),^C 同理。打断后再补一句新指令即可。

注意两点:

  • 这排快捷键只在**显示输出(截图模式)**且非 riff 后端时出现——先「显示输出」才点得到 Esc。
  • 默认行为是当前轮不打断、新消息排队(type-ahead),本轮结束再依次输入;要立刻纠偏就用 Esc 先断。

CLI 主动发的消息

卡片是 botmux 自动渲染的终端画面;CLI 主动发的消息(通过 botmux send)则是独立的富文本 / 图文消息,可带图片、文件、@mention。需要完全自定义展示时也可以用 --card-file / --card-json 发送原始 interactive 卡片 JSON。

安全限制:原始卡片只允许纯展示 + open_url 跳转按钮;任何会触发回调的控件——回调按钮(带 value)、下拉 / 人员选择、日期时间选择、输入框、表单提交——都会被拒绝。这是为了防止自定义卡片伪造交互回调。

更多疑难(卡片不刷新、状态卡死等)见 faq。