🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

browser-pilot-cli

Package Overview
Dependencies
Maintainers
1
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

browser-pilot-cli - npm Package Compare versions

Comparing version
0.3.0
to
0.4.0
+53
docs/releases/v0.2.0.md
# Browser Pilot 0.2.0
Browser Pilot 0.2.0 turns the original one-shot CLI into an Agent-neutral
browser control platform while preserving direct `bp` commands and the user's
real Chrome profile. It requires no browser extension.
## Highlights
- Adds a versioned `bridge --stdio` protocol for products embedding the
official executable, with runtime tool discovery and no required SDK or MCP
dependency.
- Adds a shared per-user Broker with isolated Workspaces, Leases, targets,
refs, network rules, auth state, events, and Artifacts for concurrent Agents.
- Lists and controls eligible user-opened tabs alongside Browser Pilot managed
tabs. Bulk cleanup and session release close only managed tabs.
- Makes Chrome discovery passive. Only an explicit `bp connect` or
`browser.connect` may request browser authorization, and concurrent requests
share one in-flight connection attempt without timer-driven retries.
- Replaces file-backed refs with ephemeral Observation-scoped identity across
browser generations, targets, frames, CDP sessions, loaders, and documents.
- Fuses accessibility, DOM, and layout information; supports Shadow DOM,
same-process frames, and OOPIFs with bounded output and typed stale-ref
failures.
- Adds verified click, input, keyboard, upload, scroll, and dropdown behavior,
including obstruction checks, controlled-input readback, and composite-action
cancellation when page state changes.
- Adds bounded read, search, DOM metadata, page geometry, annotated screenshot,
PDF, download Artifact, dialog, network interception, cookie, and HTTP auth
support.
- Adds typed browser events, disconnect/reconnect state, command idempotency,
deadlines, cancellation, unknown outcomes, event cursors, and protected
Artifact delivery.
- Adds npm, local project, and self-contained macOS, Linux, and Windows launch
modes plus a language-neutral stdio conformance suite and reference Tenon and
OpenClaw adapters.
## Upgrade Notes
- Chrome remote debugging must be enabled at
`chrome://inspect/#remote-debugging`.
- Browser authorization is explicit. Run `bp connect` once when Browser Pilot
reports that it is disconnected; ordinary discovery and bridge startup do
not prompt.
- Direct CLI behavior remains supported. Embedded products should launch the
pinned executable with `bridge --stdio` and depend only on the documented
protocol.
- Refs are intentionally transient. Obtain a fresh snapshot after navigation,
frame changes, reconnects, or `stale_ref` responses.
See the [platform specification](https://github.com/relixiaobo/browser-pilot/blob/v0.2.0/docs/architecture/browser-pilot-platform-spec.md),
[stdio integration contract](https://github.com/relixiaobo/browser-pilot/blob/v0.2.0/docs/integration/stdio-bridge.md),
and [conformance suite](https://github.com/relixiaobo/browser-pilot/blob/v0.2.0/docs/integration/stdio-conformance.md)
for the stable public contracts.
# Browser Pilot 0.2.1
This packaging-only patch adds the canonical GitHub repository metadata
required for npm Trusted Publishing provenance verification. Browser runtime,
protocol, CLI, and Agent integration behavior are unchanged from 0.2.0.
This is the first 0.2 stable version published through the package's GitHub
Actions OIDC Trusted Publisher. The npm package requires no long-lived publish
token, and its provenance identifies
`https://github.com/relixiaobo/browser-pilot` as the source repository.
See the [Browser Pilot 0.2.0 release](https://github.com/relixiaobo/browser-pilot/releases/tag/v0.2.0)
for the complete feature and upgrade notes.
# Browser Pilot 0.2.2
This patch fixes executable ownership validation when a CLI command encounters
a compatible Broker started by another Browser Pilot installation.
The CLI now checks the Broker's executable version and identity before it
initializes its one-shot connection. A mismatched installation returns the
structured `protocol_incompatible` error without creating or changing Broker
session state. The executable that owns the Broker can therefore still shut it
down cleanly, which makes in-place upgrades deterministic and avoids a failed
command leaving the old Broker unusable.
Health responses from older compatible Brokers that do not expose executable
metadata remain supported. Current Brokers continue to enforce exact ownership
for protected shutdown.
Browser authorization, tab ownership, public protocol, and Agent integration
behavior are otherwise unchanged from 0.2.1.
# Browser Pilot 0.4.0
Browser Pilot 0.4.0 introduces protocol 1.3 while preserving protocol 1.0-1.2
compatibility and the extension-free browser control model.
## Profile identity
- `browser.profiles.list` remains passive and returns neutral, connection-scoped
Profile contexts without opening or attaching to identity pages.
- New `browser.profiles.identify` explicitly creates temporary visible
`chrome://version` targets, verifies the reported Profile path against the
connected browser `userDataRoot`, reads bounded Chrome Local State metadata,
and proves cleanup before returning.
- Results distinguish `unidentified`, `verified`, and `unavailable`, with
structured Profile/account fields and stable failure codes. Identity is
cached only for one browser connection generation.
- `bp profiles --identify [--refresh]` exposes the same behavior. Profile and
tab selectors are one-based and may use a uniquely verified Profile name,
account name, or email address.
## Agent isolation and vocabulary
- Direct one-shot CLI Agents can set a stable `BROWSER_PILOT_CLIENT_KEY` or
`--client-key`; different keys receive distinct Principal, Connection,
Workspace, and Lease state while repeated calls with one key reuse it.
- `bp disconnect` releases only its CLI namespace and cannot stop a Broker that
still has another active Lease or embedded Connection.
- Protocol 1.3 browser discovery uses `userDataRoot` instead of the ambiguous
legacy candidate field `profile`.
- Protocol 1.3 tab inventory uses `selected` for the Lease-local target instead
of `active`, which could be mistaken for Chrome foreground focus.
## Page and target isolation
- Browser Pilot no longer injects a controller overlay or other status UI into
page DOM. Embedding Hosts may present returned controller identity in
Host-owned UI.
- Chrome and Edge extension pages are excluded from ordinary tab inventory and
Profile context evidence.
- Existing eligible user tabs remain fully controllable; managed-only cleanup
still leaves user tabs open.
## Embedding
- The Tenon/OpenClaw-neutral reference adapter negotiates protocol 1.3 and
discovers the identity operation through the canonical runtime manifest.
- One-shot CLI, embedded stdio, local Artifact export, native image results,
and protocol 1.0-1.2 compatibility remain supported without a Native SDK,
MCP server, or browser extension.
## CLI and distribution contract
- Every non-TTY one-shot failure now includes stable `code` and `retryable`
fields. Commander/parser and local input errors use `invalid_argument`, while
Broker errors preserve their protocol code and structured remediation.
- The versioned Agent plugin/skill records CLI `0.4.0` as its tested/minimum
version and accepts backward-compatible updates within the declared range. It
includes Codex UI metadata plus a machine-readable compatibility manifest.
- GitHub releases publish the plugin archive and checksum alongside a release
index that verifies the npm version, protocol range, and every native asset.
- Native targets are Apple Silicon macOS, x64 Linux, and x64 Windows. Intel Mac
is not supported and no `darwin-x64` asset is published.
+50
-19

@@ -184,5 +184,10 @@ # Browser Pilot Platform Specification

generation; the raw CDP browser-context ID is internal. A ProfileContext has a
connection-scoped neutral label, optional verified display metadata, bounded
connection-scoped neutral label, structured identity status and optional
verified Profile/account metadata, bounded
representative tabs, and current tab counts. Passive discovery never opens a
tab to infer its display name. Reconnect invalidates every ProfileContext ID.
tab to infer Profile or account identity. Protocol 1.3 identity is an explicit visible
operation: it reads Chrome's reported Profile path, verifies it against the
BrowserInstance user-data root, then maps bounded Local State metadata to
structured Profile/account fields. Reconnect invalidates every ProfileContext
ID and cached identity.

@@ -308,2 +313,10 @@ ### BrowserWorkspace

The supported native matrix is `darwin-arm64`, `linux-x64`, and `win32-x64`;
Intel Mac is not supported. Each release also publishes a versioned Agent
plugin/skill archive and checksum. A deterministic release index binds those
assets to the npm package version, exact compatible skill/CLI version, and
runtime protocol range. GitHub Release publication waits for successful npm
publication so consumers cannot observe a nominal release with only one half
of that distribution contract.
### Broker Locator and Startup

@@ -355,6 +368,10 @@

Existing and future eligible user tabs are available immediately. The command
returns the existing JSON shape during migration. Failures include a stable
machine code in addition to compatible human guidance. One-shot processes use
a fixed daemon-internal Connection, idempotently keyed Workspace, and renewable
Lease with a maximum five-minute TTL. Normal process exit leaves that transient
returns the existing JSON shape during migration. Every non-TTY failure,
including command parsing and local argument validation, includes a stable
machine code and `retryable` flag in addition to compatible human guidance.
One-shot processes
derive a stable Connection identity from `BROWSER_PILOT_CLIENT_KEY` or
`--client-key`, then use an idempotently keyed Workspace and renewable Lease
with a maximum five-minute TTL. Independent Agents use distinct stable keys;
the default key preserves single-Agent compatibility. Normal process exit leaves that transient
daemon-memory state available to the next command; expiry invalidates refs and

@@ -364,4 +381,5 @@ releases target control. No target, frame, session, Observation, ref, auth, or

compatibility Workspace and closes only its managed targets. It stops the
daemon only when called by the matching executable installation and no live
embedded Connection remains; otherwise it returns `protocol_incompatible` or
daemon only when called by the matching executable installation and no other
active Lease or embedded Connection remains; otherwise it returns
`protocol_incompatible` or
`broker_in_use` without replacing or terminating the Broker. JavaScript dialogs

@@ -423,3 +441,3 @@ remain pending and are handled explicitly with `bp dialogs` and `bp dialog`;

and carry an opaque `profileContextId`. New managed work resolves a Profile from
an explicit context, the current active target, the Workspace selection, or a
an explicit context, the current Lease-selected target, the Workspace selection, or a
single available context, in that order. Multiple contexts without an anchor

@@ -430,5 +448,7 @@ return `profile_selection_required` before creating a target. The Agent host

`browser.profiles.list` is passive and returns bounded, connection-scoped
summaries. `browser.profiles.select` updates only the owning Workspace. A Chrome
summaries. Protocol 1.3 `browser.profiles.identify` explicitly creates and
cleans temporary visible identity targets when account-aware identity is
needed. `browser.profiles.select` updates only the owning Workspace. A Chrome
reconnect invalidates old ProfileContext IDs and requires relisting and
reselection. Selection clears only the Lease's logical active-target anchor; it
reselection. Selection clears only the Lease's logical selected-target anchor; it
does not release control, activate a tab, or change Chrome focus. The exact

@@ -494,2 +514,7 @@ creation and compatibility algorithm is frozen in `docs/plans/profile-context-routing.md`.

Protocol 1.3 adds explicit verified Profile/account identity. Browser candidate
results use `userDataRoot`, Profile results use structured identity status and
fields, and tab inventory uses `selected` for the Lease-local target instead of
the ambiguous `active`. Protocol 1.2 retains its legacy field vocabulary.
### Tool Contract

@@ -589,4 +614,6 @@

No handoff call accepts a foreign Lease or target ID.
- **BR-7:** The Pilot window visibly identifies the controlling client without
injecting mutable content into the page DOM.
- **BR-7:** Browser Pilot returns controlling-client identity in scoped
protocol results and events so a Host may present it in Host-owned UI. With no
extension, Browser Pilot does not claim it can modify Chrome's browser chrome,
and it never injects status borders, labels, or controls into page DOM.
- **BR-21:** Exposing the CLI or bridge to an Agent is the product-level

@@ -610,3 +637,5 @@ browser-control authorization boundary. Chrome's own remote-debugging

with origin and ManagedTabSet membership. Browser Pilot internal targets,
DevTools, and unsupported browser-internal targets remain excluded.
DevTools, extension-owned pages, and unsupported browser-internal targets
remain excluded. Excluded extension pages do not create or represent a
ProfileContext.
- **BR-27:** Bulk cleanup and `close --all` default to the ManagedTabSet. No

@@ -619,5 +648,7 @@ bulk operation closes user tabs outside it. Each user tab requires an

- **BR-30:** Profile listing is passive. It cannot create, attach, activate, or
navigate a target solely to infer a Profile name. Unverified names are
omitted instead of guessed.
- **BR-31:** New-target Profile routing follows explicit context, active target,
navigate a target solely to infer a Profile name. Identity requires the
explicit protocol 1.3 operation, exact Profile-path verification, bounded
metadata reads, and verified cleanup. Unverified names are omitted instead
of guessed.
- **BR-31:** New-target Profile routing follows explicit context, selected target,
Workspace selection, then single available context. Multiple unanchored

@@ -930,3 +961,3 @@ contexts fail with `profile_selection_required` before browser dispatch.

identity and matching executable installation identity, and refuses while
any embedded Connection remains live.
any embedded Connection or active Lease remains live.
- Additive tool and field changes use capability negotiation and schema

@@ -959,3 +990,3 @@ evolution. Breaking semantics require a protocol-major change.

- **AC-3:** Two clients can operate separate Pilot windows concurrently, and
refs, active targets, frames, auth, rules, and close operations cannot cross
refs, selected targets, frames, auth, rules, and close operations cannot cross
Workspace boundaries.

@@ -962,0 +993,0 @@ - **FR-4 User-browser control:** An Agent can list and control all eligible

@@ -20,2 +20,7 @@ # Stdio Bridge Integration Contract

For release bundles, verify the versioned release index first. It binds the npm
package, Agent plugin/skill compatible CLI range and tested version, protocol
range, supported native assets, and adjacent SHA-256 files. Native releases support `darwin-arm64`,
`linux-x64`, and `win32-x64`; Intel Mac is not supported.
Launch it directly, without a shell:

@@ -109,3 +114,3 @@

```json
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"client":{"id":"com.example.agent","name":"Example Agent","version":"2.0.0","instanceId":"install:01J..."},"protocol":{"min":{"major":1,"minor":1},"max":{"major":1,"minor":2}},"requestedCapabilities":["browser.control","workspace.manage","observation.read","action.input","artifact.read","event.read"],"launchMode":"embedded","limits":{"maxMessageBytes":1048576,"maxResultBytes":4194304}}}
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"client":{"id":"com.example.agent","name":"Example Agent","version":"2.0.0","instanceId":"install:01J..."},"protocol":{"min":{"major":1,"minor":1},"max":{"major":1,"minor":3}},"requestedCapabilities":["browser.control","workspace.manage","observation.read","action.input","artifact.read","event.read"],"launchMode":"embedded","limits":{"maxMessageBytes":1048576,"maxResultBytes":4194304}}}
```

@@ -116,3 +121,3 @@

identity, a Connection ID, browser candidates, and negotiated limits. Each
candidate has a stable `id`, product/channel/profile identity, aggregate
candidate has a stable `id`, product/channel and `userDataRoot`, aggregate
`state`, separate `processState`, `remoteDebuggingState`, and

@@ -139,2 +144,9 @@ `authorizationState`, plus structured `remediation` when action is needed.

Protocol 1.3 adds the explicit `browser.profiles.identify` mutation and
structured Profile identity fields. Browser discovery returns `userDataRoot`
instead of the legacy candidate field `profile`, and tab inventory returns
`selected` instead of `active`. `selected` means the target selected by this
Lease; it does not describe Chrome foreground focus. Protocol 1.2 clients keep
the old field vocabulary and do not see the identity tool.
The initialize request and response use the service's fixed bootstrap limits.

@@ -266,21 +278,32 @@ The bridge switches limits only after the successful response has been written,

Profile selection is routing for new managed targets, not a permission grant.
Browser-internal and extension-owned pages are excluded from ordinary tab and
Profile representative inventory.
Protocol 1.2 hosts should use this flow when creating independent work:
Protocol 1.2+ hosts should use this flow when creating independent work:
1. Call `browser.profiles.list`. It is passive and returns neutral labels,
bounded representative tabs, counts, and the Workspace selection.
2. If there is one Profile, `browser.open` can infer it. If there are several
2. On protocol 1.3, if account-aware identity is needed, call
`browser.profiles.identify`. It briefly creates visible `chrome://version`
targets, verifies each reported path as an immediate child of the connected
`userDataRoot`, reads bounded Chrome Local State metadata, closes every
temporary target, and caches the result for one connection generation.
`refresh: true` explicitly re-probes.
3. If there is one Profile, `browser.open` can infer it. If there are several
and no current target or Workspace selection, ask the user which Profile to
use.
3. Call `browser.profiles.select` with the returned opaque ID, or pass that ID
4. Call `browser.profiles.select` with the returned opaque ID, or pass that ID
directly as `browser.open.arguments.profileContextId`.
4. Treat IDs as scoped to the current browser connection generation. After
reconnect, relist Profiles, tabs, frames, and Observations.
5. Treat IDs and verified identity as scoped to the current browser connection
generation. After reconnect, relist Profiles, tabs, frames, and Observations.
Profile names are included only when Browser Pilot has verified them without a
visible discovery tab; otherwise hosts present the neutral label and
representative page titles/URLs. Never expose or persist raw CDP context IDs.
New-target routing uses an explicit call argument, the Lease's logical active
Profile results use `identityStatus: unidentified | verified | unavailable`.
Only verified results may include `profileName`, `accountName`, `accountEmail`,
and `profileDirectory`; unavailable results include a stable
`identityErrorCode` rather than a guessed account. Current codes are
`profile_path_unavailable`, `profile_path_unverified`,
`local_state_unavailable`, and `profile_metadata_missing`. Never expose or persist raw
CDP context IDs. New-target routing uses an explicit call argument, the Lease's logical selected
target, the Workspace selection, or the only available context, in that order.
`browser.profiles.select` clears only the logical active-target anchor so its
`browser.profiles.select` clears only the logical selected-target anchor so its
selection applies to the next new managed target; it does not release control,

@@ -606,3 +629,4 @@ activate a user tab, or change Chrome focus.

request only when the Broker process identity and executable installation
identity still match and `embeddedConnections` is zero. Otherwise it returns
identity still match, `embeddedConnections` is zero, and no other active Lease
remains. Otherwise it returns
`protocol_incompatible` or retryable `broker_in_use`; it never evicts an Agent

@@ -635,5 +659,5 @@ product to complete an upgrade.

The shared example launches an absolute executable path without a shell,
negotiates protocol 1.1 through 1.2, discovers tools at runtime, and maps a host work scope
negotiates protocol 1.1 through 1.3, discovers tools at runtime, and maps a host work scope
to a Workspace plus its active invocation to a renewable Lease. It never stores
an active tab, frame, Observation, ref, credential, rule, Artifact, or event
a selected tab, frame, Observation, ref, credential, rule, Artifact, or event
cursor on disk. Host tool-call IDs become Command and idempotency identities;

@@ -640,0 +664,0 @@ transport loss after dispatch of a mutating operation is returned as

# Profile Context Routing Plan
Status: **Complete**
Target: Browser Pilot `v0.3.0`, protocol `1.2`
Target: Browser Pilot `v0.4.0`, protocol `1.3`
Source of truth: `docs/architecture/browser-pilot-platform-spec.md`

@@ -56,3 +56,4 @@

- a connection-scoped neutral label;
- an optional verified display name and Profile directory;
- connection-generation-scoped identity status plus optional verified Profile
name, account name/email, and Profile directory;
- current total and eligible tab counts;

@@ -103,6 +104,27 @@ - one or more bounded representative targets for routing and user recognition.

## Protocol 1.3
Protocol 1.3 adds `browser.profiles.identify` as an explicit, mutating identity
operation. For each requested unidentified Profile it creates a temporary
visible `chrome://version` target in that exact context, reads `#profile_path`,
verifies that path as an immediate child of the connected browser's
`userDataRoot`, reads bounded metadata from Chrome `Local State`, then detaches
and proves the temporary target was closed. Failure to prove cleanup returns
`unknown_outcome`; Browser Pilot never silently leaves an identity page behind.
Results use `identityStatus: unidentified | verified | unavailable` plus
optional `profileName`, `accountName`, `accountEmail`, `profileDirectory`, and a
stable `identityErrorCode`. Identity is cached only for the current browser
connection generation. `refresh: true` explicitly re-probes. No directory
ordering, tab title, or raw context ID is treated as account identity.
Protocol 1.3 also renames browser candidate `profile` to `userDataRoot` and tab
inventory `active` to `selected`. The latter is the Lease's logical target, not
Chrome foreground focus. Protocol 1.2 clients retain their legacy fields.
`browser.profiles.select` accepts only a public `profileContextId`. Human CLI
selectors such as index, neutral label, or verified display name are resolved
selectors such as one-based index, neutral label, or verified Profile/account
name or email are resolved
client-side from a fresh list. The machine protocol never accepts an ambiguous
free-form selector. Selecting a Profile clears the Lease's logical active-target
free-form selector. Selecting a Profile clears the Lease's logical selected-target
anchor without releasing control or changing Chrome focus, so the next new

@@ -117,3 +139,3 @@ managed target uses that explicit Workspace selection.

1. an explicit, current-generation `profileContextId`;
2. the current Lease's active target context;
2. the current Lease's selected target context;
3. the Workspace's current, valid selection;

@@ -167,3 +189,3 @@ 4. the only currently available Profile context;

automatic.
- In multiple contexts, an active target remains an unambiguous anchor.
- In multiple contexts, a selected target remains an unambiguous anchor.
- With multiple contexts and no anchor, older clients receive a structured

@@ -173,4 +195,4 @@ failure and Browser Pilot never silently chooses the first context.

private.
- The current CLI negotiates protocol 1.2, while the Broker continues to accept
1.0 and 1.1.
- The current CLI negotiates protocol 1.3, while the Broker continues to accept
1.0 through 1.2.

@@ -194,3 +216,3 @@ ## Delivery

- [x] No multi-context open silently selects a first Profile.
- [x] Explicit, active-target, Workspace, and single-context resolution follow the
- [x] Explicit, selected-target, Workspace, and single-context resolution follow the
specified order.

@@ -202,2 +224,5 @@ - [x] Every managed target and popup matches its ManagedTabSet Profile context.

- [x] Passive listing creates no target and never focuses or navigates a user tab.
- [x] Explicit identity verifies Profile paths, returns structured account-aware
fields, cleans temporary targets, caches only within one connection
generation, and never guesses unavailable metadata.
- [x] Janitor EOF/SIGKILL cleanup closes fallback-created managed windows but never

@@ -204,0 +229,0 @@ user tabs.

@@ -96,5 +96,7 @@ # Universal Agent Integration Plan

- Covers: FR-1, FR-3, AC-1, AC-3.
- Complete: the CLI uses a fixed daemon-internal one-shot Connection plus
idempotently keyed compatibility Workspace and renewable five-minute Lease.
Every CLI command calls canonical tools; active targets, frames, sessions,
- Complete: the CLI derives a stable one-shot Connection identity from
`BROWSER_PILOT_CLIENT_KEY`/`--client-key`, plus an idempotently keyed
compatibility Workspace and renewable five-minute Lease. The default key
preserves single-Agent compatibility; distinct stable keys isolate Agents.
Every CLI command calls canonical tools; selected targets, frames, sessions,
Observations, refs, auth, rules, and request identity remain only in daemon

@@ -276,3 +278,4 @@ memory. No `state.json` or `refs.json` compatibility mapping remains.

client counts. Protected compare-and-stop shutdown rejects mismatched
executables and returns `broker_in_use` while embedded Connections remain.
executables and returns `broker_in_use` while embedded Connections or any
active Lease remains.
Owner-only version history retains only current/previous executable metadata

@@ -295,3 +298,7 @@ and no transient browser state. `BROWSER_PILOT_HOME` provides explicit

remains explicit. Release CI uses fixed official Node 22.17.0 native runners
and verifies every artifact before publishing it.
and verifies every artifact before publishing it. The supported native
matrix is Apple Silicon macOS, x64 Linux, and x64 Windows; Intel Mac is not
supported. A versioned release index binds these assets to the npm package,
exact Agent plugin/skill version, protocol range, and checksums, and GitHub
Release publication waits for npm publication.

@@ -324,2 +331,8 @@ ### A7. Agent-neutral integration kit

- Covers: FR-1, AC-1.
- Complete: the main skill is a bounded operating guide with progressive
command/stdio references, version-range CLI compatibility checking, stable
one-shot error recovery, explicit user-tab/Profile/tab-group boundaries,
local capture semantics, and generated Codex UI metadata. Release
verification and a machine-readable skill compatibility manifest prevent
silent CLI/skill version drift.

@@ -326,0 +339,0 @@ ## Cross-Workstream Dependencies

# Browser Pilot v0.3.0 Stabilization Plan
Status: **In progress**
Candidate baseline: `v0.3.0-rc.6`; release target: `v0.3.0`, protocol `1.2`
Status: **Complete**
Released baseline: `v0.3.0`, protocol `1.2`

@@ -51,3 +51,7 @@ ## Goal

and managed-only cleanup. User tabs and exported files were preserved.
- [ ] Tag `v0.3.0`, publish npm `latest`, and verify upgrade/rollback metadata.
- [x] Tag `v0.3.0`, publish a non-prerelease GitHub Release and npm
`latest=0.3.0`, and retain `next=0.3.0-rc.6` plus the local RC.6 standalone
as rollback paths. The installed stable executable connected through one
authorization request and repeated managed open/cleanup with
`closed: 1, remaining: 6`; all six user tabs remained available.

@@ -68,2 +72,4 @@ ## Stable decision

standalone now satisfies every pre-stable source, distribution, Host, and live
Chrome gate above. Stable publication remains a separate explicit release step.
Chrome gate above. The identical stable runtime passed the complete source and
distribution gates, published successfully on all three platforms, and passed
the installed user-Chrome smoke check.
{
"name": "browser-pilot-cli",
"version": "0.3.0",
"version": "0.4.0",
"description": "CLI tool to control your browser via Chrome DevTools Protocol",

@@ -17,2 +17,7 @@ "repository": "https://github.com/relixiaobo/browser-pilot",

"package:standalone": "node scripts/package-standalone.mjs",
"package:agent-plugin": "node scripts/package-agent-plugin.mjs",
"package:release-index": "node scripts/build-release-index.mjs",
"release:sync-version": "node scripts/sync-release-version.mjs",
"release:check-version": "node scripts/sync-release-version.mjs --check",
"version": "node scripts/sync-release-version.mjs",
"verify:standalone": "node scripts/verify-standalone.mjs",

@@ -48,9 +53,3 @@ "dev": "tsup --watch",

"docs/plans/universal-agent-integration.md",
"docs/releases/v0.3.0-rc.1.md",
"docs/releases/v0.3.0-rc.2.md",
"docs/releases/v0.3.0-rc.3.md",
"docs/releases/v0.3.0-rc.4.md",
"docs/releases/v0.3.0-rc.5.md",
"docs/releases/v0.3.0-rc.6.md",
"docs/releases/v0.3.0.md",
"docs/releases/",
"README.md",

@@ -57,0 +56,0 @@ "LICENSE"

+90
-27

@@ -6,5 +6,12 @@ # browser-pilot

```bash
npm install -g browser-pilot-cli
npm install -g browser-pilot-cli@latest
bp --version
```
Each skill/plugin release declares a supported CLI range and the exact version
it was tested with. Newer CLI releases remain usable within that range;
embedded products should pin the tested version for reproducible builds.
The native release targets Apple Silicon macOS, x64 Linux, and x64 Windows;
Intel Mac is not supported.
## Agent Setup

@@ -33,4 +40,8 @@

One connection covers every live Chrome Profile on that endpoint. When several
Profiles are open, `bp connect` lists them without creating a Pilot window; use
`bp profiles` and `bp profile <index>`, or pass `--profile` to `bp open --new`.
Profiles are open, `bp connect` lists them without creating a Pilot window. Use
the passive `bp profiles` inventory first. Run `bp profiles --identify` only
when account-aware names are needed; it briefly opens and closes one visible
`chrome://version` page per unidentified Profile. Profile and tab indexes are
one-based. Select with `bp profile <index>`, or pass `--profile` to
`bp open --new`.

@@ -47,3 +58,3 @@ ### 2. Install the plugin for your agent

```bash
npx skills add relixiaobo/browser-pilot
npx skills add relixiaobo/browser-pilot --skill browser-pilot
```

@@ -58,3 +69,3 @@

```bash
npx skills add relixiaobo/browser-pilot
npx skills add relixiaobo/browser-pilot --skill browser-pilot
```

@@ -76,3 +87,3 @@

- **Real login sessions** — Operates your actual browser profile. Cookies, extensions, logins all intact
- **Multi-Profile routing** — Lists user tabs across live Chrome Profiles and creates managed work only in a resolved Profile
- **Multi-Profile routing** — Lists user tabs across live Chrome Profiles, explicitly verifies account-aware Profile identity, and creates managed work only in a resolved Profile
- **CLI-native** — Any agent with bash access can use it. No MCP protocol, no SDK integration needed

@@ -110,5 +121,5 @@ - **Auto-snapshot** — Every action returns page state with numbered `[ref]` elements, so the agent always knows what's on screen

Chrome (your browser, your profile)
├── Your windows (untouched)
└── Pilot window (agent operates here)
Chrome (your browser, your Profiles)
├── Eligible user tabs (selectable)
└── Managed windows (Broker-owned)
```

@@ -119,4 +130,5 @@

to the daemon. It also owns only Browser Pilot-created tabs so it can clean them
after a Broker crash without touching user-opened tabs. A pulsing blue glow
around a Pilot window indicates Agent activity.
after a Broker crash without touching user-opened tabs. Controller identity is
returned to the embedding Host; Browser Pilot never injects a status border or
other control UI into the page DOM.

@@ -154,3 +166,4 @@ ## Platform Evolution

dispatch, event replay, protected Artifacts, protocol 1.1 transport limit
negotiation, and protocol 1.2 Chrome Profile routing are implemented. Browser
negotiation, protocol 1.2 Chrome Profile routing, and protocol 1.3 verified
Profile identity and unambiguous result vocabulary are implemented. Browser
disconnect and explicit reconnect handling, scoped

@@ -172,3 +185,4 @@ download Artifacts, Workspace resource isolation, and typed watchdog events for

Compatible Agent products reuse one per-user Broker through protocol
negotiation. Protected shutdown cannot terminate live embedded clients, and an
negotiation. Protected shutdown cannot terminate live embedded clients or
another CLI Agent's active Lease, and an
incompatible product must explicitly select a separate `BROWSER_PILOT_HOME`.

@@ -185,3 +199,4 @@ Global npm installation, local npm/npx use, and product-bundled absolute-path

```bash
npm install -g browser-pilot-cli
npm install -g browser-pilot-cli@latest
bp --version
bp connect

@@ -195,3 +210,3 @@ bp tabs

```bash
npm install --save-exact browser-pilot-cli@0.3.0
npm install --save-exact browser-pilot-cli@latest
npx --no-install browser-pilot tabs

@@ -213,2 +228,8 @@ ```

The same GitHub release also contains
`browser-pilot-plugin-<version>.tgz`, its checksum, and a versioned release index
that binds the npm version, protocol range, compatible skill/plugin range,
tested CLI version, and the three supported native assets. Consumers should
verify that index before bundling. No `darwin-x64` asset is produced.
All three forms use the same protocol and compatible per-user Broker. Use a

@@ -218,2 +239,15 @@ distinct absolute `BROWSER_PILOT_HOME` only when a product deliberately needs

Products embedding `bridge --stdio` already receive isolated Connections,
Workspaces, and Leases. When several independent Agents instead invoke the
one-shot CLI directly, assign each integration a distinct stable namespace:
```bash
BROWSER_PILOT_CLIENT_KEY=agent.product.install-01 bp tabs
bp --client-key agent.product.install-01 snapshot
```
Repeated commands with the same key reuse that Agent's selected target, frame,
refs, auth, and network state. Different keys cannot overwrite one another.
The default key remains `browser-pilot-cli` for a single interactive Agent.
## Commands

@@ -266,4 +300,6 @@

user opened elsewhere across all live Profiles in the same browser endpoint.
Each JSON entry includes its opaque `profileContextId`; `bp tab <n>` switches
control to any listed tab.
Extension-owned and browser-internal pages are excluded. Each JSON entry
includes its opaque `profileContextId`; `bp tab <n>` selects any listed tab for
the current Agent Lease. Its `selected` field is not a claim about Chrome's
foreground tab or operating-system focus.

@@ -288,7 +324,8 @@ ### Network

| `bp connect` | Connect to Chrome; create a Pilot window immediately only when Profile routing is unambiguous |
| `bp disconnect` | Close the CLI Pilot window; stop the daemon when no embedded client is live |
| `bp profiles` | List live Chrome Profile contexts and representative tabs |
| `bp profile <index\|id\|label\|name>` | Select a Profile for subsequent managed tabs |
| `bp disconnect` | Release this CLI namespace; stop the daemon only when no other client or active Lease is live |
| `bp profiles` | Passively list live Chrome Profile contexts and representative tabs |
| `bp profiles --identify [--refresh]` | Explicitly verify Profile/account identity using temporary visible Chrome pages |
| `bp profile <index\|id\|label\|name\|email>` | Select a Profile for subsequent managed tabs |
| `bp tabs` | List all controllable tabs in the current browser |
| `bp tab <n>` | Switch to any listed managed or user tab |
| `bp tab <n>` | Select any listed managed or user tab for the current Agent Lease |
| `bp close` | Close the current tab (`--all` closes Pilot-managed tabs only) |

@@ -318,6 +355,8 @@

Across one-shot CLI processes, active target, frame, and refs live only in the
Across one-shot CLI processes, selected target, frame, and refs live only in the
daemon's keyed compatibility Workspace and renewable Lease. They are never
written to `state.json` or `refs.json`; after Lease expiry the Agent must
observe again. `bp disconnect` explicitly clears the compatibility Workspace.
observe again. Set a distinct stable `BROWSER_PILOT_CLIENT_KEY` for each Agent
that directly invokes the CLI. `bp disconnect` clears only that namespace and
stops the Broker only when no other active Lease or embedded client remains.

@@ -332,7 +371,10 @@ ## Output

Errors include hints:
Machine errors include stable codes and may include hints or remediation:
```json
{"ok":false, "error":"Ref [99] not found.", "hint":"Run 'bp snapshot' to refresh element refs."}
{"ok":false,"error":"Ref [99] is stale.","code":"stale_ref","retryable":false,"context":{"field":"ref"},"hint":"Run 'bp snapshot' to refresh element refs."}
```
Branch on `code`, not English text. `retryable` means a later call may be valid;
it does not make the same uncertain mutation safe to replay.
Force human output: `bp --human open https://example.com`

@@ -399,6 +441,8 @@

For `<select>` dropdowns (shown as `combobox`), use `bp eval`:
For `<select>` and exposed ARIA dropdowns, inspect and select with the dedicated
commands:
```bash
bp eval 'document.querySelector("select").value = "opt2"; document.querySelector("select").dispatchEvent(new Event("change",{bubbles:true}))'
bp dropdown 4
bp select 4 "Option 2"
```

@@ -467,2 +511,20 @@

For a new release, bump only the root package version through npm. The npm
`version` lifecycle synchronizes every active distribution manifest from that
source of truth:
```bash
npm version "$BROWSER_PILOT_RELEASE_VERSION" --no-git-tag-version
npm run release:check-version
node scripts/verify-release-version.mjs
```
The sync step updates the lockfile root, Agent plugin version and CLI peer
range, Claude plugin/marketplace manifests, and skill `compatibility.json`.
The current release becomes the skill's tested/minimum CLI version while the
upper bound remains the next major version. Browser Pilot keeps public one-shot
commands backward compatible within a major line, including additive `0.x`
releases before 1.0. Historical release notes and version-specific fixtures are
never rewritten.
The canary report is written to

@@ -478,2 +540,3 @@ `test-results/real-site-canary/report.json`. It distinguishes semantic drift,

- Remote debugging enabled (`chrome://inspect/#remote-debugging`)
- Native archives: Apple Silicon macOS, x64 Linux, or x64 Windows; no Intel Mac

@@ -480,0 +543,0 @@ ## License

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display