browser-pilot-cli
Advanced tools
| # 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. |
@@ -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" |
+15
-6
@@ -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
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
1027985
6.09%14
16.67%20477
4.64%462
1.99%39
-2.5%