Compare commits

...
Author SHA1 Message Date
Chris Tate d44a9fb590 add sub --help flag 2026-01-12 10:41:40 -06:00
Chris Tate a4fcc1c198 fix windows bug (#26)
* fix windows bug

* test windows

* address feedback
2026-01-12 10:33:21 -06:00
Chris Tate 574037080c 0.4.3 (#20) 2026-01-12 01:24:48 -06:00
Chris Tate 278466764b fix readme + add missing wait flags (#19)
* fix inaccuracies

* fix wait

* address feedback
2026-01-12 01:22:10 -06:00
Chris Tate f2878c750d fix typo (#18)
* fix skill name

* 0.4.2
2026-01-12 00:58:07 -06:00
Chris Tate bc0b99c374 0.4.1 (#17)
* sync version

* 0.4.1

* add release script
2026-01-12 00:43:52 -06:00
12 changed files with 1225 additions and 30 deletions
+72
View File
@@ -83,3 +83,75 @@ jobs:
- name: Build release binary
run: cargo build --release --manifest-path cli/Cargo.toml --target ${{ matrix.target }}
- name: Run Rust tests
run: cargo test --manifest-path cli/Cargo.toml --target ${{ matrix.target }}
windows-integration:
name: Windows Integration Test
runs-on: windows-latest
needs: rust
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 9
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- name: Setup Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: x86_64-pc-windows-msvc
- name: Cache Cargo dependencies
uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
cli/target/
key: windows-cargo-x86_64-pc-windows-msvc-${{ hashFiles('cli/Cargo.lock') }}
restore-keys: |
windows-cargo-x86_64-pc-windows-msvc-
- name: Build Rust CLI
run: cargo build --release --manifest-path cli/Cargo.toml --target x86_64-pc-windows-msvc
- name: Install npm dependencies
run: pnpm install
- name: Build TypeScript
run: pnpm build
- name: Copy CLI binary to bin directory
run: |
Copy-Item cli/target/x86_64-pc-windows-msvc/release/agent-browser.exe bin/agent-browser-win32-x64.exe
- name: Test agent-browser install command
run: |
$env:PATH = "$pwd\bin;$env:PATH"
bin/agent-browser-win32-x64.exe install
shell: pwsh
- name: Verify Chromium was installed
run: |
$playwrightPath = "$env:LOCALAPPDATA\ms-playwright"
if (Test-Path $playwrightPath) {
Write-Host "Playwright browsers installed at: $playwrightPath"
Get-ChildItem $playwrightPath -Recurse -Depth 2 | Select-Object -First 20
} else {
Write-Error "Playwright browsers not found!"
exit 1
}
shell: pwsh
+22 -16
View File
@@ -55,13 +55,13 @@ agent-browser find role button click --name "Submit"
### Core Commands
```bash
agent-browser open <url> # Navigate to URL
agent-browser open <url> # Navigate to URL (aliases: goto, navigate)
agent-browser click <sel> # Click element
agent-browser dblclick <sel> # Double-click element
agent-browser focus <sel> # Focus element
agent-browser type <sel> <text> # Type into element
agent-browser fill <sel> <text> # Clear and fill
agent-browser press <key> # Press key (Enter, Tab, Control+a)
agent-browser press <key> # Press key (Enter, Tab, Control+a) (alias: key)
agent-browser keydown <key> # Hold key down
agent-browser keyup <key> # Release key
agent-browser hover <sel> # Hover element
@@ -69,14 +69,14 @@ agent-browser select <sel> <val> # Select dropdown option
agent-browser check <sel> # Check checkbox
agent-browser uncheck <sel> # Uncheck checkbox
agent-browser scroll <dir> [px] # Scroll (up/down/left/right)
agent-browser scrollintoview <sel> # Scroll element into view
agent-browser scrollintoview <sel> # Scroll element into view (alias: scrollinto)
agent-browser drag <src> <tgt> # Drag and drop
agent-browser upload <sel> <files> # Upload files
agent-browser screenshot [path] # Take screenshot (--full for full page)
agent-browser pdf <path> # Save as PDF
agent-browser snapshot # Accessibility tree with refs (best for AI)
agent-browser eval <js> # Run JavaScript
agent-browser close # Close browser
agent-browser close # Close browser (aliases: quit, exit)
```
### Get Info
@@ -129,9 +129,9 @@ agent-browser find nth 2 "a" text
### Wait
```bash
agent-browser wait <selector> # Wait for element
agent-browser wait <ms> # Wait for time
agent-browser wait --text "Welcome" # Wait for text
agent-browser wait <selector> # Wait for element to be visible
agent-browser wait <ms> # Wait for time (milliseconds)
agent-browser wait --text "Welcome" # Wait for text to appear
agent-browser wait --url "**/dash" # Wait for URL pattern
agent-browser wait --load networkidle # Wait for load state
agent-browser wait --fn "window.ready === true" # Wait for JS condition
@@ -253,6 +253,10 @@ AGENT_BROWSER_SESSION=agent1 agent-browser click "#btn"
# List active sessions
agent-browser session list
# Output:
# Active sessions:
# -> default
# agent1
# Show current session
agent-browser session
@@ -393,15 +397,17 @@ agent-browser uses a client-daemon architecture:
The daemon starts automatically on first command and persists between commands for fast subsequent operations.
**Browser Engine:** Uses Chromium by default. The daemon also supports Firefox and WebKit via the Playwright protocol.
## Platforms
| Platform | Binary | Fallback |
|----------|--------|----------|
| macOS ARM64 | Native Rust | Node.js |
| macOS x64 | Native Rust | Node.js |
| Linux ARM64 | Native Rust | Node.js |
| Linux x64 | Native Rust | Node.js |
| Windows | - | Node.js |
| macOS ARM64 | Native Rust | Node.js |
| macOS x64 | Native Rust | Node.js |
| Linux ARM64 | Native Rust | Node.js |
| Linux x64 | Native Rust | Node.js |
| Windows x64 | Native Rust | Node.js |
## Usage with AI Agents
@@ -436,15 +442,15 @@ Core workflow:
For Claude Code, a [skill](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices) provides richer context:
```bash
cp -r node_modules/agent-browser/skills/browsing-web .claude/skills/
cp -r node_modules/agent-browser/skills/agent-browser .claude/skills/
```
Or download:
```bash
mkdir -p .claude/skills/browsing-web
curl -o .claude/skills/browsing-web/SKILL.md \
https://raw.githubusercontent.com/vercel-labs/agent-browser/main/skills/browsing-web/SKILL.md
mkdir -p .claude/skills/agent-browser
curl -o .claude/skills/agent-browser/SKILL.md \
https://raw.githubusercontent.com/vercel-labs/agent-browser/main/skills/agent-browser/SKILL.md
```
## License
+1 -1
View File
@@ -4,7 +4,7 @@ version = 4
[[package]]
name = "agent-browser"
version = "0.4.0"
version = "0.4.3"
dependencies = [
"libc",
"serde",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "agent-browser"
version = "0.4.0"
version = "0.4.3"
edition = "2021"
description = "Fast browser automation CLI for AI agents"
license = "Apache-2.0"
+90 -1
View File
@@ -212,6 +212,44 @@ pub fn parse_command(args: &[String], flags: &Flags) -> Result<Value, ParseError
// === Wait ===
"wait" => {
// Check for --url flag: wait --url "**/dashboard"
if let Some(idx) = rest.iter().position(|&s| s == "--url" || s == "-u") {
let url = rest.get(idx + 1).ok_or_else(|| ParseError::MissingArguments {
context: "wait --url".to_string(),
usage: "wait --url <pattern>",
})?;
return Ok(json!({ "id": id, "action": "waitforurl", "url": url }));
}
// Check for --load flag: wait --load networkidle
if let Some(idx) = rest.iter().position(|&s| s == "--load" || s == "-l") {
let state = rest.get(idx + 1).ok_or_else(|| ParseError::MissingArguments {
context: "wait --load".to_string(),
usage: "wait --load <state>",
})?;
return Ok(json!({ "id": id, "action": "waitforloadstate", "state": state }));
}
// Check for --fn flag: wait --fn "window.ready === true"
if let Some(idx) = rest.iter().position(|&s| s == "--fn" || s == "-f") {
let expr = rest.get(idx + 1).ok_or_else(|| ParseError::MissingArguments {
context: "wait --fn".to_string(),
usage: "wait --fn <expression>",
})?;
return Ok(json!({ "id": id, "action": "waitforfunction", "expression": expr }));
}
// Check for --text flag: wait --text "Welcome"
if let Some(idx) = rest.iter().position(|&s| s == "--text" || s == "-t") {
let text = rest.get(idx + 1).ok_or_else(|| ParseError::MissingArguments {
context: "wait --text".to_string(),
usage: "wait --text <text>",
})?;
// Use getByText locator to wait for text to appear
return Ok(json!({ "id": id, "action": "wait", "selector": format!("text={}", text) }));
}
// Default: selector or timeout
if let Some(arg) = rest.get(0) {
if arg.parse::<u64>().is_ok() {
Ok(json!({ "id": id, "action": "wait", "timeout": arg.parse::<u64>().unwrap() }))
@@ -221,7 +259,7 @@ pub fn parse_command(args: &[String], flags: &Flags) -> Result<Value, ParseError
} else {
Err(ParseError::MissingArguments {
context: "wait".to_string(),
usage: "wait <selector|ms>",
usage: "wait <selector|ms|--url|--load|--fn|--text>",
})
}
}
@@ -1090,6 +1128,57 @@ mod tests {
assert_eq!(cmd["maxDepth"], 3);
}
// === Wait ===
#[test]
fn test_wait_selector() {
let cmd = parse_command(&args("wait #element"), &default_flags()).unwrap();
assert_eq!(cmd["action"], "wait");
assert_eq!(cmd["selector"], "#element");
}
#[test]
fn test_wait_timeout() {
let cmd = parse_command(&args("wait 5000"), &default_flags()).unwrap();
assert_eq!(cmd["action"], "wait");
assert_eq!(cmd["timeout"], 5000);
}
#[test]
fn test_wait_url() {
let cmd = parse_command(&args("wait --url **/dashboard"), &default_flags()).unwrap();
assert_eq!(cmd["action"], "waitforurl");
assert_eq!(cmd["url"], "**/dashboard");
}
#[test]
fn test_wait_load() {
let cmd = parse_command(&args("wait --load networkidle"), &default_flags()).unwrap();
assert_eq!(cmd["action"], "waitforloadstate");
assert_eq!(cmd["state"], "networkidle");
}
#[test]
fn test_wait_load_missing_state() {
let result = parse_command(&args("wait --load"), &default_flags());
assert!(result.is_err());
assert!(matches!(result.unwrap_err(), ParseError::MissingArguments { .. }));
}
#[test]
fn test_wait_fn() {
let cmd = parse_command(&args("wait --fn window.ready"), &default_flags()).unwrap();
assert_eq!(cmd["action"], "waitforfunction");
assert_eq!(cmd["expression"], "window.ready");
}
#[test]
fn test_wait_text() {
let cmd = parse_command(&args("wait --text Welcome"), &default_flags()).unwrap();
assert_eq!(cmd["action"], "wait");
assert_eq!(cmd["selector"], "text=Welcome");
}
// === Unknown command ===
#[test]
+7 -2
View File
@@ -206,8 +206,13 @@ pub fn ensure_daemon(session: &str, headed: bool) -> Result<(), String> {
{
use std::os::windows::process::CommandExt;
let mut cmd = Command::new("node");
cmd.arg(daemon_path)
// On Windows, use cmd.exe to run node to ensure proper PATH resolution.
// This handles cases where node.exe isn't directly in PATH but node.cmd is.
// Pass the entire command as a single string to /c to handle paths with spaces.
let cmd_string = format!("node \"{}\"", daemon_path.display());
let mut cmd = Command::new("cmd");
cmd.arg("/c")
.arg(&cmd_string)
.env("AGENT_BROWSER_DAEMON", "1")
.env("AGENT_BROWSER_SESSION", session);
+10
View File
@@ -128,6 +128,16 @@ pub fn run_install(with_deps: bool) {
}
println!("\x1b[36mInstalling Chromium browser...\x1b[0m");
// On Windows, we need to use cmd.exe to run npx because npx is actually npx.cmd
// and Command::new() doesn't resolve .cmd files the way the shell does.
// Pass the entire command as a single string to /c to handle paths with spaces.
#[cfg(windows)]
let status = Command::new("cmd")
.args(["/c", "npx playwright install chromium"])
.status();
#[cfg(not(windows))]
let status = Command::new("npx")
.args(["playwright", "install", "chromium"])
.status();
+14 -2
View File
@@ -21,7 +21,7 @@ use commands::{gen_id, parse_command, ParseError};
use connection::{ensure_daemon, send_command};
use flags::{clean_args, parse_flags};
use install::run_install;
use output::{print_help, print_response};
use output::{print_command_help, print_help, print_response};
fn run_session(args: &[String], session: &str, json_mode: bool) {
let subcommand = args.get(1).map(|s| s.as_str());
@@ -98,7 +98,19 @@ fn main() {
let flags = parse_flags(&args);
let clean = clean_args(&args);
if clean.is_empty() || args.iter().any(|a| a == "--help" || a == "-h") {
let has_help = args.iter().any(|a| a == "--help" || a == "-h");
if clean.is_empty() {
print_help();
return;
}
if has_help {
if let Some(cmd) = clean.get(0) {
if print_command_help(cmd) {
return;
}
}
print_help();
return;
}
+955
View File
@@ -145,6 +145,961 @@ pub fn print_response(resp: &Response, json_mode: bool) {
}
}
/// Print command-specific help. Returns true if help was printed, false if command unknown.
pub fn print_command_help(command: &str) -> bool {
let help = match command {
// === Navigation ===
"open" | "goto" | "navigate" => r##"
agent-browser open - Navigate to a URL
Usage: agent-browser open <url>
Navigates the browser to the specified URL. If no protocol is provided,
https:// is automatically prepended.
Aliases: goto, navigate
Global Options:
--json Output as JSON
--session <name> Use specific session
--headed Show browser window
Examples:
agent-browser open example.com
agent-browser open https://github.com
agent-browser open localhost:3000
"##,
"back" => r##"
agent-browser back - Navigate back in history
Usage: agent-browser back
Goes back one page in the browser history, equivalent to clicking
the browser's back button.
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser back
"##,
"forward" => r##"
agent-browser forward - Navigate forward in history
Usage: agent-browser forward
Goes forward one page in the browser history, equivalent to clicking
the browser's forward button.
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser forward
"##,
"reload" => r##"
agent-browser reload - Reload the current page
Usage: agent-browser reload
Reloads the current page, equivalent to pressing F5 or clicking
the browser's reload button.
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser reload
"##,
// === Core Actions ===
"click" => r##"
agent-browser click - Click an element
Usage: agent-browser click <selector>
Clicks on the specified element. The selector can be a CSS selector,
XPath, or an element reference from snapshot (e.g., @e1).
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser click "#submit-button"
agent-browser click @e1
agent-browser click "button.primary"
agent-browser click "//button[@type='submit']"
"##,
"dblclick" => r##"
agent-browser dblclick - Double-click an element
Usage: agent-browser dblclick <selector>
Double-clicks on the specified element. Useful for text selection
or triggering double-click handlers.
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser dblclick "#editable-text"
agent-browser dblclick @e5
"##,
"fill" => r##"
agent-browser fill - Clear and fill an input field
Usage: agent-browser fill <selector> <text>
Clears the input field and fills it with the specified text.
This replaces any existing content in the field.
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser fill "#email" "user@example.com"
agent-browser fill @e3 "Hello World"
agent-browser fill "input[name='search']" "query"
"##,
"type" => r##"
agent-browser type - Type text into an element
Usage: agent-browser type <selector> <text>
Types text into the specified element character by character.
Unlike fill, this does not clear existing content first.
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser type "#search" "hello"
agent-browser type @e2 "additional text"
"##,
"hover" => r##"
agent-browser hover - Hover over an element
Usage: agent-browser hover <selector>
Moves the mouse to hover over the specified element. Useful for
triggering hover states or dropdown menus.
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser hover "#dropdown-trigger"
agent-browser hover @e4
"##,
"focus" => r##"
agent-browser focus - Focus an element
Usage: agent-browser focus <selector>
Sets keyboard focus to the specified element.
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser focus "#input-field"
agent-browser focus @e2
"##,
"check" => r##"
agent-browser check - Check a checkbox
Usage: agent-browser check <selector>
Checks a checkbox element. If already checked, no action is taken.
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser check "#terms-checkbox"
agent-browser check @e7
"##,
"uncheck" => r##"
agent-browser uncheck - Uncheck a checkbox
Usage: agent-browser uncheck <selector>
Unchecks a checkbox element. If already unchecked, no action is taken.
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser uncheck "#newsletter-opt-in"
agent-browser uncheck @e8
"##,
"select" => r##"
agent-browser select - Select a dropdown option
Usage: agent-browser select <selector> <value>
Selects an option in a <select> dropdown by its value attribute.
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser select "#country" "US"
agent-browser select @e5 "option2"
"##,
"drag" => r##"
agent-browser drag - Drag and drop
Usage: agent-browser drag <source> <target>
Drags an element from source to target location.
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser drag "#draggable" "#drop-zone"
agent-browser drag @e1 @e2
"##,
"upload" => r##"
agent-browser upload - Upload files
Usage: agent-browser upload <selector> <files...>
Uploads one or more files to a file input element.
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser upload "#file-input" ./document.pdf
agent-browser upload @e3 ./image1.png ./image2.png
"##,
// === Keyboard ===
"press" | "key" => r##"
agent-browser press - Press a key or key combination
Usage: agent-browser press <key>
Presses a key or key combination. Supports special keys and modifiers.
Aliases: key
Special Keys:
Enter, Tab, Escape, Backspace, Delete, Space
ArrowUp, ArrowDown, ArrowLeft, ArrowRight
Home, End, PageUp, PageDown
F1-F12
Modifiers (combine with +):
Control, Alt, Shift, Meta
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser press Enter
agent-browser press Tab
agent-browser press Control+a
agent-browser press Control+Shift+s
agent-browser press Escape
"##,
"keydown" => r##"
agent-browser keydown - Press a key down (without release)
Usage: agent-browser keydown <key>
Presses a key down without releasing it. Use keyup to release.
Useful for holding modifier keys.
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser keydown Shift
agent-browser keydown Control
"##,
"keyup" => r##"
agent-browser keyup - Release a key
Usage: agent-browser keyup <key>
Releases a key that was pressed with keydown.
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser keyup Shift
agent-browser keyup Control
"##,
// === Scroll ===
"scroll" => r##"
agent-browser scroll - Scroll the page
Usage: agent-browser scroll [direction] [amount]
Scrolls the page in the specified direction.
Arguments:
direction up, down, left, right (default: down)
amount Pixels to scroll (default: 300)
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser scroll
agent-browser scroll down 500
agent-browser scroll up 200
agent-browser scroll left 100
"##,
"scrollintoview" | "scrollinto" => r##"
agent-browser scrollintoview - Scroll element into view
Usage: agent-browser scrollintoview <selector>
Scrolls the page until the specified element is visible in the viewport.
Aliases: scrollinto
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser scrollintoview "#footer"
agent-browser scrollintoview @e15
"##,
// === Wait ===
"wait" => r##"
agent-browser wait - Wait for condition
Usage: agent-browser wait <selector|ms|option>
Waits for an element to appear, a timeout, or other conditions.
Modes:
<selector> Wait for element to appear
<ms> Wait for specified milliseconds
--url <pattern> Wait for URL to match pattern
--load <state> Wait for load state (load, domcontentloaded, networkidle)
--fn <expression> Wait for JavaScript expression to be truthy
--text <text> Wait for text to appear on page
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser wait "#loading-spinner"
agent-browser wait 2000
agent-browser wait --url "**/dashboard"
agent-browser wait --load networkidle
agent-browser wait --fn "window.appReady === true"
agent-browser wait --text "Welcome back"
"##,
// === Screenshot/PDF ===
"screenshot" => r##"
agent-browser screenshot - Take a screenshot
Usage: agent-browser screenshot [path]
Captures a screenshot of the current page. If no path is provided,
outputs base64-encoded image data.
Options:
--full, -f Capture full page (not just viewport)
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser screenshot
agent-browser screenshot ./screenshot.png
agent-browser screenshot --full ./full-page.png
"##,
"pdf" => r##"
agent-browser pdf - Save page as PDF
Usage: agent-browser pdf <path>
Saves the current page as a PDF file.
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser pdf ./page.pdf
agent-browser pdf ~/Documents/report.pdf
"##,
// === Snapshot ===
"snapshot" => r##"
agent-browser snapshot - Get accessibility tree snapshot
Usage: agent-browser snapshot [options]
Returns an accessibility tree representation of the page with element
references (like @e1, @e2) that can be used in subsequent commands.
Designed for AI agents to understand page structure.
Options:
-i, --interactive Only include interactive elements
-c, --compact Remove empty structural elements
-d, --depth <n> Limit tree depth
-s, --selector <sel> Scope snapshot to CSS selector
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser snapshot
agent-browser snapshot -i
agent-browser snapshot --compact --depth 5
agent-browser snapshot -s "#main-content"
"##,
// === Eval ===
"eval" => r##"
agent-browser eval - Execute JavaScript
Usage: agent-browser eval <script>
Executes JavaScript code in the browser context and returns the result.
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser eval "document.title"
agent-browser eval "window.location.href"
agent-browser eval "document.querySelectorAll('a').length"
"##,
// === Close ===
"close" | "quit" | "exit" => r##"
agent-browser close - Close the browser
Usage: agent-browser close
Closes the browser instance for the current session.
Aliases: quit, exit
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser close
agent-browser close --session mysession
"##,
// === Get ===
"get" => r##"
agent-browser get - Retrieve information from elements or page
Usage: agent-browser get <subcommand> [args]
Retrieves various types of information from elements or the page.
Subcommands:
text <selector> Get text content of element
html <selector> Get inner HTML of element
value <selector> Get value of input element
attr <selector> <name> Get attribute value
title Get page title
url Get current URL
count <selector> Count matching elements
box <selector> Get bounding box (x, y, width, height)
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser get text @e1
agent-browser get html "#content"
agent-browser get value "#email-input"
agent-browser get attr "#link" href
agent-browser get title
agent-browser get url
agent-browser get count "li.item"
agent-browser get box "#header"
"##,
// === Is ===
"is" => r##"
agent-browser is - Check element state
Usage: agent-browser is <subcommand> <selector>
Checks the state of an element and returns true/false.
Subcommands:
visible <selector> Check if element is visible
enabled <selector> Check if element is enabled (not disabled)
checked <selector> Check if checkbox/radio is checked
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser is visible "#modal"
agent-browser is enabled "#submit-btn"
agent-browser is checked "#agree-checkbox"
"##,
// === Find ===
"find" => r##"
agent-browser find - Find and interact with elements by locator
Usage: agent-browser find <locator> <value> [action] [text]
Finds elements using semantic locators and optionally performs an action.
Locators:
role <role> Find by ARIA role (--name <n>, --exact)
text <text> Find by text content (--exact)
label <label> Find by associated label (--exact)
placeholder <text> Find by placeholder text (--exact)
alt <text> Find by alt text (--exact)
title <text> Find by title attribute (--exact)
testid <id> Find by data-testid attribute
first <selector> First matching element
last <selector> Last matching element
nth <index> <selector> Nth matching element (0-based)
Actions (default: click):
click, fill, type, hover, focus, check, uncheck
Options:
--name <name> Filter role by accessible name
--exact Require exact text match
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser find role button click --name Submit
agent-browser find text "Sign In" click
agent-browser find label "Email" fill "user@example.com"
agent-browser find placeholder "Search..." type "query"
agent-browser find testid "login-form" click
agent-browser find first "li.item" click
agent-browser find nth 2 ".card" hover
"##,
// === Mouse ===
"mouse" => r##"
agent-browser mouse - Low-level mouse operations
Usage: agent-browser mouse <subcommand> [args]
Performs low-level mouse operations for precise control.
Subcommands:
move <x> <y> Move mouse to coordinates
down [button] Press mouse button (left, right, middle)
up [button] Release mouse button
wheel <dy> [dx] Scroll mouse wheel
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser mouse move 100 200
agent-browser mouse down
agent-browser mouse up
agent-browser mouse down right
agent-browser mouse wheel 100
agent-browser mouse wheel -50 0
"##,
// === Set ===
"set" => r##"
agent-browser set - Configure browser settings
Usage: agent-browser set <setting> [args]
Configures various browser settings and emulation options.
Settings:
viewport <w> <h> Set viewport size
device <name> Emulate device (e.g., "iPhone 12")
geo <lat> <lng> Set geolocation
offline [on|off] Toggle offline mode
headers <json> Set extra HTTP headers
credentials <user> <pass> Set HTTP authentication
media [dark|light] Set color scheme preference
[reduced-motion] Enable reduced motion
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser set viewport 1920 1080
agent-browser set device "iPhone 12"
agent-browser set geo 37.7749 -122.4194
agent-browser set offline on
agent-browser set headers '{"X-Custom": "value"}'
agent-browser set credentials admin secret123
agent-browser set media dark
agent-browser set media light reduced-motion
"##,
// === Network ===
"network" => r##"
agent-browser network - Network interception and monitoring
Usage: agent-browser network <subcommand> [args]
Intercept, mock, or monitor network requests.
Subcommands:
route <url> [options] Intercept requests matching URL pattern
--abort Abort matching requests
--body <json> Respond with custom body
unroute [url] Remove route (all if no URL)
requests [options] List captured requests
--clear Clear request log
--filter <pattern> Filter by URL pattern
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser network route "**/api/*" --abort
agent-browser network route "**/data.json" --body '{"mock": true}'
agent-browser network unroute
agent-browser network requests
agent-browser network requests --filter "api"
agent-browser network requests --clear
"##,
// === Storage ===
"storage" => r##"
agent-browser storage - Manage web storage
Usage: agent-browser storage <type> [operation] [key] [value]
Manage localStorage and sessionStorage.
Types:
local localStorage
session sessionStorage
Operations:
get [key] Get all storage or specific key
set <key> <value> Set a key-value pair
clear Clear all storage
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser storage local
agent-browser storage local get authToken
agent-browser storage local set theme "dark"
agent-browser storage local clear
agent-browser storage session get userId
"##,
// === Cookies ===
"cookies" => r##"
agent-browser cookies - Manage browser cookies
Usage: agent-browser cookies [operation] [args]
Manage browser cookies for the current context.
Operations:
get Get all cookies (default)
set <name> <value> Set a cookie
clear Clear all cookies
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser cookies
agent-browser cookies get
agent-browser cookies set session_id "abc123"
agent-browser cookies clear
"##,
// === Tabs ===
"tab" => r##"
agent-browser tab - Manage browser tabs
Usage: agent-browser tab [operation] [args]
Manage browser tabs in the current window.
Operations:
list List all tabs (default)
new [url] Open new tab
close [index] Close tab (current if no index)
<index> Switch to tab by index
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser tab
agent-browser tab list
agent-browser tab new
agent-browser tab new https://example.com
agent-browser tab 2
agent-browser tab close
agent-browser tab close 1
"##,
// === Window ===
"window" => r##"
agent-browser window - Manage browser windows
Usage: agent-browser window <operation>
Manage browser windows.
Operations:
new Open new browser window
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser window new
"##,
// === Frame ===
"frame" => r##"
agent-browser frame - Switch frame context
Usage: agent-browser frame <selector|main>
Switch to an iframe or back to the main frame.
Arguments:
<selector> CSS selector for iframe
main Switch back to main frame
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser frame "#embed-iframe"
agent-browser frame "iframe[name='content']"
agent-browser frame main
"##,
// === Dialog ===
"dialog" => r##"
agent-browser dialog - Handle browser dialogs
Usage: agent-browser dialog <response> [text]
Respond to browser dialogs (alert, confirm, prompt).
Operations:
accept [text] Accept dialog, optionally with prompt text
dismiss Dismiss/cancel dialog
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser dialog accept
agent-browser dialog accept "my input"
agent-browser dialog dismiss
"##,
// === Trace ===
"trace" => r##"
agent-browser trace - Record execution trace
Usage: agent-browser trace <operation> [path]
Record a trace for debugging with Playwright Trace Viewer.
Operations:
start [path] Start recording trace
stop [path] Stop recording and save trace
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser trace start
agent-browser trace start ./my-trace
agent-browser trace stop
agent-browser trace stop ./debug-trace.zip
"##,
// === Console/Errors ===
"console" => r##"
agent-browser console - View console logs
Usage: agent-browser console [--clear]
View browser console output (log, warn, error, info).
Options:
--clear Clear console log buffer
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser console
agent-browser console --clear
"##,
"errors" => r##"
agent-browser errors - View page errors
Usage: agent-browser errors [--clear]
View JavaScript errors and uncaught exceptions.
Options:
--clear Clear error buffer
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser errors
agent-browser errors --clear
"##,
// === Highlight ===
"highlight" => r##"
agent-browser highlight - Highlight an element
Usage: agent-browser highlight <selector>
Visually highlights an element on the page for debugging.
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser highlight "#target-element"
agent-browser highlight @e5
"##,
// === State ===
"state" => r##"
agent-browser state - Save/load browser state
Usage: agent-browser state <operation> <path>
Save or restore browser state (cookies, localStorage, sessionStorage).
Operations:
save <path> Save current state to file
load <path> Load state from file
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser state save ./auth-state.json
agent-browser state load ./auth-state.json
"##,
// === Session ===
"session" => r##"
agent-browser session - Manage sessions
Usage: agent-browser session [operation]
Manage isolated browser sessions. Each session has its own browser
instance with separate cookies, storage, and state.
Operations:
(none) Show current session name
list List all active sessions
Environment:
AGENT_BROWSER_SESSION Default session name
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser session
agent-browser session list
agent-browser --session test open example.com
"##,
// === Install ===
"install" => r##"
agent-browser install - Install browser binaries
Usage: agent-browser install [--with-deps]
Downloads and installs browser binaries required for automation.
Options:
-d, --with-deps Also install system dependencies (Linux only)
Examples:
agent-browser install
agent-browser install --with-deps
"##,
_ => return false,
};
println!("{}", help.trim());
true
}
pub fn print_help() {
println!(
r#"
+9 -6
View File
@@ -1,6 +1,6 @@
{
"name": "agent-browser",
"version": "0.4.0",
"version": "0.4.3",
"description": "Headless browser automation CLI for AI agents",
"type": "module",
"main": "dist/daemon.js",
@@ -15,13 +15,16 @@
},
"scripts": {
"prepare": "husky",
"version:sync": "node scripts/sync-version.js",
"version": "npm run version:sync && git add cli/Cargo.toml",
"build": "tsc",
"build:native": "cargo build --release --manifest-path cli/Cargo.toml && node scripts/copy-native.js",
"build:linux": "docker compose -f docker/docker-compose.yml run --rm build-linux",
"build:macos": "(cargo build --release --manifest-path cli/Cargo.toml --target aarch64-apple-darwin & cargo build --release --manifest-path cli/Cargo.toml --target x86_64-apple-darwin & wait) && cp cli/target/aarch64-apple-darwin/release/agent-browser bin/agent-browser-darwin-arm64 && cp cli/target/x86_64-apple-darwin/release/agent-browser bin/agent-browser-darwin-x64",
"build:windows": "docker compose -f docker/docker-compose.yml run --rm build-windows",
"build:all-platforms": "(npm run build:linux & npm run build:windows & wait) && npm run build:macos",
"build:native": "npm run version:sync && cargo build --release --manifest-path cli/Cargo.toml && node scripts/copy-native.js",
"build:linux": "npm run version:sync && docker compose -f docker/docker-compose.yml run --rm build-linux",
"build:macos": "npm run version:sync && (cargo build --release --manifest-path cli/Cargo.toml --target aarch64-apple-darwin & cargo build --release --manifest-path cli/Cargo.toml --target x86_64-apple-darwin & wait) && cp cli/target/aarch64-apple-darwin/release/agent-browser bin/agent-browser-darwin-arm64 && cp cli/target/x86_64-apple-darwin/release/agent-browser bin/agent-browser-darwin-x64",
"build:windows": "npm run version:sync && docker compose -f docker/docker-compose.yml run --rm build-windows",
"build:all-platforms": "npm run version:sync && (npm run build:linux & npm run build:windows & wait) && npm run build:macos",
"build:docker": "docker build -t agent-browser-builder -f docker/Dockerfile.build .",
"release": "npm run version:sync && npm run build && npm run build:all-platforms && npm publish",
"start": "node dist/daemon.js",
"dev": "tsx src/daemon.ts",
"typecheck": "tsc --noEmit",
+43
View File
@@ -0,0 +1,43 @@
#!/usr/bin/env node
/**
* Syncs the version from package.json to all other config files.
* Run this script before building or releasing.
*/
import { readFileSync, writeFileSync } from "fs";
import { dirname, join } from "path";
import { fileURLToPath } from "url";
const __dirname = dirname(fileURLToPath(import.meta.url));
const rootDir = join(__dirname, "..");
// Read version from package.json (single source of truth)
const packageJson = JSON.parse(
readFileSync(join(rootDir, "package.json"), "utf-8")
);
const version = packageJson.version;
console.log(`Syncing version ${version} to all config files...`);
// Update Cargo.toml
const cargoTomlPath = join(rootDir, "cli/Cargo.toml");
let cargoToml = readFileSync(cargoTomlPath, "utf-8");
const cargoVersionRegex = /^version\s*=\s*"[^"]*"/m;
const newCargoVersion = `version = "${version}"`;
if (cargoVersionRegex.test(cargoToml)) {
const oldMatch = cargoToml.match(cargoVersionRegex)?.[0];
if (oldMatch !== newCargoVersion) {
cargoToml = cargoToml.replace(cargoVersionRegex, newCargoVersion);
writeFileSync(cargoTomlPath, cargoToml);
console.log(` Updated cli/Cargo.toml: ${oldMatch} -> ${newCargoVersion}`);
} else {
console.log(` cli/Cargo.toml already up to date`);
}
} else {
console.error(" Could not find version field in cli/Cargo.toml");
process.exit(1);
}
console.log("Version sync complete.");
@@ -1,5 +1,5 @@
---
name: browsing-web
name: agent-browser
description: Automates browser interactions for web testing, form filling, screenshots, and data extraction. Use when the user needs to navigate websites, interact with web pages, fill forms, take screenshots, test web applications, or extract information from web pages.
---