From b656a894144daa4ee249acef72a861aff1aac33a Mon Sep 17 00:00:00 2001 From: cliffhall Date: Wed, 28 Oct 2026 23:43:20 -0400 Subject: [PATCH 1/4] chore(engines): raise the Node floor to the October 2026 security releases (#2822) engines.node goes from >=22.19.0 to ^22.23.4 || ^24.22.1 || >=26.12.1, the patched release on each supported line, so npm warns (EBADENGINE) on an unpatched runtime. A per-line range is what keeps an unpatched 24.x or 26.x from satisfying it. Every doc that states the floor is updated. The code comments that reasoned from the 22.19 floor were re-read rather than replaced: - NODE_USE_ENV_PROXY was "unsupported at our floor"; it was added in 22.21.0, so it exists at 22.23.4. It is still no substitute: opt-in at process start and Stability 1.1. The comments now say that. - The short-GCM-tag note said only Node 22 accepts a truncated tag. The floor now spans 22 and 24, and 24 only runtime-deprecates it (DEP0182); Node 26 is where it is end-of-life. Co-Authored-By: Claude Opus 5.5 Signed-off-by: cliffhall --- .claude/skills/local-dev/SKILL.md | 2 +- .github/ISSUE_TEMPLATE/1-bug_report.yml | 6 +++--- AGENTS.md | 2 +- README.md | 2 +- clients/cli/README.md | 4 ++-- .../integration/auth/node/file-secret-store.test.ts | 10 +++++----- .../mcp/remote/server-extra-coverage.test.ts | 4 ++-- core/auth/node/file-secret-store.ts | 6 +++--- core/mcp/node/proxyFetch.ts | 4 ++-- core/mcp/remote/node/server.ts | 6 +++--- docs/cli-smoke-testing.md | 2 +- docs/v1-to-v2-migration.md | 4 ++-- package-lock.json | 2 +- package.json | 2 +- scripts/verify-typecheck-coverage.mjs | 2 +- specification/v2_cli_tui_launcher.md | 2 +- 16 files changed, 30 insertions(+), 30 deletions(-) diff --git a/.claude/skills/local-dev/SKILL.md b/.claude/skills/local-dev/SKILL.md index c21df8b06d..0787c57d64 100644 --- a/.claude/skills/local-dev/SKILL.md +++ b/.claude/skills/local-dev/SKILL.md @@ -12,7 +12,7 @@ running and where a package goes. ## Install -Requires Node `>=22.19.0`. +Requires Node `^22.23.4 || ^24.22.1 || >=26.12.1`. ```sh npm install # at the REPO ROOT diff --git a/.github/ISSUE_TEMPLATE/1-bug_report.yml b/.github/ISSUE_TEMPLATE/1-bug_report.yml index e46c789064..fa6b804c2f 100644 --- a/.github/ISSUE_TEMPLATE/1-bug_report.yml +++ b/.github/ISSUE_TEMPLATE/1-bug_report.yml @@ -59,9 +59,9 @@ body: attributes: label: Node version description: > - Output of `node --version`. The current v2 line requires Node >= - 22.19.0; the deprecated v1 line has its own, older floor. - placeholder: "v22.19.0" + Output of `node --version`. The current v2 line requires Node ^22.23.4, + ^24.22.1 or >=26.12.1; the deprecated v1 line has its own, older floor. + placeholder: "v22.23.4" validations: required: true diff --git a/AGENTS.md b/AGENTS.md index 85ac58b11c..42ffc3fe5d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -88,7 +88,7 @@ silently. For the fuller map (what each `core/` area owns, what each v2 is **not** an npm workspace — each client under `clients/*` keeps its own `package.json` and `node_modules`. A single `npm install` at the **repo root** is still all you need: the root `postinstall` cascades into every client. Node -`>=22.19.0`. +`^22.23.4 || ^24.22.1 || >=26.12.1`. ```sh npm install # repo root diff --git a/README.md b/README.md index 78c73eeffd..7f5c529411 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ npx -p @modelcontextprotocol/inspector mcpdo --help # mcpdo ## Quick start (development) -Requires Node `>=22.19.0`. +Requires Node `^22.23.4 || ^24.22.1 || >=26.12.1`: the patched release on each supported line. ```bash npm install # at the repo root; postinstall cascades into every client diff --git a/clients/cli/README.md b/clients/cli/README.md index 807b9881e9..f20116baa8 100644 --- a/clients/cli/README.md +++ b/clients/cli/README.md @@ -94,9 +94,9 @@ Connections to remote HTTP/SSE servers honor the conventional proxy environment OAuth requests go through the destination guard rather than the plain proxied fetch: it reads the same variables, refuses link-local and cloud-metadata targets, and pins each direct connection to the addresses it checked ([#2749](https://github.com/modelcontextprotocol/inspector/issues/2749)). What it can and cannot promise behind a proxy is in [Outbound fetch destination guard](../web/README.md#outbound-fetch-destination-guard). -Proxy routing is powered by the [`undici`](https://www.npmjs.com/package/undici) package (declared in the **root** manifest only; `^8.x` requires Node `>= 22.19.0`, the Inspector's supported floor). It is imported lazily on the first request and, for MCP traffic, only when a proxy variable is set, so MCP connections without a proxy configured pay no cost. OAuth requests load it either way, for the destination guard. +Proxy routing is powered by the [`undici`](https://www.npmjs.com/package/undici) package (declared in the **root** manifest only; `^8.x` requires Node `>= 22.19.0`, below the Inspector's supported floor of `^22.23.4 || ^24.22.1 || >=26.12.1`). It is imported lazily on the first request and, for MCP traffic, only when a proxy variable is set, so MCP connections without a proxy configured pay no cost. OAuth requests load it either way, for the destination guard. -**Both halves of the pair come from userland undici — its `fetch` _and_ its `EnvHttpProxyAgent` ([#2067](https://github.com/modelcontextprotocol/inspector/issues/2067)).** The obvious-looking alternative is to hand the agent to Node's built-in `fetch` as a `dispatcher`, which is what v2.0.0–2.3.0 did. That couples two _different copies_ of undici at the dispatcher handler interface, and that interface is not stable across majors: Node 22 embeds undici 6, Node 24 embeds 7, Node 26 embeds 8. A userland undici 8 agent handed a built-in undici 7 handler is rejected outright — `fetch failed: invalid onRequestStart method` — and the request never leaves the process. Keeping both sides inside one copy is what makes proxying work unchanged from the Node 22.19 floor through Node 26. (Node's own `NODE_USE_ENV_PROXY` is not a substitute: it is unsupported at our 22.19 engine floor.) +**Both halves of the pair come from userland undici — its `fetch` _and_ its `EnvHttpProxyAgent` ([#2067](https://github.com/modelcontextprotocol/inspector/issues/2067)).** The obvious-looking alternative is to hand the agent to Node's built-in `fetch` as a `dispatcher`, which is what v2.0.0–2.3.0 did. That couples two _different copies_ of undici at the dispatcher handler interface, and that interface is not stable across majors: Node 22 embeds undici 6, Node 24 embeds 7, Node 26 embeds 8. A userland undici 8 agent handed a built-in undici 7 handler is rejected outright — `fetch failed: invalid onRequestStart method` — and the request never leaves the process. Keeping both sides inside one copy is what makes proxying work unchanged on every line the floor admits, Node 22 through Node 26. (Node's own `NODE_USE_ENV_PROXY` is not a substitute: it exists at our floor, added in 22.21.0, but it is opt-in at process start and still experimental, so a user who only exports `HTTPS_PROXY` would not get it.) Because undici's `Response` is a different class from `globalThis.Response`, the proxied fetch re-wraps each response as a genuine global `Response`, streaming preserved. Without that, `res instanceof Response` is `false` for callers that test it — including the MCP SDK, whose OAuth error formatter would degrade every message to `Raw body: [object Response]`. diff --git a/clients/web/src/test/integration/auth/node/file-secret-store.test.ts b/clients/web/src/test/integration/auth/node/file-secret-store.test.ts index eb9ec0e321..7dd61244b2 100644 --- a/clients/web/src/test/integration/auth/node/file-secret-store.test.ts +++ b/clients/web/src/test/integration/auth/node/file-secret-store.test.ts @@ -371,8 +371,8 @@ describe("FileSecretStore failure handling", () => { }); it("refuses an authentic tag truncated to 4 bytes (#2485)", async () => { - // A genuine tag, cut short. Node 22 (the engines floor) authenticates a - // 4-byte GCM tag unless the length is pinned, which makes a forgery a + // A genuine tag, cut short. Node 22 and 24 (both within the engines floor) + // authenticate a 4-byte GCM tag unless the length is pinned, which makes a forgery a // ~2^-32 guess — so no read may return the secret, whatever the runtime. await writeEncryptedFixture(); const parsed = JSON.parse(await fs.readFile(filePath(), "utf-8")); @@ -398,9 +398,9 @@ describe("FileSecretStore failure handling", () => { it("pins the tag length at the cipher, not only in the envelope check (#2485)", async () => { // The test above cannot see this: `encryptedEnvelopeProblem` rejects a - // short tag before `createDecipheriv` runs, and current Node rejects one - // natively. So observe the options themselves — without them, Node 22 - // authenticates a 4-byte tag should the envelope check ever regress. + // short tag before `createDecipheriv` runs, and Node 26 rejects one + // natively. So observe the options themselves — without them, Node 22 and + // 24 authenticate a 4-byte tag should the envelope check ever regress. const seen: { cipher: unknown[]; decipher: unknown[] } = { cipher: [], decipher: [], diff --git a/clients/web/src/test/integration/mcp/remote/server-extra-coverage.test.ts b/clients/web/src/test/integration/mcp/remote/server-extra-coverage.test.ts index c303fb23c0..b5e1357518 100644 --- a/clients/web/src/test/integration/mcp/remote/server-extra-coverage.test.ts +++ b/clients/web/src/test/integration/mcp/remote/server-extra-coverage.test.ts @@ -707,8 +707,8 @@ describe("server.ts supplemental coverage", () => { // client's `environment.fetch` is `createRemoteFetch()`, which forwards // OAuth discovery and token requests here. On the bare global `fetch` a // corporate-proxy user could connect to a server but never authorize - // against it, and Node's native NODE_USE_ENV_PROXY does not cover them - // (unsupported at the 22.19 engine floor). + // against it. Node's native NODE_USE_ENV_PROXY does not cover them + // unless the user opts in at process start, so it is no substitute. const { createServer } = await import("node:http"); const { request } = await import("node:http"); const seen: string[] = []; diff --git a/core/auth/node/file-secret-store.ts b/core/auth/node/file-secret-store.ts index 1e7e30db2b..90b3c32b2d 100644 --- a/core/auth/node/file-secret-store.ts +++ b/core/auth/node/file-secret-store.ts @@ -702,9 +702,9 @@ export class FileSecretStore implements SecretStore { try { const key = await this.deriveKey(parsed.kdf); // `authTagLength` pins the tag size at the cipher itself, not only in - // `encryptedEnvelopeProblem` above: Node 22 (our engines floor) will - // otherwise authenticate a tag truncated to 4 bytes, cutting a forgery - // to ~2^-32 per attempt (#2485). Newer Node rejects it on its own. + // `encryptedEnvelopeProblem` above: Node 22 and 24, both within our + // engines floor, will otherwise authenticate a tag truncated to 4 bytes, + // cutting a forgery to ~2^-32 per attempt (#2485). Node 26 rejects it. const decipher = crypto.createDecipheriv(CIPHER, key, parts.iv, { authTagLength: GCM_TAG_BYTES, }); diff --git a/core/mcp/node/proxyFetch.ts b/core/mcp/node/proxyFetch.ts index fe6e5a77aa..2b61c3513d 100644 --- a/core/mcp/node/proxyFetch.ts +++ b/core/mcp/node/proxyFetch.ts @@ -115,8 +115,8 @@ export function toGlobalResponse(res: UndiciResponse): Response { * ships 8, so a userland undici 8 agent handed a built-in undici 7 handler is * rejected with `invalid onRequestStart method` and the request never leaves the * process (#2067). Using undici's own `fetch` keeps the handler on both sides of - * the call inside one copy, which is why it works unchanged from the Node 22.19 - * engine floor through Node 26. + * the call inside one copy, which is why it works unchanged on every line the + * engine floor admits, Node 22 through Node 26. */ /** * Process-wide, so every client shares one `EnvHttpProxyAgent` and therefore one diff --git a/core/mcp/remote/node/server.ts b/core/mcp/remote/node/server.ts index 55e68ef426..4294de4a1b 100644 --- a/core/mcp/remote/node/server.ts +++ b/core/mcp/remote/node/server.ts @@ -1392,9 +1392,9 @@ export function createRemoteApp( // out to the network: the web client's `environment.fetch` is // `createRemoteFetch()`, which forwards OAuth discovery and token // requests here. Left on the global `fetch`, a corporate-proxy user could - // connect to a server but never authorize against it — and Node's native - // `NODE_USE_ENV_PROXY` does not cover them either, being unsupported at - // our 22.19 engine floor (#2067). The guard (#2749) reads the same proxy + // connect to a server but never authorize against it. Node's native + // `NODE_USE_ENV_PROXY` is present at our floor but opt-in at process + // start and still experimental (#2067). The guard (#2749) reads the same proxy // variables and routes through the same `EnvHttpProxyAgent` class. // // Guarded because some of these URLs come from the server under test: diff --git a/docs/cli-smoke-testing.md b/docs/cli-smoke-testing.md index 256e4a35e4..63011c511c 100644 --- a/docs/cli-smoke-testing.md +++ b/docs/cli-smoke-testing.md @@ -15,7 +15,7 @@ that composes those flags. > changed — see the [v1 → v2 migration guide](./v1-to-v2-migration.md) before > porting a v1 script. -**Prerequisites:** Node `>= 22.19.0` and [`jq`](https://jqlang.github.io/jq/) +**Prerequisites:** Node `^22.23.4 || ^24.22.1 || >=26.12.1` and [`jq`](https://jqlang.github.io/jq/) for the assertions. Every example invokes the CLI as `npx @modelcontextprotocol/inspector --cli`, which resolves the **latest** release each time it runs — fine while you are working at a terminal, wrong for diff --git a/docs/v1-to-v2-migration.md b/docs/v1-to-v2-migration.md index 9c2e34e12e..f175881aff 100644 --- a/docs/v1-to-v2-migration.md +++ b/docs/v1-to-v2-migration.md @@ -14,7 +14,7 @@ This guide is the map. It covers what breaks, what it becomes, and the handful o | | v1 | v2 | | ----------------- | ------------------------------------------------ | --------------------------------------------------------------- | -| Node | `>=22.7.5` | **`>=22.19.0`** | +| Node | `>=22.7.5` | **`^22.23.4 \|\| ^24.22.1 \|\| >=26.12.1`** | | npm packages | 4 (`inspector` + `-client` / `-server` / `-cli`) | **1** (`@modelcontextprotocol/inspector`) | | Processes / ports | web UI on `6274` **+ MCP proxy on `6277`** | one web server on `6274` (plus a dynamic MCP Apps sandbox port) | | Modes | web, `--cli` | web, `--cli`, **`--tui`** | @@ -30,7 +30,7 @@ The three changes most likely to bite an existing setup: ## Requirements -v2 requires **Node `>=22.19.0`** (v1 required `>=22.7.5`). The floor comes from `undici@^8`, used for HTTP proxy support. npm only _warns_ about an `engines` mismatch (`EBADENGINE`) unless you have `engine-strict=true` set, so an older Node won't stop you at install time — it fails later, obscurely. Check `node -v` first. +v2 requires **Node `^22.23.4 || ^24.22.1 || >=26.12.1`** (v1 required `>=22.7.5`). Two things set it. The 22.x minimum first came from `undici@^8`, used for HTTP proxy support, which needs `>=22.19.0`; that was v2's floor through v2.13. Since v2.14 the floor is the patched release on each supported line from the [October 2026 Node.js security releases](https://nodejs.org/en/blog/vulnerability/october-2026-security-releases), which update the bundled CA certificates and fix several high-severity TLS and DNS CVEs. The Inspector ships no CA certificates of its own, so every HTTPS connection it makes, OAuth included, is only as safe as the Node it runs on. A per-line range rather than a plain `>=22.23.4` is what keeps an unpatched 24.x or 26.x from satisfying it. npm only _warns_ about an `engines` mismatch (`EBADENGINE`) unless you have `engine-strict=true` set, so an older Node won't stop you at install time — it fails later, obscurely. Check `node -v` first. ## What no longer ships diff --git a/package-lock.json b/package-lock.json index bcfc09e634..33abdd11c0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55,7 +55,7 @@ "vitest": "4.1.11" }, "engines": { - "node": ">=22.19.0" + "node": "^22.23.4 || ^24.22.1 || >=26.12.1" } }, "node_modules/@alcalzone/ansi-tokenize": { diff --git a/package.json b/package.json index 9974b1bbec..e7b7381c4c 100644 --- a/package.json +++ b/package.json @@ -148,7 +148,7 @@ "zod": "^4.4.3" }, "engines": { - "node": ">=22.19.0" + "node": "^22.23.4 || ^24.22.1 || >=26.12.1" }, "allowScripts": { "fsevents": false diff --git a/scripts/verify-typecheck-coverage.mjs b/scripts/verify-typecheck-coverage.mjs index 9f98e12146..1f71e2c4be 100644 --- a/scripts/verify-typecheck-coverage.mjs +++ b/scripts/verify-typecheck-coverage.mjs @@ -88,7 +88,7 @@ export const isRequiredSource = (rel) => /** * Whether a tracked test file is matched by one of the `test:scripts` command's * globs. Delegates to node's own `path.matchesGlob` (22.5.0+; the repo floor is - * `>=22.19.0`) rather than hand-translating the glob to a RegExp — `node --test` + * `^22.23.4`) rather than hand-translating the glob to a RegExp — `node --test` * is the thing whose matching we're modeling, so measuring with node's matcher * is exact for every form it accepts (`**` incl. zero depth, `*`, `?` as exactly * one non-separator char, brace alternation, character classes) instead of diff --git a/specification/v2_cli_tui_launcher.md b/specification/v2_cli_tui_launcher.md index f8a91f41b7..75e6c2901b 100644 --- a/specification/v2_cli_tui_launcher.md +++ b/specification/v2_cli_tui_launcher.md @@ -66,7 +66,7 @@ Root scripts `inspector`, `web`, and `web:dev` are thin wrappers around the laun **Production web caveat:** launcher `prebuild` chains `build:runner` for web, not a full `vite build`. Running `mcp-inspector --web` (without `--dev`) requires `clients/web/dist/` from a prior `cd clients/web && npm run build`. CI builds CLI, TUI, and launcher before the launcher smoke step but does not currently validate prod web startup end-to-end. -**Build targets:** client `tsdown` bundles target `node22`, aligned with root `engines.node` (`>=22.19.0`). +**Build targets:** client `tsdown` bundles target `node22`, aligned with root `engines.node` (`^22.23.4 || ^24.22.1 || >=26.12.1`). --- From 1b339db55cbc0e3a7b2bdee18688d52d2a362efe Mon Sep 17 00:00:00 2001 From: cliffhall Date: Wed, 28 Oct 2026 23:43:20 -0400 Subject: [PATCH 2/4] chore(deps): refresh @modelcontextprotocol/ext-apps to 2.0.4 (#2811) Lockfile-only: ^2.0.0 already admits 2.0.4. Upstream calls it a patch of example and dependency changes with no library API change; its exports map and dependency set are identical to 2.0.3, so the bundler externals need no change. Co-Authored-By: Claude Opus 5.5 Signed-off-by: cliffhall --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 33abdd11c0..f6549b7d0b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -676,9 +676,9 @@ } }, "node_modules/@modelcontextprotocol/ext-apps": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/ext-apps/-/ext-apps-2.0.3.tgz", - "integrity": "sha512-Tn+4+cyhO4f4cQSDxNyLiIfEE+qlTTuIbWBJB8JTinEXOhDYgCT4wDTQplxD9MBYZH5pCYGC59GaxiwIT4bu8w==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/ext-apps/-/ext-apps-2.0.4.tgz", + "integrity": "sha512-B+PcbuGiaf0e5I3uy4iO5tS3Abo+5w8JvZFzHMzQdq9yVwP836zJkw2+KCGOQ0r4TM1fuQi4JdnbuWjkS4aBvg==", "license": "MIT", "workspaces": [ "examples/*" From 66a96d1d12bf5c74d81e20acbe36f708474c8252 Mon Sep 17 00:00:00 2001 From: cliffhall Date: Wed, 28 Oct 2026 23:43:20 -0400 Subject: [PATCH 3/4] chore(deps): bump vitest to 4.1.12 and ip-address to 10.7.5 (#2814) The four-edit vitest bump: the exact pins on vitest and @vitest/coverage-v8 (root) and @vitest/browser-playwright (web), plus web's vitest overrides entry. Clears GHSA-qxg6-89mg-rqv8 and GHSA-xp26-3454-mjgp, and the @storybook/addon-vitest finding that was only inherited from vitest. ip-address (transitive, via server-legacy -> express-rate-limit ^10.2.0) is an in-range npm update, so no overrides entry. fast-uri was already fixed at 3.1.9 by #2820. Co-Authored-By: Claude Opus 5.5 Signed-off-by: cliffhall --- clients/web/package-lock.json | 126 ++++++++++++++++----------------- clients/web/package.json | 4 +- package-lock.json | 128 +++++++++++++++++----------------- package.json | 4 +- 4 files changed, 131 insertions(+), 131 deletions(-) diff --git a/clients/web/package-lock.json b/clients/web/package-lock.json index 263de1b9e9..9743c1af8e 100644 --- a/clients/web/package-lock.json +++ b/clients/web/package-lock.json @@ -43,7 +43,7 @@ "@types/react-dom": "^19.2.3", "@types/react-syntax-highlighter": "^15.5.13", "@vitejs/plugin-react": "^6.0.0", - "@vitest/browser-playwright": "4.1.11", + "@vitest/browser-playwright": "4.1.12", "eslint-plugin-react-hooks": "^7.1.1", "eslint-plugin-react-refresh": "^0.5.2", "eslint-plugin-storybook": "^10.5.5", @@ -3321,15 +3321,15 @@ } }, "node_modules/@vitest/browser": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-4.1.11.tgz", - "integrity": "sha512-bwMovvAeuTFOK5kIFevw4VEf+1gVEICv4SYK4k3knJOxl6b1zEWud8mYKD73e1B0odAn174h1MofURy2TPWf3w==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-4.1.12.tgz", + "integrity": "sha512-Yl/6JIxJrcMlWMqKPoRkMhZy9sDpaAXdSJ+90hMVEJVE94tVysjp34SXTwCXJSIXjAtW2ha33qEjMeGG0G/Z0Q==", "dev": true, "license": "MIT", "dependencies": { "@blazediff/core": "1.9.1", - "@vitest/mocker": "4.1.11", - "@vitest/utils": "4.1.11", + "@vitest/mocker": "4.1.12", + "@vitest/utils": "4.1.12", "magic-string": "^0.30.21", "pngjs": "^7.0.0", "sirv": "^3.0.2", @@ -3340,18 +3340,18 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "vitest": "4.1.11" + "vitest": "4.1.12" } }, "node_modules/@vitest/browser-playwright": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/browser-playwright/-/browser-playwright-4.1.11.tgz", - "integrity": "sha512-riLBxPqwnJ0lWs2DN2WeUfYeKLoAjbP2Xx8cLQdSddzMi20sksIa6K2mPz79DyMZKKVKH2ksOC2yJvtNcZg8cg==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/browser-playwright/-/browser-playwright-4.1.12.tgz", + "integrity": "sha512-bU/TcyiBwFUijaIltxKXxgpQmLu9njO/t6G9wiD2LjSFX6SfmyUOf+pOJ8N26KsvhFOHWfVdzNS6P62ab/ONlA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/browser": "4.1.11", - "@vitest/mocker": "4.1.11", + "@vitest/browser": "4.1.12", + "@vitest/mocker": "4.1.12", "tinyrainbow": "^3.1.0" }, "funding": { @@ -3359,7 +3359,7 @@ }, "peerDependencies": { "playwright": "*", - "vitest": "4.1.11" + "vitest": "4.1.12" }, "peerDependenciesMeta": { "playwright": { @@ -3436,13 +3436,13 @@ } }, "node_modules/@vitest/mocker": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.11.tgz", - "integrity": "sha512-2XJVD55d1o5AZous5CCGKS74g/riOj9odEt2bQpCVZeblHyHdnMeFl4jl0XjU21stf4mbjUkew2eXQZt65g5CQ==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.12.tgz", + "integrity": "sha512-fKShNpKZzupWZuY0z7egydvL0sqW4INEZBEExMBMAa6izlENEVHwoXgdaTCaBZ5fwlr4xf2o1wXC83n9RpO+NA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "4.1.11", + "@vitest/spy": "4.1.12", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, @@ -3473,9 +3473,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.11.tgz", - "integrity": "sha512-yiZzPbGTS9Sr/JpFl8zHrcIkAofNbFV6k21vIgQN/cY/oxZeXhJv5sc/MBJ5jFKWmWs+oJHw0UXLZjmf931+Vw==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.12.tgz", + "integrity": "sha512-XW9O8+Mxx4VpCtkYdMJLZQQwsVryP9wk7cPKDxtXFfwSak6yRh5+2fep/Y0XF/ElBvJHq8bcYdi6aeuai0opZA==", "dev": true, "license": "MIT", "dependencies": { @@ -3486,14 +3486,14 @@ } }, "node_modules/@vitest/runner": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.11.tgz", - "integrity": "sha512-LztvUgdwMNJMIkj3hQnnxiC2Xy1zNxq928W/xhjCLaNCzqTZOudjwbQf6v9IntZGPw132i2Lq2rgTRZHD3JHNw==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.12.tgz", + "integrity": "sha512-NKlVKCr5QnCe8jijdMnmkpHHU+WTqiLFR6G0pHji9uRjXK9xJl1k1nTw6F3pOOj2PDcsDt2GKQMI7wIsaT491w==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@vitest/utils": "4.1.11", + "@vitest/utils": "4.1.12", "pathe": "^2.0.3" }, "funding": { @@ -3501,15 +3501,15 @@ } }, "node_modules/@vitest/snapshot": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.11.tgz", - "integrity": "sha512-pN7ikn1ON7h8ee4gIAp4AzyK+zBtJPzVbqOgu5LCEh4VaJVbPQcgYQYJIMGQPXVeJJq1fnfazis7a5pFNPahog==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.12.tgz", + "integrity": "sha512-ko1y1Qgb/slzQ9mr+b89Cuqud8WG1TKtsPD8r7ZUBdvVOGt85Af2HwCqHujrhwJq95hs/9RM7fcAPg57o1vlzw==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@vitest/pretty-format": "4.1.11", - "@vitest/utils": "4.1.11", + "@vitest/pretty-format": "4.1.12", + "@vitest/utils": "4.1.12", "magic-string": "^0.30.21", "pathe": "^2.0.3" }, @@ -3518,9 +3518,9 @@ } }, "node_modules/@vitest/spy": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.11.tgz", - "integrity": "sha512-apNa/prQy2qCeywhnixOHPRCgGNhvg7T4Dapfl1GahLp/R+uhBm5cPyFoNVyqsNd2h1nJxL6BqqdIjiABL60YA==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.12.tgz", + "integrity": "sha512-RGq9x4JNGNTZHEJxvN0oSiJjeSCExm0n2gZKKJZHY9cX5AVA6M7VJILBT3ZJ/tJ/0J9uWT7fETV9/btoi//vSg==", "dev": true, "license": "MIT", "funding": { @@ -3528,13 +3528,13 @@ } }, "node_modules/@vitest/utils": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.11.tgz", - "integrity": "sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.12.tgz", + "integrity": "sha512-Q3awXrwOfEV+qc3WmO5ONyE0yO7Q1gQ9/oyHxGLZ/pl7N3NO/ZztqQwKLuwMkV+CA1JYSIeO3gkHnRDIo4AVaA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.11", + "@vitest/pretty-format": "4.1.12", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" }, @@ -8013,9 +8013,9 @@ "peer": true }, "node_modules/std-env": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.2.0.tgz", - "integrity": "sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.3.0.tgz", + "integrity": "sha512-OtU/EgQ1kIm5KwqQpBC6ZEMXrZRui11w8zgfTWp8cdO9B8OaPsbA8bTHO2P+HNo1VlUTGMVBwPhydu6poeXiag==", "dev": true, "license": "MIT", "peer": true @@ -8872,20 +8872,20 @@ } }, "node_modules/vitest": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.11.tgz", - "integrity": "sha512-fhACrNXUidIbGSBr5FlbuBkO7VWC1ZyLl0DO4CU2DrQoAPxX84Ysxs+HeGQpii5lZWV1Q4gBZTTu49mF+A6Edw==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.12.tgz", + "integrity": "sha512-5eWdz2yb3ajxWF3C8C4TjkXl7FGm3n2E/VlazALrQHzK7nYMSGFnCZto0bbPNl77AwkOZVLk0YnBAejUu0NiWA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@vitest/expect": "4.1.11", - "@vitest/mocker": "4.1.11", - "@vitest/pretty-format": "4.1.11", - "@vitest/runner": "4.1.11", - "@vitest/snapshot": "4.1.11", - "@vitest/spy": "4.1.11", - "@vitest/utils": "4.1.11", + "@vitest/expect": "4.1.12", + "@vitest/mocker": "4.1.12", + "@vitest/pretty-format": "4.1.12", + "@vitest/runner": "4.1.12", + "@vitest/snapshot": "4.1.12", + "@vitest/spy": "4.1.12", + "@vitest/utils": "4.1.12", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", @@ -8913,12 +8913,12 @@ "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "4.1.11", - "@vitest/browser-preview": "4.1.11", - "@vitest/browser-webdriverio": "4.1.11", - "@vitest/coverage-istanbul": "4.1.11", - "@vitest/coverage-v8": "4.1.11", - "@vitest/ui": "4.1.11", + "@vitest/browser-playwright": "4.1.12", + "@vitest/browser-preview": "4.1.12", + "@vitest/browser-webdriverio": "^4.1.11", + "@vitest/coverage-istanbul": "4.1.12", + "@vitest/coverage-v8": "4.1.12", + "@vitest/ui": "4.1.12", "happy-dom": "*", "jsdom": "*", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" @@ -8963,17 +8963,17 @@ } }, "node_modules/vitest/node_modules/@vitest/expect": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.11.tgz", - "integrity": "sha512-VX2x5vNJXET47KAFzwERI+KRMtTTCSWTfSMKsW7JsUsXV4psq++e3DvZpuTDOpHcxytiDs6p2nhVb2tVDiiUYw==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.12.tgz", + "integrity": "sha512-vFlTt+YEu9WBpNjdGayNmlMVzrWPi1+sv853/7t2FU7hpO5gAFBKHzQmkCq5Xjpr+evegF2994LQT3hF3mRlqQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", - "@vitest/spy": "4.1.11", - "@vitest/utils": "4.1.11", + "@vitest/spy": "4.1.12", + "@vitest/utils": "4.1.12", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" }, @@ -8982,9 +8982,9 @@ } }, "node_modules/vitest/node_modules/chai": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", - "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.3.0.tgz", + "integrity": "sha512-XWAtwJ6OHO+tj0EKCs0Y2UamnyOxseZWltU4x2U2wh8g4AigdjwvtUjvLP2tqkA/avxHEtzxNaqGq/YGNwckKg==", "dev": true, "license": "MIT", "peer": true, diff --git a/clients/web/package.json b/clients/web/package.json index 6249a34b55..e6802c53f3 100644 --- a/clients/web/package.json +++ b/clients/web/package.json @@ -71,7 +71,7 @@ "@types/react-dom": "^19.2.3", "@types/react-syntax-highlighter": "^15.5.13", "@vitejs/plugin-react": "^6.0.0", - "@vitest/browser-playwright": "4.1.11", + "@vitest/browser-playwright": "4.1.12", "eslint-plugin-react-hooks": "^7.1.1", "eslint-plugin-react-refresh": "^0.5.2", "eslint-plugin-storybook": "^10.5.5", @@ -86,7 +86,7 @@ "@types/node": "^24.12.4", "esbuild": "^0.28.2", "open": "^11.0.4", - "vitest": "4.1.11", + "vitest": "4.1.12", "rolldown": "1.2.13" } } diff --git a/package-lock.json b/package-lock.json index f6549b7d0b..4b1baa8ed6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,7 +43,7 @@ "@modelcontextprotocol/server-legacy": "2.4.0", "@types/node": "^24.12.4", "@types/proper-lockfile": "^4.1.4", - "@vitest/coverage-v8": "4.1.11", + "@vitest/coverage-v8": "4.1.12", "eslint": "^10.8.0", "eslint-plugin-react-hooks": "^7.1.1", "express": "^5.2.1", @@ -52,7 +52,7 @@ "semver": "^7.8.5", "typescript": "~5.9.3", "typescript-eslint": "^8.65.0", - "vitest": "4.1.11" + "vitest": "4.1.12" }, "engines": { "node": "^22.23.4 || ^24.22.1 || >=26.12.1" @@ -1611,14 +1611,14 @@ } }, "node_modules/@vitest/coverage-v8": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.11.tgz", - "integrity": "sha512-8MVGEFnJIcdGjcbfKmeq8z0pZHH0JlVtoVZH9Q/qwUp6wyFnEJUBMrw9DCaj+ra3vShGmhavjalMIhPNxZAUcw==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.12.tgz", + "integrity": "sha512-6S7/iVknKglLAxMFxQGNppBI0iqJS2NgM6FBxavitj7KaDq/vywOWGf6dGu7F2L1Qy0G6S3uTp7aGshHrzK8JA==", "dev": true, "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^1.0.2", - "@vitest/utils": "4.1.11", + "@vitest/utils": "4.1.12", "ast-v8-to-istanbul": "^1.0.0", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", @@ -1632,8 +1632,8 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@vitest/browser": "4.1.11", - "vitest": "4.1.11" + "@vitest/browser": "4.1.12", + "vitest": "4.1.12" }, "peerDependenciesMeta": { "@vitest/browser": { @@ -1642,16 +1642,16 @@ } }, "node_modules/@vitest/expect": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.11.tgz", - "integrity": "sha512-VX2x5vNJXET47KAFzwERI+KRMtTTCSWTfSMKsW7JsUsXV4psq++e3DvZpuTDOpHcxytiDs6p2nhVb2tVDiiUYw==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.12.tgz", + "integrity": "sha512-vFlTt+YEu9WBpNjdGayNmlMVzrWPi1+sv853/7t2FU7hpO5gAFBKHzQmkCq5Xjpr+evegF2994LQT3hF3mRlqQ==", "dev": true, "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", - "@vitest/spy": "4.1.11", - "@vitest/utils": "4.1.11", + "@vitest/spy": "4.1.12", + "@vitest/utils": "4.1.12", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" }, @@ -1660,13 +1660,13 @@ } }, "node_modules/@vitest/mocker": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.11.tgz", - "integrity": "sha512-2XJVD55d1o5AZous5CCGKS74g/riOj9odEt2bQpCVZeblHyHdnMeFl4jl0XjU21stf4mbjUkew2eXQZt65g5CQ==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.12.tgz", + "integrity": "sha512-fKShNpKZzupWZuY0z7egydvL0sqW4INEZBEExMBMAa6izlENEVHwoXgdaTCaBZ5fwlr4xf2o1wXC83n9RpO+NA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "4.1.11", + "@vitest/spy": "4.1.12", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, @@ -1687,9 +1687,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.11.tgz", - "integrity": "sha512-yiZzPbGTS9Sr/JpFl8zHrcIkAofNbFV6k21vIgQN/cY/oxZeXhJv5sc/MBJ5jFKWmWs+oJHw0UXLZjmf931+Vw==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.12.tgz", + "integrity": "sha512-XW9O8+Mxx4VpCtkYdMJLZQQwsVryP9wk7cPKDxtXFfwSak6yRh5+2fep/Y0XF/ElBvJHq8bcYdi6aeuai0opZA==", "dev": true, "license": "MIT", "dependencies": { @@ -1700,13 +1700,13 @@ } }, "node_modules/@vitest/runner": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.11.tgz", - "integrity": "sha512-LztvUgdwMNJMIkj3hQnnxiC2Xy1zNxq928W/xhjCLaNCzqTZOudjwbQf6v9IntZGPw132i2Lq2rgTRZHD3JHNw==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.12.tgz", + "integrity": "sha512-NKlVKCr5QnCe8jijdMnmkpHHU+WTqiLFR6G0pHji9uRjXK9xJl1k1nTw6F3pOOj2PDcsDt2GKQMI7wIsaT491w==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "4.1.11", + "@vitest/utils": "4.1.12", "pathe": "^2.0.3" }, "funding": { @@ -1714,14 +1714,14 @@ } }, "node_modules/@vitest/snapshot": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.11.tgz", - "integrity": "sha512-pN7ikn1ON7h8ee4gIAp4AzyK+zBtJPzVbqOgu5LCEh4VaJVbPQcgYQYJIMGQPXVeJJq1fnfazis7a5pFNPahog==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.12.tgz", + "integrity": "sha512-ko1y1Qgb/slzQ9mr+b89Cuqud8WG1TKtsPD8r7ZUBdvVOGt85Af2HwCqHujrhwJq95hs/9RM7fcAPg57o1vlzw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.11", - "@vitest/utils": "4.1.11", + "@vitest/pretty-format": "4.1.12", + "@vitest/utils": "4.1.12", "magic-string": "^0.30.21", "pathe": "^2.0.3" }, @@ -1730,9 +1730,9 @@ } }, "node_modules/@vitest/spy": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.11.tgz", - "integrity": "sha512-apNa/prQy2qCeywhnixOHPRCgGNhvg7T4Dapfl1GahLp/R+uhBm5cPyFoNVyqsNd2h1nJxL6BqqdIjiABL60YA==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.12.tgz", + "integrity": "sha512-RGq9x4JNGNTZHEJxvN0oSiJjeSCExm0n2gZKKJZHY9cX5AVA6M7VJILBT3ZJ/tJ/0J9uWT7fETV9/btoi//vSg==", "dev": true, "license": "MIT", "funding": { @@ -1740,13 +1740,13 @@ } }, "node_modules/@vitest/utils": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.11.tgz", - "integrity": "sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.12.tgz", + "integrity": "sha512-Q3awXrwOfEV+qc3WmO5ONyE0yO7Q1gQ9/oyHxGLZ/pl7N3NO/ZztqQwKLuwMkV+CA1JYSIeO3gkHnRDIo4AVaA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.11", + "@vitest/pretty-format": "4.1.12", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" }, @@ -2107,9 +2107,9 @@ "license": "CC-BY-4.0" }, "node_modules/chai": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", - "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.3.0.tgz", + "integrity": "sha512-XWAtwJ6OHO+tj0EKCs0Y2UamnyOxseZWltU4x2U2wh8g4AigdjwvtUjvLP2tqkA/avxHEtzxNaqGq/YGNwckKg==", "dev": true, "license": "MIT", "engines": { @@ -3345,9 +3345,9 @@ } }, "node_modules/ip-address": { - "version": "10.7.2", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.7.2.tgz", - "integrity": "sha512-7H/2gFSIitxc0hG3nOI1glS8QLo/EHBFFLk8vEUjXY/xu0AdL8jZ9U1IzO2PUm0d2D/ofQcAifb0g6OBkt8U7w==", + "version": "10.7.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.7.5.tgz", + "integrity": "sha512-t2v0rkILYv9WXmSL7TpAaU3HXgaFYOPUcH3QHgwQ++gpJuH3bqyMy4Fvt/DJCTKwzH3Cf+bAp5W/mFL39KPLzA==", "dev": true, "license": "MIT", "engines": { @@ -4936,9 +4936,9 @@ } }, "node_modules/std-env": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.2.0.tgz", - "integrity": "sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.3.0.tgz", + "integrity": "sha512-OtU/EgQ1kIm5KwqQpBC6ZEMXrZRui11w8zgfTWp8cdO9B8OaPsbA8bTHO2P+HNo1VlUTGMVBwPhydu6poeXiag==", "dev": true, "license": "MIT" }, @@ -5068,9 +5068,9 @@ } }, "node_modules/tinyrainbow": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.1.tgz", - "integrity": "sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.2.0.tgz", + "integrity": "sha512-LgO3D9yZJjApUiuUfl9iFAwrtaX4+lok3wJIqttGoKCHlWUqHqbQpnxCf82L8FjgKsh4iGo78hqJwgL8F6To2A==", "dev": true, "license": "MIT", "engines": { @@ -5354,19 +5354,19 @@ } }, "node_modules/vitest": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.11.tgz", - "integrity": "sha512-fhACrNXUidIbGSBr5FlbuBkO7VWC1ZyLl0DO4CU2DrQoAPxX84Ysxs+HeGQpii5lZWV1Q4gBZTTu49mF+A6Edw==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.12.tgz", + "integrity": "sha512-5eWdz2yb3ajxWF3C8C4TjkXl7FGm3n2E/VlazALrQHzK7nYMSGFnCZto0bbPNl77AwkOZVLk0YnBAejUu0NiWA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/expect": "4.1.11", - "@vitest/mocker": "4.1.11", - "@vitest/pretty-format": "4.1.11", - "@vitest/runner": "4.1.11", - "@vitest/snapshot": "4.1.11", - "@vitest/spy": "4.1.11", - "@vitest/utils": "4.1.11", + "@vitest/expect": "4.1.12", + "@vitest/mocker": "4.1.12", + "@vitest/pretty-format": "4.1.12", + "@vitest/runner": "4.1.12", + "@vitest/snapshot": "4.1.12", + "@vitest/spy": "4.1.12", + "@vitest/utils": "4.1.12", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", @@ -5394,12 +5394,12 @@ "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "4.1.11", - "@vitest/browser-preview": "4.1.11", - "@vitest/browser-webdriverio": "4.1.11", - "@vitest/coverage-istanbul": "4.1.11", - "@vitest/coverage-v8": "4.1.11", - "@vitest/ui": "4.1.11", + "@vitest/browser-playwright": "4.1.12", + "@vitest/browser-preview": "4.1.12", + "@vitest/browser-webdriverio": "^4.1.11", + "@vitest/coverage-istanbul": "4.1.12", + "@vitest/coverage-v8": "4.1.12", + "@vitest/ui": "4.1.12", "happy-dom": "*", "jsdom": "*", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" diff --git a/package.json b/package.json index e7b7381c4c..c25a3a41bf 100644 --- a/package.json +++ b/package.json @@ -158,7 +158,7 @@ "@modelcontextprotocol/server-legacy": "2.4.0", "@types/node": "^24.12.4", "@types/proper-lockfile": "^4.1.4", - "@vitest/coverage-v8": "4.1.11", + "@vitest/coverage-v8": "4.1.12", "eslint": "^10.8.0", "eslint-plugin-react-hooks": "^7.1.1", "express": "^5.2.1", @@ -167,6 +167,6 @@ "semver": "^7.8.5", "typescript": "~5.9.3", "typescript-eslint": "^8.65.0", - "vitest": "4.1.11" + "vitest": "4.1.12" } } From 00bbec38b9697721d17279bbf581b5f4a2887a38 Mon Sep 17 00:00:00 2001 From: cliffhall Date: Wed, 28 Oct 2026 23:43:20 -0400 Subject: [PATCH 4/4] chore(deps): bump happy-dom to 21.0.4 past GHSA-834v-8h66-3h79 (#2813) happy-dom 21 turns iframe page loading off by default. The web unit project already stopped child-frame navigation, but with loading off every sandbox iframe now logs a NotSupportedError and gets no contentWindow. Turning enableIframePageLoading back on restores the previous behavior; the navigation flag still stops the frame before it fetches anything. Co-Authored-By: Claude Opus 5.5 Signed-off-by: cliffhall --- clients/web/package-lock.json | 14 +++++++------- clients/web/package.json | 2 +- clients/web/src/test/setup.ts | 2 +- clients/web/vite.config.ts | 13 ++++++++++++- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/clients/web/package-lock.json b/clients/web/package-lock.json index 9743c1af8e..a80bb685a0 100644 --- a/clients/web/package-lock.json +++ b/clients/web/package-lock.json @@ -47,7 +47,7 @@ "eslint-plugin-react-hooks": "^7.1.1", "eslint-plugin-react-refresh": "^0.5.2", "eslint-plugin-storybook": "^10.5.5", - "happy-dom": "^20.11.2", + "happy-dom": "^21.0.4", "playwright": "^1.58.2", "storybook": "^10.5.5", "tsdown": "^0.23.1", @@ -3134,9 +3134,9 @@ "license": "MIT" }, "node_modules/@types/ws": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", - "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.2.tgz", + "integrity": "sha512-67MQl+fpWKVTT1NYdnmo3U4sc/xPo/zQBncVnI74qmQa0z/b+1g6iYqNmGCPbxO+zz2aklb08a0oHfegiVd0/w==", "dev": true, "license": "MIT", "dependencies": { @@ -5004,9 +5004,9 @@ "optional": true }, "node_modules/happy-dom": { - "version": "20.14.5", - "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-20.14.5.tgz", - "integrity": "sha512-x/RzkpWO40bTjIoT30iQtt64FLLmH/iRcUCN2X//bLx7H3ifkdfPXyqsro/OYtqzIAhiLMMA7mmiOR9C3NOKjQ==", + "version": "21.0.4", + "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-21.0.4.tgz", + "integrity": "sha512-tFm+GaLBgo6o0awHnvHaNoraVo27qJ+2tZEtZ+cIa08hXbeitrxAJajLI05hsUy/2/YTKcUjQYzHe5mCcraLBw==", "dev": true, "license": "MIT", "dependencies": { diff --git a/clients/web/package.json b/clients/web/package.json index e6802c53f3..ef9a491342 100644 --- a/clients/web/package.json +++ b/clients/web/package.json @@ -75,7 +75,7 @@ "eslint-plugin-react-hooks": "^7.1.1", "eslint-plugin-react-refresh": "^0.5.2", "eslint-plugin-storybook": "^10.5.5", - "happy-dom": "^20.11.2", + "happy-dom": "^21.0.4", "playwright": "^1.58.2", "storybook": "^10.5.5", "tsdown": "^0.23.1", diff --git a/clients/web/src/test/setup.ts b/clients/web/src/test/setup.ts index aeb1751234..363d9c2f53 100644 --- a/clients/web/src/test/setup.ts +++ b/clients/web/src/test/setup.ts @@ -116,7 +116,7 @@ Object.defineProperty(globalThis, "fetch", { ), }); -// happy-dom (v20) *does* implement `matchMedia`/`MediaQueryList`, so this isn't +// happy-dom (v21) *does* implement `matchMedia`/`MediaQueryList`, so this isn't // a polyfill for a missing API — it's a deliberate **override** of happy-dom's // implementation, pinning `prefers-reduced-motion: reduce` and reporting `false` // for every other query (preserving the historical absent-matchMedia layout diff --git a/clients/web/vite.config.ts b/clients/web/vite.config.ts index da458a8a62..4c544b1222 100644 --- a/clients/web/vite.config.ts +++ b/clients/web/vite.config.ts @@ -321,9 +321,20 @@ export default defineConfig(({ command }) => { // `AsyncTaskManager destroyed` output. The component tests only assert // on the iframe element/attributes, not its loaded document, so // disabling frame navigation removes the noise without losing coverage. + // + // `enableIframePageLoading` keeps that arrangement on happy-dom 21, + // which turned iframe loading OFF by default (an SSRF fix). With it + // off, every sandbox iframe logs a `NotSupportedError` "Iframe page + // loading is disabled" and gets no `contentWindow`. Turned back on, + // the iframe gets its child frame as before, and the + // navigation flag above still stops that frame before it fetches + // anything, so no request leaves the test process either way. environmentOptions: { happyDOM: { - settings: { navigation: { disableChildFrameNavigation: true } }, + settings: { + enableIframePageLoading: true, + navigation: { disableChildFrameNavigation: true }, + }, }, }, // Root the unit project at the repo root so vitest's coverage