full native (#754)

* full native

* fix: apply cargo fmt formatting

* fix: prevent zip path traversal in Chromium installer

Use enclosed_name() to sanitize zip entry paths, preventing malicious
archives from writing outside the extraction directory.

* improvements

* fix: apply cargo fmt formatting

* benchmarks

* bench

* updates

* fixes
This commit is contained in:
Chris Tate
2026-03-13 19:59:21 -05:00
committed by GitHub
parent d4b948c1d4
commit 8e43469c8b
88 changed files with 2511 additions and 22629 deletions
+1 -1
View File
@@ -62,7 +62,7 @@ This is useful when:
## Color scheme
Playwright overrides the browser's color scheme to `light` by default when connecting via CDP. Use `--color-scheme` to set a persistent preference:
Use `--color-scheme` to set a persistent preference when connecting via CDP:
```bash
agent-browser --cdp 9222 --color-scheme dark open https://example.com
+2 -2
View File
@@ -50,7 +50,7 @@ agent-browser screenshot --screenshot-format jpeg --screenshot-quality 80
### New Features
- **`inspect` command** -- Opens Chrome DevTools for the active page by launching a local proxy server that forwards the DevTools frontend to the browser's CDP WebSocket. Agent commands continue to work while DevTools is open. Implemented in both Node.js and native daemon paths.
- **`inspect` command** -- Opens Chrome DevTools for the active page by launching a local proxy server that forwards the DevTools frontend to the browser's CDP WebSocket. Agent commands continue to work while DevTools is open.
```bash
agent-browser open example.com
@@ -64,7 +64,7 @@ agent-browser click "Submit" # commands still work while DevTools is open
agent-browser get cdp-url
```
- **Native screenshot annotate** -- The `--annotate` flag for screenshots now works in the native Rust daemon, bringing full parity with the Node.js path.
- **Screenshot annotate** -- The `--annotate` flag overlays numbered labels on interactive elements in screenshots.
### Improvements
+4 -5
View File
@@ -81,7 +81,6 @@ Every CLI flag can be set in the config file using its camelCase equivalent:
<tr><td><code>confirmActions</code></td><td><code>--confirm-actions</code></td><td>string</td></tr>
<tr><td><code>confirmInteractive</code></td><td><code>--confirm-interactive</code></td><td>boolean</td></tr>
<tr><td><code>engine</code></td><td><code>--engine</code></td><td>string (<code>chrome</code>, <code>lightpanda</code>)</td></tr>
<tr><td><code>native</code></td><td><code>--native</code></td><td>boolean (experimental)</td></tr>
<tr><td><code>headers</code></td><td><code>--headers</code></td><td>string (JSON)</td></tr>
</tbody>
</table>
@@ -151,7 +150,7 @@ agent-browser --headed open example.com # same as --headed true
agent-browser --headed true open example.com # explicit
```
This applies to all boolean flags: `--headed`, `--debug`, `--json`, `--ignore-https-errors`, `--allow-file-access`, `--auto-connect`, `--content-boundaries`, `--confirm-interactive`, `--native`.
This applies to all boolean flags: `--headed`, `--debug`, `--json`, `--ignore-https-errors`, `--allow-file-access`, `--auto-connect`, `--content-boundaries`, `--confirm-interactive`.
## Extensions Merging
@@ -172,13 +171,14 @@ These environment variables configure additional daemon and runtime behavior:
<tr><td><code>AGENT_BROWSER_ALLOW_FILE_ACCESS</code></td><td>Allow <code>file://</code> URLs to access local files.</td><td>(disabled)</td></tr>
<tr><td><code>AGENT_BROWSER_COLOR_SCHEME</code></td><td>Color scheme preference (<code>dark</code>, <code>light</code>, <code>no-preference</code>).</td><td>(none)</td></tr>
<tr><td><code>AGENT_BROWSER_DOWNLOAD_PATH</code></td><td>Default directory for browser downloads.</td><td>(temp directory)</td></tr>
<tr><td><code>AGENT_BROWSER_DEFAULT_TIMEOUT</code></td><td>Default Playwright timeout in ms. Keep below 30000 to avoid IPC timeouts.</td><td><code>25000</code></td></tr>
<tr><td><code>AGENT_BROWSER_DEFAULT_TIMEOUT</code></td><td>Default timeout in ms. Keep below 30000 to avoid IPC timeouts.</td><td><code>25000</code></td></tr>
<tr><td><code>AGENT_BROWSER_SESSION_NAME</code></td><td>Auto-save/load state persistence name.</td><td>(none)</td></tr>
<tr><td><code>AGENT_BROWSER_STATE_EXPIRE_DAYS</code></td><td>Auto-delete saved session states older than N days.</td><td><code>30</code></td></tr>
<tr><td><code>AGENT_BROWSER_ENCRYPTION_KEY</code></td><td>64-char hex key for AES-256-GCM session encryption.</td><td>(none)</td></tr>
<tr><td><code>AGENT_BROWSER_EXTENSIONS</code></td><td>Comma-separated browser extension paths. Extensions work in both headed and headless mode.</td><td>(none)</td></tr>
<tr><td><code>AGENT_BROWSER_HEADED</code></td><td>Show browser window instead of running headless (<code>1</code> to enable).</td><td>(disabled)</td></tr>
<tr><td><code>AGENT_BROWSER_STREAM_PORT</code></td><td>Enable WebSocket streaming on the specified port (e.g., <code>9223</code>).</td><td>(disabled)</td></tr>
<tr><td><code>AGENT_BROWSER_IDLE_TIMEOUT_MS</code></td><td>Auto-shutdown the daemon after N ms of inactivity (no commands received). Useful for ephemeral environments.</td><td>(disabled)</td></tr>
<tr><td><code>AGENT_BROWSER_IOS_DEVICE</code></td><td>Default iOS device name for the <code>ios</code> provider.</td><td>(none)</td></tr>
<tr><td><code>AGENT_BROWSER_IOS_UDID</code></td><td>Default iOS device UDID for the <code>ios</code> provider.</td><td>(none)</td></tr>
<tr><td><code>AGENT_BROWSER_DEBUG</code></td><td>Enable debug output (<code>1</code> to enable).</td><td>(disabled)</td></tr>
@@ -188,8 +188,7 @@ These environment variables configure additional daemon and runtime behavior:
<tr><td><code>AGENT_BROWSER_ACTION_POLICY</code></td><td>Path to action policy JSON file.</td><td>(none)</td></tr>
<tr><td><code>AGENT_BROWSER_CONFIRM_ACTIONS</code></td><td>Comma-separated action categories requiring confirmation.</td><td>(none)</td></tr>
<tr><td><code>AGENT_BROWSER_CONFIRM_INTERACTIVE</code></td><td>Enable interactive confirmation prompts (auto-denies if stdin is not a TTY).</td><td>(disabled)</td></tr>
<tr><td><code>AGENT_BROWSER_ENGINE</code></td><td>Browser engine to use: <code>chrome</code> (default), <code>lightpanda</code>. Implies <code>--native</code>.</td><td><code>chrome</code></td></tr>
<tr><td><code>AGENT_BROWSER_NATIVE</code></td><td>Use the experimental native Rust daemon instead of Node.js/Playwright.</td><td>(disabled)</td></tr>
<tr><td><code>AGENT_BROWSER_ENGINE</code></td><td>Browser engine to use: <code>chrome</code> (default), <code>lightpanda</code>.</td><td><code>chrome</code></td></tr>
</tbody>
</table>
+3 -3
View File
@@ -21,7 +21,7 @@ When no `--executable-path` is provided, agent-browser searches for Chrome in th
<code>/Applications/Google Chrome.app</code>,
<code>/Applications/Google Chrome Canary.app</code>,
<code>/Applications/Chromium.app</code>,
Playwright Chromium cache
Chrome for Testing cache
</td>
</tr>
<tr>
@@ -31,7 +31,7 @@ When no `--executable-path` is provided, agent-browser searches for Chrome in th
<code>google-chrome-stable</code>,
<code>chromium-browser</code>,
<code>chromium</code> in PATH,
Playwright Chromium cache
Chrome for Testing cache
</td>
</tr>
<tr>
@@ -45,7 +45,7 @@ When no `--executable-path` is provided, agent-browser searches for Chrome in th
</tbody>
</table>
If Chrome is not found, run `agent-browser install` to download Chromium via Playwright.
If Chrome is not found, run `agent-browser install` to download Chrome from Chrome for Testing.
## Usage
+6 -27
View File
@@ -10,42 +10,34 @@ Installs the native Rust binary for maximum performance:
```bash
npm install -g agent-browser
agent-browser install # Download Chromium
agent-browser install # Download Chrome from Chrome for Testing (first time)
```
This is the fastest option -- commands run through the native Rust CLI directly with sub-millisecond parsing overhead.
## Quick start (no install)
Run directly with `npx` if you want to try it without installing globally:
```bash
npx agent-browser install # Download Chromium (first time only)
npx agent-browser install # Download Chrome (first time only)
npx agent-browser open example.com
```
> **Note:** `npx` routes through Node.js before reaching the Rust CLI, so it is noticeably slower than a global install. For regular use, install globally.
## Project installation (local dependency)
For projects that want to pin the version in `package.json`:
```bash
npm install agent-browser
npx agent-browser install
npx agent-browser install # Download Chrome (first time)
```
Then use via `npx` or `package.json` scripts:
```bash
npx agent-browser open example.com
```
Then use via `npx` or `package.json` scripts.
## Homebrew (macOS)
```bash
brew install agent-browser
agent-browser install # Download Chromium
agent-browser install # Download Chrome (first time)
```
## From source
@@ -66,7 +58,6 @@ On Linux, install system dependencies:
```bash
agent-browser install --with-deps
# or manually: npx playwright install-deps chromium
```
## Custom browser
@@ -87,19 +78,7 @@ AGENT_BROWSER_EXECUTABLE_PATH=/path/to/chromium agent-browser open example.com
### Serverless example
```typescript
import chromium from '@sparticuz/chromium';
import { BrowserManager } from 'agent-browser';
export async function handler() {
const browser = new BrowserManager();
await browser.launch({
executablePath: await chromium.executablePath(),
headless: true,
});
// ... use browser
}
```
Use `@sparticuz/chromium` or similar to obtain a Chromium executable path, then pass it via `--executable-path` or `AGENT_BROWSER_EXECUTABLE_PATH`.
## AI agent setup
+3 -80
View File
@@ -2,85 +2,8 @@ import { pageMetadata } from "@/lib/page-metadata"
export const metadata = pageMetadata("native-mode")
# Native Mode (Experimental)
# Native Mode
agent-browser includes an experimental native Rust daemon that communicates with Chrome directly via the Chrome DevTools Protocol (CDP), eliminating the Node.js and Playwright dependencies entirely.
agent-browser is now 100% native Rust by default. The Node.js/Playwright daemon has been removed.
## Enabling Native Mode
Native mode is opt-in. Enable it with the `--native` flag or the `AGENT_BROWSER_NATIVE` environment variable.
### CLI Flag
```bash
agent-browser --native open example.com
agent-browser --native snapshot
agent-browser --native close
```
### Environment Variable
Set `AGENT_BROWSER_NATIVE=1` to avoid passing the flag on every command:
```bash
export AGENT_BROWSER_NATIVE=1
agent-browser open example.com
agent-browser snapshot
agent-browser close
```
### Config File
Add `"native": true` to your `agent-browser.json`:
```json
{"native": true}
```
## Architecture Comparison
<table>
<thead>
<tr><th></th><th>Default (Node.js)</th><th>Native (<code>--native</code>)</th></tr>
</thead>
<tbody>
<tr><td><strong>Runtime</strong></td><td>Node.js + Playwright</td><td>Pure Rust binary</td></tr>
<tr><td><strong>Protocol</strong></td><td>Playwright protocol</td><td>Direct CDP / WebDriver</td></tr>
<tr><td><strong>Install size</strong></td><td>Larger (Node.js + npm deps)</td><td>Smaller (single binary)</td></tr>
<tr><td><strong>Browser support</strong></td><td>Chromium, Firefox, WebKit</td><td>Chromium, Safari (via WebDriver)</td></tr>
<tr><td><strong>Stability</strong></td><td>Stable</td><td>Experimental</td></tr>
</tbody>
</table>
## What Works
All core commands are supported in native mode:
- Navigation: `open`, `back`, `forward`, `reload`
- Interaction: `click`, `fill`, `type`, `press`, `hover`, `select`, `check`, `uncheck`, `scroll`, `focus`, `clear`, `upload`, `drag`
- Observation: `snapshot`, `screenshot`, `eval`, `get text/html/value/attr/count/box/styles`, `is visible/enabled/checked`
- State: `cookies get/set/clear`, `storage local/session`, `state save/load/list`
- Tabs: `tab new/list/close`, tab switching
- Emulation: `set viewport`, `set device`, `set geo`, user agent, timezone, locale
- Streaming: WebSocket screencast and remote input
- Diffing: `diff snapshot`, `diff url`
- Recording: `record start/stop`
- Profiling: `profiler start/stop`, `trace start/stop`
## Known Limitations
- **Firefox and WebKit** are not yet supported (Chromium and Safari only)
- **Annotated screenshots** (`screenshot --annotate`) currently work on the CDP-backed browser path. The Safari/WebDriver backend does not yet support them.
- **Playwright trace format** is not available (native tracing uses Chrome's built-in tracing)
- **HAR export** is not available
- **Network route interception** uses CDP Fetch domain instead of Playwright's route API
## Switching Between Modes
The native daemon and Node.js daemon share the same session socket. You cannot run both simultaneously for the same session. Close the current daemon before switching:
```bash
agent-browser close
export AGENT_BROWSER_NATIVE=1
agent-browser open example.com
```
This page is no longer relevant. See the main [documentation](/) for current architecture and usage.
+4 -4
View File
@@ -4,11 +4,12 @@ export const metadata = pageMetadata("")
# agent-browser
Browser automation CLI designed for AI agents. Compact text output minimizes context usage. Fast Rust CLI with Node.js fallback.
Browser automation CLI designed for AI agents. Compact text output minimizes context usage. 100% native Rust.
```bash
npm install -g agent-browser # all platforms (fastest, native Rust CLI)
npm install -g agent-browser # all platforms
brew install agent-browser # macOS
agent-browser install # Download Chrome (first time)
# or try without installing
npx agent-browser open example.com
@@ -59,8 +60,7 @@ has a unique ref like `@e1`, `@e2`. This provides:
Client-daemon architecture for optimal performance:
1. **Rust CLI** - Parses commands, communicates with daemon
2. **Node.js Daemon** (default) - Manages Playwright browser instance
3. **Native Daemon** (experimental, `--native`) - Pure Rust daemon using direct CDP, no Node.js required
2. **Native Daemon** - Pure Rust daemon using direct CDP, manages Chrome via Chrome DevTools Protocol
Daemon starts automatically and persists between commands.
+1 -1
View File
@@ -38,7 +38,7 @@ export const navigation: NavSection[] = [
{ name: "iOS Simulator", href: "/ios" },
{ name: "Security", href: "/security" },
{ name: "Next.js + Vercel", href: "/next" },
{ name: "Native Mode (Experimental)", href: "/native-mode" },
{ name: "Native Mode", href: "/native-mode" },
],
},
{
+1 -1
View File
@@ -17,7 +17,7 @@ export const PAGE_TITLES: Record<string, string> = {
"engines/chrome": "Chrome",
"engines/lightpanda": "Lightpanda",
next: "Next.js + Vercel",
"native-mode": "Native Mode (Experimental)",
"native-mode": "Native Mode",
changelog: "Changelog",
};