From 5bbde0af440c3d33efa763ca56f6ce52eeb65b98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Beaufort?= Date: Thu, 1 Oct 2026 10:15:43 +0200 Subject: [PATCH] Remove origin-keyed agent cluster requirement Follow webmachinelearning/webmcp#330 (draft d61d0e6): registerTool(), getTools() and executeTool() no longer reject with SecurityError outside an origin-keyed agent cluster. Drop the Origin-Agent-Cluster setup advice, the Firefox WPT pref, and the fixture route that tested the old behavior. Move the WPT pin to fe52996 (web-platform-tests/wpt#63114), which deletes the document-domain-enabled tests. The new pin also moves lifecycle events to ModelContext and adds ToolActivatedEvent/ToolCancelEvent tests; record those as expected failures since the polyfill does not implement them, and record new cases that rely on uninstrumented /common/blank.html frames. Validation: 223 browser tests and packed consumer checks pass. WPT in Chrome Canary 157.0.8080.0 and Firefox Nightly 159.0a1: 70 files, 190 subtests, zero unexpected results. --- README.md | 4 +- TESTING.md | 49 ++++++++----------- src/index.ts | 3 -- tests/fixtures/server.ts | 2 - tests/index.test.ts | 33 ------------- ...document-domain-enabled.sub.https.html.ini | 5 -- ...teTool-detach-toolactivated.https.html.ini | 5 ++ .../webmcp/idlharness.https.window.js.ini | 35 +++++++++++++ ...document-domain-enabled.sub.https.html.ini | 11 ----- ...teTool-detach-toolactivated.https.html.ini | 7 +++ ...ecuteTool-detach-toolcancel.https.html.ini | 7 +++ .../executeTool-events.https.html.ini | 10 ++-- ...ecuteTool-target-detachment.https.html.ini | 8 ++- .../tool-activated-event.https.html.ini | 11 +++++ .../webmcp/tool-cancel-event.https.html.ini | 12 +++++ wpt/revision.txt | 2 +- wpt/run.ts | 6 +-- 17 files changed, 117 insertions(+), 93 deletions(-) delete mode 100644 wpt/metadata/webmcp/declarative/document-domain-enabled.sub.https.html.ini create mode 100644 wpt/metadata/webmcp/declarative/executeTool-detach-toolactivated.https.html.ini create mode 100644 wpt/metadata/webmcp/idlharness.https.window.js.ini delete mode 100644 wpt/metadata/webmcp/imperative/document-domain-enabled.sub.https.html.ini create mode 100644 wpt/metadata/webmcp/imperative/executeTool-detach-toolactivated.https.html.ini create mode 100644 wpt/metadata/webmcp/imperative/executeTool-detach-toolcancel.https.html.ini create mode 100644 wpt/metadata/webmcp/tool-activated-event.https.html.ini create mode 100644 wpt/metadata/webmcp/tool-cancel-event.https.html.ini diff --git a/README.md b/README.md index b3e0171..8bd317f 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Then install the checkout in your app with `pnpm add /path/to/webmcp-polyfill`. ## Usage -Use HTTPS or localhost. Some browsers need an `Origin-Agent-Cluster: ?1` header; current Chrome enables origin keying by default. +Use HTTPS or localhost. Load the polyfill before registering tools: @@ -75,8 +75,6 @@ import "webmcp-polyfill/auto"; Next.js runs [client instrumentation](https://nextjs.org/docs/app/api-reference/file-conventions/instrumentation-client) before hydration. A Server Component import alone won't install the polyfill in the browser. -Configure `Origin-Agent-Cluster` through Next.js [`headers()`](https://nextjs.org/docs/app/api-reference/config/next-config-js/headers) if your browser needs it. - Both entry points are SSR-safe: installation does nothing without a document. Your pages can stay server-rendered; WebMCP runs in the browser. The package needs no `"use client"` directive. Use it on your [Client Components](https://nextjs.org/docs/app/api-reference/directives/use-client) and access `document.modelContext` in effects or event handlers. Pass an `AbortSignal` when registering in an effect, then abort it during cleanup. diff --git a/TESTING.md b/TESTING.md index a6fcb1e..316b960 100644 --- a/TESTING.md +++ b/TESTING.md @@ -2,28 +2,29 @@ ## Results -**226 browser tests pass** across Chromium 153.0.8010.12, Firefox 155.0, and +**223 browser tests pass** across Chromium 153.0.8010.12, Firefox 155.0, and Playwright WebKit 26.6. Package checks also pass: imports, types, SSR, and tarball contents. CI runs these checks plus WPT in Chrome, Firefox, and actual Safari. Safari runs on `macos-26`; Playwright WebKit is a separate build. -WPT covers **all 67 WebMCP testharness files, 161 subtests**, with zero unexpected results: +WPT covers **all 70 WebMCP testharness files, 190 subtests**, with zero unexpected results +in Chrome and Firefox: -| Subtest result | Chrome / Firefox | Safari | -| --- | ---: | ---: | -| PASS | 96 | 92 | -| Expected FAIL | 23 | 27 | -| Expected TIMEOUT | 24 | 24 | -| Expected NOTRUN | 18 | 18 | +| Subtest result | Count | +| --- | ---: | +| PASS | 92 | +| Expected FAIL | 52 | +| Expected TIMEOUT | 26 | +| Expected NOTRUN | 20 | -Tested with Chrome Canary 156.0.8068.0, Firefox Nightly 158.0a1 (20260922211342), -Firefox 142.0.1, and Safari 26.6.2 (21624.5.1.11.3) on macOS 26.6.2. -At the file level: 42 OK, 24 expected timeouts, one expected error. +Tested with Chrome Canary 157.0.8080.0 and Firefox Nightly 159.0a1 (20260930214513). +Safari has not yet run at this pin; none of the expectations are browser-specific. +At the file level: 43 OK, 26 expected timeouts, one expected error. Expected failures are still failures. `NOTRUN` means an earlier timeout prevented the test from running, including three abort cases. Passing declarative checks only -cover rejection or absence of tools. All 22 pinned IDL checks pass, but that IDL -predates `debugging` and lifecycle events. This is not full conformance. +cover rejection or absence of tools. Of the 38 pinned IDL checks, the 16 for lifecycle +event handlers and interfaces fail. This is not full conformance. ## Run locally @@ -41,7 +42,7 @@ native WebMCP. A separate Chromium test uses `--enable-features=WebMCP` to check that loading the polyfill preserves the native context and its tools. WPT needs Python 3.11+ and a clean checkout at -[`2699eaa`](https://github.com/web-platform-tests/wpt/commit/2699eaa2e5f906eda4d7443f7080c3de19e62365). +[`fe52996`](https://github.com/web-platform-tests/wpt/commit/fe52996d4465f23617bce91927bdd58e6ce8f541). The [CI workflow](.github/workflows/test.yml) has the sparse-checkout and dependency setup. ```sh @@ -50,10 +51,7 @@ WPT_ROOT=../wpt WPT_BROWSER=firefox pnpm test:wpt WPT_ROOT=../wpt WPT_BROWSER=safari pnpm test:wpt ``` -Firefox downloads Nightly unless `FIREFOX_BIN` is set. The runner enables -`dom.origin_agent_cluster.default` in the test profile because the pinned pages -assume origin keying without a header; [Firefox defaults to site keying](https://github.com/mozilla-firefox/firefox/blob/FIREFOX_142_0_1_RELEASE/modules/libpref/init/StaticPrefList.yaml#L5768-L5773). -Local fixtures test explicit `Origin-Agent-Cluster` headers. +Firefox downloads Nightly unless `FIREFOX_BIN` is set. Safari requires macOS, [Remote Automation, and WPT hosts-file setup](https://web-platform-tests.org/running-tests/safari.html). Set `WPT_PYTHON` or `WPT_VENV` to use an existing Python environment. Extra arguments @@ -67,23 +65,18 @@ other non-testharness files are outside this suite. ## Draft alignment and limitations -Checked against [draft `f5645e9`](https://github.com/webmachinelearning/webmcp/blob/f5645e9aea51eb589599f181d104a2f49430608e/index.bs) +Checked against [draft `d61d0e6`](https://github.com/webmachinelearning/webmcp/blob/d61d0e6d297ddb6bff3510b1330dbb215c6ef43c/index.bs) and `webmcp-types@0.1.9`. -- **Missing APIs:** declarative forms, CSS states, and lifecycle events are not - implemented. This includes both the draft's `ModelContext` events and the older - `window` events WPT expects. +- **Missing APIs:** declarative forms, CSS states, and lifecycle events + (`toolactivated`/`toolcancel`, their handlers, and `ToolActivatedEvent`/`ToolCancelEvent`) + are not implemented. - **Draft differences:** results are JSON-serialized; some pinned tests expect raw - strings. Omitted or `undefined` input becomes `{}`, matching the types and pinned - IDL rather than the recorded draft. `null` and primitives reject. + strings. Omitted or `undefined` input becomes `{}`; `null` and primitives reject. - **Timing:** MessagePorts approximate native task ordering. Aborting before dispatch skips the callback; the draft dispatches and then aborts its signal. Delegated permission checks are asynchronous, so argument errors can precede `NotAllowedError`. -- **Safari:** the tested version lacks `originAgentCluster`, so the polyfill skips - that check. Four WPT assertions fail with `NotAllowedError` instead of - `SecurityError`. [WebKit's implementation](https://github.com/WebKit/WebKit/pull/66162) - landed behind a flag. - **Frames:** each participating document must load the polyfill. Native contexts and WPT's uninstrumented blank helper documents cannot answer its messages. Opaque-origin handshakes and inaccessible cross-origin shadow frames are diff --git a/src/index.ts b/src/index.ts index b64a245..4b7a150 100644 --- a/src/index.ts +++ b/src/index.ts @@ -607,9 +607,6 @@ function requireActiveWindow(owner: Document): Window { if (!view) { throw new NativeDOMException("The document is not fully active", "InvalidStateError"); } - if (view.originAgentCluster === false && view.location.protocol !== "file:") { - throw new NativeDOMException("An origin-keyed agent cluster is required", "SecurityError"); - } // Synchronous where the browser exposes the policy; FrameBridge.allowed() covers the rest. if (readToolsPolicy(owner) === false) { diff --git a/tests/fixtures/server.ts b/tests/fixtures/server.ts index 911ea41..4a63b26 100644 --- a/tests/fixtures/server.ts +++ b/tests/fixtures/server.ts @@ -45,7 +45,6 @@ const frameHtml = 'WebMCP frame