cpx 是一个静态二进制(约 8–9 MB,CGO_ENABLED=0,无运行时依赖),传过去就能用,
不需要 Go、不需要 npm、不需要装一堆东西。
# ① 在 Mac 上:按远端架构交叉编译 → scp → 装好 → 远程自检(一条 make 命令)
make push HOST=user@ubuntu
# ② 在 Ubuntu 上:一条命令自证(不需要 codex、不需要登录、不联网)
cpx selftest
# ③ 真实使用(需要 codex 已登录;没装就先 codex login)
cpx exec "把 build.sh 里的死代码删掉"没有 ssh 直达,手工三步等价:
make release # → dist/release/cpx-<版本>-linux-<架构>.tar.gz(附 SHA256SUMS)
scp dist/cpx-linux-amd64 user@ubuntu:/tmp/cpx
ssh user@ubuntu 'chmod +x /tmp/cpx && /tmp/cpx install' # 装到 ~/.local/bin,无需 sudocpx install 会打印 PATH 提示与下一步;cpx selftest 会用内置假上游把转发、
turn 归组、模型替换识别、凭证检查全跑一遍并给出结论。两条命令都不碰你的真实审计日志
(自检写在临时目录,可用 --keep 保留)。
| 依赖 | 用途 | 安装 |
|---|---|---|
| codex CLI | 真实使用(cpx 是它的代理层) | npm i -g @openai/codex,首次 codex login |
| tmux | cpx tui 的实时状态面板 |
sudo apt install tmux |
| libnotify-bin | 降级桌面通知(notify_on_mismatch) |
sudo apt install libnotify-bin |
cpx doctor # 环境自检 + 明确的"下一步"
cpx # 交互式 TUI(参数原样透传给 codex)
cpx exec "…" # 一次性任务
cpx tui # TUI + 下方实时状态面板(tmux 分屏)
cpx report # 事后:哪条请求被替换了模型、STATE 格式是否符合预期、第几个 turn
cpx status # 当前会话状态块(默认取最新会话;有降级 → 退出码 1)
cpx status --follow --session <id> # 只看某个会话(tmux 面板用的就是这条)
cpx watch # 实时跟读审计日志| 项 | macOS | Linux |
|---|---|---|
| 系统代理检测 | 额外读 scutil --proxy |
只认环境变量:export HTTPS_PROXY=… |
| 桌面通知 | osascript(自带) |
notify-send(libnotify-bin;无桌面会话时静默跳过) |
cpx tui |
brew install tmux |
sudo apt install tmux |
其余(审计、报告、凭证、状态文件、退出摘要、loopback NO_PROXY 注入)完全一致。
代理注意:Ubuntu 上如果走 Clash/Mihomo 的"系统代理"(GNOME 设置界面),它不写环境变量, 请在 shell rc 或 systemd unit 里显式导出:
export HTTPS_PROXY=http://127.0.0.1:7890
export HTTP_PROXY=http://127.0.0.1:7890
export NO_PROXY=127.0.0.1,localhost# ~/.config/systemd/user/cpx.service
[Unit]
Description=CodexProxy
After=network-online.target
[Service]
Environment=CPX_LISTEN=127.0.0.1:8787
Environment=HTTPS_PROXY=http://127.0.0.1:7890
ExecStart=%h/.local/bin/cpx serve
Restart=on-failure
[Install]
WantedBy=default.targetsystemctl --user daemon-reload && systemctl --user enable --now cpx
journalctl --user -u cpx -fcpx serve 只起代理、不拉 codex;把它打印的手动接入命令行加到需要代理的工具上即可。
状态文件按会话隔离(
~/.codexproxy/status-<会话>.json),并发会话不会互相覆盖。listen默认只允许回环;要在服务器上对外监听必须显式Environment=CPX_ALLOW_REMOTE=1, 因为那等于把账号借给任何能访问该端口的人。
e2e/linux/run.sh # 需要 docker;默认 ubuntu:24.04脚本做的事与你的路径完全一致:构建 linux 静态二进制 → 拷进干净容器(等价 scp)→
cpx install → cpx selftest → 完整链路(基于假 codex + 假上游,免登录)。
2026-09-20 实测(Ubuntu 24.04.5 LTS 容器,e2e/linux/run.sh):
== 1/5 构建 linux/arm64 静态二进制 ==
8.7M /tmp/…/cpx(单文件、全静态)
== 3/5 传入二进制 + cpx install ==
已安装:/root/.local/bin/cpx
提示:/root/.local/bin 不在 PATH。两种办法:
1) cpx install --add-path # 自动写进 /root/.profile(幂等)
2) 手工加一行到 /root/.profile:
export PATH="/root/.local/bin:$PATH"
已验证可运行:cpx dev
== 4/5 cpx selftest(无需 codex / 登录 / 联网)==
请求 1 → gpt-6-astra(上游签发新凭证:true · 292 字符)
请求 2 → gpt-5.6-sol
会话 s-selftest · 2026-09-20 05:42:43 → 05:42:43 · 2 请求 / 1 turns · 模型 ⚠ 被替换 1 次
turn 1 05:42:43 2 请求 ⚠ 1 条被替换
⚠ #2 05:42:43 0ms gpt-6-astra → gpt-5.6-sol [凭证 ✔ 292 字符 3d4d248a] tier=default req_selftest_2
凭证检查: ✔ 合格
见过的长度: 292 字符×2
来源: 客户端携带 1 次 / 未携带 1 次 · 上游签发新凭证 1 张 · 客户端带的是上游此前签发的凭证
最近一张: 3d4d248a · 292 字符 · 客户端携带 · 不到 1 分钟前签发
✅ 自检通过:转发、turn 归组、模型替换识别、凭证检查都正常
自检日志已清理(需要保留时:cpx selftest --keep)
== 5/5 完整链路(假 codex + 假上游)==
cpx: 本次会话 s-1c745cb6:2 请求 / 1 turns,模型 ⚠ 被替换 1 次(gpt-6-astra → gpt-5.6-sol),凭证 ✔ 合格(见过 292 字符×2);客户端携带 1 次 / 未携带 1 次 · 上游签发新凭证 1 张 · 客户端带的是上游此前签发的凭证
⚠ #2 05:42:44 42ms gpt-6-astra → gpt-5.6-sol [凭证 ✔ 292 字符(仅长度/前缀合格) 61541f42] tier=default req_linux_2
凭证检查: ✔ 合格
来源: 客户端携带 1 次 / 未携带 1 次 · 上游签发新凭证 1 张 · 客户端带的是上游此前签发的凭证
最近一张: 61541f42 · 292 字符 · 客户端携带
status exit=1(有降级)
-- cpx tui(tmux 分屏状态面板;面板窗格 2 行,两行结论都在)--
%0 h=30 cmd=sleep
--- 附加在 TUI 下方的 cpx 状态面板 ---
当前 turn 1 · 模型 ✗ · 凭证 292 字符 ✔
累计 · 模型正确 1 次 / 错误 1 次 · 凭证 292 字符正确 2 次 / 312 字符错误 0 次
-- 5b 客户端提前断流(读到终局事件就挂断)--
fake_codex_stream: terminal=True, hung up
cpx: 本次会话 s-eb2b1bc3:1 请求 / 1 turns,模型 ✔ 没被替换,凭证 ✔ 合格(见过 292 字符×1);客户端携带 0 次 / 未携带 1 次 · 上游签发新凭证 1 张
✓ 审计记为 client_closed,不计入转发错误
| 现象 | 处理 |
|---|---|
doctor 报 codex 不可用 |
which codex 确认 PATH(nvm 安装时常见);必要时 export CPX_CODEX_BIN=/path/to/codex |
| 上不通 / 超时 | 多数是代理:curl -x $HTTPS_PROXY https://chatgpt.com 自测,或 CPX_UPSTREAM_BASE 指向可达端点 |
| 没有桌面通知 | sudo apt install libnotify-bin;服务器无桌面会话时按设计静默跳过 |
cpx tui 提示未找到 tmux |
sudo apt install tmux;或直接 cpx(功能不受影响) |
| 状态面板只看到「累计」一行 | 你跑的是修复前的旧二进制(v0.1.0 的发布包正是它):每帧多打一个换行,把「当前 turn」顶出 2 行窗格。cpx version 确认 ≥ 0.1.1,然后重装(源码机器 make install,远端 make push HOST=…,或解压新包 ./cpx install);0.1.1 起两行都在,e2e/linux/run.sh 会断言这一点 |
| 想换安装目录 | cpx install --prefix ~/bin;或 make push HOST=user@ubuntu DIR=bin |
| 审计/状态文件在哪 | ~/.codexproxy/audit.jsonl(0600)、~/.codexproxy/status.json,均可用环境变量覆盖 |