## Summary
Fixed an issue where the `tab list` command couldn't recognize new pages that were opened externally (e.g., via `target="_blank"` links or popup windows). The problem occurred because context-level page tracking wasn't properly set up for all browser launch methods, causing new pages created outside of explicit `newTab()` calls to go untracked.
## Changes
- Added `setupContextTracking(context)` calls to `launch()`, `launchIncognito()`, and other context creation methods to ensure all contexts listen for new page events
- Added duplicate page checks (`!this.pages.includes(page)`) in `setupContextTracking()`, `newTab()`, and `launchIncognito()` to prevent the same page from being tracked multiple times
- Fixed `activePageIndex` calculation in `launch()` to properly set the active page index
- Enhanced comments to clarify that `setupContextTracking()` handles externally created pages (popups, new tabs from links)
## Implementation Details
The fix ensures that when a user clicks an element that opens a new tab/window, the browser context's 'page' event listener will automatically detect and track the new page. The duplicate prevention logic handles cases where both the context listener and manual page creation might try to add the same page.
Fixes#273
Add Kernel (https://kernel.sh) as a third-party cloud browser provider,
following the same pattern as Browserbase and Browser Use integrations.
Features:
- Launch browser with `-p kernel` flag or `AGENT_BROWSER_PROVIDER=kernel`
- Configurable via environment variables:
- KERNEL_API_KEY (required)
- KERNEL_HEADLESS (default: false)
- KERNEL_STEALTH (default: true)
- KERNEL_TIMEOUT_SECONDS (default: 300)
- KERNEL_PROFILE_NAME (optional, for persistent sessions)
- Profile find-or-create: automatically creates profile if it doesn't exist
- Profile persistence: cookies/logins saved back to profile on session close
- Uses raw fetch() calls for API communication (no SDK dependency)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Add CLI flags for cookie URL, domain, path, httpOnly, secure, and expires
Extends the `cookies set` command to support setting cookies with additional parameters before loading a page, solving authentication workflows where cookies need to be set for different domains.
**Key changes:**
- Added CLI flags: `--url`, `--domain`, `--path`, `--httpOnly`, `--secure`, `--sameSite`, `--expires`
- Added comprehensive test coverage for all new flags and combinations
- Updated help documentation with usage examples
- No daemon changes needed - it already supported these parameters
**Example usage:**
```bash
agent-browser cookies set session_id "abc123" --url https://app.example.com --httpOnly --secure
```
This allows setting cookies for a URL before opening the page, eliminating the need for workarounds in cross-domain authentication scenarios.
Fixes#261
* Update lock
* Fix compilation error
* feat: add support for ignoring HTTPS certificate errors
* fix: update warning message for already running daemon to include ignore HTTPS errors option
* docs: add documentation for --ignore-https-errors option in README and SKILL.md
* feat: initialize ignore_https_errors flag in command context
* fix: change launch_cmd to mutable for cdp value handling
The screenshot command was failing with 'Validation error: selector: Expected string, received null' when only a path was provided (e.g., 'agent-browser screenshot ~/Desktop/test.png').
The Rust CLI serializes None values as null in JSON, but the Zod schema only allowed undefined (via .optional()), not null. Changed selector field to use .nullish() which accepts both null and undefined.
Fixes issue where screenshot command without selector fails validation.
* fix: download artifacts to temp directory to avoid naming conflict
The download-artifact action creates directories named after each artifact.
When downloading to bin/, this caused conflicts because the artifact directory
names matched the binary names (e.g., bin/agent-browser-darwin-arm64/agent-browser-darwin-arm64).
Fix by downloading to artifacts/ first, then using find to move the binaries to bin/.
* fix docs
The download-artifact action creates directories named after each artifact.
When downloading to bin/, this caused conflicts because the artifact directory
names matched the binary names (e.g., bin/agent-browser-darwin-arm64/agent-browser-darwin-arm64).
Fix by downloading to artifacts/ first, then using find to move the binaries to bin/.
* fix(screenshot): support refs and improve error messages
* fix(cli): support selector argument in screenshot command
* Fix CSS class selectors being treated as file paths
* fix(test): update screenshot test assertions
---------
Co-authored-by: Chris Tate <chris@ctate.dev>
* feat: add download and waitfordownload CLI commands
Add CLI support for the existing download functionality in the daemon:
- `download <selector> <path>`: Click an element to trigger download
and save to specified path
- `wait --download [path] [--timeout ms]`: Wait for any download to
complete, optionally save to path with configurable timeout
Includes comprehensive unit tests and help documentation.
* fix: download command ref support and output message
- Fix handleDownload to use browser.getLocator() for ref selector support
- Fix CLI output to show "Downloaded to" instead of "Screenshot saved"
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Chris Tate <chris@ctate.dev>
* Add --profile flag for persistent browser profiles
Adds support for persistent browser profiles that preserve cookies,
localStorage, and login sessions across browser restarts.
Changes:
- Add --profile <path> CLI flag (flags.rs)
- Add AGENT_BROWSER_PROFILE environment variable support
- Add profile field to LaunchCommand type (types.ts)
- Use launchPersistentContext when profile is specified (browser.ts)
- Update help text and README with documentation
Usage:
agent-browser --profile ~/.myapp-profile open myapp.com
This enables AI agents to maintain authenticated sessions across
browser restarts without re-authenticating each time.
* Expand tilde in profile path to home directory
* fix: add missing profile field to test Flags struct
---------
Co-authored-by: Chris Tate <chris@ctate.dev>
* fix: use ~/.agent-browser for socket files instead of TMPDIR
This fixes issue #163 where different TMPDIR values (common with
tmux/screen/VSCode/IntelliJ) caused the CLI and daemon to use
different socket paths.
Socket directory priority:
1. AGENT_BROWSER_SOCKET_DIR (explicit override)
2. $XDG_RUNTIME_DIR/agent-browser (Linux standard)
3. ~/.agent-browser (fallback, like Docker Desktop)
Both CLI (Rust) and daemon (Node.js) now use the same logic.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: session list now looks in correct socket directory
- Make get_socket_dir() public in connection.rs
- Update session list to use get_socket_dir() instead of temp_dir()
- Update pid file pattern from agent-browser-{session}.pid to {session}.pid
- Add tmpdir fallback to daemon.ts when homedir is unavailable
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* test: add unit tests for socket directory resolution
Add comprehensive tests for get_socket_dir/getSocketDir to verify:
- AGENT_BROWSER_SOCKET_DIR takes priority
- Empty strings are ignored (fixes Rust/TypeScript consistency)
- XDG_RUNTIME_DIR fallback works correctly
- Home directory fallback when env vars unset
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
The copy-native.js script was looking for 'agent-browser' but on Windows
the compiled binary is 'agent-browser.exe', causing the copy to fail.
Co-authored-by: jiazhuangai <jiazhuangai@example.com>
Co-authored-by: Claude <noreply@anthropic.com>
Previously, the --cdp flag only accepted a port number and connected via
http://localhost:{port}. This made it impossible to connect to remote
browser services like Kernel, Browserless, etc. that provide WebSocket URLs.
The --cdp flag now accepts either:
- A port number (e.g., 9222) for local connections
- A full WebSocket URL (e.g., wss://...) for remote browser services
Changes:
- Added cdpUrl field to LaunchCommand type
- Updated protocol validation to accept URL format with scheme validation
- Modified connectViaCDP to detect and handle both formats
- Handle numeric strings for JSON serialization edge cases
- Updated CLI to send cdpUrl or cdpPort based on input format
- Updated README with examples for remote connections
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add Browser Use cloud browser
integration
* feat: enhance Browser Use integration with provider flag support
- Updated README to reflect new usage instructions for enabling Browser Use with the `-p` flag.
- Modified CLI to parse and handle the `-p` flag for specifying the provider.
- Implemented logic in the main application to launch with the specified cloud provider.
- Adjusted BrowserManager to connect to Browser Use based on the provider flag or environment variable.
- Updated types and protocol schemas to include provider information.
* feat: add validation for mutually exclusive CLI options
- Implemented checks to prevent the use of both --cdp and --provider flags simultaneously.
- Added validation to ensure --extension cannot be used with the --provider flag.
- Enhanced error handling to provide clear feedback in both JSON and console output formats.
* Add Browserbase support for remote browser over CDP
When BROWSERBASE_API_KEY and BROWSERBASE_PROJECT_ID env vars are set,
connect to a Browserbase session via CDP instead of launching a local browser.
* Update URLs to browserbase repo
* Add Browserbase support for remote browser over CDP
When BROWSERBASE_API_KEY and BROWSERBASE_PROJECT_ID env vars are set,
connect to a Browserbase session via CDP instead of launching a local browser.
* Update link to Browserbase Dashboard in README
* bump browserbase sdk to latest version
* remove sdk as a dep
* change name back to vercel labs
* added try catch blocks, functions to close session
* revert package names
* remove extra if statement
---------
Co-authored-by: Kylejeong2 <kylejeong21@gmail.com>
Adds a `connect <port>` command that establishes a CDP connection
to a running browser. The daemon remembers the connection, so
subsequent commands work without needing --cdp on every call.
Example:
agent-browser connect 9222
agent-browser snapshot # works without --cdp
agent-browser tab
agent-browser close
* fix: support libasound2t64 on newer Ubuntu versions
Updates the install logic to check if `libasound2t64` is available using
`apt-cache` before falling back to `libasound2`. This fixes installation
on Ubuntu 24.04 and other systems affected by the 64-bit time_t transition.
* Update cli/src/install.rs
Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>
---------
Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>