@tunnelbox/codex 0.1.3 → 0.1.4
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 +138 -103
- package/README.zh-CN.md +138 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,103 +1,138 @@
|
|
|
1
|
-
# @tunnelbox/codex
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
-
|
|
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
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
-
|
|
102
|
-
-
|
|
103
|
-
-
|
|
1
|
+
# @tunnelbox/codex
|
|
2
|
+
|
|
3
|
+
[English](README.md) · [简体中文](README.zh-CN.md)
|
|
4
|
+
|
|
5
|
+
**Official website:** [www.tunnelbox.top](https://www.tunnelbox.top)
|
|
6
|
+
|
|
7
|
+
**tunnelbox Codex adapter (standalone daemon):** drive the Codex CLI on your computer from your phone — sessions, streaming, abort, delete, workspaces. It runs as a background Node process that dials **out** to a relay only (no public IP, no port forwarding).
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
Phone app ──WSS──► relay ──WSS──► tunnelbox-codex (this adapter)
|
|
11
|
+
└─ codex exec --json (spawns a codex subprocess per message)
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Quick start (install → run → pair → use)
|
|
15
|
+
|
|
16
|
+
Follow these steps once on a computer that has Codex installed and signed in.
|
|
17
|
+
|
|
18
|
+
### Step 0 — Prepare your phone
|
|
19
|
+
|
|
20
|
+
Install the tunnelbox App (Android & iOS) from the official website: **https://www.tunnelbox.top**
|
|
21
|
+
|
|
22
|
+
- Sign in / create an account when prompted.
|
|
23
|
+
|
|
24
|
+
### Step 1 — Install the adapter on your computer
|
|
25
|
+
|
|
26
|
+
Prerequisites: Node.js ≥ 22, and the **Codex CLI** installed & signed in (`codex --version`, `codex login` / API key configured).
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install -g @tunnelbox/codex
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Step 2 — Run it
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
tunnelbox-codex
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
On first start the adapter connects to the relay (`wss://relay.tunnelbox.top` by default) and prints a **pairing QR code + pairing code** in the terminal.
|
|
39
|
+
|
|
40
|
+
### Step 3 — Pair with your phone
|
|
41
|
+
|
|
42
|
+
In the phone app tap **Scan to pair** and scan the terminal QR code (or type the pairing code manually). The code is single-use and valid for about 10 minutes.
|
|
43
|
+
|
|
44
|
+
- Once bound, the adapter prints "connected account — open the app and pick this computer" on later starts, and does not refresh the code.
|
|
45
|
+
- Want a fresh code any time? Stop and run:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
tunnelbox-codex --pair
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Step 4 — Use it from your phone
|
|
52
|
+
|
|
53
|
+
In the app, open this computer and you can start new sessions, send messages, watch streaming output, approve risky tool calls, and abort a running session.
|
|
54
|
+
|
|
55
|
+
## Configuration
|
|
56
|
+
|
|
57
|
+
| Env var | Default | Description |
|
|
58
|
+
|---|---|---|
|
|
59
|
+
| `TUNNELBOX_RELAY_URL` | saved relay URL | Relay address (e.g. `wss://chat.example.com`); set it if you self-host |
|
|
60
|
+
| `TUNNELBOX_CWD` | `process.cwd()` | Default workspace; switch per-session from the phone workspace picker |
|
|
61
|
+
| `TUNNELBOX_CODEX_SANDBOX` | `workspace-write` | `read-only` / `workspace-write` / `danger-full-access` (passed as `codex exec --sandbox`) |
|
|
62
|
+
| `TUNNELBOX_CODEX_MODEL` | codex default | `-m <model>` |
|
|
63
|
+
| `TUNNELBOX_CODEX_BIN` | `codex` | Codex executable name / absolute path |
|
|
64
|
+
| `TUNNELBOX_CODEX_APPROVAL` | `on` | Phone approval switch `on`/`off`. When on, tool requests are pushed to the phone approval card via the Codex `PermissionRequest` hook (**experimental**) |
|
|
65
|
+
| `TUNNELBOX_CODEX_HOOK_PORT` | `18790` | Local approval HTTP port (hook subprocess ↔ adapter) |
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
TUNNELBOX_RELAY_URL=wss://chat.example.com TUNNELBOX_CODEX_SANDBOX=workspace-write tunnelbox-codex
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Capabilities
|
|
72
|
+
|
|
73
|
+
| Capability | Value | Notes |
|
|
74
|
+
|---|---|---|
|
|
75
|
+
| streaming | ✅ | `codex exec --json` NDJSON events → live `message.part` deltas |
|
|
76
|
+
| thinking | ✅ | `agent_reasoning` → thinking parts (when present) |
|
|
77
|
+
| permission | ✅ default | `PermissionRequest` hook → phone approval card (**experimental**) |
|
|
78
|
+
| commands | ✅ | `/new`, `/help` |
|
|
79
|
+
| abort | ✅ | kill subprocess (SIGTERM → SIGKILL) |
|
|
80
|
+
| workspaces | ✅ | per-session `cwd` |
|
|
81
|
+
|
|
82
|
+
## Phone approval (experimental)
|
|
83
|
+
|
|
84
|
+
On startup the adapter idempotently installs a `PermissionRequest` hook into the Codex config (`~/.codex/hooks.json`). Each tool request goes hook → local HTTP (`127.0.0.1:18790`) → relay → your phone's approval card. Allow/deny from the phone is written back; denials block the tool (exit 2). When approval is on, `codex exec` runs with `-c approval_policy=on-request`.
|
|
85
|
+
|
|
86
|
+
**Fail-closed:** if the relay is offline, the request times out (120s), or anything errors, the tool is **denied** — never auto-approved. Scope is still bounded by `--sandbox`.
|
|
87
|
+
|
|
88
|
+
> ⚠️ Experimental: Codex's hooks system is still evolving. If anything misbehaves, disable with `TUNNELBOX_CODEX_APPROVAL=off` (restores the built-in fail-closed sandbox behavior, `capability.permission=false`).
|
|
89
|
+
|
|
90
|
+
## Sessions
|
|
91
|
+
|
|
92
|
+
- **New phone sessions = adapter UUIDs.** The transcript id from the first `codex exec` is stored in an alias table (`~/.tunnelbox/codex-aliases.json`); follow-ups resume that session (`codex exec --resume <codexId>`), stable across processes.
|
|
93
|
+
- **Native codex sessions** you started in a terminal also appear in the list (scanned from `CODEX_HOME/sessions`, default `~/.codex/sessions`) and can be resumed by their native id.
|
|
94
|
+
- History is read from the transcript JSONL; deleting a session deletes the file.
|
|
95
|
+
- Workspaces = session `cwd`; sessions run in parallel (one subprocess each); a running session can't receive another message.
|
|
96
|
+
|
|
97
|
+
## Security notes
|
|
98
|
+
|
|
99
|
+
- Phone approval defaults **on** and is **fail-closed** (offline/timeout/error ⇒ deny). Enforcement boundary still follows `--sandbox`:
|
|
100
|
+
- `read-only` — no writes;
|
|
101
|
+
- `workspace-write` (default) — writes inside the workspace; writes/network outside need higher policy;
|
|
102
|
+
- `danger-full-access` — full access (dangerous, trusted workspaces only).
|
|
103
|
+
- Set `TUNNELBOX_CODEX_APPROVAL=off` to go back to `capability.permission=false`: no approval card, gating decided by `--sandbox` alone.
|
|
104
|
+
- Don't expose sensitive projects to an untrusted phone.
|
|
105
|
+
|
|
106
|
+
## Troubleshooting
|
|
107
|
+
|
|
108
|
+
| Problem | Fix |
|
|
109
|
+
|---|---|
|
|
110
|
+
| No QR / pairing code on screen | Run `tunnelbox-codex --pair` to print a fresh one |
|
|
111
|
+
| Need to pair a different phone | Unbind in the app settings, then run with `--pair` again |
|
|
112
|
+
| Already bound but phone doesn't connect | Confirm both use the same relay; check `~/.tunnelbox/tunnelbox.log` |
|
|
113
|
+
| Use your own relay | Start with `TUNNELBOX_RELAY_URL=wss://<your-relay>` |
|
|
114
|
+
|
|
115
|
+
## State files
|
|
116
|
+
|
|
117
|
+
Independent tunnelbox state lives in `~/.tunnelbox/`:
|
|
118
|
+
|
|
119
|
+
- `remote-state.codex.json` — agentID / relay / bound state / language
|
|
120
|
+
- `codex-aliases.json` — adapter-UUID → codex transcript-id aliases
|
|
121
|
+
- `remote-pairing.codex.txt` + `remote-pairing.json` — latest pairing info
|
|
122
|
+
- `tunnelbox.log` — adapter log
|
|
123
|
+
|
|
124
|
+
## Multilingual
|
|
125
|
+
|
|
126
|
+
User-visible output supports 8 languages (`zh-CN` / `zh-TW` / `en-US` / `ja-JP` / `ko-KR` / `fr-FR` / `de-DE` / `es-ES`). Resolution order: `TUNNELBOX_LANG` > saved `remote-state.codex.json.lang` > system locale > `en-US`.
|
|
127
|
+
|
|
128
|
+
## Uninstall
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
npm uninstall -g @tunnelbox/codex
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Remove `~/.tunnelbox` (all adapters' shared state) only if you no longer use any tunnelbox adapter.
|
|
135
|
+
|
|
136
|
+
## Development
|
|
137
|
+
|
|
138
|
+
Implementation details (protocol mapping, source layout, design decisions, untested items) are kept in the source repository as `DEV.md` next to this package, plus the protocol spec under the repo's `docs/`.
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# @tunnelbox/codex
|
|
2
|
+
|
|
3
|
+
[English](README.md) · [简体中文](README.zh-CN.md)
|
|
4
|
+
|
|
5
|
+
**官网:** [www.tunnelbox.top](https://www.tunnelbox.top)
|
|
6
|
+
|
|
7
|
+
**tunnelbox Codex 适配器(独立进程)**:用手机远程驱动电脑上的 Codex CLI——会话 / 流式 / 中止 / 删除 / 工作区。它以常驻 Node 进程运行,只向中继发出站连接(无需公网 IP / 端口映射)。
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
手机 App ──WSS──► relay ──WSS──► tunnelbox-codex(本适配器)
|
|
11
|
+
└─ codex exec --json(每条消息拉起一个 codex 子进程)
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## 快速上手(安装 → 运行 → 配对 → 使用)
|
|
15
|
+
|
|
16
|
+
在装有 Codex 并已登录的电脑上,按以下步骤操作一次即可。
|
|
17
|
+
|
|
18
|
+
### 第 0 步 — 准备手机
|
|
19
|
+
|
|
20
|
+
在官网下载并安装 tunnelbox App(Android / iOS 均已上架):**https://www.tunnelbox.top**
|
|
21
|
+
|
|
22
|
+
- 按提示登录/注册账号。
|
|
23
|
+
|
|
24
|
+
### 第 1 步 — 电脑上安装适配器
|
|
25
|
+
|
|
26
|
+
前置条件:Node.js ≥ 22,且本机已安装并登录 **Codex CLI**(`codex --version` 可用、已 `codex login` 或配好 API key)。
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install -g @tunnelbox/codex
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### 第 2 步 — 运行
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
tunnelbox-codex
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
首次启动会连接中继(默认 `wss://relay.tunnelbox.top`),并在终端打印**配对二维码 + 配对码**。
|
|
39
|
+
|
|
40
|
+
### 第 3 步 — 与手机配对
|
|
41
|
+
|
|
42
|
+
在手机 App 点「扫一扫配对」,扫描终端二维码(或手动输入配对码)。配对码一次性有效,约 10 分钟。
|
|
43
|
+
|
|
44
|
+
- 绑定后再次启动会打印「已绑定账号,从手机「我的电脑」直接连接」,不再刷新码;
|
|
45
|
+
- 随时需要新码:停止后运行:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
tunnelbox-codex --pair
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 第 4 步 — 在手机上使用
|
|
52
|
+
|
|
53
|
+
在 App 里打开这台电脑,即可新建会话、发消息、看流式输出、审批危险工具调用、中止运行中的会话。
|
|
54
|
+
|
|
55
|
+
## 配置
|
|
56
|
+
|
|
57
|
+
| 环境变量 | 默认 | 说明 |
|
|
58
|
+
|---|---|---|
|
|
59
|
+
| `TUNNELBOX_RELAY_URL` | state 保存的地址 | 中继地址(如 `wss://chat.example.com`);自建中继时设置 |
|
|
60
|
+
| `TUNNELBOX_CWD` | `process.cwd()` | 默认工作区;手机上可按会话切换工作区 |
|
|
61
|
+
| `TUNNELBOX_CODEX_SANDBOX` | `workspace-write` | `read-only` / `workspace-write` / `danger-full-access`(传给 `codex exec --sandbox`) |
|
|
62
|
+
| `TUNNELBOX_CODEX_MODEL` | codex 默认 | `-m <model>` |
|
|
63
|
+
| `TUNNELBOX_CODEX_BIN` | `codex` | codex 可执行名/绝对路径 |
|
|
64
|
+
| `TUNNELBOX_CODEX_APPROVAL` | `on` | 手机审批开关 `on`/`off`。开启时经 Codex `PermissionRequest` hook 把工具请求推到手机审批卡(**实验**) |
|
|
65
|
+
| `TUNNELBOX_CODEX_HOOK_PORT` | `18790` | 本地审批 HTTP 端口(hook 子进程与适配器通信用) |
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
TUNNELBOX_RELAY_URL=wss://chat.example.com TUNNELBOX_CODEX_SANDBOX=workspace-write tunnelbox-codex
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## 能力位
|
|
72
|
+
|
|
73
|
+
| 能力 | 值 | 说明 |
|
|
74
|
+
|---|---|---|
|
|
75
|
+
| streaming | ✅ | `codex exec --json` NDJSON 事件 → 实时 `message.part` 增量 |
|
|
76
|
+
| thinking | ✅ | `agent_reasoning` → thinking 部件(如有) |
|
|
77
|
+
| permission | ✅ 默认 | `PermissionRequest` hook → 手机审批卡(**实验**) |
|
|
78
|
+
| commands | ✅ | `/new`、`/help` |
|
|
79
|
+
| abort | ✅ | kill 子进程(SIGTERM → SIGKILL) |
|
|
80
|
+
| workspaces | ✅ | 每会话一个 `cwd` |
|
|
81
|
+
|
|
82
|
+
## 手机审批(实验)
|
|
83
|
+
|
|
84
|
+
启动时把 `PermissionRequest` hook 幂等写入 Codex 配置(`~/.codex/hooks.json`)。每次工具请求走 hook → 本地 HTTP(`127.0.0.1:18790`)→ 中继 → 手机审批卡;手机 allow/deny 回填,deny 阻止工具(exit 2)。审批开启时 `codex exec` 以 `-c approval_policy=on-request` 运行。
|
|
85
|
+
|
|
86
|
+
**fail-closed**:中继离线 / 请求超时(120s)/ 任何异常 → 一律**拒绝**,绝不自动放行;放行边界仍由 `--sandbox` 决定。
|
|
87
|
+
|
|
88
|
+
> ⚠️ 实验性:Codex hooks 体系仍在演进。异常时可 `TUNNELBOX_CODEX_APPROVAL=off` 关闭(恢复内置 fail-closed 沙箱行为,`capability.permission=false`)。
|
|
89
|
+
|
|
90
|
+
## 会话模型
|
|
91
|
+
|
|
92
|
+
- **手机新建会话 = 适配器 UUID**。首次 `codex exec` 的 transcript id 记入别名表(`~/.tunnelbox/codex-aliases.json`),后续用 `codex exec --resume <codexId>` 续聊(跨进程稳定)。
|
|
93
|
+
- **codex 原生会话**:终端里开过的会话也会出现在列表(扫描 `CODEX_HOME/sessions`,默认 `~/.codex/sessions`),以原生 id resume。
|
|
94
|
+
- 历史 = 读 transcript JSONL;删除会话即删对应 jsonl。
|
|
95
|
+
- 工作区 = 会话 `cwd`;会话并行(每会话一个子进程),运行中的会话不能再发消息。
|
|
96
|
+
|
|
97
|
+
## 安全说明
|
|
98
|
+
|
|
99
|
+
- 手机审批默认**开启**且 **fail-closed**(离线/超时/异常一律拒绝)。放行边界由 `--sandbox` 决定:
|
|
100
|
+
- `read-only`:只读,不写文件;
|
|
101
|
+
- `workspace-write`(默认):允许写工作区内;工作区外的写/网络需更高策略;
|
|
102
|
+
- `danger-full-access`:全放行(危险,仅可信工作区)。
|
|
103
|
+
- `TUNNELBOX_CODEX_APPROVAL=off` 回到 `capability.permission=false`:手机不弹审批卡,完全由 `--sandbox` 门控。
|
|
104
|
+
- 请勿把敏感工程目录暴露给不受信手机。
|
|
105
|
+
|
|
106
|
+
## 故障排查
|
|
107
|
+
|
|
108
|
+
| 问题 | 解决 |
|
|
109
|
+
|---|---|
|
|
110
|
+
| 终端没有二维码/配对码 | 运行 `tunnelbox-codex --pair` 打印新码 |
|
|
111
|
+
| 需要换手机配对 | 在 App 设置里解绑,再带 `--pair` 运行 |
|
|
112
|
+
| 已绑定但手机连不上 | 确认两端同一中继;查看 `~/.tunnelbox/tunnelbox.log` |
|
|
113
|
+
| 使用自建中继 | 启动时带 `TUNNELBOX_RELAY_URL=wss://<你的中继>` |
|
|
114
|
+
|
|
115
|
+
## 状态文件
|
|
116
|
+
|
|
117
|
+
tunnelbox 独立状态存于 `~/.tunnelbox/`:
|
|
118
|
+
|
|
119
|
+
- `remote-state.codex.json` — agentID / 中继地址 / 绑定状态 / 语言
|
|
120
|
+
- `codex-aliases.json` — 适配器 UUID → codex transcript id 别名表
|
|
121
|
+
- `remote-pairing.codex.txt` + `remote-pairing.json` — 最新配对信息
|
|
122
|
+
- `tunnelbox.log` — 适配器日志
|
|
123
|
+
|
|
124
|
+
## 多语言
|
|
125
|
+
|
|
126
|
+
用户可见输出支持 8 种语言(`zh-CN` / `zh-TW` / `en-US` / `ja-JP` / `ko-KR` / `fr-FR` / `de-DE` / `es-ES`)。解析顺序:`TUNNELBOX_LANG` > `remote-state.codex.json` 的 `lang` > 系统 locale > 默认 `en-US`。
|
|
127
|
+
|
|
128
|
+
## 卸载
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
npm uninstall -g @tunnelbox/codex
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
仅当不再使用任何 tunnelbox 适配器时,才删除 `~/.tunnelbox`(各适配器共享状态)。
|
|
135
|
+
|
|
136
|
+
## 开发
|
|
137
|
+
|
|
138
|
+
实现细节(协议映射、源码结构、决策记录、待实测项)保存在源码仓库中本包旁的 `DEV.md` 与仓库 `docs/` 下。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tunnelbox/codex",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "tunnelbox 的 Codex 适配器(B 类):手机远程驱动本机 Codex CLI(codex exec --json,会话/流式/中止/删除)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.mjs",
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
11
|
"dist",
|
|
12
|
-
"README.md"
|
|
12
|
+
"README.md",
|
|
13
|
+
"README.zh-CN.md"
|
|
13
14
|
],
|
|
14
15
|
"publishConfig": {
|
|
15
16
|
"access": "public"
|