From 50e813c9e98cedabb0a3d968e872e8ed8a85c8ac Mon Sep 17 00:00:00 2001 From: Madhavi Pasumarthi Date: Sat, 14 Feb 2026 15:00:34 -0500 Subject: [PATCH 01/15] fix(mcp) : improve tool invocation reliability for agents Addresses cases where DevTools MCP tools were not consistently picked up from natural language prompts by improving tool descriptions and metadata. Refs #940 --- src/tools/performance.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/performance.ts b/src/tools/performance.ts index 393d38f15..7f0612a27 100644 --- a/src/tools/performance.ts +++ b/src/tools/performance.ts @@ -28,7 +28,7 @@ const filePathSchema = zod export const startTrace = defineTool({ name: 'performance_start_trace', - description: `Starts a performance trace recording on the selected page. This can be used to look for performance problems and insights to improve the performance of the page. It will also report Core Web Vital (CWV) scores for the page.`, + description: `Start a performance trace on the selected webpage. Use to find frontend performance issues, Core Web Vitals (LCP, FID, CLS), and improve page load speed.`, annotations: { category: ToolCategory.PERFORMANCE, readOnlyHint: false, @@ -115,7 +115,7 @@ export const startTrace = defineTool({ export const stopTrace = defineTool({ name: 'performance_stop_trace', description: - 'Stops the active performance trace recording on the selected page.', + 'Stop the active performance trace recording on the selected webpage.', annotations: { category: ToolCategory.PERFORMANCE, readOnlyHint: false, From 42d30c244dfc6d53b262833e12eb840e0d16938d Mon Sep 17 00:00:00 2001 From: Madhavi Pasumarthi Date: Tue, 17 Feb 2026 07:25:50 -0500 Subject: [PATCH 02/15] fix(mcp): update Core Web Vitals references from FID to INP Refs #940 --- src/tools/performance.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/performance.ts b/src/tools/performance.ts index 7f0612a27..b7d8cd399 100644 --- a/src/tools/performance.ts +++ b/src/tools/performance.ts @@ -28,7 +28,7 @@ const filePathSchema = zod export const startTrace = defineTool({ name: 'performance_start_trace', - description: `Start a performance trace on the selected webpage. Use to find frontend performance issues, Core Web Vitals (LCP, FID, CLS), and improve page load speed.`, + description: `Start a performance trace on the selected webpage. Use to find frontend performance issues, Core Web Vitals (LCP, INP, CLS), and improve page load speed.`, annotations: { category: ToolCategory.PERFORMANCE, readOnlyHint: false, From 95b1d0aaea1228c7e190ca1451ca3db7fc9985c0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Feb 2026 12:32:25 +0100 Subject: [PATCH 03/15] chore(deps-dev): bump the dev-dependencies group with 4 updates (#983) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the dev-dependencies group with 4 updates: [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin), [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser), [rollup-plugin-license](https://github.com/mjeanroy/rollup-plugin-license) and [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint). Updates `@typescript-eslint/eslint-plugin` from 8.55.0 to 8.56.0
Release notes

Sourced from @​typescript-eslint/eslint-plugin's releases.

v8.56.0

8.56.0 (2026-02-16)

🚀 Features

🩹 Fixes

  • use parser options from context.languageOptions (#12043)

❤️ Thank You

See GitHub Releases for more information.

You can read about our versioning strategy and releases on our website.

Changelog

Sourced from @​typescript-eslint/eslint-plugin's changelog.

8.56.0 (2026-02-16)

🚀 Features

🩹 Fixes

  • use parser options from context.languageOptions (#12043)

❤️ Thank You

See GitHub Releases for more information.

You can read about our versioning strategy and releases on our website.

Commits

Updates `@typescript-eslint/parser` from 8.55.0 to 8.56.0
Release notes

Sourced from @​typescript-eslint/parser's releases.

v8.56.0

8.56.0 (2026-02-16)

🚀 Features

🩹 Fixes

  • use parser options from context.languageOptions (#12043)

❤️ Thank You

See GitHub Releases for more information.

You can read about our versioning strategy and releases on our website.

Changelog

Sourced from @​typescript-eslint/parser's changelog.

8.56.0 (2026-02-16)

🚀 Features

❤️ Thank You

See GitHub Releases for more information.

You can read about our versioning strategy and releases on our website.

Commits

Updates `rollup-plugin-license` from 3.6.0 to 3.7.0
Changelog

Sourced from rollup-plugin-license's changelog.

3.5.0 (2024-06-22)

  • release: prepare next release (71f5bcf)
  • release: prepare next release (2c51c64)
  • release: release version (f27f51d)
  • release: release version (8a7f79c)
  • chore: fix lint task (a7c455f)
  • chore: remove (deprecated) eslint-config-google (0ba031f)
  • chore(ci): push release to current branch (03112e9)
  • chore(deps-dev): bump @​rollup/plugin-commonjs from 25.0.7 to 25.0.8 (#1732) (8bd6fb3), closes #1732
  • chore(deps-dev): bump @​rollup/plugin-commonjs from 25.0.8 to 26.0.1 (#1741) (25f03f2), closes #1741
  • chore(deps-dev): bump globalthis from 1.0.3 to 1.0.4 (#1721) (54084da), closes #1721
  • chore(deps-dev): bump gulp-conventional-changelog from 4.0.0 to 5.0.0 (#1723) (d6ae13f), closes #1723
  • chore(deps-dev): bump prettier from 3.2.5 to 3.3.0 (#1737) (3e80b2a), closes #1737
  • chore(deps-dev): bump prettier from 3.3.0 to 3.3.1 (#1740) (ef8aabf), closes #1740
  • chore(deps-dev): bump prettier from 3.3.1 to 3.3.2 (#1746) (e4fbe41), closes #1746
  • chore(deps-dev): bump rimraf from 5.0.5 to 5.0.7 (#1727) (44fd2d4), closes #1727
  • chore(deps-dev): bump rollup from 4.14.3 to 4.16.2 (#1715) (0126778), closes #1715
  • chore(deps-dev): bump rollup from 4.16.2 to 4.16.4 (#1716) (2256205), closes #1716
  • chore(deps-dev): bump rollup from 4.16.4 to 4.17.2 (#1722) (084276a), closes #1722
  • chore(deps-dev): bump the babel group with 2 updates (#1720) (6720a77), closes #1720
  • chore(deps-dev): bump the babel group with 2 updates (#1739) (2d3d1d3), closes #1739
  • chore(deps-dev): bump the babel group with 3 updates (#1733) (b56dc88), closes #1733
  • chore(deps-dev): bump the typescript-eslint group across 1 directory with 2 updates (#1729) (5cfc7c0), closes #1729
  • chore(deps-dev): bump the typescript-eslint group across 1 directory with 2 updates (#1748) (c0abf2d), closes #1748
  • chore(deps-dev): bump the typescript-eslint group with 2 updates (#1714) (1deea69), closes #1714
  • chore(deps-dev): bump the typescript-eslint group with 2 updates (#1717) (3571d80), closes #1717
  • chore(deps-dev): bump the typescript-eslint group with 2 updates (#1735) (c3d769f), closes #1735
  • chore(deps-dev): bump the typescript-eslint group with 2 updates (#1736) (2e053de), closes #1736
  • chore(deps-dev): bump typescript from 5.4.5 to 5.5.2 (#1750) (374962d), closes #1750
  • --- (#1730) (40dc5e6), closes #1730
  • Update readme (780ff50)
  • feat: drop glob usage (#1742) (2623a1b), closes #1742
  • feat: drop mkdirp (#1743) (2f90c74), closes #1743
  • feat: include private self dependency (1401f5d)
  • docs: update README & changelog (bdfca87)

3.4.0 (2024-04-18)

  • release: prepare next release (1c6c911)
  • release: release version (a576572)
  • chore: add changelog update workflow (5f4ed57)
  • chore: update changelog (a48e164)
  • chore: update readme (8254eae)
  • chore(ci): add node 21 (80cefa0)
  • chore(ci): remove invalid option (16e4d5d)
  • chore(ci): update actions/checkout to version 4.1.2 (9742e59)
  • chore(ci): use node 20 (184cc0b)

... (truncated)

Commits
  • bb34bb5 release: release version
  • 6ef9f81 chore(ci): clear node_auth_token before publish
  • add404f chore(ci): remove reference of npm token
  • 07357c2 chore(docs): update readme
  • 488b043 chore(ci): add npm oidc permission
  • c20ab48 chore: remove warning
  • ef99eed chore: update dependencies
  • df9ac73 fix return type of template (#2069)
  • 6967948 chore: remove node core modules prefix
  • cc8c079 chore(ci): group jasmine dependabot updates
  • Additional commits viewable in compare view
Maintainer changes

This version was pushed to npm by [GitHub Actions](https://www.npmjs.com/~GitHub Actions), a new releaser for rollup-plugin-license since your current version.


Updates `typescript-eslint` from 8.55.0 to 8.56.0
Release notes

Sourced from typescript-eslint's releases.

v8.56.0

8.56.0 (2026-02-16)

🚀 Features

🩹 Fixes

  • use parser options from context.languageOptions (#12043)

❤️ Thank You

See GitHub Releases for more information.

You can read about our versioning strategy and releases on our website.

Changelog

Sourced from typescript-eslint's changelog.

8.56.0 (2026-02-16)

🚀 Features

❤️ Thank You

See GitHub Releases for more information.

You can read about our versioning strategy and releases on our website.

Commits

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 165 +++++++++++++++++++++++++--------------------- 1 file changed, 89 insertions(+), 76 deletions(-) diff --git a/package-lock.json b/package-lock.json index 757d6b4fd..20a63a1a8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1435,17 +1435,17 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.55.0.tgz", - "integrity": "sha512-1y/MVSz0NglV1ijHC8OT49mPJ4qhPYjiK08YUQVbIOyu+5k862LKUHFkpKHWu//zmr7hDR2rhwUm6gnCGNmGBQ==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.0.tgz", + "integrity": "sha512-lRyPDLzNCuae71A3t9NEINBiTn7swyOhvUj3MyUOxb8x6g6vPEFoOU+ZRmGMusNC3X3YMhqMIX7i8ShqhT74Pw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.55.0", - "@typescript-eslint/type-utils": "8.55.0", - "@typescript-eslint/utils": "8.55.0", - "@typescript-eslint/visitor-keys": "8.55.0", + "@typescript-eslint/scope-manager": "8.56.0", + "@typescript-eslint/type-utils": "8.56.0", + "@typescript-eslint/utils": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" @@ -1459,21 +1459,21 @@ }, "peerDependencies": { "@typescript-eslint/parser": "^8.43.0", - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.55.0.tgz", - "integrity": "sha512-4z2nCSBfVIMnbuu8uinj+f0o4qOeggYJLbjpPHka3KH1om7e+H9yLKTYgksTaHcGco+NClhhY2vyO3HsMH1RGw==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.0.tgz", + "integrity": "sha512-IgSWvLobTDOjnaxAfDTIHaECbkNlAlKv2j5SjpB2v7QHKv1FIfjwMy8FsDbVfDX/KjmCmYICcw7uGaXLhtsLNg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.55.0", - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/typescript-estree": "8.55.0", - "@typescript-eslint/visitor-keys": "8.55.0", + "@typescript-eslint/scope-manager": "8.56.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/typescript-estree": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0", "debug": "^4.4.3" }, "engines": { @@ -1484,19 +1484,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.55.0.tgz", - "integrity": "sha512-zRcVVPFUYWa3kNnjaZGXSu3xkKV1zXy8M4nO/pElzQhFweb7PPtluDLQtKArEOGmjXoRjnUZ29NjOiF0eCDkcQ==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.0.tgz", + "integrity": "sha512-M3rnyL1vIQOMeWxTWIW096/TtVP+8W3p/XnaFflhmcFp+U4zlxUxWj4XwNs6HbDeTtN4yun0GNTTDBw/SvufKg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.55.0", - "@typescript-eslint/types": "^8.55.0", + "@typescript-eslint/tsconfig-utils": "^8.56.0", + "@typescript-eslint/types": "^8.56.0", "debug": "^4.4.3" }, "engines": { @@ -1511,14 +1511,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.55.0.tgz", - "integrity": "sha512-fVu5Omrd3jeqeQLiB9f1YsuK/iHFOwb04bCtY4BSCLgjNbOD33ZdV6KyEqplHr+IlpgT0QTZ/iJ+wT7hvTx49Q==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.0.tgz", + "integrity": "sha512-7UiO/XwMHquH+ZzfVCfUNkIXlp/yQjjnlYUyYz7pfvlK3/EyyN6BK+emDmGNyQLBtLGaYrTAI6KOw8tFucWL2w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/visitor-keys": "8.55.0" + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1529,9 +1529,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.55.0.tgz", - "integrity": "sha512-1R9cXqY7RQd7WuqSN47PK9EDpgFUK3VqdmbYrvWJZYDd0cavROGn+74ktWBlmJ13NXUQKlZ/iAEQHI/V0kKe0Q==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.0.tgz", + "integrity": "sha512-bSJoIIt4o3lKXD3xmDh9chZcjCz5Lk8xS7Rxn+6l5/pKrDpkCwtQNQQwZ2qRPk7TkUYhrq3WPIHXOXlbXP0itg==", "dev": true, "license": "MIT", "engines": { @@ -1546,15 +1546,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.55.0.tgz", - "integrity": "sha512-x1iH2unH4qAt6I37I2CGlsNs+B9WGxurP2uyZLRz6UJoZWDBx9cJL1xVN/FiOmHEONEg6RIufdvyT0TEYIgC5g==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.56.0.tgz", + "integrity": "sha512-qX2L3HWOU2nuDs6GzglBeuFXviDODreS58tLY/BALPC7iu3Fa+J7EOTwnX9PdNBxUI7Uh0ntP0YWGnxCkXzmfA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/typescript-estree": "8.55.0", - "@typescript-eslint/utils": "8.55.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/typescript-estree": "8.56.0", + "@typescript-eslint/utils": "8.56.0", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, @@ -1566,14 +1566,14 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.55.0.tgz", - "integrity": "sha512-ujT0Je8GI5BJWi+/mMoR0wxwVEQaxM+pi30xuMiJETlX80OPovb2p9E8ss87gnSVtYXtJoU9U1Cowcr6w2FE0w==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.0.tgz", + "integrity": "sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==", "dev": true, "license": "MIT", "engines": { @@ -1585,16 +1585,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.55.0.tgz", - "integrity": "sha512-EwrH67bSWdx/3aRQhCoxDaHM+CrZjotc2UCCpEDVqfCE+7OjKAGWNY2HsCSTEVvWH2clYQK8pdeLp42EVs+xQw==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.0.tgz", + "integrity": "sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.55.0", - "@typescript-eslint/tsconfig-utils": "8.55.0", - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/visitor-keys": "8.55.0", + "@typescript-eslint/project-service": "8.56.0", + "@typescript-eslint/tsconfig-utils": "8.56.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0", "debug": "^4.4.3", "minimatch": "^9.0.5", "semver": "^7.7.3", @@ -1613,16 +1613,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.55.0.tgz", - "integrity": "sha512-BqZEsnPGdYpgyEIkDC1BadNY8oMwckftxBT+C8W0g1iKPdeqKZBtTfnvcq0nf60u7MkjFO8RBvpRGZBPw4L2ow==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.0.tgz", + "integrity": "sha512-RZ3Qsmi2nFGsS+n+kjLAYDPVlrzf7UhTffrDIKr+h2yzAlYP/y5ZulU0yeDEPItos2Ph46JAL5P/On3pe7kDIQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.55.0", - "@typescript-eslint/types": "8.55.0", - "@typescript-eslint/typescript-estree": "8.55.0" + "@typescript-eslint/scope-manager": "8.56.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/typescript-estree": "8.56.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1632,19 +1632,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.55.0.tgz", - "integrity": "sha512-AxNRwEie8Nn4eFS1FzDMJWIISMGoXMb037sgCBJ3UR6o0fQTzr2tqN9WT+DkWJPhIdQCfV7T6D387566VtnCJA==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.0.tgz", + "integrity": "sha512-q+SL+b+05Ud6LbEE35qe4A99P+htKTKVbyiNEe45eCbJFyh/HVK9QXwlrbz+Q4L8SOW4roxSVwXYj4DMBT7Ieg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.55.0", - "eslint-visitor-keys": "^4.2.1" + "@typescript-eslint/types": "8.56.0", + "eslint-visitor-keys": "^5.0.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1654,6 +1654,19 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.0.tgz", + "integrity": "sha512-A0XeIi7CXU7nPlfHS9loMYEKxUaONu/hTEzHTGba9Huu94Cq1hPivf+DE5erJozZOky0LfvXAyrV/tcswpLI0Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@unrs/resolver-binding-android-arm-eabi": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", @@ -6300,20 +6313,20 @@ } }, "node_modules/rollup-plugin-license": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-license/-/rollup-plugin-license-3.6.0.tgz", - "integrity": "sha512-1ieLxTCaigI5xokIfszVDRoy6c/Wmlot1fDEnea7Q/WXSR8AqOjYljHDLObAx7nFxHC2mbxT3QnTSPhaic2IYw==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-license/-/rollup-plugin-license-3.7.0.tgz", + "integrity": "sha512-RvvOIF+GH3fBR3wffgc/vmjQn6qOn72WjppWVDp/v+CLpT0BbcRBdSkPeeIOL6U5XccdYgSIMjUyXgxlKEEFcw==", "dev": true, "license": "MIT", "dependencies": { - "commenting": "~1.1.0", + "commenting": "^1.1.0", "fdir": "^6.4.3", - "lodash": "~4.17.21", - "magic-string": "~0.30.0", - "moment": "~2.30.1", - "package-name-regex": "~2.0.6", - "spdx-expression-validate": "~2.0.0", - "spdx-satisfies": "~5.0.1" + "lodash": "^4.17.21", + "magic-string": "^0.30.0", + "moment": "^2.30.1", + "package-name-regex": "^2.0.6", + "spdx-expression-validate": "^2.0.0", + "spdx-satisfies": "^5.0.1" }, "engines": { "node": ">=14.0.0" @@ -7321,16 +7334,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.55.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.55.0.tgz", - "integrity": "sha512-HE4wj+r5lmDVS9gdaN0/+iqNvPZwGfnJ5lZuz7s5vLlg9ODw0bIiiETaios9LvFI1U94/VBXGm3CB2Y5cNFMpw==", + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.56.0.tgz", + "integrity": "sha512-c7toRLrotJ9oixgdW7liukZpsnq5CZ7PuKztubGYlNppuTqhIoWfhgHo/7EU0v06gS2l/x0i2NEFK1qMIf0rIg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.55.0", - "@typescript-eslint/parser": "8.55.0", - "@typescript-eslint/typescript-estree": "8.55.0", - "@typescript-eslint/utils": "8.55.0" + "@typescript-eslint/eslint-plugin": "8.56.0", + "@typescript-eslint/parser": "8.56.0", + "@typescript-eslint/typescript-estree": "8.56.0", + "@typescript-eslint/utils": "8.56.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -7340,7 +7353,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, From dcdd75ca39ba436e721efa189ede1ae4fe4f034e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Feb 2026 12:33:51 +0100 Subject: [PATCH 04/15] chore(deps-dev): bump chrome-devtools-frontend from 1.0.1583146 to 1.0.1585538 in the bundled-devtools group (#984) Bumps the bundled-devtools group with 1 update: [chrome-devtools-frontend](https://github.com/ChromeDevTools/devtools-frontend). Updates `chrome-devtools-frontend` from 1.0.1583146 to 1.0.1585538
Commits
  • 4d8f4f7 Update DevTools DEPS (trusted)
  • 84b7f20 RPP: persist sidebar state
  • 672475e ComputedStyles: pass model to widget as a setter
  • 7d49b08 ComputedStylesWidget is given styles rather than fetching them.
  • 748db09 Extract common var in UI helpers
  • c26d0ba Roll browser-protocol
  • 3ada56c Update DevTools DEPS (trusted)
  • 4a8d3db Update context selection per Greenlines
  • 509282f Update prompt for AI code gen to handle vague instructions
  • b9cf6fc Make teaser text click-through
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=chrome-devtools-frontend&package-manager=npm_and_yarn&previous-version=1.0.1583146&new-version=1.0.1585538)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 20a63a1a8..7826a85f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,7 @@ "@types/yargs": "^17.0.33", "@typescript-eslint/eslint-plugin": "^8.43.0", "@typescript-eslint/parser": "^8.43.0", - "chrome-devtools-frontend": "1.0.1583146", + "chrome-devtools-frontend": "1.0.1585538", "core-js": "3.48.0", "debug": "4.4.3", "eslint": "^9.35.0", @@ -2549,9 +2549,9 @@ } }, "node_modules/chrome-devtools-frontend": { - "version": "1.0.1583146", - "resolved": "https://registry.npmjs.org/chrome-devtools-frontend/-/chrome-devtools-frontend-1.0.1583146.tgz", - "integrity": "sha512-WfH6W0WY/WGJXWwOHTBTPldHM4hT+7ewDPu6zBgNjKxrU9jYjnwDMwX0WS94XuCo2ytBzvTrUOMeprHET/KSdg==", + "version": "1.0.1585538", + "resolved": "https://registry.npmjs.org/chrome-devtools-frontend/-/chrome-devtools-frontend-1.0.1585538.tgz", + "integrity": "sha512-zSiEUA7wZYfqhh25U4kc0hbyAoiRHAi4fcKgFJPCIIfHDCiwebiQL/ke6TFCk7TNT3ooW0PLGAMeKrim/O656Q==", "dev": true, "license": "BSD-3-Clause" }, diff --git a/package.json b/package.json index 6f65c1638..2dc503546 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "@types/yargs": "^17.0.33", "@typescript-eslint/eslint-plugin": "^8.43.0", "@typescript-eslint/parser": "^8.43.0", - "chrome-devtools-frontend": "1.0.1583146", + "chrome-devtools-frontend": "1.0.1585538", "core-js": "3.48.0", "debug": "4.4.3", "eslint": "^9.35.0", From f0995493444ab095cbe40dc2fc46f1ab59fac7ce Mon Sep 17 00:00:00 2001 From: Alex Rudenko Date: Wed, 18 Feb 2026 14:08:29 +0100 Subject: [PATCH 05/15] refactor(network): de-duplicate String and JSON formatters (#985) - string formatters should use the same data as the JSON formatters - removed an extra space in network status --- src/formatters/NetworkFormatter.ts | 161 +++++++++++++++------------ tests/McpResponse.test.js.snapshot | 4 +- tests/tools/network.test.js.snapshot | 2 +- 3 files changed, 94 insertions(+), 73 deletions(-) diff --git a/src/formatters/NetworkFormatter.ts b/src/formatters/NetworkFormatter.ts index 313e091cb..036eb5748 100644 --- a/src/formatters/NetworkFormatter.ts +++ b/src/formatters/NetworkFormatter.ts @@ -23,6 +23,25 @@ export interface NetworkFormatterOptions { ) => Promise<{filename: string}>; } +interface NetworkRequestConcise { + requestId?: number | string; + method: string; + url: string; + status: string; + selectedInDevToolsUI?: boolean; +} + +interface NetworkRequestDetailed extends NetworkRequestConcise { + requestHeaders: Record; + requestBody?: string; + requestBodyFilePath?: string; + responseHeaders?: Record; + responseBody?: string; + responseBodyFilePath?: string; + failure?: string; + redirectChain?: NetworkRequestConcise[]; +} + export class NetworkFormatter { #request: HTTPRequest; #options: NetworkFormatterOptions; @@ -114,72 +133,14 @@ export class NetworkFormatter { } toString(): string { - // TODO truncate the URL - return `reqid=${this.#options.requestId} ${this.#request.method()} ${this.#request.url()} ${this.#getStatusFromRequest(this.#request)}${this.#options.selectedInDevToolsUI ? ` [selected in the DevTools Network panel]` : ''}`; + return convertNetworkRequestConciseToString(this.toJSON()); } toStringDetailed(): string { - const response: string[] = []; - response.push(`## Request ${this.#request.url()}`); - response.push(`Status: ${this.#getStatusFromRequest(this.#request)}`); - response.push(`### Request Headers`); - for (const line of this.#getFormattedHeaderValue(this.#request.headers())) { - response.push(line); - } - - if (this.#requestBody) { - response.push(`### Request Body`); - response.push(this.#requestBody); - } else if (this.#requestBodyFilePath) { - response.push(`### Request Body`); - response.push(`Saved to ${this.#requestBodyFilePath}.`); - } - - const httpResponse = this.#request.response(); - if (httpResponse) { - response.push(`### Response Headers`); - for (const line of this.#getFormattedHeaderValue( - httpResponse.headers(), - )) { - response.push(line); - } - } - - if (this.#responseBody) { - response.push(`### Response Body`); - response.push(this.#responseBody); - } else if (this.#responseBodyFilePath) { - response.push(`### Response Body`); - response.push(`Saved to ${this.#responseBodyFilePath}.`); - } - - const httpFailure = this.#request.failure(); - if (httpFailure) { - response.push(`### Request failed with`); - response.push(httpFailure.errorText); - } - - const redirectChain = this.#request.redirectChain(); - if (redirectChain.length) { - response.push(`### Redirect chain`); - let indent = 0; - for (const request of redirectChain.reverse()) { - const id = this.#options.requestIdResolver - ? this.#options.requestIdResolver(request) - : undefined; - // We create a temporary synchronous instance just for toString - const formatter = new NetworkFormatter(request, { - requestId: id, - saveFile: this.#options.saveFile, - }); - response.push(`${' '.repeat(indent)}${formatter.toString()}`); - indent++; - } - } - return response.join('\n'); + return converNetworkRequestDetailedToStringDetailed(this.toJSONDetailed()); } - toJSON(): object { + toJSON(): NetworkRequestConcise { return { requestId: this.#options.requestId, method: this.#request.method(), @@ -189,7 +150,7 @@ export class NetworkFormatter { }; } - toJSONDetailed(): object { + toJSONDetailed(): NetworkRequestDetailed { const redirectChain = this.#request.redirectChain(); const formattedRedirectChain = redirectChain.reverse().map(request => { const id = this.#options.requestIdResolver @@ -235,14 +196,6 @@ export class NetworkFormatter { return status; } - #getFormattedHeaderValue(headers: Record): string[] { - const response: string[] = []; - for (const [name, value] of Object.entries(headers)) { - response.push(`- ${name}:${value}`); - } - return response; - } - async #getFormattedResponseBody( httpResponse: HTTPResponse, sizeLimit = BODY_CONTEXT_SIZE_LIMIT, @@ -273,3 +226,71 @@ function getSizeLimitedString(text: string, sizeLimit: number) { } return text; } + +function convertNetworkRequestConciseToString( + data: NetworkRequestConcise, +): string { + // TODO truncate the URL + return `reqid=${data.requestId} ${data.method} ${data.url} ${data.status}${data.selectedInDevToolsUI ? ` [selected in the DevTools Network panel]` : ''}`; +} + +function formatHeadlers(headers: Record): string[] { + const response: string[] = []; + for (const [name, value] of Object.entries(headers)) { + response.push(`- ${name}:${value}`); + } + return response; +} + +function converNetworkRequestDetailedToStringDetailed( + data: NetworkRequestDetailed, +): string { + const response: string[] = []; + response.push(`## Request ${data.url}`); + response.push(`Status: ${data.status}`); + response.push(`### Request Headers`); + for (const line of formatHeadlers(data.requestHeaders)) { + response.push(line); + } + + if (data.requestBody) { + response.push(`### Request Body`); + response.push(data.requestBody); + } else if (data.requestBodyFilePath) { + response.push(`### Request Body`); + response.push(`Saved to ${data.requestBodyFilePath}.`); + } + + if (data.responseHeaders) { + response.push(`### Response Headers`); + for (const line of formatHeadlers(data.responseHeaders)) { + response.push(line); + } + } + + if (data.responseBody) { + response.push(`### Response Body`); + response.push(data.responseBody); + } else if (data.responseBodyFilePath) { + response.push(`### Response Body`); + response.push(`Saved to ${data.responseBodyFilePath}.`); + } + + if (data.failure) { + response.push(`### Request failed with`); + response.push(data.failure); + } + + const redirectChain = data.redirectChain; + if (redirectChain?.length) { + response.push(`### Redirect chain`); + let indent = 0; + for (const request of redirectChain.reverse()) { + response.push( + `${' '.repeat(indent)}${convertNetworkRequestConciseToString(request)})}`, + ); + indent++; + } + } + return response.join('\n'); +} diff --git a/tests/McpResponse.test.js.snapshot b/tests/McpResponse.test.js.snapshot index e93256070..0a68077a2 100644 --- a/tests/McpResponse.test.js.snapshot +++ b/tests/McpResponse.test.js.snapshot @@ -1,7 +1,7 @@ exports[`McpResponse > add network request when attached 1`] = ` # test response ## Request http://example.com -Status: [pending] +Status: [pending] ### Request Headers - content-size:10 ## Network requests @@ -44,7 +44,7 @@ exports[`McpResponse > add network request when attached 2`] = ` exports[`McpResponse > add network request when attached with POST data 1`] = ` # test response ## Request http://example.com -Status: [success - 200] +Status: [success - 200] ### Request Headers - content-size:10 ### Request Body diff --git a/tests/tools/network.test.js.snapshot b/tests/tools/network.test.js.snapshot index f884af6fc..381112309 100644 --- a/tests/tools/network.test.js.snapshot +++ b/tests/tools/network.test.js.snapshot @@ -1,7 +1,7 @@ exports[`network > network_get_request > should get request from previous navigations 1`] = ` # get_request response ## Request http://localhost:/one -Status: [success - 200] +Status: [success - 200] ### Request Headers - accept-language: - upgrade-insecure-requests:1 From bdfbf83e0811c1475a0690b79aae563e4a430916 Mon Sep 17 00:00:00 2001 From: Alex Rudenko Date: Wed, 18 Feb 2026 14:41:04 +0100 Subject: [PATCH 06/15] docs: update codex doc URL (#987) Refs https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/967 Closes https://github.com/ChromeDevTools/chrome-devtools-mcp/pull/968 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e1313ae45..db55b32f9 100644 --- a/README.md +++ b/README.md @@ -150,7 +150,7 @@ Restart Claude Code to have the MCP server and skills load (check with `/skills`
Codex - Follow the configure MCP guide + Follow the configure MCP guide using the standard config from above. You can also install the Chrome DevTools MCP server using the Codex CLI: ```bash From 4826dbb7d17e38b8d87bb7675b504047f3b09eda Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Feb 2026 15:08:56 +0100 Subject: [PATCH 07/15] chore(deps-dev): bump puppeteer from 24.37.3 to 24.37.4 in the bundled group (#986) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the bundled group with 1 update: [puppeteer](https://github.com/puppeteer/puppeteer). Updates `puppeteer` from 24.37.3 to 24.37.4
Release notes

Sourced from puppeteer's releases.

puppeteer-core: v24.37.4

24.37.4 (2026-02-18)

🛠️ Fixes

Dependencies

  • The following workspace dependencies were updated
    • dependencies
      • @​puppeteer/browsers bumped from 2.12.1 to 2.13.0

puppeteer: v24.37.4

24.37.4 (2026-02-18)

♻️ Chores

  • puppeteer: Synchronize puppeteer versions

Dependencies

  • The following workspace dependencies were updated
    • dependencies
      • @​puppeteer/browsers bumped from 2.12.1 to 2.13.0
      • puppeteer-core bumped from 24.37.3 to 24.37.4
Changelog

Sourced from puppeteer's changelog.

24.37.4 (2026-02-18)

♻️ Chores

  • puppeteer: Synchronize puppeteer versions

Dependencies

  • The following workspace dependencies were updated
    • dependencies
      • @​puppeteer/browsers bumped from 2.12.1 to 2.13.0

🛠️ Fixes

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=puppeteer&package-manager=npm_and_yarn&previous-version=24.37.3&new-version=24.37.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 58 ++++++++++++++++++++++++++++------------------- package.json | 2 +- 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7826a85f7..2fc7d4710 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,7 +34,7 @@ "eslint-plugin-import": "^2.32.0", "globals": "^17.0.0", "prettier": "^3.6.2", - "puppeteer": "24.37.3", + "puppeteer": "24.37.4", "rollup": "4.57.1", "rollup-plugin-cleanup": "^3.2.1", "rollup-plugin-license": "^3.6.0", @@ -656,9 +656,9 @@ "license": "BSD-3-Clause" }, "node_modules/@puppeteer/browsers": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.12.1.tgz", - "integrity": "sha512-fXa6uXLxfslBlus3MEpW8S6S9fe5RwmAE5Gd8u3krqOwnkZJV3/lQJiY3LaFdTctLLqJtyMgEUGkbDnRNf6vbQ==", + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.13.0.tgz", + "integrity": "sha512-46BZJYJjc/WwmKjsvDFykHtXrtomsCIrwYQPOP7VfMJoZY2bsDF9oROBABR3paDjDcmkUye1Pb1BqdcdiipaWA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -2250,9 +2250,9 @@ } }, "node_modules/b4a": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.4.tgz", - "integrity": "sha512-u20zJLDaSWpxaZ+zaAkEIB2dZZ1o+DF4T/MRbmsvGp9nletHOyiai19OzX1fF8xUBYsO1bPXxODvcd0978pnug==", + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.5.tgz", + "integrity": "sha512-iEsKNwDh1wiWTps1/hdkNdmBgDlDVZP5U57ZVOlt+dNFqpc/lpPouCIxZw+DYBgc4P9NDfIZMPNR4CHNhzwLIA==", "dev": true, "license": "Apache-2.0", "peerDependencies": { @@ -2335,14 +2335,15 @@ } }, "node_modules/bare-stream": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.7.0.tgz", - "integrity": "sha512-oyXQNicV1y8nc2aKffH+BUHFRXmx6VrPzlnaEvMhram0nPBrKcEdcyBg5r08D0i8VxngHFAiVyn1QKXpSG0B8A==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.8.0.tgz", + "integrity": "sha512-reUN0M2sHRqCdG4lUK3Fw8w98eeUIZHL5c3H7Mbhk2yVBL+oofgaIp0ieLfD5QXwPCypBpmEEKU2WZKzbAk8GA==", "dev": true, "license": "Apache-2.0", "optional": true, "dependencies": { - "streamx": "^2.21.0" + "streamx": "^2.21.0", + "teex": "^1.0.1" }, "peerDependencies": { "bare-buffer": "*", @@ -6047,18 +6048,18 @@ } }, "node_modules/puppeteer": { - "version": "24.37.3", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-24.37.3.tgz", - "integrity": "sha512-AUGGWq0BhPM+IOS2U9A+ZREH3HDFkV1Y5HERYGDg5cbGXjoGsTCT7/A6VZRfNU0UJJdCclyEimZICkZW6pqJyw==", + "version": "24.37.4", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-24.37.4.tgz", + "integrity": "sha512-SMSq+FL3gnglolhrIks3maRkrdQEjoDCesy6FXziMPWsF1DxoX+GVxRa82y+euzkzS52/UujM/BoaFPQ+AnPXQ==", "dev": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@puppeteer/browsers": "2.12.1", + "@puppeteer/browsers": "2.13.0", "chromium-bidi": "14.0.0", "cosmiconfig": "^9.0.0", "devtools-protocol": "0.0.1566079", - "puppeteer-core": "24.37.3", + "puppeteer-core": "24.37.4", "typed-query-selector": "^2.12.0" }, "bin": { @@ -6069,13 +6070,13 @@ } }, "node_modules/puppeteer-core": { - "version": "24.37.3", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.37.3.tgz", - "integrity": "sha512-fokQ8gv+hNgsRWqVuP5rUjGp+wzV5aMTP3fcm8ekNabmLGlJdFHas1OdMscAH9Gzq4Qcf7cfI/Pe6wEcAqQhqg==", + "version": "24.37.4", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.37.4.tgz", + "integrity": "sha512-sQYtYgaNaLYO82k2FHmr7bR1tCmo2fBupEI7Kd0WpBlMropNcfxSTLOJXVRkhiHig0dUiMI7g0yq+HJI1IDCzg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@puppeteer/browsers": "2.12.1", + "@puppeteer/browsers": "2.13.0", "chromium-bidi": "14.0.0", "debug": "^4.4.3", "devtools-protocol": "0.0.1566079", @@ -7119,10 +7120,21 @@ "streamx": "^2.15.0" } }, + "node_modules/teex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", + "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "streamx": "^2.12.5" + } + }, "node_modules/text-decoder": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.4.tgz", - "integrity": "sha512-mzlffA3tBNhziEHPK5L5InZg1d/ElNIpJhnhbDRNUtem/edZcJ5zg5FgwKKKOyklxk+6Jt+TrSu83musmvrDlg==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.7.tgz", + "integrity": "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==", "dev": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index 2dc503546..019b81510 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "eslint-plugin-import": "^2.32.0", "globals": "^17.0.0", "prettier": "^3.6.2", - "puppeteer": "24.37.3", + "puppeteer": "24.37.4", "rollup": "4.57.1", "rollup-plugin-cleanup": "^3.2.1", "rollup-plugin-license": "^3.6.0", From c4fa168279a048c7063067ff10445afd274e625c Mon Sep 17 00:00:00 2001 From: Nikolay Vitkov <34244704+Lightning00Blade@users.noreply.github.com> Date: Wed, 18 Feb 2026 15:23:26 +0100 Subject: [PATCH 08/15] refactor: remove text from the status code for Network requests (#778) LLM are trained to know the common status code so we can rely on that when displaying the status code and fall back to text in case of errors or pending reponse. --- src/formatters/NetworkFormatter.ts | 12 +-- tests/McpContext.test.js.snapshot | 4 +- tests/McpResponse.test.js.snapshot | 98 +++++++++++------------ tests/formatters/NetworkFormatter.test.ts | 12 +-- tests/tools/network.test.js.snapshot | 16 ++-- 5 files changed, 69 insertions(+), 73 deletions(-) diff --git a/src/formatters/NetworkFormatter.ts b/src/formatters/NetworkFormatter.ts index 036eb5748..abfb0693e 100644 --- a/src/formatters/NetworkFormatter.ts +++ b/src/formatters/NetworkFormatter.ts @@ -183,15 +183,11 @@ export class NetworkFormatter { const failure = request.failure(); let status: string; if (httpResponse) { - const responseStatus = httpResponse.status(); - status = - responseStatus >= 200 && responseStatus <= 299 - ? `[success - ${responseStatus}]` - : `[failed - ${responseStatus}]`; + status = httpResponse.status().toString(); } else if (failure) { - status = `[failed - ${failure.errorText}]`; + status = failure.errorText; } else { - status = '[pending]'; + status = 'pending'; } return status; } @@ -231,7 +227,7 @@ function convertNetworkRequestConciseToString( data: NetworkRequestConcise, ): string { // TODO truncate the URL - return `reqid=${data.requestId} ${data.method} ${data.url} ${data.status}${data.selectedInDevToolsUI ? ` [selected in the DevTools Network panel]` : ''}`; + return `reqid=${data.requestId} ${data.method} ${data.url} [${data.status}]${data.selectedInDevToolsUI ? ` [selected in the DevTools Network panel]` : ''}`; } function formatHeadlers(headers: Record): string[] { diff --git a/tests/McpContext.test.js.snapshot b/tests/McpContext.test.js.snapshot index b688da713..cfdd6f902 100644 --- a/tests/McpContext.test.js.snapshot +++ b/tests/McpContext.test.js.snapshot @@ -4,7 +4,7 @@ exports[`McpContext > should include detailed network request in structured cont "requestId": 456, "method": "GET", "url": "http://example.com/detail", - "status": "[pending]", + "status": "pending", "requestHeaders": { "content-size": "10" } @@ -37,7 +37,7 @@ exports[`McpContext > should include network requests in structured content 1`] "requestId": 123, "method": "GET", "url": "http://example.com/api", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false } ] diff --git a/tests/McpResponse.test.js.snapshot b/tests/McpResponse.test.js.snapshot index 0a68077a2..8897adc3c 100644 --- a/tests/McpResponse.test.js.snapshot +++ b/tests/McpResponse.test.js.snapshot @@ -1,7 +1,7 @@ exports[`McpResponse > add network request when attached 1`] = ` # test response ## Request http://example.com -Status: [pending] +Status: pending ### Request Headers - content-size:10 ## Network requests @@ -15,7 +15,7 @@ exports[`McpResponse > add network request when attached 2`] = ` "requestId": 1, "method": "GET", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "requestHeaders": { "content-size": "10" } @@ -34,7 +34,7 @@ exports[`McpResponse > add network request when attached 2`] = ` "requestId": 1, "method": "GET", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false } ] @@ -44,7 +44,7 @@ exports[`McpResponse > add network request when attached 2`] = ` exports[`McpResponse > add network request when attached with POST data 1`] = ` # test response ## Request http://example.com -Status: [success - 200] +Status: 200 ### Request Headers - content-size:10 ### Request Body @@ -55,7 +55,7 @@ Status: [success - 200] {"response":"body"} ## Network requests Showing 1-1 of 1 (Page 1 of 1). -reqid=1 POST http://example.com [success - 200] +reqid=1 POST http://example.com [200] `; exports[`McpResponse > add network request when attached with POST data 2`] = ` @@ -64,7 +64,7 @@ exports[`McpResponse > add network request when attached with POST data 2`] = ` "requestId": 1, "method": "POST", "url": "http://example.com", - "status": "[success - 200]", + "status": "200", "requestHeaders": { "content-size": "10" }, @@ -88,7 +88,7 @@ exports[`McpResponse > add network request when attached with POST data 2`] = ` "requestId": 1, "method": "POST", "url": "http://example.com", - "status": "[success - 200]", + "status": "200", "selectedInDevToolsUI": false } ] @@ -119,14 +119,14 @@ exports[`McpResponse > add network requests when setting is true 2`] = ` "requestId": 1, "method": "GET", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 2, "method": "GET", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false } ] @@ -487,14 +487,14 @@ exports[`McpResponse network pagination > handles invalid page number by showing "requestId": 1, "method": "GET", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false } ] @@ -517,35 +517,35 @@ exports[`McpResponse network pagination > returns all requests when pagination i "requestId": 1, "method": "GET", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false } ] @@ -568,70 +568,70 @@ exports[`McpResponse network pagination > returns first page by default 1`] = ` "requestId": 1, "method": "GET-0", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET-1", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET-2", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET-3", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET-4", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET-5", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET-6", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET-7", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET-8", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET-9", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false } ] @@ -654,70 +654,70 @@ exports[`McpResponse network pagination > returns subsequent page when pageIdx p "requestId": 1, "method": "GET-10", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET-11", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET-12", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET-13", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET-14", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET-15", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET-16", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET-17", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET-18", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET-19", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false } ] @@ -1002,14 +1002,14 @@ exports[`McpResponse network request filtering > filters network requests by res "requestId": 1, "method": "GET", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false } ] @@ -1039,7 +1039,7 @@ exports[`McpResponse network request filtering > filters network requests by sin "requestId": 1, "method": "GET", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false } ] @@ -1073,35 +1073,35 @@ exports[`McpResponse network request filtering > shows all requests when empty r "requestId": 1, "method": "GET", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false } ] @@ -1135,35 +1135,35 @@ exports[`McpResponse network request filtering > shows all requests when no filt "requestId": 1, "method": "GET", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false }, { "requestId": 1, "method": "GET", "url": "http://example.com", - "status": "[pending]", + "status": "pending", "selectedInDevToolsUI": false } ] diff --git a/tests/formatters/NetworkFormatter.test.ts b/tests/formatters/NetworkFormatter.test.ts index a1f1fd3c2..d09e18184 100644 --- a/tests/formatters/NetworkFormatter.test.ts +++ b/tests/formatters/NetworkFormatter.test.ts @@ -60,7 +60,7 @@ describe('NetworkFormatter', () => { assert.equal( formatter.toString(), - 'reqid=1 GET http://example.com [success - 200]', + 'reqid=1 GET http://example.com [200]', ); }); it('shows correct status for request with response code in 100', async () => { @@ -75,7 +75,7 @@ describe('NetworkFormatter', () => { assert.equal( formatter.toString(), - 'reqid=1 GET http://example.com [failed - 199]', + 'reqid=1 GET http://example.com [199]', ); }); it('shows correct status for request with response code above 200', async () => { @@ -90,7 +90,7 @@ describe('NetworkFormatter', () => { assert.equal( formatter.toString(), - 'reqid=1 GET http://example.com [failed - 300]', + 'reqid=1 GET http://example.com [300]', ); }); it('shows correct status for request that failed', async () => { @@ -108,7 +108,7 @@ describe('NetworkFormatter', () => { assert.equal( formatter.toString(), - 'reqid=1 GET http://example.com [failed - Error in Network]', + 'reqid=1 GET http://example.com [Error in Network]', ); }); @@ -385,7 +385,7 @@ describe('NetworkFormatter', () => { requestId: 1, method: 'GET', url: 'http://example.com', - status: '[pending]', + status: 'pending', selectedInDevToolsUI: true, }); }); @@ -410,7 +410,7 @@ describe('NetworkFormatter', () => { requestId: 1, method: 'GET', url: 'http://example.com', - status: '[success - 200]', + status: '200', selectedInDevToolsUI: undefined, requestHeaders: { 'content-size': '10', diff --git a/tests/tools/network.test.js.snapshot b/tests/tools/network.test.js.snapshot index 381112309..4b0472980 100644 --- a/tests/tools/network.test.js.snapshot +++ b/tests/tools/network.test.js.snapshot @@ -1,7 +1,7 @@ exports[`network > network_get_request > should get request from previous navigations 1`] = ` # get_request response ## Request http://localhost:/one -Status: [success - 200] +Status: 200 ### Request Headers - accept-language: - upgrade-insecure-requests:1 @@ -31,23 +31,23 @@ exports[`network > network_list_requests > list requests form current navigation # list_request response ## Network requests Showing 1-1 of 1 (Page 1 of 1). -reqid=3 GET http://localhost:/three [success - 200] +reqid=3 GET http://localhost:/three [200] `; exports[`network > network_list_requests > list requests from previous navigations 1`] = ` # list_request response ## Network requests Showing 1-3 of 3 (Page 1 of 1). -reqid=1 GET http://localhost:/one [success - 200] -reqid=2 GET http://localhost:/two [success - 200] -reqid=3 GET http://localhost:/three [success - 200] +reqid=1 GET http://localhost:/one [200] +reqid=2 GET http://localhost:/two [200] +reqid=3 GET http://localhost:/three [200] `; exports[`network > network_list_requests > list requests from previous navigations from redirects 1`] = ` # list_request response ## Network requests Showing 1-3 of 3 (Page 1 of 1). -reqid=1 GET http://localhost:/redirect [failed - 302] -reqid=2 GET http://localhost:/redirected [success - 200] -reqid=3 GET http://localhost:/redirected-page [success - 200] +reqid=1 GET http://localhost:/redirect [302] +reqid=2 GET http://localhost:/redirected [200] +reqid=3 GET http://localhost:/redirected-page [200] `; From 915b944c98fb2485efad25a7d58f3e35f0107391 Mon Sep 17 00:00:00 2001 From: Alex Rudenko Date: Wed, 18 Feb 2026 15:38:02 +0100 Subject: [PATCH 09/15] chore: clear in prepare (#988) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 019b81510..d19611c8b 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "test:no-build": "node scripts/test.mjs", "test:only": "npm run build && node scripts/test.mjs --test-only", "test:update-snapshots": "npm run build && node scripts/test.mjs --test-update-snapshots", - "prepare": "node --experimental-strip-types scripts/prepare.ts", + "prepare": "npm run clean && node --experimental-strip-types scripts/prepare.ts", "verify-server-json-version": "node --experimental-strip-types scripts/verify-server-json-version.ts", "eval": "npm run build && CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS=true node --experimental-strip-types scripts/eval_gemini.ts", "count-tokens": "node --experimental-strip-types scripts/count_tokens.ts" From 5ed9d512b5b96137c6a27932027235e685e071b9 Mon Sep 17 00:00:00 2001 From: Alex Rudenko Date: Wed, 18 Feb 2026 16:34:45 +0100 Subject: [PATCH 10/15] revert: "chore(deps-dev): bump chrome-devtools-frontend from 1.0.1583146 to 1.0.1585538 in the bundled-devtools group" (#990) Reverts ChromeDevTools/chrome-devtools-mcp#984 might be related to flakiness on macos. --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2fc7d4710..a6394ec91 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,7 @@ "@types/yargs": "^17.0.33", "@typescript-eslint/eslint-plugin": "^8.43.0", "@typescript-eslint/parser": "^8.43.0", - "chrome-devtools-frontend": "1.0.1585538", + "chrome-devtools-frontend": "1.0.1583146", "core-js": "3.48.0", "debug": "4.4.3", "eslint": "^9.35.0", @@ -2550,9 +2550,9 @@ } }, "node_modules/chrome-devtools-frontend": { - "version": "1.0.1585538", - "resolved": "https://registry.npmjs.org/chrome-devtools-frontend/-/chrome-devtools-frontend-1.0.1585538.tgz", - "integrity": "sha512-zSiEUA7wZYfqhh25U4kc0hbyAoiRHAi4fcKgFJPCIIfHDCiwebiQL/ke6TFCk7TNT3ooW0PLGAMeKrim/O656Q==", + "version": "1.0.1583146", + "resolved": "https://registry.npmjs.org/chrome-devtools-frontend/-/chrome-devtools-frontend-1.0.1583146.tgz", + "integrity": "sha512-WfH6W0WY/WGJXWwOHTBTPldHM4hT+7ewDPu6zBgNjKxrU9jYjnwDMwX0WS94XuCo2ytBzvTrUOMeprHET/KSdg==", "dev": true, "license": "BSD-3-Clause" }, diff --git a/package.json b/package.json index d19611c8b..bdaa86f34 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "@types/yargs": "^17.0.33", "@typescript-eslint/eslint-plugin": "^8.43.0", "@typescript-eslint/parser": "^8.43.0", - "chrome-devtools-frontend": "1.0.1585538", + "chrome-devtools-frontend": "1.0.1583146", "core-js": "3.48.0", "debug": "4.4.3", "eslint": "^9.35.0", From 5a169bf925ec31ca110a90be7cf09508f804f6ea Mon Sep 17 00:00:00 2001 From: Alex Rudenko Date: Wed, 18 Feb 2026 16:39:30 +0100 Subject: [PATCH 11/15] test: fix missing sinon.restore (#989) --- tests/DevtoolsUtils.test.ts | 6 +++++- tests/McpContext.test.ts | 6 +++++- tests/PageCollector.test.ts | 6 +++++- tests/formatters/IssueFormatter.test.ts | 2 +- tests/tools/extensions.test.ts | 6 +++++- tests/tools/pages.test.ts | 6 +++++- 6 files changed, 26 insertions(+), 6 deletions(-) diff --git a/tests/DevtoolsUtils.test.ts b/tests/DevtoolsUtils.test.ts index a6f5d113c..a5e43009c 100644 --- a/tests/DevtoolsUtils.test.ts +++ b/tests/DevtoolsUtils.test.ts @@ -5,7 +5,7 @@ */ import assert from 'node:assert'; -import {describe, it} from 'node:test'; +import {afterEach, describe, it} from 'node:test'; import sinon from 'sinon'; @@ -95,6 +95,10 @@ describe('urlsEqual', () => { }); describe('UniverseManager', () => { + afterEach(() => { + sinon.restore(); + }); + it('calls the factory for existing pages', async () => { const browser = getMockBrowser(); const factory = sinon.stub().resolves({}); diff --git a/tests/McpContext.test.ts b/tests/McpContext.test.ts index e3683152d..3783f55f6 100644 --- a/tests/McpContext.test.ts +++ b/tests/McpContext.test.ts @@ -5,7 +5,7 @@ */ import assert from 'node:assert'; -import {describe, it} from 'node:test'; +import {afterEach, describe, it} from 'node:test'; import sinon from 'sinon'; @@ -16,6 +16,10 @@ import type {TraceResult} from '../src/trace-processing/parse.js'; import {getMockRequest, html, withMcpContext} from './utils.js'; describe('McpContext', () => { + afterEach(() => { + sinon.restore(); + }); + it('list pages', async () => { await withMcpContext(async (_response, context) => { const page = context.getSelectedPage(); diff --git a/tests/PageCollector.test.ts b/tests/PageCollector.test.ts index 48e60cf36..6a8155fcc 100644 --- a/tests/PageCollector.test.ts +++ b/tests/PageCollector.test.ts @@ -5,7 +5,7 @@ */ import assert from 'node:assert'; -import {beforeEach, describe, it} from 'node:test'; +import {afterEach, beforeEach, describe, it} from 'node:test'; import type {Frame, HTTPRequest, Target, Protocol} from 'puppeteer-core'; import sinon from 'sinon'; @@ -302,6 +302,10 @@ describe('ConsoleCollector', () => { }; }); + afterEach(() => { + sinon.restore(); + }); + it('emits issues on page', async () => { const browser = getMockBrowser(); const page = (await browser.pages())[0]; diff --git a/tests/formatters/IssueFormatter.test.ts b/tests/formatters/IssueFormatter.test.ts index c46fbb6fa..de1764857 100644 --- a/tests/formatters/IssueFormatter.test.ts +++ b/tests/formatters/IssueFormatter.test.ts @@ -21,7 +21,7 @@ describe('IssueFormatter', () => { }); afterEach(() => { - getIssueDescriptionStub.restore(); + sinon.restore(); }); it('formats an issue message', t => { diff --git a/tests/tools/extensions.test.ts b/tests/tools/extensions.test.ts index 65f645ab4..c8bbce683 100644 --- a/tests/tools/extensions.test.ts +++ b/tests/tools/extensions.test.ts @@ -6,7 +6,7 @@ import assert from 'node:assert'; import path from 'node:path'; -import {describe, it} from 'node:test'; +import {afterEach, describe, it} from 'node:test'; import sinon from 'sinon'; @@ -34,6 +34,10 @@ function extractId(response: McpResponse) { } describe('extension', () => { + afterEach(() => { + sinon.restore(); + }); + it('installs and uninstalls an extension and verifies it in chrome://extensions', async () => { await withMcpContext(async (response, context) => { // Install the extension diff --git a/tests/tools/pages.test.ts b/tests/tools/pages.test.ts index 2d4110f8b..cf75af222 100644 --- a/tests/tools/pages.test.ts +++ b/tests/tools/pages.test.ts @@ -5,7 +5,7 @@ */ import assert from 'node:assert'; -import {describe, it} from 'node:test'; +import {afterEach, describe, it} from 'node:test'; import type {Dialog} from 'puppeteer-core'; import sinon from 'sinon'; @@ -23,6 +23,10 @@ import { import {html, withMcpContext} from '../utils.js'; describe('pages', () => { + afterEach(() => { + sinon.restore(); + }); + describe('list_pages', () => { it('list pages', async () => { await withMcpContext(async (response, context) => { From 7760d339e756978ddf5af309d77b78eaf97c5265 Mon Sep 17 00:00:00 2001 From: Madhavi Pasumarthi Date: Wed, 18 Feb 2026 13:56:04 -0500 Subject: [PATCH 12/15] test(mcp): add eval scenarios for vague and URL-based webpage prompts (refs #940) --- .../eval_scenarios/fix_webpage_issues_test.ts | 57 +++++++++++++++++++ .../eval_scenarios/frontend_snapshot_test.ts | 34 +++++++++++ src/tools/pages.ts | 5 +- 3 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 scripts/eval_scenarios/fix_webpage_issues_test.ts create mode 100644 scripts/eval_scenarios/frontend_snapshot_test.ts diff --git a/scripts/eval_scenarios/fix_webpage_issues_test.ts b/scripts/eval_scenarios/fix_webpage_issues_test.ts new file mode 100644 index 000000000..0c4d040d2 --- /dev/null +++ b/scripts/eval_scenarios/fix_webpage_issues_test.ts @@ -0,0 +1,57 @@ +/** + * @license + * Copyright 2026 Google LLC + * SPDX-License-Identifier: Apache-2.0 + * + * Eval scenario: user asks to fix issues with their webpage (no URL given). + * When no URL is provided, the model should pick the current frontend and run + * and inspect it. Verifies the MCP server is invoked and the model opens the + * frontend and inspects it (snapshot, console, or network). + * + * Note: Tools like performance_start_trace, take_snapshot, list_console_messages, + * and list_network_requests do not require a URL in the prompt—they operate on + * the currently selected page. Only navigate_page/new_page need a URL to open + * a page; the eval runner injects the test URL when htmlRoute is set. + */ + +import assert from 'node:assert'; + +import type {TestScenario} from '../eval_gemini.ts'; + +const INSPECTION_TOOLS = [ + 'take_snapshot', + 'list_console_messages', + 'list_network_requests', +]; + +export const scenario: TestScenario = { + prompt: 'Can you fix issues with my webpage?', + maxTurns: 4, + htmlRoute: { + path: '/fix_issues_test.html', + htmlContent: ` +

Test Page

+

Some content

+ + `, + }, + expectations: calls => { + const NAVIGATION_TOOLS = ['navigate_page', 'new_page']; + assert.ok(calls.length >= 2, 'Expected at least navigation and one inspection'); + const navigationIndex = calls.findIndex(c => NAVIGATION_TOOLS.includes(c.name)); + assert.ok( + navigationIndex !== -1, + `Expected a navigation call (${NAVIGATION_TOOLS.join(' or ')}), got: ${calls.map(c => c.name).join(', ')}`, + ); + const afterNavigation = calls.slice(navigationIndex + 1); + const inspectionCalls = afterNavigation.filter(c => + INSPECTION_TOOLS.includes(c.name), + ); + assert.ok( + inspectionCalls.length >= 1, + `Expected at least one inspection tool (${INSPECTION_TOOLS.join(', ')}) after navigation, got: ${calls.map(c => c.name).join(', ')}`, + ); + }, +}; diff --git a/scripts/eval_scenarios/frontend_snapshot_test.ts b/scripts/eval_scenarios/frontend_snapshot_test.ts new file mode 100644 index 000000000..c19b0011c --- /dev/null +++ b/scripts/eval_scenarios/frontend_snapshot_test.ts @@ -0,0 +1,34 @@ +/** + * @license + * Copyright 2026 Google LLC + * SPDX-License-Identifier: Apache-2.0 + * + * Eval scenario using "website"/"webpage" wording to verify the model invokes + * the right tools when users ask to open a site and read its content. + */ + +import assert from 'node:assert'; + +import type {TestScenario} from '../eval_gemini.ts'; + +export const scenario: TestScenario = { + prompt: + 'Open the website at and tell me what content is on the page.', + maxTurns: 3, + htmlRoute: { + path: '/frontend_snapshot.html', + htmlContent: '

Frontend Test

This is a test webpage.

', + }, + expectations: calls => { + assert.strictEqual(calls.length, 2); + assert.ok( + calls[0].name === 'navigate_page' || calls[0].name === 'new_page', + 'First call should be navigation', + ); + assert.strictEqual( + calls[1].name, + 'take_snapshot', + 'Second call should be take_snapshot to read page content', + ); + }, +}; diff --git a/src/tools/pages.ts b/src/tools/pages.ts index 60fc8f3b6..8b33e2b9e 100644 --- a/src/tools/pages.ts +++ b/src/tools/pages.ts @@ -80,7 +80,8 @@ export const closePage = defineTool({ export const newPage = defineTool({ name: 'new_page', - description: `Creates a new page`, + + description: `Open a new tab and load a URL. If no URL given, ask to run from current directory or for the URL.`, annotations: { category: ToolCategory.NAVIGATION, readOnlyHint: false, @@ -113,7 +114,7 @@ export const newPage = defineTool({ export const navigatePage = defineTool({ name: 'navigate_page', - description: `Navigates the currently selected page to a URL.`, + description: `Go to a URL, or back, forward, or reload. If no URL given, ask to run from current directory or for the URL.`, annotations: { category: ToolCategory.NAVIGATION, readOnlyHint: false, From 31e1a0f20088317d358d53d35a709250d12eaddc Mon Sep 17 00:00:00 2001 From: Madhavi Pasumarthi Date: Fri, 27 Feb 2026 16:17:04 -0500 Subject: [PATCH 13/15] fix(mcp): Updated file system args --- src/main.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main.ts b/src/main.ts index 4954ae7ea..2468336fd 100644 --- a/src/main.ts +++ b/src/main.ts @@ -17,6 +17,10 @@ import {VERSION} from './version.js'; export const args = parseArguments(VERSION); +if (args.slim === undefined) { + args.slim = false; +} + const logFile = args.logFile ? saveLogsToFile(args.logFile) : undefined; if ( process.env['CI'] || From dff4104b02e9332cbbb72290b544b1b83115f30e Mon Sep 17 00:00:00 2001 From: Alex Rudenko Date: Wed, 4 Mar 2026 18:26:33 +0100 Subject: [PATCH 14/15] Update src/tools/pages.ts --- src/tools/pages.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/pages.ts b/src/tools/pages.ts index d9e254f0e..b3b4a5ad8 100644 --- a/src/tools/pages.ts +++ b/src/tools/pages.ts @@ -132,7 +132,7 @@ export const newPage = defineTool({ export const navigatePage = definePageTool({ name: 'navigate_page', - description: `Go to a URL, or back, forward, or reload. If no URL given, ask to run from current directory or for the URL.`, + description: `Go to a URL, or back, forward, or reload. Use project URL if not specified otherwise.`, annotations: { category: ToolCategory.NAVIGATION, readOnlyHint: false, From 6b8f3618b40184f989072855e65f8c4e8327c882 Mon Sep 17 00:00:00 2001 From: Alex Rudenko Date: Wed, 4 Mar 2026 18:34:20 +0100 Subject: [PATCH 15/15] chore: fixes --- docs/tool-reference.md | 10 +++++----- scripts/eval_scenarios/fix_webpage_issues_test.ts | 9 +++++++-- src/main.ts | 4 ---- src/tools/pages.ts | 3 +-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/tool-reference.md b/docs/tool-reference.md index 9599115e3..e13e94445 100644 --- a/docs/tool-reference.md +++ b/docs/tool-reference.md @@ -1,6 +1,6 @@ -# Chrome DevTools MCP Tool Reference (~6915 cl100k_base tokens) +# Chrome DevTools MCP Tool Reference (~6927 cl100k_base tokens) - **[Input automation](#input-automation)** (9 tools) - [`click`](#click) @@ -165,7 +165,7 @@ ### `navigate_page` -**Description:** Navigates the currently selected page to a URL. +**Description:** Go to a URL, or back, forward, or reload. Use project URL if not specified otherwise. **Parameters:** @@ -180,7 +180,7 @@ ### `new_page` -**Description:** Creates a new page +**Description:** Open a new tab and load a URL. Use project URL if not specified otherwise. **Parameters:** @@ -256,7 +256,7 @@ ### `performance_start_trace` -**Description:** Starts a performance trace recording on the selected page. This can be used to look for performance problems and insights to improve the performance of the page. It will also report Core Web Vital (CWV) scores for the page. +**Description:** Start a performance trace on the selected webpage. Use to find frontend performance issues, Core Web Vitals (LCP, INP, CLS), and improve page load speed. **Parameters:** @@ -268,7 +268,7 @@ ### `performance_stop_trace` -**Description:** Stops the active performance trace recording on the selected page. +**Description:** Stop the active performance trace recording on the selected webpage. **Parameters:** diff --git a/scripts/eval_scenarios/fix_webpage_issues_test.ts b/scripts/eval_scenarios/fix_webpage_issues_test.ts index 0c4d040d2..df19af9e8 100644 --- a/scripts/eval_scenarios/fix_webpage_issues_test.ts +++ b/scripts/eval_scenarios/fix_webpage_issues_test.ts @@ -39,8 +39,13 @@ export const scenario: TestScenario = { }, expectations: calls => { const NAVIGATION_TOOLS = ['navigate_page', 'new_page']; - assert.ok(calls.length >= 2, 'Expected at least navigation and one inspection'); - const navigationIndex = calls.findIndex(c => NAVIGATION_TOOLS.includes(c.name)); + assert.ok( + calls.length >= 2, + 'Expected at least navigation and one inspection', + ); + const navigationIndex = calls.findIndex(c => + NAVIGATION_TOOLS.includes(c.name), + ); assert.ok( navigationIndex !== -1, `Expected a navigation call (${NAVIGATION_TOOLS.join(' or ')}), got: ${calls.map(c => c.name).join(', ')}`, diff --git a/src/main.ts b/src/main.ts index 4eaac851e..4f97418d2 100644 --- a/src/main.ts +++ b/src/main.ts @@ -17,10 +17,6 @@ import {VERSION} from './version.js'; export const args = parseArguments(VERSION); -if (args.slim === undefined) { - args.slim = false; -} - const logFile = args.logFile ? saveLogsToFile(args.logFile) : undefined; if ( process.env['CI'] || diff --git a/src/tools/pages.ts b/src/tools/pages.ts index b3b4a5ad8..895632bd3 100644 --- a/src/tools/pages.ts +++ b/src/tools/pages.ts @@ -87,8 +87,7 @@ export const closePage = defineTool({ export const newPage = defineTool({ name: 'new_page', - - description: `Open a new tab and load a URL. If no URL given, ask to run from current directory or for the URL.`, + description: `Open a new tab and load a URL. Use project URL if not specified otherwise.`, annotations: { category: ToolCategory.NAVIGATION, readOnlyHint: false,