Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@
],
"metadata": {
"description": "Marketplace for the dev-browser skill",
"version": "0.2.6"
"version": "0.2.9"
}
}
7 changes: 5 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: write
# Required for npm trusted publishing (OIDC); also enables provenance.
id-token: write

steps:
- uses: actions/checkout@v4
Expand All @@ -107,6 +109,8 @@ jobs:
with:
node-version: 22
registry-url: 'https://registry.npmjs.org'
# Trusted publishing requires npm >= 11.5.1; node 22 ships an older npm.
- run: npm install -g npm@latest
- run: cd daemon && pnpm install && pnpm run bundle && pnpm run bundle:sandbox-client
- run: |
mkdir -p dist/bin dist/scripts dist/daemon/dist
Expand All @@ -118,9 +122,8 @@ jobs:
cp package.json dist/
cp README.md dist/
cp LICENSE dist/ 2>/dev/null || true
# No NODE_AUTH_TOKEN: auth comes from the OIDC trusted publisher config.
- run: cd dist && npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- uses: softprops/action-gh-release@v2
with:
files: artifacts/**/*
Expand Down
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,27 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [0.2.9] - 2026-07-14

- Added configurable per-browser idle cleanup with `--idle-timeout`, `DEV_BROWSER_IDLE_TIMEOUT_MS`, and `~/.dev-browser/config.json` support. Idle cleanup preserves persistent profiles, excludes externally connected Chrome, and safely rechecks activity under the per-browser lock before closing.

## [0.2.8] - 2026-06-05

- Added the `page.cua.*` pixel/vision toolset: coordinate-based `click`, `doubleClick`, `drag`, `move`, `scroll`, `keypress`, and `type`, plus a JPEG `screenshot()` whose pixels map 1:1 onto click coordinates at any DPR.
- Added the `page.domCua.*` DOM-id toolset: `getVisibleDom()` snapshots visible interactive elements as `node_id=N` lines, with `click`, `doubleClick`, `scroll`, `type`, and `keypress` acting against the latest snapshot's ids.
- Fixed script error messages being dropped from CLI output; thrown errors now report their name and message alongside the stack.
- Documented the vision and DOM-id workflows in the `--help` LLM usage guide.
- Capped the daemon's per-connection request buffer so a local client can no longer exhaust daemon memory with an unterminated frame.
- Serialized `browser-stop` with the per-browser lock so a browser can no longer be torn down while another client's script is running.
- Hardened daemon cold start against duplicate daemons when concurrent CLI invocations race to spawn one.
- Defaulted `PW_CHROMIUM_ATTACH_TO_OTHER=1` so attaching over CDP to Chrome 147's built-in remote debugging no longer hangs.

## [0.2.7] - 2026-04-09

- Updated documentation to recommend `domcontentloaded` for dev server navigation.

## [0.2.6] - 2026-03-30

- Pinned Playwright version.
Expand Down
84 changes: 61 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ A browser automation tool that lets AI agents and developers control browsers wi
- **Auto-connect** - Connect to your running Chrome or launch a fresh Chromium
- **Full Playwright API** - goto, click, fill, locators, evaluate, screenshots, and more

## Demo

https://github.com/user-attachments/assets/c6cf7fb9-b1dc-46ed-93b9-6e7240990c53

## CLI Installation

```bash
Expand Down Expand Up @@ -96,7 +100,7 @@ Windows npm installs download the native `dev-browser-windows-x64.exe` release a

When `dev-browser` runs inside WSL:

- daemon-managed launch mode still uses Playwright's bundled Chromium profile under `~/.dev-browser`
- daemon-managed launch mode uses a persistent profile under `~/.dev-browser`; the browser executable can be configured as described below
- `--connect` can auto-discover Chrome or Brave instances started on the Windows side when remote debugging is enabled
- if auto-discovery still misses your browser, point directly at the Windows profile root with `--profile-path "/mnt/c/Users/<WindowsUser>/AppData/Local/Google/Chrome/User Data"`

Expand All @@ -106,9 +110,58 @@ Example:
dev-browser --connect --profile-path "/mnt/c/Users/<WindowsUser>/AppData/Local/Google/Chrome/User Data"
```

### Default browser executable

To launch a custom Chromium build, such as native Linux `chromium-stealthcdp`
inside WSL, set its absolute executable path in `~/.dev-browser/config.json`:

```json
{
"executablePath": "/absolute/path/to/chromium-stealthcdp/chrome-linux/chrome"
}
```

This setting applies to both headed and headless daemon-managed browsers.
`dev-browser status` and `dev-browser browsers` report the configured executable
for launched browsers. Existing browser instances keep their executable until
closed; new launches read the current configuration. A missing or invalid custom
executable produces an error. Omit `executablePath` to use Playwright's bundled
Chromium. `--connect` continues to attach to the requested external browser.

### Using with AI agents

After installing, just tell your agent to run `dev-browser --help` — the help output includes a full LLM usage guide with examples and API reference. No plugin or skill installation needed.
After installing, tell your agent to run `dev-browser --help` — the help output includes the current LLM usage guide and API reference.

For agents that discover local skills, install or refresh the embedded skill explicitly:

```bash
dev-browser install-skill --codex # ~/.codex/skills/dev-browser/SKILL.md
dev-browser install-skill --claude # ~/.claude/skills/dev-browser/SKILL.md
dev-browser install-skill --agents # ~/.agents/skills/dev-browser/SKILL.md
```

Flags may be combined. With an interactive terminal, `dev-browser install-skill` prompts for targets. In non-interactive environments it updates all three locations, including Codex, so an older copied skill does not survive a CLI upgrade.

### Idle browser cleanup

Daemon-launched named Chromium instances can be closed automatically after they have been idle for a configured duration:

```bash
dev-browser --idle-timeout 5m < script.js
DEV_BROWSER_IDLE_TIMEOUT_MS=300000 dev-browser status
```

The flag accepts `30s`, `5m`, `1h`, or raw milliseconds. You can also set a user default in `~/.dev-browser/config.json`:

```json
{
"idleTimeout": "5m"
}
```

Precedence is `--idle-timeout`, then `DEV_BROWSER_IDLE_TIMEOUT_MS`, then `idleTimeout` in the user config, then disabled. Set any source to `0` to disable cleanup. The effective setting is sent to an already-running daemon and shown by `dev-browser status`.

Cleanup is applied independently to each named browser. Activity is measured from both the start and completion of each request, so running requests are never reaped. Only Chromium instances launched by dev-browser are eligible; browsers attached with `--connect` are never closed by idle cleanup. Closing an idle browser does not delete its profile directory, cookies, or login state, and the next request relaunches it from the same persistent profile. `dev-browser stop` keeps its existing behavior of stopping the daemon and all managed browser connections.

<details>
<summary>Allowing dev-browser in Claude Code without permission prompts</summary>
Expand Down Expand Up @@ -159,7 +212,7 @@ You can also allow related commands in the same list:
</details>

<details>
<summary>Legacy plugin installation (Claude Code / Amp / Codex)</summary>
<summary>Legacy Claude Code plugin installation</summary>

### Claude Code

Expand All @@ -170,26 +223,6 @@ You can also allow related commands in the same list:

Restart Claude Code after installation.

### Amp / Codex

Copy the skill to your skills directory:

```bash
# For Amp: ~/.claude/skills | For Codex: ~/.codex/skills
SKILLS_DIR=~/.claude/skills # or ~/.codex/skills

mkdir -p $SKILLS_DIR
git clone https://github.com/sawyerhood/dev-browser /tmp/dev-browser-skill
cp -r /tmp/dev-browser-skill/skills/dev-browser $SKILLS_DIR/dev-browser
rm -rf /tmp/dev-browser-skill
```

If you already have the `dev-browser` CLI installed locally, you can also install the bundled skill directly:

```bash
dev-browser install-skill --codex
```

</details>

## Script API
Expand All @@ -214,6 +247,11 @@ console.log/warn/error/info // Routed to CLI stdout/stderr

Pages are full [Playwright Page objects](https://playwright.dev/docs/api/class-page) — `goto`, `click`, `fill`, `locator`, `evaluate`, `screenshot`, and everything else, including `page.snapshotForAI({ track?, depth?, timeout? })`, which returns `{ full, incremental? }` for AI-friendly page snapshots.

Every page also exposes two computer-use toolsets:

- `page.cua.*` — pixel/vision tier: `screenshot()` saves a JPEG whose pixels map 1:1 onto CSS coordinates at any DPR and returns `{ path, width, height }`; `click`, `doubleClick`, `drag`, `move`, `scroll`, `keypress`, and `type` act at those coordinates.
- `page.domCua.*` — DOM-id tier: `getVisibleDom()` snapshots visible interactive elements as pseudo-HTML lines with `node_id=N`; `click`, `doubleClick`, and `scroll` act by node id (ids are only valid against the latest snapshot of the current document), plus `type` and `keypress` for the focused element.

## Benchmarks

| Method | Time | Cost | Turns | Success |
Expand Down
111 changes: 76 additions & 35 deletions RELEASING.md
Original file line number Diff line number Diff line change
@@ -1,69 +1,110 @@
# Releasing dev-browser

## First Time Setup
## First-Time Setup

### 1. npm authentication
```bash
npm login
```
npm publishing uses GitHub Actions trusted publishing (OIDC), so the release
workflow does not need an `NPM_TOKEN`. In the npm package settings for
`dev-browser`, configure a trusted publisher with:

- Organization or user: `SawyerHood`
- Repository: `dev-browser`
- Workflow filename: `release.yml`

### 2. GitHub secrets
Go to **GitHub repo → Settings → Secrets and variables → Actions** and add:
- `NPM_TOKEN` — your npm access token (create at https://www.npmjs.com/settings/tokens)
The workflow needs `id-token: write`, which is already configured in
`.github/workflows/release.yml`.

## Publishing a New Version

### 1. Bump the version
### 1. Prepare the release

Start from an up-to-date `main` branch with a clean working tree. Move the
relevant entries from `Unreleased` into a dated version section in
`CHANGELOG.md`, then bump the version:

```bash
node scripts/sync-version.js 0.2.0
npm version 0.2.9 --no-git-tag-version
```
This updates both `package.json` and `cli/Cargo.toml`.

### 2. Commit
The npm lifecycle hook updates all version-bearing files:

- `package.json`
- `package-lock.json`
- `cli/Cargo.toml`
- `cli/Cargo.lock`
- `.claude-plugin/marketplace.json`

Confirm that they all contain the intended version before tagging.

### 2. Build and validate

The Rust binary embeds the generated daemon bundles, so regenerate both bundles
before building the CLI:

```bash
git add -A && git commit -m "release: v0.2.0"
cd daemon
pnpm install
pnpm bundle
pnpm bundle:sandbox-client
npx tsc --noEmit
pnpm vitest run
cd ../cli
cargo build
cd ..
```

### 3. Tag and push
Also confirm that the normal CI checks for `main` are green before publishing.

### 3. Commit

```bash
git tag v0.2.0
git push && git push --tags
git add -A
git commit -m "release: v0.2.9"
```

The GitHub Actions release workflow triggers automatically and:
1. Cross-compiles the Rust CLI for 6 platforms (macOS ARM64/x64, Linux x64/ARM64/musl, Windows x64)
2. Bundles the daemon and sandbox client
3. Creates a GitHub release with all binaries attached
4. Publishes to npm
### 4. Merge, tag, and push

Merge the release commit to `main`, update the local branch, and create the tag
on the resulting `main` commit. The tag must exactly match the version in
`package.json`:

### 4. Verify
```bash
npm info dev-browser version # should show 0.2.0
npm install -g dev-browser # test the install
dev-browser --help # verify it works
git switch main
git pull --ff-only origin main
git tag v0.2.9
git push origin v0.2.9
```

## Quick Patch Release
Pushing any `v*` tag triggers the GitHub Actions release workflow. Do not push
the tag until the release commit is merged and CI is green: the workflow does
not independently verify that the tag and package versions match.

### 5. Monitor and verify

Wait for the `Release` workflow to finish, then verify both distribution
channels:

Same flow, just use a patch version:
```bash
node scripts/sync-version.js 0.1.1
git add -A && git commit -m "release: v0.1.1"
git tag v0.1.1
git push && git push --tags
gh run list --workflow release.yml --limit 1
npm info dev-browser version
npm install -g dev-browser
dev-browser --version
dev-browser --help
```

If publishing fails after npm accepts the version, do not reuse that version;
fix the release workflow and publish a new patch version.

## What the CI Does

See `.github/workflows/release.yml`. On tag push (`v*`):

| Step | What happens |
|------|-------------|
| **Build** | Cross-compiles Rust CLI for each platform target |
| **Bundle** | Runs `pnpm run bundle` and `pnpm run bundle:sandbox-client` in `daemon/` |
| **Bundle** | Runs `pnpm bundle` and `pnpm bundle:sandbox-client` in `daemon/` |
| **Build** | Cross-compiles the Rust CLI for each platform target, embedding the generated daemon bundles |
| **Assemble** | Copies bin wrapper, postinstall, daemon bundles, README, LICENSE into publish dir |
| **Publish npm** | `npm publish` from the assembled directory |
| **GitHub Release** | Creates a release with platform binaries attached |
| **Publish npm** | Uses OIDC trusted publishing to run `npm publish` from the assembled directory |
| **GitHub Release** | Creates a release with generated notes and the platform binaries attached |

## Platform Binaries

Expand Down
2 changes: 1 addition & 1 deletion cli/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "dev-browser"
version = "0.2.6"
version = "0.2.9"
edition = "2021"

[dependencies]
Expand Down
Loading
Loading