lark-codex-bridge
v0.0.2
Published
Bridge Feishu/Lark messenger with local Codex CLI coding agents
Maintainers
Readme
lark-codex-bridge
把飞书 / Lark 消息和本地 Codex CLI 打通的轻量 bot,用一条命令起服务,扫码绑应用,在飞书里和 Codex 对话、让它读图 / 改代码。
说明:本项目 fork 自 feishu-claude-code-bridge,在其飞书桥接、会话管理、交互卡片、配置向导等能力基础上,将本地 Agent 后端从 Claude Code 改为 Codex CLI,并更名为
lark-codex-bridge。
能干什么
- 在飞书(私聊直接发;群里
@bot)把消息转给本地的codexCLI,Codex 在你指定的工作目录里工作 - 流式卡片:Codex 的文本和工具调用实时出现在同一张卡片上,不用傻等
- 会话延续:每个 chat 独立 session,对话能接着上次说
- 抢占 + 批处理:中途发新消息会打断旧任务;快速连发几条会合并成一次请求
- 多工作空间:
/ws切换不同项目,session 自己重置 - 图片 / 文件:直接发给 bot,Codex 会读本地下载的文件路径
- 卡片按钮:
/help/ws list/status返回交互卡片,点按钮直接操作
前置条件
- Node.js ≥ 20
codexCLI 已安装并登录:https://developers.openai.com/codex- 一个飞书 / Lark PersonalAgent 应用(首次启动的扫码向导能帮你创建)
安装
npm i -g lark-codex-bridge
# 或
pnpm add -g lark-codex-bridge首次启动
lark-codex-bridge start第一次跑会检测到没配置应用,自动进入扫码向导:
- 终端渲染一个二维码
- 用飞书 App 扫码
- 选择 / 创建 PersonalAgent 应用
- 成功后凭据写入
~/.lark-codex/config.json
开放平台补齐 scope 和事件订阅
向导只负责创建应用,平台侧还需要手动确认:
权限 scope:
im:messageim:message:send_as_botim:resource
事件订阅(使用长连接接收):
im.message.receive_v1card.action.triggerim.message.reaction.created_v1/deleted_v1(可选)im.chat.member.bot.added_v1(可选)
启用以后再次 lark-codex-bridge start,看到 ✓ 已连接 就可以在飞书里找 bot 对话了。
命令速查
宿主 CLI
lark-codex-bridge start [-c <config>] 启动 bot
lark-codex-bridge ps 列出本机所有正在跑的 start 进程
lark-codex-bridge stop <id|#> 终止指定 start 进程(SIGTERM,2s 后 SIGKILL)
lark-codex-bridge --help 列所有命令多开同一个 app 时,开放平台会把事件随机推到其中一个长连接。
start启动前会检测同 app 已有的进程,TTY 下提示[c]ontinue / [k]ill old / [a]bort三选;非 TTY 只 warn 并继续。
其它命令(status / doctor / handover / workspace / service)是占位,后续版本补。
在飞书里用的斜杠命令
| 命令 | 作用 |
|---|---|
| /new /reset | 清空当前 chat 的会话 |
| /cd <path> | 切换工作目录(会重置 session) |
| /ws list | 列所有命名工作空间(卡片 + 按钮) |
| /ws save <name> | 把当前 cwd 存为命名工作空间 |
| /ws use <name> | 切换到命名工作空间 |
| /ws remove <name> | 删除命名工作空间 |
| /status | 当前 cwd / session / agent(卡片 + 按钮) |
| /config | 调整偏好(消息回复方式、工具调用显示等) |
| /stop | 终止当前正在跑的 run(也可点卡片底部 ⏹ 终止 按钮) |
| /timeout [N\|off\|default] | 当前 session 的 idle 探活(分钟);/config 改全局默认。详见下方"常见问题 — Codex 子进程假死" |
| /ps | 列出本机所有 start 进程,标识当前回复的是哪个 |
| /exit <id\|#> | 终止指定 start 进程(自己 = graceful 退出;他人 = SIGTERM) |
| /reconnect | 强制重连 WebSocket(网络抖动后 bot 没反应时用) |
| /doctor [描述] | 把最近运行日志和你的描述喂给 Codex,自助诊断卡住 / 异常的原因 |
| /help | 帮助卡片 |
| 其它 /xxx | 原样交给 Codex |
消息策略:私聊 = 不需要 @,任何消息都回;群(含话题群)= 默认要 @bot 才回(0.1.22 起的新默认),不 @ 时 bot 完全沉默;@全员永远不响应;云文档评论必须 @bot。要恢复"群里也不强制 @"的老行为:/config → "群里需要 @ bot" → 选"否"。
数据目录
| 路径 | 内容 |
|---|---|
| ~/.lark-codex/config.json | 应用凭据(App ID / Secret),权限 600 |
| ~/.lark-codex/sessions.json | 每个 chat / 话题 的 Codex thread id + cwd(+ 可选的 /timeout 覆盖) |
| ~/.lark-codex/workspaces.json | 工作空间映射 |
| ~/.lark-codex/processes.json | 当前在跑的 start 进程注册中心(ps/stop 用),死进程会被自动清理 |
| ~/.lark-codex/media/<chatId>/ | 下载的图片 / 文件,24h 自动清理 |
| ~/.lark-codex/logs/YYYY-MM-DD.log | 结构化运行日志(JSON line),按天滚动;启动时清理超过 7 天的老文件(LARK_CODEX_LOG_DAYS 环境变量可改);/doctor 命令读它做诊断 |
升级自 0.1.11 之前的版本?跑一次
lark-codex-bridge migrate—— 自动把~/.config/lark-codex-bridge/和~/.cache/lark-codex-bridge/下的内容搬到新位置,并把config.json升级到新结构。
Codex 运行配置
在飞书里发 /config 可以调整 Codex 子进程参数,改完从下一次 run 开始生效:
codexBinary:Codex CLI 命令或绝对路径,默认codexmodel:传给codex exec --model;留空则使用 Codex 默认配置profile/profileV2:分别对应--profile和--profile-v2sandbox:workspace-write(默认)、read-only或danger-full-accessskipGitRepoCheck:默认开启,允许/cd到非 Git 目录search:开启后以顶层codex --search exec ...方式启用 Web Search
也可以直接写 ~/.lark-codex/config.json 的 preferences.agent:
{
"preferences": {
"agent": {
"provider": "codex",
"codexBinary": "codex",
"sandbox": "workspace-write",
"skipGitRepoCheck": true,
"search": false
}
}
}访问控制(可选)
默认 bot 是"开放"的:任何能找到它的人都能私聊它,群里 @bot 就触发响应。个人自己用 / 给朋友用,这就够了——但如果想给团队用、或者怕在大群里被滥用,可以在飞书里发 /config,调下面三栏中的一栏或几栏。
几种典型用法
只让我自己用
/config 表单里:
- "用户白名单":填你自己的
open_id - 其它两栏留空
之后非你发的消息会被 bot 静默丢弃——bot 不会回"你没权限"之类的话,免得暴露它存在。
只让一小群同事用
- "用户白名单":填同事们的
open_id,英文逗号分隔 - 其它两栏留空
bot 只在指定工作群里干活
私聊不受影响;群里只有名单上的群才触发响应:
- "群白名单":填想让 bot 工作的群
chat_id,英文逗号分隔 - 私聊永远不受此约束——意味着你随时能 DM bot 调配置
谁都能跟 bot 聊,但只有我能改设置
- "管理员":填你自己的
open_id - 其它两栏留空
下次别人发 /account /config /exit /reconnect /doctor /cd /ws 这些敏感命令,会收到 ❌ 此命令仅管理员可用。普通对话(让 bot 帮忙做事)不受影响。
完全收紧
三栏全填。/config 表单会拦下常见误配——比如管理员名单里没把你自己加进去、群白名单里没包含当前会话,提交时会被拒绝并提示原因,不会让你不小心把自己锁在外面。
怎么找 open_id 和 chat_id
最快的办法:让目标用户给 bot 发一条任意消息(群的话就 @bot 一下),然后在终端:
grep '"event":"enter"' ~/.lark-codex/logs/$(date +%Y-%m-%d).log | tail -5每一行都带 chatId(= 群或私聊 ID)和 senderId(= 用户 open_id),照着复制就行。
也可以查飞书开放平台的"获取用户信息"API,但要先给你的应用加 contact:user scope,没必要为了几个 ID 折腾。
几点提醒
- 改完
/config下一条消息就生效,不用重启 - 把任何一栏设成空字符串 = 不限制(不是"一个都不允许")
- 想从某种受限状态回到"完全开放",把对应栏目清空再提交即可
- 私聊不受"群白名单"约束——这是设计上故意的:万一你不小心把所有群都锁死了,回到 bot 的私聊里发
/config就能解锁
高级:直接改配置文件
不太想登飞书也可以,/config 表单背后写的是 ~/.lark-codex/config.json 的 preferences.access:
{
"preferences": {
"access": {
"allowedUsers": ["ou_xxxxxxxxxxxxx"],
"allowedChats": ["oc_xxxxxxxxxxxxx"],
"admins": ["ou_xxxxxxxxxxxxx"]
}
}
}手改完之后重启 bridge 或者找一个被允许的会话发 /reconnect 让新配置生效。日常调整还是用 /config 表单更省事,直接改文件主要用在"部署脚本里预填"之类的场景。
常见问题
Codex 挂住不回复:通常是 codex CLI 本身没登录,或者 session 指向了不存在的 cwd。发 /status 看当前状态;/new 重开会话往往就好。
Codex 子进程假死(卡片停在最后一帧不动):支持 idle 探活:Codex 一段时间没输出就被 SIGTERM kill,卡片末尾会标 "⏱ N 分钟无响应,已自动终止"。默认关闭。开启方式:/config 设全局值(分钟),或 /timeout 10 只对当前 session 生效;/timeout off 关掉某个 session 的探活;/timeout default 清掉 session 覆盖回退到全局。
图片发过去 Codex 说看不到:确认当前 Codex CLI 支持 codex exec --image,并查看日志里的附件下载路径。
维护者发布
本项目通过 GitHub Actions + npm Trusted Publishing 自动发布,流程见 docs/release.md。
