849 Commits
Author SHA1 Message Date
Chris Tate b7665e52b6 v0.14.0 changeset (#534)
* v0.14.0 changeset

* fixes

* improvements
2026-02-23 10:48:07 -06:00
shohuandshohu 16c4ef2da6 fix(daemon): add backpressure control and command serialization to prevent IPC EAGAIN (#529)
- Add AGENT_BROWSER_DEFAULT_TIMEOUT env var to override Playwright's
  default 60s timeout (CDP/recording 10s timeouts unaffected)
- Add backpressure-aware safeWrite() that waits for drain when socket
  buffer is full, preventing data loss under load
- Serialize command execution per socket via queue to prevent concurrent
  writes that cause buffer contention

These daemon-side fixes complement #329 (CLI-side EAGAIN retry) by
addressing the root causes: Playwright operations that outlast the
CLI's IPC timeout, and concurrent socket.write() calls that overflow
the kernel buffer.

Tested with heavy React app (1000+ DOM nodes) — 10 consecutive
snapshot commands complete without os error 35/11.

Refs #322

Co-authored-by: shohu <shohu@users.noreply.github.com>
2026-02-23 10:06:06 -06:00
ProviandClaude Opus 4.6 ad6e206a90 feat: add keyboard command for raw keyboard input (#521)
Adds `keyboard type` and `keyboard insertText` subcommands that
operate on the currently focused element without requiring a selector.

Essential for contenteditable editors (Lexical, ProseMirror, CodeMirror,
Monaco) where `type <selector>` doesn't trigger the editor's internal
event pipeline (beforeinput/DOM mutation).

- `keyboard type <text>` — page.keyboard.type() with real keystrokes
- `keyboard insertText <text>` — page.keyboard.insertText()

Note: `keyboard press` intentionally omitted — the existing top-level
`press` command already operates on current focus.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 09:44:08 -06:00
Lukas Malkmus f10f3f6425 cli: only warn about --annotate when explicitly passed via CLI (#531)
The warning "⚠ --annotate only applies to the screenshot command" fires
on every non-screenshot command when annotate is set in config. This is
noisy for users who set it as a persistent default.

Add cli_annotate tracking (matching the existing cli_* pattern) so the
warning only fires when --annotate is passed as a CLI flag.
2026-02-23 09:24:19 -06:00
Chris Tate c0f8f32a55 fix remote debugging (#533)
* fix remote debugging

* debug log
2026-02-23 09:19:21 -06:00
Chris Tate 12d79e4428 add --color-scheme flag for persistent dark/light mode (#528)
Fixes #519. Playwright defaults `colorScheme` to `light` on all new contexts, overriding the browser/OS dark mode setting. This is especially disruptive in CDP mode, where every reconnection resets the scheme. The `set media dark` command also didn't persist its choice to new tabs or pages.

- Add `--color-scheme <dark|light|no-preference>` flag, config key (`colorScheme`), and env var (`AGENT_BROWSER_COLOR_SCHEME`)
- Store the preference in `BrowserManager` and automatically apply it to all new contexts (via Playwright's context option) and all new pages (via `page.emulateMedia` in `setupPageTracking`)
- `set media dark/light` now also persists its choice for subsequent pages and tabs
2026-02-23 01:50:17 -06:00
Chris Tate 467b830974 fix state load failing when no browser is running (#527)
`state load` always fails with "Cannot load state while browser is running" even when no browser is running, making the command completely unusable (#526).

The daemon's auto-launch logic starts a browser before `state_load` gets to handle the command. This adds `state_load` to the exclusion list alongside `launch` and `close`, so `handleStateLoad` can perform its own launch with the state file.
2026-02-23 00:56:48 -06:00
Chris Tate 4412899379 update header/og font (#524) 2026-02-22 16:09:37 -06:00
Chris Tate fca9d7ab5d fix og (#515) 2026-02-20 08:49:53 -06:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 2b8a51b9a6 chore: version packages (#513)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-02-20 00:14:32 -06:00
Chris Tate ebd87173e4 chore: add minor changeset for release (#512) 2026-02-20 00:06:52 -06:00
Chris Tate d5a667ea2d diff (#510)
* diff

* fixes

* fixes

* fixes

* fixes

* fixes

* better docs
2026-02-19 23:51:09 -06:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 9732031087 chore: version packages (#505)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-02-18 22:41:17 -06:00
Chris Tate 69ffad0f04 chore: add minor changeset for release (#504) 2026-02-18 22:31:37 -06:00
Chris Tate e2e259f1e2 annotated screenshots (#503)
* screenshot annotation

* fixes

* fix CI checks

* fixes

* fixes

* fixes

* fixes

* fixes
2026-02-18 22:20:01 -06:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 06a32f4191 chore: version packages (#499)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-02-18 00:40:56 -06:00
Chris Tate c6fc7df443 chore: add patch changeset for release (#498) 2026-02-18 00:34:52 -06:00
Chris Tate 98f49da196 chaining (#497) 2026-02-18 00:24:59 -06:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 85340cb432 chore: version packages (#496)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-02-17 23:33:44 -06:00
Chris Tate 5dc40b4ea4 chore: add minor changeset for release (#495) 2026-02-17 23:28:34 -06:00
Andrew ImmandChris Tate 59fa36b6e2 feat: Enable capture of profiling data (#290)
* feat: Enable capture of profiling data

Adding a new set of commands:
```
agent-browser profiler start

agent-browser profiler stop trace.json
```

With this, agents can start a profiling trace, perform a set of actions, and then extract the profiling data for analysis.

**Note:** I was originally going to call it `agent-browser profile` but I realized that might cause confusion with the `--profile` flag

CDP supports a couple commands for starting/stopping a trace.
When a trace is running, it emits events that need to be picked up.
We store these locally in the daemon until the trace is completed.
When the final event is received, we dump all of them into an output file.

That file can be loaded directly into chrome devtools or another analysis tool to visualize what happened during the agentic run.

Added some basic rust tests for parsing the commands (since they have some optional / required args)

TS daemon adds ~6 tests to make sure the profiling lifecycle (including saving the output file) works as intended

* add docs

* fixes

* fixes

---------

Co-authored-by: Chris Tate <chris@ctate.dev>
2026-02-17 23:11:11 -06:00
Chris Tate 9ca182a4df add config (#494)
* add config

* improvements

* cleaner flags

* fixes

* fixes
2026-02-17 22:27:44 -06:00
Chris Tate 76df589aea update docs (#493) 2026-02-17 21:37:41 -06:00
Chris Tate 19dd2d0c0b fix(#491): auto-disable viewport for --start-maximized and --window-size args (#492)
Fixes #491

When `--start-maximized` or `--window-size` is passed as a browser arg, Playwright's default viewport (1280x720) overrides the browser's own window sizing, making those flags have no effect on the page content.

This change auto-detects those args and sets `viewport: null` so Playwright defers to the browser's window size. Explicit viewport values still take priority.

Also allows `viewport: null` in the launch protocol for agents that want to disable viewport emulation directly.
2026-02-17 20:27:38 -06:00
Chris Tate f9b33ac23d fix: reject invalid --headers JSON, empty frame commands, and --cdp + --extension combo (#488)
## Summary

- Return a `ParseError` when `--headers` receives invalid JSON instead of silently dropping the headers and proceeding
- Reject `frame` commands that provide no `selector`, `name`, or `url` (previously returned `{ switched: true }` without doing anything)
- Add missing mutual exclusion check for `--cdp` + `--extension` (extensions require a local browser, not a CDP connection)
2026-02-16 23:55:40 -06:00
Chris Tate 01efe418af fix: resolve 3 protocol bugs, improve CLI and snapshot code quality (#487)
## Summary

- Fix `allowFileAccess` being silently stripped from launch commands by adding it to the Zod schema in `protocol.ts` (the `--allow-file-access` CLI flag was not reaching the browser)
- Fix `trace stop` requiring a path argument despite help text documenting it as optional -- now works with or without a path
- Fix `addscript`/`addstyle` silently succeeding when neither `content` nor `url` is provided -- now returns a validation error
- Replace hardcoded ANSI escape code with `color::error_indicator()` in `main.rs` to respect `NO_COLOR`
- Fix double-parse pattern and add descriptive expect messages in `commands.rs`
- Fix incomplete string escaping in `snapshot.ts` `buildSelector` (use `JSON.stringify` instead of manual quote escaping)
- Simplify redundant ternary in `snapshot.ts` cursor-interactive role assignment
- Sync docs changelog with CHANGELOG.md (v0.8.1 through v0.10.0)
2026-02-16 22:47:31 -06:00
Chris Tate b7b0da5dfa docs: fix 6 documentation issues (#303, #245, #186, #134, #61, #73) (#486)
* docs: fix 6 documentation issues (#303, #245, #186, #134, #61, #73)

Addresses six open documentation issues in a single pass:

- **#303** -- Add `npx agent-browser` usage across README, SKILL.md, docs site, and `--help` output for zero-install experience. Global install is recommended as the fastest path (native Rust CLI vs Node.js indirection with npx).
- **#245** -- Document Claude Code skill installation with `npx skills add vercel-labs/agent-browser`
- **#186** -- Split installation instructions into Global (recommended), Quick Start (npx), and Project (local dependency) sections with clear guidance on when to use each
- **#134** -- Add "Why agent-browser over playwright-mcp?" comparison table to README covering output format, element selection, protocol, sessions, performance, mobile, cloud, and streaming
- **#61** -- Add "Timeouts and Slow Pages" section to SKILL.md documenting the 60s default timeout, all `wait` variants, and guidance for slow websites
- **#73** -- Replace stale `cp node_modules/...` advice with `npx skills add`, add warning against copying SKILL.md manually, add "Session Management and Cleanup" section to SKILL.md

* remove section

* fix doc
2026-02-16 22:14:43 -06:00
Giulio LeoneandCopilot d441843cca fix(#469): deduplicate cursor-interactive elements in snapshot -C (#475)
Three fixes to eliminate duplicate entries:
1. Skip elements that only inherit cursor:pointer from a parent
   (the parent element is captured instead)
2. Broaden dedup by extracting all quoted text from the ARIA tree,
   not just ref names
3. Add accepted cursor elements to the dedup set to prevent
   multiple DOM elements with the same text from duplicating

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-16 11:55:08 -06:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 9cbb363190 chore: version packages (#452)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-02-13 14:06:37 -06:00
Chris Tate 1112a160bd chore: add minor changeset for release (#451) 2026-02-13 13:58:54 -06:00
Aman panditandChris Tate 697b788af0 feat: add session persistence, state management commands, and --new-tab click (#184)
Rebased and fixed implementation of PR #184 features on current main:

Session persistence:
- --session-name flag and AGENT_BROWSER_SESSION_NAME env var auto-save/restore
  cookies and localStorage across browser restarts
- State files stored in ~/.agent-browser/sessions/ with owner-only permissions
- AES-256-GCM encryption via AGENT_BROWSER_ENCRYPTION_KEY env var
- Auto-expiration of old state files (AGENT_BROWSER_STATE_EXPIRE_DAYS, default 30)

State management commands:
- state list: list saved state files with metadata
- state show <file>: display state summary (cookies, origins, domains)
- state rename <old> <new>: rename state files
- state clear [name] [--all]: clear saved states
- state clean --older-than <days>: delete expired states

New --new-tab flag for click command:
- Opens link href in a new tab instead of navigating the current tab

Security hardening:
- Session name validation prevents path traversal (CLI + daemon)
- safeHeaderMerge prevents prototype pollution in header merging
- WebSocket stream server binds to 127.0.0.1 only
- State files written with 0o600 permissions

Fixes applied over the original PR:
- Use color.rs module instead of hardcoded ANSI escape codes
- Align CLI output field names with daemon response format
- Add CLI-level --session-name validation (not just daemon-side)
- Avoid adding "DOM" to tsconfig.json lib (use proper typing in evaluate)
- Keep version at 0.9.3 (matches current main)
- Centralize session name validation in daemon.ts helper
- Update all documentation (README, SKILL.md, docs site, --help output)

Co-authored-by: Chris Tate <chris@ctate.dev>
2026-02-13 11:56:20 -06:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> cdd10ebb54 chore: version packages (#438)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-02-13 10:59:44 -06:00
Mathias Lafeldt 323b6cdd9d Fix clippy lints (#399)
* cargo fmt

* fix: remove redundant `use libc` import (clippy::single_component_path_imports)

* fix: use `.first()` instead of `.get(0)` (clippy::get_first)

* fix: use `.copied()` instead of `.map(|s| *s)` (clippy::map_clone)

* fix: allow too_many_arguments on ensure_daemon (clippy::too_many_arguments)

* fix: use `then_some` instead of `then` with closure (clippy::unnecessary_lazy_evaluations)

* fix: use pattern match instead of redundant guard (clippy::redundant_guards)

* fix: use pattern match instead of redundant guard in commands.rs (clippy::redundant_guards)

* fix: use `contains()` instead of `iter().any()` for simple equality (clippy::manual_contains)

* Add changeset
2026-02-13 10:44:35 -06:00
Anion 604c0b9632 fix: add missing cursor field to snapshot command schema (#435)
The `-C`/`--cursor` flag was added to the CLI parser and snapshot
implementation in #374, but the Zod schema in protocol.ts was not
updated. This caused the `cursor` field to be silently stripped
during command validation, so cursor-interactive element detection
never ran.

Fixes #434
2026-02-13 08:29:13 -06:00
Chris Tate 4b776c7ba6 fix: move skill-creator out of skills/ into .agents/skills/ (#437)
- Moves `skills/skill-creator/` to `.agents/skills/skill-creator/` so that only the project-specific `agent-browser` skill remains in `skills/`
- Non-agent-browser skills like `skill-creator` are generic tooling and don't belong alongside the product skill, which was confusing to users
2026-02-13 08:26:50 -06:00
Chris Tate 9a01e8b3b5 feat: add --auto-connect flag to discover and connect to running Chrome (#432) 2026-02-12 18:37:37 -06:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> 9c20979bfe chore: version packages (#430)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-02-12 17:47:59 -06:00
vercel[bot]andVercel <vercel[bot]@users.noreply.github.com> 14029d2450 Add Vercel Web Analytics to Next.js (#428)
Implemented Vercel Web Analytics for Next.js (App Router)

## Summary
Successfully installed and configured @vercel/analytics package for the Next.js documentation site.

## Changes Made

### 1. Installed Dependencies
- Installed `@vercel/analytics` package using pnpm
- Command executed: `pnpm install @vercel/analytics`

### 2. Modified Files
- **docs/src/app/layout.tsx**
  - Added import: `import { Analytics } from "@vercel/analytics/next";`
  - Added `<Analytics />` component inside the `<body>` tag, right after `<SpeedInsights />`
  - Placement follows best practices for App Router projects

### 3. Updated Lock Files
- **docs/package.json** - Added @vercel/analytics to dependencies
- **docs/pnpm-lock.yaml** - Updated with new dependency tree

## Implementation Details
- This is an App Router project (uses `app/` directory structure)
- The Analytics component was added to the root layout file at `docs/src/app/layout.tsx`
- Followed the same pattern as the existing SpeedInsights component
- Preserved all existing code structure and formatting

## Verification
 Build completed successfully with no errors
 TypeScript compilation passed
 Modified file passes ESLint checks
 All 15 static pages generated correctly

## Notes
- The project already had @vercel/speed-insights installed, so the pattern for adding Analytics was consistent
- Pre-existing lint errors in mobile-nav-context.tsx and theme-toggle.tsx are unrelated to this change
- Lock files are properly updated and staged as per dependency changes

Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
2026-02-12 17:41:49 -06:00
Chris Tate d03e238516 chore: add patch changeset for release (#429) 2026-02-12 17:41:41 -06:00
Chris Tate 221d22c14f fix: resolve stale session, ref resolution and cursor-ref collision bugs (#427) 2026-02-12 17:32:58 -06:00
vercel[bot]andVercel <vercel[bot]@users.noreply.github.com> b3b9fccd72 Add Vercel Speed Insights to Next.js (#420)
Successfully implemented Vercel Speed Insights for Next.js

## Changes Made

### 1. Installed @vercel/speed-insights package
- Used pnpm (the project's package manager) to install @vercel/speed-insights@1.3.1
- Updated package.json with the new dependency
- Updated pnpm-lock.yaml with the complete dependency tree

### 2. Integrated SpeedInsights component into root layout
- Modified: docs/src/app/layout.tsx
  - Added import: `import { SpeedInsights } from "@vercel/speed-insights/next"`
  - Added `<SpeedInsights />` component inside the `<body>` tag, placed after all other content
  - This follows the recommended pattern for Next.js 13.5+ with App Router

## Implementation Details

The project uses:
- Next.js 16.1.1 with App Router
- TypeScript
- pnpm as the package manager

The SpeedInsights component was added to the root layout (app/layout.tsx) which is the correct approach for Next.js 13.5+ projects using the App Router. The component is placed at the end of the body tag to ensure it loads after the main content.

## Verification

 Build completed successfully - no compilation errors
 All changes staged with git including the lockfile
 Package installed and integrated correctly

Note: Pre-existing linter warnings in mobile-nav-context.tsx and theme-toggle.tsx were not introduced by these changes and remain unchanged.

## Files Modified

1. docs/package.json - Added @vercel/speed-insights dependency
2. docs/pnpm-lock.yaml - Updated with new package dependencies
3. docs/src/app/layout.tsx - Added SpeedInsights import and component

The implementation follows Vercel's official documentation and best practices for Next.js App Router applications.

Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
2026-02-12 17:28:59 -06:00
Chris Tate ec9c6a2ed9 fix: pass --executable-path to launch command in CLI (#424) 2026-02-12 13:28:25 -06:00
Chris Tate 03a8cb95d0 fix write file (#421)
* fix write file

* fix typo
2026-02-11 19:18:48 -06:00
Chris Tate 66a11aeb4c better chat (#416)
* better chat

* fixes

* fix
2026-02-11 14:17:53 -06:00
github-actions[bot]andgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> ffe29b8a26 chore: version packages (#408)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-02-10 14:15:12 -06:00
Chris Tate 76d23db1a9 chore: add patch changeset for release (#407) 2026-02-10 14:03:06 -06:00
Chris Tate 67cdc293f0 fix: allow localhost origins in stream server ws connections (#406) 2026-02-10 13:53:55 -06:00
Chris Tate dc53fedac0 fix: auto-switch to externally opened tabs (#404)
Update `setupContextTracking` in `BrowserManager` to auto-switch `activePageIndex` to newly opened tabs and invalidate the CDP session accordingly. This mirrors what `newTab()` and `newWindow()` already do for explicitly created tabs, and aligns CLI behavior with how real browsers focus newly opened tabs.

Fixes #384
2026-02-10 13:20:01 -06:00
Chris Tate cd4473aa64 fix: forward --exact flag to Playwright for role, label, and placeholder locators (#402) (#403)
Summary

- The `--exact` flag on `find role`, `find label`, and `find placeholder` was accepted by the CLI but silently dropped by the server. The Zod validation schema, TypeScript types, and action handlers all lacked the `exact` field, so it was stripped before reaching Playwright's `getByRole`, `getByLabel`, and `getByPlaceholder` calls.
- Added `exact` to the schema, types, and handler for all three locators so the flag is forwarded to Playwright as intended.
- Added tests confirming `exact: true` survives protocol parsing for `getbyrole`, `getbylabel`, and `getbyplaceholder`.

Fixes #402
2026-02-10 09:07:47 -06:00
Chris Tate 8e5ead85c8 fix build (#401) 2026-02-09 12:10:40 -06:00