vercel-labs/agent-browser
Browser automation CLI for AI agents
Rust★ 46,032+150 that day#8 on trending
D43/100
Duplication59
6.5% in rust, tsx, typescript, javascript, bash, pythonDead code45
9.2%Complexity31
84.9% The score is jscpd's own --health model: markup, data and text left out, tests kept. The numbers below are the trending scan's.
6.89%duplicated code · 9,847 of 142,861 lines
861clones in code
175code files of 430 scanned
6.24%duplicated over all files · 941 clones
Most complex files
- cli/src/native/actions.rs3328 cx
- cli/src/native/react/installHook.js3040 cx
- cli/src/commands.rs1291 cx
- cli/src/mcp.rs1118 cx
- cli/src/output.rs1022 cx
- cli/src/native/browser.rs685 cx
- cli/src/native/e2e_tests.rs637 cx
- cli/src/native/flow/mod.rs611 cx
- cli/src/main.rs423 cx
- cli/src/native/cdp/chrome.rs408 cx
Dead code 9.18% unused · 93 findings
- docs/scripts/capture-docs-baseline.mjsunused-file
- docs/src/components/diff-demo.tsxunused-file
- docs/src/components/search.tsxunused-file
- packages/@agent-browser/eve/extension/lib/sandbox.tsunused-file
- packages/@agent-browser/eve/extension/lib/browser.tsunused-file
- docs/src/components/header.tsxunused-file
- docs/src/components/docs-mobile-nav.tsxunused-file
- docs/src/components/copy-page-button.tsxunused-file
- cli/src/native/recording-cursor.jsunused-file
- docs/src/components/docs-sidebar.tsxunused-file
The code number leaves out tests, fixtures, docs, examples, data files, styles, translations and vendored code.
Largest clones in the code
- 12 lines in 31 placesrust72 tokenscli/src/native/e2e_tests.rs:1997–2008cli/src/native/e2e_tests.rs:2276–2285cli/src/native/e2e_tests.rs:2407–2418cli/src/native/e2e_tests.rs:2751–2762cli/src/native/e2e_tests.rs:2909–2920and 26 more
1997async fn e2e_screenshot() { 1998 let mut state = DaemonState::new(); 1999 2000 let resp = execute_command( 2001 &json!({ "id": "1", "action": "launch", "headless": true }), 2002 &mut state, 2003 ) 2004 .await; 2005 assert_success(&resp); 20062276async fn e2e_select_option_label_override_names() { 2277 let mut state = DaemonState::new(); 2278 let resp = execute_command( 2279 &json!({ "id": "1", "action": "launch", "headless": true }), 2280 &mut state, 2281 ) 2282 .await; 2283 assert_success(&resp); 2284 let resp = execute_command( 2285 &json!({ "id": "2", "action": "navigate", "url": "data:text/html,<html><body></body></html>" }),First 10 of 12 lines, the second copy on the right.
- 9 lines in 18 placesrust77 tokenscli/src/native/actions.rs:7091–7099cli/src/native/actions.rs:7151–7158cli/src/native/actions.rs:7234–7242cli/src/native/actions.rs:7291–7299cli/src/native/actions.rs:7437–7445and 13 more
7091async fn handle_dblclick(cmd: &Value, state: &mut DaemonState) -> Result<Value, String> { 7092 let mgr = state.browser.as_ref().ok_or("Browser not launched")?; 7093 let session_id = mgr.active_session_id()?.to_string(); 7094 let selector = cmd 7095 .get("selector") 7096 .and_then(|v| v.as_str()) 7097 .ok_or("Missing 'selector' parameter")?; 7098 7099 let result = interaction::dblclick(7151async fn handle_type(cmd: &Value, state: &mut DaemonState) -> Result<Value, String> { 7152 let mgr = state.browser.as_ref().ok_or("Browser not launched")?; 7153 let session_id = mgr.active_session_id()?.to_string(); 7154 let selector = cmd 7155 .get("selector") 7156 .and_then(|v| v.as_str()) 7157 .ok_or("Missing 'selector' parameter")?; 7158 let text = cmd - 11 lines in 21 placesrust53 tokenscli/src/native/e2e_tests.rs:1997–2007cli/src/native/e2e_tests.rs:2150–2160cli/src/native/e2e_tests.rs:3196–3206cli/src/native/e2e_tests.rs:3289–3299cli/src/native/e2e_tests.rs:3368–3378and 16 more
1997async fn e2e_screenshot() { 1998 let mut state = DaemonState::new(); 1999 2000 let resp = execute_command( 2001 &json!({ "id": "1", "action": "launch", "headless": true }), 2002 &mut state, 2003 ) 2004 .await; 2005 assert_success(&resp); 2006First 10 of 11 lines.
7 more
- 16 lines in 6 placesrust207 tokens
- 16 lines in 10 placesrust90 tokens
- 9 lines in 14 placesrust52 tokens
- 10 lines in 11 placesrust54 tokens
- 7 lines in 8 placesrust76 tokens
- 8 lines in 7 placesrust69 tokens
- 12 lines in 6 placesrust82 tokens
Largest clones over all files, tests and data included
- 12 lines in 31 placesrust72 tokenscli/src/native/e2e_tests.rs:1997–2008cli/src/native/e2e_tests.rs:2276–2285cli/src/native/e2e_tests.rs:2407–2418cli/src/native/e2e_tests.rs:2751–2762cli/src/native/e2e_tests.rs:2909–2920and 26 more
1997async fn e2e_screenshot() { 1998 let mut state = DaemonState::new(); 1999 2000 let resp = execute_command( 2001 &json!({ "id": "1", "action": "launch", "headless": true }), 2002 &mut state, 2003 ) 2004 .await; 2005 assert_success(&resp); 20062276async fn e2e_select_option_label_override_names() { 2277 let mut state = DaemonState::new(); 2278 let resp = execute_command( 2279 &json!({ "id": "1", "action": "launch", "headless": true }), 2280 &mut state, 2281 ) 2282 .await; 2283 assert_success(&resp); 2284 let resp = execute_command( 2285 &json!({ "id": "2", "action": "navigate", "url": "data:text/html,<html><body></body></html>" }),First 10 of 12 lines, the second copy on the right.
- 9 lines in 18 placesrust77 tokenscli/src/native/actions.rs:7091–7099cli/src/native/actions.rs:7151–7158cli/src/native/actions.rs:7234–7242cli/src/native/actions.rs:7291–7299cli/src/native/actions.rs:7437–7445and 13 more
7091async fn handle_dblclick(cmd: &Value, state: &mut DaemonState) -> Result<Value, String> { 7092 let mgr = state.browser.as_ref().ok_or("Browser not launched")?; 7093 let session_id = mgr.active_session_id()?.to_string(); 7094 let selector = cmd 7095 .get("selector") 7096 .and_then(|v| v.as_str()) 7097 .ok_or("Missing 'selector' parameter")?; 7098 7099 let result = interaction::dblclick(7151async fn handle_type(cmd: &Value, state: &mut DaemonState) -> Result<Value, String> { 7152 let mgr = state.browser.as_ref().ok_or("Browser not launched")?; 7153 let session_id = mgr.active_session_id()?.to_string(); 7154 let selector = cmd 7155 .get("selector") 7156 .and_then(|v| v.as_str()) 7157 .ok_or("Missing 'selector' parameter")?; 7158 let text = cmd - 11 lines in 21 placesrust53 tokenscli/src/native/e2e_tests.rs:1997–2007cli/src/native/e2e_tests.rs:2150–2160cli/src/native/e2e_tests.rs:3196–3206cli/src/native/e2e_tests.rs:3289–3299cli/src/native/e2e_tests.rs:3368–3378and 16 more
1997async fn e2e_screenshot() { 1998 let mut state = DaemonState::new(); 1999 2000 let resp = execute_command( 2001 &json!({ "id": "1", "action": "launch", "headless": true }), 2002 &mut state, 2003 ) 2004 .await; 2005 assert_success(&resp); 2006First 10 of 11 lines.
- 16 lines in 6 placesrust207 tokens
- 16 lines in 10 placesrust90 tokens
By format, code only
| Format | Files | Lines | Clones | Duplicated lines | Duplication |
|---|---|---|---|---|---|
| rust | 101 | 131,027 | 844 | 9,587 | 7.32% |
| typescript | 36 | 5,359 | 13 | 224 | 4.18% |
| tsx | 26 | 5,190 | 3 | 24 | 0.46% |
| javascript | 7 | 783 | 1 | 12 | 1.53% |
| bash | 4 | 326 | 0 | 0 | 0% |
| python | 1 | 176 | 0 | 0 | 0% |
By format, all files
| Format | Files | Lines | Clones | Duplicated lines | Duplication |
|---|---|---|---|---|---|
| rust | 114 | 134,233 | 857 | 9,712 | 7.24% |
| typescript | 68 | 7,112 | 19 | 359 | 5.05% |
| tsx | 84 | 13,365 | 17 | 293 | 2.19% |
| json | 29 | 10,510 | 17 | 662 | 6.3% |
| yaml | 15 | 1,087 | 11 | 131 | 12.05% |
| javascript | 23 | 4,181 | 9 | 81 | 1.94% |
| css | 4 | 608 | 9 | 103 | 16.94% |
| markup | 13 | 729 | 1 | 7 | 0.96% |
| diff | 1 | 26 | 1 | 8 | 30.77% |
| markdown | 41 | 7,747 | 0 | 0 | 0% |
Trending appearances
| Day | Rank | Stars | Files | Lines | Clones | All files | Code | Health | Commit |
|---|---|---|---|---|---|---|---|---|---|
| Nov 6, 2026 | #8 | 46,032 (+150) | 430 | 181,945 | 941 | 6.24% | 6.89% | D 43 | 71850a0 |
Want this for your own project? Install jscpd and run jscpd ., or measure it the way the baselines were measured.