Skip to content

修复 macOS 锁屏恢复后 helper 后端误断开【Fix macOS helper reinjection after sleep】#105

Merged
BigPizzaV3 merged 1 commit into
BigPizzaV3:mainfrom
hl9565:codex/macos-helper-reinject
May 15, 2026
Merged

修复 macOS 锁屏恢复后 helper 后端误断开【Fix macOS helper reinjection after sleep】#105
BigPizzaV3 merged 1 commit into
BigPizzaV3:mainfrom
hl9565:codex/macos-helper-reinject

Conversation

@hl9565
Copy link
Copy Markdown

@hl9565 hl9565 commented May 15, 2026

背景

macOS 下 Codex++ 在锁屏、睡眠或恢复后,顶部状态偶尔会变红,表现为“后端已断开”。

排查发现,这个问题不一定是 helper server 真的退出,而是 renderer 里的注入 bridge 在恢复后丢失或 CDP WebSocket 被重置,导致前端无法继续调用 helper。

现场现象

出现红灯时,本地 helper 和 Codex CDP 端口仍然可能正常:

curl --noproxy '*' http://127.0.0.1:57321/health
# {"ok": true}

curl --noproxy '*' http://127.0.0.1:9229/json
# 可以看到 Codex page target

但在 Codex renderer DevTools 中检查:

typeof window.__codexSessionDeleteBridge
// 'undefined'

window.__CODEX_SESSION_DELETE_HELPER__
// undefined

这说明 helper 进程和 CDP 还在,但页面里的 bridge 已经不存在了。

相关日志

锁屏恢复后,曾观察到 bridge WebSocket 被系统重置,随后重新注入成功:

[2026-05-15T09:09:36] bridge health check failed; reinjecting debug_port=9229 helper_port=57321: [Errno 54] Connection reset by peer
[2026-05-15T09:09:36] injected renderer bridge debug_port=9229 helper_port=57321

此前也观察到 macOS 存活判断误判后关闭 helper:

[2026-05-14T23:01:32] macOS Codex liveness check failed debug_port=9229
[2026-05-14T23:01:32] shutting down helper port=57321
[2026-05-14T23:01:33] helper shutdown complete port=57321

原因分析

macOS 版 launcher 启动 Codex 后拿不到一个可等待的 Codex 子进程句柄,所以原逻辑主要依赖 ps 命令行匹配来判断 Codex 是否仍在运行。

这个判断在 macOS/Electron 场景下比较脆弱:

  • Codex 由 open -a 启动,launcher 不持有真实子进程
  • Electron 会派生多个 Helper / Renderer / app-server 进程
  • 锁屏、睡眠、恢复后,renderer bridge 可能丢失,但 helper 和 Codex 仍然存活
  • 单纯依赖进程命令行无法判断“Codex 页面是否仍可注入”

因此会出现两类问题:

  • Codex 仍在运行,但 launcher 误判后关闭 helper
  • helper 仍在运行,但 renderer bridge 丢失,前端显示后端断开

修改内容

本次改动主要做了三件事:

  1. macOS 存活判断优先使用 CDP page target

    先通过当前 debug port 检查是否还能看到 Codex page target;只有 CDP 不可用时,才回退到 ps 进程匹配。

  2. helper 端口已存在时复用健康实例

    启动前先检查 127.0.0.1:<helper_port>/health。如果已有 helper 正常运行,则复用该 helper,避免因为端口已占用直接启动失败。

  3. 增加 renderer bridge watchdog

    注入成功后定期检查 renderer 里的 window.__codexSessionDeleteBridge 是否还存在。如果 bridge 丢失或 CDP WebSocket 被重置,会尝试重新注入。

同时补充了关键运行日志,后续如果再次出现红灯,可以通过:

tail -n 120 ~/.codex-session-delete/launcher.log

判断是 helper 退出、Codex liveness 误判,还是 bridge 丢失后重注入失败。

影响范围

该修复主要影响 macOS launcher 路径:

  • macOS 下 codex_proc is None 时,会使用新的 CDP 优先存活判断
  • Windows 仍然保留原有基于进程 ID 的等待方式
  • helper 复用逻辑只在已有 /health 正常时生效,不会复用不可用端口
  • bridge watchdog 只在注入成功后运行,用于恢复 renderer bridge

验证

本地测试通过:

.venv/bin/python -m pytest tests/test_launcher_cli.py tests/test_cdp.py -q

结果:

51 passed

本地 macOS 锁屏恢复后观察到 bridge 可自动重注入,红灯状态可以恢复。

@hl9565 hl9565 force-pushed the codex/macos-helper-reinject branch from bd1e769 to cbe85ed Compare May 15, 2026 03:32
@BigPizzaV3 BigPizzaV3 merged commit 1d1599a into BigPizzaV3:main May 15, 2026
@hl9565 hl9565 deleted the codex/macos-helper-reinject branch May 16, 2026 06:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants