lark-codex-bridge 0.0.1
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/CHANGELOG.md +9 -0
- package/LICENSE +21 -0
- package/README.md +228 -0
- package/README.zh.md +228 -0
- package/bin/lark-codex-bridge.mjs +2 -0
- package/dist/cli.js +5674 -0
- package/dist/index.d.ts +85 -0
- package/dist/index.js +419 -0
- package/package.json +72 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.0.1 (2026-05-21)
|
|
4
|
+
|
|
5
|
+
Initial public package setup for `lark-codex-bridge`.
|
|
6
|
+
|
|
7
|
+
- Forked from `feishu-claude-code-bridge`.
|
|
8
|
+
- Replaced the local agent backend with Codex CLI.
|
|
9
|
+
- Added Feishu/Lark bridge runtime, Codex session resume, interactive cards, and runtime configuration.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Lark Channel Bridge contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# lark-codex-bridge
|
|
2
|
+
|
|
3
|
+
A lightweight bot that bridges Feishu / Lark messenger with your local Codex CLI. Run one command, scan a QR code to bind a Lark app, and talk to Codex from chat — read screenshots, edit code, anything you'd do at the terminal.
|
|
4
|
+
|
|
5
|
+
> Note: this project is forked from [feishu-claude-code-bridge](https://github.com/zarazhangrui/feishu-claude-code-bridge). It keeps the original Feishu/Lark bridge, session management, interactive cards, and setup wizard, while replacing the local agent backend from Claude Code with Codex CLI and renaming the package to `lark-codex-bridge`.
|
|
6
|
+
|
|
7
|
+
[中文 README](./README.zh.md)
|
|
8
|
+
|
|
9
|
+
## What it does
|
|
10
|
+
|
|
11
|
+
- Forwards Feishu / Lark messages (DM directly, or `@bot` in a group) to your local `codex` CLI, running in a working directory you control.
|
|
12
|
+
- **Streaming card**: Codex's text and tool calls update on a single Lark card in real time — no waiting for the final reply.
|
|
13
|
+
- **Per-chat sessions**: each chat keeps its own Codex thread, so conversations resume where they left off.
|
|
14
|
+
- **Preempt + batch**: a new message interrupts the running run; rapid-fire messages get coalesced into one request.
|
|
15
|
+
- **Multiple workspaces**: `/ws` switches between named project directories, with sessions tracked per workspace.
|
|
16
|
+
- **Images and files**: send them to the bot directly — Codex reads the locally downloaded paths.
|
|
17
|
+
- **Interactive cards**: `/help`, `/ws list`, `/status` return cards with buttons you can click.
|
|
18
|
+
|
|
19
|
+
## Prerequisites
|
|
20
|
+
|
|
21
|
+
- Node.js **>= 20**
|
|
22
|
+
- `codex` CLI installed and logged in — see https://developers.openai.com/codex
|
|
23
|
+
- A Lark / Feishu **PersonalAgent** app (the QR-code wizard on first launch can create one for you).
|
|
24
|
+
|
|
25
|
+
## Install
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm i -g lark-codex-bridge
|
|
29
|
+
# or
|
|
30
|
+
pnpm add -g lark-codex-bridge
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## First run
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
lark-codex-bridge start
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The first run detects there's no app configured and **opens a QR-code wizard**:
|
|
40
|
+
|
|
41
|
+
1. A QR code renders in your terminal.
|
|
42
|
+
2. Scan it with the Feishu / Lark app.
|
|
43
|
+
3. Pick or create a PersonalAgent app.
|
|
44
|
+
4. Credentials are written to `~/.lark-codex/config.json`.
|
|
45
|
+
|
|
46
|
+
### Granting scopes and event subscriptions
|
|
47
|
+
|
|
48
|
+
The wizard creates the app shell, but you still need to confirm a few things on the Lark Developer Console:
|
|
49
|
+
|
|
50
|
+
**Permission scopes:**
|
|
51
|
+
- `im:message`
|
|
52
|
+
- `im:message:send_as_bot`
|
|
53
|
+
- `im:resource`
|
|
54
|
+
|
|
55
|
+
**Event subscriptions (over long-lived WebSocket):**
|
|
56
|
+
- `im.message.receive_v1`
|
|
57
|
+
- `card.action.trigger`
|
|
58
|
+
- `im.message.reaction.created_v1` / `deleted_v1` (optional)
|
|
59
|
+
- `im.chat.member.bot.added_v1` (optional)
|
|
60
|
+
|
|
61
|
+
After enabling those, run `lark-codex-bridge start` again. Once you see `✓ Connected`, find the bot in Feishu / Lark and start chatting.
|
|
62
|
+
|
|
63
|
+
## Commands
|
|
64
|
+
|
|
65
|
+
### Host CLI
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
lark-codex-bridge start [-c <config>] Start the bot
|
|
69
|
+
lark-codex-bridge ps List all running start processes on this machine
|
|
70
|
+
lark-codex-bridge stop <id|#> Stop a start process (SIGTERM, SIGKILL after 2s)
|
|
71
|
+
lark-codex-bridge --help List all commands
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
> When the same app is started multiple times, Lark's open platform routes events to one of the live WebSocket connections at random. `start` detects existing processes for the same app and (in a TTY) prompts: `[c]ontinue / [k]ill old / [a]bort`. In non-TTY mode it warns and continues.
|
|
75
|
+
|
|
76
|
+
`status` / `doctor` / `handover` / `workspace` / `service` are placeholders, planned for later releases.
|
|
77
|
+
|
|
78
|
+
### Slash commands inside Feishu / Lark
|
|
79
|
+
|
|
80
|
+
| Command | Effect |
|
|
81
|
+
|---|---|
|
|
82
|
+
| `/new`, `/reset` | Clear the current chat's session |
|
|
83
|
+
| `/cd <path>` | Switch working directory (resets session) |
|
|
84
|
+
| `/ws list` | List named workspaces (card + buttons) |
|
|
85
|
+
| `/ws save <name>` | Save current cwd as a named workspace |
|
|
86
|
+
| `/ws use <name>` | Switch to a named workspace |
|
|
87
|
+
| `/ws remove <name>` | Delete a named workspace |
|
|
88
|
+
| `/status` | Current cwd / session / agent (card + buttons) |
|
|
89
|
+
| `/config` | Adjust preferences (reply style, tool-call display, ...) |
|
|
90
|
+
| `/stop` | Stop the run in progress (also the `⏹` button on the card) |
|
|
91
|
+
| `/timeout [N\|off\|default]` | Idle-watchdog (minutes) for the current session. `/config` sets the global default. See FAQ below. |
|
|
92
|
+
| `/ps` | List all `start` processes on this host, marking the one replying |
|
|
93
|
+
| `/exit <id\|#>` | Stop a `start` process (your own → graceful; another's → SIGTERM) |
|
|
94
|
+
| `/reconnect` | Force a WebSocket reconnect (use when the bot stops responding after a network blip) |
|
|
95
|
+
| `/doctor [description]` | Feed recent logs and your description back to Codex for self-diagnosis |
|
|
96
|
+
| `/help` | Help card |
|
|
97
|
+
| Any other `/xxx` | Forwarded verbatim to Codex |
|
|
98
|
+
|
|
99
|
+
**Reply policy**: in a DM, the bot replies to anything. In a **group (including topic groups), the bot only replies when `@`-mentioned** (default since 0.1.22); unmentioned messages are ignored. `@all` is never answered. Cloud-doc comments must mention the bot. To restore the older "always answer in groups" behaviour: `/config` → "Require @bot in groups" → No.
|
|
100
|
+
|
|
101
|
+
## Data directories
|
|
102
|
+
|
|
103
|
+
| Path | Content |
|
|
104
|
+
|---|---|
|
|
105
|
+
| `~/.lark-codex/config.json` | App credentials (App ID / Secret), mode 600 |
|
|
106
|
+
| `~/.lark-codex/sessions.json` | Codex thread id + cwd per chat / topic (+ optional `/timeout` override) |
|
|
107
|
+
| `~/.lark-codex/workspaces.json` | Named-workspace map |
|
|
108
|
+
| `~/.lark-codex/processes.json` | Process registry for live `start` instances (used by `ps`/`stop`); dead PIDs are auto-pruned |
|
|
109
|
+
| `~/.lark-codex/media/<chatId>/` | Downloaded images / files, cleaned up after 24h |
|
|
110
|
+
| `~/.lark-codex/logs/YYYY-MM-DD.log` | Structured run logs (JSONL), rotated daily; older than 7 days are pruned at startup (`LARK_CODEX_LOG_DAYS` env var overrides). `/doctor` reads these. |
|
|
111
|
+
|
|
112
|
+
> Upgrading from before 0.1.11? Run `lark-codex-bridge migrate` once — it moves anything under `~/.config/lark-codex-bridge/` and `~/.cache/lark-codex-bridge/` to the new location and upgrades `config.json` to the new schema.
|
|
113
|
+
|
|
114
|
+
## Codex Runtime Config
|
|
115
|
+
|
|
116
|
+
Send `/config` in Feishu / Lark to tune the Codex subprocess. Changes apply to the next run:
|
|
117
|
+
|
|
118
|
+
- `codexBinary`: Codex CLI command or absolute path; default `codex`
|
|
119
|
+
- `model`: passed to `codex exec --model`; leave blank to use Codex defaults
|
|
120
|
+
- `profile` / `profileV2`: passed as `--profile` and `--profile-v2`
|
|
121
|
+
- `sandbox`: `workspace-write` (default), `read-only`, or `danger-full-access`
|
|
122
|
+
- `skipGitRepoCheck`: enabled by default so `/cd` can point at non-Git folders
|
|
123
|
+
- `search`: enables Web Search by launching `codex --search exec ...`
|
|
124
|
+
|
|
125
|
+
You can also edit `~/.lark-codex/config.json` under `preferences.agent`:
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"preferences": {
|
|
130
|
+
"agent": {
|
|
131
|
+
"provider": "codex",
|
|
132
|
+
"codexBinary": "codex",
|
|
133
|
+
"sandbox": "workspace-write",
|
|
134
|
+
"skipGitRepoCheck": true,
|
|
135
|
+
"search": false
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Access control (optional)
|
|
142
|
+
|
|
143
|
+
Out of the box the bot is **open**: anyone who can find it can DM it, any group member can `@`-mention it to trigger a run, and commands like `/account` or `/cd` are usable by all. **That's fine for personal use** — but for a shared team setup, or anywhere you don't want strangers calling `/cd /`, you can tighten three allowlists by sending `/config` inside Feishu.
|
|
144
|
+
|
|
145
|
+
### Common scenarios
|
|
146
|
+
|
|
147
|
+
**Just me**
|
|
148
|
+
|
|
149
|
+
In the `/config` form:
|
|
150
|
+
- **Allowed users**: your own `open_id`
|
|
151
|
+
- Leave the other two blank
|
|
152
|
+
|
|
153
|
+
Messages from anyone else are silently dropped — no denial reply, since that would just confirm the bot exists to outsiders.
|
|
154
|
+
|
|
155
|
+
**A small team**
|
|
156
|
+
|
|
157
|
+
- **Allowed users**: comma-separated `open_id`s of team members
|
|
158
|
+
- Other two blank
|
|
159
|
+
|
|
160
|
+
**Bot only responds in specific work groups**
|
|
161
|
+
|
|
162
|
+
DMs are unaffected; only listed groups trigger responses:
|
|
163
|
+
- **Allowed chats**: comma-separated `chat_id`s of the groups
|
|
164
|
+
- DMs are **always** exempt from this list — so you can always DM the bot to change config later.
|
|
165
|
+
|
|
166
|
+
**Anyone can chat with the bot, but only I can change settings**
|
|
167
|
+
|
|
168
|
+
- **Admins**: your own `open_id`
|
|
169
|
+
- Other two blank
|
|
170
|
+
|
|
171
|
+
Others running `/account`, `/config`, `/exit`, `/reconnect`, `/doctor`, `/cd`, or `/ws` get a `❌ 此命令仅管理员可用` reply. Normal conversation (asking the bot to do things) is unaffected.
|
|
172
|
+
|
|
173
|
+
**Lock everything down**
|
|
174
|
+
|
|
175
|
+
Fill all three. The `/config` form catches common mistakes — e.g. if your admin list doesn't include yourself, or your chat allowlist doesn't include the chat you're submitting from, the submit is rejected with a message explaining why, so you can't accidentally lock yourself out.
|
|
176
|
+
|
|
177
|
+
### Finding `open_id` and `chat_id`
|
|
178
|
+
|
|
179
|
+
Easiest path: have the target user send the bot a message (or `@`-mention it in the target group), then in your terminal:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
grep '"event":"enter"' ~/.lark-codex/logs/$(date +%Y-%m-%d).log | tail -5
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Every line carries `chatId` (group or DM id) and `senderId` (the user's `open_id`). Copy them from there.
|
|
186
|
+
|
|
187
|
+
The Feishu open-platform "Get user info" API also works but needs the `contact:user` scope, which is overkill if you just need a couple of IDs.
|
|
188
|
+
|
|
189
|
+
### Worth knowing
|
|
190
|
+
|
|
191
|
+
- Changes take effect on the **next message** — no restart needed.
|
|
192
|
+
- An empty field means **unrestricted**, not "nobody allowed".
|
|
193
|
+
- To revert a restricted list back to fully open, clear that field in `/config` and submit.
|
|
194
|
+
- DMs are deliberately exempt from the chat allowlist — meaning if you ever accidentally restrict the bot out of every group, **DM the bot and send `/config`** to recover.
|
|
195
|
+
|
|
196
|
+
### Advanced: editing the config file directly
|
|
197
|
+
|
|
198
|
+
The `/config` form writes to `~/.lark-codex/config.json` under `preferences.access`:
|
|
199
|
+
|
|
200
|
+
```json
|
|
201
|
+
{
|
|
202
|
+
"preferences": {
|
|
203
|
+
"access": {
|
|
204
|
+
"allowedUsers": ["ou_xxxxxxxxxxxxx"],
|
|
205
|
+
"allowedChats": ["oc_xxxxxxxxxxxxx"],
|
|
206
|
+
"admins": ["ou_xxxxxxxxxxxxx"]
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
After a manual edit, **restart the bridge** or send **`/reconnect`** from any allowed chat to pick up the changes. The form is usually faster; direct edits make sense mostly for deployment scripts where you want to pre-seed access policy.
|
|
213
|
+
|
|
214
|
+
## FAQ
|
|
215
|
+
|
|
216
|
+
**The bot stays silent / Codex never replies.** Usually the `codex` CLI itself is not logged in, or the session points to a cwd that no longer exists. Send `/status` to inspect; `/new` to start a fresh session.
|
|
217
|
+
|
|
218
|
+
**Codex subprocess looks frozen (card stuck on the last frame).** Since 0.1.20 there's an idle watchdog: if Codex emits nothing for N minutes the process is killed and the card is annotated `⏱ N min no response, auto-terminated`. Disabled by default. Enable with `/config` (global, in minutes), or `/timeout 10` to set it on the current session; `/timeout off` disables for the session; `/timeout default` clears the session override.
|
|
219
|
+
|
|
220
|
+
**Codex says it can't see the image I sent.** Confirm your local Codex CLI supports `codex exec --image`, then check the downloaded attachment path in the bridge logs.
|
|
221
|
+
|
|
222
|
+
## Maintainer Release
|
|
223
|
+
|
|
224
|
+
This project publishes through GitHub Actions + npm Trusted Publishing. See [docs/release.md](./docs/release.md).
|
|
225
|
+
|
|
226
|
+
## License
|
|
227
|
+
|
|
228
|
+
[MIT](./LICENSE)
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# lark-codex-bridge
|
|
2
|
+
|
|
3
|
+
把飞书 / Lark 消息和本地 Codex CLI 打通的轻量 bot,用一条命令起服务,扫码绑应用,在飞书里和 Codex 对话、让它读图 / 改代码。
|
|
4
|
+
|
|
5
|
+
> 说明:本项目 fork 自 [feishu-claude-code-bridge](https://github.com/zarazhangrui/feishu-claude-code-bridge),在其飞书桥接、会话管理、交互卡片、配置向导等能力基础上,将本地 Agent 后端从 Claude Code 改为 Codex CLI,并更名为 `lark-codex-bridge`。
|
|
6
|
+
|
|
7
|
+
[English README](./README.md)
|
|
8
|
+
|
|
9
|
+
## 能干什么
|
|
10
|
+
|
|
11
|
+
- 在飞书(私聊直接发;群里 `@bot`)把消息转给本地的 `codex` CLI,Codex 在你指定的工作目录里工作
|
|
12
|
+
- **流式卡片**:Codex 的文本和工具调用实时出现在同一张卡片上,不用傻等
|
|
13
|
+
- **会话延续**:每个 chat 独立 session,对话能接着上次说
|
|
14
|
+
- **抢占 + 批处理**:中途发新消息会打断旧任务;快速连发几条会合并成一次请求
|
|
15
|
+
- **多工作空间**:`/ws` 切换不同项目,session 自己重置
|
|
16
|
+
- **图片 / 文件**:直接发给 bot,Codex 会读本地下载的文件路径
|
|
17
|
+
- **卡片按钮**:`/help` `/ws list` `/status` 返回交互卡片,点按钮直接操作
|
|
18
|
+
|
|
19
|
+
## 前置条件
|
|
20
|
+
|
|
21
|
+
- Node.js **≥ 20**
|
|
22
|
+
- `codex` CLI 已安装并登录:https://developers.openai.com/codex
|
|
23
|
+
- 一个飞书 / Lark PersonalAgent 应用(首次启动的扫码向导能帮你创建)
|
|
24
|
+
|
|
25
|
+
## 安装
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm i -g lark-codex-bridge
|
|
29
|
+
# 或
|
|
30
|
+
pnpm add -g lark-codex-bridge
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## 首次启动
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
lark-codex-bridge start
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
第一次跑会检测到没配置应用,**自动进入扫码向导**:
|
|
40
|
+
|
|
41
|
+
1. 终端渲染一个二维码
|
|
42
|
+
2. 用飞书 App 扫码
|
|
43
|
+
3. 选择 / 创建 PersonalAgent 应用
|
|
44
|
+
4. 成功后凭据写入 `~/.lark-codex/config.json`
|
|
45
|
+
|
|
46
|
+
### 开放平台补齐 scope 和事件订阅
|
|
47
|
+
|
|
48
|
+
向导只负责创建应用,平台侧还需要手动确认:
|
|
49
|
+
|
|
50
|
+
**权限 scope**:
|
|
51
|
+
- `im:message`
|
|
52
|
+
- `im:message:send_as_bot`
|
|
53
|
+
- `im:resource`
|
|
54
|
+
|
|
55
|
+
**事件订阅(使用长连接接收)**:
|
|
56
|
+
- `im.message.receive_v1`
|
|
57
|
+
- `card.action.trigger`
|
|
58
|
+
- `im.message.reaction.created_v1` / `deleted_v1`(可选)
|
|
59
|
+
- `im.chat.member.bot.added_v1`(可选)
|
|
60
|
+
|
|
61
|
+
启用以后再次 `lark-codex-bridge start`,看到 `✓ 已连接` 就可以在飞书里找 bot 对话了。
|
|
62
|
+
|
|
63
|
+
## 命令速查
|
|
64
|
+
|
|
65
|
+
### 宿主 CLI
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
lark-codex-bridge start [-c <config>] 启动 bot
|
|
69
|
+
lark-codex-bridge ps 列出本机所有正在跑的 start 进程
|
|
70
|
+
lark-codex-bridge stop <id|#> 终止指定 start 进程(SIGTERM,2s 后 SIGKILL)
|
|
71
|
+
lark-codex-bridge --help 列所有命令
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
> 多开同一个 app 时,开放平台会把事件随机推到其中一个长连接。`start` 启动前会检测同 app 已有的进程,TTY 下提示 `[c]ontinue / [k]ill old / [a]bort` 三选;非 TTY 只 warn 并继续。
|
|
75
|
+
|
|
76
|
+
其它命令(`status` / `doctor` / `handover` / `workspace` / `service`)是占位,后续版本补。
|
|
77
|
+
|
|
78
|
+
### 在飞书里用的斜杠命令
|
|
79
|
+
|
|
80
|
+
| 命令 | 作用 |
|
|
81
|
+
|---|---|
|
|
82
|
+
| `/new` `/reset` | 清空当前 chat 的会话 |
|
|
83
|
+
| `/cd <path>` | 切换工作目录(会重置 session) |
|
|
84
|
+
| `/ws list` | 列所有命名工作空间(卡片 + 按钮) |
|
|
85
|
+
| `/ws save <name>` | 把当前 cwd 存为命名工作空间 |
|
|
86
|
+
| `/ws use <name>` | 切换到命名工作空间 |
|
|
87
|
+
| `/ws remove <name>` | 删除命名工作空间 |
|
|
88
|
+
| `/status` | 当前 cwd / session / agent(卡片 + 按钮) |
|
|
89
|
+
| `/config` | 调整偏好(消息回复方式、工具调用显示等) |
|
|
90
|
+
| `/stop` | 终止当前正在跑的 run(也可点卡片底部 ⏹ 终止 按钮) |
|
|
91
|
+
| `/timeout [N\|off\|default]` | 当前 session 的 idle 探活(分钟);`/config` 改全局默认。详见下方"常见问题 — Codex 子进程假死" |
|
|
92
|
+
| `/ps` | 列出本机所有 start 进程,标识当前回复的是哪个 |
|
|
93
|
+
| `/exit <id\|#>` | 终止指定 start 进程(自己 = graceful 退出;他人 = SIGTERM) |
|
|
94
|
+
| `/reconnect` | 强制重连 WebSocket(网络抖动后 bot 没反应时用) |
|
|
95
|
+
| `/doctor [描述]` | 把最近运行日志和你的描述喂给 Codex,自助诊断卡住 / 异常的原因 |
|
|
96
|
+
| `/help` | 帮助卡片 |
|
|
97
|
+
| 其它 `/xxx` | 原样交给 Codex |
|
|
98
|
+
|
|
99
|
+
**消息策略**:私聊 = 不需要 @,任何消息都回;**群(含话题群)= 默认要 @bot 才回**(0.1.22 起的新默认),不 @ 时 bot 完全沉默;@全员永远不响应;云文档评论必须 @bot。要恢复"群里也不强制 @"的老行为:`/config` → "群里需要 @ bot" → 选"否"。
|
|
100
|
+
|
|
101
|
+
## 数据目录
|
|
102
|
+
|
|
103
|
+
| 路径 | 内容 |
|
|
104
|
+
|---|---|
|
|
105
|
+
| `~/.lark-codex/config.json` | 应用凭据(App ID / Secret),权限 600 |
|
|
106
|
+
| `~/.lark-codex/sessions.json` | 每个 chat / 话题 的 Codex thread id + cwd(+ 可选的 `/timeout` 覆盖) |
|
|
107
|
+
| `~/.lark-codex/workspaces.json` | 工作空间映射 |
|
|
108
|
+
| `~/.lark-codex/processes.json` | 当前在跑的 start 进程注册中心(`ps`/`stop` 用),死进程会被自动清理 |
|
|
109
|
+
| `~/.lark-codex/media/<chatId>/` | 下载的图片 / 文件,24h 自动清理 |
|
|
110
|
+
| `~/.lark-codex/logs/YYYY-MM-DD.log` | 结构化运行日志(JSON line),按天滚动;启动时清理超过 7 天的老文件(`LARK_CODEX_LOG_DAYS` 环境变量可改);`/doctor` 命令读它做诊断 |
|
|
111
|
+
|
|
112
|
+
> 升级自 0.1.11 之前的版本?跑一次 `lark-codex-bridge migrate` —— 自动把 `~/.config/lark-codex-bridge/` 和 `~/.cache/lark-codex-bridge/` 下的内容搬到新位置,并把 `config.json` 升级到新结构。
|
|
113
|
+
|
|
114
|
+
## Codex 运行配置
|
|
115
|
+
|
|
116
|
+
在飞书里发 `/config` 可以调整 Codex 子进程参数,改完从下一次 run 开始生效:
|
|
117
|
+
|
|
118
|
+
- `codexBinary`:Codex CLI 命令或绝对路径,默认 `codex`
|
|
119
|
+
- `model`:传给 `codex exec --model`;留空则使用 Codex 默认配置
|
|
120
|
+
- `profile` / `profileV2`:分别对应 `--profile` 和 `--profile-v2`
|
|
121
|
+
- `sandbox`:`workspace-write`(默认)、`read-only` 或 `danger-full-access`
|
|
122
|
+
- `skipGitRepoCheck`:默认开启,允许 `/cd` 到非 Git 目录
|
|
123
|
+
- `search`:开启后以顶层 `codex --search exec ...` 方式启用 Web Search
|
|
124
|
+
|
|
125
|
+
也可以直接写 `~/.lark-codex/config.json` 的 `preferences.agent`:
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"preferences": {
|
|
130
|
+
"agent": {
|
|
131
|
+
"provider": "codex",
|
|
132
|
+
"codexBinary": "codex",
|
|
133
|
+
"sandbox": "workspace-write",
|
|
134
|
+
"skipGitRepoCheck": true,
|
|
135
|
+
"search": false
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## 访问控制(可选)
|
|
142
|
+
|
|
143
|
+
默认 bot 是"开放"的:任何能找到它的人都能私聊它,群里 @bot 就触发响应。**个人自己用 / 给朋友用,这就够了**——但如果想给团队用、或者怕在大群里被滥用,可以在飞书里发 `/config`,调下面三栏中的一栏或几栏。
|
|
144
|
+
|
|
145
|
+
### 几种典型用法
|
|
146
|
+
|
|
147
|
+
**只让我自己用**
|
|
148
|
+
|
|
149
|
+
`/config` 表单里:
|
|
150
|
+
- "用户白名单":填你自己的 `open_id`
|
|
151
|
+
- 其它两栏留空
|
|
152
|
+
|
|
153
|
+
之后非你发的消息会被 bot 静默丢弃——bot 不会回"你没权限"之类的话,免得暴露它存在。
|
|
154
|
+
|
|
155
|
+
**只让一小群同事用**
|
|
156
|
+
|
|
157
|
+
- "用户白名单":填同事们的 `open_id`,英文逗号分隔
|
|
158
|
+
- 其它两栏留空
|
|
159
|
+
|
|
160
|
+
**bot 只在指定工作群里干活**
|
|
161
|
+
|
|
162
|
+
私聊不受影响;群里只有名单上的群才触发响应:
|
|
163
|
+
- "群白名单":填想让 bot 工作的群 `chat_id`,英文逗号分隔
|
|
164
|
+
- 私聊**永远**不受此约束——意味着你随时能 DM bot 调配置
|
|
165
|
+
|
|
166
|
+
**谁都能跟 bot 聊,但只有我能改设置**
|
|
167
|
+
|
|
168
|
+
- "管理员":填你自己的 `open_id`
|
|
169
|
+
- 其它两栏留空
|
|
170
|
+
|
|
171
|
+
下次别人发 `/account` `/config` `/exit` `/reconnect` `/doctor` `/cd` `/ws` 这些敏感命令,会收到 `❌ 此命令仅管理员可用`。普通对话(让 bot 帮忙做事)不受影响。
|
|
172
|
+
|
|
173
|
+
**完全收紧**
|
|
174
|
+
|
|
175
|
+
三栏全填。`/config` 表单会拦下常见误配——比如管理员名单里没把你自己加进去、群白名单里没包含当前会话,提交时会被拒绝并提示原因,不会让你不小心把自己锁在外面。
|
|
176
|
+
|
|
177
|
+
### 怎么找 `open_id` 和 `chat_id`
|
|
178
|
+
|
|
179
|
+
最快的办法:让目标用户给 bot 发一条任意消息(群的话就 @bot 一下),然后在终端:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
grep '"event":"enter"' ~/.lark-codex/logs/$(date +%Y-%m-%d).log | tail -5
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
每一行都带 `chatId`(= 群或私聊 ID)和 `senderId`(= 用户 `open_id`),照着复制就行。
|
|
186
|
+
|
|
187
|
+
也可以查飞书开放平台的"获取用户信息"API,但要先给你的应用加 `contact:user` scope,没必要为了几个 ID 折腾。
|
|
188
|
+
|
|
189
|
+
### 几点提醒
|
|
190
|
+
|
|
191
|
+
- 改完 `/config` **下一条消息**就生效,不用重启
|
|
192
|
+
- 把任何一栏设成**空字符串** = 不限制(不是"一个都不允许")
|
|
193
|
+
- 想从某种受限状态回到"完全开放",把对应栏目清空再提交即可
|
|
194
|
+
- 私聊不受"群白名单"约束——这是设计上故意的:万一你不小心把所有群都锁死了,**回到 bot 的私聊里发 `/config` 就能解锁**
|
|
195
|
+
|
|
196
|
+
### 高级:直接改配置文件
|
|
197
|
+
|
|
198
|
+
不太想登飞书也可以,`/config` 表单背后写的是 `~/.lark-codex/config.json` 的 `preferences.access`:
|
|
199
|
+
|
|
200
|
+
```json
|
|
201
|
+
{
|
|
202
|
+
"preferences": {
|
|
203
|
+
"access": {
|
|
204
|
+
"allowedUsers": ["ou_xxxxxxxxxxxxx"],
|
|
205
|
+
"allowedChats": ["oc_xxxxxxxxxxxxx"],
|
|
206
|
+
"admins": ["ou_xxxxxxxxxxxxx"]
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
手改完之后**重启 bridge** 或者**找一个被允许的会话发 `/reconnect`** 让新配置生效。日常调整还是用 `/config` 表单更省事,直接改文件主要用在"部署脚本里预填"之类的场景。
|
|
213
|
+
|
|
214
|
+
## 常见问题
|
|
215
|
+
|
|
216
|
+
**Codex 挂住不回复**:通常是 `codex` CLI 本身没登录,或者 session 指向了不存在的 cwd。发 `/status` 看当前状态;`/new` 重开会话往往就好。
|
|
217
|
+
|
|
218
|
+
**Codex 子进程假死(卡片停在最后一帧不动)**:支持 idle 探活:Codex 一段时间没输出就被 SIGTERM kill,卡片末尾会标 "⏱ N 分钟无响应,已自动终止"。默认关闭。开启方式:`/config` 设全局值(分钟),或 `/timeout 10` 只对当前 session 生效;`/timeout off` 关掉某个 session 的探活;`/timeout default` 清掉 session 覆盖回退到全局。
|
|
219
|
+
|
|
220
|
+
**图片发过去 Codex 说看不到**:确认当前 Codex CLI 支持 `codex exec --image`,并查看日志里的附件下载路径。
|
|
221
|
+
|
|
222
|
+
## 维护者发布
|
|
223
|
+
|
|
224
|
+
本项目通过 GitHub Actions + npm Trusted Publishing 自动发布,流程见 [docs/release.md](./docs/release.md)。
|
|
225
|
+
|
|
226
|
+
## 许可
|
|
227
|
+
|
|
228
|
+
[MIT](./LICENSE)
|