browser-pilot-cli 0.1.6 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,337 @@
1
+ # Universal Agent Integration Plan
2
+
3
+ Status: **Complete**
4
+ Source of truth: `docs/architecture/browser-pilot-platform-spec.md`
5
+ Workstream: A
6
+
7
+ ## Goal
8
+
9
+ Deliver the executable, Broker, machine protocol, distribution contract, and
10
+ conformance assets required for any local Agent to install or embed Browser
11
+ Pilot. Tenon and OpenClaw are reference consumers only.
12
+
13
+ ## Scope Guardrails
14
+
15
+ - Preserve existing one-shot CLI workflows under **FR-1**.
16
+ - Expose only the executable protocol under **DEC-3**; do not publish a Native
17
+ SDK or MCP server.
18
+ - Do not place Agent-specific lifecycle nouns or payloads in production code.
19
+ - Do not improve page understanding in this workstream except where needed to
20
+ preserve the shared Observation contract.
21
+ - Coordinate all changes to Observation/ref identity with Workstream B.
22
+ - Keep Broker-created ManagedTabSets as the default independent task surface,
23
+ while including every eligible user tab in the same inventory. Never add an
24
+ Agent-callable raw-CDP `adopt(targetId)` shortcut.
25
+
26
+ ## Delivery Order
27
+
28
+ ### A0. Freeze the shared contract
29
+
30
+ - [x] **A0.1** Publish the platform specification with stable decisions,
31
+ requirements, rules, and acceptance criteria.
32
+ - Covers: DEC-1 through DEC-7, FR-1 through FR-8.
33
+ - Verification: product-spec inspection and contradiction review.
34
+ - [x] **A0.2** Encode protocol versions, capabilities, domain identifiers,
35
+ result envelopes, stable errors, and Artifact/Event descriptors as internal
36
+ TypeScript types and runtime validators.
37
+ - Covers: FR-2, FR-5, FR-6, FR-7.
38
+ - Acceptance: incompatible versions and malformed messages fail with stable
39
+ codes; unknown fields follow the compatibility rules.
40
+ - [x] **A0.3** Publish the canonical machine-readable tool manifest and schema
41
+ snapshots used by bridge and conformance tests.
42
+ - Covers: FR-2, NFR-1.
43
+ - Acceptance: `tools/list` output is generated from the same definitions used
44
+ to validate `tools/call`.
45
+
46
+ ### A1. Extract the internal service boundary
47
+
48
+ - [x] **A1.1** Move browser discovery, target operations, observations,
49
+ actions, capture, network, auth, and cookies out of Commander handlers into
50
+ `BrowserPilotService` modules.
51
+ - Covers: FR-1, FR-2.
52
+ - Acceptance: CLI handlers contain parsing and formatting only; existing CLI
53
+ fixture behavior remains unchanged.
54
+ - Complete: every Commander handler now performs only parsing, compatibility
55
+ formatting, and explicit client-owned file export. Browser discovery,
56
+ target/session/frame state, observations, actions, capture, upload, tabs,
57
+ dialogs, auth, cookies, and network operations execute through the same
58
+ canonical Broker tools used by embedded clients.
59
+ - [x] **A1.2** Replace process exits and console/file side effects below the CLI
60
+ adapter with typed results, stable errors, and Artifact operations.
61
+ - Covers: FR-2, FR-6, NFR-1.
62
+ - Complete: protected screenshot/PDF/upload bytes cross the CLI boundary only
63
+ through Artifact import/export/release; services return typed data and
64
+ stable errors without console, process-exit, or destination-file effects.
65
+ - [x] **A1.3** Make arbitrary CDP forwarding private and gate page evaluation
66
+ behind `developer.eval` for machine clients.
67
+ - Covers: DEC-5, CON-4, AC-4.
68
+ - Complete: public CLI and stdio clients expose only canonical high-level
69
+ operations. The daemon's CDP transport remains an internal implementation
70
+ endpoint, and public evaluation requires `developer.eval`.
71
+
72
+ ### A2. Build Broker domain isolation
73
+
74
+ - [x] **A2.1** Implement ClientPrincipal, ClientConnection,
75
+ BrowserWorkspace, ManagedTabSet, ControlLease, BrowserInstance,
76
+ and ControlledTarget registries.
77
+ - Covers: FR-3, FR-4, FR-5.
78
+ - Complete: the daemon owns bounded in-memory Principal, Connection,
79
+ Workspace, default ManagedTabSet, and Lease registries. Principal identity
80
+ survives a bridge reconnect within one daemon lifetime; Connection-owned
81
+ Leases do not.
82
+ - [x] **A2.2** Create managed targets only through the control registry and
83
+ validate the complete popup opener chain before adoption.
84
+ - Covers: BR-1, BR-2, AC-4.
85
+ - Progress: legacy CLI popup adoption now requires a complete opener chain
86
+ ending at an already controlled Pilot target. Workspace control registry and
87
+ Broker-only target creation remain.
88
+ - Progress: the Broker inventory foundation now adopts managed popups only
89
+ through a complete live opener chain and refuses to cross a user-tab record.
90
+ - Complete: machine-created targets enter through `BrowserToolService` and
91
+ `MemoryControlledTargetRegistry`; no public machine call accepts a raw CDP
92
+ target ID.
93
+ - [x] **A2.3** Replace global target/frame/session state with Workspace and
94
+ Lease state; provide a compatibility Workspace for one-shot CLI calls.
95
+ - Covers: FR-1, FR-3, AC-1, AC-3.
96
+ - Complete: the CLI uses a fixed daemon-internal one-shot Connection plus
97
+ idempotently keyed compatibility Workspace and renewable five-minute Lease.
98
+ Every CLI command calls canonical tools; active targets, frames, sessions,
99
+ Observations, refs, auth, rules, and request identity remain only in daemon
100
+ memory. No `state.json` or `refs.json` compatibility mapping remains.
101
+ - [x] **A2.4** Serialize commands through a per-target actor and implement
102
+ explicit control transfer.
103
+ - Covers: BR-5, BR-6, NFR-4.
104
+ - Complete: reads and mutations for one physical CDP target share the same
105
+ actor across Workspace-local opaque IDs, while different physical targets
106
+ proceed concurrently. `browser.tabs.release` provides idempotent two-step
107
+ handoff: the owner releases and fully retires its scoped target session,
108
+ then another Lease acquires through its own opaque ID. Foreign Lease IDs,
109
+ silent stealing, and tab closure are not part of transfer.
110
+ - [x] **A2.5** Scope auth, network rules, request journals, downloads, and
111
+ cleanup to their owner.
112
+ - Covers: BR-3, BR-4, AC-3.
113
+ - Complete: Broker auth, interception rules, and bounded request journals are
114
+ Workspace scoped; request identity includes CDP session identity, sensitive
115
+ events are metadata-only, and legacy daemon handlers ignore Broker sessions.
116
+ Lease replacement preserves Workspace configuration while Workspace release
117
+ clears it. Downloads use target-session CDP configuration, separate protected
118
+ staging directories, bounded concurrency/bytes, Workspace-owned Artifacts,
119
+ and Lease/session/Workspace cleanup without browser-wide fallback.
120
+ - [x] **A2.6** Implement the default-unrestricted BrowserControlPolicy and
121
+ optional launch-time Host operation removal.
122
+ - Covers: FLOW-5, BR-21, BR-22, AC-4.
123
+ - Acceptance: no request/grant/approval lifecycle exists; every supported
124
+ operation is available by default; explicitly denied operations fail with
125
+ `capability_denied` before CDP dispatch.
126
+ - Complete: `createBrowserControlPolicy` exposes all eligible user tabs and
127
+ validates optional `deniedOperations` without any Agent-specific policy.
128
+ - [x] **A2.7** Build eligible user-tab discovery and internal-target exclusion.
129
+ - Covers: CON-2, FLOW-5, BR-2, BR-25, BR-26, FR-4.
130
+ - Acceptance: current and future ordinary tabs are returned, while managed
131
+ targets, Browser Pilot internal targets, DevTools, unsupported internal
132
+ pages, and non-page targets are excluded.
133
+ - Complete: `CdpBrowserTargetCatalog` implements the CDP catalog boundary.
134
+ - [x] **A2.8** Merge ManagedTabSets and all eligible user tabs in
135
+ ControlledTarget resolution, listing, switching, and popup inheritance.
136
+ - Covers: BR-1, BR-2, BR-23 through BR-27.
137
+ - Acceptance: `tabs.list` returns managed and user tabs with
138
+ origin metadata; conflicting control reports `target_busy`; bulk cleanup
139
+ closes only managed tabs; closing a user tab is explicit.
140
+ - Complete: `MemoryControlledTargetRegistry`, `TargetInventoryService`, and
141
+ `CdpBrowserTargetCatalog` now provide opaque per-Workspace target IDs,
142
+ immediate managed/user inventory merging, dynamic new-tab discovery,
143
+ physical-target Lease exclusion across Principals, ineligible-target
144
+ invalidation, managed-popup inheritance, and safe managed-only bulk close.
145
+ `tools/call` now lists, switches to, and explicitly closes both origins;
146
+ Workspace release closes only managed targets. The compatibility CLI
147
+ retains the same all-tab behavior.
148
+
149
+ ### A3. Add bounded runtime lifecycle and command semantics
150
+
151
+ - [x] **A3.1** Add in-memory Workspace, Lease, target assignment, command,
152
+ idempotency, and bounded journal stores.
153
+ - Covers: FR-5, NFR-2, NFR-5.
154
+ - Complete: Workspace, Lease, target assignment, Command, idempotency, and
155
+ per-Workspace event stores are bounded and live in daemon memory.
156
+ - [x] **A3.2** Implement heartbeat, expiry, release, crash recovery, and
157
+ idempotent cleanup for Workspaces and Leases.
158
+ - Covers: AC-5, NFR-5.
159
+ - Broker restart invalidates transient state; clients initialize, list, and
160
+ observe again. Do not recover stale browser state from disk.
161
+ - Complete: Lease heartbeat/expiry/release, EOF cleanup, idle Connection and
162
+ Workspace reclamation, and idempotent Workspace release are implemented.
163
+ Target, auth, network, frame, Observation, Artifact, and partial download
164
+ cleanup is connected. Browser connection loss now rejects tools, invalidates
165
+ sessions/refs, passively rediscovers the selected profile, and advances
166
+ generation only after an explicit reconnect succeeds. A private child janitor solely owns the browser-level CDP
167
+ connection, proxies daemon traffic over IPC, tracks verified managed popup
168
+ descendants, and closes them on daemon-pipe EOF, including `SIGKILL`,
169
+ without persisting target IDs or grouping by browser window. Process-level
170
+ tests prove user tabs survive and only one browser WebSocket is opened.
171
+ - [x] **A3.3** Implement command accepted/dispatched/completed,
172
+ `unknown_outcome`, deadline, cancellation, and duplicate-call behavior.
173
+ - Covers: BR-8 through BR-12, AC-5.
174
+ - Complete: caller or Broker IDs, Workspace-scoped idempotency, bounded
175
+ terminal outcomes, pre-dispatch cancellation, best-effort post-dispatch
176
+ cancellation, deadlines, cached results, and no-replay unknown outcomes are
177
+ enforced through the public bridge.
178
+ - [x] **A3.4** Replace dialog auto-acceptance with typed events and explicit
179
+ accept/dismiss commands.
180
+ - Covers: DEC-5, event contract.
181
+ - Complete: dialogs stay pending, emit opened/closed events, and can be listed
182
+ and explicitly accepted or dismissed through out-of-band dialog tools.
183
+ One-shot CLI dialogs use those same Workspace-scoped canonical tools and
184
+ cannot list or respond to another Workspace's dialogs.
185
+
186
+ ### A4. Deliver the stdio bridge
187
+
188
+ - [x] **A4.1** Implement strict NDJSON framing, JSON-RPC parsing, stdout/stderr
189
+ separation, initialization, and graceful shutdown.
190
+ - Covers: FR-2, NFR-1.
191
+ - Complete: fatal UTF-8 decoding, bounded line assembly, strict JSON-RPC
192
+ envelopes, ordered normal dispatch, command-control bypass, notification
193
+ semantics, stdout-only protocol, EOF cleanup, bridge-only shutdown, and
194
+ structured framing errors are covered by black-box stream tests.
195
+ - [x] **A4.2** Implement tool discovery/call, Workspace/Lease lifecycle,
196
+ cancellation, and structured errors.
197
+ - Covers: AC-2, FR-7.
198
+ - Includes direct all-tab inventory and optional Host-configured operation
199
+ removal. There are no browser-access approval methods.
200
+ - Complete: canonical `tools/list`, validated `tools/call`, Workspace/Lease
201
+ lifecycle, all-tab inventory, and production implementation filtering are
202
+ implemented. `commands/get/cancel` can overtake a pending call on the same
203
+ stdio connection and return structured outcomes.
204
+ - [x] **A4.3** Implement event notifications plus cursor polling and
205
+ `cursor_expired` recovery.
206
+ - Covers: events contract, NFR-3.
207
+ - Complete: bounded Workspace journals, explicit initial cursors, ordered
208
+ replay, `cursor_expired` bounds, Principal isolation, best-effort stdio
209
+ notifications, and daemon notification long-polling are implemented.
210
+ - [x] **A4.4** Add protocol backpressure, negotiated message limits, and
211
+ malformed-client isolation.
212
+ - Covers: NFR-1, NFR-5.
213
+ - Complete: protocol 1.1 negotiates per-Connection message/result ceilings;
214
+ bootstrap and pipelined framing apply them deterministically. Input/output
215
+ backpressure, bounded ordinary/control call queues, oversized-result
216
+ replacement, notification dropping with cursor recovery, and bridge-local
217
+ malformed-client termination prevent one client from exhausting or
218
+ terminating another.
219
+
220
+ ### A5. Deliver secure Artifacts
221
+
222
+ - [x] **A5.1** Add protected Artifact storage, metadata, quotas, TTL, preview
223
+ relationships, retain/release, and cleanup.
224
+ - Covers: BR-17 through BR-20, FR-6.
225
+ - [x] **A5.2** Return screenshot, PDF, and download results as Artifacts while
226
+ keeping explicit CLI export behavior compatible.
227
+ - Covers: AC-1, AC-6.
228
+ - Complete: screenshot and PDF tools return scoped Artifacts; large captures
229
+ produce model-sized previews with optional originals. Session-scoped download
230
+ events ingest completed files as protected `download` Artifacts without
231
+ publishing staging paths or CDP GUIDs.
232
+ - [x] **A5.3** Add adapter-facing file authorization and revoke access on
233
+ release or expiry.
234
+ - Covers: CON-5, NFR-5.
235
+ - Complete: import/get/export/retain/release require an owning active Workspace
236
+ and Lease. `artifacts/import` copies an absolute client-authorized path to a
237
+ `user_file` / `upload_input` Artifact, and `browser.upload` accepts only that
238
+ kind. Release, expiry, Workspace cleanup, and Broker shutdown delete Broker
239
+ bytes without deleting the source file.
240
+
241
+ ### A6. Browser discovery and multi-version operation
242
+
243
+ - [x] **A6.1** Return structured browser candidates and setup remediation;
244
+ persist only explicit or deterministic selection.
245
+ - Covers: browser discovery contract.
246
+ - Complete: discovery enumerates installed supported product/profile candidates
247
+ with stable IDs and separate process, remote-debugging, and authorization
248
+ state. `initialize`, `browser.discover`, and `bp browsers` are passive and
249
+ return bounded remediation; the Broker can start before any candidate is
250
+ ready, connect candidates only through explicit `browser.connect`, and route ready browser instances by
251
+ `browserId`. Selection is explicit (`--browser`/`browserId`) or stable-order
252
+ deterministic and remains daemon-memory state only.
253
+ - [x] **A6.2** Define the per-user Broker locator, socket/pipe permissions,
254
+ startup locking, stale process recovery, and platform-specific paths.
255
+ - Covers: FR-7, CON-5.
256
+ - Complete: a versioned, owner-only locator records the per-user endpoint and
257
+ Broker process identity. Unix uses a mode-`0600` domain socket with a
258
+ deterministic short runtime path when required; Windows uses a per-user
259
+ named pipe. State/runtime directories and metadata are owner-only. An
260
+ atomic startup lock plus a post-lock health check makes concurrent launch a
261
+ single-winner operation. Broker startup never requests Chrome authorization;
262
+ concurrent explicit connect calls share one in-flight attempt. Dead owners are
263
+ reclaimed without killing a PID; live but unresponsive ready Brokers fail
264
+ with explicit remediation and are never silently replaced.
265
+ - [x] **A6.3** Implement executable/protocol negotiation, live-client upgrade
266
+ protection, rollback metadata, and deliberate version isolation.
267
+ - Covers: AC-7, NFR-2.
268
+ - Complete: compatible embedded clients negotiate and reuse the running
269
+ Broker, while the one-shot compatibility CLI retains exact executable
270
+ version semantics. Health and schema-2 locator metadata expose the current
271
+ service, executable installation identity, protocol range, and bounded live
272
+ client counts. Protected compare-and-stop shutdown rejects mismatched
273
+ executables and returns `broker_in_use` while embedded Connections remain.
274
+ Owner-only version history retains only current/previous executable metadata
275
+ and no transient browser state. `BROWSER_PILOT_HOME` provides explicit
276
+ cross-platform isolation; incompatibility never triggers hidden replacement
277
+ or isolation. Process tests cover reuse, incompatibility, shutdown
278
+ protection, crash recovery, and two intentional Broker namespaces.
279
+ - [x] **A6.4** Preserve global npm, local npm/npx, and product-bundled launch
280
+ modes. Add signed/self-contained artifacts where each platform permits.
281
+ - Covers: FR-1, FR-2.
282
+ - Complete: build-time version injection and a runtime layout abstraction
283
+ preserve adjacent-script npm installs while allowing one Node SEA executable
284
+ to serve the public CLI and reserved private Broker/janitor roles. Packed
285
+ global npm, local npm/npx, and product-owned absolute-path launches pass
286
+ black-box version, bridge, Broker startup, and cleanup tests. Native bundles
287
+ include actual-state signature metadata, SHA-256 manifests, licenses, and
288
+ platform archives; macOS Developer ID/notarization and Windows Authenticode
289
+ hooks activate only with complete credentials, while unsigned/ad-hoc state
290
+ remains explicit. Release CI uses fixed official Node 22.17.0 native runners
291
+ and verifies every artifact before publishing it.
292
+
293
+ ### A7. Agent-neutral integration kit
294
+
295
+ - [x] **A7.1** Publish the process adapter contract: launch, initialize,
296
+ manifest registration, tool calls, event handling, Artifact conversion, and
297
+ cleanup.
298
+ - Covers: AC-2, AC-6.
299
+ - [x] **A7.2** Build a language-neutral conformance runner that treats the
300
+ executable as a black box.
301
+ - Covers: FR-2 through FR-7.
302
+ - [x] **A7.3** Add Tenon and OpenClaw adapters as separate examples or consumer
303
+ changes. Keep their lifecycle mapping out of Browser Pilot production code.
304
+ - Covers: DEC-1, CON-3.
305
+ - Complete: source-only Tenon and OpenClaw adapters consume only
306
+ `bridge --stdio`, runtime `tools/list`, and protected Artifact files. They
307
+ map Thread/Turn and Agent-session/run lifecycles to transient
308
+ Workspace/Lease contexts, require explicit targets, derive Command identity
309
+ from host tool-call IDs, convert screenshots to native image content, export
310
+ files to host-owned absolute paths, explicitly acknowledge processed event
311
+ cursors, and invalidate local state on failed cleanup. Concurrent begin,
312
+ initialization/release failure, cursor recovery, media conversion, bounded
313
+ model text, structured errors, and unknown outcomes are covered by process
314
+ tests. The examples remain excluded from the npm package and no
315
+ Agent-specific concept enters production code.
316
+ - [x] **A7.4** Update the Agent skill to teach direct one-shot use and embedded
317
+ stdio use without assuming a particular Agent runtime.
318
+ - Covers: FR-1, AC-1.
319
+
320
+ ## Cross-Workstream Dependencies
321
+
322
+ - A0.2 and B0.1 jointly own the Observation/ref public contract.
323
+ - A1 exposes internal service interfaces; B1-B4 implement improved behavior
324
+ behind those interfaces.
325
+ - A2 target actors provide B3 action ordering and document-change cancellation.
326
+ - A4 events depend on B4 event producers but can be tested initially with
327
+ synthetic Broker events.
328
+ - A5 Artifact delivery is required before B5 screenshot guidance is complete.
329
+
330
+ ## Release Gate
331
+
332
+ Workstream A is complete only when AC-1 through AC-7 pass, existing CLI tests
333
+ remain green, two concurrent reference clients are isolated, all eligible user
334
+ tabs are combined with the Agent's managed tabs without a grant step, bulk
335
+ cleanup leaves user tabs open, Host-disabled operations fail before dispatch,
336
+ and a client can send a screenshot Artifact to its runtime's native image
337
+ content without an SDK or MCP dependency.
package/package.json CHANGED
@@ -1,28 +1,58 @@
1
1
  {
2
2
  "name": "browser-pilot-cli",
3
- "version": "0.1.6",
3
+ "version": "0.2.2",
4
4
  "description": "CLI tool to control your browser via Chrome DevTools Protocol",
5
+ "repository": "https://github.com/relixiaobo/browser-pilot",
5
6
  "type": "module",
6
7
  "bin": {
7
8
  "bp": "dist/cli.js",
8
- "browser-pilot": "dist/cli.js"
9
+ "browser-pilot": "dist/cli.js",
10
+ "browser-pilot-conformance": "scripts/run-stdio-conformance.mjs"
9
11
  },
10
12
  "scripts": {
11
13
  "build": "tsup",
14
+ "build:standalone:js": "tsup --config tsup.standalone.config.ts",
15
+ "build:standalone": "npm run build:standalone:js && node scripts/build-standalone.mjs",
16
+ "package:standalone": "node scripts/package-standalone.mjs",
17
+ "verify:standalone": "node scripts/verify-standalone.mjs",
12
18
  "dev": "tsup --watch",
13
19
  "start": "node dist/cli.js",
14
- "test": "tsup && npx playwright test --project core --project compat --project network",
15
- "test:integration": "tsup && npx playwright test --project integration",
16
- "test:all": "tsup && npx playwright test"
20
+ "test": "tsup && node --test tests/*.test.mjs && npx playwright test --project core --project compat --project network",
21
+ "test:unit": "tsup && node --test tests/*.test.mjs",
22
+ "test:capabilities": "tsup && node --test tests/browser-capability-fixtures.test.mjs",
23
+ "test:protocol": "tsup && node --test tests/protocol.test.mjs",
24
+ "test:stdio-conformance": "tsup && node scripts/run-isolated-stdio-conformance.mjs",
25
+ "test:distribution": "tsup && node scripts/verify-npm-distribution.mjs",
26
+ "test:canary": "tsup && node scripts/run-real-site-canaries.mjs",
27
+ "test:canary:strict": "tsup && node scripts/run-real-site-canaries.mjs --strict",
28
+ "test:integration": "npm run test:canary:strict",
29
+ "test:all": "npm test && npm run test:canary",
30
+ "test:agent": "python3 tests/agent/run.py",
31
+ "test:agent:dry": "python3 tests/agent/run.py --dry-run",
32
+ "test:agent:download": "python3 tests/agent/download_data.py"
17
33
  },
34
+ "files": [
35
+ "dist/cli.js",
36
+ "dist/daemon.js",
37
+ "dist/managed-target-janitor.js",
38
+ "scripts/run-stdio-conformance.mjs",
39
+ "docs/architecture/browser-pilot-platform-spec.md",
40
+ "docs/integration/stdio-bridge.md",
41
+ "docs/integration/stdio-conformance.md",
42
+ "docs/plans/browser-capability-evolution.md",
43
+ "docs/plans/universal-agent-integration.md",
44
+ "README.md",
45
+ "LICENSE"
46
+ ],
18
47
  "dependencies": {
19
48
  "commander": "^13.1.0",
20
- "ws": "^8.18.0"
49
+ "ws": "^8.21.1"
21
50
  },
22
51
  "devDependencies": {
23
52
  "@playwright/test": "^1.59.1",
24
53
  "@types/node": "^22.0.0",
25
54
  "@types/ws": "^8.5.0",
55
+ "postject": "^1.0.0-alpha.6",
26
56
  "tsup": "^8.0.0",
27
57
  "typescript": "^5.7.0"
28
58
  },
@@ -34,5 +64,8 @@
34
64
  "cli",
35
65
  "devtools"
36
66
  ],
67
+ "engines": {
68
+ "node": ">=18"
69
+ },
37
70
  "license": "MIT"
38
71
  }