feat: add CDP connection support for external browsers (#24)
* feat: add CDP connection support for external browsers Add --cdp flag to connect to browsers via Chrome DevTools Protocol. This enables control of Electron apps, Chrome instances, or any browser exposing a CDP endpoint. - Add cdpPort option to launch command schema - Implement connectViaCDP() using chromium.connectOverCDP() - Track browser connection type for proper reconnection handling - Collect all pages from all contexts for CDP connections Usage: agent-browser --cdp 9222 snapshot Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat: enhance CDP connection handling and improve page tracking * main.rs update Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com> * fix: verify CDP connection is alive before early return in launch() Prevents misleading errors when the remote browser crashes by checking isConnected() before reusing an existing browser reference. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: reconnect when CDP port changes instead of reusing existing browser Ensures --cdp flag is respected even when a browser session already exists. Adds tests for launch() reconnection behavior. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Update src/browser.ts Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com> * fix: improve CDP connection handling and validation * feat: add CDP connection validation to ensure browser context accessibility * Update src/browser.ts Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com> * feat: enhance CDP connection handling and add reconnect logic * fix: improve CDP connection handling during browser closure * fix: reset cdpPort to null during browser initialization * feat: enhance browser launch logic to handle CDP connection switching --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
Claude Opus 4.5
vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>
parent
97b17c98fb
commit
95675e9d55
+64
-4
@@ -168,12 +168,72 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
// If --headed flag is set, send launch command first to switch to headed mode
|
||||
if flags.headed {
|
||||
let launch_cmd = json!({ "id": gen_id(), "action": "launch", "headless": false });
|
||||
// Connect via CDP if --cdp flag is set
|
||||
if let Some(ref port) = flags.cdp {
|
||||
let cdp_port: u16 = match port.parse::<u32>() {
|
||||
Ok(p) if p == 0 => {
|
||||
let msg = "Invalid CDP port: port must be greater than 0".to_string();
|
||||
if flags.json {
|
||||
println!(r#"{{"success":false,"error":"{}"}}"#, msg);
|
||||
} else {
|
||||
eprintln!("\x1b[31m✗\x1b[0m {}", msg);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
Ok(p) if p > 65535 => {
|
||||
let msg = format!("Invalid CDP port: {} is out of range (valid range: 1-65535)", p);
|
||||
if flags.json {
|
||||
println!(r#"{{"success":false,"error":"{}"}}"#, msg);
|
||||
} else {
|
||||
eprintln!("\x1b[31m✗\x1b[0m {}", msg);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
Ok(p) => p as u16,
|
||||
Err(_) => {
|
||||
let msg = format!("Invalid CDP port: '{}' is not a valid number. Port must be a number between 1 and 65535", port);
|
||||
if flags.json {
|
||||
println!(r#"{{"success":false,"error":"{}"}}"#, msg);
|
||||
} else {
|
||||
eprintln!("\x1b[31m✗\x1b[0m {}", msg);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
let launch_cmd = json!({
|
||||
"id": gen_id(),
|
||||
"action": "launch",
|
||||
"cdpPort": cdp_port
|
||||
});
|
||||
|
||||
let err = match send_command(launch_cmd, &flags.session) {
|
||||
Ok(resp) if resp.success => None,
|
||||
Ok(resp) => Some(resp.error.unwrap_or_else(|| "CDP connection failed".to_string())),
|
||||
Err(e) => Some(e.to_string()),
|
||||
};
|
||||
|
||||
if let Some(msg) = err {
|
||||
if flags.json {
|
||||
println!(r#"{{"success":false,"error":"{}"}}"#, msg);
|
||||
} else {
|
||||
eprintln!("\x1b[31m✗\x1b[0m {}", msg);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Launch headed browser if --headed flag is set (without CDP)
|
||||
if flags.headed && flags.cdp.is_none() {
|
||||
let launch_cmd = json!({
|
||||
"id": gen_id(),
|
||||
"action": "launch",
|
||||
"headless": false
|
||||
});
|
||||
|
||||
if let Err(e) = send_command(launch_cmd, &flags.session) {
|
||||
if !flags.json {
|
||||
eprintln!("\x1b[33m⚠\x1b[0m Could not switch to headed mode: {}", e);
|
||||
eprintln!("\x1b[33m⚠\x1b[0m Could not launch headed browser: {}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user