@tunnelbox/codex 0.1.1 → 0.1.3
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/README.md +103 -88
- package/dist/index.mjs +1478 -53
- package/package.json +39 -36
package/README.md
CHANGED
|
@@ -1,88 +1,103 @@
|
|
|
1
|
-
# @tunnelbox/codex
|
|
2
|
-
|
|
3
|
-
tunnelbox 的 **Codex 适配器**(B 类,独立进程):手机远程驱动电脑上的 Codex CLI(会话/流式/中止/删除/工作区),复用 `@tunnelbox/core`(RelayClient/状态/二维码)。
|
|
4
|
-
|
|
5
|
-
```
|
|
6
|
-
手机 PWA ──WSS──► relay ──WSS──► 本适配器(电脑上常驻 Node 进程)
|
|
7
|
-
└─ codex exec --json(每次消息拉起一个 codex 子进程)
|
|
8
|
-
```
|
|
9
|
-
|
|
10
|
-
## 前置条件
|
|
11
|
-
|
|
12
|
-
- Node.js ≥ 22;
|
|
13
|
-
- 本机已安装并登录 **Codex CLI**(`codex --version` 可用、已 `codex login` / 配置好 API key)。SDK 无关,直接驱动 `codex exec`。
|
|
14
|
-
|
|
15
|
-
## 构建与运行
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
cd plugin && npm install # workspaces 根(含 codex)
|
|
19
|
-
cd codex && npm run build # 产出 dist/index.mjs
|
|
20
|
-
node dist/index.mjs # 或 npm start
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## 配置
|
|
24
|
-
|
|
25
|
-
| 环境变量 | 默认 | 说明 |
|
|
26
|
-
|---|---|---|
|
|
27
|
-
| `TUNNELBOX_RELAY_URL` | state 保存地址 | 中继地址(如 `wss://chat.example.com`) |
|
|
28
|
-
| `TUNNELBOX_CWD` | `process.cwd()` | 默认工作区;手机工作区选择器可切换 |
|
|
29
|
-
| `TUNNELBOX_CODEX_SANDBOX` | `workspace-write` | `read-only` / `workspace-write` / `danger-full-access`(传给 `codex exec --sandbox`) |
|
|
30
|
-
| `TUNNELBOX_CODEX_MODEL` | codex 默认 | `-m <model>` |
|
|
31
|
-
| `TUNNELBOX_CODEX_BIN` | `codex` | codex 可执行名/绝对路径 |
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
|
42
|
-
|
|
43
|
-
|
|
|
44
|
-
|
|
|
45
|
-
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
- `codex exec`
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
1
|
+
# @tunnelbox/codex
|
|
2
|
+
|
|
3
|
+
tunnelbox 的 **Codex 适配器**(B 类,独立进程):手机远程驱动电脑上的 Codex CLI(会话/流式/中止/删除/工作区),复用 `@tunnelbox/core`(RelayClient/状态/二维码)。
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
手机 PWA ──WSS──► relay ──WSS──► 本适配器(电脑上常驻 Node 进程)
|
|
7
|
+
└─ codex exec --json(每次消息拉起一个 codex 子进程)
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## 前置条件
|
|
11
|
+
|
|
12
|
+
- Node.js ≥ 22;
|
|
13
|
+
- 本机已安装并登录 **Codex CLI**(`codex --version` 可用、已 `codex login` / 配置好 API key)。SDK 无关,直接驱动 `codex exec`。
|
|
14
|
+
|
|
15
|
+
## 构建与运行
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
cd plugin && npm install # workspaces 根(含 codex)
|
|
19
|
+
cd codex && npm run build # 产出 dist/index.mjs
|
|
20
|
+
node dist/index.mjs # 或 npm start
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## 配置
|
|
24
|
+
|
|
25
|
+
| 环境变量 | 默认 | 说明 |
|
|
26
|
+
|---|---|---|
|
|
27
|
+
| `TUNNELBOX_RELAY_URL` | state 保存地址 | 中继地址(如 `wss://chat.example.com`) |
|
|
28
|
+
| `TUNNELBOX_CWD` | `process.cwd()` | 默认工作区;手机工作区选择器可切换 |
|
|
29
|
+
| `TUNNELBOX_CODEX_SANDBOX` | `workspace-write` | `read-only` / `workspace-write` / `danger-full-access`(传给 `codex exec --sandbox`) |
|
|
30
|
+
| `TUNNELBOX_CODEX_MODEL` | codex 默认 | `-m <model>` |
|
|
31
|
+
| `TUNNELBOX_CODEX_BIN` | `codex` | codex 可执行名/绝对路径 |
|
|
32
|
+
| `TUNNELBOX_CODEX_APPROVAL` | `on` | 手机审批开关:`on`/`off`。开启后经 Codex `PermissionRequest` hook 把工具请求推到手机审批卡(**实验**,见「手机审批」) |
|
|
33
|
+
| `TUNNELBOX_CODEX_HOOK_PORT` | `18790` | 本地审批 HTTP 服务端口(hook 子进程与适配器通信用) |
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
TUNNELBOX_RELAY_URL=wss://chat.example.com TUNNELBOX_CODEX_SANDBOX=workspace-write node dist/index.mjs
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## 能力位
|
|
40
|
+
|
|
41
|
+
| 能力 | 值 | 实现 |
|
|
42
|
+
|---|---|---|
|
|
43
|
+
| streaming | true | `codex exec --json` NDJSON 事件(response_item/item_updated 快照替换)→ `message.part` |
|
|
44
|
+
| thinking | true | `agent_reasoning` → thinking 部件(如有) |
|
|
45
|
+
| permission | **true**(`TUNNELBOX_CODEX_APPROVAL=on`,默认) | 经 Codex `PermissionRequest` hook 推送到手机审批卡;中继离线/超时/异常一律 **fail-closed** 拒绝(**实验**) |
|
|
46
|
+
| commands | true | `/new` `/help` |
|
|
47
|
+
| abort | true | kill 子进程(SIGTERM → SIGKILL) |
|
|
48
|
+
|
|
49
|
+
## 手机审批(实验)
|
|
50
|
+
|
|
51
|
+
Codex CLI 通过 hooks 系统暴露外部审批通道(`PermissionRequest` 钩子,见 [Codex Hooks](https://developers.openai.com/codex/hooks))。本适配器据此实现手机审批:
|
|
52
|
+
|
|
53
|
+
- 适配器启动时把 `PermissionRequest` hook 写入 Codex 配置层(`$CODEX_HOME/hooks.json`,默认 `~/.codex/hooks.json`),hook 命令指向本适配器入口(`node <入口> --hook-permission`,幂等,不覆盖已有 hooks);
|
|
54
|
+
- Codex 每次需要审批时调用该 hook → hook 把请求 POST 到适配器的本地 HTTP 服务(`127.0.0.1:18790`)→ 适配器经中继推送 `permission.request` 到手机权限卡;
|
|
55
|
+
- 手机 allow/deny 回填后,hook 写回 Codex:deny → stderr + exit 2(Codex 视为 block);allow → stdout JSON(输出 schema 待实测校正);
|
|
56
|
+
- 开启时 `codex exec` 注入 `-c approval_policy=on-request`,使权限请求真正触发;**中继离线 / 超时(120s)/ 异常一律 fail-closed 拒绝**。
|
|
57
|
+
|
|
58
|
+
⚠️ **实验性**:Codex hooks 体系仍在演进,`PermissionRequest` 的 allow 输出 schema、`codex exec` 是否/如何触发 hooks、hook 的 trust 要求、`approval_policy=on-request` 与 `--sandbox` 组合语义,均需装有 codex CLI 后实测校正。如遇异常可 `TUNNELBOX_CODEX_APPROVAL=off` 关闭(恢复原 fail-closed 沙箱行为,`capability.permission=false`)。
|
|
59
|
+
|
|
60
|
+
## 会话模型
|
|
61
|
+
|
|
62
|
+
- **适配器新建会话 = UUID(alias)**:手机「新建会话」返回适配器生成的 UUID;首次 `codex exec` 产生的 transcript `session_id` 落盘到别名表 `~/.tunnelbox/codex-aliases.json`,后续续聊用 `codex exec --resume <codexId>`(跨进程稳定)。
|
|
63
|
+
- **codex 原生会话**:终端/CLI 里开过的会话经 `CODEX_HOME/sessions`(默认 `~/.codex/sessions`)JSONL 扫描出现在列表,直接以原生 id resume。
|
|
64
|
+
- 历史 = 读 transcript JSONL 转 ChatMessage(含工具调用卡/tool 结果卡);删除会话删除对应 jsonl。
|
|
65
|
+
- 工作区 = 会话 `cwd`(`codex exec -C`);跨会话并行(每会话一个子进程),同一会话运行中禁止再发。
|
|
66
|
+
|
|
67
|
+
## 安全说明
|
|
68
|
+
|
|
69
|
+
- 手机审批(默认开启,实验):经 `PermissionRequest` hook 把请求推到手机审批卡;**中继离线 / 超时 / 异常一律 fail-closed 拒绝**,绝不自动放行。放行边界仍由 `--sandbox` 决定:
|
|
70
|
+
- `read-only`:只读,不会写文件;
|
|
71
|
+
- `workspace-write`(默认):允许写工作区内,工作区外的写/网络等需更高策略;
|
|
72
|
+
- `danger-full-access`:全放行(危险,仅可信工作区使用)。
|
|
73
|
+
- `TUNNELBOX_CODEX_APPROVAL=off` 时回到旧行为:`capability.permission=false`,手机不弹审批卡,放行完全由 `--sandbox` 决定。
|
|
74
|
+
- 请勿把敏感工程目录暴露给不受信手机。
|
|
75
|
+
|
|
76
|
+
## 目录结构
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
plugin/codex/
|
|
80
|
+
├── package.json
|
|
81
|
+
├── tsconfig.json
|
|
82
|
+
├── scripts/build.mjs # esbuild 单文件 dist/index.mjs
|
|
83
|
+
├── scripts/smoke.mjs # 冒烟:连本地中继验证配对流程(不驱动 codex)
|
|
84
|
+
└── src/
|
|
85
|
+
├── index.ts # 入口:env 解析(sandbox/model/bin)+ 连接中继
|
|
86
|
+
├── bridge.ts # relay 连接/配对/消息路由/回合/别名/工作区
|
|
87
|
+
├── runner.ts # codex exec --json 子进程:NDJSON 流式解析 + kill
|
|
88
|
+
├── parser.ts # codex 事件/transcript → 协议 Part/ChatMessage
|
|
89
|
+
├── sessions.ts # transcript 扫描/历史/删除 + 别名表持久化
|
|
90
|
+
└── globals.d.ts # WebSocket 全局类型
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## 与官方 Codex 插件的关系(决策记录)
|
|
94
|
+
|
|
95
|
+
- 本包是 **headless 桥(B 类独立进程)**,已承载 tunnelbox 的全部远程功能需求:会话列表、消息、**流镜像**、审批(`PermissionRequest` hook → 手机审批,实验;沙箱 fail-closed 兜底)、中止、删除、工作区。
|
|
96
|
+
- 官方 Codex 插件(Agent Plugins v1 / `.codex-plugin` legacy)只能提供"会话内注入"类能力(skills/MCP/hooks),**无法提供流镜像、跨会话列表与远程驱动**——它们不是插件体系能表达的能力。
|
|
97
|
+
- 结论:**codex 适配器不需要按官方插件规范改造**。未来如想在"本地 codex 会话内"提供配对/状态等子集,可另补 official-plugin overlay,不影响本桥。
|
|
98
|
+
|
|
99
|
+
## 备注
|
|
100
|
+
|
|
101
|
+
- 状态文件独立:`~/.tunnelbox/remote-state.codex.json`;别名表 `~/.tunnelbox/codex-aliases.json`。
|
|
102
|
+
- 未验证项(需本机装有 codex CLI 后实测校正):`codex exec --json` 事件结构、`--resume` 对 cwd 的匹配、transcript 目录/文件名格式、init 事件 session_id 字段——解析集中在 `parser.ts`/`runner.ts`,便于按实际输出调整。
|
|
103
|
+
- **手机审批待实测**:`PermissionRequest` hook 的 allow 输出 schema、`codex exec` 触发 hooks 的时机、hook trust 要求、`approval_policy=on-request` 注入后与各 sandbox 的组合语义——相关实现集中在 `approval.ts`(hook 子进程 + 本地 HTTP 桥 + hooks.json 安装)。
|