From 1558fffe95cbf098f77744d3dd55264ae8784e74 Mon Sep 17 00:00:00 2001
From: lennney <94768569+lennney@users.noreply.github.com>
Date: Thu, 2 Jul 2026 13:46:27 +0800
Subject: [PATCH] perf(launcher): event-driven CDP readiness + eliminate nested
retry
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Event-driven stderr pipe (Playwright pattern) replaces 120×1s polling.
Uses three-phase fallback:
Phase 1: oneshot signal from stderr 'DevTools listening on ws://'
Phase 2: exponential backoff TCP probe (100ms→10s)
Phase 3: 1s-interval polling as ultimate safety net (30 attempts)
Also replaces self.inject() → try_inject() in all three phases to
eliminate the hidden 20×500ms retry_injection() loop nested inside
every backoff step.
Before: Phase 2 worst-case ~101s, Phase 3 ~330s, total ~446s
After: Phase 2 worst-case ~21s, Phase 3 ~60s, total ~66s
---
crates/codex-plus-core/Cargo.toml | 2 +-
crates/codex-plus-core/src/launcher.rs | 106 ++++++++++++++++++++++-
crates/codex-plus-core/tests/launcher.rs | 33 ++++++-
3 files changed, 136 insertions(+), 5 deletions(-)
diff --git a/crates/codex-plus-core/Cargo.toml b/crates/codex-plus-core/Cargo.toml
index 2e5609e2..129c6935 100644
--- a/crates/codex-plus-core/Cargo.toml
+++ b/crates/codex-plus-core/Cargo.toml
@@ -19,7 +19,7 @@ serde.workspace = true
serde_json.workspace = true
sha2.workspace = true
thiserror.workspace = true
-tokio = { workspace = true, features = ["net"] }
+tokio = { workspace = true, features = ["net", "io-util"] }
tokio-tungstenite.workspace = true
toml.workspace = true
toml_edit.workspace = true
diff --git a/crates/codex-plus-core/src/launcher.rs b/crates/codex-plus-core/src/launcher.rs
index 75a851c2..614d6285 100644
--- a/crates/codex-plus-core/src/launcher.rs
+++ b/crates/codex-plus-core/src/launcher.rs
@@ -8,7 +8,7 @@ use anyhow::Context;
use async_trait::async_trait;
use futures_util::StreamExt;
use serde_json::Value;
-use tokio::io::{AsyncReadExt, AsyncWriteExt};
+use tokio::io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt};
use tokio::process::{Child, Command};
use tokio::sync::Mutex;
@@ -216,6 +216,9 @@ pub struct DefaultLaunchHooks {
bridge_watchdog: Mutex