Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 23 additions & 57 deletions crates/autocli-browser/src/bridge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,10 @@ impl BrowserBridge {
pub async fn connect_daemon_page(&mut self) -> Result<Arc<DaemonPage>, CliError> {
let client = Arc::new(DaemonClient::new(self.port));

// Step 1: Check Chrome is running
if !is_chrome_running() {
return Err(CliError::BrowserConnect {
message: "Chrome is not running".into(),
suggestions: vec![
"Please open Google Chrome with the OpenCLI extension installed".into(),
"The extension connects to the daemon automatically when Chrome is open".into(),
],
source: None,
});
}
// Step 1: No browser-process gate. Any Chromium browser (Chrome, Edge, etc.) with the
// extension installed connects to the daemon on its own; the daemon handshake below is the
// only authority on whether a browser is usable. Skipping process-name detection keeps Edge
// and other Chromium browsers working without a per-browser allowlist (see issue #55).

// Step 2: Ensure daemon is running
if client.is_running().await {
Expand Down Expand Up @@ -167,64 +160,37 @@ impl BrowserBridge {
}
}

/// Check if Chrome/Chromium is running as a process.
fn is_chrome_running() -> bool {
if cfg!(target_os = "macos") {
// macOS: check for "Google Chrome" process
std::process::Command::new("pgrep")
.args(["-x", "Google Chrome"])
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::null())
.status()
.map(|s| s.success())
.unwrap_or(false)
} else if cfg!(target_os = "windows") {
// Windows: check for chrome.exe
std::process::Command::new("tasklist")
.args(["/FI", "IMAGENAME eq chrome.exe", "/NH"])
.output()
.map(|o| String::from_utf8_lossy(&o.stdout).contains("chrome.exe"))
.unwrap_or(false)
} else {
// Linux: check for chrome or chromium
std::process::Command::new("pgrep")
.args(["-x", "chrome|chromium"])
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::null())
.status()
.map(|s| s.success())
.unwrap_or(false)
}
}

/// Try to wake up Chrome by opening a window.
/// When Chrome is running but has no windows, the extension Service Worker is suspended.
/// Opening a window activates the Service Worker, which then reconnects to the daemon.
fn wake_chrome() {
let result = if cfg!(target_os = "macos") {
std::process::Command::new("open")
.args(["-a", "Google Chrome", "about:blank"])
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::null())
.spawn()
} else if cfg!(target_os = "windows") {
// Open a blank window in the SYSTEM DEFAULT browser to wake a suspended extension
// Service Worker. We deliberately avoid naming Chrome/Edge: `open about:blank` (macOS),
// `xdg-open about:blank` (Linux) and `cmd /C start "" about:blank` (Windows, empty title arg
// so about:blank is treated as a URL, not a program name) all resolve to the user's default
// Chromium browser. This keeps Edge/Brave/Arc working without hardcoding a binary (see #55).
let result = if cfg!(target_os = "windows") {
std::process::Command::new("cmd")
.args(["/C", "start", "chrome", "about:blank"])
.args(["/C", "start", "", "about:blank"])
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::null())
.spawn()
} else {
// Linux: try common Chrome executables
std::process::Command::new("xdg-open")
.arg("about:blank")
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::null())
.spawn()
// macOS and Linux both have a default-browser opener
std::process::Command::new(if cfg!(target_os = "macos") {
"open"
} else {
"xdg-open"
})
.arg("about:blank")
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::null())
.spawn()
};

match result {
Ok(_) => debug!("Opened Chrome window to wake extension"),
Err(e) => debug!("Failed to open Chrome window: {e}"),
Ok(_) => debug!("Opened default browser window to wake extension"),
Err(e) => debug!("Failed to open browser window: {e}"),
}
}

Expand Down