From 2a338d4c29b276d0727f46accbaa6ce4813b4982 Mon Sep 17 00:00:00 2001 From: leeguooooo Date: Mon, 15 Jun 2026 16:47:12 +0900 Subject: [PATCH] diag(connect): log CDP transport mode to detect 'Allow remote debugging?' modal source (#31) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The consent modal only appears on a raw remote-debugging attach or a browser we launched with a debug port — never on the ab-connect extension relay. Append one line per connection to ~/.chrome-use/connect-mode.log (relay | raw-port-attach | launched | remote-ws), flagging 'CONSENT-MODAL-RISK' when a raw-port/launch path runs while the relay was available. Lets us tell a code regression from Chrome's own extension-debugger consent UX when the modal reappears. Best-effort, never fails a connection. Verified: normal 'open' logs mode=relay (consent-free). --- cli/src/connect.rs | 41 +++++++++++++++++++++++++++++++++++++++ cli/src/native/browser.rs | 14 +++++++++++++ 2 files changed, 55 insertions(+) diff --git a/cli/src/connect.rs b/cli/src/connect.rs index 6504bc9..32b7f9b 100644 --- a/cli/src/connect.rs +++ b/cli/src/connect.rs @@ -449,6 +449,47 @@ pub fn relay_url() -> Option { } } +/// Append a one-line record of how a CDP connection was established, to +/// `~/.chrome-use/connect-mode.log`. This is the smoking-gun detector for the +/// "Allow remote debugging?" consent modal: that modal ONLY appears on a raw +/// remote-debugging attach / a browser we launched with a debug port — NEVER on +/// the extension relay. When the modal reappears, this log says which session +/// took which path and when, so we can tell a code regression (`raw-port` / +/// `launched` while the relay was up) from Chrome's own extension-debugger +/// consent UX. Low volume (one line per connection); best-effort, never fails a +/// connection. +pub fn log_connect_mode(ws_url: &str, launched: bool, session: &str) { + let relay = relay_url(); + let relay_up = relay.is_some(); + let mode = if launched { + "launched(debug-port)" + } else if relay.as_deref() == Some(ws_url) { + "relay" + } else if ws_url.contains("127.0.0.1") || ws_url.contains("localhost") { + "raw-port-attach" + } else { + "remote-ws" + }; + // A raw-port attach or a self-launch while the relay was available is the + // exact thing that pops the consent modal — flag it loudly in the line. + let suspect = (mode == "raw-port-attach" || launched) && relay_up; + let line = format!( + "session={session} mode={mode} relay_up={relay_up}{} ws={ws_url}\n", + if suspect { " CONSENT-MODAL-RISK" } else { "" } + ); + if let Some(home) = dirs::home_dir() { + let path = home.join(".chrome-use").join("connect-mode.log"); + use std::io::Write; + if let Ok(mut f) = std::fs::OpenOptions::new() + .create(true) + .append(true) + .open(&path) + { + let _ = f.write_all(line.as_bytes()); + } + } +} + /// Sidecar recording the connected extension's version, written by the host when /// it receives the extension's `hello` (sibling of `relay-cdp-url`). Lets /// `doctor` surface which extension build is live without a CDP round-trip. diff --git a/cli/src/native/browser.rs b/cli/src/native/browser.rs index db08a38..f8b2eff 100644 --- a/cli/src/native/browser.rs +++ b/cli/src/native/browser.rs @@ -490,6 +490,13 @@ impl BrowserManager { } }; + // A launched browser carries a debug port → it's the other path that can + // pop Chrome's consent modal; record it for #31 diagnosis. + crate::connect::log_connect_mode( + &ws_url, + true, + DAEMON_SESSION.get().map(String::as_str).unwrap_or("default"), + ); let manager = if engine == "lightpanda" { initialize_lightpanda_manager(ws_url, process).await? } else { @@ -585,6 +592,13 @@ impl BrowserManager { headers: Option>, ) -> Result { let ws_url = resolve_cdp_url(url).await?; + // Record the transport so a reappearing "Allow remote debugging?" modal + // can be traced to a raw-port attach vs the consent-free relay (#31). + crate::connect::log_connect_mode( + &ws_url, + false, + DAEMON_SESSION.get().map(String::as_str).unwrap_or("default"), + ); let client = Arc::new(CdpClient::connect_with_headers(&ws_url, headers).await?); let mut manager = Self { client,