src/setup/(22 文件)承载两条职责:① botmux setup 的机器人配置流程(飞书应用创建 → 权限/事件/redirect/发版自动化 → 写 bots.json);② botmux start/restart 前的依赖引导(tmux/字体/herdr)。命令入口在 cli.ts(cmdSetup / cmdSetupScripted,见 cli)。

两种 setup 模式

  • 交互 TUI(空参 / 纯 flag):cmdSetup(src/cli.ts:2334)。已有 bots.json 时进多机器人菜单(添加/编辑/删除/重新配置),首次进 promptBotConfig。
  • 脚本化(setup list|add|configure|edit|remove):src/setup/setup-args.ts 解析字段级 flag(--app-id/--cli/--backend/--allowed-users/...)。设计动机:给 coding agent / 脚本一个不依赖 TUI 问题顺序的稳定接口(管道喂数字会因问题序列变化静默错位)。

两种模式的共同安全约束:写盘前用凭证换 tenant_access_token 校验(verify-permissions.ts validateCredentials),失败不写 bots.json;覆盖前先 copyFileSync 备份 .bak 再原子写(bots-store.ts)。

飞书应用自动创建(扫码)

三条来源路径,均仅支持 feishu.cn 租户(Lark 国际版回退 SDK device flow):

  1. SDK 扫码建应用(register-app.ts):对接 @larksuiteoapi/node-sdk 的 registerApp,走 OAuth 2.0 Device Flow(RFC 8628)——accounts.feishu.cn/oauth/v1/app/registration 发 action=begin(archetype 写死 PersonalAgent)→ 终端 qrcode-terminal 渲染二维码 → 轮询 action=poll 拿到 client_id/client_secret(即 AppID/AppSecret)。错误分类 aborted/expired/denied/network;secret 永不打印(错误消息先过滤长随机串)。扫码人 open_id 用作 allowedUsers 默认值。
  2. Web session 一键建应用(open-platform-automation.ts createOpenPlatformAppWithClient,manifest 模板 developer_console):复用 Feishu Web 登录态直接经 console API 建普通企业自建应用,可带 botmux 图标。
  3. 复用已有应用(cli.ts pickExistingAppCredentials):Web 登录态拉当前账号可见的自建应用列表,交互选择后自动读取 AppSecret。

Web 登录态本身也是扫码:prepareFeishuWebSession 按「缓存 session 文件(~/.botmux)→ Feishu Web QR 登录 → bytedcli fallback」顺序获取 cookies,登录态可跨 setup 步骤复用(建应用那次的扫码覆盖后续权限/发版,不再二次扫码)。

开放平台自动化管线

automateOpenPlatformSetup(src/setup/open-platform-automation.ts:625)用拿到的 Web session 驱动 console 内部 API(/developers/v1/*,带页面提取的 CSRF token):

  1. 权限导入:scope/all 拉租户目录 → 与 manifest 映射 → scope/update 批量注册。非致命(「部分权限即成功」,个别租户拒个别权限时只告警继续)。
  2. 能力开关(致命):robot/switch 开启机器人能力 + event/switch 切长连接事件(LONG_CONNECTION_EVENT_MODE = 4)。
  3. 事件/回调订阅(增量契约:读现状 → operation:add 补缺失 → 回读确认)。基线事件含 im.message.receive_v1(critical,缺了 daemon 完全收不到消息)+ 成员变更等可选事件 + VC 会议事件;回调 card.action.trigger。fail-closed:核心项回读仍缺失直接判失败,避免产出「建好了却不回话」的坏 bot。批量失败时逐个补,防长尾事件拖垮核心。
  4. redirect URL:写死 http://127.0.0.1:9768/callback(本地 daemon OAuth 回调)。
  5. 发版:先读现有可见范围(visible/online,读不可靠则中止发版,绝不发一个可能把人关在门外的版本)→ app_version/create(版本号自增)→ publish/commit。

结果由 open-platform-outcome.ts 分类(ok/partial/manual/skipped);setup configure <bot> 可对 partial 的应用重跑后半段而不重建应用。--no-open-platform-auto 全程跳过并打印手动步骤深链。

lark-scopes.json 权限清单

src/setup/lark-scopes.json 是 botmux 所需 scope 的 manifest(tenant + user 两节,覆盖 im/calendar/docs/drive/board/contact/vc 等域)。自动配置时映射到租户目录里的 scope id 批量导入;同时拷一份到 ~/.botmux/lark-scopes.json,供「开放平台权限管理 → 批量导入」手动兜底。verify-permissions.ts 的 BOTMUX_REQUIRED_SCOPES 标注 critical 子集(im:message、im:message.group_at_msg:readonly、im:message.group_msg、im:resource 等)用于启动自检与深链提示——注意它只检测不自动申请:飞书 scope.apply 只能提交已声明未授权的 scope,无法给 manifest 加新声明。

依赖引导(ensureDependencies)

src/setup/index.ts 在 botmux start/restart 时调用:

  • tmux 必需(PTY 退役):二进制真缺失 + 有 bot 要用 tmux 后端 + 未显式 BACKEND_TYPE=pty 时硬失败拒绝启动(shouldHardFailStartupForMissingTmux);「存在但探测失败」不硬失败,交给 per-session worker gate 优雅降级。实现见 ensure-tmux.ts。
  • 字体 best-effort(ensure-fonts.ts,截图渲染用),失败只警告。
  • herdr 按需:只有 bots.json 里有 backendType: 'herdr' 才装(ensure-herdr.ts + ensure-herdr-integrations.ts,含 TraeX plugin 门控)。另有 ensure-zellij.ts / ensure-zmx.ts / ensure-opus.ts。

文件速查

文件职责
setup-args.ts脚本化模式 argv 解析(纯函数)
bot-config-editor.tsbot 配置规范化/编辑/唯一性校验
cli-selection.ts / cli-availability.tsCLI 适配器选择(含网关键)与可用性检查
interactive-select.tsTUI 选择器
register-app.tsSDK device flow 扫码建应用
open-platform-automation.tsWeb session + console API 全自动化(78KB 核心)
open-platform-outcome.ts / -visibility.ts结果分类 / 可见范围解析
verify-permissions.ts凭证校验 + critical scope 自检
agent-preset.ts / app-name.ts / bots-store.tspreset 导出 / 应用名生成 / bots.json 原子写
detect-platform.ts平台探测

相关:bots-json、quickstart、cli、adapters