🎩 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.2.2
to
0.3.0-rc.1
+197
docs/plans/profile-context-routing.md
# Profile Context Routing Plan
Status: **In progress**
Target: Browser Pilot `v0.3.0`, protocol `1.2`
Source of truth: `docs/architecture/browser-pilot-platform-spec.md`
## Goal
Make one Browser Pilot connection correctly inventory and control ordinary tabs
from every live Chrome Profile context, while ensuring every new managed target
is created in an explicitly resolved Profile context. The design remains
Agent-neutral, extension-free, transient, and compatible with existing
single-Profile CLI workflows.
## Real Chrome Findings
The implementation contract is based on a read-only and transient-target probe
against a user-authorized Chrome endpoint:
- one browser-level CDP endpoint exposed two ordinary Profile contexts and all
eligible tabs from both contexts;
- ordinary Profile contexts were present on `TargetInfo.browserContextId` but
absent from `Target.getBrowserContexts`;
- `Target.createTarget({ browserContextId })` was not reliable for ordinary
Profile contexts and could return `Failed to find browser context`;
- dispatching `Target.createTarget` through a target session did not inherit the
target's Profile context;
- an isolated-world `window.open` with `userGesture: true` created a target in
the representative tab's exact Profile context;
- popup window features created a separate normal Chrome window, and subsequent
`Target.createTarget({ windowId })` calls stayed in that Profile context;
- a temporary `chrome://version` target could map a runtime context to Chrome
`Local State`, but doing that is user-visible and therefore is not permitted
during passive Profile discovery.
No production logic may assume behavior contradicted by these findings.
## Model
### BrowserEndpoint
The existing `BrowserInstance` represents one running Chromium browser endpoint:
product/channel, user-data root, CDP endpoint, process identity, connection
generation, and connection state. A Chrome Profile directory is not a separate
BrowserInstance when it shares that endpoint.
### ProfileContext
A `ProfileContext` is one live regular browser context observed on an endpoint.
It has:
- a public `profileContextId`, opaque to clients;
- an internal raw CDP browser-context ID, never exposed;
- the owning BrowserInstance and connection generation;
- a connection-scoped neutral label;
- an optional verified display name and Profile directory;
- current total and eligible tab counts;
- one or more bounded representative targets for routing and user recognition.
`profileContextId` is valid only for its browser connection generation. The
Broker retains stale public IDs long enough to return `profile_context_stale`,
but never routes them to a new raw context.
### Workspace Selection
`BrowserWorkspace.selectedProfileContextId` is transient Broker memory. It is
updated by explicit selection and by switching to a target whose context is
known. It is never written as a global default and is cleared logically by
browser reconnect because the old ID becomes stale.
### ManagedTabSet Binding
Each ManagedTabSet is permanently bound to at most one ProfileContext. A
Workspace may own multiple ManagedTabSets, one per Profile context used for
managed work. The first target binds an unbound set; opening managed work in a
different context creates another set. Workspace cleanup closes every managed
set and still leaves user tabs open.
### ControlledTarget Context
Every managed, managed-popup, and user target records a public
`profileContextId`. Popup adoption requires the popup context to equal its
managed ancestor's ManagedTabSet context.
## Protocol 1.2
Protocol 1.2 adds:
- `browser.profiles.list`;
- `browser.profiles.select`;
- optional `profileContextId` input on `browser.open`;
- `profileContextId` on every `browser.tabs.list` target;
- selected Profile context on Workspace results;
- Profile context binding on ManagedTabSet results;
- `profile_selection_required`, `profile_context_stale`, and
`profile_context_unavailable` stable errors.
`browser.profiles.list` is a Workspace-scoped read-only tool. It returns bounded
Profile summaries and representative eligible tabs. It never opens, navigates,
attaches to, or focuses a target merely to discover a display name.
`browser.profiles.select` accepts only a public `profileContextId`. Human CLI
selectors such as index, neutral label, or verified display name 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
anchor without releasing control or changing Chrome focus, so the next new
managed target uses that explicit Workspace selection.
## Selection Algorithm
When `browser.open` needs a new target, resolve exactly one Profile context in
this order:
1. an explicit, current-generation `profileContextId`;
2. the current Lease's active target context;
3. the Workspace's current, valid selection;
4. the only currently available Profile context;
5. otherwise fail with `profile_selection_required` before browser dispatch.
Listing or controlling an existing target never requires prior Profile
selection. Supplying `profileContextId` while navigating an existing target is
valid only when it equals that target's context; Browser Pilot never moves a
physical target between Profiles.
`profile_selection_required` contains only bounded Profile summaries. It is a
normal structured result for an Agent host to turn into a user question. Direct
CLI JSON mode exits without reading interactive stdin.
## Managed Target Creation
Creation is serialized by Workspace/Profile context and remains owned by the
managed-target janitor:
1. If the context's ManagedTabSet already has a live window ID, create
`about:blank` with that `windowId` and verify the returned target context.
2. For the first target, try browser-level creation with `newWindow: true` and
the raw browser-context ID. Verification is mandatory because Chrome support
varies by regular Profile context.
3. If Chrome rejects or misroutes that call, attach to a bounded representative
page target in the selected context, create an isolated world, and call
`window.open("about:blank", "_blank", <fixed popup window features>)` with a
debugger user gesture.
4. Identify exactly one new target by the pre-dispatch target set, opener ID,
Profile context, page type, and blank URL. Ambiguous or mismatched targets are
closed and the operation fails.
5. Explicitly adopt the verified target into the janitor before registering it
publicly, so Broker crash cleanup still closes it.
6. Read and retain its window ID, bind the ManagedTabSet, register the opaque
target, then navigate through the normal target actor.
The fallback does not execute page-defined JavaScript, inject DOM content, read
page data, or navigate the representative user tab. It may cause ordinary
focus/blur effects inherent to Chrome opening a new window. Failure after any
possible target creation returns `unknown_outcome` unless the Broker proves all
candidate targets were closed.
## Compatibility
- Protocol 1.0/1.1 clients continue to list and control existing tabs.
- In a single available context, their existing `browser.open` behavior remains
automatic.
- In multiple contexts, an active target remains an unambiguous anchor.
- With multiple contexts and no anchor, older clients receive a structured
failure and Browser Pilot never silently chooses the first context.
- New Profile fields on existing results are additive; raw CDP IDs remain
private.
- The current CLI negotiates protocol 1.2, while the Broker continues to accept
1.0 and 1.1.
## Delivery
- [x] P0: probe ordinary multi-Profile Chrome behavior.
- [x] P1: freeze model, protocol, selection, and creation rules.
- [x] P2: implement Profile context registry, target propagation, Workspace
selection, multiple ManagedTabSets, and janitor adoption.
- [x] P3: implement `bp profiles`, `bp profile`, and `bp open --profile`.
- [x] P4: update stdio integration guidance, adapters, skill, and release docs.
- [x] P5: add protocol, dual-Profile, concurrency, reconnect, cleanup, and
compatibility tests.
- [ ] P6: run real Chrome acceptance and publish `v0.3.0-rc.1`.
## Acceptance
- All eligible user tabs across live Profile contexts appear in one inventory.
- Existing user tabs can be controlled without selecting a Profile first.
- No multi-context open silently selects a first Profile.
- Explicit, active-target, Workspace, and single-context resolution follow the
specified order.
- Every managed target and popup matches its ManagedTabSet Profile context.
- Two Workspaces may select different contexts and create targets concurrently
without cross-routing.
- Reconnect invalidates old Profile IDs, target mappings, frames, and refs.
- Passive listing creates no target and never focuses or navigates a user tab.
- Janitor EOF/SIGKILL cleanup closes fallback-created managed windows but never
user tabs.
- Protocol 1.1 clients retain existing-tab control and cannot open ambiguously.
- Single-Profile CLI and fixture behavior remains compatible.
# Browser Pilot 0.3.0-rc.1
This release candidate adds extension-free multi-Profile routing on one
authorized Chrome endpoint. Browser Pilot now inventories eligible user tabs
from every live Profile context and keeps those tabs directly controllable.
Profile selection is used only to place new managed work; it is not a permission
grant and does not require another Chrome Allow dialog.
Protocol 1.2 adds `browser.profiles.list`, `browser.profiles.select`, opaque
connection-generation-scoped `profileContextId` values, per-Profile
ManagedTabSets, and structured selection/staleness errors. Protocol 1.0 and 1.1
clients retain existing-tab control and never silently choose the first Profile
when new-target routing is ambiguous.
The CLI adds `bp profiles`, `bp profile <selector>`, and
`bp open --new --profile <selector>`. On a multi-Profile connection, `bp connect`
returns the live choices without opening an arbitrary Pilot window. Existing
single-Profile setup and direct Agent installation remain compatible.
Managed creation first verifies Chrome's returned Profile context. When regular
Profile contexts reject direct CDP creation, Browser Pilot uses a marked
isolated-world `window.open`, verifies its opener, URL, type, and Profile, then
adopts it into crash cleanup before public registration. Misrouted targets are
closed and verified absent; uncertain creation returns `unknown_outcome` and is
never automatically retried.
The stdio reference adapters now negotiate protocol 1.2, so Tenon, OpenClaw,
and other Agent products receive Profile tools through the same runtime manifest
without a Native SDK, MCP server, extension, or product-specific Browser Pilot
code.
This is an RC. The release gate includes protocol compatibility, dual-Profile
fault injection, CLI process tests, full unit and browser suites, stdio
conformance, distribution checks, and a controlled real Chrome acceptance run.
Automated release gates completed before tagging:
- TypeScript type checking passed.
- 264 Node unit, protocol, process, and adapter tests passed.
- 109 isolated Playwright core, compatibility, and network tests passed.
- The black-box stdio conformance suite passed all 13 checks.
- npm distribution verification passed for global, local project, and
product-bundled executable modes.
- The npm dry-run package contains the Profile routing plan and this release
note.
The controlled real Chrome dual-Profile acceptance is performed after installing
the published RC so it exercises the same package and Codex skill path available
to users.
+6
-1

@@ -293,2 +293,3 @@ // src/cdp.ts

const windowId = params.windowId;
const browserContextId = params.browserContextId;
if (newWindow === (windowId !== void 0)) throw new Error("Exactly one managed target window selector is required");

@@ -298,5 +299,9 @@ if (windowId !== void 0 && (!Number.isSafeInteger(windowId) || Number(windowId) < 0)) {

}
if (browserContextId !== void 0 && (typeof browserContextId !== "string" || browserContextId.length === 0 || browserContextId.length > 1024)) {
throw new Error("Invalid managed target browser context ID");
}
const created = await cdp.send("Target.createTarget", {
url: "about:blank",
...newWindow ? { newWindow: true } : { windowId }
...newWindow ? { newWindow: true } : { windowId },
...browserContextId ? { browserContextId } : {}
});

@@ -303,0 +308,0 @@ if (typeof created?.targetId !== "string" || created.targetId.length === 0) {

@@ -174,12 +174,23 @@ # Browser Pilot Platform Specification

One running, discoverable Chromium-family browser process identified by a
process-stable identity, product, profile path, debugging endpoint, and
connection generation.
One running, discoverable Chromium-family browser endpoint identified by a
process-stable identity, product, user-data root, debugging endpoint, and
connection generation. One endpoint may expose several simultaneously live
Chrome Profile contexts; those are not separate BrowserInstances.
### ProfileContext
One live regular browser context inside a BrowserInstance. Its public
`profileContextId` is opaque and scoped to the current browser connection
generation; the raw CDP browser-context ID is internal. A ProfileContext has a
connection-scoped neutral label, optional verified display metadata, bounded
representative tabs, and current tab counts. Passive discovery never opens a
tab to infer its display name. Reconnect invalidates every ProfileContext ID.
### BrowserWorkspace
A logical browser working set owned by one ClientPrincipal. It owns one or more
ManagedTabSets and transient scoped state. Workspaces live in Broker memory by
default and are recreated after Broker restart; Agent adapters map their own
active lifecycle to this object.
ManagedTabSets, an optional selected ProfileContext, and transient scoped state.
Workspaces live in Broker memory by default and are recreated after Broker
restart; Agent adapters map their own active lifecycle to this object. Profile
selection is never persisted as a global browser default.

@@ -191,4 +202,6 @@ ### ManagedTabSet

does not use extension-only native tab-group APIs. New task navigation and
owned popups stay in this set by default. Workspace cleanup may close this set,
but never user-owned tabs outside it.
owned popups stay in this set by default. A ManagedTabSet is permanently bound
to at most one ProfileContext; a Workspace that creates managed work in multiple
Profiles owns one set per Profile. Workspace cleanup may close these sets, but
never user-owned tabs outside them.

@@ -212,3 +225,4 @@ ### ControlLease

A target addressable by a Workspace. Its origin is `managed`, `managed_popup`,
or `user_tab`, and it records an optional ManagedTabSet. A user tab retains user
or `user_tab`, and it records its ProfileContext and an optional ManagedTabSet.
A user tab retains user
ownership: releasing a Workspace removes Broker mappings without closing the

@@ -403,2 +417,19 @@ tab. Every result identifies its Workspace, Lease, opaque controlled-target ID,

### FLOW-6 Multiple live Chrome Profiles
`browser.tabs.list` inventories eligible tabs from every Profile context exposed
by the selected BrowserInstance. Existing targets are immediately controllable
and carry an opaque `profileContextId`. New managed work resolves a Profile from
an explicit context, the current active target, the Workspace selection, or a
single available context, in that order. Multiple contexts without an anchor
return `profile_selection_required` before creating a target. The Agent host
asks the user which Profile to use; Browser Pilot does not add an approval UI.
`browser.profiles.list` is passive and returns bounded, connection-scoped
summaries. `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
does not release control, activate a tab, or change Chrome focus. The exact
creation and compatibility algorithm is frozen in `docs/plans/profile-context-routing.md`.
## Machine Protocol

@@ -455,2 +486,8 @@

Protocol 1.2 adds connection-generation-scoped ProfileContext discovery and
selection, Profile identity on tab inventory, and context-aware managed target
creation. Protocol 1.0/1.1 clients retain existing-target control and automatic
single-context behavior, but an ambiguous multi-context open fails rather than
silently selecting a Profile.
### Tool Contract

@@ -574,2 +611,18 @@

explicit target-specific close command.
- **BR-29:** Runtime Profile contexts are discovered from live target metadata,
not only `Target.getBrowserContexts`. Public ProfileContext IDs never expose
raw CDP identifiers and are invalid after browser reconnect.
- **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,
Workspace selection, then single available context. Multiple unanchored
contexts fail with `profile_selection_required` before browser dispatch.
- **BR-32:** Every ManagedTabSet is bound to at most one ProfileContext. Managed
target creation verifies the returned context before public registration, and
fallback-created targets enter janitor ownership before they become
addressable.
- **BR-33:** Switching to an existing target may update the owning Workspace's
selected ProfileContext, but never prevents inventory or control of targets
in other Profiles. No Profile selection is a permission grant.

@@ -791,6 +844,11 @@ ## Command Reliability

Discovery returns every supported local browser candidate with product,
channel, profile, process state, remote-debugging state, authorization state,
channel, user-data root, process state, remote-debugging state, authorization state,
and structured remediation. It does not silently select the first filesystem
match when several viable instances exist.
After connection, Profile discovery separately returns every live regular
Profile context on that endpoint. Browser candidates and Profile contexts are
different layers: selecting Chrome Stable does not silently select one of its
simultaneously open Profiles.
The client may select an instance explicitly or use a deterministic persisted

@@ -834,2 +892,3 @@ preference. Setup that requires Chrome UI remains a user-visible action. Browser

broker_in_use
profile_selection_required profile_context_stale profile_context_unavailable
workspace_not_found lease_expired target_not_owned

@@ -911,4 +970,10 @@ target_busy stale_ref command_cancelled

- **AC-8:** Observation and action conformance tests pass against the public
tool interface, including frame, navigation, stale-ref, obstruction, and
input readback cases.
tool interface, including frame, navigation, stale-ref, obstruction, and
input readback cases.
- **FR-9 Multi-Profile routing:** One endpoint can expose all eligible tabs from
multiple live Chrome Profiles without ambiguous new-target placement.
- **AC-9:** Existing tabs remain directly controllable; every tab result has a
connection-scoped ProfileContext ID; ambiguous open returns
`profile_selection_required`; explicit or inferred routing is verified; and
reconnect requires relisting rather than reusing stale Profile IDs.

@@ -961,2 +1026,8 @@ ## Non-Functional Requirements

private child roles, and archive checksums on each target platform.
8. Multi-Profile tests cover passive discovery, explicit and inferred
selection, multiple ManagedTabSets, direct-create fallback, janitor adoption,
concurrent Workspace routing, reconnect invalidation, and protocol 1.1
ambiguous-open failure. Real Chrome acceptance verifies at least two live
Profiles on one endpoint without reconnecting or requesting authorization
again.

@@ -963,0 +1034,0 @@ ## Implementation Boundary

@@ -108,3 +108,3 @@ # Stdio Bridge Integration Contract

```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":1}},"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":2}},"requestedCapabilities":["browser.control","workspace.manage","observation.read","action.input","artifact.read","event.read"],"launchMode":"embedded","limits":{"maxMessageBytes":1048576,"maxResultBytes":4194304}}}
```

@@ -131,2 +131,8 @@

Protocol 1.2 adds connection-scoped Chrome Profile routing. It exposes
`browser.profiles.list`, `browser.profiles.select`, and `profileContextId` on
tab inventory and new-target operations. Protocol 1.0/1.1 clients retain their
existing tools; the Broker hides 1.2-only operations and rejects a manually
constructed Profile call with `protocol_incompatible`.
The initialize request and response use the service's fixed bootstrap limits.

@@ -174,7 +180,9 @@ The bridge switches limits only after the successful response has been written,

stable-order browser binding. It returns a Workspace, its default logical
ManagedTabSet, and an `eventCursor`. `workspaces/get` returns the current cursor
as a recovery baseline. Creating a Workspace does not itself create a browser
ManagedTabSet, the complete `managedTabSets` array, and an `eventCursor`.
`workspaces/get` also returns the Workspace's transient
`selectedProfileContextId` when one is selected and the current cursor as a
recovery baseline. Creating a Workspace does not itself create a browser
connection or window. Call the Workspace-scoped `browser.connect` tool to
request Chrome authorization; the first managed navigation then creates the
dedicated browser window.
dedicated browser window in its resolved Profile context.

@@ -249,2 +257,39 @@ `leases/create` accepts a `workspaceId` and optional `ttlMs`. Protocol 1.1

### Chrome Profile routing
One connected Chrome endpoint may expose ordinary tabs from several live
Profiles. Browser Pilot authorizes the endpoint once; it does not reconnect or
show another Chrome Allow dialog per Profile. `browser.tabs.list` returns every
eligible managed and user-opened tab across those contexts, each with an opaque
`profileContextId`. Existing tabs can be selected and controlled immediately;
Profile selection is routing for new managed targets, not a permission grant.
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
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
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.
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
target, the Workspace selection, or the only available context, in that order.
`browser.profiles.select` clears only the logical active-target anchor so its
selection applies to the next new managed target; it does not release control,
activate a user tab, or change Chrome focus.
With multiple unanchored contexts, `browser.open` fails before browser dispatch
with `profile_selection_required`. Relist on `profile_context_stale`; on
`profile_context_unavailable`, follow its setup remediation. An
`unknown_outcome` during Profile-window creation means Chrome may have created
a target that Browser Pilot could not prove absent; list tabs and Profiles and
inspect current state before deciding whether to retry.
`browser.click` returns a new Observation plus bounded evidence. For example,

@@ -414,4 +459,4 @@ a checkbox may return:

tools to fail with retryable `browser_disconnected`. The daemon passively
refreshes the originally selected profile's endpoint metadata and does not
switch profiles or open a WebSocket. The host calls `browser.connect` when it is
refreshes the selected browser endpoint metadata and does not select a Profile
context or open a WebSocket. The host calls `browser.connect` when it is
ready to request reconnection. `connection.restored` then carries a strictly

@@ -578,3 +623,3 @@ newer generation. Existing Workspaces

The shared example launches an absolute executable path without a shell,
negotiates protocol 1.1, discovers tools at runtime, and maps a host work scope
negotiates protocol 1.1 through 1.2, discovers tools at runtime, and maps a host work scope
to a Workspace plus its active invocation to a renewable Lease. It never stores

@@ -604,3 +649,3 @@ an active tab, frame, Observation, ref, credential, rule, Artifact, or event

result validation, and production filtering prevents unwired tools from being
advertised. The current bridge supports discovery, connect, open, all-tab
advertised. The current bridge supports discovery, connect, Profile routing, open, all-tab
inventory, observe/read/search/find, scroll and dropdown actions, annotated

@@ -607,0 +652,0 @@ screenshots, core actions, scoped frames, explicit dialogs, cookies, auth,

+3
-1
{
"name": "browser-pilot-cli",
"version": "0.2.2",
"version": "0.3.0-rc.1",
"description": "CLI tool to control your browser via Chrome DevTools Protocol",

@@ -43,3 +43,5 @@ "repository": "https://github.com/relixiaobo/browser-pilot",

"docs/plans/browser-capability-evolution.md",
"docs/plans/profile-context-routing.md",
"docs/plans/universal-agent-integration.md",
"docs/releases/v0.3.0-rc.1.md",
"README.md",

@@ -46,0 +48,0 @@ "LICENSE"

@@ -31,2 +31,5 @@ # browser-pilot

--browser <selector>`; otherwise selection follows a stable platform order.
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`.

@@ -70,2 +73,3 @@ ### 2. Install the plugin for your agent

- **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
- **CLI-native** — Any agent with bash access can use it. No MCP protocol, no SDK integration needed

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

The `browser-pilot bridge --stdio` transport, Broker lifecycle, browser tool
dispatch, event replay, protected Artifacts, and protocol 1.1 transport limit
negotiation are implemented. Browser disconnect and explicit reconnect handling, scoped
dispatch, event replay, protected Artifacts, protocol 1.1 transport limit
negotiation, and protocol 1.2 Chrome Profile routing are implemented. Browser
disconnect and explicit reconnect handling, scoped
download Artifacts, Workspace resource isolation, and typed watchdog events for

@@ -183,3 +188,3 @@ stalled navigation, selected-frame detach, pending dialogs, and repeated

```bash
npm install --save-exact browser-pilot-cli@0.2.2
npm install --save-exact browser-pilot-cli@0.3.0-rc.1
npx --no-install browser-pilot tabs

@@ -212,2 +217,3 @@ ```

| `bp open <url>` | snapshot | Navigate to URL |
| `bp open <url> --new --profile <selector>` | snapshot | Create managed work in one live Chrome Profile |
| `bp snapshot` | snapshot | Get interactive elements |

@@ -251,4 +257,5 @@ | `bp read [selector]` | text | Get bounded readable page/region content |

Run `bp tabs` to list Pilot-managed tabs, their popups, and eligible tabs the
user opened elsewhere in the same browser. `bp tab <n>` switches control to any
listed tab.
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.

@@ -272,4 +279,6 @@ ### Network

|---------|-------------|
| `bp connect` | Connect to Chrome, create pilot window |
| `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 tabs` | List all controllable tabs in the current browser |

@@ -276,0 +285,0 @@ | `bp tab <n>` | Switch to any listed managed or user tab |

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

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