代理端口:
1 | mixed-port: 7897 # HTTP + SOCKS 混合端口 |
一、首次启动 reconnecting 5 次
现象:每次启动都要重连 5 次才连上,诊断命令里是这两行:
1 | ⚠ websocket Responses WebSocket failed; HTTPS fallback may still work |
最终能降级到 HTTPS 跑起来,所以表现是”慢”而不是”挂”。
根因:Windows 的「系统代理」(注册表 Internet Settings)只对主动去读它的程序生效。codex 的普通 HTTP 请求会读它,所以连通性探测是通的;但 WebSocket 客户端不读,于是直连超时、重连 5 次。
| 请求类型 | 是否读系统代理 | 结果 |
|---|---|---|
| 普通 HTTP(探测、降级后的 HTTPS) | 读 | 通 |
| WebSocket 客户端 | 不读 | 超时 → 重连 5 次 |
也就是说,「系统代理开着」对 WebSocket 完全无效,这是必然结果,不是配置没生效。
Clash 侧不需要任何额外配置:WebSocket 握手本质是一次带 Upgrade: websocket 头的 HTTP 请求,经 HTTP 代理走 CONNECT 隧道,隧道是纯字节流,Clash 不解析里面跑的是 HTTP 还是 WebSocket,没有开关要打开。
解决:WebSocket 客户端认环境变量,指向 Clash 的混合端口。
1 | setx HTTP_PROXY "http://127.0.0.1:7897" |
wss://走HTTPS_PROXY;NO_PROXY让回环地址直连。setx写的是用户级变量,对已打开的窗口不生效,终端要整个退出重开(新开标签页不够)。- 少数工具只认小写变量名,不生效就再补一组小写的
http_proxy/https_proxy。
环境变量是全局的,副作用是代理软件没开时其他程序不会自动回退直连——实测返回 000(退出码 7)。只对单条命令注入的做法:
withproxy.cmd
1 | @echo off |
用法就是 withproxy codex。
- 最后一行必须是
call %*,不能写成%*。不加call时控制权不返回本脚本,两边setlocal/endlocal的配对被打乱,刚设的变量会被一起弹掉,等于没注入。 - 文件要存成 CRLF 换行 + 纯 ASCII。
验证:
1 | ✓ websocket connected (HTTP 101 Switching Protocols) · 15s timeout |
HTTP 101 Switching Protocols 是 WebSocket 握手成功才会有的状态码。
二、无法在提权终端启动后台 daemon
现象:启动时报错,大意是检测到当前运行在提权(elevated)终端里,拒绝启动后台 daemon。
根因:不在 codex,在 Windows 的 UAC。EnableLUA 为 0(UAC 关闭)时,系统不再做令牌过滤,进程拿到的都是完整的管理员令牌——Administrators 组(S-1-5-32-544)在里面且处于启用状态。codex 检查的正是这一项(GetTokenInformation + CheckTokenMembership),于是无论终端是不是”以管理员身份运行”都判定为提权,结果就是它认为你永远在提权终端里。
而 daemon 是一个常驻的本地服务,其他 codex 进程连上它就能让它代为执行命令。把它跑在管理员权限下,等于在后台挂了一个管理员权限的执行器,所以 codex 选择直接拒绝启动。
1 | HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System |
解决:在 ~/.codex/config.toml 末尾关掉 daemon 自动启动。
1 | [features] |
codex features list可以确认这项当前是false。- 代价是依赖共享 daemon 的命令(如
codex agents)不可用。 - 临时绕过:
codex --no-daemon。 - 要恢复 daemon 的完整功能,只能把
EnableLUA改回1并重启。