@ai-ecoverse/slicc-cdp 1.44.2 → 1.45.0

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.
package/README.md CHANGED
@@ -72,9 +72,9 @@ The web storage commands, `localstorage-list`, `-get`, `-set`, `-delete` and `-c
72
72
  playwright-cli --cdp 9333 webmcp-polyfill --tab <targetId> --reload
73
73
  ```
74
74
 
75
- The holder is a foreground process: keep stdin open, and close stdin to stop it. Its first stdout line is JSON with `event: "ready"`, `loaderId`, `mode`, `tab`, `late`, `reloaded` and measured `pauseMicros`. After later navigations, a `document-ready` JSON event identifies the current `loaderId` once the top document has loaded, every frame document the holder is waiting on, including cross-origin iframes in their own processes, has passed or failed the gate, and the holder has persisted its verified metadata; consumers should await this event before listing load-time tools. Ordinary CLI saves preserve holder-owned metadata, and listing refreshes it after verifying the current document. On native hosts and WASI, session and state files are published from unique private sibling files with atomic renames, so concurrent readers see a complete previous or new generation. `--reload` is opt-in: it reloads only the selected tab so registration during page load sees the API. Without it, the shim installs into the already-loaded document and `late: true` warns that load-time registrations may have been missed. An existing native or page-provided API is not replaced. The shim's document and navigator aliases remain replaceable; the holder retains its registered tools through a private, random lexical bridge, not a page-callable binding.
75
+ The holder is a foreground process: keep stdin open, and close stdin to stop it. Its first stdout line is JSON with `event: "ready"`, `loaderId`, `mode`, `tab`, `late`, `reloaded` and measured `pauseMicros`. After later navigations, a `document-ready` JSON event identifies the current `loaderId` once the top document has loaded, its current main-world context has passed the live check, and the holder has persisted its verified metadata; consumers should await this event before listing load-time tools. Ordinary CLI saves preserve holder-owned metadata, and listing refreshes it after verifying the current document. On native hosts and WASI, session and state files are published from unique private sibling files with atomic renames, so concurrent readers see a complete previous or new generation. `--reload` is opt-in: it reloads only the selected tab so registration during page load sees the API. Without it, the shim installs into the already-loaded document and `late: true` warns that load-time registrations may have been missed. An existing native or page-provided API is not replaced. The shim's document and navigator aliases remain replaceable; the holder retains its registered tools through a private, random lexical bridge, not a page-callable binding.
76
76
 
77
- While the holder runs, a page that registers or unregisters tools after load, including in an admitted cross-origin iframe, produces a `tools-changed` JSON line:
77
+ While the holder runs, a page that registers or unregisters tools after load in its admitted main document produces a `tools-changed` JSON line:
78
78
 
79
79
  ```jsonl
80
80
  {"event":"tools-changed","tab":"<targetId>","target":"<targetId>","frameId":"<frameId>","loaderId":"<loaderId>","origin":"https://shop.example","tools":[]}
@@ -84,7 +84,7 @@ While the holder runs, a page that registers or unregisters tools after load, in
84
84
 
85
85
  `discover` reports these changes too, but only from a running holder. In watch mode it reads the changes the holder publishes to the saved session, so the holder must use the same CDP endpoint and saved session (the same working directory, or the same `--session`). Each change becomes one `webmcp` event with `"via":"page-api"` and `"summary":{"event":"tools-changed","target":…,"frameId":…,"loaderId":…,"origin":…,"tools":[…]}`, and only while the tab's top document is still the one the holder reported. Changes published before `discover` started are not replayed. Without a holder, `discover` reports a page's WebMCP tools only when it loads.
86
86
 
87
- From another terminal, using the same CDP endpoint and saved session:
87
+ On direct Chrome, from another terminal using the same CDP endpoint and saved session:
88
88
 
89
89
  ```sh
90
90
  playwright-cli --cdp 9333 webmcp-list --tab <targetId> --json
@@ -92,9 +92,15 @@ playwright-cli --cdp 9333 webmcp-call get_inbox_state '{}' --tab <targetId>
92
92
  playwright-cli --cdp 9333 webmcp-call send_reply '{}' --tab <targetId> --allow-consequential
93
93
  ```
94
94
 
95
- Same-origin frames are included. A cross-origin provider additionally requires repeatable `--from-origin <http(s)-origin>`, explicit `exposedTo` permission for the caller's origin, the `tools` Permissions Policy and iframe delegation along the entire ancestor chain. `--json` includes each provider's `frameId`; use `webmcp-call ... --frame <frameId>` to resolve duplicate names. Unknown policy is denied for all iframes and for our injected shim: on browsers without native `tools` policy introspection, the holder must observe the document response, normally through `--reload`. For compatibility, an ordinary top-level page-defined API may expose its own tools when no policy was observed and the browser does not recognize `tools`; these tools carry `"policy": "unknown"` in `--json` and a “policy: unknown, top-level page-defined” label in human output. Verified tools carry `"policy": "allowed"`. Any observed `tools=()` denies tools, including in compatibility mode. Run `webmcp-polyfill --tab <targetId> --reload` to record verified response headers rather than rely on compatibility mode. Tool lists and call results are capped at 65,536 characters per page response. The shim supports JavaScript tool registration, not declarative HTML tools.
95
+ Stage 1 retains a guarded-route limit. On both guarded routes, an independent second-process `playwright-cli webmcp-list` can return `[]` for a polyfilled page even while the running MCP server lists and calls its tools. This limit also affects pages without children and is tracked in [#693](https://github.com/ai-ecoverse/slicc-cdp/issues/693). Use the running `mcpcat serve --webmcp` server for listing and calling those tools.
96
96
 
97
- Only the hash-pinned shim can use the dedicated installer. Its inert pre-execution gate pauses each new document, verifies fresh guard-owned frame, loader and context evidence, then permits the shim body. Protected or unverified documents, including child frames, never pass the gate; errors, missing pauses or changed document evidence remove the installer and resume without the shim. No holder means no debugger gate or extra navigation pause. Stopping the holder removes future injection; an already-installed ordinary document API lasts until that document is discarded. Browser-backed tests and navigation/pause measurements run on CI only.
97
+ Same-origin frames are included on direct Chrome and the link route; same-origin child frame tools do not work on the extension route yet ([#694](https://github.com/ai-ecoverse/slicc-cdp/issues/694)). There, the injected shim is also installed through ordinary Runtime.evaluate when a same-origin child default context appears and its document is verified. On direct Chrome and the link route, this includes a child added after the root was accepted. The child queue starts only after the current root document is committed and its installation is accepted; it makes no live read while that root is navigating or a Document request is paused. This is a no-op if the pause path already installed that realm. The installer waits within a bounded placement window, binds the child frame, loader and unique context plus the root identity, rechecks after evaluation, and does nothing in an already accepted realm. It does not publish child Debugger content or pause the child script. Synchronous child registration or a WebMCP check that runs before installation cannot be recovered; awaited or asynchronous registration must leave enough time for installation. A cross-origin provider additionally requires repeatable `--from-origin <http(s)-origin>`, explicit `exposedTo` permission for the caller's origin, the `tools` Permissions Policy and iframe delegation along the entire ancestor chain. `--json` includes each provider's `frameId`; use `webmcp-call ... --frame <frameId>` to resolve duplicate names. Unknown policy is denied for all iframes and for our injected shim: on browsers without native `tools` policy introspection, the holder must observe the document response, normally through `--reload`. For compatibility, an ordinary top-level page-defined API may expose its own tools when no policy was observed and the browser does not recognize `tools`; these tools carry `"policy": "unknown"` in `--json` and a “policy: unknown, top-level page-defined” label in human output. Verified tools carry `"policy": "allowed"`. Any observed `tools=()` denies tools, including in compatibility mode. Run `webmcp-polyfill --tab <targetId> --reload` to record verified response headers rather than rely on compatibility mode. Tool lists and call results are capped at 65,536 characters per page response. The shim supports JavaScript tool registration, not declarative HTML tools.
98
+
99
+ Requested `--from-origin` origins are passed to native WebMCP's `getTools()` for listing and tool selection before native `executeTool()`. On the polyfill path, cross-origin child tools remain unavailable ([#684](https://github.com/ai-ecoverse/slicc-cdp/issues/684)); requested origins are cleared, root listing and calling remain available, and the command reports the clear limit message. A protected requested origin is refused before native or polyfill mode detection.
100
+
101
+ Only the hash-pinned shim can use the dedicated installer. With `--reload`, the holder first arms instrumentation, performs one guarded reload, waits for the normal pause published by the guard, and rechecks the document before installing through main-world `Runtime.evaluate`. The guard owns any conversion of an instrumentation pause; on direct Chrome, Rust's own guard performs that conversion with private `Debugger.pause` and `Debugger.resume`. Generic library calls refuse all Debugger methods, including the holder's five methods; only the private holder path can use them. Debugger events remain private even for that holder. Client `Debugger.pause`, `Debugger.getScriptSource` and `Debugger.evaluateOnCallFrame` remain refused. Without `--reload`, it installs into the current main document immediately and leaves instrumentation armed for the next document. The same private lexical declaration is used on both paths, without an init script or binding. A second installation in the same realm is a no-op. Protected or unverified documents never receive the shim; missing normal pauses, failed reads and changed context or loader evidence fail closed and release the holder's debugger. The holder does not automatically attach to or inject child targets in Stage 1, including on direct Chrome; child tools that require that injection are unavailable with a clear error. Restoring direct-Chrome cross-origin child injection is tracked in [#684](https://github.com/ai-ecoverse/slicc-cdp/issues/684). No holder means no debugger lease or extra navigation pause. Stopping the holder removes future injection; an already-installed ordinary document API lasts until that document is discarded. Browser-backed tests and navigation/pause measurements run on CI only.
102
+
103
+ When the debugger is refused because another extension runs scripts in an otherwise ordinary page, the holder can use a plain main-world installation after a bounded guarded frame-tree read completes. Protected, unknown, incomplete and version refusals never select this fallback. Ordinary iframes do not disable it. This path reloads only when `--reload` was requested and sends no debugger method after the refusal. It checks eligibility before the reload, installs in the new root realm after commit, then rechecks the guarded tree after load. The extension route may not expose protected subframes in that tree; on that route the fallback remains root-only and never reaches or names those subframes. The reload still uses the normal navigation guard. It can miss page startup or parse-time WebMCP checks; an empty tool result names that limitation rather than silently reporting no tools.
98
104
 
99
105
  `webmcp-list` succeeds with an empty list (`--json`: `[]`) or “No WebMCP tools on this page” when WebMCP is available but has no registered tools. If `document.modelContext` is absent or null, both `webmcp-list` and `webmcp-call` print “WebMCP is unavailable on this page” to stderr, leave stdout empty and exit 2. Evaluation and connection failures exit 1.
100
106
 
@@ -262,7 +268,7 @@ What the clients need from a CDP backend, checked against the code by `crates/cd
262
268
  - `Inspector.enable` (private guard only)
263
269
  - `Fetch.*`
264
270
 
265
- The guarded Rust client supports document-scoped operations, origin-scoped cookies and guarded interception. Persistent page capabilities that cannot be restricted to verified ordinary documents are refused before sending, including generic init scripts, bindings, page overrides and automatic debugger-waiting attachment. `Network.emulateNetworkConditions` is the one network override admitted, and only as Playwright's offline toggle on an ordinary page session. The dedicated WebMCP installer is the sole vetted-shim exception: it accepts a session, never client-provided source, and gates the pinned bytes on guard-owned document verification. The production method lifetime [inventory](crates/cdp-client/src/capability_inventory_test.rs) is checked against the CLI sources. The Node `CDPClient` is a raw CDP transport, not the guarded Rust client. Both clients send message IDs from 1 through 2^30 - 1 and refuse further sends when that range is exhausted; IDs never wrap.
271
+ The guarded Rust client supports document-scoped operations, origin-scoped cookies and guarded interception. Persistent page capabilities that cannot be restricted to verified ordinary documents are refused before sending, including generic init scripts, bindings, page overrides and automatic debugger-waiting attachment. `Network.emulateNetworkConditions` is the one network override admitted, and only as Playwright's offline toggle on an ordinary page session. The dedicated WebMCP installer accepts a session, never client-provided source, and installs the pinned bytes through ordinary guarded `Runtime.evaluate` after live document verification. Only the five scoped debugger methods (`enable`, `disable`, `resume`, `setInstrumentationBreakpoint`, `removeBreakpoint`) are admitted; source reads, call-frame evaluation and every other Debugger, DOMDebugger or EventBreakpoints method remain refused. The production method lifetime [inventory](crates/cdp-client/src/capability_inventory_test.rs) is checked against the CLI sources. The Node `CDPClient` is a raw CDP transport, not the guarded Rust client. Both clients send message IDs from 1 through 2^30 - 1 and refuse further sends when that range is exhausted; IDs never wrap.
266
272
 
267
273
  ### Session-level domains
268
274
 
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-ecoverse/slicc-cdp",
3
- "version": "1.44.2",
3
+ "version": "1.45.0",
4
4
  "description": "SLICC's CDP layer: client, browser API, transports, HAR, and ARIA snapshot",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -68,11 +68,11 @@
68
68
  "chrome": "156.0.8078.4"
69
69
  },
70
70
  "devDependencies": {
71
- "@ai-ecoverse/slicc-browsers": "1.18.21",
71
+ "@ai-ecoverse/slicc-browsers": "1.19.0",
72
72
  "@ai-ecoverse/slicc-cdp": "1.43.0",
73
- "@ai-ecoverse/slicc-jsh": "0.63.30",
73
+ "@ai-ecoverse/slicc-jsh": "0.64.0",
74
74
  "@ai-ecoverse/slicc-kernel": "1.172.2",
75
- "@ai-ecoverse/slicc-shared-web": "2.13.8",
75
+ "@ai-ecoverse/slicc-shared-web": "2.13.10",
76
76
  "@ai-ecoverse/wasi-pnpm": "12.9.1-21",
77
77
  "@ai-ecoverse/wasm-bash": "5.3.0-23",
78
78
  "@ai-ecoverse/wasm-coreutils": "9.12.0-15",