Windows: 每个命令都会泄露一个孤立的代理,而一个活动的应用程序服务器会使工作区目录变成不可删除的。

作者: y-shimomoto创建于 2026年9月3日更新于 2026年9月14日
  1. Windows 上,代理服务器准备度预算无法访问,超时路径会泄露进程。ensureBrokerSession() 等待 2000 ms,以确保代理服务器接受连接:
// scripts/lib/broker-lifecycle.mjs:149
const ready = await waitForBrokerEndpoint(endpoint, options.timeoutMs ?? 2000);
if (!ready) {
  teardownBrokerSession({
    endpoint, pidFile, logFile, sessionDir,
    pid: child.pid ?? null,
    killProcess: options.killProcess ?? null  // ← 从 connect() 中永远为 null
  });
  return null;
}

但是,代理服务器只在其自己的应用服务器客户端完成 initialize 后才开始监听:

// scripts/app-server-broker.mjs:68
const appClient = await CodexAppServerClient.connect(cwd, { disableBroker: true });
...
// scripts/app-server-broker.mjs:246
server.listen(listenTarget.path);

在 Windows 上,codex app-server 通过一个 shell(shell: process.env.SHELL || true, scripts/lib/app-server.mjs:194)启动,因此链条为 node brokerbash -c "codex app-server"bashshnode codex.jscodex.exe。测量代理服务器端口接受连接所需的时间,在一个空闲机器上连续执行三次操作:

在预装的 2000 ms 预算内准备就绪:false
在 60000 ms 内准备就绪:true(耗时 3617 ms)
在 60000 ms 内准备就绪:true(耗时 2984 ms)
在 60000 ms 内准备就绪:true(耗时 3424 ms)

后果如下:

  • 准备就绪检查 总是 超时,因此 ensureBrokerSession() 返回 null,每个命令都默认回退到直接应用服务器。代理服务器功能永远不会启用。
  • CodexAppServerClient.connect() 调用 ensureBrokerSession(cwd, { env: options.env }),因此永远不会提供 killProcess,因此超时路径 不会杀死代理服务器。它只会解除链接 pid 文件。代理服务器启动后一秒钟,并永远运行。
  • saveBrokerSession() 从未被触发,因此没有写入 broker.json,并且 SessionEnd 钩子的 broker/shutdown 无法找到应关闭的进程。
  • 总体效果是 每个伴随调用都会泄露一个孤立的 node app-server-broker.mjs 以及整个 codex app-server。在一个六个命令的测试扫描中,我们统计了七个活动代理服务器;另外两个仍然保留着前一天的工作树。

内容来源: openai/codex-plugin-cc