Showing preview only (4,726K chars total). Download the full file or copy to clipboard to get everything.
Repository: ChromeDevTools/chrome-devtools-mcp
Branch: main
Commit: 41ff9bfbc12b
Files: 214
Total size: 4.5 MB
Directory structure:
gitextract_cbkm4aqd/
├── .agent/
│ └── rules/
│ └── coding.md
├── .claude-plugin/
│ ├── marketplace.json
│ └── plugin.json
├── .gitattributes
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── 01-bug.yml
│ │ ├── 02-feature.yml
│ │ ├── 03-task.yml
│ │ └── config.yml
│ ├── dependabot.yml
│ └── workflows/
│ ├── conventional-commit.yml
│ ├── pre-release.yml
│ ├── presubmit.yml
│ ├── publish-to-npm-on-tag.yml
│ ├── release-please.yml
│ └── run-tests.yml
├── .gitignore
├── .mcp.json
├── .nvmrc
├── .prettierignore
├── .prettierrc.cjs
├── .release-please-manifest.json
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── SECURITY.md
├── docs/
│ ├── cli.md
│ ├── debugging-android.md
│ ├── design-principles.md
│ ├── slim-tool-reference.md
│ ├── tool-reference.md
│ └── troubleshooting.md
├── eslint.config.mjs
├── gemini-extension.json
├── package.json
├── puppeteer.config.cjs
├── release-please-config.json
├── rollup.config.mjs
├── scripts/
│ ├── append-lighthouse-notices.ts
│ ├── count_tokens.ts
│ ├── eslint_rules/
│ │ ├── check-license-rule.js
│ │ └── local-plugin.js
│ ├── eval_gemini.ts
│ ├── eval_scenarios/
│ │ ├── console_test.ts
│ │ ├── emulation_test.ts
│ │ ├── emulation_userAgent_test.ts
│ │ ├── emulation_viewport_test.ts
│ │ ├── fix_webpage_issues_test.ts
│ │ ├── frontend_snapshot_test.ts
│ │ ├── input_parallel_test.ts
│ │ ├── input_test.ts
│ │ ├── isolated_context_test.ts
│ │ ├── lighthouse_a11y_test.ts
│ │ ├── lighthouse_best_practices_test.ts
│ │ ├── navigation_test.ts
│ │ ├── network_test.ts
│ │ ├── page_focus_keyboard_test.ts
│ │ ├── page_id_routing_test.ts
│ │ ├── performance_test.ts
│ │ ├── select_page_test.ts
│ │ └── snapshot_test.ts
│ ├── generate-cli.ts
│ ├── generate-docs.ts
│ ├── post-build.ts
│ ├── prepare.ts
│ ├── test.mjs
│ ├── tsconfig.json
│ ├── update-lighthouse.ts
│ ├── verify-npm-package.mjs
│ └── verify-server-json-version.ts
├── server.json
├── skills/
│ ├── a11y-debugging/
│ │ ├── SKILL.md
│ │ └── references/
│ │ └── a11y-snippets.md
│ ├── chrome-devtools/
│ │ └── SKILL.md
│ ├── chrome-devtools-cli/
│ │ ├── SKILL.md
│ │ └── references/
│ │ └── installation.md
│ ├── debug-optimize-lcp/
│ │ ├── SKILL.md
│ │ └── references/
│ │ ├── elements-and-size.md
│ │ ├── lcp-breakdown.md
│ │ ├── lcp-snippets.md
│ │ └── optimization-strategies.md
│ └── troubleshooting/
│ └── SKILL.md
├── src/
│ ├── DevToolsConnectionAdapter.ts
│ ├── DevtoolsUtils.ts
│ ├── McpContext.ts
│ ├── McpPage.ts
│ ├── McpResponse.ts
│ ├── Mutex.ts
│ ├── PageCollector.ts
│ ├── SlimMcpResponse.ts
│ ├── WaitForHelper.ts
│ ├── bin/
│ │ ├── chrome-devtools-cli-options.ts
│ │ ├── chrome-devtools-mcp-cli-options.ts
│ │ ├── chrome-devtools-mcp-main.ts
│ │ ├── chrome-devtools-mcp.ts
│ │ ├── chrome-devtools.ts
│ │ └── cliDefinitions.ts
│ ├── browser.ts
│ ├── daemon/
│ │ ├── client.ts
│ │ ├── daemon.ts
│ │ ├── types.ts
│ │ └── utils.ts
│ ├── devtools.d.ts
│ ├── formatters/
│ │ ├── ConsoleFormatter.ts
│ │ ├── IssueFormatter.ts
│ │ ├── NetworkFormatter.ts
│ │ └── SnapshotFormatter.ts
│ ├── index.ts
│ ├── issue-descriptions.ts
│ ├── logger.ts
│ ├── polyfill.ts
│ ├── telemetry/
│ │ ├── ClearcutLogger.ts
│ │ ├── WatchdogClient.ts
│ │ ├── flagUtils.ts
│ │ ├── metricUtils.ts
│ │ ├── persistence.ts
│ │ ├── types.ts
│ │ └── watchdog/
│ │ ├── ClearcutSender.ts
│ │ └── main.ts
│ ├── third_party/
│ │ ├── LIGHTHOUSE_MCP_BUNDLE_THIRD_PARTY_NOTICES
│ │ ├── devtools-formatter-worker.ts
│ │ ├── index.ts
│ │ └── lighthouse-devtools-mcp-bundle.js
│ ├── tools/
│ │ ├── ToolDefinition.ts
│ │ ├── categories.ts
│ │ ├── console.ts
│ │ ├── emulation.ts
│ │ ├── extensions.ts
│ │ ├── input.ts
│ │ ├── lighthouse.ts
│ │ ├── memory.ts
│ │ ├── network.ts
│ │ ├── pages.ts
│ │ ├── performance.ts
│ │ ├── screencast.ts
│ │ ├── screenshot.ts
│ │ ├── script.ts
│ │ ├── slim/
│ │ │ └── tools.ts
│ │ ├── snapshot.ts
│ │ └── tools.ts
│ ├── trace-processing/
│ │ └── parse.ts
│ ├── types.ts
│ ├── utils/
│ │ ├── ExtensionRegistry.ts
│ │ ├── files.ts
│ │ ├── keyboard.ts
│ │ ├── pagination.ts
│ │ ├── string.ts
│ │ └── types.ts
│ └── version.ts
├── tests/
│ ├── DevtoolsUtils.test.ts
│ ├── McpContext.test.js.snapshot
│ ├── McpContext.test.ts
│ ├── McpResponse.test.js.snapshot
│ ├── McpResponse.test.ts
│ ├── PageCollector.test.ts
│ ├── browser.test.ts
│ ├── cli.test.ts
│ ├── daemon/
│ │ ├── client.test.ts
│ │ └── utils.test.ts
│ ├── e2e/
│ │ ├── chrome-devtools.test.ts
│ │ └── telemetry.test.ts
│ ├── formatters/
│ │ ├── ConsoleFormatter.test.js.snapshot
│ │ ├── ConsoleFormatter.test.ts
│ │ ├── IssueFormatter.test.js.snapshot
│ │ ├── IssueFormatter.test.ts
│ │ ├── NetworkFormatter.test.ts
│ │ ├── snapshotFormatter.test.js.snapshot
│ │ └── snapshotFormatter.test.ts
│ ├── index.test.js.snapshot
│ ├── index.test.ts
│ ├── server.ts
│ ├── setup.ts
│ ├── snapshot.ts
│ ├── telemetry/
│ │ ├── ClearcutLogger.test.ts
│ │ ├── WatchdogClient.test.ts
│ │ ├── flagUtils.test.ts
│ │ ├── metricUtils.test.ts
│ │ ├── persistence.test.ts
│ │ └── watchdog/
│ │ └── ClearcutSender.test.ts
│ ├── third_party_notices.test.js.snapshot
│ ├── third_party_notices.test.ts
│ ├── tools/
│ │ ├── console.test.js.snapshot
│ │ ├── console.test.ts
│ │ ├── emulation.test.ts
│ │ ├── extensions.test.ts
│ │ ├── fixtures/
│ │ │ ├── extension/
│ │ │ │ ├── manifest.json
│ │ │ │ └── popup.html
│ │ │ ├── extension-side-panel/
│ │ │ │ ├── manifest.json
│ │ │ │ ├── sidepanel.html
│ │ │ │ └── sw.js
│ │ │ └── extension-sw/
│ │ │ ├── manifest.json
│ │ │ ├── popup.html
│ │ │ └── sw.js
│ │ ├── input.test.ts
│ │ ├── lighthouse.test.js.snapshot
│ │ ├── lighthouse.test.ts
│ │ ├── memory.test.ts
│ │ ├── network.test.js.snapshot
│ │ ├── network.test.ts
│ │ ├── pages.test.js.snapshot
│ │ ├── pages.test.ts
│ │ ├── performance.test.js.snapshot
│ │ ├── performance.test.ts
│ │ ├── screencast.test.ts
│ │ ├── screenshot.test.ts
│ │ ├── script.test.ts
│ │ ├── slim/
│ │ │ ├── tools.test.js.snapshot
│ │ │ └── tools.test.ts
│ │ └── snapshot.test.ts
│ ├── trace-processing/
│ │ ├── fixtures/
│ │ │ └── load.ts
│ │ ├── parse.test.js.snapshot
│ │ └── parse.test.ts
│ └── utils.ts
└── tsconfig.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .agent/rules/coding.md
================================================
---
trigger: always_on
---
# Instructions
- Use only scripts from `package.json` to run commands.
- Use `npm run build` to run tsc and test build.
- Use `npm run test` to build and run tests, run all tests to verify correctness.
- Use `npm run test path-to-test.ts` to build and run a single test file, for example, `npm run test tests/McpContext.test.ts`.
- Use `npm run format` to fix formatting and get linting errors.
## Rules for TypeScript
- Do not use `any` type.
- Do not use `as` keyword for type casting.
- Do not use `!` operator for type assertion.
- Do not use `// @ts-ignore` comments.
- Do not use `// @ts-nocheck` comments.
- Do not use `// @ts-expect-error` comments.
- Prefer `for..of` instead of `forEach`.
================================================
FILE: .claude-plugin/marketplace.json
================================================
{
"name": "chrome-devtools-plugins",
"version": "1.0.0",
"description": "Bundled plugins for actuating and debugging the Chrome browser.",
"owner": {
"name": "Chrome DevTools Team",
"email": "devtools-dev@chromium.org"
},
"plugins": [
{
"name": "chrome-devtools-mcp",
"source": "./",
"description": "Reliable automation, in-depth debugging, and performance analysis in Chrome using Chrome DevTools and Puppeteer"
}
]
}
================================================
FILE: .claude-plugin/plugin.json
================================================
{
"name": "chrome-devtools-mcp",
"version": "latest",
"description": "Reliable automation, in-depth debugging, and performance analysis in Chrome using Chrome DevTools and Puppeteer",
"mcpServers": {
"chrome-devtools": {
"command": "npx",
"args": ["chrome-devtools-mcp@latest"]
}
}
}
================================================
FILE: .gitattributes
================================================
* text=auto eol=lf
================================================
FILE: .github/ISSUE_TEMPLATE/01-bug.yml
================================================
name: Bug report
description: File a bug report for chrome-devtools-mcp
title: '<short description of the bug>'
type: 'Bug'
body:
- id: description
type: textarea
attributes:
label: Description of the bug
description: >
A clear and concise description of what the bug is.
placeholder:
validations:
required: true
- id: reproduce
type: textarea
attributes:
label: Reproduction
description: >
Steps to reproduce the behavior:
placeholder: |
1. Use tool '...'
2. Then use tool '...'
- id: expectation
type: textarea
attributes:
label: Expectation
description: A clear and concise description of what you expected to happen.
- id: mcp-configuration
type: textarea
attributes:
label: MCP configuration
- id: chrome-devtools-mcp-version
type: input
attributes:
label: Chrome DevTools MCP version
validations:
required: true
- id: chrome-version
type: input
attributes:
label: Chrome version
- id: coding-agent-version
type: input
attributes:
label: Coding agent version
- id: model-version
type: input
attributes:
label: Model version
- id: chat-log
type: input
attributes:
label: Chat log
- id: node-version
type: input
attributes:
label: Node version
description: >
Please verify you have the minimal supported version listed in the README.md
- id: operating-system
type: dropdown
attributes:
label: Operating system
description: What supported operating system are you running?
options:
- Windows
- Windows Subsystem for Linux (WSL)
- macOS
- Linux
- type: checkboxes
id: provide-pr
attributes:
label: Extra checklist
options:
- label: I want to provide a PR to fix this bug
================================================
FILE: .github/ISSUE_TEMPLATE/02-feature.yml
================================================
name: Feature
description: Suggest an idea for for chrome-devtools-mcp
title: '<short description of the feature request>'
type: 'Feature'
labels:
- feature
body:
- id: description
type: textarea
attributes:
label: Is your feature request related to a problem? Please describe.
description: >
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
placeholder:
validations:
required: true
- id: solution
type: textarea
attributes:
label: Describe the solution you'd like
description: >
A clear and concise description of what you want to happen.
placeholder:
validations:
required: true
- id: alternatives
type: textarea
attributes:
label: Describe alternatives you've considered
description: >
A clear and concise description of any alternative solutions or features you've considered.
placeholder:
validations:
required: true
- id: additional-context
type: textarea
attributes:
label: Additional context
description: >
Add any other context or screenshots about the feature request here.
placeholder:
================================================
FILE: .github/ISSUE_TEMPLATE/03-task.yml
================================================
name: Task
description: Work tracking for mainainers only!
title: '[Task]:'
type: 'Task'
body:
- type: markdown
attributes:
value: |
### This issue type should be used only by mainainers!
Task are to track small non user facing issue or improvements.
The issue will be closed if it does not follow those rules.
- type: textarea
attributes:
label: 'Task to do:'
id: task
validations:
required: true
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: npm
directory: /
schedule:
interval: weekly
day: 'sunday'
time: '02:00'
timezone: Europe/Berlin
groups:
dependencies:
dependency-type: production
patterns:
- '*'
dev-dependencies:
dependency-type: development
exclude-patterns:
- 'puppeteer*'
- 'chrome-devtools-frontend'
- '@modelcontextprotocol/sdk'
- 'yargs'
- 'debug'
- 'core-js'
patterns:
- '*'
# breaks often so better to roll separetely.
bundled-devtools:
patterns:
- 'chrome-devtools-frontend'
bundled:
patterns:
- 'puppeteer*'
- '@modelcontextprotocol/sdk'
- 'yargs'
- 'debug'
- 'core-js'
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
day: 'sunday'
time: '04:00'
timezone: Europe/Berlin
groups:
all:
patterns:
- '*'
================================================
FILE: .github/workflows/conventional-commit.yml
================================================
name: 'Conventional Commit'
on:
merge_group:
pull_request_target:
types:
# Defaults
# https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows#pull_request_target
- opened
- reopened
- synchronize
# Tracks editing PR title or description, or base branch changes
# https://docs.github.com/en/webhooks/webhook-events-and-payloads?actionType=edited#pull_request
- edited
jobs:
main:
name: '[Required] Validate PR title'
runs-on: ubuntu-latest
permissions:
pull-requests: read
steps:
- if: github.event_name != 'merge_group'
uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6.1.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
================================================
FILE: .github/workflows/pre-release.yml
================================================
name: Pre-release
permissions: read-all
on:
workflow_dispatch:
push:
branches:
- release-please-*
jobs:
pre-release:
name: 'Verify artifacts before release'
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 2
- name: Set up Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
cache: npm
node-version-file: '.nvmrc'
registry-url: 'https://registry.npmjs.org'
# Ensure npm 11.5.1 or later is installed
- name: Update npm
run: npm install -g npm@latest
- name: Install dependencies
run: npm ci
- name: Build and bundle
run: npm run bundle
env:
NODE_ENV: 'production'
- name: Verify server.json
run: npm run verify-server-json-version
- name: Verify npm package
run: npm run verify-npm-package
================================================
FILE: .github/workflows/presubmit.yml
================================================
name: Check code before submitting
permissions: read-all
on:
merge_group:
push:
branches:
- main
pull_request:
jobs:
check-format:
name: '[Required] Check correct format'
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 2
- name: Set up Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
cache: npm
node-version-file: '.nvmrc'
- name: Install dependencies
run: npm ci
- name: Run format check
run: npm run check-format
check-docs:
name: '[Required] Check docs updated'
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 2
- name: Set up Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
cache: npm
node-version-file: '.nvmrc'
- name: Install dependencies
run: npm ci
- name: Generate
run: npm run gen
- name: Check if autogenerated code and docs are out of date
run: |
diff_file=$(mktemp doc_diff_XXXXXX)
git diff --color > $diff_file
if [[ -s $diff_file ]]; then
echo "Please update the documentation by running 'npm run gen'. The following was the diff"
cat $diff_file
rm $diff_file
exit 1
fi
rm $diff_file
================================================
FILE: .github/workflows/publish-to-npm-on-tag.yml
================================================
name: publish-on-tag
on:
push:
tags:
- 'chrome-devtools-mcp-v*'
workflow_dispatch:
inputs:
npm-publish:
description: 'Try to publish to NPM'
default: false
type: boolean
mcp-publish:
description: 'Try to publish to MCP registry'
default: true
type: boolean
permissions:
id-token: write # Required for OIDC
contents: read
jobs:
publish-to-npm:
runs-on: ubuntu-latest
if: ${{ (github.event_name != 'workflow_dispatch') || (inputs.npm-publish && always()) }}
steps:
- name: Check out repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 2
- name: Set up Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
cache: npm
node-version-file: '.nvmrc'
registry-url: 'https://registry.npmjs.org'
# Ensure npm 11.5.1 or later is installed
- name: Update npm
run: npm install -g npm@latest
- name: Install dependencies
run: npm ci
- name: Build and bundle
run: npm run bundle
env:
NODE_ENV: 'production'
- name: Publish
run: |
npm publish --provenance --access public
publish-to-mcp-registry:
runs-on: ubuntu-latest
needs: publish-to-npm
if: ${{ (github.event_name != 'workflow_dispatch' && needs.publish-to-npm.result == 'success') || (inputs.mcp-publish && always()) }}
steps:
- name: Check out repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 2
- name: Set up Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
cache: npm
node-version-file: '.nvmrc'
registry-url: 'https://registry.npmjs.org'
# Ensure npm 11.5.1 or later is installed
- name: Update npm
run: npm install -g npm@latest
- name: Install dependencies
run: npm ci
- name: Build and bundle
run: npm run bundle
env:
NODE_ENV: 'production'
- name: Install MCP Publisher
run: |
export OS=$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')
curl -L "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_${OS}.tar.gz" | tar xz mcp-publisher
- name: Login to MCP Registry
run: ./mcp-publisher login github-oidc
- name: Publish to MCP Registry
run: ./mcp-publisher publish
================================================
FILE: .github/workflows/release-please.yml
================================================
on:
push:
branches:
- main
permissions: read-all
name: release-please
jobs:
release-please:
runs-on: ubuntu-latest
steps:
- uses: googleapis/release-please-action@v4
with:
token: ${{ secrets.BROWSER_AUTOMATION_BOT_TOKEN }}
target-branch: main
config-file: release-please-config.json
manifest-file: .release-please-manifest.json
================================================
FILE: .github/workflows/run-tests.yml
================================================
name: Compile and run tests
permissions: read-all
on:
merge_group:
push:
branches:
- main
pull_request:
jobs:
run-tests:
name: Tests on ${{ matrix.os }} with node ${{ matrix.node }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
- windows-latest
- macos-latest
node:
- 20
- 22
- 23
- 24
steps:
- name: Check out repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 2
- name: Set up Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
cache: npm
node-version: 22 # build works only with 22+.
- name: Install dependencies
shell: bash
run: npm ci
- name: Build
run: npm run bundle
env:
NODE_OPTIONS: '--max_old_space_size=4096'
- name: Set up Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
cache: npm
node-version: ${{ matrix.node }}
- name: Disable AppArmor
if: ${{ matrix.os == 'ubuntu-latest' }}
shell: bash
run: echo 0 | sudo tee /proc/sys/kernel/apparmor_restrict_unprivileged_userns
- name: Run tests
shell: bash
# Retry tests if they fail in the merge queue.
run: npm run test:no-build -- ${{ github.event_name == 'merge_group' && '--retry' || '' }}
# Gating job for branch protection.
test-success:
name: '[Required] Tests passed'
runs-on: ubuntu-latest
needs: run-tests
if: ${{ !cancelled() }}
steps:
- if: ${{ needs.run-tests.result != 'success' }}
run: 'exit 1'
- run: 'exit 0'
================================================
FILE: .gitignore
================================================
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
trace.json
trace.json.gz
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional stylelint cache
.stylelintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# vuepress v2.x temp and cache directory
.temp
.cache
# vitepress build output
**/.vitepress/dist
# vitepress cache directory
**/.vitepress/cache
# Docusaurus cache and generated files
.docusaurus
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# Stores VSCode specific settings
.vscode
!.vscode/*.template.json
!.vscode/extensions.json
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
# Build output directory
build/
log.txt
.DS_Store
================================================
FILE: .mcp.json
================================================
{
"chrome-devtools": {
"command": "npx",
"args": ["chrome-devtools-mcp@latest"]
}
}
================================================
FILE: .nvmrc
================================================
v22
================================================
FILE: .prettierignore
================================================
# Prettier-only ignores.
CHANGELOG.md
src/third_party/lighthouse-devtools-mcp-bundle.js
================================================
FILE: .prettierrc.cjs
================================================
/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @type {import('prettier').Config}
*/
module.exports = {
bracketSpacing: false,
singleQuote: true,
trailingComma: 'all',
arrowParens: 'avoid',
singleAttributePerLine: true,
htmlWhitespaceSensitivity: 'strict',
endOfLine: 'lf',
};
================================================
FILE: .release-please-manifest.json
================================================
{
".": "0.20.2"
}
================================================
FILE: CHANGELOG.md
================================================
# Changelog
## [0.20.2](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.20.1...chrome-devtools-mcp-v0.20.2) (2026-03-18)
### 📄 Documentation
* add troubleshooting for Claude Code plugin HTTPS clone failures ([#1195](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1195)) ([d082ca4](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/d082ca4ecd35a023d09f9c1ff949d5fb0c3fb069))
## [0.20.1](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.20.0...chrome-devtools-mcp-v0.20.1) (2026-03-16)
### 🛠️ Fixes
* update VS Code manual installation powershell command ([#1151](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1151)) ([6c64a5b](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/6c64a5b543714796b25a12dc6f2be7a1e683e8bd))
### ⚡ Performance
* use CDP to find open DevTools pages. ([#1150](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1150)) ([94de19c](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/94de19cdcdae9e31d0962b273ce352dc248eb5a8))
## [0.20.0](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.19.0...chrome-devtools-mcp-v0.20.0) (2026-03-11)
### 🎉 Features
* experimental `chrome-devtools` CLI ([#1100](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1100)) ([1ac574e](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/1ac574e7154948e86e414e5149fb975a190d5bb0))
### 📄 Documentation
* fix typo ([#1155](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1155)) ([b59cabc](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/b59cabcc1d59802ffd7d9667040188e46192357d))
* fix typos and improve phrasing ([#1130](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1130)) ([70d4f36](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/70d4f365dc619a5743e697c30800f7065bc6227d))
* revise contribution process and add release process ([#1134](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1134)) ([d7d26a1](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/d7d26a103b840e2feb7cb9af6a242edda94f1ddf))
* **troubleshooting:** add symptom for missing tools due to read-only mode ([#1148](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1148)) ([57e7d51](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/57e7d51e8ca1e2ee325a9e7a9c64c033acbe6d6a))
* Update troubleshooting for MCP server connection errors ([#1017](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1017)) ([00f9c31](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/00f9c3108ab9caefca57998439052c728298920b))
### 🏗️ Refactor
* move main files ([#1120](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1120)) ([c2d8009](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/c2d8009ff75f76bce1ec4cf79c2467b50d81725e))
## [0.19.0](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.18.1...chrome-devtools-mcp-v0.19.0) (2026-03-05)
### 🎉 Features
* add pageId routing for parallel multi-agent workflows ([#1022](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1022)) ([caf601a](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/caf601a32832bb87cfac801a6bbeacb87508412f)), closes [#1019](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1019)
* Add skill which helps with onboarding of the mcp server ([#1083](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1083)) ([7273f16](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/7273f16ec08f6d5b46a2693b0ad4d559086ded89))
* integrate Lighthouse audits ([#831](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/831)) ([dfdac26](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/dfdac2648e560d756a8711ad3bb1fa470be8e7c9))
### 🛠️ Fixes
* improve error messages around --auto-connect ([#1075](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1075)) ([bcb852d](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/bcb852dd2e440b0005f4a9ad270a1a7998767907))
* improve tool descriptions ([#965](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/965)) ([bdbbc84](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/bdbbc84c125bdd48f4be48aa476bec0323de611c))
* repair broken markdown and extract snippets in a11y-debugging skill ([#1096](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1096)) ([adac7c5](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/adac7c537ee304f324c5e7284fb363396d1773f5))
* simplify emulation and script tools ([#1073](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1073)) ([e51ba47](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/e51ba4720338951e621585b77efc6a0e07678d99))
* simplify focus state management ([#1063](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1063)) ([f763da2](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/f763da24a10e27605c0a5069853ce7c92974eec2))
* tweak lighthouse description ([#1112](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1112)) ([5538180](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/55381804ae7ffa8a1e5933b621a9b8390b3000ff))
### 📄 Documentation
* Adapt a11y skill to utilize Lighthouse ([#1054](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1054)) ([21634e6](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/21634e660c346e469ae62116b1824538f51567dd))
* add feature release checklist to CONTRIBUTING.md ([#1118](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1118)) ([0378457](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/03784577ffb6e238bcb2d637bff9ad759723ea7b))
* fix typo in README regarding slim mode ([#1093](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1093)) ([92f2c7b](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/92f2c7b48b56a6b1d6ac7c9e2f2e92beb26bcf62))
### 🏗️ Refactor
* clean up more of the context getters ([#1062](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1062)) ([9628dab](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/9628dabcb4d39f0b94d152a0fc419e049246a29d))
* consistently use McpPage in tools ([#1057](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1057)) ([302e5a0](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/302e5a04191ba0558e3c79f1486d01d5eb0f6896))
* improve type safety for page scoped tools ([#1051](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1051)) ([5f694c6](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/5f694c60ffd21f8b022554c92b2ad4cbdb457375))
* make cdp resolvers use McpPage ([#1060](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1060)) ([d6c06c5](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/d6c06c56a7b8e4968318adc9fc7c820ace9f5bd9))
* move dialog handling to McpPage ([#1059](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1059)) ([40c241b](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/40c241bbfc80d6282953ab325b30a597d3d85ade))
* move server to a separate file ([#1043](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1043)) ([a8bf3e5](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/a8bf3e585682c3126dfd378e9f98b5dc7ab6045d))
* remove page passing via context ([#1061](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1061)) ([4cb5a17](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/4cb5a17b57f57d8a367cd423c960ba122b9952e3))
* set defaults to performance trace tool ([#1090](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1090)) ([dfa9b79](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/dfa9b79a4ecc9e67f5b043f2dd97f6889d1fee0b))
* simplify the response texts ([#1095](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1095)) ([cb0079e](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/cb0079efbbd41874f6913772fe3f2a037e9f5f8f))
* type-cast as internal CdpPage interface ([#1064](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1064)) ([2d5e4fa](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/2d5e4fa3579650a384ff21c88c2e6b9cda031e1a))
## [0.18.1](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.18.0...chrome-devtools-mcp-v0.18.1) (2026-02-25)
### 🛠️ Fixes
* remove endsWith for filePath in memory tools ([#1041](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1041)) ([d0622d5](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/d0622d52d46ac72a28bc22f93a337fb5007214c7))
## [0.18.0](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.17.3...chrome-devtools-mcp-v0.18.0) (2026-02-24)
### 🎉 Features
* `--slim` mode for maximum token savings ([#958](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/958)) ([c402b43](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/c402b43697d834994c4fc141305189082da14bee))
* add a new skill for accessibility debugging and auditing with Chrome DevTools MCP. ([#1002](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1002)) ([b0c6d04](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/b0c6d042e4d68763acf989edc8097ce07e85dc7a))
* add experimental screencast recording tools ([#941](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/941)) ([33446d4](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/33446d457e4386fadcfe4ddf6c7a43b2e9098c9a))
* add skill to debug and optimize LCP ([#993](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/993)) ([2cd9b95](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/2cd9b95346226aa52cce18f6ab889a2ae194806c))
* add storage-isolated browser contexts ([#991](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/991)) ([59f6477](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/59f6477a70eb07585e9a510089f1dfc840a012fd))
* add take_memory_snapshot tool ([#1023](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1023)) ([7ffdc5e](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/7ffdc5ee4d9df9f62f03354fa758fb4d022c3b08))
* support any-match text arrays in wait_for ([#1011](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1011)) ([496ab1b](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/496ab1b45f7a283a1432643777e0795a17f33667))
* support type_text ([#1026](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1026)) ([b5d01b5](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/b5d01b5fe65fa20f9b76555b86a749960a5d1738))
### 🛠️ Fixes
* detect X server display on Linux ([#1027](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1027)) ([1746ed9](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/1746ed9ee11c212f78dcbb00af99a0400595e778))
### ♻️ Chores
* cleanup string and structured console formatters ([#1005](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1005)) ([0d78685](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/0d78685a5b37dc68bb11a1088ff8816ecff3bb82))
* extract version in a seprate file ([#1032](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1032)) ([0106865](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/0106865aad6d51b6cb590bf98ccaf7078e8d7436))
* move emulation settings to context ([#1000](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1000)) ([bc3c40e](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/bc3c40e8f961433fb2ae858482d66f9a55fdde32))
* optimize slim tool descriptions and params ([#1028](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1028)) ([ca6635d](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/ca6635d5a5d5e8b7b9944fa8b4e1063e6269a5f2))
* simplify JavaScript code examples, update code block language, and refine descriptions in a11y debugging skill documentation. ([#1009](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1009)) ([5cedcaa](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/5cedcaad2c8a5e488064e21fb56cbd8643345440))
* types for JSON output of IssueFormatter ([#1007](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1007)) ([9ef4479](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/9ef4479bec39c5f2651d6ebb63e9ec0fecf8bf89))
## [0.17.3](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.17.2...chrome-devtools-mcp-v0.17.3) (2026-02-19)
### 🛠️ Fixes
* remove clean from prepare ([#997](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/997)) ([2016b98](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/2016b98217bf5aa8d65c6668b1e46c8a3400276f))
## [0.17.2](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.17.1...chrome-devtools-mcp-v0.17.2) (2026-02-19)
### 🛠️ Fixes
* check that combobox is actually a select element before filling out options ([#979](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/979)) ([d2bc489](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/d2bc489e4351551ba62a104433839c4198ecae84))
* handle network request pagination correctly ([#980](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/980)) ([0d9f422](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/0d9f422201538aa847a50417f1ed370e3a6c95b2))
### 📄 Documentation
* Add a note about previously installed server installations ([#982](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/982)) ([c0009f7](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/c0009f7ab2f15bedd1c4ceb609db77bcb3c96f2d))
* update codex doc URL ([#987](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/987)) ([ebbbea7](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/ebbbea7f9d20e4dea902d06e9b86dfe1cc9b221f))
### ♻️ Chores
* **network:** de-duplicate String and JSON formatters ([#985](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/985)) ([1896dbb](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/1896dbb5a7cdc3fc0bcc5e665aee986a1180b014))
* remove text from the status code for Network requests ([#778](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/778)) ([327a388](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/327a3884d8443b8591c06ddb3f9081771ae973c3))
## [0.17.1](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.17.0...chrome-devtools-mcp-v0.17.1) (2026-02-16)
### 📄 Documentation
* Add 'Progressive Complexity' and 'Reference over Value' design principles. ([#939](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/939)) ([8d765c0](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/8d765c0aef7bbcd476c7e7fbe9ea63ee26cf4fa6))
* add Katalon Studio setup instructions to README ([#929](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/929)) ([6cfef24](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/6cfef24ec734ed62221c66bdf03b09ce000f5bfe))
* add MCP config for Claude plugin + docs ([#944](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/944)) ([a781da4](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/a781da4434c3490901b28017bc7aa40493ef8dcc))
* estimate tokens using tiktoken ([#959](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/959)) ([fd0a919](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/fd0a9193b37be4c5cda21dc4904093c7b58d61be))
* improve Claude Code installation instructions ([#947](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/947)) ([3ec5b7e](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/3ec5b7e7a2d97c9f0165c5af3317c531a9dc058f))
* Update README with WSL configuration details ([#946](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/946)) ([107c46a](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/107c46a4dbd2ba7c7b9217a75ae2b1871d3c7f0d))
### ♻️ Chores
* rename files to have more consistent style ([#935](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/935)) ([9e1f9ac](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/9e1f9ac69667ddc3e2917e2c30e5ee940a03d853))
## [0.17.0](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.16.0...chrome-devtools-mcp-v0.17.0) (2026-02-10)
### 🎉 Features
* include Error.cause chain for uncaught errors and logged Errors ([#906](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/906)) ([05b01ec](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/05b01ecaba47cf1ce38564636663222c9cab46de))
* Integrate CrUX data into performance trace summaries ([#733](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/733)) ([b747f9d](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/b747f9d74a12d2119b6531476b2f88ab66be0ff8))
* show message and stack trace in details when console.log'ging Error objects ([#902](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/902)) ([ffa00da](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/ffa00dab1b65b2eac8db215e0289317b8ed9b725))
### 🛠️ Fixes
* console formatter hides frames from ignored scripts ([#927](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/927)) ([8e2380b](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/8e2380b434d9659ffa8a7043d2589261772fa04f))
* limit stack traces to 50 lines ([#923](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/923)) ([caea23a](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/caea23a7cf33c87cd4ce426eb2a10724aba3cc71))
### 📄 Documentation
* add macOS Web Bluetooth troubleshooting note ([#930](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/930)) ([3c9528b](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/3c9528b43d9bbff166fcfcfee321149ff44ddd21)), closes [#917](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/917)
## [0.16.0](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.15.1...chrome-devtools-mcp-v0.16.0) (2026-02-04)
### 🎉 Features
* include source-mapped stack trace for uncaught errors ([#876](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/876)) ([ecef712](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/ecef712e70b47ae81eb3364d0aed801ec1c91a70))
### 🛠️ Fixes
* accidental extra typing in the fill tool ([#886](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/886)) ([3d6e59d](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/3d6e59dda42be3c6fd97446344a28cbbaa5809b3))
* update evaluateScript description formatting ([#880](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/880)) ([24db9dd](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/24db9dd78cd4f054d291322685b4f47601da3f5a))
* use 1-based line/column and fix wasm offsets in stack frames ([#884](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/884)) ([7e1ec81](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/7e1ec81fb63ec8b7c6d77dbdc88beef4240243ba))
### 📄 Documentation
* mention source-mapped stack traces in 'Key features' ([#883](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/883)) ([579d18a](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/579d18a3f4d1d8d05bf267a39de7f2f53e719b17))
* remove outdated --channel=beta note ([#882](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/882)) ([acdb5c9](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/acdb5c9bb3f249c5a9ce1d4a3e84c580af999141))
## [0.15.1](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.15.0...chrome-devtools-mcp-v0.15.1) (2026-01-30)
### 🛠️ Fixes
* disable usage statistics when CI or CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS env is set ([#862](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/862)) ([c0435a2](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/c0435a2d53eb51b7500fc5cce50344520ea164e7))
* respect custom timeouts in navigate tools ([#865](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/865)) ([a0aeb97](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/a0aeb97693fd5ca641f45ebcd4ce3b4b08ce21b8))
## [0.15.0](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.14.0...chrome-devtools-mcp-v0.15.0) (2026-01-28)
### 🎉 Features
* Add ability to inject script to run on page load ([#568](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/568)) ([d845ad4](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/d845ad48584a49aa57b11de308beeb17ed0b2e10))
* enable usage statistics by default with opt-out ([#855](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/855)) ([7e279f1](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/7e279f1b67c5cfd4ad033a4147c51fe20a7833f7))
* support testing light and dark mode ([#858](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/858)) ([5a23a8c](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/5a23a8c201d30d40395e283f4434d933826333fa))
## [0.14.0](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.13.0...chrome-devtools-mcp-v0.14.0) (2026-01-27)
### 🎉 Features
* add a skill for using chrome-devtools-mcp ([#830](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/830)) ([aa0a367](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/aa0a3679f59ab441908d31252afee1cd56102da8))
* add background parameter to new_page tool ([#837](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/837)) ([d756888](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/d7568881ba4aa0e2c10dc6148fd0ef941fee10d5))
* allow skipping snapshot generation for input tools ([#821](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/821)) ([4b8e9f2](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/4b8e9f287572e0a95c30b5ca612acf08bf79595b))
* include stack trace in 'get_console_message' tool ([#740](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/740)) ([a3a0021](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/a3a00210a30f78045244bc897ee736bdbdc36007))
* support device viewport and user agent emulation ([#798](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/798)) ([a816967](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/a8169676f920f88965a2574f53affe15c1278b43))
* support filePath for network request and response bodies ([#795](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/795)) ([6d0e4ca](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/6d0e4cab28a8498c2783c1c0c6436c655de7b336))
### 🛠️ Fixes
* handle beforeunload dialogs in navigations ([#788](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/788)) ([9b21f8b](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/9b21f8b2e972f78f58c6f633851466356330c77d))
* improve error handling for console messages ([#844](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/844)) ([dc43ede](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/dc43ede1f20302bd2feb706e63bcf992b4a66a96))
* improve error reporting when retrieving the element ([#845](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/845)) ([f7dd003](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/f7dd00340a8ac5af7fbe4922f2a1d27d99d933cc))
* improve performance tool description ([#800](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/800)) ([aa9a176](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/aa9a1769568aca2a357f186b2e80b38b2ed76323))
* increase timeouts for long text input ([#787](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/787)) ([a83a338](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/a83a33835148905b538b39be93f6115774f91696))
* make request and response handling more robust ([#846](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/846)) ([695817f](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/695817f6d6da5fcb94934fb1c2be8b006522f53b))
* re-use node ids across snapshots ([#814](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/814)) ([a6cd2cd](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/a6cd2cd3f2bd823f0e044d7796fd8ff2c100cda3))
### 📄 Documentation
* add a mention of evals into contributing.md ([#773](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/773)) ([9a31ac7](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/9a31ac7abab5890d11fec627bbdcbb8051452453))
* document how to add extensions to gemini-cli ([#834](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/834)) ([0610d11](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/0610d11aa9add484951b76adef557eed5e2bd275))
* update auto-connect docs ([#779](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/779)) ([a106fba](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/a106fbadbc1a487ce4c53a9eb783c98e524c0a9e))
* Update README.md to include a link to Android debugging ([#783](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/783)) ([6e52e66](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/6e52e66a7a7ebbf1f2e2080a857f72192036eb0c))
## [0.13.0](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.12.1...chrome-devtools-mcp-v0.13.0) (2026-01-14)
### 🎉 Features
* Allow opting out of default Chrome launch arguments ([#729](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/729)) ([9a51af2](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/9a51af219fc9216cd463bef9363716283f41f36a))
* support filePath in performance tools ([#686](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/686)) ([68ae2f8](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/68ae2f8253e2ba5c34436e25df114874c537f6df))
### 🛠️ Fixes
* support resize_page when browser window is maximized/fullscreenwindow state ([#748](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/748)) ([4d9ac22](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/4d9ac227ddff6fc4aec44e46673f6e44a8168db9))
* use relative path for plugin source in marketplace ([#724](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/724)) ([5c1ecf8](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/5c1ecf835ac8aad4947d0a8f82c899acd4115b64))
### 📄 Documentation
* add experimental chrome on android guide ([#691](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/691)) ([4a87702](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/4a87702ca6913ed62987f71e080f3d481d13b8d8))
* autoConnect - clarify how the mcp server selects a profile ([#693](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/693)) ([28b8ff8](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/28b8ff816461760c82e9b19b70f288bc7fa2fa38))
* claude code broken link ([#707](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/707)) ([1f532b8](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/1f532b8fafa0fa60aaf94c302bad663fab1c12ea))
* enhance cli docs + sort required vs opt params ([#674](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/674)) ([81cbd99](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/81cbd99f52d013d07bdcf21a0840f61a16bacd33))
* update auto connect docs to mention min Chrome version ([#681](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/681)) ([ab2340f](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/ab2340f40127dcdabde6887a411163ce9d130394))
* Update Claude Code instructions in README.md ([#711](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/711)) ([f81cd2d](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/f81cd2d8dfc35da8c718b227e0ee4c4d7c5daca8))
* update readme to include OpenCode example ([#560](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/560)) ([fbba3c9](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/fbba3c9461cec8113216fa4569e879c85312ea29))
### ♻️ Chores
* change pageIdx to page ids ([#741](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/741)) ([a23c6ba](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/a23c6ba8c9e1da90c885e68946635a8cc536a11e))
## [0.12.1](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.12.0...chrome-devtools-mcp-v0.12.1) (2025-12-12)
### 🛠️ Fixes
* catch unexpected error in event handlers ([#672](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/672)) ([ca0f560](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/ca0f5607f18bf04134e85ea1f61d1a839a47827b))
* log unhandledRejection instead of crashing ([#673](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/673)) ([f59b4a2](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/f59b4a2ed8b09e1d64916552ee6db49b978fe9a7))
* make bringToFront optional in select_page ([#668](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/668)) ([ceae17b](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/ceae17be26b0a812f1b013dcebaed9beb510e7b3))
* Update installation badges in README.md for VS Code ([#660](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/660)) ([61ede1c](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/61ede1c0531ea8b028d9a5cbb28fcdc00cc521e0))
### 📄 Documentation
* Add debug instructions ([#670](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/670)) ([a8aae66](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/a8aae6652e205b87ac2efa29217b7cbd18dcbbe6))
* explain new auto connection feature ([#664](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/664)) ([a537a8c](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/a537a8c8cef4f2a3493e9f7de47345d565b6fc9f))
## [0.12.0](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.11.0...chrome-devtools-mcp-v0.12.0) (2025-12-09)
### 🎉 Features
* support --auto-connect to a Chrome instance ([#651](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/651)) ([6ab6d85](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/6ab6d85d50226cf12a62563430f552e783f428b2))
* support --user-data-dir with --auto-connect ([#654](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/654)) ([e3c59bc](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/e3c59bcd9c284f3be99cc15e22116b887f04cdab))
### 🛠️ Fixes
* map channel for resolveDefaultUserDataDir ([#658](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/658)) ([6f59b39](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/6f59b3975abda50536f8b890f3245662b22e3657))
### 📄 Documentation
* Add AX design principles ([#643](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/643)) ([90ed192](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/90ed192c558d36faf9f6300be1c1fd5abd464d8a))
* improve autoConnect docs ([#653](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/653)) ([09111cc](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/09111cc16464bed27cd623f3b345d3885db12521))
## [0.11.0](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.10.2...chrome-devtools-mcp-v0.11.0) (2025-12-03)
### 🎉 Features
* **emulation:** add geolocation emulation tool ([#634](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/634)) ([3991e4c](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/3991e4c2a9c28bf8180f9057ce804d978c39529d))
* integrate DevTools issues into the console tools ([#636](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/636)) ([d892145](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/d8921453c77a1c0815059fb9bc72c0cd769a7bd4))
* support --user-data-dir ([#622](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/622)) ([fcaf553](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/fcaf55354c2afbdbae538e27eb4b6d02f2e87985))
### 🛠️ Fixes
* handle error messages that are not instanceof Error ([#618](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/618)) ([a67528a](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/a67528a046746c7131d5265f6c94613d607aaf90))
* handle the case when all pages are filtered out ([#616](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/616)) ([bff5c65](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/bff5c6569003fdbc207448d89a8be6a9a8172ca0))
* ignore hash parts of URLs when finding DevTools ([#608](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/608)) ([52533d0](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/52533d0c695354b816807de253f0ec17099aa9d7))
* ignore quality for png ([#589](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/589)) ([2eaf268](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/2eaf2689c3360f88479f4cdab8ddde5899378e33))
* include a note about selected elements missing from the snapshot ([#593](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/593)) ([80e77fd](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/80e77fd9a35a3dc5c451cc5b070b8baa574c686c))
* prevent dropping license notices on some files when publishing ([#604](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/604)) ([94752ff](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/94752ffade847671ebfd15e4013a5b5cdf8377df))
* rename page content to latest page snapshot ([#579](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/579)) ([9cb99ad](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/9cb99ad3e65054f4ea12a39358719f6630a020d0))
* **wait_for:** respect the provided timeout ([#630](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/630)) ([6b0984a](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/6b0984aa7dca6f651afd1fed56246893810781c9)), closes [#624](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/624)
### 📄 Documentation
* add Antigravity config ([#580](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/580)) ([6f9182f](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/6f9182f4b60f1f6ff8d321fec35545712828686e))
* add Qoder CLI to the MCP client configuration section in the README. ([#552](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/552)) ([1a16f15](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/1a16f15546e227a0708f89d3084c98d4916db53f))
* add VS Code install badges ([#532](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/532)) ([cc4d065](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/cc4d065dd6081a2a9fbcc3d8ebb1536e5426116e))
* clarify browser-url parameter in README ([#613](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/613)) ([05cf8cb](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/05cf8cb8a6c68506282075bc1522c81f0b84f07b))
* Fix Antigravity docs ([#605](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/605)) ([fae2608](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/fae260888748ece77b368a13ee913153caffcef7))
* update readme to explain agy's browser integration ([#612](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/612)) ([2d89865](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/2d89865ddbff6e77332c6157f687dcc2f0bef892))
### ♻️ Chores
* avoid throwing in resolveCdpElementId ([#606](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/606)) ([eb261fd](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/eb261fd48b6753db246d24b77e1f477dc7a9455e))
## [0.10.2](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.10.1...chrome-devtools-mcp-v0.10.2) (2025-11-19)
### 📄 Documentation
* add Factory CLI configuration to MCP clients ([#523](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/523)) ([016e2fd](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/016e2fd6ee57447103f7385285dd503b5576a860))
### ♻️ Chores
* clear issue aggregator on page navigation ([#565](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/565)) ([c3784d1](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/c3784d1990a926f651951e4eef05520c5c448964))
* disable issues in list_console_messages for now ([#575](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/575)) ([08e9a9f](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/08e9a9f42e6ff1a92c60b3e958b0817c7b785afc))
* simplify issue management ([#564](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/564)) ([3b016f1](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/3b016f1a814b1a69750813548b3f35e79bfb6fef))
## [0.10.1](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.10.0...chrome-devtools-mcp-v0.10.1) (2025-11-07)
### 🛠️ Fixes
* avoid no page selected errors ([#537](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/537)) ([4724bbb](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/4724bbba9327fc162cd1f0372e608f6ebefc59cc))
## [0.10.0](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.9.0...chrome-devtools-mcp-v0.10.0) (2025-11-05)
### 🎉 Features
* add a press_key tool ([#458](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/458)) ([b427392](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/b4273923928704e718e0a0f8b5cc86758416e994))
* add insightSetId to performance_analyze_insight ([#518](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/518)) ([36504d2](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/36504d29caf637b2d7bf231204c0478b54220c83))
* an option to ignore cache on reload ([#485](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/485)) ([8e56307](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/8e56307d623fe3651262287b30544ed70426b0b8))
* detect network requests inspected in DevTools UI ([#477](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/477)) ([796aed7](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/796aed72b7126ed4332888ffbc06d6cb678265ef))
* fetch DOM node selected in the DevTools Elements panel ([#486](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/486)) ([4a83574](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/4a83574961d8d6b974037db56fc8bdbbb91f79b6))
* support page reload ([#462](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/462)) ([d177087](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/d17708798194486b2571092aa67838085da7231e))
* support saving snapshots to file ([#463](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/463)) ([b0ce08a](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/b0ce08ae2ce422813fef3f28c18f2cb6c976d9fc))
### 🛠️ Fixes
* Augment fix to prevent stray OGS frames in NTP from causing hangs. ([#521](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/521)) ([d90abd4](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/d90abd4e9e534417622d7f4676e9c3dbeb39ea8d))
* improve get_network_request description ([#500](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/500)) ([2f448e8](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/2f448e84ea8d3a44687c74b3577edf882ef2c19f))
* work around NTP iframes causing hangs ([#504](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/504)) ([cca5ff4](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/cca5ff471c2d2c663e63ade1e2ea58f9a7f5a2cd))
### 📄 Documentation
* add Windsurf to the editor config README ([#493](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/493)) ([63a5d82](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/63a5d824c2d914c9007e2b837fa292f5ba74ceed))
* fix typos in README.md exlcude -> exclude ([#513](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/513)) ([8854a34](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/8854a3400c3a6b84c761bf8ed82769fc2dec7366))
* remove unnecessary replace ([#475](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/475)) ([40e1753](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/40e1753d2e874bb22005dbebdb551da304a80033))
### ♻️ Chores
* connect to DevTools targets by default ([#466](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/466)) ([a41e440](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/a41e4407996b8090f8cccc85f6c4696006fc31ec))
* detect DevTools page for each page ([#467](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/467)) ([1560ff2](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/1560ff23cad28ab63c1cf9fb1b961db886bc4a3e))
* merge emulate tools into one ([#494](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/494)) ([c06f452](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/c06f4522ee8f762b59c60c2fd23a0deaaa544766))
## [0.9.0](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.8.1...chrome-devtools-mcp-v0.9.0) (2025-10-22)
### 🎉 Features
* add claude marketplace and plugin json ([#396](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/396)) ([0498611](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/0498611429f769c6ccae365674003d2bd538c292))
* add filters and pagination to the console messages tool ([#387](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/387)) ([15d942c](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/15d942c4f3335b35f1cba8e8634651688323663d))
* add WebSocket endpoint and custom headers support ([#404](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/404)) ([41d6a10](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/41d6a107baee0d14a1c14573f958d44198de23aa))
* allow configuring tool categories ([#454](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/454)) ([0fe2b8a](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/0fe2b8a2b4d64b9da5f7d1adccc5425fd7cbec34))
* expose previous navigations to the MCP ([#419](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/419)) ([165cf9c](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/165cf9c70b7f91dc116558547a870281f29da710))
* support previous navigation for Console messages ([#452](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/452)) ([6f24362](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/6f243620391f0c608f51d464257cf3222d653e9e))
* support stable id for network requests ([#375](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/375)) ([f4d7b49](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/f4d7b49bb112b4336bef0d90059485f41f71e4f1))
* support verbose snapshots ([#388](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/388)) ([d47aaa9](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/d47aaa96ff990c49dd07a481ea1924f85881eafa))
* tool to get a verbose single console message ([#435](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/435)) ([9205593](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/92055933dc44e5d200dda2ee4ae0e365b24281bb))
* use stable id for network request querying ([#382](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/382)) ([579819b](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/579819b5e76f7a34c7c5c0877ac1e5e284beb328))
### 🛠️ Fixes
* allow evaluating in Frames ([#443](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/443)) ([053f1f8](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/053f1f830d051ec415f4b00e645f5a1aff8554a1))
* better wording for evaluate_script ([#392](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/392)) ([2313fda](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/2313fdacad72a1bc5c4d8f1cbdd80fd64ba91771))
* indicate when request and response bodies are not available ([#446](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/446)) ([7d47d6b](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/7d47d6b2f40bf08def29de3ca37b1a4a28ce6777))
* pageerror for non-error types ([#442](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/442)) ([b6b42ec](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/b6b42ecb998dd4f8fbf4a8e7a49f461333a41103))
* retrieve data correctly with fewer than 3 navigations ([#451](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/451)) ([4c65f59](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/4c65f59cf9f62662cf903fbbd19b67a8828d674a))
### 📄 Documentation
* add instructions for Qoder ([#386](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/386)) ([d8df784](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/d8df784127afd590eb02e0060378465ae115a7a4))
* add VM-to-host remote debugging workaround ([#399](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/399)) ([9f9dab0](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/9f9dab0787f19c5730b65daf148c382fb2d9e365))
* Update Copilot CLI instructions ([#423](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/423)) ([c7733a8](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/c7733a818050e50830c9a8e3d62bb80892cf9121))
### ♻️ Chores
* bundle all dependencies together ([#450](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/450)) ([914b980](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/914b980113353fd41b301da397aa45975090487a))
* bundle modelcontextprotocol-sdk ([#409](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/409)) ([6c8432b](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/6c8432b6b69d5d56d0dee01968882492033f2dc1))
* bundle puppeteer-core ([#417](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/417)) ([b443033](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/b443033000e46a992ea7fa071af0f9ec304b9ea7))
* bundle zod together with modelcontextprotocol/sdk ([#414](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/414)) ([800e7e8](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/800e7e836433f3f1b2bfafa12ed35a991404d270))
* cleanup data fetching ([#441](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/441)) ([5c871c3](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/5c871c3bd98127996011f269faddd8d8e7163917))
* dispose listeners on page destroyed ([#318](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/318)) ([76d5e94](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/76d5e9416d833299561242ac45c0ce7813e61dbe))
* extract common paginate type ([#415](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/415)) ([29fd602](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/29fd60216ca1394c46a266c6f853f8d65418e861))
* store the last 3 navigations in PageCollector ([#411](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/411)) ([b873822](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/b8738221d8cf8322d5f968ee829f03dc83238a05))
* use different format for reqid ([#380](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/380)) ([78bf66a](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/78bf66a7b1eefc93768f39d6d38fd141104fe812))
## [0.8.1](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.8.0...chrome-devtools-mcp-v0.8.1) (2025-10-13)
### Bug Fixes
* add an option value to the snapshot ([#362](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/362)) ([207137e](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/207137edd6d8af2f49277d88a30d8afa51671631))
* improve navigate_page_history error messages ([#321](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/321)) ([0624029](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/0624029e0f8735345d202d29dde446b8869d9561))
* return the default dialog value correctly ([#366](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/366)) ([f08f808](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/f08f8080d0be1074a48e5c2ab0a6533f01f65928))
* update puppeteer to 24.24.1 ([#370](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/370)) ([477eef4](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/477eef481a2e6241121ee4aaaed34e8342a8b347))
## [0.8.0](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.7.1...chrome-devtools-mcp-v0.8.0) (2025-10-10)
### Features
* support passing args to Chrome ([#338](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/338)) ([e1b5363](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/e1b536365363e1e1a3aa7661dd84290c794510ad))
## [0.7.1](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.7.0...chrome-devtools-mcp-v0.7.1) (2025-10-10)
### Bug Fixes
* document that console and requests are since the last nav ([#335](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/335)) ([9ad7cbb](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/9ad7cbb2de3d285e46e5f3e7c098b0a7535c7e7a))
## [0.7.0](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.6.1...chrome-devtools-mcp-v0.7.0) (2025-10-10)
### Features
* Add offline network emulation support to emulate_network command ([#326](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/326)) ([139ce60](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/139ce607814bf25ba541a7264ce96a04b2fac871))
* add request and response body ([#267](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/267)) ([dd3c143](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/dd3c14336ee44d057d06231a5bfd5c5bcf661029))
### Bug Fixes
* ordering of information in performance trace summary ([#334](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/334)) ([2d4484a](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/2d4484a123968754b4840d112b9c1ca59fb29997))
* publishing to MCP registry ([#313](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/313)) ([1faec78](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/1faec78f84569a03f63585fb84df35992bcfe81a))
* use default ProtocolTimeout ([#315](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/315)) ([a525f19](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/a525f199458afb266db4540bf0fa8007323f3301))
## [0.6.1](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.6.0...chrome-devtools-mcp-v0.6.1) (2025-10-07)
### Bug Fixes
* change default screen size in headless ([#299](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/299)) ([357db65](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/357db65d18f87b1299a0f6212b7ec982ef187171))
* **cli:** tolerate empty browser URLs ([#298](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/298)) ([098a904](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/098a904b363f3ad81595ed58c25d34dd7d82bcd8))
* guard performance_stop_trace when tracing inactive ([#295](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/295)) ([8200194](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/8200194c8037cc30b8ab815e5ee0d0b2b000bea6))
## [0.6.0](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.5.1...chrome-devtools-mcp-v0.6.0) (2025-10-01)
### Features
* **screenshot:** add WebP format support with quality parameter ([#220](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/220)) ([03e02a2](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/03e02a2d769fbfc0c98599444dfed5413d15ae6e))
* **screenshot:** adds ability to output screenshot to a specific pat… ([#172](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/172)) ([f030726](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/f03072698ddda8587ce23229d733405f88b7c89e))
* support --accept-insecure-certs CLI ([#231](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/231)) ([efb106d](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/efb106dc94af0057f88c89f810beb65114eeaa4b))
* support --proxy-server CLI ([#230](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/230)) ([dfacc75](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/dfacc75ee9f46137b5194e35fc604b89a00ff53f))
* support initial viewport in the CLI ([#229](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/229)) ([ef61a08](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/ef61a08707056c5078d268a83a2c95d10e224f31))
* support timeouts in wait_for and navigations ([#228](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/228)) ([36e64d5](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/36e64d5ae21e8bb244a18201a23a16932947e938))
### Bug Fixes
* **network:** show only selected request ([#236](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/236)) ([73f0aec](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/73f0aecd8a48b9d1ee354897fe14d785c80e863e))
* PageCollector subscribing multiple times ([#241](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/241)) ([0412878](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/0412878bf51ae46e48a171183bb38cfbbee1038a))
* snapshot does not capture Iframe content ([#217](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/217)) ([ce356f2](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/ce356f256545e805db74664797de5f42e7b92bed)), closes [#186](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/186)
## [0.5.1](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.5.0...chrome-devtools-mcp-v0.5.1) (2025-09-29)
### Bug Fixes
* update package.json engines to reflect node20 support ([#210](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/210)) ([b31e647](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/b31e64713e0524f28cbf760fad27b25829ec419d))
## [0.5.0](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.4.0...chrome-devtools-mcp-v0.5.0) (2025-09-29)
### Features
* **screenshot:** add JPEG quality parameter support ([#184](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/184)) ([139cfd1](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/139cfd135cdb07573fe87d824631fcdb6153186e))
### Bug Fixes
* do not error if the dialog was already handled ([#208](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/208)) ([d9f77f8](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/d9f77f85098ffe851308c5de05effb03ac21237b))
* reference to handle_dialog tool ([#209](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/209)) ([205eef5](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/205eef5cdff19ccb7ddbd113bb1450cb87e8f398))
* support node20 ([#52](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/52)) ([13613b4](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/13613b4a33ab7cf2d4fb1f4849bfa6b82f546945))
* update tool reference in an error ([#205](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/205)) ([7765bb3](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/7765bb381ad9d01219547faf879a74978188754a))
## [0.4.0](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.3.0...chrome-devtools-mcp-v0.4.0) (2025-09-26)
### Features
* add network request filtering by resource type ([#162](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/162)) ([59d81a3](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/59d81a33258a199a3f993c9e02a415f62ef05ce4))
### Bug Fixes
* add core web vitals to performance_start_trace description ([#168](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/168)) ([6cfc977](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/6cfc9774f4ec7944c70842999506b2bc2018a667))
* add data format information to trace summary ([#166](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/166)) ([869dd42](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/869dd4273e42309c1bb57d44e0e5a6a9506ffad7))
* expose --debug-file argument ([#164](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/164)) ([22ec7ee](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/22ec7ee45cc04892000cf6dc32f3fe58d33855c1))
* typo in the disclaimers ([#156](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/156)) ([90f686e](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/90f686e5df3d880c35ec566c837ee5a98824be28))
## [0.3.0](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.2.7...chrome-devtools-mcp-v0.3.0) (2025-09-25)
### Features
* Add pagination list_network_requests ([#145](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/145)) ([4c909bb](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/4c909bb8d7c4a420cb8e3219ec98abf28f5cc664))
### Bug Fixes
* avoid reporting page close errors as errors ([#127](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/127)) ([44cfc8f](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/44cfc8f945edf9370efe26247f322a59a4a4a7be))
* clarify the node version message ([#135](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/135)) ([0cc907a](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/0cc907a9ad79289a6785e9690c3c6940f0a5de52))
* do not set channel if executablePath is provided ([#150](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/150)) ([03b59f0](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/03b59f0bca024173ad45d7a617994e919d9cbbad))
* **performance:** ImageDelivery insight errors ([#144](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/144)) ([d64ba0d](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/d64ba0d9027540eb707381e2577ae3c1fe014346))
* roll latest DevTools to handle Insight errors ([#149](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/149)) ([b2e1e39](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/b2e1e3944c7fa170584ce36c7b8923b0e6d6c6cb))
## [0.2.7](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.2.6...chrome-devtools-mcp-v0.2.7) (2025-09-24)
### Bug Fixes
* validate and report incompatible Node versions ([#113](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/113)) ([adfcecf](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/adfcecf9871938b1ad5d1460e0050b849fb2aa49))
## [0.2.6](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.2.5...chrome-devtools-mcp-v0.2.6) (2025-09-24)
### Bug Fixes
* manually bump server.json versions based on package.json ([#105](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/105)) ([cae1cf1](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/cae1cf13d5a97add3b96f20c425f720a1ceabf94))
## [0.2.5](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.2.4...chrome-devtools-mcp-v0.2.5) (2025-09-24)
### Bug Fixes
* add mcpName to package.json ([#103](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/103)) ([bd0351f](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/bd0351fd36ae35e41e613f0d15df40aeca17ba94))
## [0.2.4](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.2.3...chrome-devtools-mcp-v0.2.4) (2025-09-24)
### Bug Fixes
* forbid closing the last page ([#90](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/90)) ([0ca2434](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/0ca2434a29eb4bc6e570a4ebe21a135d85f4c0f3))
## [0.2.3](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.2.2...chrome-devtools-mcp-v0.2.3) (2025-09-24)
### Bug Fixes
* add a message indicating that no console messages exist ([#91](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/91)) ([1a4ba4d](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/1a4ba4d3e05f51a85747816f8638f31230881437))
* clean up pending promises on action errors ([#84](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/84)) ([4e7001a](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/4e7001ac375ec51f55b29e9faf68aff0dd09fa0f))
## [0.2.2](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.2.1...chrome-devtools-mcp-v0.2.2) (2025-09-23)
### Bug Fixes
* cli version being reported as unknown ([#74](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/74)) ([d6bab91](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/d6bab912df55dc2e96a8d7893d1906f1fc608d0a))
* remove unnecessary waiting for navigation ([#83](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/83)) ([924c042](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/924c042492222a555074063841ce765342e3b5b9))
* rework performance parsing & error handling ([#75](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/75)) ([e8fb30c](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/e8fb30c1bfdc2b4ea8c2daf74b24aa82210f99be))
## [0.2.1](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.2.0...chrome-devtools-mcp-v0.2.1) (2025-09-23)
### Bug Fixes
* add 'on the selected page' to performance tools ([#69](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/69)) ([b877f7a](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/b877f7a3053d0cdf2aad1fefc26cf7b913eb95ce))
* **emulation:** correctly report info for selected page ([#63](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/63)) ([1e8662f](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/1e8662f06860aecb5c01ed4ff1515ceb9dac26e4))
* expose timeout when Emulation is enabled ([#73](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/73)) ([0208bfd](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/0208bfdcf6924953879408c18f4c20da544bf4ff))
* fix browserUrl not working ([#53](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/53)) ([a6923b8](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/a6923b8d9397d12ee0f9fe67dd62b10088ec6e87))
* increase timeouts in case of Emulation ([#71](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/71)) ([c509c64](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/c509c64576e1be1ddc283653004ef08a117907a2))
* **windows:** work around Chrome not reporting reasons for crash ([#64](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/64)) ([d545741](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/d5457412a4a76726547190fb3a46bb78c9d6645c))
## [0.2.0](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.1.0...chrome-devtools-mcp-v0.2.0) (2025-09-17)
### Features
* add performance_analyze_insight tool. ([#42](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/42)) ([21e175b](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/21e175b862c624d7a2d07802141187edf2d2e489))
* support script evaluate arguments ([#40](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/40)) ([c663f4d](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/c663f4d7f9c0b868e8b4750f6441525939bfe920))
* use Performance Trace Formatter in trace output ([#36](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/36)) ([0cb6147](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/0cb6147b870e17bc3a624e9c6396d963a3e16b44))
* validate uids ([#37](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/37)) ([014a8bc](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/014a8bc52ecc58080cedeb8023d44f4a55055a05))
### Bug Fixes
* change profile folder name to browser-profile ([#39](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/39)) ([36115d7](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/36115d757abbae0502ffee814f55368d2ca59b9e))
* refresh context based on the browser instance ([#44](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/44)) ([93f4579](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/93f4579dd9aca3beef2bd9f2930ddfcc4069c0e3))
* update puppeteer to fix a11y snapshot issues ([#43](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/43)) ([b58f787](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/b58f787234a34d5fcb01b336f5fb14e1c55ecdd5))
## [0.1.0](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.0.2...chrome-devtools-mcp-v0.1.0) (2025-09-16)
### Features
* improve tools with awaiting common events ([#10](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/10)) ([dba8b3c](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/dba8b3c5fad0d1bca26aaf172751c51188799927))
* initial version ([31a0bdc](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/31a0bdce266a33eaca9a7daae4611abb78ff5a25))
### Bug Fixes
* define tracing categories ([#21](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/21)) ([c939456](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/c93945657cc96ac7ba213730a750c16e9ab87526))
* detect multiple instances and throw ([#12](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/12)) ([732267d](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/732267db5fea0048ed1fcc530bcdd074df4126be))
* make sure tool calls are processed sequentially ([#22](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/22)) ([a76b23d](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/a76b23dccf074a13304b0341178665465a2c3399))
================================================
FILE: CONTRIBUTING.md
================================================
# How to contribute
We'd love to accept your patches and contributions to this project.
## Before you begin
### Sign our Contributor License Agreement
Contributions to this project must be accompanied by a
[Contributor License Agreement](https://cla.developers.google.com/about) (CLA).
You (or your employer) retain the copyright to your contribution; this simply
gives us permission to use and redistribute your contributions as part of the
project.
If you or your current employer have already signed the Google CLA (even if it
was for a different project), you probably don't need to do it again.
Visit <https://cla.developers.google.com/> to see your current agreements or to
sign a new one.
### Review our community guidelines
This project follows
[Google's Open Source Community Guidelines](https://opensource.google/conduct/).
## Development process
### Code reviews
All submissions, including submissions by project members, require review. We
use GitHub pull requests for this purpose. Consult
[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
information on using pull requests.
### Conventional commits
Please follow [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/)
for PR and commit titles.
### Feature release checklist
Use `chore:` for commits containing incomplete features that are not available
to users yet. Once the feature is ready to be released, create a PR with a
`feat:` prefix that enables the feature. The following criteria need to be
completed:
- Documentation for the feature is up to date. For example, README.md and tools
reference are updated.
- The feature can be used with Chrome stable or version restrictions are
documented otherwise.
- Corresponding skills are updated or new skills are added if needed.
- The feature fulfills the use case by its own or in conjunction with existing
features (we want to avoid features that offer some tools but cannot be used
successfully to debug things).
### Release process
Releasing `chrome-devtools-mcp` is automated by GitHub Actions. To release a new
version, [search for a PR titled `chore(main): release chrome-devtools-mcp`](https://github.com/ChromeDevTools/chrome-devtools-mcp/pulls?q=is%3Apr+is%3Aopen+%22chore%28main%29%3A+release+chrome-devtools-mcp%22)
and review, test, and land it. The release PR is automatically opened if there
are any changes on the main branch that show up in the changelog.
## Installation
Check that you are using node version specified in .nvmrc, then run following commands:
```sh
git clone https://github.com/ChromeDevTools/chrome-devtools-mcp.git
cd chrome-devtools-mcp
npm ci
npm run build
```
### Testing with @modelcontextprotocol/inspector
```sh
npx @modelcontextprotocol/inspector node /build/src/bin/chrome-devtools-mcp.js
```
### Testing with an MCP client
Add the MCP server to your client's config.
```json
{
"mcpServers": {
"chrome-devtools": {
"command": "node",
"args": ["/path-to/build/src/bin/chrome-devtools-mcp.js"]
}
}
}
```
#### Using with VS Code SSH
When running the `@modelcontextprotocol/inspector` it spawns 2 services - one on port `6274` and one on `6277`.
Usually VS Code automatically detects and forwards `6274` but fails to detect `6277` so you need to manually forward it.
### Debugging
To write debug logs to `log.txt` in the working directory, run with the following commands:
```sh
npx @modelcontextprotocol/inspector node /build/src/bin/chrome-devtools-mcp.js --log-file=/your/desired/path/log.txt
```
You can use the `DEBUG` environment variable as usual to control categories that are logged.
### Updating documentation
When adding a new tool or updating a tool name or description, make sure to run `npm run gen` to generate the tool reference documentation.
### Contributing to Evals
We use Gemini to evaluate the MCP server tools in `scripts/eval_scenarios`.
Each scenario is a TypeScript file that exports a `scenario` object implementing `TestScenario`.
- **prompt**: The prompt to send to the model.
- **maxTurns**: Maximum number of conversation turns.
- **expectations**: A function that verifies the tool calls made by the model.
- **htmlRoute** (Optional): Serve custom HTML content for the test at a specific path.
We look to test that the tools are used correctly without too rigid assertions. Avoid asserting exact argument values if they can vary (e.g., natural language reasoning), but ensure the core parameters (like URLs or selectors) were correct.
Example:
```ts
import {TestScenario} from '../eval_gemini.js';
export const scenario: TestScenario = {
prompt: 'Navigate to example.com',
maxTurns: 2,
expectations: calls => {
// Check that at least one call was 'browse_page'
const navigation = calls.find(c => c.name === 'browse_page');
if (!navigation) throw new Error('Model did not browse the page');
// Verify essential args
if (navigation.args.url !== 'http://example.com') {
throw new Error(`Wrong URL: ${navigation.args.url}`);
}
},
};
```
## Restrictions on JSON schema
- no .nullable(), no .object() types.
- represent complex object as a short formatted string.
TODO: implement eslint for schema https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1076
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
# Chrome DevTools MCP
[](https://npmjs.org/package/chrome-devtools-mcp)
`chrome-devtools-mcp` lets your coding agent (such as Gemini, Claude, Cursor or Copilot)
control and inspect a live Chrome browser. It acts as a Model-Context-Protocol
(MCP) server, giving your AI coding assistant access to the full power of
Chrome DevTools for reliable automation, in-depth debugging, and performance analysis.
## [Tool reference](./docs/tool-reference.md) | [Changelog](./CHANGELOG.md) | [Contributing](./CONTRIBUTING.md) | [Troubleshooting](./docs/troubleshooting.md) | [Design Principles](./docs/design-principles.md)
## Key features
- **Get performance insights**: Uses [Chrome
DevTools](https://github.com/ChromeDevTools/devtools-frontend) to record
traces and extract actionable performance insights.
- **Advanced browser debugging**: Analyze network requests, take screenshots and
check browser console messages (with source-mapped stack traces).
- **Reliable automation**. Uses
[puppeteer](https://github.com/puppeteer/puppeteer) to automate actions in
Chrome and automatically wait for action results.
## Disclaimers
`chrome-devtools-mcp` exposes content of the browser instance to the MCP clients
allowing them to inspect, debug, and modify any data in the browser or DevTools.
Avoid sharing sensitive or personal information that you don't want to share with
MCP clients.
Performance tools may send trace URLs to the Google CrUX API to fetch real-user
experience data. This helps provide a holistic performance picture by
presenting field data alongside lab data. This data is collected by the [Chrome
User Experience Report (CrUX)](https://developer.chrome.com/docs/crux). To disable
this, run with the `--no-performance-crux` flag.
## **Usage statistics**
Google collects usage statistics (such as tool invocation success rates, latency, and environment information) to improve the reliability and performance of Chrome DevTools MCP.
Data collection is **enabled by default**. You can opt-out by passing the `--no-usage-statistics` flag when starting the server:
```json
"args": ["-y", "chrome-devtools-mcp@latest", "--no-usage-statistics"]
```
Google handles this data in accordance with the [Google Privacy Policy](https://policies.google.com/privacy).
Google's collection of usage statistics for Chrome DevTools MCP is independent from the Chrome browser's usage statistics. Opting out of Chrome metrics does not automatically opt you out of this tool, and vice-versa.
Collection is disabled if CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS or CI env variables are set.
## Requirements
- [Node.js](https://nodejs.org/) v20.19 or a newer [latest maintenance LTS](https://github.com/nodejs/Release#release-schedule) version.
- [Chrome](https://www.google.com/chrome/) current stable version or newer.
- [npm](https://www.npmjs.com/).
## Getting started
Add the following config to your MCP client:
```json
{
"mcpServers": {
"chrome-devtools": {
"command": "npx",
"args": ["-y", "chrome-devtools-mcp@latest"]
}
}
}
```
> [!NOTE]
> Using `chrome-devtools-mcp@latest` ensures that your MCP client will always use the latest version of the Chrome DevTools MCP server.
If you are interested in doing only basic browser tasks, use the `--slim` mode:
```json
{
"mcpServers": {
"chrome-devtools": {
"command": "npx",
"args": ["-y", "chrome-devtools-mcp@latest", "--slim", "--headless"]
}
}
}
```
See [Slim tool reference](./docs/slim-tool-reference.md).
### MCP Client configuration
<details>
<summary>Amp</summary>
Follow https://ampcode.com/manual#mcp and use the config provided above. You can also install the Chrome DevTools MCP server using the CLI:
```bash
amp mcp add chrome-devtools -- npx chrome-devtools-mcp@latest
```
</details>
<details>
<summary>Antigravity</summary>
To use the Chrome DevTools MCP server follow the instructions from <a href="https://antigravity.google/docs/mcp">Antigravity's docs</a> to install a custom MCP server. Add the following config to the MCP servers config:
```bash
{
"mcpServers": {
"chrome-devtools": {
"command": "npx",
"args": [
"chrome-devtools-mcp@latest",
"--browser-url=http://127.0.0.1:9222",
"-y"
]
}
}
}
```
This will make the Chrome DevTools MCP server automatically connect to the browser that Antigravity is using. If you are not using port 9222, make sure to adjust accordingly.
Chrome DevTools MCP will not start the browser instance automatically using this approach because the Chrome DevTools MCP server connects to Antigravity's built-in browser. If the browser is not already running, you have to start it first by clicking the Chrome icon at the top right corner.
</details>
<details>
<summary>Claude Code</summary>
**Install via CLI (MCP only)**
Use the Claude Code CLI to add the Chrome DevTools MCP server (<a href="https://code.claude.com/docs/en/mcp">guide</a>):
```bash
claude mcp add chrome-devtools --scope user npx chrome-devtools-mcp@latest
```
**Install as a Plugin (MCP + Skills)**
> [!NOTE]
> If you already had Chrome DevTools MCP installed previously for Claude Code, make sure to remove it first from your installation and configuration files.
To install Chrome DevTools MCP with skills, add the marketplace registry in Claude Code:
```sh
/plugin marketplace add ChromeDevTools/chrome-devtools-mcp
```
Then, install the plugin:
```sh
/plugin install chrome-devtools-mcp
```
Restart Claude Code to have the MCP server and skills load (check with `/skills`).
> [!TIP]
> If the plugin installation fails with a `Failed to clone repository` error (e.g., HTTPS connectivity issues behind a corporate firewall), see the [troubleshooting guide](./docs/troubleshooting.md#claude-code-plugin-installation-fails-with-failed-to-clone-repository) for workarounds, or use the CLI installation method above instead.
</details>
<details>
<summary>Cline</summary>
Follow https://docs.cline.bot/mcp/configuring-mcp-servers and use the config provided above.
</details>
<details>
<summary>Codex</summary>
Follow the <a href="https://developers.openai.com/codex/mcp/#configure-with-the-cli">configure MCP guide</a>
using the standard config from above. You can also install the Chrome DevTools MCP server using the Codex CLI:
```bash
codex mcp add chrome-devtools -- npx chrome-devtools-mcp@latest
```
**On Windows 11**
Configure the Chrome install location and increase the startup timeout by updating `.codex/config.toml` and adding the following `env` and `startup_timeout_ms` parameters:
```
[mcp_servers.chrome-devtools]
command = "cmd"
args = [
"/c",
"npx",
"-y",
"chrome-devtools-mcp@latest",
]
env = { SystemRoot="C:\\Windows", PROGRAMFILES="C:\\Program Files" }
startup_timeout_ms = 20_000
```
</details>
<details>
<summary>Copilot CLI</summary>
Start Copilot CLI:
```
copilot
```
Start the dialog to add a new MCP server by running:
```
/mcp add
```
Configure the following fields and press `CTRL+S` to save the configuration:
- **Server name:** `chrome-devtools`
- **Server Type:** `[1] Local`
- **Command:** `npx -y chrome-devtools-mcp@latest`
</details>
<details>
<summary>Copilot / VS Code</summary>
**Click the button to install:**
[<img src="https://img.shields.io/badge/VS_Code-VS_Code?style=flat-square&label=Install%20Server&color=0098FF" alt="Install in VS Code">](https://vscode.dev/redirect/mcp/install?name=io.github.ChromeDevTools%2Fchrome-devtools-mcp&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22chrome-devtools-mcp%22%5D%2C%22env%22%3A%7B%7D%7D)
[<img src="https://img.shields.io/badge/VS_Code_Insiders-VS_Code_Insiders?style=flat-square&label=Install%20Server&color=24bfa5" alt="Install in VS Code Insiders">](https://insiders.vscode.dev/redirect?url=vscode-insiders%3Amcp%2Finstall%3F%257B%2522name%2522%253A%2522io.github.ChromeDevTools%252Fchrome-devtools-mcp%2522%252C%2522config%2522%253A%257B%2522command%2522%253A%2522npx%2522%252C%2522args%2522%253A%255B%2522-y%2522%252C%2522chrome-devtools-mcp%2522%255D%252C%2522env%2522%253A%257B%257D%257D%257D)
**Or install manually:**
Follow the MCP install <a href="https://code.visualstudio.com/docs/copilot/chat/mcp-servers#_add-an-mcp-server">guide</a>,
with the standard config from above. You can also install the Chrome DevTools MCP server using the VS Code CLI:
For macOS and Linux:
```bash
code --add-mcp '{"name":"io.github.ChromeDevTools/chrome-devtools-mcp","command":"npx","args":["-y","chrome-devtools-mcp"],"env":{}}'
```
For Windows (PowerShell):
```powershell
code --add-mcp '{"""name""":"""io.github.ChromeDevTools/chrome-devtools-mcp""","""command""":"""npx""","""args""":["""-y""","""chrome-devtools-mcp"""]}'
```
</details>
<details>
<summary>Cursor</summary>
**Click the button to install:**
[<img src="https://cursor.com/deeplink/mcp-install-dark.svg" alt="Install in Cursor">](https://cursor.com/en/install-mcp?name=chrome-devtools&config=eyJjb21tYW5kIjoibnB4IC15IGNocm9tZS1kZXZ0b29scy1tY3BAbGF0ZXN0In0%3D)
**Or install manually:**
Go to `Cursor Settings` -> `MCP` -> `New MCP Server`. Use the config provided above.
</details>
<details>
<summary>Factory CLI</summary>
Use the Factory CLI to add the Chrome DevTools MCP server (<a href="https://docs.factory.ai/cli/configuration/mcp">guide</a>):
```bash
droid mcp add chrome-devtools "npx -y chrome-devtools-mcp@latest"
```
</details>
<details>
<summary>Gemini CLI</summary>
Install the Chrome DevTools MCP server using the Gemini CLI.
**Project wide:**
```bash
# Either MCP only:
gemini mcp add chrome-devtools npx chrome-devtools-mcp@latest
# Or as a Gemini extension (MCP+Skills):
gemini extensions install --auto-update https://github.com/ChromeDevTools/chrome-devtools-mcp
```
**Globally:**
```bash
gemini mcp add -s user chrome-devtools npx chrome-devtools-mcp@latest
```
Alternatively, follow the <a href="https://github.com/google-gemini/gemini-cli/blob/main/docs/tools/mcp-server.md#how-to-set-up-your-mcp-server">MCP guide</a> and use the standard config from above.
</details>
<details>
<summary>Gemini Code Assist</summary>
Follow the <a href="https://cloud.google.com/gemini/docs/codeassist/use-agentic-chat-pair-programmer#configure-mcp-servers">configure MCP guide</a>
using the standard config from above.
</details>
<details>
<summary>JetBrains AI Assistant & Junie</summary>
Go to `Settings | Tools | AI Assistant | Model Context Protocol (MCP)` -> `Add`. Use the config provided above.
The same way chrome-devtools-mcp can be configured for JetBrains Junie in `Settings | Tools | Junie | MCP Settings` -> `Add`. Use the config provided above.
</details>
<details>
<summary>Kiro</summary>
In **Kiro Settings**, go to `Configure MCP` > `Open Workspace or User MCP Config` > Use the configuration snippet provided above.
Or, from the IDE **Activity Bar** > `Kiro` > `MCP Servers` > `Click Open MCP Config`. Use the configuration snippet provided above.
</details>
<details>
<summary>Katalon Studio</summary>
The Chrome DevTools MCP server can be used with <a href="https://docs.katalon.com/katalon-studio/studioassist/mcp-servers/setting-up-chrome-devtools-mcp-server-for-studioassist">Katalon StudioAssist</a> via an MCP proxy.
**Step 1:** Install the MCP proxy by following the <a href="https://docs.katalon.com/katalon-studio/studioassist/mcp-servers/setting-up-mcp-proxy-for-stdio-mcp-servers">MCP proxy setup guide</a>.
**Step 2:** Start the Chrome DevTools MCP server with the proxy:
```bash
mcp-proxy --transport streamablehttp --port 8080 -- npx -y chrome-devtools-mcp@latest
```
**Note:** You may need to pick another port if 8080 is already in use.
**Step 3:** In Katalon Studio, add the server to StudioAssist with the following settings:
- **Connection URL:** `http://127.0.0.1:8080/mcp`
- **Transport type:** `HTTP`
Once connected, the Chrome DevTools MCP tools will be available in StudioAssist.
</details>
<details>
<summary>OpenCode</summary>
Add the following configuration to your `opencode.json` file. If you don't have one, create it at `~/.config/opencode/opencode.json` (<a href="https://opencode.ai/docs/mcp-servers">guide</a>):
```json
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"chrome-devtools": {
"type": "local",
"command": ["npx", "-y", "chrome-devtools-mcp@latest"]
}
}
}
```
</details>
<details>
<summary>Qoder</summary>
In **Qoder Settings**, go to `MCP Server` > `+ Add` > Use the configuration snippet provided above.
Alternatively, follow the <a href="https://docs.qoder.com/user-guide/chat/model-context-protocol">MCP guide</a> and use the standard config from above.
</details>
<details>
<summary>Qoder CLI</summary>
Install the Chrome DevTools MCP server using the Qoder CLI (<a href="https://docs.qoder.com/cli/using-cli#mcp-servers">guide</a>):
**Project wide:**
```bash
qodercli mcp add chrome-devtools -- npx chrome-devtools-mcp@latest
```
**Globally:**
```bash
qodercli mcp add -s user chrome-devtools -- npx chrome-devtools-mcp@latest
```
</details>
<details>
<summary>Visual Studio</summary>
**Click the button to install:**
[<img src="https://img.shields.io/badge/Visual_Studio-Install-C16FDE?logo=visualstudio&logoColor=white" alt="Install in Visual Studio">](https://vs-open.link/mcp-install?%7B%22name%22%3A%22chrome-devtools%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22chrome-devtools-mcp%40latest%22%5D%7D)
</details>
<details>
<summary>Warp</summary>
Go to `Settings | AI | Manage MCP Servers` -> `+ Add` to [add an MCP Server](https://docs.warp.dev/knowledge-and-collaboration/mcp#adding-an-mcp-server). Use the config provided above.
</details>
<details>
<summary>Windsurf</summary>
Follow the <a href="https://docs.windsurf.com/windsurf/cascade/mcp#mcp-config-json">configure MCP guide</a>
using the standard config from above.
</details>
### Your first prompt
Enter the following prompt in your MCP Client to check if everything is working:
```
Check the performance of https://developers.chrome.com
```
Your MCP client should open the browser and record a performance trace.
> [!NOTE]
> The MCP server will start the browser automatically once the MCP client uses a tool that requires a running browser instance. Connecting to the Chrome DevTools MCP server on its own will not automatically start the browser.
## Tools
If you run into any issues, checkout our [troubleshooting guide](./docs/troubleshooting.md).
<!-- BEGIN AUTO GENERATED TOOLS -->
- **Input automation** (9 tools)
- [`click`](docs/tool-reference.md#click)
- [`drag`](docs/tool-reference.md#drag)
- [`fill`](docs/tool-reference.md#fill)
- [`fill_form`](docs/tool-reference.md#fill_form)
- [`handle_dialog`](docs/tool-reference.md#handle_dialog)
- [`hover`](docs/tool-reference.md#hover)
- [`press_key`](docs/tool-reference.md#press_key)
- [`type_text`](docs/tool-reference.md#type_text)
- [`upload_file`](docs/tool-reference.md#upload_file)
- **Navigation automation** (6 tools)
- [`close_page`](docs/tool-reference.md#close_page)
- [`list_pages`](docs/tool-reference.md#list_pages)
- [`navigate_page`](docs/tool-reference.md#navigate_page)
- [`new_page`](docs/tool-reference.md#new_page)
- [`select_page`](docs/tool-reference.md#select_page)
- [`wait_for`](docs/tool-reference.md#wait_for)
- **Emulation** (2 tools)
- [`emulate`](docs/tool-reference.md#emulate)
- [`resize_page`](docs/tool-reference.md#resize_page)
- **Performance** (4 tools)
- [`performance_analyze_insight`](docs/tool-reference.md#performance_analyze_insight)
- [`performance_start_trace`](docs/tool-reference.md#performance_start_trace)
- [`performance_stop_trace`](docs/tool-reference.md#performance_stop_trace)
- [`take_memory_snapshot`](docs/tool-reference.md#take_memory_snapshot)
- **Network** (2 tools)
- [`get_network_request`](docs/tool-reference.md#get_network_request)
- [`list_network_requests`](docs/tool-reference.md#list_network_requests)
- **Debugging** (6 tools)
- [`evaluate_script`](docs/tool-reference.md#evaluate_script)
- [`get_console_message`](docs/tool-reference.md#get_console_message)
- [`lighthouse_audit`](docs/tool-reference.md#lighthouse_audit)
- [`list_console_messages`](docs/tool-reference.md#list_console_messages)
- [`take_screenshot`](docs/tool-reference.md#take_screenshot)
- [`take_snapshot`](docs/tool-reference.md#take_snapshot)
<!-- END AUTO GENERATED TOOLS -->
## Configuration
The Chrome DevTools MCP server supports the following configuration option:
<!-- BEGIN AUTO GENERATED OPTIONS -->
- **`--autoConnect`/ `--auto-connect`**
If specified, automatically connects to a browser (Chrome 144+) running locally from the user data directory identified by the channel param (default channel is stable). Requires the remoted debugging server to be started in the Chrome instance via chrome://inspect/#remote-debugging.
- **Type:** boolean
- **Default:** `false`
- **`--browserUrl`/ `--browser-url`, `-u`**
Connect to a running, debuggable Chrome instance (e.g. `http://127.0.0.1:9222`). For more details see: https://github.com/ChromeDevTools/chrome-devtools-mcp#connecting-to-a-running-chrome-instance.
- **Type:** string
- **`--wsEndpoint`/ `--ws-endpoint`, `-w`**
WebSocket endpoint to connect to a running Chrome instance (e.g., ws://127.0.0.1:9222/devtools/browser/<id>). Alternative to --browserUrl.
- **Type:** string
- **`--wsHeaders`/ `--ws-headers`**
Custom headers for WebSocket connection in JSON format (e.g., '{"Authorization":"Bearer token"}'). Only works with --wsEndpoint.
- **Type:** string
- **`--headless`**
Whether to run in headless (no UI) mode.
- **Type:** boolean
- **Default:** `false`
- **`--executablePath`/ `--executable-path`, `-e`**
Path to custom Chrome executable.
- **Type:** string
- **`--isolated`**
If specified, creates a temporary user-data-dir that is automatically cleaned up after the browser is closed. Defaults to false.
- **Type:** boolean
- **`--userDataDir`/ `--user-data-dir`**
Path to the user data directory for Chrome. Default is $HOME/.cache/chrome-devtools-mcp/chrome-profile$CHANNEL_SUFFIX_IF_NON_STABLE
- **Type:** string
- **`--channel`**
Specify a different Chrome channel that should be used. The default is the stable channel version.
- **Type:** string
- **Choices:** `stable`, `canary`, `beta`, `dev`
- **`--logFile`/ `--log-file`**
Path to a file to write debug logs to. Set the env variable `DEBUG` to `*` to enable verbose logs. Useful for submitting bug reports.
- **Type:** string
- **`--viewport`**
Initial viewport size for the Chrome instances started by the server. For example, `1280x720`. In headless mode, max size is 3840x2160px.
- **Type:** string
- **`--proxyServer`/ `--proxy-server`**
Proxy server configuration for Chrome passed as --proxy-server when launching the browser. See https://www.chromium.org/developers/design-documents/network-settings/ for details.
- **Type:** string
- **`--acceptInsecureCerts`/ `--accept-insecure-certs`**
If enabled, ignores errors relative to self-signed and expired certificates. Use with caution.
- **Type:** boolean
- **`--experimentalScreencast`/ `--experimental-screencast`**
Exposes experimental screencast tools (requires ffmpeg). Install ffmpeg https://www.ffmpeg.org/download.html and ensure it is available in the MCP server PATH.
- **Type:** boolean
- **`--chromeArg`/ `--chrome-arg`**
Additional arguments for Chrome. Only applies when Chrome is launched by chrome-devtools-mcp.
- **Type:** array
- **`--ignoreDefaultChromeArg`/ `--ignore-default-chrome-arg`**
Explicitly disable default arguments for Chrome. Only applies when Chrome is launched by chrome-devtools-mcp.
- **Type:** array
- **`--categoryEmulation`/ `--category-emulation`**
Set to false to exclude tools related to emulation.
- **Type:** boolean
- **Default:** `true`
- **`--categoryPerformance`/ `--category-performance`**
Set to false to exclude tools related to performance.
- **Type:** boolean
- **Default:** `true`
- **`--categoryNetwork`/ `--category-network`**
Set to false to exclude tools related to network.
- **Type:** boolean
- **Default:** `true`
- **`--performanceCrux`/ `--performance-crux`**
Set to false to disable sending URLs from performance traces to CrUX API to get field performance data.
- **Type:** boolean
- **Default:** `true`
- **`--usageStatistics`/ `--usage-statistics`**
Set to false to opt-out of usage statistics collection. Google collects usage data to improve the tool, handled under the Google Privacy Policy (https://policies.google.com/privacy). This is independent from Chrome browser metrics. Disabled if CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS or CI env variables are set.
- **Type:** boolean
- **Default:** `true`
- **`--slim`**
Exposes a "slim" set of 3 tools covering navigation, script execution and screenshots only. Useful for basic browser tasks.
- **Type:** boolean
<!-- END AUTO GENERATED OPTIONS -->
Pass them via the `args` property in the JSON configuration. For example:
```json
{
"mcpServers": {
"chrome-devtools": {
"command": "npx",
"args": [
"chrome-devtools-mcp@latest",
"--channel=canary",
"--headless=true",
"--isolated=true"
]
}
}
}
```
### Connecting via WebSocket with custom headers
You can connect directly to a Chrome WebSocket endpoint and include custom headers (e.g., for authentication):
```json
{
"mcpServers": {
"chrome-devtools": {
"command": "npx",
"args": [
"chrome-devtools-mcp@latest",
"--wsEndpoint=ws://127.0.0.1:9222/devtools/browser/<id>",
"--wsHeaders={\"Authorization\":\"Bearer YOUR_TOKEN\"}"
]
}
}
}
```
To get the WebSocket endpoint from a running Chrome instance, visit `http://127.0.0.1:9222/json/version` and look for the `webSocketDebuggerUrl` field.
You can also run `npx chrome-devtools-mcp@latest --help` to see all available configuration options.
## Concepts
### User data directory
`chrome-devtools-mcp` starts a Chrome's stable channel instance using the following user
data directory:
- Linux / macOS: `$HOME/.cache/chrome-devtools-mcp/chrome-profile-$CHANNEL`
- Windows: `%HOMEPATH%/.cache/chrome-devtools-mcp/chrome-profile-$CHANNEL`
The user data directory is not cleared between runs and shared across
all instances of `chrome-devtools-mcp`. Set the `isolated` option to `true`
to use a temporary user data dir instead which will be cleared automatically after
the browser is closed.
### Connecting to a running Chrome instance
By default, the Chrome DevTools MCP server will start a new Chrome instance with a dedicated profile. This might not be ideal in all situations:
- If you would like to maintain the same application state when alternating between manual site testing and agent-driven testing.
- When the MCP needs to sign into a website. Some accounts may prevent sign-in when the browser is controlled via WebDriver (the default launch mechanism for the Chrome DevTools MCP server).
- If you're running your LLM inside a sandboxed environment, but you would like to connect to a Chrome instance that runs outside the sandbox.
In these cases, start Chrome first and let the Chrome DevTools MCP server connect to it. There are two ways to do so:
- **Automatic connection (available in Chrome 144)**: best for sharing state between manual and agent-driven testing.
- **Manual connection via remote debugging port**: best when running inside a sandboxed environment.
#### Automatically connecting to a running Chrome instance
**Step 1:** Set up remote debugging in Chrome
In Chrome (\>= M144), do the following to set up remote debugging:
1. Navigate to `chrome://inspect/#remote-debugging` to enable remote debugging.
2. Follow the dialog UI to allow or disallow incoming debugging connections.
**Step 2:** Configure Chrome DevTools MCP server to automatically connect to a running Chrome Instance
To connect the `chrome-devtools-mcp` server to the running Chrome instance, use
`--autoConnect` command line argument for the MCP server.
The following code snippet is an example configuration for gemini-cli:
```json
{
"mcpServers": {
"chrome-devtools": {
"command": "npx",
"args": ["chrome-devtools-mcp@latest", "--autoConnect"]
}
}
}
```
**Step 3:** Test your setup
Make sure your browser is running. Open gemini-cli and run the following prompt:
```none
Check the performance of https://developers.chrome.com
```
> [!NOTE]
> The <code>autoConnect</code> option requires the user to start Chrome. If the user has multiple active profiles, the MCP server will connect to the default profile (as determined by Chrome). The MCP server has access to all open windows for the selected profile.
The Chrome DevTools MCP server will try to connect to your running Chrome
instance. It shows a dialog asking for user permission.
Clicking **Allow** results in the Chrome DevTools MCP server opening
[developers.chrome.com](http://developers.chrome.com) and taking a performance
trace.
#### Manual connection using port forwarding
You can connect to a running Chrome instance by using the `--browser-url` option. This is useful if you are running the MCP server in a sandboxed environment that does not allow starting a new Chrome instance.
Here is a step-by-step guide on how to connect to a running Chrome instance:
**Step 1: Configure the MCP client**
Add the `--browser-url` option to your MCP client configuration. The value of this option should be the URL of the running Chrome instance. `http://127.0.0.1:9222` is a common default.
```json
{
"mcpServers": {
"chrome-devtools": {
"command": "npx",
"args": [
"chrome-devtools-mcp@latest",
"--browser-url=http://127.0.0.1:9222"
]
}
}
}
```
**Step 2: Start the Chrome browser**
> [!WARNING]
> Enabling the remote debugging port opens up a debugging port on the running browser instance. Any application on your machine can connect to this port and control the browser. Make sure that you are not browsing any sensitive websites while the debugging port is open.
Start the Chrome browser with the remote debugging port enabled. Make sure to close any running Chrome instances before starting a new one with the debugging port enabled. The port number you choose must be the same as the one you specified in the `--browser-url` option in your MCP client configuration.
For security reasons, [Chrome requires you to use a non-default user data directory](https://developer.chrome.com/blog/remote-debugging-port) when enabling the remote debugging port. You can specify a custom directory using the `--user-data-dir` flag. This ensures that your regular browsing profile and data are not exposed to the debugging session.
**macOS**
```bash
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222 --user-data-dir=/tmp/chrome-profile-stable
```
**Linux**
```bash
/usr/bin/google-chrome --remote-debugging-port=9222 --user-data-dir=/tmp/chrome-profile-stable
```
**Windows**
```bash
"C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222 --user-data-dir="%TEMP%\chrome-profile-stable"
```
**Step 3: Test your setup**
After configuring the MCP client and starting the Chrome browser, you can test your setup by running a simple prompt in your MCP client:
```
Check the performance of https://developers.chrome.com
```
Your MCP client should connect to the running Chrome instance and receive a performance report.
If you hit VM-to-host port forwarding issues, see the “Remote debugging between virtual machine (VM) and host fails” section in [`docs/troubleshooting.md`](./docs/troubleshooting.md#remote-debugging-between-virtual-machine-vm-and-host-fails).
For more details on remote debugging, see the [Chrome DevTools documentation](https://developer.chrome.com/docs/devtools/remote-debugging/).
### Debugging Chrome on Android
Please consult [these instructions](./docs/debugging-android.md).
## Known limitations
See [Troubleshooting](./docs/troubleshooting.md).
================================================
FILE: SECURITY.md
================================================
## Security policy
The Chrome DevTools MCP project takes security very seriously. Please use [Chromium’s process to report security issues](https://www.chromium.org/Home/chromium-security/reporting-security-bugs/).
================================================
FILE: docs/cli.md
================================================
# Chrome DevTools CLI
The `chrome-devtools-mcp` package includes an **experimental** CLI interface that allows you to interact with the browser directly from your terminal. This is particularly useful for debugging or when you want an agent to generate scripts that automate browser actions.
## Getting started
Install the package globally to make the `chrome-devtools` command available:
```sh
npm i chrome-devtools-mcp@latest -g
chrome-devtools status # check if install worked.
```
## How it works
The CLI acts as a client to a background `chrome-devtools-mcp` daemon (uses Unix sockets on Linux/Mac and named pipes on Windows).
- **Automatic Start**: The first time you call a tool (e.g., `list_pages`), the CLI automatically starts the MCP server and the browser in the background if they aren't already running.
- **Persistence**: The same background instance is reused for subsequent commands, preserving the browser state (open pages, cookies, etc.).
- **Manual Control**: You can explicitly manage the background process using `start`, `stop`, and `status`. The `start` command forwards all subsequent arguments to the underlying MCP server (e.g., `--headless`, `--userDataDir`) but not all args are supported. Run `chrome-devtools start --help` for supported args. Headless and isolated are enabled by default.
```sh
# Check if the daemon is running
chrome-devtools status
# Navigate the current page to a URL
chrome-devtools navigate_page "https://google.com"
# Take a screenshot and save it to a file
chrome-devtools take_screenshot --filePath screenshot.png
# Stop the background daemon when finished
chrome-devtools stop
```
## Command Usage
The CLI supports all tools available in the [Tool reference](./tool-reference.md).
```sh
chrome-devtools <tool> [arguments] [flags]
```
- **Required Arguments**: Passed as positional arguments.
- **Optional Arguments**: Passed as flags (e.g., `--filePath`, `--fullPage`).
### Examples
**New Page and Navigation:**
```sh
chrome-devtools new_page "https://example.com"
chrome-devtools navigate_page "https://web.dev" --type url
```
**Interaction:**
```sh
# Click an element by its UID from a snapshot
chrome-devtools click "element-uid-123"
# Fill a form field
chrome-devtools fill "input-uid-456" "search query"
```
**Analysis:**
```sh
# Run a Lighthouse audit (defaults to navigation mode)
chrome-devtools lighthouse_audit --mode snapshot
```
## Output format
By default, the CLI outputs a human-readable summary of the tool's result. For programmatic use, you can request raw JSON:
```sh
chrome-devtools list_pages --output-format=json
```
## Troubleshooting
If the CLI hangs or fails to connect, try stopping the background process:
```sh
chrome-devtools stop
```
For more verbose logs, set the `DEBUG` environment variable:
```sh
DEBUG=* chrome-devtools list_pages
```
## CLI generation
Implemented in `scripts/generate-cli.ts`. Some commands are excluded from CLI
generation such as `wait_for` and `fill_form`.
`chrome-devtools-mcp` args are also filtered in `src/bin/chrome-devtools.ts`
because not all args make sense in a CLI interface.
================================================
FILE: docs/debugging-android.md
================================================
# Experimental: Debugging Chrome on Android
This is an experimental feature as Puppeteer does not officially support Chrome on Android as a target.
The workflow below works for most users. See [Troubleshooting: DevTools is not detecting the Android device for more help](https://developer.chrome.com/docs/devtools/remote-debugging#troubleshooting) for more help.
1. Open the Developer Options screen on your Android. See [Configure on-device developer Options](https://developer.android.com/studio/debug/dev-options.html).
2. Select Enable USB Debugging.
3. Connect your Android device directly to your development machine using a USB cable.
4. On your development machine setup port forwarding from your development machine to your android device:
```shell
adb forward tcp:9222 localabstract:chrome_devtools_remote
```
5. Configure your MCP server to connect to the Chrome
```json
"chrome-devtools": {
"command": "npx",
"args": [
"chrome-devtools-mcp@latest",
"--wsEndpoint=ws://127.0.0.1:9222/devtools/browser/"
],
"trust": true
}
```
6. Test your setup by running the following prompt in your coding agent:
```none
Check the performance of developers.chrome.com
```
The Chrome DevTools MCP server should now control Chrome on your Android device.
================================================
FILE: docs/design-principles.md
================================================
# Design Principles
These are rough guidelines to follow when shipping features for the MCP server.
Apply them with nuance.
- **Agent-Agnostic API**: Use standards like MCP. Don't lock in to one LLM. Interoperability is key.
- **Token-Optimized**: Return semantic summaries. "LCP was 3.2s" is better than 50k lines of JSON. Files are the right location for large amounts of data.
- **Small, Deterministic Blocks**: Give agents composable tools (Click, Screenshot), not magic buttons.
- **Self-Healing Errors**: Return actionable errors that include context and potential fixes.
- **Human-Agent Collaboration**: Output must be readable by machines (structured) AND humans (summaries).
- **Progressive Complexity**: Tools should be simple by default (high-level actions) but offer advanced optional arguments for power users.
- **Reference over Value**: for heavy assets (screenshots, traces, videos), return a file path or resource URI, never the raw data stream. Some MCP clients support a built-in handling of heavy assets e.g. directly displaying images. This _could_ be an exception.
================================================
FILE: docs/slim-tool-reference.md
================================================
<!-- AUTO GENERATED DO NOT EDIT - run 'npm run gen' to update-->
# Chrome DevTools MCP Slim Tool Reference (~359 cl100k_base tokens)
- **[Navigation automation](#navigation-automation)** (1 tools)
- [`navigate`](#navigate)
- **[Debugging](#debugging)** (2 tools)
- [`evaluate`](#evaluate)
- [`screenshot`](#screenshot)
## Navigation automation
### `navigate`
**Description:** Loads a URL
**Parameters:**
- **url** (string) **(required)**: URL to [`navigate`](#navigate) to
---
## Debugging
### `evaluate`
**Description:** Evaluates a JavaScript script
**Parameters:**
- **script** (string) **(required)**: JS script to run on the page
---
### `screenshot`
**Description:** Takes a [`screenshot`](#screenshot)
**Parameters:** None
---
================================================
FILE: docs/tool-reference.md
================================================
<!-- AUTO GENERATED DO NOT EDIT - run 'npm run gen' to update-->
# Chrome DevTools MCP Tool Reference (~6940 cl100k_base tokens)
- **[Input automation](#input-automation)** (9 tools)
- [`click`](#click)
- [`drag`](#drag)
- [`fill`](#fill)
- [`fill_form`](#fill_form)
- [`handle_dialog`](#handle_dialog)
- [`hover`](#hover)
- [`press_key`](#press_key)
- [`type_text`](#type_text)
- [`upload_file`](#upload_file)
- **[Navigation automation](#navigation-automation)** (6 tools)
- [`close_page`](#close_page)
- [`list_pages`](#list_pages)
- [`navigate_page`](#navigate_page)
- [`new_page`](#new_page)
- [`select_page`](#select_page)
- [`wait_for`](#wait_for)
- **[Emulation](#emulation)** (2 tools)
- [`emulate`](#emulate)
- [`resize_page`](#resize_page)
- **[Performance](#performance)** (4 tools)
- [`performance_analyze_insight`](#performance_analyze_insight)
- [`performance_start_trace`](#performance_start_trace)
- [`performance_stop_trace`](#performance_stop_trace)
- [`take_memory_snapshot`](#take_memory_snapshot)
- **[Network](#network)** (2 tools)
- [`get_network_request`](#get_network_request)
- [`list_network_requests`](#list_network_requests)
- **[Debugging](#debugging)** (6 tools)
- [`evaluate_script`](#evaluate_script)
- [`get_console_message`](#get_console_message)
- [`lighthouse_audit`](#lighthouse_audit)
- [`list_console_messages`](#list_console_messages)
- [`take_screenshot`](#take_screenshot)
- [`take_snapshot`](#take_snapshot)
## Input automation
### `click`
**Description:** Clicks on the provided element
**Parameters:**
- **uid** (string) **(required)**: The uid of an element on the page from the page content snapshot
- **dblClick** (boolean) _(optional)_: Set to true for double clicks. Default is false.
- **includeSnapshot** (boolean) _(optional)_: Whether to include a snapshot in the response. Default is false.
---
### `drag`
**Description:** [`Drag`](#drag) an element onto another element
**Parameters:**
- **from_uid** (string) **(required)**: The uid of the element to [`drag`](#drag)
- **to_uid** (string) **(required)**: The uid of the element to drop into
- **includeSnapshot** (boolean) _(optional)_: Whether to include a snapshot in the response. Default is false.
---
### `fill`
**Description:** Type text into a input, text area or select an option from a <select> element.
**Parameters:**
- **uid** (string) **(required)**: The uid of an element on the page from the page content snapshot
- **value** (string) **(required)**: The value to [`fill`](#fill) in
- **includeSnapshot** (boolean) _(optional)_: Whether to include a snapshot in the response. Default is false.
---
### `fill_form`
**Description:** [`Fill`](#fill) out multiple form elements at once
**Parameters:**
- **elements** (array) **(required)**: Elements from snapshot to [`fill`](#fill) out.
- **includeSnapshot** (boolean) _(optional)_: Whether to include a snapshot in the response. Default is false.
---
### `handle_dialog`
**Description:** If a browser dialog was opened, use this command to handle it
**Parameters:**
- **action** (enum: "accept", "dismiss") **(required)**: Whether to dismiss or accept the dialog
- **promptText** (string) _(optional)_: Optional prompt text to enter into the dialog.
---
### `hover`
**Description:** [`Hover`](#hover) over the provided element
**Parameters:**
- **uid** (string) **(required)**: The uid of an element on the page from the page content snapshot
- **includeSnapshot** (boolean) _(optional)_: Whether to include a snapshot in the response. Default is false.
---
### `press_key`
**Description:** Press a key or key combination. Use this when other input methods like [`fill`](#fill)() cannot be used (e.g., keyboard shortcuts, navigation keys, or special key combinations).
**Parameters:**
- **key** (string) **(required)**: A key or a combination (e.g., "Enter", "Control+A", "Control++", "Control+Shift+R"). Modifiers: Control, Shift, Alt, Meta
- **includeSnapshot** (boolean) _(optional)_: Whether to include a snapshot in the response. Default is false.
---
### `type_text`
**Description:** Type text using keyboard into a previously focused input
**Parameters:**
- **text** (string) **(required)**: The text to type
- **submitKey** (string) _(optional)_: Optional key to press after typing. E.g., "Enter", "Tab", "Escape"
---
### `upload_file`
**Description:** Upload a file through a provided element.
**Parameters:**
- **filePath** (string) **(required)**: The local path of the file to upload
- **uid** (string) **(required)**: The uid of the file input element or an element that will open file chooser on the page from the page content snapshot
- **includeSnapshot** (boolean) _(optional)_: Whether to include a snapshot in the response. Default is false.
---
## Navigation automation
### `close_page`
**Description:** Closes the page by its index. The last open page cannot be closed.
**Parameters:**
- **pageId** (number) **(required)**: The ID of the page to close. Call [`list_pages`](#list_pages) to list pages.
---
### `list_pages`
**Description:** Get a list of pages open in the browser.
**Parameters:** None
---
### `navigate_page`
**Description:** Go to a URL, or back, forward, or reload. Use project URL if not specified otherwise.
**Parameters:**
- **handleBeforeUnload** (enum: "accept", "decline") _(optional)_: Whether to auto accept or beforeunload dialogs triggered by this navigation. Default is accept.
- **ignoreCache** (boolean) _(optional)_: Whether to ignore cache on reload.
- **initScript** (string) _(optional)_: A JavaScript script to be executed on each new document before any other scripts for the next navigation.
- **timeout** (integer) _(optional)_: Maximum wait time in milliseconds. If set to 0, the default timeout will be used.
- **type** (enum: "url", "back", "forward", "reload") _(optional)_: Navigate the page by URL, back or forward in history, or reload.
- **url** (string) _(optional)_: Target URL (only type=url)
---
### `new_page`
**Description:** Open a new tab and load a URL. Use project URL if not specified otherwise.
**Parameters:**
- **url** (string) **(required)**: URL to load in a new page.
- **background** (boolean) _(optional)_: Whether to open the page in the background without bringing it to the front. Default is false (foreground).
- **isolatedContext** (string) _(optional)_: If specified, the page is created in an isolated browser context with the given name. Pages in the same browser context share cookies and storage. Pages in different browser contexts are fully isolated.
- **timeout** (integer) _(optional)_: Maximum wait time in milliseconds. If set to 0, the default timeout will be used.
---
### `select_page`
**Description:** Select a page as a context for future tool calls.
**Parameters:**
- **pageId** (number) **(required)**: The ID of the page to select. Call [`list_pages`](#list_pages) to get available pages.
- **bringToFront** (boolean) _(optional)_: Whether to focus the page and bring it to the top.
---
### `wait_for`
**Description:** Wait for the specified text to appear on the selected page.
**Parameters:**
- **text** (array) **(required)**: Non-empty list of texts. Resolves when any value appears on the page.
- **timeout** (integer) _(optional)_: Maximum wait time in milliseconds. If set to 0, the default timeout will be used.
---
## Emulation
### `emulate`
**Description:** Emulates various features on the selected page.
**Parameters:**
- **colorScheme** (enum: "dark", "light", "auto") _(optional)_: [`Emulate`](#emulate) the dark or the light mode. Set to "auto" to reset to the default.
- **cpuThrottlingRate** (number) _(optional)_: Represents the CPU slowdown factor. Omit or set the rate to 1 to disable throttling
- **geolocation** (string) _(optional)_: Geolocation (`<latitude>x<longitude>`) to [`emulate`](#emulate). Latitude between -90 and 90. Longitude between -180 and 180. Omit clear the geolocation override.
- **networkConditions** (enum: "Offline", "Slow 3G", "Fast 3G", "Slow 4G", "Fast 4G") _(optional)_: Throttle network. Omit to disable throttling.
- **userAgent** (string) _(optional)_: User agent to [`emulate`](#emulate). Set to empty string to clear the user agent override.
- **viewport** (string) _(optional)_: [`Emulate`](#emulate) device viewports '<width>x<height>x<devicePixelRatio>[,mobile][,touch][,landscape]'. 'touch' and 'mobile' to [`emulate`](#emulate) mobile devices. 'landscape' to [`emulate`](#emulate) landscape mode.
---
### `resize_page`
**Description:** Resizes the selected page's window so that the page has specified dimension
**Parameters:**
- **height** (number) **(required)**: Page height
- **width** (number) **(required)**: Page width
---
## Performance
### `performance_analyze_insight`
**Description:** Provides more detailed information on a specific Performance Insight of an insight set that was highlighted in the results of a trace recording.
**Parameters:**
- **insightName** (string) **(required)**: The name of the Insight you want more information on. For example: "DocumentLatency" or "LCPBreakdown"
- **insightSetId** (string) **(required)**: The id for the specific insight set. Only use the ids given in the "Available insight sets" list.
---
### `performance_start_trace`
**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:**
- **autoStop** (boolean) _(optional)_: Determines if the trace recording should be automatically stopped.
- **filePath** (string) _(optional)_: The absolute file path, or a file path relative to the current working directory, to save the raw trace data. For example, trace.json.gz (compressed) or trace.json (uncompressed).
- **reload** (boolean) _(optional)_: Determines if, once tracing has started, the current selected page should be automatically reloaded. Navigate the page to the right URL using the [`navigate_page`](#navigate_page) tool BEFORE starting the trace if reload or autoStop is set to true.
---
### `performance_stop_trace`
**Description:** Stop the active performance trace recording on the selected webpage.
**Parameters:**
- **filePath** (string) _(optional)_: The absolute file path, or a file path relative to the current working directory, to save the raw trace data. For example, trace.json.gz (compressed) or trace.json (uncompressed).
---
### `take_memory_snapshot`
**Description:** Capture a memory heapsnapshot of the currently selected page to memory leak debugging
**Parameters:**
- **filePath** (string) **(required)**: A path to a .heapsnapshot file to save the heapsnapshot to.
---
## Network
### `get_network_request`
**Description:** Gets a network request by an optional reqid, if omitted returns the currently selected request in the DevTools Network panel.
**Parameters:**
- **reqid** (number) _(optional)_: The reqid of the network request. If omitted returns the currently selected request in the DevTools Network panel.
- **requestFilePath** (string) _(optional)_: The absolute or relative path to save the request body to. If omitted, the body is returned inline.
- **responseFilePath** (string) _(optional)_: The absolute or relative path to save the response body to. If omitted, the body is returned inline.
---
### `list_network_requests`
**Description:** List all requests for the currently selected page since the last navigation.
**Parameters:**
- **includePreservedRequests** (boolean) _(optional)_: Set to true to return the preserved requests over the last 3 navigations.
- **pageIdx** (integer) _(optional)_: Page number to return (0-based). When omitted, returns the first page.
- **pageSize** (integer) _(optional)_: Maximum number of requests to return. When omitted, returns all requests.
- **resourceTypes** (array) _(optional)_: Filter requests to only return requests of the specified resource types. When omitted or empty, returns all requests.
---
## Debugging
### `evaluate_script`
**Description:** Evaluate a JavaScript function inside the currently selected page. Returns the response as JSON,
so returned values have to be JSON-serializable.
**Parameters:**
- **function** (string) **(required)**: A JavaScript function declaration to be executed by the tool in the currently selected page.
Example without arguments: `() => {
return document.title
}` or `async () => {
return await fetch("example.com")
}`.
Example with arguments: `(el) => {
return el.innerText;
}`
- **args** (array) _(optional)_: An optional list of arguments to pass to the function.
---
### `get_console_message`
**Description:** Gets a console message by its ID. You can get all messages by calling [`list_console_messages`](#list_console_messages).
**Parameters:**
- **msgid** (number) **(required)**: The msgid of a console message on the page from the listed console messages
---
### `lighthouse_audit`
**Description:** Get Lighthouse score and reports for accessibility, SEO and best practices. This excludes performance. For performance audits, run [`performance_start_trace`](#performance_start_trace)
**Parameters:**
- **device** (enum: "desktop", "mobile") _(optional)_: Device to [`emulate`](#emulate).
- **mode** (enum: "navigation", "snapshot") _(optional)_: "navigation" reloads & audits. "snapshot" analyzes current state.
- **outputDirPath** (string) _(optional)_: Directory for reports. If omitted, uses temporary files.
---
### `list_console_messages`
**Description:** List all console messages for the currently selected page since the last navigation.
**Parameters:**
- **includePreservedMessages** (boolean) _(optional)_: Set to true to return the preserved messages over the last 3 navigations.
- **pageIdx** (integer) _(optional)_: Page number to return (0-based). When omitted, returns the first page.
- **pageSize** (integer) _(optional)_: Maximum number of messages to return. When omitted, returns all requests.
- **types** (array) _(optional)_: Filter messages to only return messages of the specified resource types. When omitted or empty, returns all messages.
---
### `take_screenshot`
**Description:** Take a screenshot of the page or element.
**Parameters:**
- **filePath** (string) _(optional)_: The absolute path, or a path relative to the current working directory, to save the screenshot to instead of attaching it to the response.
- **format** (enum: "png", "jpeg", "webp") _(optional)_: Type of format to save the screenshot as. Default is "png"
- **fullPage** (boolean) _(optional)_: If set to true takes a screenshot of the full page instead of the currently visible viewport. Incompatible with uid.
- **quality** (number) _(optional)_: Compression quality for JPEG and WebP formats (0-100). Higher values mean better quality but larger file sizes. Ignored for PNG format.
- **uid** (string) _(optional)_: The uid of an element on the page from the page content snapshot. If omitted takes a pages screenshot.
---
### `take_snapshot`
**Description:** Take a text snapshot of the currently selected page based on the a11y tree. The snapshot lists page elements along with a unique
identifier (uid). Always use the latest snapshot. Prefer taking a snapshot over taking a screenshot. The snapshot indicates the element selected
in the DevTools Elements panel (if any).
**Parameters:**
- **filePath** (string) _(optional)_: The absolute path, or a path relative to the current working directory, to save the snapshot to instead of attaching it to the response.
- **verbose** (boolean) _(optional)_: Whether to include all possible information available in the full a11y tree. Default is false.
---
================================================
FILE: docs/troubleshooting.md
================================================
# Troubleshooting
## General tips
- Run `npx chrome-devtools-mcp@latest --help` to test if the MCP server runs on your machine.
- Make sure that your MCP client uses the same npm and node version as your terminal.
- When configuring your MCP client, try using the `--yes` argument to `npx` to
auto-accept installation prompt.
- Find a specific error in the output of the `chrome-devtools-mcp` server.
Usually, if your client is an IDE, logs would be in the Output pane.
- Search the [GitHub repository issues and discussions](https://github.com/ChromeDevTools/chrome-devtools-mcp) for help or existing similar problems.
## Debugging
Start the MCP server with debugging enabled and a log file:
- `DEBUG=* npx chrome-devtools-mcp@latest --log-file=/path/to/chrome-devtools-mcp.log`
Using `.mcp.json` to debug while using a client:
```json
{
"mcpServers": {
"chrome-devtools": {
"type": "stdio",
"command": "npx",
"args": [
"chrome-devtools-mcp@latest",
"--log-file",
"/path/to/chrome-devtools-mcp.log"
],
"env": {
"DEBUG": "*"
}
}
}
}
```
## Specific problems
### `Error [ERR_MODULE_NOT_FOUND]: Cannot find module ...`
This usually indicates either a non-supported Node version is in use or that the
`npm`/`npx` cache is corrupted. Try clearing the cache, uninstalling
`chrome-devtools-mcp` and installing it again. Clear the cache by running:
```sh
rm -rf ~/.npm/_npx # NOTE: this might remove other installed npx executables.
npm cache clean --force
```
### `Target closed` error
This indicates that the browser could not be started. Make sure that no Chrome
instances are running or close them. Make sure you have the latest stable Chrome
installed and that [your system is able to run Chrome](https://support.google.com/chrome/a/answer/7100626?hl=en).
### Chrome crashes on macOS when using Web Bluetooth
On macOS, Chrome launched by an MCP client application (such as Claude Desktop) may crash when a Web Bluetooth prompt appears. This is caused by a macOS privacy permission violation (TCC).
To resolve this, grant Bluetooth permission to the MCP client application in `System Settings > Privacy & Security > Bluetooth`. After granting permission, restart the client application and start a new MCP session.
### Remote debugging between virtual machine (VM) and host fails
When attempting to connect to Chrome running on a host machine from within a virtual machine (VM), Chrome may reject the connection due to 'Host' header validation. You can bypass this restriction by creating an SSH tunnel from the VM to the host. In the VM, run:
```sh
ssh -N -L 127.0.0.1:9222:127.0.0.1:9222 <user>@<host-ip>
```
Point the MCP connection inside the VM to `http://127.0.0.1:9222`. This allows DevTools to reach the host browser without triggering the Host validation error.
### Operating system sandboxes
Some MCP clients allow sandboxing the MCP server using macOS Seatbelt or Linux
containers. If sandboxes are enabled, `chrome-devtools-mcp` is not able to start
Chrome that requires permissions to create its own sandboxes. As a workaround,
either disable sandboxing for `chrome-devtools-mcp` in your MCP client or use
`--browser-url` to connect to a Chrome instance that you start manually outside
of the MCP client sandbox.
### WSL
By default, `chrome-devtools-mcp` in WSL requires Chrome to be installed within the Linux environment. While it normally attempts to launch Chrome on the Windows side, this currently fails due to a [known WSL issue](https://github.com/microsoft/WSL/issues/14201). Ensure you are using a [Linux distribution compatible with Chrome](https://support.google.com/chrome/a/answer/7100626).
Possible workarounds include:
- **Install Google Chrome in WSL:**
- `wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb`
- `sudo dpkg -i google-chrome-stable_current_amd64.deb`
- **Use Mirrored networking:**
1. Configure [Mirrored networking for WSL](https://learn.microsoft.com/en-us/windows/wsl/networking).
2. Start Chrome on the Windows side with:
`chrome.exe --remote-debugging-port=9222 --user-data-dir=C:\path\to\dir`
3. Start `chrome-devtools-mcp` with:
`npx chrome-devtools-mcp --browser-url http://127.0.0.1:9222`
- **Use Powershell or Git Bash** instead of WSL.
### Windows 10: Error during discovery for MCP server 'chrome-devtools': MCP error -32000: Connection closed
- **Solution 1** Call using `cmd` (For more info https://github.com/modelcontextprotocol/servers/issues/1082#issuecomment-2791786310)
```json
"mcpServers": {
"chrome-devtools": {
"command": "cmd",
"args": ["/c", "npx", "-y", "chrome-devtools-mcp@latest"]
}
}
```
> **The Key Change:** On Windows, running a Node.js package via `npx` often requires the `cmd /c` prefix to be executed correctly from within another process like VSCode's extension host. Therefore, `"command": "npx"` was replaced with `"command": "cmd"`, and the actual `npx` command was moved into the `"args"` array, preceded by `"/c"`. This fix allows Windows to interpret the command correctly and launch the server.
- **Solution 2** Instead of another layer of shell you can write the absolute path to `npx`:
> Note: The path below is an example. You must adjust it to match the actual location of `npx` on your machine. Depending on your setup, the file extension might be `.cmd`, `.bat`, or `.exe` rather than `.ps1`. Also, ensure you use double backslashes (`\\`) as path delimiters, as required by the JSON format.
```json
"mcpServers": {
"chrome-devtools": {
"command": "C:\\nvm4w\\nodejs\\npx.ps1",
"args": ["-y", "chrome-devtools-mcp@latest"]
}
}
```
### Claude Code plugin installation fails with `Failed to clone repository`
When installing `chrome-devtools-mcp` as a Claude Code plugin (either from the
official marketplace or via `/plugin marketplace add`), the installation may fail
with a timeout error if your environment cannot reach `github.com` on port 443
(HTTPS):
```
Failed to download/cache plugin chrome-devtools-mcp: Failed to clone repository:
Cloning into '...'...
fatal: unable to access 'https://github.com/ChromeDevTools/chrome-devtools-mcp.git/':
Failed to connect to github.com port 443
```
This can happen in environments with restricted outbound HTTPS connectivity,
corporate firewalls, or proxy configurations that block HTTPS git operations.
**Workaround 1: Use SSH instead of HTTPS**
If you have SSH access to GitHub configured, you can redirect all GitHub HTTPS
URLs to use SSH by running:
```sh
git config --global url."git@github.com:".insteadOf "https://github.com/"
```
Then retry the plugin installation. This tells git to use your SSH key for all
GitHub operations instead of HTTPS.
**Workaround 2: Install via CLI instead**
If the plugin marketplace approach fails, you can install `chrome-devtools-mcp`
as an MCP server directly without cloning the repository:
```sh
claude mcp add chrome-devtools --scope user npx chrome-devtools-mcp@latest
```
This bypasses the git clone entirely and uses npm/npx to fetch the package. Note
that this method installs only the MCP server without the bundled skills.
### Connection timeouts with `--autoConnect`
If you are using the `--autoConnect` flag and tools like `list_pages`, `new_page`, or `navigate_page` fail with a timeout (e.g., `ProtocolError: Network.enable timed out` or `The socket connection was closed unexpectedly`), this usually means the MCP server cannot handshake with the running Chrome instance correctly. Ensure:
1. Chrome 144+ is **already** running.
2. Remote debugging is enabled in Chrome via `chrome://inspect/#remote-debugging`.
3. You have allowed the remote debugging connection prompt in the browser.
4. There is no other MCP server or tool trying to connect to the same debugging port.
================================================
FILE: eslint.config.mjs
================================================
/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import js from '@eslint/js';
import stylisticPlugin from '@stylistic/eslint-plugin';
import {defineConfig, globalIgnores} from 'eslint/config';
import importPlugin from 'eslint-plugin-import';
import globals from 'globals';
import tseslint from 'typescript-eslint';
import localPlugin from './scripts/eslint_rules/local-plugin.js';
export default defineConfig([
globalIgnores([
'**/node_modules',
'**/build/',
'tests/tools/fixtures/',
'src/third_party/lighthouse-devtools-mcp-bundle.js',
]),
importPlugin.flatConfigs.typescript,
{
languageOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
globals: {
...globals.node,
},
parserOptions: {
projectService: {
allowDefaultProject: [
'.prettierrc.cjs',
'puppeteer.config.cjs',
'eslint.config.mjs',
'rollup.config.mjs',
],
},
},
parser: tseslint.parser,
},
plugins: {
js,
'@local': localPlugin,
'@typescript-eslint': tseslint.plugin,
'@stylistic': stylisticPlugin,
},
settings: {
'import/resolver': {
typescript: true,
},
},
extends: ['js/recommended'],
},
tseslint.configs.recommended,
tseslint.configs.stylistic,
{
name: 'TypeScript rules',
rules: {
'@local/check-license': 'error',
curly: ['error', 'all'],
'no-undef': 'off',
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
},
],
'@typescript-eslint/no-explicit-any': [
'error',
{
ignoreRestArgs: true,
},
],
// This optimizes the dependency tracking for type-only files.
'@typescript-eslint/consistent-type-imports': 'error',
// So type-only exports get elided.
'@typescript-eslint/consistent-type-exports': 'error',
// Prefer interfaces over types for shape like.
'@typescript-eslint/consistent-type-definitions': ['error', 'interface'],
'@typescript-eslint/array-type': [
'error',
{
default: 'array-simple',
},
],
'@typescript-eslint/no-floating-promises': 'error',
'import/order': [
'error',
{
'newlines-between': 'always',
alphabetize: {
order: 'asc',
caseInsensitive: true,
},
},
],
'import/no-cycle': [
'error',
{
maxDepth: Infinity,
},
],
'import/enforce-node-protocol-usage': ['error', 'always'],
'@stylistic/function-call-spacing': 'error',
'@stylistic/semi': 'error',
'no-restricted-imports': [
'error',
{
patterns: [
{
regex: '.*chrome-devtools-frontend/(?!mcp/mcp.js$).*',
message:
'Import only the devtools-frontend code exported via node_modules/chrome-devtools-frontend/mcp/mcp.js',
},
],
},
],
},
},
{
name: 'Tests',
files: ['**/*.test.ts'],
rules: {
// With the Node.js test runner, `describe` and `it` are technically
// promises, but we don't need to await them.
'@typescript-eslint/no-floating-promises': 'off',
},
},
]);
================================================
FILE: gemini-extension.json
================================================
{
"name": "chrome-devtools-mcp",
"version": "latest",
"mcpServers": {
"chrome-devtools": {
"command": "npx",
"args": ["chrome-devtools-mcp@latest"]
}
}
}
================================================
FILE: package.json
================================================
{
"name": "chrome-devtools-mcp",
"version": "0.20.2",
"description": "MCP server for Chrome DevTools",
"type": "module",
"bin": {
"chrome-devtools-mcp": "./build/src/bin/chrome-devtools-mcp.js",
"chrome-devtools": "./build/src/bin/chrome-devtools.js"
},
"main": "./build/src/index.js",
"scripts": {
"cli:generate": "node --experimental-strip-types scripts/generate-cli.ts",
"clean": "node -e \"require('fs').rmSync('build', {recursive: true, force: true})\"",
"bundle": "npm run clean && npm run build && rollup -c rollup.config.mjs && node -e \"require('fs').rmSync('build/node_modules', {recursive: true, force: true})\" && node --experimental-strip-types scripts/append-lighthouse-notices.ts",
"build": "tsc && node --experimental-strip-types --no-warnings=ExperimentalWarning scripts/post-build.ts",
"typecheck": "tsc --noEmit",
"format": "eslint --cache --fix . && prettier --write --cache .",
"check-format": "eslint --cache . && prettier --check --cache .;",
"gen": "npm run build && npm run docs:generate && npm run cli:generate && npm run format",
"docs:generate": "node --experimental-strip-types scripts/generate-docs.ts",
"start": "npm run build && node build/src/index.js",
"start-debug": "DEBUG=mcp:* DEBUG_COLORS=false npm run build && node build/src/index.js",
"test": "npm run build && node scripts/test.mjs",
"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",
"verify-server-json-version": "node --experimental-strip-types scripts/verify-server-json-version.ts",
"update-lighthouse": "node --experimental-strip-types scripts/update-lighthouse.ts",
"verify-npm-package": "node scripts/verify-npm-package.mjs",
"eval": "npm run build && node --experimental-strip-types scripts/eval_gemini.ts",
"count-tokens": "node --experimental-strip-types scripts/count_tokens.ts"
},
"files": [
"build/src",
"LICENSE",
"!*.tsbuildinfo"
],
"repository": "ChromeDevTools/chrome-devtools-mcp",
"author": "Google LLC",
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/ChromeDevTools/chrome-devtools-mcp/issues"
},
"homepage": "https://github.com/ChromeDevTools/chrome-devtools-mcp#readme",
"mcpName": "io.github.ChromeDevTools/chrome-devtools-mcp",
"devDependencies": {
"@eslint/js": "^9.35.0",
"@google/genai": "^1.37.0",
"@modelcontextprotocol/sdk": "1.27.1",
"@rollup/plugin-commonjs": "^29.0.0",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^16.0.3",
"@stylistic/eslint-plugin": "^5.4.0",
"@types/debug": "^4.1.12",
"@types/filesystem": "^0.0.36",
"@types/node": "^25.0.0",
"@types/sinon": "^21.0.0",
"@types/yargs": "^17.0.33",
"@typescript-eslint/eslint-plugin": "^8.43.0",
"@typescript-eslint/parser": "^8.43.0",
"chrome-devtools-frontend": "1.0.1599001",
"core-js": "3.48.0",
"debug": "4.4.3",
"eslint": "^9.35.0",
"eslint-import-resolver-typescript": "^4.4.4",
"eslint-plugin-import": "^2.32.0",
"globals": "^17.0.0",
"lighthouse": "13.0.3",
"prettier": "^3.6.2",
"puppeteer": "24.39.1",
"rollup": "4.59.0",
"rollup-plugin-cleanup": "^3.2.1",
"rollup-plugin-license": "^3.6.0",
"sinon": "^21.0.0",
"tiktoken": "^1.0.22",
"typescript": "^5.9.2",
"typescript-eslint": "^8.43.0",
"yargs": "18.0.0"
},
"engines": {
"node": "^20.19.0 || ^22.12.0 || >=23"
}
}
================================================
FILE: puppeteer.config.cjs
================================================
/**
* @license
* Copyright 2025 Google Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @type {import("puppeteer").Configuration}
*/
module.exports = {
chrome: {
skipDownload: false,
},
['chrome-headless-shell']: {
skipDownload: true,
},
firefox: {
skipDownload: true,
},
};
================================================
FILE: release-please-config.json
================================================
{
"changelog-sections": [
{"type": "feat", "section": "🎉 Features", "hidden": false},
{"type": "fix", "section": "🛠️ Fixes", "hidden": false},
{"type": "docs", "section": "📄 Documentation", "hidden": false},
{"type": "perf", "section": "⚡ Performance", "hidden": false},
{"type": "refactor", "section": "🏗️ Refactor", "hidden": false},
{"type": "chore", "section": "♻️ Chores", "hidden": true},
{"type": "test", "section": "♻️ Chores", "hidden": true},
{"type": "build", "section": "⚙️ Automation", "hidden": true},
{"type": "ci", "section": "⚙️ Automation", "hidden": true}
],
"packages": {
".": {
"extra-files": [
{
"type": "generic",
"path": "src/version.ts"
},
{
"type": "json",
"path": "server.json",
"jsonpath": "version"
},
{
"type": "json",
"path": "server.json",
"jsonpath": "packages[0].version"
}
]
}
}
}
================================================
FILE: rollup.config.mjs
================================================
/**
* Copyright 2021 Google LLC.
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview taken from {@link https://github.com/GoogleChromeLabs/chromium-bidi/blob/main/rollup.config.mjs | chromium-bidi}
* and modified to specific requirement.
*/
import fs from 'node:fs';
import path from 'node:path';
import commonjs from '@rollup/plugin-commonjs';
import json from '@rollup/plugin-json';
import {nodeResolve} from '@rollup/plugin-node-resolve';
import cleanup from 'rollup-plugin-cleanup';
import license from 'rollup-plugin-license';
const isProduction = process.env.NODE_ENV === 'production';
const allowedLicenses = [
'MIT',
'Apache 2.0',
'Apache-2.0',
'BSD-3-Clause',
'BSD-2-Clause',
'ISC',
'0BSD',
];
const thirdPartyDir = './build/src/third_party';
const {devDependencies = {}} = JSON.parse(
fs.readFileSync(path.join(process.cwd(), 'package.json'), 'utf-8'),
);
// special case for puppeteer, from which we only bundle puppeteer-core
devDependencies['puppeteer-core'] = devDependencies['puppeteer'];
const aggregatedStats = {
bundlesProcessed: 0,
totalBundles: 0,
bundledPackages: new Set(),
};
const projectNodeModulesPath =
path.join(process.cwd(), 'node_modules') + path.sep;
function getPackageName(modulePath) {
// Handle rollup's virtual module paths (paths starting with 0x00)
const absolutePathStart = modulePath.indexOf(projectNodeModulesPath);
if (absolutePathStart < 0) {
return null;
}
const relativePath = modulePath.slice(
projectNodeModulesPath.length + absolutePathStart,
);
const segments = relativePath.split(path.sep);
// handle scoped packages
if (segments[0].startsWith('@') && segments[1]) {
return `${segments[0]}/${segments[1]}`;
}
return segments[0];
}
/**
* @returns {import('rollup').Plugin}
*/
function listBundledDeps() {
aggregatedStats.totalBundles++;
return {
name: 'gather-bundled-dependencies',
generateBundle(options, bundle) {
for (const chunk of Object.values(bundle)) {
if (chunk.type === 'chunk' && chunk.modules) {
// chunk.modules is an object where keys are the absolute file paths
Object.keys(chunk.modules).forEach(modulePath => {
const packageName = getPackageName(modulePath);
if (packageName) {
aggregatedStats.bundledPackages.add(packageName);
}
});
}
}
aggregatedStats.bundlesProcessed++;
// Only write the file when the last bundle is finished
if (aggregatedStats.bundlesProcessed === aggregatedStats.totalBundles) {
const outputPath = path.join(thirdPartyDir, 'bundled-packages.json');
const bundledDevDeps = Object.fromEntries(
Object.entries(devDependencies).filter(
([name]) =>
aggregatedStats.bundledPackages.has(name) ||
name === 'chrome-devtools-frontend' ||
name === 'lighthouse',
),
);
fs.writeFileSync(outputPath, JSON.stringify(bundledDevDeps, null, 2));
}
},
};
}
const seenDependencies = new Map();
/**
* @param {string} wrapperIndexName
* @param {import('rollup').OutputOptions} [extraOutputOptions={}]
* @param {import('rollup').ExternalOption} [external=[]]
* @returns {import('rollup').RollupOptions}
*/
const bundleDependency = (
wrapperIndexName,
extraOutputOptions = {},
external = [],
) => ({
input: path.join(thirdPartyDir, wrapperIndexName),
output: {
...extraOutputOptions,
file: path.join(thirdPartyDir, wrapperIndexName),
sourcemap: !isProduction,
format: 'esm',
},
plugins: [
cleanup({
// Keep license comments. Other comments are removed due to
// http://b/390559299 and
// https://github.com/microsoft/TypeScript/issues/60811.
comments: [/Copyright/i],
}),
license({
thirdParty: {
allow: {
test: dependency => {
return allowedLicenses.includes(dependency.license);
},
failOnUnlicensed: true,
failOnViolation: true,
},
output: {
file: path.join(thirdPartyDir, 'THIRD_PARTY_NOTICES'),
template(dependencies) {
for (const dependency of dependencies) {
const key = `${dependency.name}:${dependency.version}`;
seenDependencies.set(key, dependency);
}
const stringifiedDependencies = Array.from(
seenDependencies.values(),
).map(dependency => {
let arr = [];
arr.push(`Name: ${dependency.name ?? 'N/A'}`);
let url = dependency.homepage ?? dependency.repository;
if (url !== null && typeof url !== 'string') {
url = url.url;
}
arr.push(`URL: ${url ?? 'N/A'}`);
arr.push(`Version: ${dependency.version ?? 'N/A'}`);
arr.push(`License: ${dependency.license ?? 'N/A'}`);
if (dependency.licenseText !== null) {
arr.push('');
arr.push(dependency.licenseText.replaceAll('\r', ''));
}
return arr.join('\n');
});
// Manual license handling for chrome-devtools-frontend third_party
const tsConfig = JSON.parse(
fs.readFileSync(
path.join(process.cwd(), 'tsconfig.json'),
'utf-8',
),
);
const thirdPartyDirectories = tsConfig.include.filter(location =>
location.includes(
'node_modules/chrome-devtools-frontend/front_end/third_party',
),
);
const manualLicenses = [];
// Add chrome-devtools-frontend main license
const cdtfLicensePath = path.join(
process.cwd(),
'node_modules/chrome-devtools-frontend/LICENSE',
);
if (fs.existsSync(cdtfLicensePath)) {
manualLicenses.push(
[
'Name: chrome-devtools-frontend',
'License: Apache-2.0',
'',
fs.readFileSync(cdtfLicensePath, 'utf-8'),
].join('\n'),
);
}
// Add chrome-devtools-frontend main license
const lighthouseLicensePath = path.join(
process.cwd(),
'node_modules/lighthouse/LICENSE',
);
if (fs.existsSync(lighthouseLicensePath)) {
manualLicenses.push(
[
'Name: lighthouse',
'License: Apache-2.0',
'',
fs.readFileSync(lighthouseLicensePath, 'utf-8'),
].join('\n'),
);
}
for (const thirdPartyDir of thirdPartyDirectories) {
const fullPath = path.join(process.cwd(), thirdPartyDir);
const licenseFile = path.join(fullPath, 'LICENSE');
if (fs.existsSync(licenseFile)) {
const name = path.basename(thirdPartyDir);
manualLicenses.push(
[
`Name: ${name}`,
`License:`,
'',
fs.readFileSync(licenseFile, 'utf-8').replaceAll('\r', ''),
].join('\n'),
);
}
}
if (manualLicenses.length > 0) {
stringifiedDependencies.push(...manualLicenses);
}
const divider =
'\n\n-------------------- DEPENDENCY DIVIDER --------------------\n\n';
return stringifiedDependencies.join(divider);
},
},
},
}),
listBundledDeps(),
commonjs(),
json(),
nodeResolve(),
],
external,
});
export default [
bundleDependency(
'index.js',
{
inlineDynamicImports: true,
},
(source, importer, _isResolved) => {
if (
source === 'yargs' &&
importer &&
importer.includes('puppeteer-core')
) {
return true;
}
const existingExternals = [
'./bidi.js',
'../bidi/bidi.js',
'./lighthouse-devtools-mcp-bundle.js',
];
if (existingExternals.includes(source)) {
return true;
}
return false;
},
),
bundleDependency(
'devtools-formatter-worker.js',
{
inlineDynamicImports: true,
},
(_source, _importer, _isResolved) => false,
),
];
================================================
FILE: scripts/append-lighthouse-notices.ts
================================================
/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import fs from 'node:fs';
import path from 'node:path';
const ROOT_DIR = process.cwd();
const TARGET_DIR = path.join(ROOT_DIR, 'build/src/third_party');
const SOURCE_DIR = path.join(ROOT_DIR, 'src/third_party');
function main() {
const lighthouseNotices = fs.readFileSync(
path.join(SOURCE_DIR, 'LIGHTHOUSE_MCP_BUNDLE_THIRD_PARTY_NOTICES'),
'utf8',
);
const bundledNotices = fs.readFileSync(
path.join(TARGET_DIR, 'THIRD_PARTY_NOTICES'),
'utf8',
);
fs.writeFileSync(
path.join(TARGET_DIR, 'THIRD_PARTY_NOTICES'),
bundledNotices +
'\n\n-------------------- DEPENDENCY DIVIDER --------------------\n\n' +
lighthouseNotices,
);
console.log('Done.');
}
main();
================================================
FILE: scripts/count_tokens.ts
================================================
/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import {readFileSync} from 'node:fs';
import {parseArgs} from 'node:util';
import {GoogleGenAI} from '@google/genai';
const ai = new GoogleGenAI({apiKey: process.env.GEMINI_API_KEY});
const {values, positionals} = parseArgs({
options: {
model: {
type: 'string',
default: 'gemini-2.5-flash',
},
file: {
type: 'string',
short: 'f',
},
},
allowPositionals: true,
});
let contents = positionals[0];
if (values.file) {
contents = readFileSync(values.file, 'utf8');
}
if (!contents) {
console.error('Usage: npm run count-tokens -- [-f <file>] [<text>]');
process.exit(1);
}
const response = await ai.models.countTokens({
model: values.model,
contents,
});
console.log(`Input: ${values.file || positionals[0]}`);
console.log(`Tokens: ${response.totalTokens}`);
================================================
FILE: scripts/eslint_rules/check-license-rule.js
================================================
/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
const currentYear = new Date().getFullYear();
const licenseHeader = `
/**
* @license
* Copyright ${currentYear} Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
`;
export default {
name: 'check-license',
meta: {
type: 'layout',
docs: {
description: 'Validate existence of license header',
},
fixable: 'code',
schema: [],
messages: {
licenseRule: 'Add license header.',
emptyLine: 'Add empty line after license header.',
},
},
defaultOptions: [],
create(context) {
const sourceCode = context.getSourceCode();
const comments = sourceCode.getAllComments();
let insertAfter = [0, 0];
let header = null;
// Check only the first 2 comments
for (let index = 0; index < 2; index++) {
const comment = comments[index];
if (!comment) {
break;
}
// Shebang comments should be at the top
if (
comment.type === 'Shebang' ||
(comment.type === 'Line' && comment.value.startsWith('#!'))
) {
insertAfter = comment.range;
continue;
}
if (comment.type === 'Block') {
header = comment;
break;
}
}
return {
Program(node) {
if (context.getFilename().endsWith('.json')) {
return;
}
if (
header &&
(header.value.includes('@license') ||
header.value.includes('License') ||
header.value.includes('Copyright'))
) {
const nextToken = sourceCode.getTokenAfter(header, {
includeComments: true,
});
if (
nextToken &&
nextToken.loc.start.line === header.loc.end.line + 1
) {
context.report({
node: node,
loc: header.loc,
messageId: 'emptyLine',
fix(fixer) {
return fixer.insertTextAfter(header, '\n');
},
});
}
return;
}
// Add header license
if (!header || !header.value.includes('@license')) {
context.report({
node: node,
messageId: 'licenseRule',
fix(fixer) {
return fixer.insertTextAfterRange(insertAfter, licenseHeader);
},
});
}
},
};
},
};
================================================
FILE: scripts/eslint_rules/local-plugin.js
================================================
/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import checkLicenseRule from './check-license-rule.js';
export default {rules: {'check-license': checkLicenseRule}};
================================================
FILE: scripts/eval_gemini.ts
================================================
/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import fs from 'node:fs';
import path from 'node:path';
import {pathToFileURL} from 'node:url';
import {parseArgs} from 'node:util';
import {GoogleGenAI, mcpToTool} from '@google/genai';
import {Client} from '@modelcontextprotocol/sdk/client/index.js';
import {StdioClientTransport} from '@modelcontextprotocol/sdk/client/stdio.js';
import {TestServer} from '../build/tests/server.js';
const ROOT_DIR = path.resolve(import.meta.dirname, '..');
const SCENARIOS_DIR = path.join(import.meta.dirname, 'eval_scenarios');
const SKILL_PATH = path.join(ROOT_DIR, 'skills', 'chrome-devtools', 'SKILL.md');
// Define schema for our test scenarios
export interface CapturedFunctionCall {
name: string;
args: Record<string, unknown>;
}
export interface TestScenario {
prompt: string;
maxTurns: number;
expectations: (calls: CapturedFunctionCall[]) => void;
htmlRoute?: {
path: string;
htmlContent: string;
};
/** Extra CLI flags passed to the MCP server (e.g. '--experimental-page-id-routing'). */
serverArgs?: string[];
}
async function loadScenario(scenarioPath: string): Promise<TestScenario> {
const module = await import(pathToFileURL(scenarioPath).href);
if (!module.scenario) {
throw new Error(
`Scenario file ${scenarioPath} does not export a 'scenario' object.`,
);
}
return module.scenario;
}
async function runSingleScenario(
scenarioPath: string,
apiKey: string,
server: TestServer,
modelId: string,
debug: boolean,
includeSkill: boolean,
): Promise<void> {
const debugLog = (...args: unknown[]) => {
if (debug) {
console.log(...args);
}
};
const absolutePath = path.resolve(scenarioPath);
debugLog(
`\n### Running Scenario: ${path.relative(ROOT_DIR, absolutePath)} ###`,
);
let client: Client | undefined;
let transport: StdioClientTransport | undefined;
try {
const loadedScenario = await loadScenario(absolutePath);
const scenario = {...loadedScenario};
// Prepend skill content if requested
if (includeSkill) {
if (!fs.existsSync(SKILL_PATH)) {
throw new Error(
`Skill file not found at ${SKILL_PATH}. Please ensure the skill file exists.`,
);
}
const skillContent = fs.readFileSync(SKILL_PATH, 'utf-8');
scenario.prompt = `${skillContent}\n\n---\n\n${scenario.prompt}`;
}
// Append random queryid to avoid caching issues and test distinct runs
const randomId = Math.floor(Math.random() * 1000000);
scenario.prompt = `${scenario.prompt}\nqueryid=${randomId}`;
if (scenario.htmlRoute) {
server.addHtmlRoute(
scenario.htmlRoute.path,
scenario.htmlRoute.htmlContent,
);
scenario.prompt = scenario.prompt.replace(
'<TEST_URL>',
server.getRoute(scenario.htmlRoute.path),
);
}
// Path to the compiled MCP server
const serverPath = path.join(ROOT_DIR, 'build/src/index.js');
if (!fs.existsSync(serverPath)) {
throw new Error(
`MCP server not found at ${serverPath}. Please run 'npm run build' first.`,
);
}
// Environment variables
const env: Record<string, string> = {};
Object.entries(process.env).forEach(([key, value]) => {
if (value !== undefined) {
env[key] = value;
}
});
env['CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS'] = 'true';
const args = [serverPath];
if (!debug) {
args.push('--headless');
}
if (scenario.serverArgs) {
args.push(...scenario.serverArgs);
}
transport = new StdioClientTransport({
command: 'node',
args,
env,
stderr: debug ? 'inherit' : 'ignore',
});
client = new Client(
{name: 'gemini-eval-client', version: '1.0.0'},
{capabilities: {}},
);
await client.connect(transport);
const allCalls: CapturedFunctionCall[] = [];
const originalCallTool = client.callTool.bind(client);
client.callTool = async (request, schema) => {
// NOTE: request.name is the original name as the MCP client sees it.
// mcpToTool handles the conversion from Gemini sanitized name to original name.
debugLog(
`Executing tool: ${request.name} with args: ${JSON.stringify(request.arguments)}`,
);
allCalls.push({
name: request.name,
args: (request.arguments as Record<string, unknown>) || {},
});
const response = await originalCallTool(request, schema);
debugLog(`Tool response: ${JSON.stringify(response)}`);
return response;
};
const ai = new GoogleGenAI({apiKey});
debugLog(`\n--- Prompt ---\n${scenario.prompt}`);
const result = await ai.models.generateContent({
model: modelId,
contents: scenario.prompt,
config: {
tools: [mcpToTool(client)],
automaticFunctionCalling: {
maximumRemoteCalls: scenario.maxTurns,
},
},
});
debugLog(`\n--- Response ---\n${result.text}`);
debugLog('\nVerifying expectations...');
scenario.expectations(allCalls);
} finally {
try {
await client?.close();
} catch (e) {
console.error('Error closing client:', e);
}
}
}
async function main() {
const apiKey = process.env.GEMINI_API_KEY;
if (!apiKey) {
throw new Error('GEMINI_API_KEY environment variable is required.');
}
const {values, positionals} = parseArgs({
options: {
model: {
type: 'string',
default: 'gemini-2.5-flash',
},
debug: {
type: 'boolean',
default: false,
},
repeat: {
type: 'boolean',
default: false,
},
'include-skill': {
type: 'boolean',
default: false,
},
},
allowPositionals: true,
});
const modelId = values.model;
const debug = values.debug;
const repeat = values.repeat;
const includeSkill = values['include-skill'];
const scenarioFiles =
positionals.length > 0
? positionals.map(p => path.resolve(p))
: fs
.readdirSync(SCENARIOS_DIR)
.filter(file => file.endsWith('.ts') || file.endsWith('.js'))
.map(file => path.join(SCENARIOS_DIR, file));
const server = new TestServer(TestServer.randomPort());
await server.start();
let successCount = 0;
let failureCount = 0;
try {
for (const scenarioPath of scenarioFiles) {
for (let i = 1; i <= (repeat ? 3 : 1); i++) {
try {
if (debug) {
console.log(
`Running scenario: ${path.relative(ROOT_DIR, scenarioPath)} (Run ${i}/3)`,
);
}
await runSingleScenario(
scenarioPath,
apiKey,
server,
modelId,
debug,
includeSkill,
);
console.log(`✔ ${path.relative(ROOT_DIR, scenarioPath)} (Run ${i})`);
successCount++;
} catch (e) {
console.error(
`✖ ${path.relative(ROOT_DIR, scenarioPath)} (Run ${i})`,
);
console.error(e);
failureCount++;
} finally {
server.restore();
}
}
}
} finally {
await server.stop();
}
console.log(`\nSummary: ${successCount} passed, ${failureCount} failed`);
if (failureCount > 0) {
process.exit(1);
}
}
main().catch(error => {
console.error('Fatal error:', error);
process.exit(1);
});
================================================
FILE: scripts/eval_scenarios/console_test.ts
================================================
/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import assert from 'node:assert';
import type {TestScenario} from '../eval_gemini.ts';
export const scenario: TestScenario = {
prompt: 'Navigate to <TEST_URL> and check the console messages.',
maxTurns: 2,
htmlRoute: {
path: '/console_test.html',
htmlContent: `
<script>
console.log('Test log message');
console.error('Test error message');
</script>
`,
},
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,
'list_console_messages',
'Second call should be list_console_messages',
);
},
};
================================================
FILE: scripts/eval_scenarios/emulation_test.ts
================================================
/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import assert from 'node:assert';
import type {TestScenario} from '../eval_gemini.ts';
export const scenario: TestScenario = {
prompt: 'Emulate offline network conditions.',
maxTurns: 2,
expectations: calls => {
assert.strictEqual(calls.length, 1);
assert.strictEqual(calls[0].name, 'emulate');
assert.strictEqual(calls[0].args.networkConditions, 'Offline');
},
};
================================================
FILE: scripts/eval_scenarios/emulation_userAgent_test.ts
================================================
/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import assert from 'node:assert';
import type {TestScenario} from '../eval_gemini.ts';
export const scenario: TestScenario = {
prompt: 'Emulate iPhone 14 user agent',
maxTurns: 2,
expectations: calls => {
assert.strictEqual(calls.length, 1);
assert.strictEqual(calls[0].name, 'emulate');
assert.deepStrictEqual(
calls[0].args.userAgent,
'Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1',
);
},
};
================================================
FILE: scripts/eval_scenarios/emulation_viewport_test.ts
================================================
/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import assert from 'node:assert';
import {KnownDevices} from 'puppeteer';
import type {TestScenario} from '../eval_gemini.ts';
export const scenario: TestScenario = {
prompt: 'Emulate iPhone 14 viewport',
maxTurns: 2,
expectations: calls => {
assert.strictEqual(calls.length, 1);
assert.strictEqual(calls[0].name, 'emulate');
assert.deepStrictEqual(
{
...(calls[0].args.viewport as object),
// models might not send defaults.
isLandscape: KnownDevices['iPhone 14'].viewport.isLandscape ?? false,
},
{
...KnownDevices['iPhone 14'].viewport,
height: 844, // Puppeteer is wrong about the expected height.
},
);
},
};
================================================
FILE: scripts/eval_scenarios/fix_webpage_issues_test.ts
================================================
/**
* @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: `
<h1>Test Page</h1>
<p>Some content</p>
<script>
console.error('Intentional error for testing');
</script>
`,
},
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_TO
gitextract_cbkm4aqd/ ├── .agent/ │ └── rules/ │ └── coding.md ├── .claude-plugin/ │ ├── marketplace.json │ └── plugin.json ├── .gitattributes ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── 01-bug.yml │ │ ├── 02-feature.yml │ │ ├── 03-task.yml │ │ └── config.yml │ ├── dependabot.yml │ └── workflows/ │ ├── conventional-commit.yml │ ├── pre-release.yml │ ├── presubmit.yml │ ├── publish-to-npm-on-tag.yml │ ├── release-please.yml │ └── run-tests.yml ├── .gitignore ├── .mcp.json ├── .nvmrc ├── .prettierignore ├── .prettierrc.cjs ├── .release-please-manifest.json ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── SECURITY.md ├── docs/ │ ├── cli.md │ ├── debugging-android.md │ ├── design-principles.md │ ├── slim-tool-reference.md │ ├── tool-reference.md │ └── troubleshooting.md ├── eslint.config.mjs ├── gemini-extension.json ├── package.json ├── puppeteer.config.cjs ├── release-please-config.json ├── rollup.config.mjs ├── scripts/ │ ├── append-lighthouse-notices.ts │ ├── count_tokens.ts │ ├── eslint_rules/ │ │ ├── check-license-rule.js │ │ └── local-plugin.js │ ├── eval_gemini.ts │ ├── eval_scenarios/ │ │ ├── console_test.ts │ │ ├── emulation_test.ts │ │ ├── emulation_userAgent_test.ts │ │ ├── emulation_viewport_test.ts │ │ ├── fix_webpage_issues_test.ts │ │ ├── frontend_snapshot_test.ts │ │ ├── input_parallel_test.ts │ │ ├── input_test.ts │ │ ├── isolated_context_test.ts │ │ ├── lighthouse_a11y_test.ts │ │ ├── lighthouse_best_practices_test.ts │ │ ├── navigation_test.ts │ │ ├── network_test.ts │ │ ├── page_focus_keyboard_test.ts │ │ ├── page_id_routing_test.ts │ │ ├── performance_test.ts │ │ ├── select_page_test.ts │ │ └── snapshot_test.ts │ ├── generate-cli.ts │ ├── generate-docs.ts │ ├── post-build.ts │ ├── prepare.ts │ ├── test.mjs │ ├── tsconfig.json │ ├── update-lighthouse.ts │ ├── verify-npm-package.mjs │ └── verify-server-json-version.ts ├── server.json ├── skills/ │ ├── a11y-debugging/ │ │ ├── SKILL.md │ │ └── references/ │ │ └── a11y-snippets.md │ ├── chrome-devtools/ │ │ └── SKILL.md │ ├── chrome-devtools-cli/ │ │ ├── SKILL.md │ │ └── references/ │ │ └── installation.md │ ├── debug-optimize-lcp/ │ │ ├── SKILL.md │ │ └── references/ │ │ ├── elements-and-size.md │ │ ├── lcp-breakdown.md │ │ ├── lcp-snippets.md │ │ └── optimization-strategies.md │ └── troubleshooting/ │ └── SKILL.md ├── src/ │ ├── DevToolsConnectionAdapter.ts │ ├── DevtoolsUtils.ts │ ├── McpContext.ts │ ├── McpPage.ts │ ├── McpResponse.ts │ ├── Mutex.ts │ ├── PageCollector.ts │ ├── SlimMcpResponse.ts │ ├── WaitForHelper.ts │ ├── bin/ │ │ ├── chrome-devtools-cli-options.ts │ │ ├── chrome-devtools-mcp-cli-options.ts │ │ ├── chrome-devtools-mcp-main.ts │ │ ├── chrome-devtools-mcp.ts │ │ ├── chrome-devtools.ts │ │ └── cliDefinitions.ts │ ├── browser.ts │ ├── daemon/ │ │ ├── client.ts │ │ ├── daemon.ts │ │ ├── types.ts │ │ └── utils.ts │ ├── devtools.d.ts │ ├── formatters/ │ │ ├── ConsoleFormatter.ts │ │ ├── IssueFormatter.ts │ │ ├── NetworkFormatter.ts │ │ └── SnapshotFormatter.ts │ ├── index.ts │ ├── issue-descriptions.ts │ ├── logger.ts │ ├── polyfill.ts │ ├── telemetry/ │ │ ├── ClearcutLogger.ts │ │ ├── WatchdogClient.ts │ │ ├── flagUtils.ts │ │ ├── metricUtils.ts │ │ ├── persistence.ts │ │ ├── types.ts │ │ └── watchdog/ │ │ ├── ClearcutSender.ts │ │ └── main.ts │ ├── third_party/ │ │ ├── LIGHTHOUSE_MCP_BUNDLE_THIRD_PARTY_NOTICES │ │ ├── devtools-formatter-worker.ts │ │ ├── index.ts │ │ └── lighthouse-devtools-mcp-bundle.js │ ├── tools/ │ │ ├── ToolDefinition.ts │ │ ├── categories.ts │ │ ├── console.ts │ │ ├── emulation.ts │ │ ├── extensions.ts │ │ ├── input.ts │ │ ├── lighthouse.ts │ │ ├── memory.ts │ │ ├── network.ts │ │ ├── pages.ts │ │ ├── performance.ts │ │ ├── screencast.ts │ │ ├── screenshot.ts │ │ ├── script.ts │ │ ├── slim/ │ │ │ └── tools.ts │ │ ├── snapshot.ts │ │ └── tools.ts │ ├── trace-processing/ │ │ └── parse.ts │ ├── types.ts │ ├── utils/ │ │ ├── ExtensionRegistry.ts │ │ ├── files.ts │ │ ├── keyboard.ts │ │ ├── pagination.ts │ │ ├── string.ts │ │ └── types.ts │ └── version.ts ├── tests/ │ ├── DevtoolsUtils.test.ts │ ├── McpContext.test.js.snapshot │ ├── McpContext.test.ts │ ├── McpResponse.test.js.snapshot │ ├── McpResponse.test.ts │ ├── PageCollector.test.ts │ ├── browser.test.ts │ ├── cli.test.ts │ ├── daemon/ │ │ ├── client.test.ts │ │ └── utils.test.ts │ ├── e2e/ │ │ ├── chrome-devtools.test.ts │ │ └── telemetry.test.ts │ ├── formatters/ │ │ ├── ConsoleFormatter.test.js.snapshot │ │ ├── ConsoleFormatter.test.ts │ │ ├── IssueFormatter.test.js.snapshot │ │ ├── IssueFormatter.test.ts │ │ ├── NetworkFormatter.test.ts │ │ ├── snapshotFormatter.test.js.snapshot │ │ └── snapshotFormatter.test.ts │ ├── index.test.js.snapshot │ ├── index.test.ts │ ├── server.ts │ ├── setup.ts │ ├── snapshot.ts │ ├── telemetry/ │ │ ├── ClearcutLogger.test.ts │ │ ├── WatchdogClient.test.ts │ │ ├── flagUtils.test.ts │ │ ├── metricUtils.test.ts │ │ ├── persistence.test.ts │ │ └── watchdog/ │ │ └── ClearcutSender.test.ts │ ├── third_party_notices.test.js.snapshot │ ├── third_party_notices.test.ts │ ├── tools/ │ │ ├── console.test.js.snapshot │ │ ├── console.test.ts │ │ ├── emulation.test.ts │ │ ├── extensions.test.ts │ │ ├── fixtures/ │ │ │ ├── extension/ │ │ │ │ ├── manifest.json │ │ │ │ └── popup.html │ │ │ ├── extension-side-panel/ │ │ │ │ ├── manifest.json │ │ │ │ ├── sidepanel.html │ │ │ │ └── sw.js │ │ │ └── extension-sw/ │ │ │ ├── manifest.json │ │ │ ├── popup.html │ │ │ └── sw.js │ │ ├── input.test.ts │ │ ├── lighthouse.test.js.snapshot │ │ ├── lighthouse.test.ts │ │ ├── memory.test.ts │ │ ├── network.test.js.snapshot │ │ ├── network.test.ts │ │ ├── pages.test.js.snapshot │ │ ├── pages.test.ts │ │ ├── performance.test.js.snapshot │ │ ├── performance.test.ts │ │ ├── screencast.test.ts │ │ ├── screenshot.test.ts │ │ ├── script.test.ts │ │ ├── slim/ │ │ │ ├── tools.test.js.snapshot │ │ │ └── tools.test.ts │ │ └── snapshot.test.ts │ ├── trace-processing/ │ │ ├── fixtures/ │ │ │ └── load.ts │ │ ├── parse.test.js.snapshot │ │ └── parse.test.ts │ └── utils.ts └── tsconfig.json
Showing preview only (214K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (2193 symbols across 82 files)
FILE: rollup.config.mjs
function getPackageName (line 62) | function getPackageName(modulePath) {
function listBundledDeps (line 84) | function listBundledDeps() {
method template (line 159) | template(dependencies) {
FILE: scripts/append-lighthouse-notices.ts
constant ROOT_DIR (line 10) | const ROOT_DIR = process.cwd();
constant TARGET_DIR (line 11) | const TARGET_DIR = path.join(ROOT_DIR, 'build/src/third_party');
constant SOURCE_DIR (line 12) | const SOURCE_DIR = path.join(ROOT_DIR, 'src/third_party');
function main (line 14) | function main() {
FILE: scripts/eslint_rules/check-license-rule.js
method create (line 31) | create(context) {
FILE: scripts/eval_gemini.ts
constant ROOT_DIR (line 18) | const ROOT_DIR = path.resolve(import.meta.dirname, '..');
constant SCENARIOS_DIR (line 19) | const SCENARIOS_DIR = path.join(import.meta.dirname, 'eval_scenarios');
constant SKILL_PATH (line 20) | const SKILL_PATH = path.join(ROOT_DIR, 'skills', 'chrome-devtools', 'SKI...
type CapturedFunctionCall (line 23) | interface CapturedFunctionCall {
type TestScenario (line 28) | interface TestScenario {
function loadScenario (line 40) | async function loadScenario(scenarioPath: string): Promise<TestScenario> {
function runSingleScenario (line 50) | async function runSingleScenario(
function main (line 185) | async function main() {
FILE: scripts/eval_scenarios/fix_webpage_issues_test.ts
constant INSPECTION_TOOLS (line 21) | const INSPECTION_TOOLS = [
FILE: scripts/generate-cli.ts
constant OUTPUT_PATH (line 17) | const OUTPUT_PATH = path.join(
function fetchTools (line 22) | async function fetchTools() {
type CliOption (line 60) | interface CliOption {
type JsonSchema (line 69) | interface JsonSchema {
function schemaToCLIOptions (line 78) | function schemaToCLIOptions(schema: JsonSchema): CliOption[] {
function generateCli (line 103) | async function generateCli() {
FILE: scripts/generate-docs.ts
constant OUTPUT_PATH (line 19) | const OUTPUT_PATH = './docs/tool-reference.md';
constant SLIM_OUTPUT_PATH (line 20) | const SLIM_OUTPUT_PATH = './docs/slim-tool-reference.md';
constant README_PATH (line 21) | const README_PATH = './README.md';
function measureServer (line 23) | async function measureServer(args: string[]) {
type ToolWithAnnotations (line 60) | interface ToolWithAnnotations extends Tool {
type ZodCheck (line 68) | interface ZodCheck {
type ZodDef (line 72) | interface ZodDef {
type ZodSchema (line 82) | interface ZodSchema {
type TypeInfo (line 87) | interface TypeInfo {
function escapeHtmlTags (line 95) | function escapeHtmlTags(text: string): string {
function addCrossLinks (line 101) | function addCrossLinks(text: string, tools: ToolWithAnnotations[]): stri...
function generateToolsTOC (line 129) | function generateToolsTOC(
function updateReadmeWithToolsTOC (line 151) | function updateReadmeWithToolsTOC(toolsTOC: string): void {
function generateConfigOptionsMarkdown (line 174) | function generateConfigOptionsMarkdown(): string {
function updateReadmeWithOptionsMarkdown (line 218) | function updateReadmeWithOptionsMarkdown(optionsMarkdown: string): void {
function getZodTypeInfo (line 242) | function getZodTypeInfo(schema: ZodSchema): TypeInfo {
function isRequired (line 303) | function isRequired(schema: ZodSchema): boolean {
function generateReference (line 315) | async function generateReference(
function getToolsAndCategories (line 435) | function getToolsAndCategories(tools: any) {
function generateToolDocumentation (line 501) | async function generateToolDocumentation(): Promise<void> {
FILE: scripts/post-build.ts
constant BUILD_DIR (line 10) | const BUILD_DIR = path.join(process.cwd(), 'build');
function writeFile (line 17) | function writeFile(filePath: string, content: string): void {
function main (line 21) | function main(): void {
function copyDevToolsDescriptionFiles (line 99) | function copyDevToolsDescriptionFiles() {
FILE: scripts/prepare.ts
function removeConflictingGlobalDeclaration (line 25) | function removeConflictingGlobalDeclaration(): void {
function main (line 44) | async function main() {
FILE: scripts/test.mjs
function installChrome (line 62) | function installChrome(version) {
function runTests (line 75) | async function runTests(attempt) {
FILE: scripts/update-lighthouse.ts
constant ROOT_DIR (line 11) | const ROOT_DIR = process.cwd();
constant LIGHTHOUSE_DIR (line 12) | const LIGHTHOUSE_DIR = path.resolve(ROOT_DIR, '../lighthouse');
constant DEST_DIR (line 13) | const DEST_DIR = path.join(ROOT_DIR, 'src/third_party');
function main (line 15) | function main() {
FILE: scripts/verify-npm-package.mjs
function verifyPackageContents (line 10) | function verifyPackageContents() {
FILE: src/DevToolsConnectionAdapter.ts
class PuppeteerDevToolsConnection (line 19) | class PuppeteerDevToolsConnection
method constructor (line 29) | constructor(session: puppeteer.CDPSession) {
method send (line 44) | send<T extends DevTools.CDPConnection.Command>(
method observe (line 70) | observe(observer: DevTools.CDPConnection.CDPConnectionObserver): void {
method unobserve (line 74) | unobserve(observer: DevTools.CDPConnection.CDPConnectionObserver): void {
method #startForwardingCdpEvents (line 78) | #startForwardingCdpEvents(session: puppeteer.CDPSession): void {
method #stopForwardingCdpEvents (line 87) | #stopForwardingCdpEvents(session: puppeteer.CDPSession): void {
method #handleEvent (line 94) | #handleEvent(
FILE: src/DevtoolsUtils.ts
function extractUrlLikeFromDevToolsTitle (line 18) | function extractUrlLikeFromDevToolsTitle(
function urlsEqual (line 25) | function urlsEqual(url1: string, url2: string): boolean {
function normalizeUrl (line 43) | function normalizeUrl(url: string): string {
class FakeIssuesManager (line 77) | class FakeIssuesManager extends DevTools.Common.ObjectWrapper
method issues (line 79) | issues(): DevTools.Issue[] {
type TargetUniverse (line 103) | interface TargetUniverse {
type TargetUniverseFactoryFn (line 108) | type TargetUniverseFactoryFn = (page: Page) => Promise<TargetUniverse>;
class UniverseManager (line 110) | class UniverseManager {
method constructor (line 118) | constructor(
method init (line 126) | async init(pages: Page[]) {
method get (line 147) | get(page: Page): TargetUniverse | null {
method dispose (line 151) | dispose() {
constant SKIP_ALL_PAUSES (line 220) | const SKIP_ALL_PAUSES = {
method modelAdded (line 221) | modelAdded(model: DevTools.DebuggerModel): void {
method modelRemoved (line 225) | modelRemoved(): void {
class SymbolizedError (line 237) | class SymbolizedError {
method constructor (line 242) | private constructor(
method fromDetails (line 252) | static async fromDetails(opts: {
method fromError (line 310) | static async fromError(opts: {
method #getMessage (line 334) | static #getMessage(details: Protocol.Runtime.ExceptionDetails): string {
method #getMessageFromException (line 347) | static #getMessageFromException(
method #getExceptionDetails (line 354) | static async #getExceptionDetails(
method #lookupCause (line 375) | static async #lookupCause(
method createForTesting (line 399) | static createForTesting(
function createStackTraceForConsoleMessage (line 408) | async function createStackTraceForConsoleMessage(
function createStackTrace (line 423) | async function createStackTrace(
function waitForScript (line 477) | async function waitForScript(
FILE: src/McpContext.ts
type McpContextOptions (line 59) | interface McpContextOptions {
constant DEFAULT_TIMEOUT (line 68) | const DEFAULT_TIMEOUT = 5_000;
constant NAVIGATION_TIMEOUT (line 69) | const NAVIGATION_TIMEOUT = 10_000;
function getNetworkMultiplierFromString (line 71) | function getNetworkMultiplierFromString(condition: string | null): number {
class McpContext (line 88) | class McpContext implements Context {
method constructor (line 123) | private constructor(
method #init (line 152) | async #init() {
method dispose (line 160) | dispose() {
method from (line 174) | static async from(
method resolveCdpRequestId (line 186) | resolveCdpRequestId(page: McpPage, cdpRequestId: string): number | und...
method resolveCdpElementId (line 202) | resolveCdpElementId(
method getNetworkRequests (line 229) | getNetworkRequests(
method getConsoleData (line 239) | getConsoleData(
method getDevToolsUniverse (line 249) | getDevToolsUniverse(page: McpPage): TargetUniverse | null {
method getConsoleMessageStableId (line 253) | getConsoleMessageStableId(
method getConsoleMessageById (line 259) | getConsoleMessageById(
method newPage (line 266) | async newPage(
method closePage (line 287) | async closePage(pageId: number): Promise<void> {
method getNetworkRequestById (line 299) | getNetworkRequestById(page: McpPage, reqid: number): HTTPRequest {
method restoreEmulation (line 303) | async restoreEmulation(page: McpPage) {
method emulate (line 308) | async emulate(
method setIsRunningPerformanceTrace (line 401) | setIsRunningPerformanceTrace(x: boolean): void {
method isRunningPerformanceTrace (line 405) | isRunningPerformanceTrace(): boolean {
method getScreenRecorder (line 409) | getScreenRecorder(): {recorder: ScreenRecorder; filePath: string} | nu...
method setScreenRecorder (line 413) | setScreenRecorder(
method isCruxEnabled (line 419) | isCruxEnabled(): boolean {
method getSelectedPptrPage (line 423) | getSelectedPptrPage(): Page {
method getSelectedMcpPage (line 436) | getSelectedMcpPage(): McpPage {
method getPageById (line 441) | getPageById(pageId: number): McpPage {
method getPageId (line 449) | getPageId(page: Page): number | undefined {
method #getMcpPage (line 453) | #getMcpPage(page: Page): McpPage {
method #getSelectedMcpPage (line 461) | #getSelectedMcpPage(): McpPage {
method isPageSelected (line 465) | isPageSelected(page: Page): boolean {
method selectPage (line 469) | selectPage(newPage: McpPage): void {
method #updateSelectedPageTimeouts (line 474) | #updateSelectedPageTimeouts() {
method getAXNodeByUid (line 494) | getAXNodeByUid(uid: string) {
method createExtensionServiceWorkersSnapshot (line 507) | async createExtensionServiceWorkersSnapshot(): Promise<
method createPagesSnapshot (line 539) | async createPagesSnapshot(): Promise<Page[]> {
method #getAllPages (line 584) | async #getAllPages(): Promise<{
method detectOpenDevToolsWindows (line 653) | async detectOpenDevToolsWindows() {
method getExtensionServiceWorkers (line 689) | getExtensionServiceWorkers(): ExtensionServiceWorker[] {
method getExtensionServiceWorkerId (line 693) | getExtensionServiceWorkerId(
method getPages (line 699) | getPages(): Page[] {
method getIsolatedContextName (line 703) | getIsolatedContextName(page: Page): string | undefined {
method getDevToolsPage (line 707) | getDevToolsPage(page: Page): Page | undefined {
method getDevToolsData (line 711) | async getDevToolsData(page: McpPage): Promise<DevToolsData> {
method createTextSnapshot (line 747) | async createTextSnapshot(
method saveTemporaryFile (line 829) | async saveTemporaryFile(
method saveFile (line 835) | async saveFile(
method storeTraceRecording (line 850) | storeTraceRecording(result: TraceResult): void {
method recordedTraces (line 856) | recordedTraces(): TraceResult[] {
method getWaitForHelper (line 860) | getWaitForHelper(
method waitForEventsAfterAction (line 868) | waitForEventsAfterAction(
method getNetworkRequestStableId (line 885) | getNetworkRequestStableId(request: HTTPRequest): number {
method waitForTextOnPage (line 889) | waitForTextOnPage(
method setUpNetworkCollectorForTesting (line 916) | async setUpNetworkCollectorForTesting() {
method installExtension (line 931) | async installExtension(extensionPath: string): Promise<string> {
method uninstallExtension (line 937) | async uninstallExtension(id: string): Promise<void> {
method triggerExtensionAction (line 942) | async triggerExtensionAction(id: string): Promise<void> {
method listExtensions (line 959) | listExtensions(): InstalledExtension[] {
method getExtension (line 963) | getExtension(id: string): InstalledExtension | undefined {
FILE: src/McpPage.ts
class McpPage (line 30) | class McpPage implements ContextPage {
method constructor (line 49) | constructor(page: Page, id: number) {
method dialog (line 58) | get dialog(): Dialog | undefined {
method getDialog (line 62) | getDialog(): Dialog | undefined {
method clearDialog (line 66) | clearDialog(): void {
method networkConditions (line 70) | get networkConditions(): string | null {
method cpuThrottlingRate (line 74) | get cpuThrottlingRate(): number {
method geolocation (line 78) | get geolocation(): GeolocationOptions | null {
method viewport (line 82) | get viewport(): Viewport | null {
method userAgent (line 86) | get userAgent(): string | null {
method colorScheme (line 90) | get colorScheme(): 'dark' | 'light' | null {
method dispose (line 94) | dispose(): void {
method getElementByUid (line 98) | async getElementByUid(uid: string): Promise<ElementHandle<Element>> {
method #resolveElementHandle (line 111) | async #resolveElementHandle(
method getAXNodeByUid (line 129) | getAXNodeByUid(uid: string) {
FILE: src/McpResponse.ts
type TraceInsightData (line 37) | interface TraceInsightData {
class McpResponse (line 43) | class McpResponse implements Response {
method constructor (line 78) | constructor(args: ParsedArguments) {
method setPage (line 82) | setPage(page: McpPage): void {
method attachDevToolsData (line 86) | attachDevToolsData(data: DevToolsData): void {
method setTabId (line 90) | setTabId(tabId: string): void {
method setIncludePages (line 94) | setIncludePages(value: boolean): void {
method includeSnapshot (line 103) | includeSnapshot(params?: SnapshotParams): void {
method setListExtensions (line 109) | setListExtensions(): void {
method setIncludeNetworkRequests (line 113) | setIncludeNetworkRequests(
method setIncludeConsoleData (line 141) | setIncludeConsoleData(
method attachNetworkRequest (line 167) | attachNetworkRequest(
method attachConsoleMessage (line 175) | attachConsoleMessage(msgid: number): void {
method attachTraceSummary (line 179) | attachTraceSummary(result: TraceResult): void {
method attachTraceInsight (line 183) | attachTraceInsight(
method attachLighthouseResult (line 195) | attachLighthouseResult(result: LighthouseData): void {
method includePages (line 199) | get includePages(): boolean {
method attachedTraceSummary (line 203) | get attachedTraceSummary(): TraceResult | undefined {
method attachedTracedInsight (line 207) | get attachedTracedInsight(): TraceInsightData | undefined {
method attachedLighthouseResult (line 211) | get attachedLighthouseResult(): LighthouseData | undefined {
method includeNetworkRequests (line 215) | get includeNetworkRequests(): boolean {
method includeConsoleData (line 219) | get includeConsoleData(): boolean {
method attachedNetworkRequestId (line 222) | get attachedNetworkRequestId(): number | undefined {
method networkRequestsPageIdx (line 225) | get networkRequestsPageIdx(): number | undefined {
method consoleMessagesPageIdx (line 228) | get consoleMessagesPageIdx(): number | undefined {
method consoleMessagesTypes (line 231) | get consoleMessagesTypes(): string[] | undefined {
method appendResponseLine (line 235) | appendResponseLine(value: string): void {
method attachImage (line 239) | attachImage(value: ImageContentData): void {
method responseLines (line 243) | get responseLines(): readonly string[] {
method images (line 247) | get images(): ImageContentData[] {
method snapshotParams (line 251) | get snapshotParams(): SnapshotParams | undefined {
method handle (line 255) | async handle(
method format (line 465) | format(
method #dataWithPagination (line 791) | #dataWithPagination<T>(data: T[], pagination?: PaginationOptions) {
method resetResponseLineForTesting (line 826) | resetResponseLineForTesting() {
function createStructuredPage (line 830) | function createStructuredPage(page: Page, context: McpContext) {
FILE: src/Mutex.ts
class Mutex (line 7) | class Mutex {
method constructor (line 10) | constructor(mutex: Mutex) {
method dispose (line 13) | dispose(): void {
method acquire (line 22) | async acquire(): Promise<InstanceType<typeof Mutex.Guard>> {
method release (line 33) | release(): void {
FILE: src/PageCollector.ts
class UncaughtError (line 25) | class UncaughtError {
method constructor (line 29) | constructor(details: Protocol.Runtime.ExceptionDetails, targetId: stri...
type PageEvents (line 35) | interface PageEvents extends PuppeteerPageEvents {
type ListenerMap (line 40) | type ListenerMap<EventMap extends PageEvents = PageEvents> = {
function createIdGenerator (line 44) | function createIdGenerator() {
type WithSymbolId (line 55) | type WithSymbolId<T> = T & {
class PageCollector (line 59) | class PageCollector<T> {
method constructor (line 74) | constructor(
method init (line 82) | async init(pages: Page[]) {
method dispose (line 91) | dispose() {
method addPage (line 120) | public addPage(page: Page) {
method #initializePage (line 124) | #initializePage(page: Page) {
method splitAfterNavigation (line 155) | protected splitAfterNavigation(page: Page) {
method cleanupPageDestroyed (line 165) | protected cleanupPageDestroyed(page: Page) {
method getData (line 175) | getData(page: Page, includePreservedData?: boolean): T[] {
method getIdForResource (line 194) | getIdForResource(resource: WithSymbolId<T>): number {
method getById (line 198) | getById(page: Page, stableId: number): T {
method find (line 213) | find(
class ConsoleCollector (line 232) | class ConsoleCollector extends PageCollector<
method addPage (line 237) | override addPage(page: Page): void {
method cleanupPageDestroyed (line 246) | protected override cleanupPageDestroyed(page: Page): void {
class PageEventSubscriber (line 253) | class PageEventSubscriber {
method constructor (line 262) | constructor(page: Page) {
method #resetIssueAggregator (line 270) | #resetIssueAggregator() {
method subscribe (line 285) | async subscribe() {
method unsubscribe (line 297) | unsubscribe() {
class NetworkCollector (line 374) | class NetworkCollector extends PageCollector<HTTPRequest> {
method constructor (line 375) | constructor(
method splitAfterNavigation (line 389) | override splitAfterNavigation(page: Page) {
FILE: src/SlimMcpResponse.ts
class SlimMcpResponse (line 15) | class SlimMcpResponse extends McpResponse {
method handle (line 16) | override async handle(
FILE: src/WaitForHelper.ts
class WaitForHelper (line 10) | class WaitForHelper {
method constructor (line 18) | constructor(
method waitForStableDom (line 35) | async waitForStableDom(): Promise<void> {
method waitForNavigationStarted (line 84) | async waitForNavigationStarted() {
method timeout (line 116) | timeout(time: number): Promise<void> {
method waitForEventsAfterAction (line 126) | async waitForEventsAfterAction(
FILE: src/bin/chrome-devtools-cli-options.ts
type ArgDef (line 9) | interface ArgDef {
type Commands (line 17) | type Commands = Record<
FILE: src/bin/chrome-devtools-mcp-cli-options.ts
type ParsedArguments (line 259) | type ParsedArguments = ReturnType<typeof parseArguments>;
function parseArguments (line 261) | function parseArguments(version: string, argv = process.argv) {
FILE: src/bin/chrome-devtools.ts
function start (line 27) | async function start(args: string[]) {
FILE: src/bin/cliDefinitions.ts
type ArgDef (line 9) | interface ArgDef {
type Commands (line 17) | type Commands = Record<
FILE: src/browser.ts
function makeTargetFilter (line 23) | function makeTargetFilter(enableExtensions = false) {
function ensureBrowserConnected (line 46) | async function ensureBrowserConnected(options: {
type McpLaunchOptions (line 136) | interface McpLaunchOptions {
function detectDisplay (line 155) | function detectDisplay(): void {
function launch (line 173) | async function launch(options: McpLaunchOptions): Promise<Browser> {
function ensureBrowserLaunched (line 263) | async function ensureBrowserLaunched(
type Channel (line 273) | type Channel = 'stable' | 'canary' | 'beta' | 'dev';
FILE: src/daemon/client.ts
constant FILE_TIMEOUT (line 24) | const FILE_TIMEOUT = 10_000;
function waitForFile (line 29) | function waitForFile(filePath: string, removed = false) {
function startDaemon (line 70) | async function startDaemon(mcpArgs: string[] = []) {
constant SEND_COMMAND_TIMEOUT (line 95) | const SEND_COMMAND_TIMEOUT = 60_000;
function sendCommand (line 100) | async function sendCommand(
function stopDaemon (line 136) | async function stopDaemon() {
function handleResponse (line 149) | async function handleResponse(
FILE: src/daemon/daemon.ts
function setupMCPClient (line 53) | async function setupMCPClient() {
type McpContent (line 80) | interface McpContent {
type McpResult (line 85) | interface McpResult {
function handleRequest (line 89) | async function handleRequest(msg: DaemonMessage) {
function startSocketServer (line 144) | async function startSocketServer() {
function cleanup (line 194) | async function cleanup() {
FILE: src/daemon/types.ts
type DaemonMessage (line 7) | type DaemonMessage =
type DaemonResponse (line 20) | interface DaemonResponse {
FILE: src/daemon/utils.ts
constant DAEMON_SCRIPT_PATH (line 15) | const DAEMON_SCRIPT_PATH = path.join(import.meta.dirname, 'daemon.js');
constant INDEX_SCRIPT_PATH (line 16) | const INDEX_SCRIPT_PATH = path.join(
constant APP_NAME (line 23) | const APP_NAME = 'chrome-devtools-mcp';
function getSocketPath (line 26) | function getSocketPath(): string {
function getRuntimeHome (line 46) | function getRuntimeHome(): string {
constant IS_WINDOWS (line 65) | const IS_WINDOWS = os.platform() === 'win32';
function getPidFilePath (line 67) | function getPidFilePath() {
function getDaemonPid (line 72) | function getDaemonPid() {
function isDaemonRunning (line 91) | function isDaemonRunning(pid = getDaemonPid()): pid is number {
function serializeArgs (line 103) | function serializeArgs(
FILE: src/devtools.d.ts
type CSSInJS (line 7) | type CSSInJS = string & {_tag: 'CSS-in-JS'};
FILE: src/formatters/ConsoleFormatter.ts
type ConsoleFormatterOptions (line 16) | interface ConsoleFormatterOptions {
type IgnoreCheck (line 26) | type IgnoreCheck = (
type ConsoleMessageConcise (line 30) | interface ConsoleMessageConcise {
type ConsoleMessageDetailed (line 37) | interface ConsoleMessageDetailed extends ConsoleMessageConcise {
class ConsoleFormatter (line 44) | class ConsoleFormatter {
method constructor (line 57) | private constructor(params: {
method from (line 77) | static async from(
method toString (line 174) | toString(): string {
method toStringDetailed (line 179) | toStringDetailed(): string {
method #getArgs (line 183) | #getArgs(): unknown[] {
method toJSON (line 195) | toJSON(): ConsoleMessageConcise {
method toJSONDetailed (line 204) | toJSONDetailed(): ConsoleMessageDetailed {
function convertConsoleMessageConciseToString (line 218) | function convertConsoleMessageConciseToString(msg: ConsoleMessageConcise) {
function convertConsoleMessageConciseDetailedToString (line 222) | function convertConsoleMessageConciseDetailedToString(
function formatArgs (line 234) | function formatArgs(msg: ConsoleMessageDetailed): string {
function formatArg (line 250) | function formatArg(arg: unknown, formatter: {isIgnored: IgnoreCheck}) {
constant STACK_TRACE_MAX_LINES (line 264) | const STACK_TRACE_MAX_LINES = 50;
function formatStackTrace (line 266) | function formatStackTrace(
function formatStackTraceInner (line 284) | function formatStackTraceInner(
function formatFragment (line 302) | function formatFragment(
function formatAsyncFragment (line 310) | function formatAsyncFragment(
function formatFrame (line 325) | function formatFrame(
function formatCause (line 338) | function formatCause(
FILE: src/formatters/IssueFormatter.ts
type IssueFormatterOptions (line 11) | interface IssueFormatterOptions {
type AffectedResource (line 17) | interface AffectedResource {
type IssueConcise (line 23) | interface IssueConcise {
type IssueDetailed (line 30) | interface IssueDetailed extends IssueConcise {
class IssueFormatter (line 39) | class IssueFormatter {
method constructor (line 43) | constructor(issue: DevTools.AggregatedIssue, options: IssueFormatterOp...
method toString (line 48) | toString(): string {
method toStringDetailed (line 52) | toStringDetailed(): string {
method toJSON (line 56) | toJSON(): IssueConcise {
method toJSONDetailed (line 65) | toJSONDetailed(): IssueDetailed {
method #getAffectedResources (line 77) | #getAffectedResources(): AffectedResource[] {
method isValid (line 150) | isValid(): boolean {
method #getTitle (line 155) | #getTitle(): string | undefined {
method #getDescription (line 193) | #getDescription(): string | undefined {
function convertIssueConciseToString (line 216) | function convertIssueConciseToString(issue: IssueConcise): string {
function convertIssueDetailedToString (line 220) | function convertIssueDetailedToString(issue: IssueDetailed): string {
FILE: src/formatters/NetworkFormatter.ts
constant BODY_CONTEXT_SIZE_LIMIT (line 11) | const BODY_CONTEXT_SIZE_LIMIT = 10000;
type NetworkFormatterOptions (line 13) | interface NetworkFormatterOptions {
type NetworkRequestConcise (line 26) | interface NetworkRequestConcise {
type NetworkRequestDetailed (line 34) | interface NetworkRequestDetailed extends NetworkRequestConcise {
class NetworkFormatter (line 45) | class NetworkFormatter {
method constructor (line 53) | private constructor(request: HTTPRequest, options: NetworkFormatterOpt...
method from (line 58) | static async from(
method #loadDetailedData (line 69) | async #loadDetailedData(): Promise<void> {
method toString (line 135) | toString(): string {
method toStringDetailed (line 139) | toStringDetailed(): string {
method toJSON (line 143) | toJSON(): NetworkRequestConcise {
method toJSONDetailed (line 153) | toJSONDetailed(): NetworkRequestDetailed {
method #getStatusFromRequest (line 181) | #getStatusFromRequest(request: HTTPRequest): string {
method #getFormattedResponseBody (line 195) | async #getFormattedResponseBody(
function getSizeLimitedString (line 219) | function getSizeLimitedString(text: string, sizeLimit: number) {
function convertNetworkRequestConciseToString (line 226) | function convertNetworkRequestConciseToString(
function formatHeadlers (line 233) | function formatHeadlers(headers: Record<string, string>): string[] {
function converNetworkRequestDetailedToStringDetailed (line 241) | function converNetworkRequestDetailedToStringDetailed(
FILE: src/formatters/SnapshotFormatter.ts
class SnapshotFormatter (line 9) | class SnapshotFormatter {
method constructor (line 12) | constructor(snapshot: TextSnapshot) {
method toString (line 16) | toString(): string {
method toJSON (line 34) | toJSON(): object {
method #formatNode (line 38) | #formatNode(node: TextSnapshotNode, depth = 0): string {
method #nodeToJSON (line 56) | #nodeToJSON(node: TextSnapshotNode): object {
method #getAttributes (line 66) | #getAttributes(serializedAXNodeRoot: TextSnapshotNode): string[] {
method #getAttributesMap (line 106) | #getAttributesMap(
method #extractedAttributes (line 128) | #extractedAttributes(node: TextSnapshotNode): Record<string, unknown> {
FILE: src/index.ts
function createMcpServer (line 31) | async function createMcpServer(
FILE: src/issue-descriptions.ts
constant DESCRIPTIONS_PATH (line 10) | const DESCRIPTIONS_PATH = path.join(
function loadIssueDescriptions (line 20) | async function loadIssueDescriptions(): Promise<void> {
function getIssueDescription (line 47) | function getIssueDescription(fileName: string): string | null {
constant ISSUE_UTILS (line 51) | const ISSUE_UTILS = {
FILE: src/logger.ts
function saveLogsToFile (line 18) | function saveLogsToFile(fileName: string): fs.WriteStream {
function flushLogs (line 34) | function flushLogs(
FILE: src/telemetry/ClearcutLogger.ts
constant MS_PER_DAY (line 16) | const MS_PER_DAY = 24 * 60 * 60 * 1000;
function detectOsType (line 18) | function detectOsType(): OsType {
class ClearcutLogger (line 31) | class ClearcutLogger {
method constructor (line 35) | constructor(options: {
method logToolInvocation (line 58) | async logToolInvocation(args: {
method logServerStart (line 75) | async logServerStart(flagUsage: FlagUsage): Promise<void> {
method logDailyActiveIfNeeded (line 86) | async logDailyActiveIfNeeded(): Promise<void> {
method #shouldLogDailyActive (line 116) | #shouldLogDailyActive(state: LocalState): boolean {
FILE: src/telemetry/WatchdogClient.ts
class WatchdogClient (line 14) | class WatchdogClient {
method constructor (line 17) | constructor(
method send (line 69) | send(message: WatchdogMessage): void {
FILE: src/telemetry/flagUtils.ts
type CliOptions (line 12) | type CliOptions = typeof cliOptions;
function computeFlagUsage (line 25) | function computeFlagUsage(
FILE: src/telemetry/metricUtils.ts
constant LATENCY_BUCKETS (line 7) | const LATENCY_BUCKETS = [50, 100, 250, 500, 1000, 2500, 5000, 10000];
function bucketizeLatency (line 9) | function bucketizeLatency(latencyMs: number): number {
FILE: src/telemetry/persistence.ts
type LocalState (line 14) | interface LocalState {
constant STATE_FILE_NAME (line 18) | const STATE_FILE_NAME = 'telemetry_state.json';
function getDataFolder (line 19) | function getDataFolder(): string {
type Persistence (line 40) | interface Persistence {
class FilePersistence (line 45) | class FilePersistence implements Persistence {
method constructor (line 48) | constructor(dataFolderOverride?: string) {
method loadState (line 52) | async loadState(): Promise<LocalState> {
method saveState (line 64) | async saveState(state: LocalState): Promise<void> {
FILE: src/telemetry/types.ts
type ChromeDevToolsMcpExtension (line 8) | interface ChromeDevToolsMcpExtension {
type ServerShutdown (line 19) | type ServerShutdown = Record<string, never>;
type ToolInvocation (line 21) | interface ToolInvocation {
type ServerStart (line 27) | interface ServerStart {
type DailyActive (line 31) | interface DailyActive {
type FlagUsage (line 35) | type FlagUsage = Record<string, boolean | string | number | undefined>;
type LogRequest (line 38) | interface LogRequest {
type LogResponse (line 50) | interface LogResponse {
type OsType (line 59) | enum OsType {
type ChromeChannel (line 66) | enum ChromeChannel {
type McpClient (line 74) | enum McpClient {
type WatchdogMessageType (line 82) | enum WatchdogMessageType {
type WatchdogMessage (line 86) | interface WatchdogMessage {
FILE: src/telemetry/watchdog/ClearcutSender.ts
type ClearcutSenderConfig (line 17) | interface ClearcutSenderConfig {
constant MAX_BUFFER_SIZE (line 25) | const MAX_BUFFER_SIZE = 1000;
constant DEFAULT_CLEARCUT_ENDPOINT (line 26) | const DEFAULT_CLEARCUT_ENDPOINT =
constant DEFAULT_FLUSH_INTERVAL_MS (line 28) | const DEFAULT_FLUSH_INTERVAL_MS = 15 * 60 * 1000;
constant LOG_SOURCE (line 30) | const LOG_SOURCE = 2839;
constant CLIENT_TYPE (line 31) | const CLIENT_TYPE = 47;
constant MIN_RATE_LIMIT_WAIT_MS (line 32) | const MIN_RATE_LIMIT_WAIT_MS = 30_000;
constant REQUEST_TIMEOUT_MS (line 33) | const REQUEST_TIMEOUT_MS = 30_000;
constant SHUTDOWN_TIMEOUT_MS (line 34) | const SHUTDOWN_TIMEOUT_MS = 5_000;
constant SESSION_ROTATION_INTERVAL_MS (line 35) | const SESSION_ROTATION_INTERVAL_MS = 24 * 60 * 60 * 1000;
type BufferedEvent (line 37) | interface BufferedEvent {
class ClearcutSender (line 42) | class ClearcutSender {
method constructor (line 55) | constructor(config: ClearcutSenderConfig) {
method enqueueEvent (line 67) | enqueueEvent(event: ChromeDevToolsMcpExtension): void {
method sendShutdownEvent (line 88) | async sendShutdownEvent(): Promise<void> {
method #flush (line 110) | async #flush(): Promise<void> {
method #addToBuffer (line 159) | #addToBuffer(event: ChromeDevToolsMcpExtension): void {
method #scheduleFlush (line 170) | #scheduleFlush(delayMs: number): void {
method #sendBatch (line 182) | async #sendBatch(events: BufferedEvent[]): Promise<{
method #finalFlush (line 238) | async #finalFlush(): Promise<void> {
method stopForTesting (line 246) | stopForTesting(): void {
method bufferSizeForTesting (line 254) | get bufferSizeForTesting(): number {
FILE: src/telemetry/watchdog/main.ts
type WatchdogArgs (line 18) | interface WatchdogArgs {
function parseWatchdogArgs (line 30) | function parseWatchdogArgs(): WatchdogArgs {
function main (line 78) | function main() {
FILE: src/third_party/lighthouse-devtools-mcp-bundle.js
method "build/process-global.js" (line 51) | "build/process-global.js"() {
method "types/lh.js" (line 59) | "types/lh.js"() {
method "core/gather/base-gatherer.js" (line 73) | "core/gather/base-gatherer.js"() {
method "lh-gatherer-shim:/Users/alexrudenko/src/lighthouse/core/gather/gatherers/trace.js" (line 138) | "lh-gatherer-shim:/Users/alexrudenko/src/lighthouse/core/gather/gatherer...
method "node_modules/debug/node_modules/ms/index.js" (line 159) | "node_modules/debug/node_modules/ms/index.js"(exports2, module2) {
method "node_modules/debug/src/common.js" (line 280) | "node_modules/debug/src/common.js"(exports2, module2) {
method "node_modules/debug/src/browser.js" (line 455) | "node_modules/debug/src/browser.js"(exports2, module2) {
method "node_modules/marky/lib/marky.cjs.js" (line 630) | "node_modules/marky/lib/marky.cjs.js"(exports2) {
method "lighthouse-logger/index.js" (line 737) | "lighthouse-logger/index.js"() {
method "node_modules/lodash-es/_freeGlobal.js" (line 982) | "node_modules/lodash-es/_freeGlobal.js"() {
method "node_modules/lodash-es/_root.js" (line 992) | "node_modules/lodash-es/_root.js"() {
method "node_modules/lodash-es/_Symbol.js" (line 1004) | "node_modules/lodash-es/_Symbol.js"() {
function getRawTag (line 1013) | function getRawTag(value) {
method "node_modules/lodash-es/_getRawTag.js" (line 1032) | "node_modules/lodash-es/_getRawTag.js"() {
function objectToString (line 1045) | function objectToString(value) {
method "node_modules/lodash-es/_objectToString.js" (line 1050) | "node_modules/lodash-es/_objectToString.js"() {
function baseGetTag (line 1060) | function baseGetTag(value) {
method "node_modules/lodash-es/_baseGetTag.js" (line 1068) | "node_modules/lodash-es/_baseGetTag.js"() {
function isObjectLike (line 1082) | function isObjectLike(value) {
method "node_modules/lodash-es/isObjectLike.js" (line 1087) | "node_modules/lodash-es/isObjectLike.js"() {
method "node_modules/lodash-es/isArray.js" (line 1097) | "node_modules/lodash-es/isArray.js"() {
function isObject (line 1105) | function isObject(value) {
method "node_modules/lodash-es/isObject.js" (line 1111) | "node_modules/lodash-es/isObject.js"() {
function isFunction (line 1119) | function isFunction(value) {
method "node_modules/lodash-es/isFunction.js" (line 1128) | "node_modules/lodash-es/isFunction.js"() {
method "node_modules/lodash-es/_coreJsData.js" (line 1144) | "node_modules/lodash-es/_coreJsData.js"() {
function isMasked (line 1153) | function isMasked(func) {
method "node_modules/lodash-es/_isMasked.js" (line 1158) | "node_modules/lodash-es/_isMasked.js"() {
function toSource (line 1171) | function toSource(func) {
method "node_modules/lodash-es/_toSource.js" (line 1186) | "node_modules/lodash-es/_toSource.js"() {
function baseIsNative (line 1196) | function baseIsNative(value) {
method "node_modules/lodash-es/_baseIsNative.js" (line 1205) | "node_modules/lodash-es/_baseIsNative.js"() {
function getValue (line 1226) | function getValue(object, key) {
method "node_modules/lodash-es/_getValue.js" (line 1231) | "node_modules/lodash-es/_getValue.js"() {
function getNative (line 1239) | function getNative(object, key) {
method "node_modules/lodash-es/_getNative.js" (line 1245) | "node_modules/lodash-es/_getNative.js"() {
method "node_modules/lodash-es/_WeakMap.js" (line 1257) | "node_modules/lodash-es/_WeakMap.js"() {
function isIndex (line 1267) | function isIndex(value, length) {
method "node_modules/lodash-es/_isIndex.js" (line 1274) | "node_modules/lodash-es/_isIndex.js"() {
function eq (line 1284) | function eq(value, other) {
method "node_modules/lodash-es/eq.js" (line 1289) | "node_modules/lodash-es/eq.js"() {
function isLength (line 1297) | function isLength(value) {
method "node_modules/lodash-es/isLength.js" (line 1302) | "node_modules/lodash-es/isLength.js"() {
function isArrayLike (line 1311) | function isArrayLike(value) {
method "node_modules/lodash-es/isArrayLike.js" (line 1316) | "node_modules/lodash-es/isArrayLike.js"() {
function isPrototype (line 1326) | function isPrototype(value) {
method "node_modules/lodash-es/_isPrototype.js" (line 1332) | "node_modules/lodash-es/_isPrototype.js"() {
function baseTimes (line 1341) | function baseTimes(n, iteratee) {
method "node_modules/lodash-es/_baseTimes.js" (line 1350) | "node_modules/lodash-es/_baseTimes.js"() {
function baseIsArguments (line 1358) | function baseIsArguments(value) {
method "node_modules/lodash-es/_baseIsArguments.js" (line 1363) | "node_modules/lodash-es/_baseIsArguments.js"() {
method "node_modules/lodash-es/isArguments.js" (line 1376) | "node_modules/lodash-es/isArguments.js"() {
function stubFalse (line 1393) | function stubFalse() {
method "node_modules/lodash-es/stubFalse.js" (line 1398) | "node_modules/lodash-es/stubFalse.js"() {
method "node_modules/lodash-es/isBuffer.js" (line 1408) | "node_modules/lodash-es/isBuffer.js"() {
function baseIsTypedArray (line 1423) | function baseIsTypedArray(value) {
method "node_modules/lodash-es/_baseIsTypedArray.js" (line 1428) | "node_modules/lodash-es/_baseIsTypedArray.js"() {
function baseUnary (line 1466) | function baseUnary(func) {
method "node_modules/lodash-es/_baseUnary.js" (line 1473) | "node_modules/lodash-es/_baseUnary.js"() {
method "node_modules/lodash-es/_nodeUtil.js" (line 1483) | "node_modules/lodash-es/_nodeUtil.js"() {
method "node_modules/lodash-es/isTypedArray.js" (line 1507) | "node_modules/lodash-es/isTypedArray.js"() {
function arrayLikeKeys (line 1519) | function arrayLikeKeys(value, inherited) {
method "node_modules/lodash-es/_arrayLikeKeys.js" (line 1534) | "node_modules/lodash-es/_arrayLikeKeys.js"() {
function overArg (line 1550) | function overArg(func, transform) {
method "node_modules/lodash-es/_overArg.js" (line 1557) | "node_modules/lodash-es/_overArg.js"() {
method "node_modules/lodash-es/_nativeKeys.js" (line 1567) | "node_modules/lodash-es/_nativeKeys.js"() {
function baseKeys (line 1576) | function baseKeys(object) {
method "node_modules/lodash-es/_baseKeys.js" (line 1590) | "node_modules/lodash-es/_baseKeys.js"() {
function keys (line 1602) | function keys(object) {
method "node_modules/lodash-es/keys.js" (line 1607) | "node_modules/lodash-es/keys.js"() {
method "node_modules/lodash-es/_nativeCreate.js" (line 1620) | "node_modules/lodash-es/_nativeCreate.js"() {
function hashClear (line 1629) | function hashClear() {
method "node_modules/lodash-es/_hashClear.js" (line 1635) | "node_modules/lodash-es/_hashClear.js"() {
function hashDelete (line 1644) | function hashDelete(key) {
method "node_modules/lodash-es/_hashDelete.js" (line 1651) | "node_modules/lodash-es/_hashDelete.js"() {
function hashGet (line 1659) | function hashGet(key) {
method "node_modules/lodash-es/_hashGet.js" (line 1669) | "node_modules/lodash-es/_hashGet.js"() {
function hashHas (line 1681) | function hashHas(key) {
method "node_modules/lodash-es/_hashHas.js" (line 1687) | "node_modules/lodash-es/_hashHas.js"() {
function hashSet (line 1698) | function hashSet(key, value) {
method "node_modules/lodash-es/_hashSet.js" (line 1706) | "node_modules/lodash-es/_hashSet.js"() {
function Hash (line 1716) | function Hash(entries) {
method "node_modules/lodash-es/_Hash.js" (line 1726) | "node_modules/lodash-es/_Hash.js"() {
function listCacheClear (line 1744) | function listCacheClear() {
method "node_modules/lodash-es/_listCacheClear.js" (line 1750) | "node_modules/lodash-es/_listCacheClear.js"() {
function assocIndexOf (line 1758) | function assocIndexOf(array, key) {
method "node_modules/lodash-es/_assocIndexOf.js" (line 1769) | "node_modules/lodash-es/_assocIndexOf.js"() {
function listCacheDelete (line 1778) | function listCacheDelete(key) {
method "node_modules/lodash-es/_listCacheDelete.js" (line 1794) | "node_modules/lodash-es/_listCacheDelete.js"() {
function listCacheGet (line 1805) | function listCacheGet(key) {
method "node_modules/lodash-es/_listCacheGet.js" (line 1811) | "node_modules/lodash-es/_listCacheGet.js"() {
function listCacheHas (line 1820) | function listCacheHas(key) {
method "node_modules/lodash-es/_listCacheHas.js" (line 1825) | "node_modules/lodash-es/_listCacheHas.js"() {
function listCacheSet (line 1834) | function listCacheSet(key, value) {
method "node_modules/lodash-es/_listCacheSet.js" (line 1846) | "node_modules/lodash-es/_listCacheSet.js"() {
function ListCache (line 1855) | function ListCache(entries) {
method "node_modules/lodash-es/_ListCache.js" (line 1865) | "node_modules/lodash-es/_ListCache.js"() {
method "node_modules/lodash-es/_Map.js" (line 1885) | "node_modules/lodash-es/_Map.js"() {
function mapCacheClear (line 1895) | function mapCacheClear() {
method "node_modules/lodash-es/_mapCacheClear.js" (line 1905) | "node_modules/lodash-es/_mapCacheClear.js"() {
function isKeyable (line 1916) | function isKeyable(value) {
method "node_modules/lodash-es/_isKeyable.js" (line 1922) | "node_modules/lodash-es/_isKeyable.js"() {
function getMapData (line 1930) | function getMapData(map, key) {
method "node_modules/lodash-es/_getMapData.js" (line 1936) | "node_modules/lodash-es/_getMapData.js"() {
function mapCacheDelete (line 1945) | function mapCacheDelete(key) {
method "node_modules/lodash-es/_mapCacheDelete.js" (line 1952) | "node_modules/lodash-es/_mapCacheDelete.js"() {
function mapCacheGet (line 1961) | function mapCacheGet(key) {
method "node_modules/lodash-es/_mapCacheGet.js" (line 1966) | "node_modules/lodash-es/_mapCacheGet.js"() {
function mapCacheHas (line 1975) | function mapCacheHas(key) {
method "node_modules/lodash-es/_mapCacheHas.js" (line 1980) | "node_modules/lodash-es/_mapCacheHas.js"() {
function mapCacheSet (line 1989) | function mapCacheSet(key, value) {
method "node_modules/lodash-es/_mapCacheSet.js" (line 1997) | "node_modules/lodash-es/_mapCacheSet.js"() {
function MapCache (line 2006) | function MapCache(entries) {
method "node_modules/lodash-es/_MapCache.js" (line 2016) | "node_modules/lodash-es/_MapCache.js"() {
function arrayPush (line 2034) | function arrayPush(array, values) {
method "node_modules/lodash-es/_arrayPush.js" (line 2043) | "node_modules/lodash-es/_arrayPush.js"() {
function stackClear (line 2051) | function stackClear() {
method "node_modules/lodash-es/_stackClear.js" (line 2057) | "node_modules/lodash-es/_stackClear.js"() {
function stackDelete (line 2066) | function stackDelete(key) {
method "node_modules/lodash-es/_stackDelete.js" (line 2073) | "node_modules/lodash-es/_stackDelete.js"() {
function stackGet (line 2081) | function stackGet(key) {
method "node_modules/lodash-es/_stackGet.js" (line 2086) | "node_modules/lodash-es/_stackGet.js"() {
function stackHas (line 2094) | function stackHas(key) {
method "node_modules/lodash-es/_stackHas.js" (line 2099) | "node_modules/lodash-es/_stackHas.js"() {
function stackSet (line 2107) | function stackSet(key, value) {
method "node_modules/lodash-es/_stackSet.js" (line 2124) | "node_modules/lodash-es/_stackSet.js"() {
function Stack (line 2136) | function Stack(entries) {
method "node_modules/lodash-es/_Stack.js" (line 2142) | "node_modules/lodash-es/_Stack.js"() {
function arrayFilter (line 2161) | function arrayFilter(array, predicate) {
method "node_modules/lodash-es/_arrayFilter.js" (line 2173) | "node_modules/lodash-es/_arrayFilter.js"() {
function stubArray (line 2181) | function stubArray() {
method "node_modules/lodash-es/stubArray.js" (line 2186) | "node_modules/lodash-es/stubArray.js"() {
method "node_modules/lodash-es/_getSymbols.js" (line 2196) | "node_modules/lodash-es/_getSymbols.js"() {
function baseGetAllKeys (line 2217) | function baseGetAllKeys(object, keysFunc, symbolsFunc) {
method "node_modules/lodash-es/_baseGetAllKeys.js" (line 2223) | "node_modules/lodash-es/_baseGetAllKeys.js"() {
function getAllKeys (line 2233) | function getAllKeys(object) {
method "node_modules/lodash-es/_getAllKeys.js" (line 2238) | "node_modules/lodash-es/_getAllKeys.js"() {
method "node_modules/lodash-es/_DataView.js" (line 2251) | "node_modules/lodash-es/_DataView.js"() {
method "node_modules/lodash-es/_Promise.js" (line 2263) | "node_modules/lodash-es/_Promise.js"() {
method "node_modules/lodash-es/_Set.js" (line 2275) | "node_modules/lodash-es/_Set.js"() {
method "node_modules/lodash-es/_getTag.js" (line 2287) | "node_modules/lodash-es/_getTag.js"() {
method "node_modules/lodash-es/_Uint8Array.js" (line 2335) | "node_modules/lodash-es/_Uint8Array.js"() {
function setCacheAdd (line 2344) | function setCacheAdd(value) {
method "node_modules/lodash-es/_setCacheAdd.js" (line 2350) | "node_modules/lodash-es/_setCacheAdd.js"() {
function setCacheHas (line 2359) | function setCacheHas(value) {
method "node_modules/lodash-es/_setCacheHas.js" (line 2364) | "node_modules/lodash-es/_setCacheHas.js"() {
function SetCache (line 2372) | function SetCache(values) {
method "node_modules/lodash-es/_SetCache.js" (line 2381) | "node_modules/lodash-es/_SetCache.js"() {
function arraySome (line 2394) | function arraySome(array, predicate) {
method "node_modules/lodash-es/_arraySome.js" (line 2405) | "node_modules/lodash-es/_arraySome.js"() {
function cacheHas (line 2413) | function cacheHas(cache, key) {
method "node_modules/lodash-es/_cacheHas.js" (line 2418) | "node_modules/lodash-es/_cacheHas.js"() {
function equalArrays (line 2426) | function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
method "node_modules/lodash-es/_equalArrays.js" (line 2471) | "node_modules/lodash-es/_equalArrays.js"() {
function mapToArray (line 2484) | function mapToArray(map) {
method "node_modules/lodash-es/_mapToArray.js" (line 2493) | "node_modules/lodash-es/_mapToArray.js"() {
function setToArray (line 2501) | function setToArray(set) {
method "node_modules/lodash-es/_setToArray.js" (line 2510) | "node_modules/lodash-es/_setToArray.js"() {
function equalByTag (line 2518) | function equalByTag(object, other, tag, bitmask, customizer, equalFunc, ...
method "node_modules/lodash-es/_equalByTag.js" (line 2566) | "node_modules/lodash-es/_equalByTag.js"() {
function equalObjects (line 2595) | function equalObjects(object, other, bitmask, customizer, equalFunc, sta...
method "node_modules/lodash-es/_equalObjects.js" (line 2640) | "node_modules/lodash-es/_equalObjects.js"() {
function baseIsEqualDeep (line 2652) | function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, ...
method "node_modules/lodash-es/_baseIsEqualDeep.js" (line 2684) | "node_modules/lodash-es/_baseIsEqualDeep.js"() {
function baseIsEqual (line 2706) | function baseIsEqual(value, other, bitmask, customizer, stack) {
method "node_modules/lodash-es/_baseIsEqual.js" (line 2717) | "node_modules/lodash-es/_baseIsEqual.js"() {
function isEqual (line 2727) | function isEqual(value, other) {
method "node_modules/lodash-es/isEqual.js" (line 2732) | "node_modules/lodash-es/isEqual.js"() {
method "node_modules/lodash-es/lodash.js" (line 2742) | "node_modules/lodash-es/lodash.js"() {
method "core/lib/lh-env.js" (line 2761) | "core/lib/lh-env.js"() {
function erf (line 2774) | function erf(x) {
function getLogNormalScore (line 2787) | function getLogNormalScore({ median, p10 }, value) {
method "shared/statistics.js" (line 2811) | "shared/statistics.js"() {
method "shared/util.js" (line 2831) | "shared/util.js"() {
method "core/audits/audit.js" (line 3197) | "core/audits/audit.js"() {
function __extends (line 3652) | function __extends(d, b) {
function __rest (line 3662) | function __rest(s, e) {
function __decorate (line 3673) | function __decorate(decorators, target, key, desc) {
function __param (line 3679) | function __param(paramIndex, decorator) {
function __esDecorate (line 3684) | function __esDecorate(ctor, descriptorIn, decorators, contextIn, initial...
function __runInitializers (line 3717) | function __runInitializers(thisArg, initializers, value) {
function __propKey (line 3724) | function __propKey(x) {
function __setFunctionName (line 3727) | function __setFunctionName(f, name, prefix) {
function __metadata (line 3731) | function __metadata(metadataKey, metadataValue) {
function __awaiter (line 3734) | function __awaiter(thisArg, _arguments, P, generator) {
function __generator (line 3765) | function __generator(thisArg, body) {
function __exportStar (line 3836) | function __exportStar(m, o) {
function __values (line 3839) | function __values(o) {
function __read (line 3850) | function __read(o, n) {
function __spread (line 3867) | function __spread() {
function __spreadArrays (line 3872) | function __spreadArrays() {
function __spreadArray (line 3879) | function __spreadArray(to, from, pack) {
function __await (line 3888) | function __await(v) {
function __asyncGenerator (line 3891) | function __asyncGenerator(thisArg, _arguments, generator) {
function __asyncDelegator (line 3930) | function __asyncDelegator(o) {
function __asyncValues (line 3944) | function __asyncValues(o) {
function __makeTemplateObject (line 3965) | function __makeTemplateObject(cooked, raw) {
function __importStar (line 3973) | function __importStar(mod2) {
function __importDefault (line 3982) | function __importDefault(mod2) {
function __classPrivateFieldGet (line 3985) | function __classPrivateFieldGet(receiver, state, kind, f) {
function __classPrivateFieldSet (line 3990) | function __classPrivateFieldSet(receiver, state, value, kind, f) {
function __classPrivateFieldIn (line 3996) | function __classPrivateFieldIn(state, receiver) {
function __addDisposableResource (line 4000) | function __addDisposableResource(env, value, async) {
function __disposeResources (line 4019) | function __disposeResources(env) {
method "node_modules/intl-messageformat/node_modules/tslib/tslib.es6.mjs" (line 4045) | "node_modules/intl-messageformat/node_modules/tslib/tslib.es6.mjs"() {
function __extends2 (line 4184) | function __extends2(d, b) {
function __rest2 (line 4194) | function __rest2(s, e) {
function __decorate2 (line 4205) | function __decorate2(decorators, target, key, desc) {
function __param2 (line 4211) | function __param2(paramIndex, decorator) {
function __esDecorate2 (line 4216) | function __esDecorate2(ctor, descriptorIn, decorators, contextIn, initia...
function __runInitializers2 (line 4249) | function __runInitializers2(thisArg, initializers, value) {
function __propKey2 (line 4256) | function __propKey2(x) {
function __setFunctionName2 (line 4259) | function __setFunctionName2(f, name, prefix) {
function __metadata2 (line 4263) | function __metadata2(metadataKey, metadataValue) {
function __awaiter2 (line 4266) | function __awaiter2(thisArg, _arguments, P, generator) {
function __generator2 (line 4297) | function __generator2(thisArg, body) {
function __exportStar2 (line 4368) | function __exportStar2(m, o) {
function __values2 (line 4371) | function __values2(o) {
function __read2 (line 4382) | function __read2(o, n) {
function __spread2 (line 4399) | function __spread2() {
function __spreadArrays2 (line 4404) | function __spreadArrays2() {
function __spreadArray2 (line 4411) | function __spreadArray2(to, from, pack) {
function __await2 (line 4420) | function __await2(v) {
function __asyncGenerator2 (line 4423) | function __asyncGenerator2(thisArg, _arguments, generator) {
function __asyncDelegator2 (line 4462) | function __asyncDelegator2(o) {
function __asyncValues2 (line 4476) | function __asyncValues2(o) {
function __makeTemplateObject2 (line 4497) | function __makeTemplateObject2(cooked, raw) {
function __importStar2 (line 4505) | function __importStar2(mod2) {
function __importDefault2 (line 4514) | function __importDefault2(mod2) {
function __classPrivateFieldGet2 (line 4517) | function __classPrivateFieldGet2(receiver, state, kind, f) {
function __classPrivateFieldSet2 (line 4522) | function __classPrivateFieldSet2(receiver, state, value, kind, f) {
function __classPrivateFieldIn2 (line 4528) | function __classPrivateFieldIn2(state, receiver) {
function __addDisposableResource2 (line 4532) | function __addDisposableResource2(env, value, async) {
function __disposeResources2 (line 4551) | function __disposeResources2(env) {
method "node_modules/@formatjs/icu-messageformat-parser/node_modules/tslib/tslib.es6.mjs" (line 4577) | "node_modules/@formatjs/icu-messageformat-parser/node_modules/tslib/tsli...
method "node_modules/@formatjs/icu-messageformat-parser/error.js" (line 4682) | "node_modules/@formatjs/icu-messageformat-parser/error.js"(exports2) {
method "node_modules/@formatjs/icu-messageformat-parser/types.js" (line 4721) | "node_modules/@formatjs/icu-messageformat-parser/types.js"(exports2) {
method "node_modules/@formatjs/icu-messageformat-parser/regex.generated.js" (line 4820) | "node_modules/@formatjs/icu-messageformat-parser/regex.generated.js"(exp...
function __extends3 (line 4866) | function __extends3(d, b) {
function __rest3 (line 4876) | function __rest3(s, e) {
function __decorate3 (line 4887) | function __decorate3(decorators, target, key, desc) {
function __param3 (line 4893) | function __param3(paramIndex, decorator) {
function __esDecorate3 (line 4898) | function __esDecorate3(ctor, descriptorIn, decorators, contextIn, initia...
function __runInitializers3 (line 4931) | function __runInitializers3(thisArg, initializers, value) {
function __propKey3 (line 4938) | function __propKey3(x) {
function __setFunctionName3 (line 4941) | function __setFunctionName3(f, name, prefix) {
function __metadata3 (line 4945) | function __metadata3(metadataKey, metadataValue) {
function __awaiter3 (line 4948) | function __awaiter3(thisArg, _arguments, P, generator) {
function __generator3 (line 4979) | function __generator3(thisArg, body) {
function __exportStar3 (line 5050) | function __exportStar3(m, o) {
function __values3 (line 5053) | function __values3(o) {
function __read3 (line 5064) | function __read3(o, n) {
function __spread3 (line 5081) | function __spread3() {
function __spreadArrays3 (line 5086) | function __spreadArrays3() {
function __spreadArray3 (line 5093) | function __spreadArray3(to, from, pack) {
function __await3 (line 5102) | function __await3(v) {
function __asyncGenerator3 (line 5105) | function __asyncGenerator3(thisArg, _arguments, generator) {
function __asyncDelegator3 (line 5144) | function __asyncDelegator3(o) {
function __asyncValues3 (line 5158) | function __asyncValues3(o) {
function __makeTemplateObject3 (line 5179) | function __makeTemplateObject3(cooked, raw) {
function __importStar3 (line 5187) | function __importStar3(mod2) {
function __importDefault3 (line 5196) | function __importDefault3(mod2) {
function __classPrivateFieldGet3 (line 5199) | function __classPrivateFieldGet3(receiver, state, kind, f) {
function __classPrivateFieldSet3 (line 5204) | function __classPrivateFieldSet3(receiver, state, value, kind, f) {
function __classPrivateFieldIn3 (line 5210) | function __classPrivateFieldIn3(state, receiver) {
function __addDisposableResource3 (line 5214) | function __addDisposableResource3(env, value, async) {
function __disposeResources3 (line 5233) | function __disposeResources3(env) {
method "node_modules/@formatjs/icu-skeleton-parser/node_modules/tslib/tslib.es6.mjs" (line 5259) | "node_modules/@formatjs/icu-skeleton-parser/node_modules/tslib/tslib.es6...
method "node_modules/@formatjs/icu-skeleton-parser/date-time.js" (line 5364) | "node_modules/@formatjs/icu-skeleton-parser/date-time.js"(exports2) {
method "node_modules/@formatjs/icu-skeleton-parser/regex.generated.js" (line 5492) | "node_modules/@formatjs/icu-skeleton-parser/regex.generated.js"(exports2) {
method "node_modules/@formatjs/icu-skeleton-parser/number.js" (line 5503) | "node_modules/@formatjs/icu-skeleton-parser/number.js"(exports2) {
method "node_modules/@formatjs/icu-skeleton-parser/index.js" (line 5790) | "node_modules/@formatjs/icu-skeleton-parser/index.js"(exports2) {
method "node_modules/@formatjs/icu-messageformat-parser/time-data.generated.js" (line 5802) | "node_modules/@formatjs/icu-messageformat-parser/time-data.generated.js"...
method "node_modules/@formatjs/icu-messageformat-parser/date-time-pattern-generator.js" (line 7149) | "node_modules/@formatjs/icu-messageformat-parser/date-time-pattern-gener...
method "node_modules/@formatjs/icu-messageformat-parser/parser.js" (line 7223) | "node_modules/@formatjs/icu-messageformat-parser/parser.js"(exports2) {
method "node_modules/@formatjs/icu-messageformat-parser/index.js" (line 8058) | "node_modules/@formatjs/icu-messageformat-parser/index.js"(exports2) {
method "node_modules/@formatjs/fast-memoize/index.js" (line 8111) | "node_modules/@formatjs/fast-memoize/index.js"(exports2) {
method "node_modules/intl-messageformat/src/error.js" (line 8196) | "node_modules/intl-messageformat/src/error.js"(exports2) {
method "node_modules/intl-messageformat/src/formatters.js" (line 8267) | "node_modules/intl-messageformat/src/formatters.js"(exports2) {
method "node_modules/intl-messageformat/src/core.js" (line 8422) | "node_modules/intl-messageformat/src/core.js"(exports2) {
method "node_modules/intl-messageformat/index.js" (line 8660) | "node_modules/intl-messageformat/index.js"(exports2) {
method "replace-modules:module" (line 8676) | "replace-modules:module"() {
method "replace-modules:url" (line 8689) | "replace-modules:url"() {
function getModulePath (line 8698) | function getModulePath(importMeta) {
method "shared/esm-utils.js" (line 8702) | "shared/esm-utils.js"() {
function isObjectOfUnknownValues (line 8717) | function isObjectOfUnknownValues(val) {
function isObjectOrArrayOfUnknownValues (line 8720) | function isObjectOrArrayOfUnknownValues(val) {
method "shared/type-verifiers.js" (line 8724) | "shared/type-verifiers.js"() {
method "replace-modules:/Users/alexrudenko/src/lighthouse/shared/localization/locales.js" (line 8740) | "replace-modules:/Users/alexrudenko/src/lighthouse/shared/localization/l...
function collectAllCustomElementsFromICU (line 8747) | function collectAllCustomElementsFromICU(icuElements, customElements = /...
function _preformatValues (line 8759) | function _preformatValues(messageFormatter, values = {}, lhlMessage) {
function escapeIcuMessage (line 8794) | function escapeIcuMessage(message) {
function formatMessage (line 8797) | function formatMessage(message, values, locale) {
function _localizeIcuMessage (line 8811) | function _localizeIcuMessage(icuMessage, locale) {
function getRendererFormattedStrings (line 8819) | function getRendererFormattedStrings(locale) {
function isIcuMessage (line 8832) | function isIcuMessage(icuMessageOrNot) {
function getFormatted (line 8855) | function getFormatted(icuMessageOrRawString, locale) {
function _formatPathAsString (line 8864) | function _formatPathAsString(pathInLHR) {
function replaceIcuMessages (line 8877) | function replaceIcuMessages(inputObject, locale) {
function _getLocaleMessages (line 8901) | function _getLocaleMessages(locale) {
function getAvailableLocales (line 8911) | function getAvailableLocales() {
function getIcuMessageIdParts (line 8918) | function getIcuMessageIdParts(i18nMessageId) {
method "shared/localization/format.js" (line 8927) | "shared/localization/format.js"() {
method "node_modules/lighthouse-stack-packs/packs/amp.js" (line 8993) | "node_modules/lighthouse-stack-packs/packs/amp.js"(exports2, module2) {
method "node_modules/lighthouse-stack-packs/packs/angular.js" (line 9021) | "node_modules/lighthouse-stack-packs/packs/angular.js"(exports2, module2) {
method "node_modules/lighthouse-stack-packs/packs/drupal.js" (line 9049) | "node_modules/lighthouse-stack-packs/packs/drupal.js"(exports2, module2) {
method "node_modules/lighthouse-stack-packs/packs/ezoic.js" (line 9099) | "node_modules/lighthouse-stack-packs/packs/ezoic.js"(exports2, module2) {
method "node_modules/lighthouse-stack-packs/packs/gatsby.js" (line 9141) | "node_modules/lighthouse-stack-packs/packs/gatsby.js"(exports2, module2) {
method "node_modules/lighthouse-stack-packs/packs/joomla.js" (line 9175) | "node_modules/lighthouse-stack-packs/packs/joomla.js"(exports2, module2) {
method "node_modules/lighthouse-stack-packs/packs/magento.js" (line 9226) | "node_modules/lighthouse-stack-packs/packs/magento.js"(exports2, module2) {
method "node_modules/lighthouse-stack-packs/packs/next.js" (line 9266) | "node_modules/lighthouse-stack-packs/packs/next.js"(exports2, module2) {
method "node_modules/lighthouse-stack-packs/packs/nitropack.js" (line 9307) | "node_modules/lighthouse-stack-packs/packs/nitropack.js"(exports2, modul...
method "node_modules/lighthouse-stack-packs/packs/nuxt.js" (line 9349) | "node_modules/lighthouse-stack-packs/packs/nuxt.js"(exports2, module2) {
method "node_modules/lighthouse-stack-packs/packs/octobercms.js" (line 9377) | "node_modules/lighthouse-stack-packs/packs/octobercms.js"(exports2, modu...
method "node_modules/lighthouse-stack-packs/packs/react.js" (line 9421) | "node_modules/lighthouse-stack-packs/packs/react.js"(exports2, module2) {
method "node_modules/lighthouse-stack-packs/packs/wix.js" (line 9453) | "node_modules/lighthouse-stack-packs/packs/wix.js"(exports2, module2) {
method "node_modules/lighthouse-stack-packs/packs/wordpress.js" (line 9480) | "node_modules/lighthouse-stack-packs/packs/wordpress.js"(exports2, modul...
method "node_modules/lighthouse-stack-packs/packs/wp-rocket.js" (line 9524) | "node_modules/lighthouse-stack-packs/packs/wp-rocket.js"(exports2, modul...
method "node_modules/lighthouse-stack-packs/index.js" (line 9562) | "node_modules/lighthouse-stack-packs/index.js"(exports2, module2) {
method "node_modules/lookup-closest-locale/index.js" (line 9587) | "node_modules/lookup-closest-locale/index.js"(exports2, module2) {
method "shared/root.js" (line 9608) | "shared/root.js"() {
function lookupLocale (line 9853) | function lookupLocale(locales2, possibleLocales) {
function createIcuMessageFn (line 9873) | function createIcuMessageFn(filename, fileStrings = {}) {
function isStringOrIcuMessage (line 9891) | function isStringOrIcuMessage(value) {
method "core/lib/i18n/i18n.js" (line 9896) | "core/lib/i18n/i18n.js"() {
method "node_modules/@paulirish/trace_engine/models/trace/lantern/core/LanternError.js" (line 10016) | "node_modules/@paulirish/trace_engine/models/trace/lantern/core/LanternE...
method "node_modules/@paulirish/trace_engine/models/trace/lantern/core/NetworkAnalyzer.js" (line 10029) | "node_modules/@paulirish/trace_engine/models/trace/lantern/core/NetworkA...
method "node_modules/@paulirish/trace_engine/models/trace/lantern/core/core.js" (line 10480) | "node_modules/@paulirish/trace_engine/models/trace/lantern/core/core.js"...
method "node_modules/@paulirish/trace_engine/models/trace/lantern/graph/BaseNode.js" (line 10490) | "node_modules/@paulirish/trace_engine/models/trace/lantern/graph/BaseNod...
method "node_modules/@paulirish/trace_engine/models/trace/lantern/graph/CPUNode.js" (line 10743) | "node_modules/@paulirish/trace_engine/models/trace/lantern/graph/CPUNode...
function isNonNetworkProtocol (line 10811) | function isNonNetworkProtocol(protocol) {
method "node_modules/@paulirish/trace_engine/models/trace/lantern/graph/NetworkNode.js" (line 10817) | "node_modules/@paulirish/trace_engine/models/trace/lantern/graph/Network...
method "node_modules/@paulirish/trace_engine/models/trace/lantern/graph/PageDependencyGraph.js" (line 10895) | "node_modules/@paulirish/trace_engine/models/trace/lantern/graph/PageDep...
method "node_modules/@paulirish/trace_engine/models/trace/lantern/graph/graph.js" (line 11374) | "node_modules/@paulirish/trace_engine/models/trace/lantern/graph/graph.j...
method "node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/Metric.js" (line 11386) | "node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/Metri...
method "node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/FirstContentfulPaint.js" (line 11459) | "node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/First...
method "node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/Interactive.js" (line 11579) | "node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/Inter...
method "node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/LargestContentfulPaint.js" (line 11645) | "node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/Large...
method "node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/MaxPotentialFID.js" (line 11718) | "node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/MaxPo...
method "node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/SpeedIndex.js" (line 11768) | "node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/Speed...
function calculateTbtImpactForEvent (line 11867) | function calculateTbtImpactForEvent(event, startTimeMs, endTimeMs, topLe...
function calculateSumOfBlockingTime (line 11889) | function calculateSumOfBlockingTime(topLevelEvents, startTimeMs, endTime...
method "node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/TBTUtils.js" (line 11901) | "node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/TBTUt...
method "node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/TotalBlockingTime.js" (line 11912) | "node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/Total...
method "node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/metrics.js" (line 11996) | "node_modules/@paulirish/trace_engine/models/trace/lantern/metrics/metri...
method "node_modules/@paulirish/trace_engine/models/trace/lantern/simulation/TCPConnection.js" (line 12012) | "node_modules/@paulirish/trace_engine/models/trace/lantern/simulation/TC...
method "node_modules/@paulirish/trace_engine/models/trace/lantern/simulation/ConnectionPool.js" (line 12164) | "node_modules/@paulirish/trace_engine/models/trace/lantern/simulation/Co...
method "node_modules/@paulirish/trace_engine/models/trace/lantern/simulation/Constants.js" (line 12281) | "node_modules/@paulirish/trace_engine/models/trace/lantern/simulation/Co...
method "node_modules/@paulirish/trace_engine/models/trace/lantern/simulation/DNSCache.js" (line 12328) | "node_modules/@paulirish/trace_engine/models/trace/lantern/simulation/DN...
method "node_modules/@paulirish/trace_engine/models/trace/lantern/simulation/SimulationTimingMap.js" (line 12377) | "node_modules/@paulirish/trace_engine/models/trace/lantern/simulation/Si...
method "node_modules/@paulirish/trace_engine/models/trace/lantern/simulation/Simulator.js" (line 12510) | "node_modules/@paulirish/trace_engine/models/trace/lantern/simulation/Si...
method "node_modules/@paulirish/trace_engine/models/trace/lantern/simulation/simulation.js" (line 12929) | "node_modules/@paulirish/trace_engine/models/trace/lantern/simulation/si...
method "node_modules/@paulirish/trace_engine/models/trace/lantern/types/Lantern.js" (line 12943) | "node_modules/@paulirish/trace_engine/models/trace/lantern/types/Lantern...
method "node_modules/@paulirish/trace_engine/models/trace/lantern/types/types.js" (line 12975) | "node_modules/@paulirish/trace_engine/models/trace/lantern/types/types.j...
method "node_modules/@paulirish/trace_engine/models/trace/lantern/lantern.js" (line 12983) | "node_modules/@paulirish/trace_engine/models/trace/lantern/lantern.js"() {
method "node_modules/@paulirish/trace_engine/node_modules/third-party-web/lib/create-entity-finder-api.js" (line 12995) | "node_modules/@paulirish/trace_engine/node_modules/third-party-web/lib/c...
method "node_modules/@paulirish/trace_engine/node_modules/third-party-web/dist/entities.json" (line 13122) | "node_modules/@paulirish/trace_engine/node_modules/third-party-web/dist/...
method "node_modules/@paulirish/trace_engine/node_modules/third-party-web/lib/index.js" (line 13414) | "node_modules/@paulirish/trace_engine/node_modules/third-party-web/lib/i...
method "node_modules/@paulirish/trace_engine/third_party/third-party-web/third-party-web.js" (line 13425) | "node_modules/@paulirish/trace_engine/third_party/third-party-web/third-...
function configToCacheKey (line 13437) | function configToCacheKey(config3) {
method "node_modules/@paulirish/trace_engine/models/trace/types/Configuration.js" (line 13442) | "node_modules/@paulirish/trace_engine/models/trace/types/Configuration.j...
function isExtensionPayloadMarker (line 13465) | function isExtensionPayloadMarker(payload) {
function isExtensionEntryObj (line 13468) | function isExtensionEntryObj(payload) {
function isConsoleTimestampPayloadTrackEntry (line 13473) | function isConsoleTimestampPayloadTrackEntry(payload) {
function isValidExtensionPayload (line 13476) | function isValidExtensionPayload(payload) {
function isSyntheticExtensionEntry (line 13479) | function isSyntheticExtensionEntry(entry) {
method "node_modules/@paulirish/trace_engine/models/trace/types/Extensions.js" (line 13484) | "node_modules/@paulirish/trace_engine/models/trace/types/Extensions.js"() {
function isTimeRangeAnnotation (line 13518) | function isTimeRangeAnnotation(annotation) {
function isEntryLabelAnnotation (line 13521) | function isEntryLabelAnnotation(annotation) {
function isEntriesLinkAnnotation (line 13524) | function isEntriesLinkAnnotation(annotation) {
function traceEventKeyToValues (line 13527) | function traceEventKeyToValues(key) {
method "node_modules/@paulirish/trace_engine/models/trace/types/File.js" (line 13573) | "node_modules/@paulirish/trace_engine/models/trace/types/File.js"() {
method "node_modules/@paulirish/trace_engine/models/trace/types/Overlays.js" (line 13599) | "node_modules/@paulirish/trace_engine/models/trace/types/Overlays.js"() {
function Micro (line 13611) | function Micro(value) {
function Milli (line 13614) | function Milli(value) {
function Seconds (line 13617) | function Seconds(value) {
method "node_modules/@paulirish/trace_engine/models/trace/types/Timing.js" (line 13621) | "node_modules/@paulirish/trace_engine/models/trace/types/Timing.js"() {
function isNestableAsyncPhase (line 13801) | function isNestableAsyncPhase(phase) {
function isPhaseAsync (line 13804) | function isPhaseAsync(phase) {
function isFlowPhase (line 13807) | function isFlowPhase(phase) {
function objectIsCallFrame (line 13810) | function objectIsCallFrame(object) {
function isRunTask (line 13813) | function isRunTask(event) {
function isAuctionWorkletRunningInProcess (line 13816) | function isAuctionWorkletRunningInProcess(event) {
function isAuctionWorkletDoneWithProcess (line 13819) | function isAuctionWorkletDoneWithProcess(event) {
function isLegacyScreenshot (line 13822) | function isLegacyScreenshot(event) {
function isLegacySyntheticScreenshot (line 13825) | function isLegacySyntheticScreenshot(event) {
function isScreenshot (line 13828) | function isScreenshot(event) {
function isMarkerEvent (line 13831) | function isMarkerEvent(event) {
function eventIsPageLoadEvent (line 13837) | function eventIsPageLoadEvent(event) {
function isTracingSessionIdForWorker (line 13843) | function isTracingSessionIdForWorker(event) {
function isScheduleStyleInvalidationTracking (line 13846) | function isScheduleStyleInvalidationTracking(event) {
function isStyleRecalcInvalidationTracking (line 13849) | function isStyleRecalcInvalidationTracking(event) {
function isStyleInvalidatorInvalidationTracking (line 13852) | function isStyleInvalidatorInvalidationTracking(event) {
function isBeginCommitCompositorFrame (line 13855) | function isBeginCommitCompositorFrame(event) {
function isParseMetaViewport (line 13858) | function isParseMetaViewport(event) {
function isLinkPreconnect (line 13861) | function isLinkPreconnect(event) {
function isScheduleStyleRecalculation (line 13864) | function isScheduleStyleRecalculation(event) {
function isRenderFrameImplCreateChildFrame (line 13867) | function isRenderFrameImplCreateChildFrame(event) {
function isLayoutImageUnsized (line 13870) | function isLayoutImageUnsized(event) {
function isPairableAsyncBegin (line 13873) | function isPairableAsyncBegin(e) {
function isPairableAsyncEnd (line 13876) | function isPairableAsyncEnd(e) {
function isPairableAsyncInstant (line 13879) | function isPairableAsyncInstant(e) {
function isAnimationFrameAsyncStart (line 13882) | function isAnimationFrameAsyncStart(data31) {
function isAnimationFrameAsyncEnd (line 13885) | function isAnimationFrameAsyncEnd(data31) {
function isAnimationFramePresentation (line 13888) | function isAnimationFramePresentation(data31) {
function isPipelineReporter (line 13891) | function isPipelineReporter(event) {
function isSyntheticBased (line 13894) | function isSyntheticBased(event) {
function isSyntheticInteraction (line 13897) | function isSyntheticInteraction(event) {
function isDrawFrame (line 13900) | function isDrawFrame(event) {
function isBeginFrame (line 13903) | function isBeginFrame(event) {
function isDroppedFrame (line 13906) | function isDroppedFrame(event) {
function isRequestMainThreadFrame (line 13909) | function isRequestMainThreadFrame(event) {
function isBeginMainThreadFrame (line 13912) | function isBeginMainThreadFrame(event) {
function isNeedsBeginFrameChanged (line 13915) | function isNeedsBeginFrameChanged(event) {
function isCommit (line 13918) | function isCommit(event) {
function isRasterTask (line 13921) | function isRasterTask(event) {
function isCompositeLayers (line 13924) | function isCompositeLayers(event) {
function isActivateLayerTree (line 13927) | function isActivateLayerTree(event) {
function isInvalidationTracking (line 13930) | function isInvalidationTracking(event) {
function isDrawLazyPixelRef (line 13933) | function isDrawLazyPixelRef(event) {
function isDecodeLazyPixelRef (line 13936) | function isDecodeLazyPixelRef(event) {
function isDecodeImage (line 13939) | function isDecodeImage(event) {
function isSelectorStats (line 13942) | function isSelectorStats(event) {
function isRecalcStyle (line 13945) | function isRecalcStyle(event) {
function isLayout (line 13948) | function isLayout(event) {
function isInvalidateLayout (line 13951) | function isInvalidateLayout(event) {
function isDebuggerAsyncTaskScheduled (line 13954) | function isDebuggerAsyncTaskScheduled(event) {
function isDebuggerAsyncTaskRun (line 13957) | function isDebuggerAsyncTaskRun(event) {
function ProfileID (line 13960) | function ProfileID(value) {
function CallFrameID (line 13963) | function CallFrameID(value) {
function SampleIndex (line 13966) | function SampleIndex(value) {
function ProcessID (line 13969) | function ProcessID(value) {
function ThreadID (line 13972) | function ThreadID(value) {
function WorkerId (line 13975) | function WorkerId(value) {
function isComplete (line 13978) | function isComplete(event) {
function isBegin (line 13981) | function isBegin(event) {
function isEnd (line 13984) | function isEnd(event) {
function isDispatch (line 13987) | function isDispatch(event) {
function isInstant (line 13990) | function isInstant(event) {
function isRendererEvent (line 13993) | function isRendererEvent(event) {
function isFireIdleCallback (line 13996) | function isFireIdleCallback(event) {
function isSchedulePostMessage (line 13999) | function isSchedulePostMessage(event) {
function isHandlePostMessage (line 14002) | function isHandlePostMessage(event) {
function isUpdateCounters (line 14005) | function isUpdateCounters(event) {
function isDOMStats (line 14008) | function isDOMStats(event) {
function isThreadName (line 14011) | function isThreadName(event) {
function isProcessName (line 14014) | function isProcessName(event) {
function isTracingStartedInBrowser (line 14017) | function isTracingStartedInBrowser(event) {
function isFrameCommittedInBrowser (line 14020) | function isFrameCommittedInBrowser(event) {
function isCommitLoad (line 14023) | function isCommitLoad(event) {
function isAnimation (line 14026) | function isAnimation(event) {
function isSyntheticAnimation (line 14029) | function isSyntheticAnimation(event) {
function isLayoutShift (line 14039) | function isLayoutShift(event) {
function isLayoutInvalidationTracking (line 14042) | function isLayoutInvalidationTracking(event) {
function isFirstContentfulPaint (line 14045) | function isFirstContentfulPaint(event) {
function isLargestContentfulPaintCandidate (line 14048) | function isLargestContentfulPaintCandidate(event) {
function isLargestImagePaintCandidate (line 14051) | function isLargestImagePaintCandidate(event) {
function isLargestTextPaintCandidate (line 14054) | function isLargestTextPaintCandidate(event) {
function isMarkLoad (line 14057) | function isMarkLoad(event) {
function isFirstPaint (line 14060) | function isFirstPaint(event) {
function isMarkDOMContent (line 14063) | function isMarkDOMContent(event) {
function isInteractiveTime (line 14066) | function isInteractiveTime(event) {
function isEventTiming (line 14069) | function isEventTiming(event) {
function isEventTimingEnd (line 14072) | function isEventTimingEnd(event) {
function isEventTimingStart (line 14075) | function isEventTimingStart(event) {
function isGPUTask (line 14078) | function isGPUTask(event) {
function isProfile (line 14081) | function isProfile(event) {
function isSyntheticCpuProfile (line 14084) | function isSyntheticCpuProfile(event) {
function isProfileChunk (line 14087) | function isProfileChunk(event) {
function isResourceChangePriority (line 14090) | function isResourceChangePriority(event) {
function isResourceSendRequest (line 14093) | function isResourceSendRequest(event) {
function isResourceReceiveResponse (line 14096) | function isResourceReceiveResponse(event) {
function isResourceMarkAsCached (line 14099) | function isResourceMarkAsCached(event) {
function isResourceFinish (line 14102) | function isResourceFinish(event) {
function isResourceWillSendRequest (line 14105) | function isResourceWillSendRequest(event) {
function isResourceReceivedData (line 14108) | function isResourceReceivedData(event) {
function isReceivedDataEvent (line 14111) | function isReceivedDataEvent(event) {
function isSyntheticNetworkRequest (line 14114) | function isSyntheticNetworkRequest(event) {
function isSyntheticWebSocketConnection (line 14117) | function isSyntheticWebSocketConnection(event) {
function isNetworkTrackEntry (line 14120) | function isNetworkTrackEntry(event) {
function isPrePaint (line 14123) | function isPrePaint(event) {
function isNavigationStart (line 14126) | function isNavigationStart(event) {
function isDidCommitSameDocumentNavigation (line 14129) | function isDidCommitSameDocumentNavigation(event) {
function isMainFrameViewport (line 14132) | function isMainFrameViewport(event) {
function isSyntheticUserTiming (line 14135) | function isSyntheticUserTiming(event) {
function isSyntheticConsoleTiming (line 14145) | function isSyntheticConsoleTiming(event) {
function isUserTiming (line 14155) | function isUserTiming(event) {
function isDomLoading (line 14158) | function isDomLoading(event) {
function isBeginRemoteFontLoad (line 14161) | function isBeginRemoteFontLoad(event) {
function isRemoteFontLoaded (line 14164) | function isRemoteFontLoaded(event) {
function isPerformanceMeasure (line 14167) | function isPerformanceMeasure(event) {
function isPerformanceMeasureBegin (line 14170) | function isPerformanceMeasureBegin(event) {
function isPerformanceMark (line 14173) | function isPerformanceMark(event) {
function isConsoleTime (line 14176) | function isConsoleTime(event) {
function isConsoleTimeStamp (line 14179) | function isConsoleTimeStamp(event) {
function isUserTimingMeasure (line 14182) | function isUserTimingMeasure(event) {
function isParseHTML (line 14185) | function isParseHTML(event) {
function isSyntheticLayoutShift (line 14188) | function isSyntheticLayoutShift(event) {
function isSyntheticLayoutShiftCluster (line 14191) | function isSyntheticLayoutShiftCluster(event) {
function isProfileCall (line 14194) | function isProfileCall(event) {
function isPaint (line 14197) | function isPaint(event) {
function isPaintImage (line 14200) | function isPaintImage(event) {
function isScrollLayer (line 14203) | function isScrollLayer(event) {
function isSetLayerId (line 14206) | function isSetLayerId(event) {
function isUpdateLayer (line 14209) | function isUpdateLayer(event) {
function isDisplayListItemListSnapshot (line 14212) | function isDisplayListItemListSnapshot(event) {
function isLayerTreeHostImplSnapshot (line 14215) | function isLayerTreeHostImplSnapshot(event) {
function isFireAnimationFrame (line 14218) | function isFireAnimationFrame(event) {
function isTimerInstall (line 14221) | function isTimerInstall(event) {
function isTimerFire (line 14224) | function isTimerFire(event) {
function isRequestIdleCallback (line 14227) | function isRequestIdleCallback(event) {
function isWebSocketCreate (line 14230) | function isWebSocketCreate(event) {
function isWebSocketInfo (line 14233) | function isWebSocketInfo(event) {
function isWebSocketTransfer (line 14236) | function isWebSocketTransfer(event) {
function isWebSocketSendHandshakeRequest (line 14239) | function isWebSocketSendHandshakeRequest(event) {
function isWebSocketReceiveHandshakeResponse (line 14242) | function isWebSocketReceiveHandshakeResponse(event) {
function isWebSocketDestroy (line 14245) | function isWebSocketDestroy(event) {
function isWebSocketTraceEvent (line 14248) | function isWebSocketTraceEvent(event) {
function isWebSocketEvent (line 14251) | function isWebSocketEvent(event) {
function isV8Compile (line 14254) | function isV8Compile(event) {
function isFunctionCall (line 14257) | function isFunctionCall(event) {
function isSchedulePostTaskCallback (line 14260) | function isSchedulePostTaskCallback(event) {
function isRunPostTaskCallback (line 14263) | function isRunPostTaskCallback(event) {
function isAbortPostTaskCallback (line 14266) | function isAbortPostTaskCallback(event) {
function isJSInvocationEvent (line 14269) | function isJSInvocationEvent(event) {
function isConsoleRunTask (line 14289) | function isConsoleRunTask(event) {
function isFlowPhaseEvent (line 14292) | function isFlowPhaseEvent(event) {
function isParseAuthorStyleSheetEvent (line 14295) | function isParseAuthorStyleSheetEvent(event) {
function isLegacyTimelineFrame (line 14298) | function isLegacyTimelineFrame(data31) {
function isRundownScriptCompiled (line 14301) | function isRundownScriptCompiled(event) {
function isRundownScript (line 14304) | function isRundownScript(event) {
function isRundownScriptSource (line 14307) | function isRundownScriptSource(event) {
function isRundownScriptSourceLarge (line 14310) | function isRundownScriptSourceLarge(event) {
function isAnyScriptSourceEvent (line 14313) | function isAnyScriptSourceEvent(event) {
method "node_modules/@paulirish/trace_engine/models/trace/types/TraceEvents.js" (line 14318) | "node_modules/@paulirish/trace_engine/models/trace/types/TraceEvents.js"...
method "node_modules/@paulirish/trace_engine/models/trace/types/types.js" (line 14737) | "node_modules/@paulirish/trace_engine/models/trace/types/types.js"() {
function getEntityForEvent (line 14758) | function getEntityForEvent(event, entityMappings3) {
function getEntityForUrl (line 14765) | function getEntityForUrl(url, entityMappings3) {
function getNonResolvedURL (line 14776) | function getNonResolvedURL(entry, handlerData) {
function makeUpEntity (line 14814) | function makeUpEntity(entityCache, url) {
function getChromeExtensionOrigin (line 14842) | function getChromeExtensionOrigin(url) {
function makeUpChromeExtensionEntity (line 14845) | function makeUpChromeExtensionEntity(entityCache, url, extensionName) {
function addEventToEntityMapping (line 14868) | function addEventToEntityMapping(event, entityMappings3) {
function addNetworkRequestToEntityMapping (line 14884) | function addNetworkRequestToEntityMapping(networkRequest, entityMappings...
method "node_modules/@paulirish/trace_engine/models/trace/handlers/helpers.js" (line 14901) | "node_modules/@paulirish/trace_engine/models/trace/handlers/helpers.js"() {
function swap (line 14931) | function swap(array, i1, i2) {
function partition (line 14936) | function partition(array, comparator, left, right, pivotIndex) {
function quickSortRange (line 14949) | function quickSortRange(array, comparator, left, right, sortWindowLeft, ...
function sortRange (line 14962) | function sortRange(array, comparator, leftBound, rightBound, sortWindowL...
function mergeOrIntersect (line 14970) | function mergeOrIntersect(array1, array2, comparator, mergeNotIntersect) {
function lowerBound (line 14996) | function lowerBound(array, needle, comparator, left, right) {
function upperBound (line 15009) | function upperBound(array, needle, comparator, left, right) {
function nearestIndex (line 15022) | function nearestIndex(arr, predicate, searchStart) {
function nearestIndexFromBeginning (line 15049) | function nearestIndexFromBeginning(arr, predicate) {
function nearestIndexFromEnd (line 15057) | function nearestIndexFromEnd(arr, predicate) {
function arrayDoesNotContainNullOrUndefined (line 15065) | function arrayDoesNotContainNullOrUndefined(arr) {
method "node_modules/@paulirish/trace_engine/core/platform/ArrayUtilities.js" (line 15070) | "node_modules/@paulirish/trace_engine/core/platform/ArrayUtilities.js"() {
method "node_modules/@paulirish/trace_engine/core/platform/Brand.js" (line 15118) | "node_modules/@paulirish/trace_engine/core/platform/Brand.js"() {
method "node_modules/@paulirish/trace_engine/core/platform/Constructor.js" (line 15125) | "node_modules/@paulirish/trace_engine/core/platform/Constructor.js"() {
method "node_modules/@paulirish/trace_engine/core/platform/DateUtilities.js" (line 15132) | "node_modules/@paulirish/trace_engine/core/platform/DateUtilities.js"() {
method "node_modules/@paulirish/trace_engine/core/platform/DevToolsPath.js" (line 15139) | "node_modules/@paulirish/trace_engine/core/platform/DevToolsPath.js"() {
method "node_modules/@paulirish/trace_engine/core/platform/DOMUtilities.js" (line 15146) | "node_modules/@paulirish/trace_engine/core/platform/DOMUtilities.js"() {
method "node_modules/@paulirish/trace_engine/core/platform/KeyboardUtilities.js" (line 15153) | "node_modules/@paulirish/trace_engine/core/platform/KeyboardUtilities.js...
function getWithDefault (line 15165) | function getWithDefault(map, key, defaultValueFactory) {
method "node_modules/@paulirish/trace_engine/core/platform/MapUtilities.js" (line 15175) | "node_modules/@paulirish/trace_engine/core/platform/MapUtilities.js"() {
method "node_modules/@paulirish/trace_engine/core/platform/MimeType.js" (line 15250) | "node_modules/@paulirish/trace_engine/core/platform/MimeType.js"() {
method "node_modules/@paulirish/trace_engine/core/platform/NumberUtilities.js" (line 15268) | "node_modules/@paulirish/trace_engine/core/platform/NumberUtilities.js"() {
method "node_modules/@paulirish/trace_engine/core/platform/StringUtilities.js" (line 15332) | "node_modules/@paulirish/trace_engine/core/platform/StringUtilities.js"() {
method "node_modules/@paulirish/trace_engine/core/platform/Timing.js" (line 15339) | "node_modules/@paulirish/trace_engine/core/platform/Timing.js"() {
method "node_modules/@paulirish/trace_engine/core/platform/TypedArrayUtilities.js" (line 15346) | "node_modules/@paulirish/trace_engine/core/platform/TypedArrayUtilities....
function assertNotNullOrUndefined (line 15358) | function assertNotNullOrUndefined(val, message) {
function assertNever (line 15364) | function assertNever(_type, message) {
function assertUnhandled (line 15367) | function assertUnhandled(_caseVariable) {
method "node_modules/@paulirish/trace_engine/core/platform/TypescriptUtilities.js" (line 15371) | "node_modules/@paulirish/trace_engine/core/platform/TypescriptUtilities....
method "node_modules/@paulirish/trace_engine/core/platform/UIString.js" (line 15381) | "node_modules/@paulirish/trace_engine/core/platform/UIString.js"() {
method "node_modules/@paulirish/trace_engine/core/platform/UserVisibleError.js" (line 15388) | "node_modules/@paulirish/trace_engine/core/platform/UserVisibleError.js"...
method "node_modules/@paulirish/trace_engine/core/platform/platform.js" (line 15395) | "node_modules/@paulirish/trace_engine/core/platform/platform.js"() {
method "node_modules/@paulirish/trace_engine/models/trace/helpers/SyntheticEvents.js" (line 15424) | "node_modules/@paulirish/trace_engine/models/trace/helpers/SyntheticEven...
function timeStampForEventAdjustedByClosestNavigation (line 15523) | function timeStampForEventAdjustedByClosestNavigation(event, traceBounds...
function expandWindowByPercentOrToOneMillisecond (line 15538) | function expandWindowByPercentOrToOneMillisecond(annotationWindow, maxTr...
function eventTimingsMicroSeconds (line 15555) | function eventTimingsMicroSeconds(event) {
function eventTimingsMilliSeconds (line 15562) | function eventTimingsMilliSeconds(event) {
function traceWindowMilliSeconds (line 15569) | function traceWindowMilliSeconds(bounds) {
function traceWindowMicroSecondsToMilliSeconds (line 15576) | function traceWindowMicroSecondsToMilliSeconds(bounds) {
function traceWindowFromMilliSeconds (line 15583) | function traceWindowFromMilliSeconds(min, max) {
function traceWindowFromMicroSeconds (line 15591) | function traceWindowFromMicroSeconds(min, max) {
function traceWindowFromEvent (line 15599) | function traceWindowFromEvent(event) {
function traceWindowFromOverlay (line 15606) | function traceWindowFromOverlay(overlay) {
function combineTraceWindowsMicro (line 15642) | function combineTraceWindowsMicro(windows) {
function boundsIncludeTimeRange (line 15654) | function boundsIncludeTimeRange(data31) {
function eventIsInBounds (line 15659) | function eventIsInBounds(event, bounds) {
function timestampIsInBounds (line 15663) | function timestampIsInBounds(bounds, timestamp) {
function windowFitsInsideBounds (line 15666) | function windowFitsInsideBounds(data31) {
function windowsEqual (line 15669) | function windowsEqual(w1, w2) {
method "node_modules/@paulirish/trace_engine/models/trace/helpers/Timing.js" (line 15674) | "node_modules/@paulirish/trace_engine/models/trace/helpers/Timing.js"() {
function stackTraceInEvent (line 15737) | function stackTraceInEvent(event) {
function extractOriginFromTrace (line 15774) | function extractOriginFromTrace(firstNavigationURL) {
function addEventToProcessThread (line 15784) | function addEventToProcessThread(event, eventsInProcessThread2) {
function compareBeginAndEnd (line 15798) | function compareBeginAndEnd(aBeginTime, bBeginTime, aEndTime, bEndTime) {
function eventTimeComparator (line 15813) | function eventTimeComparator(a, b) {
function sortTraceEventsInPlace (line 15832) | function sortTraceEventsInPlace(events) {
function mergeEventsInOrder (line 15835) | function mergeEventsInOrder(eventsArray1, eventsArray2) {
function parseDevtoolsDetails (line 15860) | function parseDevtoolsDetails(timingDetail, key) {
function getNavigationForTraceEvent (line 15874) | function getNavigationForTraceEvent(event, eventFrameId, navigationsByFr...
function extractId (line 15885) | function extractId(event) {
function activeURLForFrameAtTime (line 15888) | function activeURLForFrameAtTime(frameId, time, rendererProcessesByFrame) {
function makeProfileCall (line 15903) | function makeProfileCall(node, profileId, sampleIndex, ts, pid, tid) {
function matchEvents (line 15919) | function matchEvents(unpairedEvents) {
function getSyntheticId (line 15981) | function getSyntheticId(event) {
function createSortedSyntheticEvents (line 15985) | function createSortedSyntheticEvents(matchedPairs) {
function createMatchedSortedSyntheticEvents (line 16030) | function createMatchedSortedSyntheticEvents(unpairedAsyncEvents2) {
function getZeroIndexedLineAndColumnForEvent (line 16035) | function getZeroIndexedLineAndColumnForEvent(event) {
function getZeroIndexedStackTraceInEventPayload (line 16062) | function getZeroIndexedStackTraceInEventPayload(event) {
function getStackTraceTopCallFrameInEventPayload (line 16083) | function getStackTraceTopCallFrameInEventPayload(event) {
function makeZeroBasedCallFrame (line 16104) | function makeZeroBasedCallFrame(callFrame) {
function getRawLineAndColumnNumbersForEvent (line 16110) | function getRawLineAndColumnNumbersForEvent(event) {
function frameIDForEvent (line 16127) | function frameIDForEvent(event) {
function isTopLevelEvent (line 16136) | function isTopLevelEvent(event) {
function isExtensionUrl (line 16139) | function isExtensionUrl(url) {
function topLevelEventIndexEndingAfter (line 16142) | function topLevelEventIndexEndingAfter(events, time) {
function findRecalcStyleEvents (line 16149) | function findRecalcStyleEvents(events, startTime, endTime) {
function findNextEventAfterTimestamp (line 16164) | function findNextEventAfterTimestamp(candidates, ts) {
function findPreviousEventBeforeTimestamp (line 16168) | function findPreviousEventBeforeTimestamp(candidates, ts) {
function forEachEvent (line 16172) | function forEachEvent(events, config3) {
function eventHasCategory (line 16216) | function eventHasCategory(event, category) {
function isMatchingCallFrame (line 16223) | function isMatchingCallFrame(eventFrame, nodeFrame) {
function eventContainsTimestamp (line 16226) | function eventContainsTimestamp(event, ts) {
function extractSampleTraceId (line 16229) | function extractSampleTraceId(event) {
method "node_modules/@paulirish/trace_engine/models/trace/helpers/Trace.js" (line 16241) | "node_modules/@paulirish/trace_engine/models/trace/helpers/Trace.js"() {
function treify (line 16394) | function treify(entries, options) {
function walkTreeFromEntry (line 16453) | function walkTreeFromEntry(entryToNode4, rootEntry, onEntryStart, onEntr...
function walkEntireTree (line 16460) | function walkEntireTree(entryToNode4, tree, onEntryStart, onEntryEnd, tr...
function walkTreeByNode (line 16465) | function walkTreeByNode(entryToNode4, rootNode, onEntryStart, onEntryEnd...
function treeNodeIsInWindow (line 16481) | function treeNodeIsInWindow(node, traceWindow) {
function canBuildTreesFromEvents (line 16484) | function canBuildTreesFromEvents(events) {
method "node_modules/@paulirish/trace_engine/models/trace/helpers/TreeHelpers.js" (line 16512) | "node_modules/@paulirish/trace_engine/models/trace/helpers/TreeHelpers.j...
function buildTrackDataFromExtensionEntries (line 16543) | function buildTrackDataFromExtensionEntries(extensionEntries, extensionT...
method "node_modules/@paulirish/trace_engine/models/trace/helpers/Extensions.js" (line 16572) | "node_modules/@paulirish/trace_engine/models/trace/helpers/Extensions.js...
function isSyntheticNetworkRequestEventRenderBlocking (line 16592) | function isSyntheticNetworkRequestEventRenderBlocking(event) {
function isSyntheticNetworkRequestHighPriority (line 16595) | function isSyntheticNetworkRequestHighPriority(event) {
function parseCacheControl (line 16598) | function parseCacheControl(header) {
function isSyntheticNetworkRequestLocalhost (line 16632) | function isSyntheticNetworkRequestLocalhost(event) {
method "node_modules/@paulirish/trace_engine/models/trace/helpers/Network.js" (line 16642) | "node_modules/@paulirish/trace_engine/models/trace/helpers/Network.js"() {
method "node_modules/@paulirish/trace_engine/models/trace/helpers/SamplesIntegrator.js" (line 16690) | "node_modules/@paulirish/trace_engine/models/trace/helpers/SamplesIntegr...
method "node_modules/@paulirish/trace_engine/models/trace/helpers/helpers.js" (line 17084) | "node_modules/@paulirish/trace_engine/models/trace/helpers/helpers.js"() {
function threadKey (line 17106) | function threadKey(data31) {
function reset (line 17109) | function reset() {
function handleUserConfig (line 17117) | function handleUserConfig(config3) {
function handleEvent (line 17120) | function handleEvent(event) {
function finalize (line 17138) | async function finalize() {
function data (line 17174) | function data() {
function deps (line 17180) | function deps() {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/AnimationFramesHandler.js" (line 17185) | "node_modules/@paulirish/trace_engine/models/trace/handlers/AnimationFra...
function reset2 (line 17213) | function reset2() {
function handleEvent2 (line 17217) | function handleEvent2(event) {
function finalize2 (line 17223) | async function finalize2() {
function data2 (line 17227) | function data2() {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/AnimationHandler.js" (line 17234) | "node_modules/@paulirish/trace_engine/models/trace/handlers/AnimationHan...
function reset3 (line 17255) | function reset3() {
function handleEvent3 (line 17263) | function handleEvent3(event) {
function processNonFlowEvent (line 17270) | function processNonFlowEvent(event) {
function processFlowEvent (line 17285) | function processFlowEvent(flowPhaseEvent) {
function addFlowIdToEventBinding (line 17312) | function addFlowIdToEventBinding(event, flowId) {
function flowGroupTokenForFlowPhaseEvent (line 17319) | function flowGroupTokenForFlowPhaseEvent(event) {
function finalize3 (line 17322) | async function finalize3() {
function data3 (line 17327) | function data3() {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/FlowsHandler.js" (line 17334) | "node_modules/@paulirish/trace_engine/models/trace/handlers/FlowsHandler...
function reset4 (line 17364) | function reset4() {
function handleEvent4 (line 17371) | function handleEvent4(event) {
function workletType (line 17390) | function workletType(input) {
function makeSyntheticEventBase (line 17400) | function makeSyntheticEventBase(event) {
function finalize4 (line 17415) | async function finalize4() {
function data4 (line 17459) | function data4() {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/AuctionWorkletsHandler.js" (line 17466) | "node_modules/@paulirish/trace_engine/models/trace/handlers/AuctionWorkl...
function makeNewTraceBounds (line 17492) | function makeNewTraceBounds() {
function reset5 (line 17499) | function reset5() {
function updateRendererProcessByFrame (line 17518) | function updateRendererProcessByFrame(event, frame) {
function handleEvent5 (line 17538) | function handleEvent5(event) {
function finalize5 (line 17667) | async function finalize5() {
function data5 (line 17709) | function data5() {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/MetaHandler.js" (line 17734) | "node_modules/@paulirish/trace_engine/models/trace/handlers/MetaHandler....
function storeTraceEventWithRequestId (line 17789) | function storeTraceEventWithRequestId(requestId, key, value) {
function firstPositiveValueInList (line 17805) | function firstPositiveValueInList(entries) {
function reset6 (line 17813) | function reset6() {
function handleEvent6 (line 17828) | function handleEvent6(event) {
function finalize6 (line 17883) | async function finalize6() {
function data6 (line 18102) | function data6() {
function deps2 (line 18117) | function deps2() {
function finalizeWebSocketData (line 18120) | function finalizeWebSocketData() {
function createSyntheticWebSocketConnection (line 18135) | function createSyntheticWebSocketConnection(startEvent, endEvent, firstR...
method "node_modules/@paulirish/trace_engine/models/trace/handlers/NetworkRequestsHandler.js" (line 18163) | "node_modules/@paulirish/trace_engine/models/trace/handlers/NetworkReque...
method "node_modules/@paulirish/trace_engine/models/cpu_profile/ProfileTreeModel.js" (line 18200) | "node_modules/@paulirish/trace_engine/models/cpu_profile/ProfileTreeMode...
method "node_modules/@paulirish/trace_engine/models/cpu_profile/CPUProfileDataModel.js" (line 18306) | "node_modules/@paulirish/trace_engine/models/cpu_profile/CPUProfileDataM...
method "node_modules/@paulirish/trace_engine/models/cpu_profile/cpu_profile.js" (line 18764) | "node_modules/@paulirish/trace_engine/models/cpu_profile/cpu_profile.js"...
function parseCPUProfileData (line 18780) | function parseCPUProfileData(parseOptions) {
function reset7 (line 18852) | function reset7() {
function handleEvent7 (line 18857) | function handleEvent7(event) {
function finalize7 (line 18915) | async function finalize7(parseOptions = {}) {
function data7 (line 18918) | function data7() {
function getOrCreatePreProcessedData (line 18924) | function getOrCreatePreProcessedData(processId, profileId) {
function getProfileCallFunctionName (line 18938) | function getProfileCallFunctionName(data31, entry) {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/SamplesHandler.js" (line 18948) | "node_modules/@paulirish/trace_engine/models/trace/handlers/SamplesHandl...
function handleUserConfig2 (line 18985) | function handleUserConfig2(userConfig) {
function reset8 (line 18988) | function reset8() {
function handleEvent8 (line 19000) | function handleEvent8(event) {
function finalize8 (line 19033) | async function finalize8() {
function data8 (line 19041) | function data8() {
function gatherCompositorThreads (line 19054) | function gatherCompositorThreads() {
function assignMeta (line 19063) | function assignMeta(processes2, mainFrameId2, rendererProcessesByFrame, ...
function assignOrigin (line 19068) | function assignOrigin(processes2, rendererProcessesByFrame) {
function assignIsMainFrame (line 19085) | function assignIsMainFrame(processes2, mainFrameId2, rendererProcessesBy...
function assignThreadName (line 19095) | function assignThreadName(processes2, threadsInProcess2) {
function sanitizeProcesses (line 19103) | function sanitizeProcesses(processes2) {
function sanitizeThreads (line 19121) | function sanitizeThreads(processes2) {
function buildHierarchy (line 19130) | function buildHierarchy(processes2, options) {
function makeCompleteEvent (line 19162) | function makeCompleteEvent(event) {
function deps3 (line 19183) | function deps3() {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/RendererHandler.js" (line 19188) | "node_modules/@paulirish/trace_engine/models/trace/handlers/RendererHand...
function reset9 (line 19254) | function reset9() {
function handleEvent9 (line 19260) | function handleEvent9(_) {
function finalize9 (line 19262) | async function finalize9() {
function findNearestJSAncestor (line 19296) | function findNearestJSAncestor(asyncTaskScheduled, entryToNode4) {
function acceptJSInvocationsPredicate (line 19306) | function acceptJSInvocationsPredicate(event) {
function findFirstJsInvocationForAsyncTaskRun (line 19311) | function findFirstJsInvocationForAsyncTaskRun(asyncTaskRun, entryToNode4) {
function findFirstJSCallsForAsyncTaskRun (line 19314) | function findFirstJSCallsForAsyncTaskRun(asyncTaskRun, entryToNode4) {
function findFirstDescendantsOfType (line 19317) | function findFirstDescendantsOfType(root2, entryToNode4, predicateAccept...
function data9 (line 19337) | function data9() {
function deps4 (line 19344) | function deps4() {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/AsyncJSCallsHandler.js" (line 19349) | "node_modules/@paulirish/trace_engine/models/trace/handlers/AsyncJSCalls...
function reset10 (line 19380) | function reset10() {
function handleEvent10 (line 19383) | function handleEvent10(event) {
function finalize10 (line 19390) | async function finalize10() {
function data10 (line 19392) | function data10() {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/DOMStatsHandler.js" (line 19397) | "node_modules/@paulirish/trace_engine/models/trace/handlers/DOMStatsHand...
function reset11 (line 19418) | function reset11() {
function getEventTimings (line 19426) | function getEventTimings(event) {
function getEventTrack (line 19438) | function getEventTrack(event) {
function userTimingComparator (line 19453) | function userTimingComparator(a, b, originalArray) {
function handleEvent11 (line 19469) | function handleEvent11(event) {
function finalize11 (line 19490) | async function finalize11() {
function data11 (line 19496) | function data11() {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/UserTimingsHandler.js" (line 19507) | "node_modules/@paulirish/trace_engine/models/trace/handlers/UserTimingsH...
function handleEvent12 (line 19579) | function handleEvent12(_event) {
function reset12 (line 19581) | function reset12() {
function finalize12 (line 19589) | async function finalize12() {
function createExtensionFlameChartEntries (line 19592) | function createExtensionFlameChartEntries() {
function extractConsoleAPIExtensionEntries (line 19601) | function extractConsoleAPIExtensionEntries() {
function extractPerformanceAPIExtensionEntries (line 19651) | function extractPerformanceAPIExtensionEntries(timings) {
function extensionDataInPerformanceTiming (line 19681) | function extensionDataInPerformanceTiming(timing) {
function extensionDataInConsoleTimeStamp (line 19695) | function extensionDataInConsoleTimeStamp(timeStamp) {
function data12 (line 19715) | function data12() {
function deps5 (line 19723) | function deps5() {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/ExtensionTraceDataHandler.js" (line 19728) | "node_modules/@paulirish/trace_engine/models/trace/handlers/ExtensionTra...
function reset13 (line 19761) | function reset13() {
function handleEvent13 (line 19770) | function handleEvent13(event) {
function finalize13 (line 19775) | async function finalize13() {
function data13 (line 19817) | function data13() {
function deps6 (line 19824) | function deps6() {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/LayerTreeHandler.js" (line 19829) | "node_modules/@paulirish/trace_engine/models/trace/handlers/LayerTreeHan...
function getThreadTypeForRendererThread (line 19856) | function getThreadTypeForRendererThread(pid, thread, auctionWorkletsData) {
function threadsInRenderer (line 19871) | function threadsInRenderer(rendererData, auctionWorkletsData) {
function threadsInTrace (line 19895) | function threadsInTrace(handlerData) {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/Threads.js" (line 19932) | "node_modules/@paulirish/trace_engine/models/trace/handlers/Threads.js"() {
function isFrameEvent (line 19964) | function isFrameEvent(event) {
function entryIsTopLevel (line 19971) | function entryIsTopLevel(entry) {
function reset14 (line 19975) | function reset14() {
function handleEvent14 (line 19979) | function handleEvent14(event) {
function finalize14 (line 19984) | async function finalize14() {
function data14 (line 19989) | function data14() {
function deps7 (line 19995) | function deps7() {
function framesWithinWindow (line 19998) | function framesWithinWindow(frames2, startTime, endTime) {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/FramesHandler.js" (line 20005) | "node_modules/@paulirish/trace_engine/models/trace/handlers/FramesHandle...
function reset15 (line 20414) | function reset15() {
function handleEvent15 (line 20418) | function handleEvent15(event) {
function finalize15 (line 20424) | async function finalize15() {
function data15 (line 20431) | function data15() {
function deps8 (line 20436) | function deps8() {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/GPUHandler.js" (line 20441) | "node_modules/@paulirish/trace_engine/models/trace/handlers/GPUHandler.j...
function reset16 (line 20464) | function reset16() {
function handleEvent16 (line 20473) | function handleEvent16(event) {
function finalize16 (line 20518) | async function finalize16(options) {
function data16 (line 20539) | function data16() {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/ImagePaintingHandler.js" (line 20550) | "node_modules/@paulirish/trace_engine/models/trace/handlers/ImagePaintin...
function reset17 (line 20578) | function reset17() {
function storeInitiator (line 20589) | function storeInitiator(data31) {
function handleEvent17 (line 20595) | function handleEvent17(event) {
function createRelationshipsFromFlows (line 20667) | function createRelationshipsFromFlows() {
function createRelationshipsFromAsyncJSCalls (line 20676) | function createRelationshipsFromAsyncJSCalls() {
function finalize17 (line 20684) | async function finalize17() {
function data17 (line 20688) | function data17() {
function deps9 (line 20694) | function deps9() {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/InitiatorsHandler.js" (line 20699) | "node_modules/@paulirish/trace_engine/models/trace/handlers/InitiatorsHa...
function reset18 (line 20734) | function reset18() {
function handleUserConfig3 (line 20738) | function handleUserConfig3(userConfig) {
function getState (line 20741) | function getState(frameId) {
function getFrameId (line 20755) | function getFrameId(event) {
function addInvalidationToEvent (line 20761) | function addInvalidationToEvent(frameState, event, invalidation) {
function handleEvent18 (line 20771) | function handleEvent18(event) {
function finalize18 (line 20819) | async function finalize18() {
function data18 (line 20821) | function data18() {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/InvalidationsHandler.js" (line 20839) | "node_modules/@paulirish/trace_engine/models/trace/handlers/Invalidation...
function reset19 (line 20873) | function reset19() {
function handleEvent19 (line 20879) | function handleEvent19(event) {
function storePageLoadMetricAgainstNavigationId (line 20885) | function storePageLoadMetricAgainstNavigationId(navigation2, event) {
function storeMetricScore (line 21003) | function storeMetricScore(frameId, navigationId, metricScore) {
function getFrameIdForPageLoadEvent (line 21009) | function getFrameIdForPageLoadEvent(event) {
function getNavigationForPageLoadEvent (line 21022) | function getNavigationForPageLoadEvent(event) {
function scoreClassificationForFirstContentfulPaint (line 21045) | function scoreClassificationForFirstContentfulPaint(fcpScoreInMicrosecon...
function scoreClassificationForTimeToInteractive (line 21057) | function scoreClassificationForTimeToInteractive(ttiTimeInMicroseconds) {
function scoreClassificationForLargestContentfulPaint (line 21069) | function scoreClassificationForLargestContentfulPaint(lcpTimeInMicroseco...
function scoreClassificationForDOMContentLoaded (line 21081) | function scoreClassificationForDOMContentLoaded(_dclTimeInMicroseconds) {
function scoreClassificationForTotalBlockingTime (line 21084) | function scoreClassificationForTotalBlockingTime(tbtTimeInMicroseconds) {
function gatherFinalLCPEvents (line 21096) | function gatherFinalLCPEvents() {
function finalize19 (line 21110) | async function finalize19() {
function data19 (line 21124) | function data19() {
function deps10 (line 21130) | function deps10() {
function metricIsLCP (line 21133) | function metricIsLCP(metric) {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/PageLoadMetricsHandler.js" (line 21138) | "node_modules/@paulirish/trace_engine/models/trace/handlers/PageLoadMetr...
function reset20 (line 21193) | function reset20() {
function handleEvent20 (line 21197) | function handleEvent20(event) {
function finalize20 (line 21204) | async function finalize20() {
function data20 (line 21243) | function data20() {
function deps11 (line 21246) | function deps11() {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/LargestImagePaintHandler.js" (line 21251) | "node_modules/@paulirish/trace_engine/models/trace/handlers/LargestImage...
function reset21 (line 21276) | function reset21() {
function handleEvent21 (line 21279) | function handleEvent21(event) {
function finalize21 (line 21288) | async function finalize21() {
function data21 (line 21290) | function data21() {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/LargestTextPaintHandler.js" (line 21295) | "node_modules/@paulirish/trace_engine/models/trace/handlers/LargestTextP...
function reset22 (line 21316) | function reset22() {
function handleEvent22 (line 21323) | function handleEvent22(event) {
function finalize22 (line 21332) | async function finalize22() {
function screenshotImageDataUri (line 21360) | function screenshotImageDataUri(event) {
function data22 (line 21366) | function data22() {
function deps12 (line 21372) | function deps12() {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/ScreenshotsHandler.js" (line 21377) | "node_modules/@paulirish/trace_engine/models/trace/handlers/ScreenshotsH...
function reset23 (line 21408) | function reset23() {
function handleEvent23 (line 21426) | function handleEvent23(event) {
function traceWindowFromTime (line 21472) | function traceWindowFromTime(time) {
function updateTraceWindowMax (line 21479) | function updateTraceWindowMax(traceWindow, newMax) {
function findScreenshots (line 21483) | function findScreenshots(timestamp) {
function buildScoreRecords (line 21497) | function buildScoreRecords() {
function collectNodes (line 21516) | function collectNodes() {
function finalize23 (line 21539) | async function finalize23() {
function buildLayoutShiftsClusters (line 21552) | async function buildLayoutShiftsClusters() {
function data23 (line 21702) | function data23() {
function deps13 (line 21721) | function deps13() {
function scoreClassificationForLayoutShift (line 21724) | function scoreClassificationForLayoutShift(score) {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/LayoutShiftsHandler.js" (line 21736) | "node_modules/@paulirish/trace_engine/models/trace/handlers/LayoutShifts...
function reset24 (line 21790) | function reset24() {
function handleEvent24 (line 21793) | function handleEvent24(event) {
function finalize24 (line 21800) | async function finalize24() {
function data24 (line 21802) | function data24() {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/MemoryHandler.js" (line 21807) | "node_modules/@paulirish/trace_engine/models/trace/handlers/MemoryHandle...
function reset25 (line 21827) | function reset25() {
function handleEvent25 (line 21830) | function handleEvent25(event) {
function finalize25 (line 21853) | async function finalize25() {
function data25 (line 21855) | function data25() {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/PageFramesHandler.js" (line 21862) | "node_modules/@paulirish/trace_engine/models/trace/handlers/PageFramesHa...
function completeURL (line 21883) | function completeURL(base, url) {
function deps14 (line 21893) | function deps14() {
function reset26 (line 21896) | function reset26() {
function handleEvent26 (line 21899) | function handleEvent26(event) {
function findFrame (line 21940) | function findFrame(meta, frameId) {
function findNetworkRequest (line 21949) | function findNetworkRequest(networkRequests, script) {
function computeMappingEndColumns (line 21955) | function computeMappingEndColumns(map) {
function computeGeneratedFileSizes (line 21967) | function computeGeneratedFileSizes(script) {
function getScriptGeneratedSizes (line 22015) | function getScriptGeneratedSizes(script) {
function findCachedRawSourceMap (line 22021) | function findCachedRawSourceMap(script, options) {
function finalize26 (line 22047) | async function finalize26(options) {
function data26 (line 22103) | function data26() {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/ScriptsHandler.js" (line 22110) | "node_modules/@paulirish/trace_engine/models/trace/handlers/ScriptsHandl...
function reset27 (line 22140) | function reset27() {
function handleEvent27 (line 22146) | function handleEvent27(event) {
function finalize27 (line 22186) | async function finalize27() {
function data27 (line 22188) | function data27() {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/SelectorStatsHandler.js" (line 22196) | "node_modules/@paulirish/trace_engine/models/trace/handlers/SelectorStat...
function reset28 (line 22223) | function reset28() {
function handleEvent28 (line 22232) | function handleEvent28(event) {
function categoryOfInteraction (line 22256) | function categoryOfInteraction(interaction) {
function removeNestedInteractionsAndSetProcessingTime (line 22265) | function removeNestedInteractionsAndSetProcessingTime(interactions) {
function writeSyntheticTimespans (line 22308) | function writeSyntheticTimespans(event) {
function finalize28 (line 22315) | async function finalize28() {
function data28 (line 22378) | function data28() {
function deps15 (line 22390) | function deps15() {
function scoreClassificationForInteractionToNextPaint (line 22393) | function scoreClassificationForInteractionToNextPaint(timing) {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/UserInteractionsHandler.js" (line 22404) | "node_modules/@paulirish/trace_engine/models/trace/handlers/UserInteract...
function reset29 (line 22455) | function reset29() {
function handleEvent29 (line 22460) | function handleEvent29(event) {
function finalize29 (line 22465) | async function finalize29() {
function data29 (line 22474) | function data29() {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/WorkersHandler.js" (line 22483) | "node_modules/@paulirish/trace_engine/models/trace/handlers/WorkersHandl...
function reset30 (line 22507) | function reset30() {
function storeWarning (line 22515) | function storeWarning(event, warning) {
function handleEvent30 (line 22523) | function handleEvent30(event) {
function processForcedReflowWarning (line 22540) | function processForcedReflowWarning(event) {
function accomodateEventInStack (line 22562) | function accomodateEventInStack(event, stack, pushEventToStack = true) {
function deps16 (line 22573) | function deps16() {
function finalize30 (line 22576) | async function finalize30() {
function data30 (line 22588) | function data30() {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/WarningsHandler.js" (line 22596) | "node_modules/@paulirish/trace_engine/models/trace/handlers/WarningsHand...
method "node_modules/@paulirish/trace_engine/models/trace/handlers/ModelHandlers.js" (line 22657) | "node_modules/@paulirish/trace_engine/models/trace/handlers/ModelHandler...
method "node_modules/@paulirish/trace_engine/models/trace/handlers/types.js" (line 22694) | "node_modules/@paulirish/trace_engine/models/trace/handlers/types.js"() {
method "node_modules/@paulirish/trace_engine/models/trace/handlers/handlers.js" (line 22701) | "node_modules/@paulirish/trace_engine/models/trace/handlers/handlers.js"...
method "node_modules/@paulirish/trace_engine/models/trace/EntityMapper.js" (line 22712) | "node_modules/@paulirish/trace_engine/models/trace/EntityMapper.js"() {
method "node_modules/@paulirish/trace_engine/models/trace/EventsSerializer.js" (line 22721) | "node_modules/@paulirish/trace_engine/models/trace/EventsSerializer.js"() {
function normalizeSource (line 22736) | function normalizeSource(source) {
function shouldIgnoreSource (line 22744) | function shouldIgnoreSource(source) {
function normalizeDuplication (line 22756) | function normalizeDuplication(duplication) {
function indexOfOrLength (line 22774) | function indexOfOrLength(haystack, needle, startPosition = 0) {
function getNodeModuleName (line 22778) | function getNodeModuleName(source) {
function groupByNodeModules (line 22787) | function groupByNodeModules(duplication) {
function sorted (line 22812) | function sorted(duplication) {
function computeScriptDuplication (line 22815) | function computeScriptDuplication(scriptsData, compressionRatios) {
method "node_modules/@paulirish/trace_engine/models/trace/extras/ScriptDuplication.js" (line 22869) | "node_modules/@paulirish/trace_engine/models/trace/extras/ScriptDuplicat...
function clearCacheForTrace (line 22892) | function clearCacheForTrace(data31) {
function get (line 22895) | function get(event, data31) {
function getForEvent (line 22926) | function getForEvent(event, data31) {
function addAsyncParentToStack (line 22970) | function addAsyncParentToStack(stackTrace, taskName) {
function getForExtensionEntry (line 22976) | function getForExtensionEntry(event, data31) {
function getForPerformanceMeasure (line 22986) | function getForPerformanceMeasure(event, data31) {
function isNativeJSFunction (line 22997) | function isNativeJSFunction({ columnNumber, lineNumber, url, scriptId }) {
function getTraceEventPayloadStackAsProtocolCallFrame (line 23000) | function getTraceEventPayloadStackAsProtocolCallFrame(event) {
method "node_modules/@paulirish/trace_engine/models/trace/extras/StackTraceForEvent.js" (line 23010) | "node_modules/@paulirish/trace_engine/models/trace/extras/StackTraceForE...
method "node_modules/@paulirish/trace_engine/models/trace/extras/TraceFilter.js" (line 23029) | "node_modules/@paulirish/trace_engine/models/trace/extras/TraceFilter.js...
function generateEventID (line 23079) | function generateEventID(event) {
method "node_modules/@paulirish/trace_engine/models/trace/extras/TraceTree.js" (line 23095) | "node_modules/@paulirish/trace_engine/models/trace/extras/TraceTree.js"() {
function collectMainThreadActivity (line 23450) | function collectMainThreadActivity(data31) {
function summarizeByThirdParty (line 23460) | function summarizeByThirdParty(data31, traceBounds2) {
function summarizeByURL (line 23470) | function summarizeByURL(data31, traceBounds2) {
function summarizeBottomUpByEntity (line 23479) | function summarizeBottomUpByEntity(root2, data31) {
function summarizeBottomUpByURL (line 23500) | function summarizeBottomUpByURL(root2, data31) {
function getBottomUpTree (line 23525) | function getBottomUpTree(mainThreadEvents, tracebounds, groupingFunction) {
method "node_modules/@paulirish/trace_engine/models/trace/extras/ThirdParties.js" (line 23542) | "node_modules/@paulirish/trace_engine/models/trace/extras/ThirdParties.j...
method "node_modules/@paulirish/trace_engine/models/trace/extras/extras.js" (line 23560) | "node_modules/@paulirish/trace_engine/models/trace/extras/extras.js"() {
function erf2 (line 23571) | function erf2(x) {
function getLogNormalScore2 (line 23584) | function getLogNormalScore2({ median, p10 }, value) {
function linearInterpolation (line 23614) | function linearInterpolation(x0, y0, x1, y1, x) {
method "node_modules/@paulirish/trace_engine/models/trace/insights/Statistics.js" (line 23620) | "node_modules/@paulirish/trace_engine/models/trace/insights/Statistics.j...
method "node_modules/@paulirish/trace_engine/models/trace/insights/types.js" (line 23640) | "node_modules/@paulirish/trace_engine/models/trace/insights/types.js"() {
function getInsight (line 23697) | function getInsight(insightName, insightSet) {
function getLCP (line 23704) | function getLCP(insightSet) {
function getINP (line 23712) | function getINP(insightSet) {
function getCLS (line 23720) | function getCLS(insightSet) {
function evaluateLCPMetricScore (line 23735) | function evaluateLCPMetricScore(value) {
function evaluateINPMetricScore (line 23738) | function evaluateINPMetricScore(value) {
function evaluateCLSMetricScore (line 23741) | function evaluateCLSMetricScore(value) {
function getPageResult (line 23744) | function getPageResult(cruxFieldData, url, origin, scope = null) {
function getMetricResult (line 23750) | function getMetricResult(pageResult, name, scope = null) {
function getMetricTimingResult (line 23770) | function getMetricTimingResult(pageResult, name, scope = null) {
function getFieldMetricsForInsightSet (line 23778) | function getFieldMetricsForInsightSet(insightSet, metadata, scope = null) {
function calculateMetricWeightsForSorting (line 23800) | function calculateMetricWeightsForSorting(insightSet, metadata) {
function estimateSavingsWithGraphs (line 23832) | function estimateSavingsWithGraphs(wastedBytesByRequestId, simulator, gr...
function metricSavingsForWastedBytes (line 23862) | function metricSavingsForWastedBytes(wastedBytesByRequestId, context) {
function isRequestCompressed (line 23877) | function isRequestCompressed(request) {
function isRequestServedFromBrowserCache (line 23890) | function isRequestServedFromBrowserCache(request) {
function getRequestSizes (line 23904) | function getRequestSizes(request) {
function estimateCompressedContentSize (line 23909) | function estimateCompressedContentSize(request, totalBytes, resourceType) {
function estimateCompressionRatioForScript (line 23932) | function estimateCompressionRatioForScript(script) {
function calculateDocFirstByteTs (line 23950) | function calculateDocFirstByteTs(docRequest) {
function insightBounds (line 23960) | function insightBounds(insight, insightSetBounds) {
method "node_modules/@paulirish/trace_engine/models/trace/insights/Common.js" (line 23971) | "node_modules/@paulirish/trace_engine/models/trace/insights/Common.js"() {
function finalize31 (line 24016) | function finalize31(partialModel) {
function isCacheable (line 24028) | function isCacheable(request) {
function computeCacheLifetimeInSeconds (line 24037) | function computeCacheLifetimeInSeconds(headers, cacheControl) {
function getCacheHitProbability (line 24051) | function getCacheHitProbability(maxAgeInSeconds) {
function getCombinedHeaders (line 24067) | function getCombinedHeaders(responseHeaders) {
function cachingDisabled (line 24079) | function cachingDisabled(headers, parsedCacheControl) {
function isCacheInsight (line 24090) | function isCacheInsight(model2) {
function generateInsight (line 24093) | function generateInsight(data31, context) {
function createOverlayForRequest (line 24138) | function createOverlayForRequest(request) {
function createOverlays (line 24145) | function createOverlays(model2) {
method "node_modules/@paulirish/trace_engine/models/trace/insights/Cache.js" (line 24150) | "node_modules/@paulirish/trace_engine/models/trace/insights/Cache.js"() {
function isInRootCauseWindow (line 24210) | function isInRootCauseWindow(event, targetEvent) {
function getNonCompositedFailure (line 24214) | function getNonCompositedFailure(animationEvent) {
function getNonCompositedFailureRootCauses (line 24235) | function getNonCompositedFailureRootCauses(animationEvents, prePaintEven...
function getShiftsByPrePaintEvents (line 24264) | function getShiftsByPrePaintEvents(layoutShifts, prePaintEvents2) {
function getNextEvent (line 24284) | function getNextEvent(sourceEvents, targetEvent) {
function getIframeRootCauses (line 24291) | function getIframeRootCauses(data31, iframeCreatedEvents, prePaintEvents...
function getUnsizedImageRootCauses (line 24323) | function getUnsizedImageRootCauses(unsizedImageEvents, paintImageEvents3...
function isCLSCulpritsInsight (line 24346) | function isCLSCulpritsInsight(insight) {
function getFontRootCauses (line 24349) | function getFontRootCauses(networkRequests, prePaintEvents2, shiftsByPre...
function getTopCulprits (line 24373) | function getTopCulprits(cluster, culpritsByShift) {
function finalize32 (line 24410) | function finalize32(partialModel) {
function generateInsight2 (line 24431) | function generateInsight2(data31, context) {
function createOverlays2 (line 24471) | function createOverlays2(model2) {
method "node_modules/@paulirish/trace_engine/models/trace/insights/CLSCulprits.js" (line 24495) | "node_modules/@paulirish/trace_engine/models/trace/insights/CLSCulprits....
function isDocumentLatencyInsight (line 24681) | function isDocumentLatencyInsight(x) {
function getServerResponseTime (line 24684) | function getServerResponseTime(request) {
function getCompressionSavings (line 24696) | function getCompressionSavings(request) {
function finalize33 (line 24739) | function finalize33(partialModel) {
function generateInsight3 (line 24755) | function generateInsight3(data31, context) {
function createOverlays3 (line 24812) | function createOverlays3(model2) {
method "node_modules/@paulirish/trace_engine/models/trace/insights/DocumentLatency.js" (line 24855) | "node_modules/@paulirish/trace_engine/models/trace/insights/DocumentLate...
function finalize34 (line 24933) | function finalize34(partialModel) {
function isDomSizeInsight (line 24947) | function isDomSizeInsight(model2) {
function generateInsight4 (line 24950) | function generateInsight4(data31, context) {
function createOverlays4 (line 25032) | function createOverlays4(model2) {
method "node_modules/@paulirish/trace_engine/models/trace/insights/DOMSize.js" (line 25042) | "node_modules/@paulirish/trace_engine/models/trace/insights/DOMSize.js"() {
function finalize35 (line 25120) | function finalize35(partialModel) {
function isDuplicatedJavaScriptInsight (line 25134) | function isDuplicatedJavaScriptInsight(model2) {
function generateInsight5 (line 25137) | function generateInsight5(data31, context) {
function createOverlays5 (line 25177) | function createOverlays5(model2) {
method "node_modules/@paulirish/trace_engine/models/trace/insights/DuplicatedJavaScript.js" (line 25188) | "node_modules/@paulirish/trace_engine/models/trace/insights/DuplicatedJa...
function finalize36 (line 25225) | function finalize36(partialModel) {
function isFontDisplayInsight (line 25237) | function isFontDisplayInsight(model2) {
function generateInsight6 (line 25240) | function generateInsight6(data31, context) {
function createOverlays6 (line 25276) | function createOverlays6(model2) {
method "node_modules/@paulirish/trace_engine/models/trace/insights/FontDisplay.js" (line 25285) | "node_modules/@paulirish/trace_engine/models/trace/insights/FontDisplay....
function getCallFrameId (line 25321) | function getCallFrameId(callFrame) {
function getLargestTopLevelFunctionData (line 25324) | function getLargestTopLevelFunctionData(forcedReflowEvents, traceParsedD...
function finalize37 (line 25372) | function finalize37(partialModel) {
function getBottomCallFrameForEvent (line 25384) | function getBottomCallFrameForEvent(event, traceParsedData) {
function isForcedReflowInsight (line 25389) | function isForcedReflowInsight(model2) {
function generateInsight7 (line 25392) | function generateInsight7(traceParsedData, context) {
function createOverlays7 (line 25420) | function createOverlays7(model2) {
function createOverlayForEvents (line 25430) | function createOverlayForEvents(events, outlineReason = "ERROR") {
method "node_modules/@paulirish/trace_engine/models/trace/insights/ForcedReflow.js" (line 25439) | "node_modules/@paulirish/trace_engine/models/trace/insights/ForcedReflow...
function isImageDeliveryInsight (line 25501) | function isImageDeliveryInsight(model2) {
function getOptimizationMessage (line 25504) | function getOptimizationMessage(optimization) {
function getOptimizationMessageWithBytes (line 25519) | function getOptimizationMessageWithBytes(optimization) {
function finalize38 (line 25524) | function finalize38(partialModel) {
function estimateGIFPercentSavings (line 25537) | function estimateGIFPercentSavings(request) {
function getDisplayedSize (line 25540) | function getDisplayedSize(data31, paintImage) {
function getPixelCounts (line 25546) | function getPixelCounts(data31, paintImage) {
function generateInsight8 (line 25553) | function generateInsight8(data31, context) {
function createOverlayForRequest2 (line 25642) | function createOverlayForRequest2(request) {
function createOverlays8 (line 25649) | function createOverlays8(model2) {
method "node_modules/@paulirish/trace_engine/models/trace/insights/ImageDelivery.js" (line 25654) | "node_modules/@paulirish/trace_engine/models/trace/insights/ImageDeliver...
function isINPBreakdownInsight (line 25740) | function isINPBreakdownInsight(insight) {
function finalize39 (line 25743) | function finalize39(partialModel) {
function generateInsight9 (line 25764) | function generateInsight9(data31, context) {
function createOverlaysForSubpart (line 25788) | function createOverlaysForSubpart(event, subpartIndex = -1) {
function createOverlays9 (line 25809) | function createOverlays9(model2) {
method "node_modules/@paulirish/trace_engine/models/trace/insights/INPBreakdown.js" (line 25818) | "node_modules/@paulirish/trace_engine/models/trace/insights/INPBreakdown...
function isLCPBreakdownInsight (line 25876) | function isLCPBreakdownInsight(model2) {
function anyValuesNaN (line 25879) | function anyValuesNaN(...values) {
function determineSubparts (line 25882) | function determineSubparts(nav, docRequest, lcpEvent, lcpRequest) {
function finalize40 (line 25915) | function finalize40(partialModel) {
function generateInsight10 (line 25944) | function generateInsight10(data31, context) {
function createOverlays10 (line 25977) | function createOverlays10(model2) {
method "node_modules/@paulirish/trace_engine/models/trace/insights/LCPBreakdown.js" (line 25994) | "node_modules/@paulirish/trace_engine/models/trace/insights/LCPBreakdown...
function isLCPDiscoveryInsight (line 26064) | function isLCPDiscoveryInsight(model2) {
function finalize41 (line 26067) | function finalize41(partialModel) {
function generateInsight11 (line 26084) | function generateInsight11(data31, context) {
function getImageData (line 26131) | function getImageData(model2) {
function createOverlays11 (line 26154) | function createOverlays11(model2) {
method "node_modules/@paulirish/trace_engine/models/trace/insights/LCPDiscovery.js" (line 26186) | "node_modules/@paulirish/trace_engine/models/trace/insights/LCPDiscovery...
function buildPolyfillExpression (line 26248) | function buildPolyfillExpression(object, property, coreJs3Module) {
function getCoreJsPolyfillData (line 26271) | function getCoreJsPolyfillData() {
function getPolyfillPatterns (line 26279) | function getPolyfillPatterns() {
function getTransformPatterns (line 26292) | function getTransformPatterns() {
function estimateWastedBytes (line 26354) | function estimateWastedBytes(content, matches) {
function detectLegacyJavaScript (line 26381) | function detectLegacyJavaScript(content, map) {
method "node_modules/legacy-javascript/legacy-javascript.js" (line 26410) | "node_modules/legacy-javascript/legacy-javascript.js"() {
method "node_modules/@paulirish/trace_engine/third_party/legacy-javascript/legacy-javascript.js" (line 27200) | "node_modules/@paulirish/trace_engine/third_party/legacy-javascript/lega...
function finalize42 (line 27215) | function finalize42(partialModel) {
function isLegacyJavaScript (line 27229) | function isLegacyJavaScript(model2) {
function generateInsight12 (line 27232) | function generateInsight12(data31, context) {
function createOverlays12 (line 27268) | function createOverlays12(model2) {
method "node_modules/@paulirish/trace_engine/models/trace/insights/LegacyJavaScript.js" (line 27279) | "node_modules/@paulirish/trace_engine/models/trace/insights/LegacyJavaSc...
function isModernHTTPInsight (line 27320) | function isModernHTTPInsight(model2) {
function isMultiplexableStaticAsset (line 27323) | function isMultiplexableStaticAsset(request, entityMappings3, firstParty...
function determineHttp1Requests (line 27340) | function determineHttp1Requests(requests, entityMappings3, firstPartyEnt...
function computeWasteWithGraph (line 27376) | function computeWasteWithGraph(urlsToChange, graph2, simulator) {
function computeMetricSavings (line 27403) | function computeMetricSavings(http1Requests, context) {
function finalize43 (line 27415) | function finalize43(partialModel) {
function generateInsight13 (line 27428) | function generateInsight13(data31, context) {
function createOverlayForRequest3 (line 27440) | function createOverlayForRequest3(request) {
function createOverlays13 (line 27447) | function createOverlays13(model2) {
method "node_modules/@paulirish/trace_engine/models/trace/insights/ModernHTTP.js" (line 27452) | "node_modules/@paulirish/trace_engine/models/trace/insights/ModernHTTP.j...
function finalize44 (line 27509) | function finalize44(partialModel) {
function isCritical (line 27521) | function isCritical(request, context) {
function findMaxLeafNode (line 27541) | function findMaxLeafNode(node) {
function sortRecursively (line 27554) | function sortRecursively(nodes) {
function generateNetworkDependencyTree (line 27566) | function generateNetworkDependencyTree(context) {
function getSecurityOrigin (line 27649) | function getSecurityOrigin(url) {
function handleLinkResponseHeaderPart (line 27653) | function handleLinkResponseHeaderPart(trimmedPart) {
function handleLinkResponseHeader (line 27690) | function handleLinkResponseHeader(linkHeaderValue) {
function generatePreconnectedOrigins (line 27715) | function generatePreconnectedOrigins(data31, context, contextRequests, p...
function hasValidTiming (line 27751) | function hasValidTiming(request) {
function hasAlreadyConnectedToOrigin (line 27754) | function hasAlreadyConnectedToOrigin(request) {
function socketStartTimeIsBelowThreshold (line 27767) | function socketStartTimeIsBelowThreshold(request, mainResource) {
function candidateRequestsByOrigin (line 27771) | function candidateRequestsByOrigin(data31, mainResource, contextRequests...
function generatePreconnectCandidates (line 27802) | function generatePreconnectCandidates(data31, context, contextRequests) {
function isNetworkDependencyTreeInsight (line 27858) | function isNetworkDependencyTreeInsight(model2) {
function generateInsight14 (line 27861) | function generateInsight14(data31, context) {
function createOverlays14 (line 27885) | function createOverlays14(model2) {
function normalizePath (line 27901) | function normalizePath(path7) {
function schemeIs (line 27925) | function schemeIs(url, scheme) {
method "node_modules/@paulirish/trace_engine/models/trace/insights/NetworkDependencyTree.js" (line 27934) | "node_modules/@paulirish/trace_engine/models/trace/insights/NetworkDepen...
function isRenderBlockingInsight (line 28416) | function isRenderBlockingInsight(insight) {
function getNodesAndTimingByRequestId (line 28419) | function getNodesAndTimingByRequestId(nodeTimings) {
function estimateSavingsWithGraphs2 (line 28429) | function estimateSavingsWithGraphs2(deferredIds, lanternContext) {
function hasImageLCP (line 28450) | function hasImageLCP(data31, context) {
function computeSavings (line 28453) | function computeSavings(data31, context, renderBlockingRequests) {
function finalize45 (line 28482) | function finalize45(partialModel) {
function generateInsight15 (line 28494) | function generateInsight15(data31, context) {
function createOverlayForRequest4 (line 28541) | function createOverlayForRequest4(request) {
function createOverlays15 (line 28548) | function createOverlays15(model2) {
method "node_modules/@paulirish/trace_engine/models/trace/insights/RenderBlocking.js" (line 28553) | "node_modules/@paulirish/trace_engine/models/trace/insights/RenderBlocki...
function aggregateSelectorStats (line 28603) | function aggregateSelectorStats(data31, context) {
function finalize46 (line 28627) | function finalize46(partialModel) {
function isSlowCSSSelectorInsight (line 28639) | function isSlowCSSSelectorInsight(model2) {
function generateInsight16 (line 28642) | function generateInsight16(data31, context) {
function createOverlays16 (line 28679) | function createOverlays16(_) {
method "node_modules/@paulirish/trace_engine/models/trace/insights/SlowCSSSelector.js" (line 28684) | "node_modules/@paulirish/trace_engine/models/trace/insights/SlowCSSSelec...
function getRelatedEvents (line 28752) | function getRelatedEvents(summaries, firstPartyEntity) {
function finalize47 (line 28761) | function finalize47(partialModel) {
function isThirdPartyInsight (line 28773) | function isThirdPartyInsight(model2) {
function generateInsight17 (line 28776) | function generateInsight17(data31, context) {
function createOverlaysForSummary (line 28786) | function createOverlaysForSummary(summary) {
function createOverlays17 (line 28801) | function createOverlays17(model2) {
method "node_modules/@paulirish/trace_engine/models/trace/insights/ThirdParties.js" (line 28815) | "node_modules/@paulirish/trace_engine/models/trace/insights/ThirdParties...
function finalize48 (line 28859) | function finalize48(partialModel) {
function isViewportInsight (line 28871) | function isViewportInsight(model2) {
function generateInsight18 (line 28874) | function generateInsight18(data31, context) {
function createOverlays18 (line 28914) | function createOverlays18(model2) {
method "node_modules/@paulirish/trace_engine/models/trace/insights/Viewport.js" (line 28931) | "node_modules/@paulirish/trace_engine/models/trace/insights/Viewport.js"...
method "node_modules/@paulirish/trace_engine/models/trace/insights/Models.js" (line 28981) | "node_modules/@paulirish/trace_engine/models/trace/insights/Models.js"() {
method "node_modules/@paulirish/trace_engine/models/trace/insights/insights.js" (line 29006) | "node_modules/@paulirish/trace_engine/models/trace/insights/insights.js"...
function createProcessedNavigation (line 29018) | function createProcessedNavigation(data31, frameId, navigationId) {
function createParsedUrl (line 29048) | function createParsedUrl(url) {
function findWorkerThreads (line 29059) | function findWorkerThreads(trace) {
function createLanternRequest (line 29078) | function createLanternRequest(parsedTrace, workerThreads, request) {
function chooseInitiatorRequest (line 29171) | function chooseInitiatorRequest(request, requestsByURL) {
function linkInitiators (line 29210) | function linkInitiators(lanternRequests) {
function createNetworkRequests (line 29224) | function createNetworkRequests(trace, data31, startTime = 0, endTime = N...
function collectMainThreadEvents (line 29300) | function collectMainThreadEvents(trace, data31) {
function createGraph (line 29327) | function createGraph(requests, trace, data31, url) {
method "node_modules/@paulirish/trace_engine/models/trace/LanternComputationData.js" (line 29343) | "node_modules/@paulirish/trace_engine/models/trace/LanternComputationDat...
function calculateProgress (line 29360) | function calculateProgress(value, phase) {
function sortHandlers (line 29366) | function sortHandlers(traceHandlers) {
method "node_modules/@paulirish/trace_engine/models/trace/Processor.js" (line 29401) | "node_modules/@paulirish/trace_engine/models/trace/Processor.js"() {
method "node_modules/@paulirish/trace_engine/models/trace/ModelImpl.js" (line 29853) | "node_modules/@paulirish/trace_engine/models/trace/ModelImpl.js"() {
method "node_modules/@paulirish/trace_engine/core/common/common.js" (line 29865) | "node_modules/@paulirish/trace_engine/core/common/common.js"() {
method "node_modules/@paulirish/trace_engine/models/trace/Styles.js" (line 29873) | "node_modules/@paulirish/trace_engine/models/trace/Styles.js"() {
method "node_modules/@paulirish/trace_engine/models/trace/Name.js" (line 29898) | "node_modules/@paulirish/trace_engine/models/trace/Name.js"() {
method "node_modules/@paulirish/trace_engine/models/trace/trace.js" (line 29909) | "node_modules/@paulirish/trace_engine/models/trace/trace.js"() {
method "core/lib/lantern/lantern.js" (line 29929) | "core/lib/lantern/lantern.js"() {
method "core/lib/tracehouse/trace-processor.js" (line 29945) | "core/lib/tracehouse/trace-processor.js"() {
method "core/lib/arbitrary-equality-map.js" (line 30688) | "core/lib/arbitrary-equality-map.js"() {
function makeComputedArtifact (line 30761) | function makeComputedArtifact(computableArtifact, keys2) {
method "core/computed/computed-artifact.js" (line 30798) | "core/computed/computed-artifact.js"() {
method "node_modules/tldts-icann/dist/cjs/index.js" (line 30815) | "node_modules/tldts-icann/dist/cjs/index.js"(exports2) {
method "core/lib/lh-error.js" (line 31391) | "core/lib/lh-error.js"() {
function rewriteChromeInternalUrl (line 31790) | function rewriteChromeInternalUrl(url) {
method "core/lib/url-utils.js" (line 31797) | "core/lib/url-utils.js"() {
method "core/lib/network-request.js" (line 32051) | "core/lib/network-request.js"() {
method "core/lib/network-recorder.js" (line 32515) | "core/lib/network-recorder.js"() {
method "core/computed/network-records.js" (line 32839) | "core/computed/network-records.js"() {
method "core/lib/axe.js" (line 32869) | "core/lib/axe.js"() {
function wrapRuntimeEvalErrorInBrowser (line 33454) | function wrapRuntimeEvalErrorInBrowser(err) {
function getElementsInDocument2 (line 33465) | function getElementsInDocument2(selector) {
function getOuterHTMLSnippet (line 33482) | function getOuterHTMLSnippet(element, ignoreAttrs = [], snippetCharacter...
function computeBenchmarkIndex (line 33542) | function computeBenchmarkIndex() {
function getNodePath (line 33574) | function getNodePath(node) {
function getNodeSelector (line 33601) | function getNodeSelector(element) {
function isPositionFixed (line 33625) | function isPositionFixed(element) {
function getNodeLabel (line 33645) | function getNodeLabel(element) {
function getBoundingClientRect (line 33660) | function getBoundingClientRect(element) {
function wrapRequestIdleCallback (line 33672) | function wrapRequestIdleCallback(cpuSlowdownMultiplier) {
function getNodeDetails2 (line 33698) | function getNodeDetails2(element) {
function truncate (line 33723) | function truncate(string, characterLimit) {
function isBundledEnvironment (line 33726) | function isBundledEnvironment() {
function createEsbuildFunctionWrapper (line 33736) | function createEsbuildFunctionWrapper() {
function getRuntimeFunctionName (line 33752) | function getRuntimeFunctionName(fn) {
method "core/lib/page-functions.js" (line 33759) | "core/lib/page-functions.js"() {
function runA11yChecks (line 33839) | async function runA11yChecks() {
function runA11yChecksAndResetScroll (line 33917) | async function runA11yChecksAndResetScroll() {
function createAxeRuleResultArtifact (line 33928) | function createAxeRuleResultArtifact(result) {
method "core/gather/gatherers/accessibility.js" (line 33973) | "core/gather/gatherers/accessibility.js"() {
function handlePotentialMissingNodeError (line 34022) | function handlePotentialMissingNodeError(err) {
function resolveDevtoolsNodePathToObjectId (line 34028) | async function resolveDevtoolsNodePathToObjectId(session, path7) {
method "core/gather/driver/dom.js" (line 34038) | "core/gather/driver/dom.js"() {
function collectAnchorElements (line 34056) | function collectAnchorElements() {
function getEventListeners (line 34125) | async function getEventListeners(session, devtoolsNodePath) {
method "core/gather/gatherers/anchor-elements.js" (line 34135) | "core/gather/gatherers/anchor-elements.js"() {
function remoteObjectToString (line 34194) | function remoteObjectToString(obj) {
method "core/gather/gatherers/console-messages.js" (line 34207) | "core/gather/gatherers/console-messages.js"() {
method "core/gather/gatherers/devtools-log.js" (line 34349) | "core/gather/gatherers/devtools-log.js"() {
function getDoctype (line 34449) | function getDoctype() {
method "core/gather/gatherers/dobetterweb/doctype.js" (line 34459) | "core/gather/gatherers/dobetterweb/doctype.js"() {
function getClientRect (line 34498) | function getClientRect(element) {
function getPosition (line 34508) | function getPosition(element, computedStyle) {
function getHTMLImages (line 34515) | function getHTMLImages(allElements) {
function getCSSImages (line 34554) | function getCSSImages(allElements) {
function collectImageElementInfo (line 34586) | function collectImageElementInfo() {
function determineNaturalSize (line 34590) | function determineNaturalSize(url) {
function findSizeDeclaration (line 34603) | function findSizeDeclaration(rule, property) {
function findMostSpecificMatchedCSSRule (line 34609) | function findMostSpecificMatchedCSSRule(matchedCSSRules = [], isDeclarat...
function findMostSpecificCSSRule (line 34628) | function findMostSpecificCSSRule(matchedCSSRules, property) {
function getEffectiveSizingRule (line 34634) | function getEffectiveSizingRule({ attributesStyle, inlineStyle, matchedC...
function getPixelArea (line 34643) | function getPixelArea(element) {
method "core/gather/gatherers/image-elements.js" (line 34651) | "core/gather/gatherers/image-elements.js"() {
function collectElements (line 34800) | function collectElements() {
method "core/gather/gatherers/inputs.js" (line 34859) | "core/gather/gatherers/inputs.js"() {
method "core/gather/gatherers/inspector-issues.js" (line 34904) | "core/gather/gatherers/inspector-issues.js"() {
method "node_modules/http-link-header/lib/link.js" (line 34996) | "node_modules/http-link-header/lib/link.js"(exports2, module2) {
method "core/computed/main-resource.js" (line 35296) | "core/computed/main-resource.js"() {
function normalizeUrlOrNull (line 35337) | function normalizeUrlOrNull(url, finalDisplayedUrl) {
function getCrossoriginFromHeader (line 35344) | function getCrossoriginFromHeader(value) {
function getLinkElementsInDOM (line 35349) | function getLinkElementsInDOM() {
method "core/gather/gatherers/link-elements.js" (line 35373) | "core/gather/gatherers/link-elements.js"() {
function fetchResponseBodyFromCache (line 35480) | async function fetchResponseBodyFromCache(session, requestId, timeout = ...
method "core/gather/driver/network.js" (line 35487) | "core/gather/driver/network.js"() {
method "core/gather/gatherers/main-document-content.js" (line 35507) | "core/gather/gatherers/main-document-content.js"() {
function collectMetaElements (line 35548) | function collectMetaElements() {
method "core/gather/gatherers/meta-elements.js" (line 35577) | "core/gather/gatherers/meta-elements.js"() {
function runInSeriesOrParallel (line 35621) | async function runInSeriesOrParallel(values, promiseMapper, runInSeries) {
function isLighthouseRuntimeEvaluateScript (line 35634) | function isLighthouseRuntimeEvaluateScript(script) {
method "core/gather/gatherers/scripts.js" (line 35640) | "core/gather/gatherers/scripts.js"() {
method "core/gather/gatherers/seo/robots-txt.js" (line 35727) | "core/gather/gatherers/seo/robots-txt.js"() {
method "core/lib/cdt/generated/ParsedURL.js" (line 35760) | "core/lib/cdt/generated/ParsedURL.js"(exports2) {
method "core/lib/cdt/Common.js" (line 35915) | "core/lib/cdt/Common.js"(exports2, module2) {
method "core/lib/cdt/Platform.js" (line 35932) | "core/lib/cdt/Platform.js"(exports2, module2) {
method "core/lib/cdt/generated/SourceMap.js" (line 35982) | "core/lib/cdt/generated/SourceMap.js"(exports2, module2) {
method "core/lib/cdt/SDK.js" (line 36476) | "core/lib/cdt/SDK.js"(exports2, module2) {
method "core/gather/gatherers/source-maps.js" (line 36509) | "core/gather/gatherers/source-maps.js"() {
function detectLibraries (line 36624) | async function detectLibraries() {
method "core/gather/gatherers/stacks.js" (line 36648) | "core/gather/gatherers/stacks.js"() {
function getViewportDimensions (line 36745) | function getViewportDimensions() {
method "core/gather/gatherers/viewport-dimensions.js" (line 36756) | "core/gather/gatherers/viewport-dimensions.js"() {
method "core/audits/accessibility/axe-audit.js" (line 36799) | "core/audits/accessibility/axe-audit.js"() {
method "core/audits/accessibility/accesskeys.js" (line 36899) | "core/audits/accessibility/accesskeys.js"() {
method "core/audits/accessibility/aria-allowed-attr.js" (line 36947) | "core/audits/accessibility/aria-allowed-attr.js"() {
method "core/audits/accessibility/aria-allowed-role.js" (line 36995) | "core/audits/accessibility/aria-allowed-role.js"() {
method "core/audits/accessibility/aria-command-name.js" (line 37044) | "core/audits/accessibility/aria-command-name.js"() {
method "core/audits/accessibility/aria-conditional-attr.js" (line 37092) | "core/audits/accessibility/aria-conditional-attr.js"() {
method "core/audits/accessibility/aria-deprecated-role.js" (line 37140) | "core/audits/accessibility/aria-deprecated-role.js"() {
method "core/audits/accessibility/aria-dialog-name.js" (line 37188) | "core/audits/accessibility/aria-dialog-name.js"() {
method "core/audits/accessibility/aria-hidden-body.js" (line 37236) | "core/audits/accessibility/aria-hidden-body.js"() {
method "core/audits/accessibility/aria-hidden-focus.js" (line 37284) | "core/audits/accessibility/aria-hidden-focus.js"() {
method "core/audits/accessibility/aria-input-field-name.js" (line 37332) | "core/audits/accessibility/aria-input-field-name.js"() {
method "core/audits/accessibility/aria-meter-name.js" (line 37380) | "core/audits/accessibility/aria-meter-name.js"() {
method "core/audits/accessibility/aria-progressbar-name.js" (line 37428) | "core/audits/accessibility/aria-progressbar-name.js"() {
method "core/audits/accessibility/aria-prohibited-attr.js" (line 37476) | "core/audits/accessibility/aria-prohibited-attr.js"() {
method "core/audits/accessibility/aria-required-attr.js" (line 37524) | "core/audits/accessibility/aria-required-attr.js"() {
method "core/audits/accessibility/aria-required-children.js" (line 37572) | "core/audits/accessibility/aria-required-children.js"() {
method "core/audits/accessibility/aria-required-parent.js" (line 37620) | "core/audits/accessibility/aria-required-parent.js"() {
method "core/audits/accessibility/aria-roles.js" (line 37668) | "core/audits/accessibility/aria-roles.js"() {
method "core/audits/accessibility/aria-text.js" (line 37716) | "core/audits/accessibility/aria-text.js"() {
method "core/audits/accessibility/aria-toggle-field-name.js" (line 37764) | "core/audits/accessibility/aria-toggle-field-name.js"() {
method "core/audits/accessibility/aria-tooltip-name.js" (line 37812) | "core/audits/accessibility/aria-tooltip-name.js"() {
method "core/audits/accessibility/aria-treeitem-name.js" (line 37860) | "core/audits/accessibility/aria-treeitem-name.js"() {
method "core/audits/accessibility/aria-valid-attr-value.js" (line 37908) | "core/audits/accessibility/aria-valid-attr-value.js"() {
method "core/audits/accessibility/aria-valid-attr.js" (line 37956) | "core/audits/accessibility/aria-valid-attr.js"() {
method "core/audits/accessibility/button-name.js" (line 38004) | "core/audits/accessibility/button-name.js"() {
method "core/audits/accessibility/bypass.js" (line 38052) | "core/audits/accessibility/bypass.js"() {
method "core/audits/accessibility/color-contrast.js" (line 38101) | "core/audits/accessibility/color-contrast.js"() {
method "core/audits/accessibility/definition-list.js" (line 38149) | "core/audits/accessibility/definition-list.js"() {
method "core/audits/accessibility/dlitem.js" (line 38197) | "core/audits/accessibility/dlitem.js"() {
method "core/audits/accessibility/document-title.js" (line 38245) | "core/audits/accessibility/document-title.js"() {
method "core/audits/accessibility/duplicate-id-aria.js" (line 38293) | "core/audits/accessibility/duplicate-id-aria.js"() {
method "core/audits/accessibility/empty-heading.js" (line 38342) | "core/audits/accessibility/empty-heading.js"() {
method "core/audits/accessibility/form-field-multiple-labels.js" (line 38391) | "core/audits/accessibility/form-field-multiple-labels.js"() {
method "core/audits/accessibility/frame-title.js" (line 38440) | "core/audits/accessibility/frame-title.js"() {
method "core/audits/accessibility/heading-order.js" (line 38488) | "core/audits/accessibility/heading-order.js"() {
method "core/audits/accessibility/html-has-lang.js" (line 38536) | "core/audits/accessibility/html-has-lang.js"() {
method "core/audits/accessibility/html-lang-valid.js" (line 38584) | "core/audits/accessibility/html-lang-valid.js"() {
method "core/audits/accessibility/html-xml-lang-mismatch.js" (line 38632) | "core/audits/accessibility/html-xml-lang-mismatch.js"() {
method "core/audits/accessibility/identical-links-same-purpose.js" (line 38680) | "core/audits/accessibility/identical-links-same-purpose.js"() {
method "core/audits/accessibility/image-alt.js" (line 38729) | "core/audits/accessibility/image-alt.js"() {
method "core/audits/accessibility/image-redundant-alt.js" (line 38777) | "core/audits/accessibility/image-redundant-alt.js"() {
method "core/audits/accessibility/input-button-name.js" (line 38826) | "core/audits/accessibility/input-button-name.js"() {
method "core/audits/accessibility/input-image-alt.js" (line 38874) | "core/audits/accessibility/input-image-alt.js"() {
method "core/audits/accessibility/label-content-name-mismatch.js" (line 38922) | "core/audits/accessibility/label-content-name-mismatch.js"() {
method "core/audits/accessibility/label.js" (line 38970) | "core/audits/accessibility/label.js"() {
method "core/audits/accessibility/landmark-one-main.js" (line 39018) | "core/audits/accessibility/landmark-one-main.js"() {
method "core/audits/accessibility/link-in-text-block.js" (line 39066) | "core/audits/accessibility/link-in-text-block.js"() {
method "core/audits/accessibility/link-name.js" (line 39114) | "core/audits/accessibility/link-name.js"() {
method "core/audits/accessibility/list.js" (line 39162) | "core/audits/accessibility/list.js"() {
method "core/audits/accessibility/listitem.js" (line 39210) | "core/audits/accessibility/listitem.js"() {
method "core/audits/manual/manual-audit.js" (line 39253) | "core/audits/manual/manual-audit.js"() {
method "core/audits/accessibility/manual/custom-controls-labels.js" (line 39296) | "core/audits/accessibility/manual/custom-controls-labels.js"() {
method "core/audits/accessibility/manual/custom-controls-roles.js" (line 39331) | "core/audits/accessibility/manual/custom-controls-roles.js"() {
method "core/audits/accessibility/manual/focus-traps.js" (line 39366) | "core/audits/accessibility/manual/focus-traps.js"() {
method "core/audits/accessibility/manual/focusable-controls.js" (line 39401) | "core/audits/accessibility/manual/focusable-controls.js"() {
method "core/audits/accessibility/manual/interactive-element-affordance.js" (line 39436) | "core/audits/accessibility/manual/interactive-element-affordance.js"() {
method "core/audits/accessibility/manual/logical-tab-order.js" (line 39471) | "core/audits/accessibility/manual/logical-tab-order.js"() {
method "core/audits/accessibility/manual/managed-focus.js" (line 39506) | "core/audits/accessibility/manual/managed-focus.js"() {
method "core/audits/accessibility/manual/offscreen-content-hidden.js" (line 39541) | "core/audits/accessibility/manual/offscreen-content-hidden.js"() {
method "core/audits/accessibility/manual/use-landmarks.js" (line 39576) | "core/audits/accessibility/manual/use-landmarks.js"() {
method "core/audits/accessibility/manual/visual-order-follows-dom.js" (line 39611) | "core/audits/accessibility/manual/visual-order-follows-dom.js"() {
method "core/audits/accessibility/meta-refresh.js" (line 39647) | "core/audits/accessibility/meta-refresh.js"() {
method "core/audits/accessibility/meta-viewport.js" (line 39695) | "core/audits/accessibility/meta-viewport.js"() {
method "core/audits/accessibility/object-alt.js" (line 39743) | "core/audits/accessibility/object-alt.js"() {
method "core/audits/accessibility/select-name.js" (line 39791) | "core/audits/accessibility/select-name.js"() {
method "core/audits/accessibility/skip-link.js" (line 39839) | "core/audits/accessibility/skip-link.js"() {
method "core/audits/accessibility/tabindex.js" (line 39887) | "core/audits/accessibility/tabindex.js"() {
method "core/audits/accessibility/table-duplicate-name.js" (line 39935) | "core/audits/accessibility/table-duplicate-name.js"() {
method "core/audits/accessibility/table-fake-caption.js" (line 39984) | "core/audits/accessibility/table-fake-caption.js"() {
method "core/audits/accessibility/target-size.js" (line 40032) | "core/audits/accessibility/target-size.js"() {
method "core/audits/accessibility/td-has-header.js" (line 40080) | "core/audits/accessibility/td-has-header.js"() {
method "core/audits/accessibility/td-headers-attr.js" (line 40128) | "core/audits/accessibility/td-headers-attr.js"() {
method "core/audits/accessibility/th-has-data-cells.js" (line 40176) | "core/audits/accessibility/th-has-data-cells.js"() {
method "core/audits/accessibility/valid-lang.js" (line 40225) | "core/audits/accessibility/valid-lang.js"() {
method "core/audits/accessibility/video-caption.js" (line 40273) | "core/audits/accessibility/video-caption.js"() {
method "core/audits/clickjacking-mitigation.js" (line 40322) | "core/audits/clickjacking-mitigation.js"() {
method "node_modules/csp_evaluator/dist/finding.js" (line 40443) | "node_modules/csp_evaluator/dist/finding.js"(exports2) {
method "node_modules/csp_evaluator/dist/csp.js" (line 40525) | "node_modules/csp_evaluator/dist/csp.js"(exports2) {
method "node_modules/csp_evaluator/dist/checks/parser_checks.js" (line 40777) | "node_modules/csp_evaluator/dist/checks/parser_checks.js"(exports2) {
method "node_modules/csp_evaluator/dist/allowlist_bypasses/angular.js" (line 40880) | "node_modules/csp_evaluator/dist/allowlist_bypasses/angular.js"(exports2) {
method "node_modules/csp_evaluator/dist/allowlist_bypasses/flash.js" (line 40933) | "node_modules/csp_evaluator/dist/allowlist_bypasses/flash.js"(exports2) {
method "node_modules/csp_evaluator/dist/allowlist_bypasses/jsonp.js" (line 40947) | "node_modules/csp_evaluator/dist/allowlist_bypasses/jsonp.js"(exports2) {
method "node_modules/csp_evaluator/dist/utils.js" (line 41090) | "node_modules/csp_evaluator/dist/utils.js"(exports2) {
method "node_modules/csp_evaluator/dist/checks/security_checks.js" (line 41168) | "node_modules/csp_evaluator/dist/checks/security_checks.js"(exports2) {
method "node_modules/csp_evaluator/dist/checks/strictcsp_checks.js" (line 41503) | "node_modules/csp_evaluator/dist/checks/strictcsp_checks.js"(exports2) {
method "node_modules/csp_evaluator/dist/lighthouse/lighthouse_checks.js" (line 41596) | "node_modules/csp_evaluator/dist/lighthouse/lighthouse_checks.js"(export...
method "node_modules/csp_evaluator/dist/parser.js" (line 41701) | "node_modules/csp_evaluator/dist/parser.js"(exports2) {
function getTranslatedDescription (line 41779) | function getTranslatedDescription(finding) {
function parseCsp (line 41794) | function parseCsp(rawCsp) {
function evaluateRawCspsForXss (line 41797) | function evaluateRawCspsForXss(rawCsps) {
method "core/lib/csp-evaluator.js" (line 41806) | "core/lib/csp-evaluator.js"() {
method "core/audits/csp-xss.js" (line 41913) | "core/audits/csp-xss.js"() {
function computeGeneratedFileSizes2 (line 42072) | function computeGeneratedFileSizes2(map, contentLength, content) {
method "core/computed/js-bundles.js" (line 42117) | "core/computed/js-bundles.js"() {
method "core/lib/deprecations-strings.js" (line 42167) | "core/lib/deprecations-strings.js"() {
function getIssueDetailDescription (line 42508) | function getIssueDetailDescription(issueDetails) {
method "core/lib/deprecation-description.js" (line 42545) | "core/lib/deprecation-description.js"() {
method "core/audits/deprecations.js" (line 42588) | "core/audits/deprecations.js"() {
method "core/audits/dobetterweb/charset.js" (line 42696) | "core/audits/dobetterweb/charset.js"() {
method "core/lib/lh-trace-processor.js" (line 42770) | "core/lib/lh-trace-processor.js"() {
method "core/computed/processed-trace.js" (line 42819) | "core/computed/processed-trace.js"() {
method "core/audits/dobetterweb/doctype.js" (line 42853) | "core/audits/dobetterweb/doctype.js"() {
method "core/audits/violation-audit.js" (line 42968) | "core/audits/violation-audit.js"() {
method "core/audits/dobetterweb/geolocation-on-start.js" (line 43018) | "core/audits/dobetterweb/geolocation-on-start.js"() {
method "core/audits/dobetterweb/inspector-issues.js" (line 43083) | "core/audits/dobetterweb/inspector-issues.js"() {
method "core/audits/dobetterweb/js-libraries.js" (line 43261) | "core/audits/dobetterweb/js-libraries.js"() {
method "core/audits/dobetterweb/notification-on-start.js" (line 43348) | "core/audits/dobetterweb/notification-on-start.js"() {
method "core/audits/dobetterweb/paste-preventing-inputs.js" (line 43413) | "core/audits/dobetterweb/paste-preventing-inputs.js"() {
method "core/audits/errors-in-console.js" (line 43482) | "core/audits/errors-in-console.js"() {
method "core/audits/has-hsts.js" (line 43589) | "core/audits/has-hsts.js"() {
method "core/audits/image-aspect-ratio.js" (line 43784) | "core/audits/image-aspect-ratio.js"() {
method "core/computed/image-records.js" (line 43882) | "core/computed/image-records.js"() {
function isVisible (line 43945) | function isVisible(imageRect, viewportDimensions) {
function isSmallerThanViewport (line 43948) | function isSmallerThanViewport(imageRect, viewportDimensions) {
function isCandidate (line 43951) | function isCandidate(image, imageRecord) {
function imageHasNaturalDimensions (line 43980) | function imageHasNaturalDimensions(image) {
function imageHasRightSize (line 43983) | function imageHasRightSize(image, DPR) {
function getResult (line 43987) | function getResult(image, DPR) {
function allowedImageSize (line 43999) | function allowedImageSize(displayedWidth, displayedHeight, DPR) {
function expectedImageSize (line 44009) | function expectedImageSize(displayedWidth, displayedHeight, DPR) {
function deduplicateResultsByUrl (line 44014) | function deduplicateResultsByUrl(results) {
function sortResultsBySizeDelta (line 44029) | function sortResultsBySizeDelta(results) {
function quantizeDpr (line 44034) | function quantizeDpr(dpr) {
method "core/audits/image-size-responsive.js" (line 44045) | "core/audits/image-size-responsive.js"() {
method "core/audits/is-on-https.js" (line 44147) | "core/audits/is-on-https.js"() {
method "core/audits/origin-isolation.js" (line 44255) | "core/audits/origin-isolation.js"() {
method "core/audits/redirects-http.js" (line 44408) | "core/audits/redirects-http.js"() {
method "core/audits/seo/canonical.js" (line 44481) | "core/audits/seo/canonical.js"() {
method "core/audits/seo/crawlable-anchors.js" (line 44652) | "core/audits/seo/crawlable-anchors.js"() {
function isValidLang (line 44753) | function isValidLang(lang) {
method "third-party/axe/valid-langs.js" (line 44769) | "third-party/axe/valid-langs.js"() {
function isFullyQualified (line 44820) | function isFullyQualified(href) {
function isExpectedLanguageCode (line 44823) | function isExpectedLanguageCode(hreflang) {
method "core/audits/seo/hreflang.js" (line 44832) | "core/audits/seo/hreflang.js"() {
method "core/audits/seo/http-status-code.js" (line 44949) | "core/audits/seo/http-status-code.js"() {
method "node_modules/robots-parser/Robots.js" (line 45015) | "node_modules/robots-parser/Robots.js"(exports2, module2) {
method "node_modules/robots-parser/index.js" (line 45246) | "node_modules/robots-parser/index.js"(exports2, module2) {
function isUnavailable (line 45261) | function isUnavailable(directive) {
function hasBlockingDirective (line 45269) | function hasBlockingDirective(directives) {
function getUserAgentFromHeaderDirectives (line 45272) | function getUserAgentFromHeaderDirectives(directives) {
method "core/audits/seo/is-crawlable.js" (line 45280) | "core/audits/seo/is-crawlable.js"() {
method "core/audits/seo/link-text.js" (line 45451) | "core/audits/seo/link-text.js"() {
method "core/audits/seo/manual/structured-data.js" (line 45672) | "core/audits/seo/manual/structured-data.js"() {
method "core/audits/seo/meta-description.js" (line 45716) | "core/audits/seo/meta-description.js"() {
function verifyDirective (line 45786) | function verifyDirective(directiveName, directiveValue) {
function parseLine (line 45814) | function parseLine(line) {
function validateRobots (line 45835) | function validateRobots(content) {
method "core/audits/seo/robots-txt.js" (line 45866) | "core/audits/seo/robots-txt.js"() {
method "core/audits/third-party-cookies.js" (line 46001) | "core/audits/third-party-cookies.js"() {
method "core/audits/trusted-types-xss.js" (line 46103) | "core/audits/trusted-types-xss.js"() {
method "replace-modules:/Users/alexrudenko/src/lighthouse/core/computed/entity-classification.js" (line 46229) | "replace-modules:/Users/alexrudenko/src/lighthouse/core/computed/entity-...
method "core/audits/valid-source-maps.js" (line 46256) | "core/audits/valid-source-maps.js"() {
method "replace-modules:/Users/alexrudenko/src/lighthouse/core/computed/speedline.js" (line 46406) | "replace-modules:/Users/alexrudenko/src/lighthouse/core/computed/speedli...
method "replace-modules:/Users/alexrudenko/src/lighthouse/core/computed/metrics/timing-summary.js" (line 46430) | "replace-modules:/Users/alexrudenko/src/lighthouse/core/computed/metrics...
method "replace-modules:/Users/alexrudenko/src/lighthouse/core/computed/trace-engine-result.js" (line 46453) | "replace-modules:/Users/alexrudenko/src/lighthouse/core/computed/trace-e...
method "lh-gatherer-shim:/Users/alexrudenko/src/lighthouse/core/gather/gatherers/bf-cache-failures.js" (line 46478) | "lh-gatherer-shim:/Users/alexrudenko/src/lighthouse/core/gather/gatherer...
method "lh-gatherer-shim:/Users/alexrudenko/src/lighthouse/core/gather/gatherers/css-usage.js" (line 46504) | "lh-gatherer-shim:/Users/alexrudenko/src/lighthouse/core/gather/gatherer...
method "lh-gatherer-shim:/Users/alexrudenko/src/lighthouse/core/gather/gatherers/full-page-screenshot.js" (line 46530) | "lh-gatherer-shim:/Users/alexrudenko/src/lighthouse/core/gather/gatherer...
method "lh-gatherer-shim:/Users/alexrudenko/src/lighthouse/core/gather/gatherers/iframe-elements.js" (line 46556) | "lh-gatherer-shim:/Users/alexrudenko/src/lighthouse/core/gather/gatherer...
method "lh-gatherer-shim:/Users/alexrudenko/src/lighthouse/core/gather/gatherers/js-usage.js" (line 46582) | "lh-gatherer-shim:/Users/alexrudenko/src/lighthouse/core/gather/gatherer...
method "lh-gatherer-shim:/Users/alexrudenko/src/lighthouse/core/gather/gatherers/network-user-agent.js" (line 46608) | "lh-gatherer-shim:/Users/alexrudenko/src/lighthouse/core/gather/gatherer...
method "lh-gatherer-shim:/Users/alexrudenko/src/lighthouse/core/gather/gatherers/stylesheets.js" (line 46634) | "lh-gatherer-shim:/Users/alexrudenko/src/lighthouse/core/gather/gatherer...
method "lh-gatherer-shim:/Users/alexrudenko/src/lighthouse/core/gather/gatherers/trace-elements.js" (line 46660) | "lh-gatherer-shim:/Users/alexrudenko/src/lighthouse/core/gather/gatherer...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/autocomplete.js" (line 46686) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/autocomplet...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/bf-cache.js" (line 46717) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/bf-cache.js...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/bootup-time.js" (line 46748) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/bootup-time...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/byte-efficiency/total-byte-weight.js" (line 46779) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/byte-effici...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/byte-efficiency/unminified-css.js" (line 46810) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/byte-effici...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/byte-efficiency/unminified-javascript.js" (line 46841) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/byte-effici...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/byte-efficiency/unused-css-rules.js" (line 46872) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/byte-effici...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/byte-efficiency/unused-javascript.js" (line 46903) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/byte-effici...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/diagnostics.js" (line 46934) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/diagnostics...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/final-screenshot.js" (line 46965) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/final-scree...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/cache-insight.js" (line 46996) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/ca...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/cls-culprits-insight.js" (line 47027) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/cl...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/document-latency-insight.js" (line 47058) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/do...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/dom-size-insight.js" (line 47089) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/do...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/duplicated-javascript-insight.js" (line 47120) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/du...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/font-display-insight.js" (line 47151) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/fo...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/forced-reflow-insight.js" (line 47182) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/fo...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/image-delivery-insight.js" (line 47213) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/im...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/inp-breakdown-insight.js" (line 47244) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/in...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/lcp-breakdown-insight.js" (line 47275) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/lc...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/lcp-discovery-insight.js" (line 47306) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/lc...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/legacy-javascript-insight.js" (line 47337) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/le...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/modern-http-insight.js" (line 47368) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/mo...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/network-dependency-tree-insight.js" (line 47399) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/ne...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/render-blocking-insight.js" (line 47430) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/re...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/slow-css-selector-insight.js" (line 47461) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/sl...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/third-parties-insight.js" (line 47492) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/th...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/viewport-insight.js" (line 47523) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/insights/vi...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/layout-shifts.js" (line 47554) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/layout-shif...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/long-tasks.js" (line 47585) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/long-tasks....
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/main-thread-tasks.js" (line 47616) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/main-thread...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/mainthread-work-breakdown.js" (line 47647) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/mainthread-...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/metrics.js" (line 47678) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/metrics.js"...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/metrics/cumulative-layout-shift.js" (line 47709) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/metrics/cum...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/metrics/first-contentful-paint.js" (line 47740) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/metrics/fir...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/metrics/interaction-to-next-paint.js" (line 47771) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/metrics/int...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/metrics/interactive.js" (line 47802) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/metrics/int...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/metrics/largest-contentful-paint.js" (line 47833) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/metrics/lar...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/metrics/max-potential-fid.js" (line 47864) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/metrics/max...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/metrics/speed-index.js" (line 47895) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/metrics/spe...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/metrics/total-blocking-time.js" (line 47926) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/metrics/tot...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/network-requests.js" (line 47957) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/network-req...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/network-rtt.js" (line 47988) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/network-rtt...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/network-server-latency.js" (line 48019) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/network-ser...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/non-composited-animations.js" (line 48050) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/non-composi...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/oopif-iframe-test-audit.js" (line 48081) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/oopif-ifram...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/predictive-perf.js" (line 48112) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/predictive-...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/redirects.js" (line 48143) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/redirects.j...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/resource-summary.js" (line 48174) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/resource-su...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/screenshot-thumbnails.js" (line 48205) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/screenshot-...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/script-treemap-data.js" (line 48236) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/script-tree...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/server-response-time.js" (line 48267) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/server-resp...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/unsized-images.js" (line 48298) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/unsized-ima...
method "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/user-timings.js" (line 48329) | "lh-audit-shim:/Users/alexrudenko/src/lighthouse/core/audits/user-timing...
method "replace-modules:/Users/alexrudenko/src/lighthouse/node_modules/@sentry/node/build/cjs/index.js" (line 48360) | "replace-modules:/Users/alexrudenko/src/lighthouse/node_modules/@sentry/...
method arithmeticMean (line 48397) | static arithmeticMean(items) {
method scoreAllCategories (line 48420) | static scoreAllCategories(configCategories, resultsByAuditId) {
function getStackPacks (line 48523) | function getStackPacks(pageStacks) {
method compute_ (line 48613) | static async compute_(devtoolsLog, context) {
method compute_ (line 48648) | static async compute_(data31, context) {
method convertAnalysisToSaveableLanternData (line 48656) | static convertAnalysisToSaveableLanternData(networkAnalysis) {
function writeJson (line 48681) | async function writeJson(contents, path7, gzip) {
function readJson (line 48690) | function readJson(filename, reviver) {
function endsWithSuffix (line 48701) | function endsWithSuffix(filename, suffix) {
function loadArtifacts (line 48705) | function loadArtifacts(basePath) {
function stringifyReplacer (line 48737) | function stringifyReplacer(key, value) {
function saveArtifacts (line 48744) | async function saveArtifacts(artifacts, basePath, options = {}) {
function saveLhr (line 48791) | function saveLhr(lhr, basePath) {
function saveTrace (line 48831) | function saveTrace(traceData, traceFilename2, options = {}) {
function saveDevtoolsLog (line 48836) | function saveDevtoolsLog(devtoolsLog, devtoolLogFilename, options = {}) {
function isValidArtifactDependency (line 49601) | function isValidArtifactDependency(dependent, dependency) {
function assertValidPluginName (line 49610) | function assertValidPluginName(config3, pluginName) {
function assertValidArtifact (line 49623) | function assertValidArtifact(artifactDefn) {
function assertValidAudit (line 49636) | function assertValidAudit(auditDefinition) {
function assertValidCategories (line 49668) | function assertValidCategories(categories, audits, groups) {
function assertValidSettings (line 49699) | function assertValidSettings(settings) {
function assertValidArtifacts (line 49714) | function assertValidArtifacts(artifactDefns) {
function assertValidConfig (line 49730) | function assertValidConfig(resolvedConfig) {
function throwInvalidDependencyOrder (line 49739) | function throwInvalidDependencyOrder(artifactId, dependencyKey) {
function throwInvalidArtifactDependency (line 49750) | function throwInvalidArtifactDependency(artifactId, dependencyKey) {
function getAuditIdsInCategories (line 49785) | function getAuditIdsInCategories(allCategories, onlyCategories) {
function filterArtifactsByAvailableAudits (line 49793) | function filterArtifactsByAvailableAudits(artifacts, audits) {
function filterArtifactsByGatherMode (line 49816) | function filterArtifactsByGatherMode(artifacts, mode) {
function filterAuditsByAvailableArtifacts (line 49823) | function filterAuditsByAvailableArtifacts(audits, availableArtifacts) {
function filterAuditsByGatherMode (line 49834) | function filterAuditsByGatherMode(audits, mode) {
function filterCategoriesByGatherMode (line 49842) | function filterCategoriesByGatherMode(categories, mode) {
function filterCategoriesByExplicitFilters (line 49850) | function filterCategoriesByExplicitFilters(categories, onlyCategories) {
function errorOnUnknownOnlyCategories (line 49856) | function errorOnUnknownOnlyCategories(allCategories, onlyCategories) {
function filterCategoriesByAvailableAudits (line 49864) | function filterCategoriesByAvailableAudits(categories, availableAudits) {
function filterConfigByGatherMode (line 49886) | function filterConfigByGatherMode(resolvedConfig, mode) {
function filterConfigByExplicitFilters (line 49900) | function filterConfigByExplicitFilters(resolvedConfig, filters) {
function isArrayOfUnknownObjects (line 49958) | function isArrayOfUnknownObjects(arr) {
function isObjectOfUnknownProperties (line 49962) | function isObjectOfUnknownProperties(val) {
function objectIsGatherMode (line 49966) | function objectIsGatherMode(str) {
function isArrayOfGatherModes (line 49971) | function isArrayOfGatherModes(arr) {
function assertNoExcessProperties (line 49976) | function assertNoExcessProperties(obj, pluginName, objectName = "") {
method _parseAuditsList (line 49998) | static _parseAuditsList(auditsJson, pluginName) {
method _parseAuditRefsList (line 50021) | static _parseAuditRefsList(auditRefsJson, pluginName) {
method _parseCategory (line 50051) | static _parseCategory(categoryJson, pluginName) {
method _parseGroups (line 50093) | static _parseGroups(groupsJson, pluginName) {
method parsePlugin (line 50128) | static parsePlugin(pluginJson, pluginName) {
function isBundledEnvironment2 (line 50160) | function isBundledEnvironment2() {
function _mergeConfigFragment (line 50182) | function _mergeConfigFragment(base, extension, overwriteArrays = false) {
function mergeConfigFragmentArrayByKey (line 50208) | function mergeConfigFragmentArrayByKey(baseArray, extensionArray, keyFn) {
function expandGathererShorthand (line 50228) | function expandGathererShorthand(gatherer) {
function expandAuditShorthand (line 50247) | function expandAuditShorthand(audit) {
function requireWrapper (line 50448) | async function requireWrapper(requirePath) {
function requireGatherer (line 50474) | async function requireGatherer(gathererPath, coreGathererList, configDir) {
function requireAudit (line 50491) | function requireAudit(auditPath, coreAuditList, configDir) {
function cleanFlagsForSettings (line 50510) | function cleanFlagsForSettings(flags = {}) {
function resolveSettings (line 50520) | function resolveSettings(settingsJson = {}, overrides = void 0) {
function mergePlugins (line 50537) | async function mergePlugins(config3, configDir, flags) {
function resolveGathererToDefn (line 50551) | async function resolveGathererToDefn(gathererJson, coreGathererList, con...
function resolveAuditsToDefns (line 50574) | async function resolveAuditsToDefns(audits, configDir) {
function resolveModulePath (line 50599) | function resolveModulePath(moduleIdentifier, configDir, category) {
function shallowClone (line 50633) | function shallowClone(item) {
function deepClone (line 50645) | function deepClone(json) {
function deepCloneConfigJson (line 50649) | function deepCloneConfigJson(json) {
function resolveWorkingCopy (line 50680) | function resolveWorkingCopy(config3, context) {
function resolveExtensions (line 50697) | function resolveExtensions(config3) {
function resolveArtifactDependencies (line 50713) | function resolveArtifactDependencies(artifact, gatherer, artifactDefnsBy...
function resolveArtifactsToDefns (line 50727) | async function resolveArtifactsToDefns(artifacts, configDir) {
function overrideSettingsForGatherMode (line 50756) | function overrideSettingsForGatherMode(settings, gatherMode) {
function overrideThrottlingWindows (line 50764) | function overrideThrottlingWindows(settings) {
function initializeConfig (line 50784) | async function initializeConfig(gatherMode, config3, flags = {}) {
method _shouldSample (line 50830) | _shouldSample() {
function init (line 50834) | async function init(opts) {
method replaceStrings (line 51147) | static replaceStrings(source, replacements) {
method sanitizeJson (line 51159) | static sanitizeJson(object) {
method generateReportHtml (line 51167) | static generateReportHtml(lhr) {
method generateFlowReportHtml (line 51180) | static generateFlowReportHtml(flow) {
method generateReportCSV (line 51201) | static generateReportCSV(lhr) {
method isFlowResult (line 51245) | static isFlowResult(result) {
method generateReport (line 51254) | static generateReport(result, outputModes) {
method audit (line 51299) | static async audit(artifacts, options) {
method getEntityClassification (line 51385) | static async getEntityClassification(artifacts, context) {
method gather (line 51420) | static async gather(gatherFn, options) {
method createRunnerError (line 51451) | static createRunnerError(err, settings) {
method _getTiming (line 51465) | static _getTiming(artifacts) {
method _runAudits (line 51504) | static async _runAudits(settings, audits, artifacts, runWarnings, comput...
method _runAudit (line 51562) | static async _runAudit(auditDefn, artifacts, sharedAuditContext, runWarn...
method getArtifactRuntimeError (line 51632) | static getArtifactRuntimeError(artifacts) {
method getAuditList (line 51661) | static getAuditList() {
method getGathererList (line 51692) | static getGathererList() {
method _getDataSavePath (line 51705) | static _getDataSavePath(settings) {
method constructor (line 51738) | constructor(session) {
method getContextId (line 51752) | getContextId() {
method clearContextId (line 51759) | clearContextId() {
method _getOrCreateIsolatedContextId (line 51768) | async _getOrCreateIsolatedContextId() {
method _evaluateInContext (line 51790) | async _evaluateInContext(expression, contextId, timeout) {
method evaluateAsync (line 51859) | async evaluateAsync(expression, options = {}) {
method evaluate (line 51885) | evaluate(mainFn, options) {
method evaluateOnNewDocument (line 51903) | async evaluateOnNewDocument(mainFn, options) {
method cacheNativesOnNewDocument (line 51919) | async cacheNativesOnNewDocument() {
method serializeArguments (line 51945) | static serializeArguments(args) {
method serializeDeps (line 51956) | static serializeDeps(deps17) {
method constructor (line 52003) | constructor(cdpSession) {
method id (line 52020) | id() {
method _handleProtocolEvent (line 52029) | _handleProtocolEvent(method, ...params) {
method setTargetInfo (line 52033) | setTargetInfo(targetInfo) {
method hasNextProtocolTimeout (line 52039) | hasNextProtocolTimeout() {
method getNextProtocolTimeout (line 52045) | getNextProtocolTimeout() {
method setNextProtocolTimeout (line 52051) | setNextProtocolTimeout(ms) {
method sendCommand (line 52061) | sendCommand(method, ...params) {
method sendCommandAndIgnore (line 52089) | sendCommandAndIgnore(method, ...params) {
method dispose (line 52096) | async dispose() {
method onCrashPromise (line 52100) | onCrashPromise() {
method constructor (line 52120) | constructor(cdpSession) {
method _onFrameNavigated (line 52136) | async _onFrameNavigated(frameNavigatedEvent) {
method _findSession (line 52153) | _findSession(sessionId) {
method _isAcceptedTargetType (line 52163) | _isAcceptedTargetType(targetType) {
method rootSession (line 52170) | rootSession() {
method mainFrameExecutionContexts (line 52174) | mainFrameExecutionContexts() {
method _onSessionAttached (line 52182) | async _onSessionAttached(cdpSession) {
method _onExecutionContextCreated (line 52226) | _onExecutionContextCreated(event) {
method _onExecutionContextDestroyed (line 52234) | _onExecutionContextDestroyed(event) {
method _onExecutionContextsCleared (line 52237) | _onExecutionContextsCleared() {
method _getProtocolEventListener (line 52246) | _getProtocolEventListener(targetType, sessionId) {
method enable (line 52259) | async enable() {
method disable (line 52276) | async disable() {
method constructor (line 52313) | constructor(session) {
method fetchResource (line 52323) | async fetchResource(url, options = { timeout: 2e3 }) {
method _fetchWithFetchApi (line 52333) | async _fetchWithFetchApi(url) {
method _readIOStream (line 52350) | async _readIOStream(handle, options = { timeout: 2e3 }) {
method _loadNetworkResource (line 52369) | async _loadNetworkResource(url) {
method _fetchResourceOverProtocol (line 52389) | async _fetchResourceOverProtocol(url, options) {
method _wrapWithTimeout (line 52403) | async _wrapWithTimeout(promise, ms) {
method constructor (line 52439) | constructor(targetManager) {
method enable (line 52452) | async enable() {
method disable (line 52468) | async disable() {
method getNavigationUrls (line 52476) | async getNavigationUrls() {
method getInflightRequests (line 52498) | getInflightRequests() {
method isIdle (line 52505) | isIdle() {
method isCriticalIdle (line 52514) | isCriticalIdle() {
method is2Idle (line 52529) | is2Idle() {
method _isIdlePeriod (line 52539) | _isIdlePeriod(allowedRequests, requestFilter) {
method _emitNetworkStatus (line 52555) | _emitNetworkStatus() {
method findNetworkQuietPeriods (line 52575) | static findNetworkQuietPeriods(requests, allowedConcurrentRequests, endT...
method constructor (line 52638) | constructor(page) {
method executionContext (line 52647) | get executionContext() {
method fetcher (line 52651) | get fetcher() {
method targetManager (line 52655) | get targetManager() {
method networkMonitor (line 52659) | get networkMonitor() {
method url (line 52664) | async url() {
method connect (line 52668) | async connect() {
method disconnect (line 52683) | async disconnect() {
function createDependencyError (line 52699) | function createDependencyError(dependency, error) {
function getEmptyArtifactState (line 52705) | function getEmptyArtifactState() {
function collectPhaseArtifacts (line 52722) | async function collectPhaseArtifacts(options) {
function collectArtifactDependencies (line 52778) | async function collectArtifactDependencies(artifact, artifactsById) {
function awaitArtifacts (line 52797) | async function awaitArtifacts(artifactState) {
function getBrowserVersion (line 52831) | async function getBrowserVersion(session) {
function getBenchmarkIndex (line 52841) | async function getBenchmarkIndex(executionContext) {
function getDevicePixelRatio (line 52851) | async function getDevicePixelRatio(executionContext) {
function getSlowHostCpuWarning (line 52861) | function getSlowHostCpuWarning(context) {
function getEnvironmentWarnings (line 52873) | function getEnvironmentWarnings(context) {
function getBaseArtifacts (line 52886) | async function getBaseArtifacts(resolvedConfig, driver, context) {
function deduplicateWarnings (line 52911) | function deduplicateWarnings(warnings) {
function finalizeArtifacts (line 52920) | function finalizeArtifacts(baseArtifacts, gathererArtifacts) {
function snapshotGather (line 52944) | async function snapshotGather(page, options = {}) {
function clearDataForOrigin (line 53012) | async function clearDataForOrigin(session, url, clearStorageTypes) {
function getImportantStorageWarning (line 53040) | async function getImportantStorageWarning(session, url) {
function clearBrowserCaches (line 53058) | async function clearBrowserCaches(session) {
function parseUseragentIntoMetadata (line 53099) | function parseUseragentIntoMetadata(fullVersion, formFactor) {
function matchHostUAVersion (line 53129) | async function matchHostUAVersion(session, userAgent) {
function emulate (line 53136) | async function emulate(session, settings) {
function throttle (line 53158) | async function throttle(session, settings) {
function clearThrottling (line 53166) | async function clearThrottling(session) {
function enableNetwor
Condensed preview — 214 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (4,891K chars).
[
{
"path": ".agent/rules/coding.md",
"chars": 730,
"preview": "---\ntrigger: always_on\n---\n\n# Instructions\n\n- Use only scripts from `package.json` to run commands.\n- Use `npm run build"
},
{
"path": ".claude-plugin/marketplace.json",
"chars": 467,
"preview": "{\n \"name\": \"chrome-devtools-plugins\",\n \"version\": \"1.0.0\",\n \"description\": \"Bundled plugins for actuating and debuggi"
},
{
"path": ".claude-plugin/plugin.json",
"chars": 314,
"preview": "{\n \"name\": \"chrome-devtools-mcp\",\n \"version\": \"latest\",\n \"description\": \"Reliable automation, in-depth debugging, and"
},
{
"path": ".gitattributes",
"chars": 19,
"preview": "* text=auto eol=lf\n"
},
{
"path": ".github/ISSUE_TEMPLATE/01-bug.yml",
"chars": 1929,
"preview": "name: Bug report\ndescription: File a bug report for chrome-devtools-mcp\ntitle: '<short description of the bug>'\ntype: 'B"
},
{
"path": ".github/ISSUE_TEMPLATE/02-feature.yml",
"chars": 1220,
"preview": "name: Feature\ndescription: Suggest an idea for for chrome-devtools-mcp\ntitle: '<short description of the feature request"
},
{
"path": ".github/ISSUE_TEMPLATE/03-task.yml",
"chars": 461,
"preview": "name: Task\ndescription: Work tracking for mainainers only!\ntitle: '[Task]:'\ntype: 'Task'\nbody:\n - type: markdown\n at"
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 28,
"preview": "blank_issues_enabled: false\n"
},
{
"path": ".github/dependabot.yml",
"chars": 1071,
"preview": "version: 2\nupdates:\n - package-ecosystem: npm\n directory: /\n schedule:\n interval: weekly\n day: 'sunday'"
},
{
"path": ".github/workflows/conventional-commit.yml",
"chars": 814,
"preview": "name: 'Conventional Commit'\n\non:\n merge_group:\n pull_request_target:\n types:\n # Defaults\n # https://docs."
},
{
"path": ".github/workflows/pre-release.yml",
"chars": 1043,
"preview": "name: Pre-release\n\npermissions: read-all\n\non:\n workflow_dispatch:\n push:\n branches:\n - release-please-*\n\njobs:"
},
{
"path": ".github/workflows/presubmit.yml",
"chars": 1661,
"preview": "name: Check code before submitting\n\npermissions: read-all\n\non:\n merge_group:\n push:\n branches:\n - main\n pull_"
},
{
"path": ".github/workflows/publish-to-npm-on-tag.yml",
"chars": 2689,
"preview": "name: publish-on-tag\n\non:\n push:\n tags:\n - 'chrome-devtools-mcp-v*'\n workflow_dispatch:\n inputs:\n npm-"
},
{
"path": ".github/workflows/release-please.yml",
"chars": 406,
"preview": "on:\n push:\n branches:\n - main\n\npermissions: read-all\nname: release-please\n\njobs:\n release-please:\n runs-on:"
},
{
"path": ".github/workflows/run-tests.yml",
"chars": 1865,
"preview": "name: Compile and run tests\n\npermissions: read-all\n\non:\n merge_group:\n push:\n branches:\n - main\n pull_request"
},
{
"path": ".gitignore",
"chars": 2312,
"preview": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n.pnpm-debug.log*\n\ntrace.json\ntrace.jso"
},
{
"path": ".mcp.json",
"chars": 96,
"preview": "{\n \"chrome-devtools\": {\n \"command\": \"npx\",\n \"args\": [\"chrome-devtools-mcp@latest\"]\n }\n}\n"
},
{
"path": ".nvmrc",
"chars": 3,
"preview": "v22"
},
{
"path": ".prettierignore",
"chars": 87,
"preview": "# Prettier-only ignores.\nCHANGELOG.md\nsrc/third_party/lighthouse-devtools-mcp-bundle.js"
},
{
"path": ".prettierrc.cjs",
"chars": 340,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @type {import('prettier'"
},
{
"path": ".release-please-manifest.json",
"chars": 20,
"preview": "{\n \".\": \"0.20.2\"\n}\n"
},
{
"path": "CHANGELOG.md",
"chars": 66759,
"preview": "# Changelog\n\n## [0.20.2](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.20.1...chr"
},
{
"path": "CONTRIBUTING.md",
"chars": 5306,
"preview": "# How to contribute\n\nWe'd love to accept your patches and contributions to this project.\n\n## Before you begin\n\n### Sign "
},
{
"path": "LICENSE",
"chars": 11357,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "README.md",
"chars": 28460,
"preview": "# Chrome DevTools MCP\n\n[](https:"
},
{
"path": "SECURITY.md",
"chars": 216,
"preview": "## Security policy\n\nThe Chrome DevTools MCP project takes security very seriously. Please use [Chromium’s process to rep"
},
{
"path": "docs/cli.md",
"chars": 3134,
"preview": "# Chrome DevTools CLI\n\nThe `chrome-devtools-mcp` package includes an **experimental** CLI interface that allows you to i"
},
{
"path": "docs/debugging-android.md",
"chars": 1318,
"preview": "# Experimental: Debugging Chrome on Android\n\nThis is an experimental feature as Puppeteer does not officially support Ch"
},
{
"path": "docs/design-principles.md",
"chars": 1089,
"preview": "# Design Principles\n\nThese are rough guidelines to follow when shipping features for the MCP server.\nApply them with nua"
},
{
"path": "docs/slim-tool-reference.md",
"chars": 758,
"preview": "<!-- AUTO GENERATED DO NOT EDIT - run 'npm run gen' to update-->\n\n# Chrome DevTools MCP Slim Tool Reference (~359 cl100k"
},
{
"path": "docs/tool-reference.md",
"chars": 15842,
"preview": "<!-- AUTO GENERATED DO NOT EDIT - run 'npm run gen' to update-->\n\n# Chrome DevTools MCP Tool Reference (~6940 cl100k_bas"
},
{
"path": "docs/troubleshooting.md",
"chars": 7932,
"preview": "# Troubleshooting\n\n## General tips\n\n- Run `npx chrome-devtools-mcp@latest --help` to test if the MCP server runs on your"
},
{
"path": "eslint.config.mjs",
"chars": 3508,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport js from '@eslint/js';\nim"
},
{
"path": "gemini-extension.json",
"chars": 182,
"preview": "{\n \"name\": \"chrome-devtools-mcp\",\n \"version\": \"latest\",\n \"mcpServers\": {\n \"chrome-devtools\": {\n \"command\": \"n"
},
{
"path": "package.json",
"chars": 3693,
"preview": "{\n \"name\": \"chrome-devtools-mcp\",\n \"version\": \"0.20.2\",\n \"description\": \"MCP server for Chrome DevTools\",\n \"type\": \""
},
{
"path": "puppeteer.config.cjs",
"chars": 309,
"preview": "/**\n * @license\n * Copyright 2025 Google Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @type {import(\"puppetee"
},
{
"path": "release-please-config.json",
"chars": 1011,
"preview": "{\n \"changelog-sections\": [\n {\"type\": \"feat\", \"section\": \"🎉 Features\", \"hidden\": false},\n {\"type\": \"fix\", \"section"
},
{
"path": "rollup.config.mjs",
"chars": 9135,
"preview": "/**\n * Copyright 2021 Google LLC.\n * Copyright (c) Microsoft Corporation.\n *\n * Licensed under the Apache License, Versi"
},
{
"path": "scripts/append-lighthouse-notices.ts",
"chars": 799,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport fs from 'node:fs';\nimpor"
},
{
"path": "scripts/count_tokens.ts",
"chars": 906,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {readFileSync} from 'nod"
},
{
"path": "scripts/eslint_rules/check-license-rule.js",
"chars": 2437,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nconst currentYear = new Date()."
},
{
"path": "scripts/eslint_rules/local-plugin.js",
"chars": 207,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport checkLicenseRule from '."
},
{
"path": "scripts/eval_gemini.ts",
"chars": 7493,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport fs from 'node:fs';\nimpor"
},
{
"path": "scripts/eval_scenarios/console_test.ts",
"chars": 844,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "scripts/eval_scenarios/emulation_test.ts",
"chars": 476,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "scripts/eval_scenarios/emulation_userAgent_test.ts",
"chars": 612,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "scripts/eval_scenarios/emulation_viewport_test.ts",
"chars": 794,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "scripts/eval_scenarios/fix_webpage_issues_test.ts",
"chars": 2044,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n *\n * Eval scenario: user asks to fi"
},
{
"path": "scripts/eval_scenarios/frontend_snapshot_test.ts",
"chars": 958,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n *\n * Eval scenario using \"website\"/"
},
{
"path": "scripts/eval_scenarios/input_parallel_test.ts",
"chars": 934,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "scripts/eval_scenarios/input_test.ts",
"chars": 795,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "scripts/eval_scenarios/isolated_context_test.ts",
"chars": 819,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "scripts/eval_scenarios/lighthouse_a11y_test.ts",
"chars": 473,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "scripts/eval_scenarios/lighthouse_best_practices_test.ts",
"chars": 480,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "scripts/eval_scenarios/navigation_test.ts",
"chars": 495,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "scripts/eval_scenarios/network_test.ts",
"chars": 867,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "scripts/eval_scenarios/page_focus_keyboard_test.ts",
"chars": 2291,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "scripts/eval_scenarios/page_id_routing_test.ts",
"chars": 1537,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "scripts/eval_scenarios/performance_test.ts",
"chars": 532,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "scripts/eval_scenarios/select_page_test.ts",
"chars": 1096,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "scripts/eval_scenarios/snapshot_test.ts",
"chars": 605,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "scripts/generate-cli.ts",
"chars": 4980,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport fs from 'node:fs';\nimpor"
},
{
"path": "scripts/generate-docs.ts",
"chars": 16274,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport fs from 'node:fs';\n\nimpo"
},
{
"path": "scripts/post-build.ts",
"chars": 3577,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport * as fs from 'node:fs';\n"
},
{
"path": "scripts/prepare.ts",
"chars": 2065,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {readFileSync, writeFile"
},
{
"path": "scripts/test.mjs",
"chars": 2538,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\n// Note: can be converted to ts"
},
{
"path": "scripts/tsconfig.json",
"chars": 622,
"preview": "{\n \"extends\": \"../tsconfig.json\",\n \"compilerOptions\": {\n \"target\": \"esnext\",\n \"module\": \"nodenext\",\n \"moduleR"
},
{
"path": "scripts/update-lighthouse.ts",
"chars": 1388,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {execSync} from 'node:ch"
},
{
"path": "scripts/verify-npm-package.mjs",
"chars": 1189,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {execSync} from 'node:ch"
},
{
"path": "scripts/verify-server-json-version.ts",
"chars": 2306,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {execSync} from 'node:ch"
},
{
"path": "server.json",
"chars": 650,
"preview": "{\n \"$schema\": \"https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json\",\n \"name\": \"io.github.Chro"
},
{
"path": "skills/a11y-debugging/SKILL.md",
"chars": 5632,
"preview": "---\nname: a11y-debugging\ndescription: Uses Chrome DevTools MCP for accessibility (a11y) debugging and auditing based on "
},
{
"path": "skills/a11y-debugging/references/a11y-snippets.md",
"chars": 2788,
"preview": "# Accessibility Debugging Snippets\n\nUse these JavaScript snippets with the `evaluate_script` tool.\n\n## 1. Find Orphaned "
},
{
"path": "skills/chrome-devtools/SKILL.md",
"chars": 2294,
"preview": "---\nname: chrome-devtools\ndescription: Uses Chrome DevTools via MCP for efficient debugging, troubleshooting and browser"
},
{
"path": "skills/chrome-devtools-cli/SKILL.md",
"chars": 7223,
"preview": "---\nname: chrome-devtools-cli\ndescription: Use this to skill to write shell scripts or run shell commands to automate ta"
},
{
"path": "skills/chrome-devtools-cli/references/installation.md",
"chars": 879,
"preview": "# Installation\n\nInstall the package globally to make the `chrome-devtools` command available. You only need to do this t"
},
{
"path": "skills/debug-optimize-lcp/SKILL.md",
"chars": 6473,
"preview": "---\nname: debug-optimize-lcp\ndescription: Guides debugging and optimizing Largest Contentful Paint (LCP) using Chrome De"
},
{
"path": "skills/debug-optimize-lcp/references/elements-and-size.md",
"chars": 1326,
"preview": "# Elements and Size for LCP\n\n## What Elements are Considered?\n\nThe types of elements considered for Largest Contentful P"
},
{
"path": "skills/debug-optimize-lcp/references/lcp-breakdown.md",
"chars": 2525,
"preview": "# Largest Contentful Paint (LCP) Breakdown\n\nLCP measures the time from when the user initiates loading the page until th"
},
{
"path": "skills/debug-optimize-lcp/references/lcp-snippets.md",
"chars": 2432,
"preview": "# LCP Debugging Snippets\n\nUse these JavaScript snippets with the `evaluate_script` tool to extract deep insights from th"
},
{
"path": "skills/debug-optimize-lcp/references/optimization-strategies.md",
"chars": 2154,
"preview": "# LCP Optimization Strategies\n\n## 1. Eliminate Resource Load Delay\n\n**Goal**: Ensure the LCP resource starts loading as "
},
{
"path": "skills/troubleshooting/SKILL.md",
"chars": 6345,
"preview": "---\nname: troubleshooting\ndescription: Uses Chrome DevTools MCP and documentation to troubleshoot connection and target "
},
{
"path": "src/DevToolsConnectionAdapter.ts",
"chars": 3425,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type * as puppeteer from"
},
{
"path": "src/DevtoolsUtils.ts",
"chars": 15235,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {PuppeteerDevToolsConnec"
},
{
"path": "src/McpContext.ts",
"chars": 28591,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport fs from 'node:fs/promise"
},
{
"path": "src/McpPage.ts",
"chars": 3272,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {\n Dialog,\n Eleme"
},
{
"path": "src/McpResponse.ts",
"chars": 26647,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {ParsedArguments} f"
},
{
"path": "src/Mutex.ts",
"chars": 839,
"preview": "/**\n * @license\n * Copyright 2025 Google Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport class Mutex {\n static "
},
{
"path": "src/PageCollector.ts",
"chars": 11042,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {FakeIssuesManager} from"
},
{
"path": "src/SlimMcpResponse.ts",
"chars": 684,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {\n TextContent,\n "
},
{
"path": "src/WaitForHelper.ts",
"chars": 4533,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {logger} from './logger."
},
{
"path": "src/bin/chrome-devtools-cli-options.ts",
"chars": 23066,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\n// NOTE: do not edit manually. "
},
{
"path": "src/bin/chrome-devtools-mcp-cli-options.ts",
"chars": 11810,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {YargsOptions} from"
},
{
"path": "src/bin/chrome-devtools-mcp-main.ts",
"chars": 1500,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport '../polyfill.js';\n\nimpor"
},
{
"path": "src/bin/chrome-devtools-mcp.ts",
"chars": 876,
"preview": "#!/usr/bin/env node\n\n/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {ve"
},
{
"path": "src/bin/chrome-devtools.ts",
"chars": 6887,
"preview": "#!/usr/bin/env node\n\n/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport pro"
},
{
"path": "src/bin/cliDefinitions.ts",
"chars": 21987,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\n// NOTE: do not edit manually. "
},
{
"path": "src/browser.ts",
"chars": 7753,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {execSync} from 'node:ch"
},
{
"path": "src/daemon/client.ts",
"chars": 4736,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {spawn} from 'node:child"
},
{
"path": "src/daemon/daemon.ts",
"chars": 5845,
"preview": "#!/usr/bin/env node\n\n/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport fs "
},
{
"path": "src/daemon/types.ts",
"chars": 413,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport type DaemonMessage =\n |"
},
{
"path": "src/daemon/utils.ts",
"chars": 3462,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport fs from 'node:fs';\nimpor"
},
{
"path": "src/devtools.d.ts",
"chars": 214,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\ntype CSSInJS = string & {_tag: "
},
{
"path": "src/formatters/ConsoleFormatter.ts",
"chars": 9745,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {\n createStackTraceForC"
},
{
"path": "src/formatters/IssueFormatter.ts",
"chars": 7454,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {ISSUE_UTILS} from '../i"
},
{
"path": "src/formatters/NetworkFormatter.ts",
"chars": 8355,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n * */\n\nimport {isUtf8} from 'node:bu"
},
{
"path": "src/formatters/SnapshotFormatter.ts",
"chars": 4352,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {TextSnapshot, Text"
},
{
"path": "src/index.ts",
"chars": 8929,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type fs from 'node:fs';\n"
},
{
"path": "src/issue-descriptions.ts",
"chars": 1295,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport * as fs from 'node:fs';\n"
},
{
"path": "src/logger.ts",
"chars": 1152,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport fs from 'node:fs';\n\nimpo"
},
{
"path": "src/polyfill.ts",
"chars": 180,
"preview": "/**\n * @license\n * Copyright 2025 Google Inc.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n// polyfills are now bundled w"
},
{
"path": "src/telemetry/ClearcutLogger.ts",
"chars": 3522,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport process from 'node:proce"
},
{
"path": "src/telemetry/WatchdogClient.ts",
"chars": 2270,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {spawn, type ChildProces"
},
{
"path": "src/telemetry/flagUtils.ts",
"chars": 2147,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {cliOptions} from '"
},
{
"path": "src/telemetry/metricUtils.ts",
"chars": 382,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nconst LATENCY_BUCKETS = [50, 10"
},
{
"path": "src/telemetry/persistence.ts",
"chars": 1972,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport fs from 'node:fs/promise"
},
{
"path": "src/telemetry/types.ts",
"chars": 1873,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\n// Protobuf message interfaces\n"
},
{
"path": "src/telemetry/watchdog/ClearcutSender.ts",
"chars": 6989,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport crypto from 'node:crypto"
},
{
"path": "src/telemetry/watchdog/main.ts",
"chars": 4254,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {WriteStream} from "
},
{
"path": "src/third_party/LIGHTHOUSE_MCP_BUNDLE_THIRD_PARTY_NOTICES",
"chars": 51409,
"preview": "Name: ms\nURL: N/A\nVersion: 2.1.2\nLicense: MIT\n\nThe MIT License (MIT)\n\nCopyright (c) 2016 Zeit, Inc.\n\nPermission is hereb"
},
{
"path": "src/third_party/devtools-formatter-worker.ts",
"chars": 263,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\n// eslint-disable-next-line no-"
},
{
"path": "src/third_party/index.ts",
"chars": 2193,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport 'core-js/modules/es.prom"
},
{
"path": "src/third_party/lighthouse-devtools-mcp-bundle.js",
"chars": 3402058,
"preview": "/**\n * Lighthouse v13.0.3-4-gd6e2a8e40 (Mar 04 2026)\n *\n * Automated auditing, performance metrics, and best practices f"
},
{
"path": "src/tools/ToolDefinition.ts",
"chars": 9263,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {ParsedArguments} f"
},
{
"path": "src/tools/categories.ts",
"chars": 636,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport enum ToolCategory {\n IN"
},
{
"path": "src/tools/console.ts",
"chars": 2654,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {zod} from '../third_par"
},
{
"path": "src/tools/emulation.ts",
"chars": 2103,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n *\n */\n\nimport {zod, PredefinedNetwo"
},
{
"path": "src/tools/extensions.ts",
"chars": 3107,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {zod} from '../third_par"
},
{
"path": "src/tools/input.ts",
"chars": 13421,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {logger} from '../logger"
},
{
"path": "src/tools/lighthouse.ts",
"chars": 3935,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport path from 'node:path';\n\n"
},
{
"path": "src/tools/memory.ts",
"chars": 922,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {zod} from '../third_par"
},
{
"path": "src/tools/network.ts",
"chars": 4129,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {zod} from '../third_par"
},
{
"path": "src/tools/pages.ts",
"chars": 11745,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {logger} from '../logger"
},
{
"path": "src/tools/performance.ts",
"chars": 8342,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport zlib from 'node:zlib';\n\n"
},
{
"path": "src/tools/screencast.ts",
"chars": 2971,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport fs from 'node:fs/promise"
},
{
"path": "src/tools/screenshot.ts",
"chars": 3373,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {zod} from '../third_par"
},
{
"path": "src/tools/script.ts",
"chars": 5073,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {zod} from '../third_par"
},
{
"path": "src/tools/slim/tools.ts",
"chars": 2439,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {Dialog} from '../."
},
{
"path": "src/tools/snapshot.ts",
"chars": 2178,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {zod} from '../third_par"
},
{
"path": "src/tools/tools.ts",
"chars": 1871,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {ParsedArguments} f"
},
{
"path": "src/trace-processing/parse.ts",
"chars": 3590,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {logger} from '../logger"
},
{
"path": "src/types.ts",
"chars": 1073,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {SerializedAXNode, "
},
{
"path": "src/utils/ExtensionRegistry.ts",
"chars": 1212,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport fs from 'node:fs/promise"
},
{
"path": "src/utils/files.ts",
"chars": 610,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport fs from 'node:fs/promise"
},
{
"path": "src/utils/keyboard.ts",
"chars": 3825,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {KeyInput} from '.."
},
{
"path": "src/utils/pagination.ts",
"chars": 1920,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type {PaginationOptions}"
},
{
"path": "src/utils/string.ts",
"chars": 1518,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * Converts a given string "
},
{
"path": "src/utils/types.ts",
"chars": 169,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nexport interface PaginationOpti"
},
{
"path": "src/version.ts",
"chars": 221,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\n// If moved update release-plea"
},
{
"path": "tests/DevtoolsUtils.test.ts",
"chars": 4344,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "tests/McpContext.test.js.snapshot",
"chars": 959,
"preview": "exports[`McpContext > should include detailed network request in structured content 1`] = `\n{\n \"networkRequest\": {\n "
},
{
"path": "tests/McpContext.test.ts",
"chars": 8065,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "tests/McpResponse.test.js.snapshot",
"chars": 43579,
"preview": "exports[`McpResponse > add network request when attached 1`] = `\n## Request http://example.com\nStatus: pending\n### Reque"
},
{
"path": "tests/McpResponse.test.ts",
"chars": 32843,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "tests/PageCollector.test.ts",
"chars": 12576,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "tests/browser.test.ts",
"chars": 2865,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "tests/cli.test.ts",
"chars": 7840,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "tests/daemon/client.test.ts",
"chars": 3247,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "tests/daemon/utils.test.ts",
"chars": 2369,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "tests/e2e/chrome-devtools.test.ts",
"chars": 3839,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "tests/e2e/telemetry.test.ts",
"chars": 6813,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "tests/formatters/ConsoleFormatter.test.js.snapshot",
"chars": 12333,
"preview": "exports[`ConsoleFormatter > toString/toJSON > formats a console.log message toJSON 1`] = `\n{\n \"type\": \"log\",\n \"text\": "
},
{
"path": "tests/formatters/ConsoleFormatter.test.ts",
"chars": 17122,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport {describe, it} from 'nod"
},
{
"path": "tests/formatters/IssueFormatter.test.js.snapshot",
"chars": 1239,
"preview": "exports[`IssueFormatter > formats a detailed issue toJSONDetailed 1`] = `\n{\n \"id\": 5,\n \"type\": \"issue\",\n \"title\": \"Mo"
},
{
"path": "tests/formatters/IssueFormatter.test.ts",
"chars": 6663,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "tests/formatters/NetworkFormatter.test.ts",
"chars": 14618,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "tests/formatters/snapshotFormatter.test.js.snapshot",
"chars": 746,
"preview": "exports[`snapshotFormatter > does not include a note if the snapshot is already verbose 1`] = `\nNote: there is a selecte"
},
{
"path": "tests/formatters/snapshotFormatter.test.ts",
"chars": 7668,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "tests/index.test.js.snapshot",
"chars": 222,
"preview": "exports[`e2e > calls a tool 1`] = `\n[{\"type\":\"text\",\"text\":\"## Pages\\\\n1: about:blank [selected]\"}]\n`;\n\nexports[`e2e > c"
},
{
"path": "tests/index.test.ts",
"chars": 4088,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "tests/server.ts",
"chars": 2780,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport http, {\n type IncomingM"
},
{
"path": "tests/setup.ts",
"chars": 943,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport '../src/polyfill.js';\n\ni"
},
{
"path": "tests/snapshot.ts",
"chars": 443,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\ninterface ScreenshotData {\n ht"
},
{
"path": "tests/telemetry/ClearcutLogger.test.ts",
"chars": 4347,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "tests/telemetry/WatchdogClient.test.ts",
"chars": 3577,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "tests/telemetry/flagUtils.test.ts",
"chars": 3848,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "tests/telemetry/metricUtils.test.ts",
"chars": 1345,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "tests/telemetry/persistence.test.ts",
"chars": 1967,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "tests/telemetry/watchdog/ClearcutSender.test.ts",
"chars": 12859,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "tests/third_party_notices.test.js.snapshot",
"chars": 166498,
"preview": "exports[`THIRD_PARTY_NOTICES > matches snapshot if exists 1`] = `\nName: core-js\nURL: https://core-js.io\nVersion: <VERSIO"
},
{
"path": "tests/third_party_notices.test.ts",
"chars": 672,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport fs from 'node:fs';\nimpor"
},
{
"path": "tests/tools/console.test.js.snapshot",
"chars": 4707,
"preview": "exports[`console > get_console_message > applies source maps to stack traces of Error object (with cause) console.log ar"
},
{
"path": "tests/tools/console.test.ts",
"chars": 20599,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "tests/tools/emulation.test.ts",
"chars": 18722,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "tests/tools/extensions.test.ts",
"chars": 4822,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "tests/tools/fixtures/extension/manifest.json",
"chars": 129,
"preview": "{\n \"manifest_version\": 3,\n \"name\": \"Test Extension\",\n \"version\": \"1.0\",\n \"action\": {\n \"default_popup\": \"popup.htm"
},
{
"path": "tests/tools/fixtures/extension/popup.html",
"chars": 74,
"preview": "<!doctype html>\n<html>\n <body>\n <h1>Test Popup</h1>\n </body>\n</html>\n"
},
{
"path": "tests/tools/fixtures/extension-side-panel/manifest.json",
"chars": 296,
"preview": "{\n \"name\": \"Test Extension Side Panel\",\n \"version\": \"1.0.0\",\n \"manifest_version\": 3,\n \"permissions\": [\"sidePanel\"],\n"
},
{
"path": "tests/tools/fixtures/extension-side-panel/sidepanel.html",
"chars": 123,
"preview": "<!doctype html>\n<html>\n <head>\n <title>Side Panel</title>\n </head>\n <body>\n <h1>Side Panel</h1>\n </body>\n</htm"
},
{
"path": "tests/tools/fixtures/extension-side-panel/sw.js",
"chars": 94,
"preview": "chrome.sidePanel\n .setPanelBehavior({openPanelOnActionClick: true})\n .catch(console.error);\n"
},
{
"path": "tests/tools/fixtures/extension-sw/manifest.json",
"chars": 190,
"preview": "{\n \"manifest_version\": 3,\n \"name\": \"Test Extension with SW\",\n \"version\": \"1.0\",\n \"background\": {\n \"service_worker"
},
{
"path": "tests/tools/fixtures/extension-sw/popup.html",
"chars": 93,
"preview": "<!doctype html>\n<html>\n <body>\n <h1>Extension With Service Worker</h1>\n </body>\n</html>\n"
},
{
"path": "tests/tools/fixtures/extension-sw/sw.js",
"chars": 82,
"preview": "chrome.action.onClicked.addListener(tab => {\n console.log('Action clicked');\n});\n"
},
{
"path": "tests/tools/input.test.ts",
"chars": 26684,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "tests/tools/lighthouse.test.js.snapshot",
"chars": 6946,
"preview": "exports[`lighthouse > lighthouse_audit > runs Lighthouse accessibility audit 1`] = `\n{\n \"Accessibility\": {\n \"score\":"
},
{
"path": "tests/tools/lighthouse.test.ts",
"chars": 5433,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "tests/tools/memory.test.ts",
"chars": 1113,
"preview": "/**\n * @license\n * Copyright 2026 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "tests/tools/network.test.js.snapshot",
"chars": 1681,
"preview": "exports[`network > network_get_request > should get request from previous navigations 1`] = `\n## Request http://localhos"
},
{
"path": "tests/tools/network.test.ts",
"chars": 6145,
"preview": "/**\n * @license\n * Copyright 2025 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport assert from 'node:assert"
},
{
"path": "tests/tools/pages.test.js.snapshot",
"chars": 846,
"preview": "exports[`pages > list_pages > list pages for extension pages with --category-extensions 1`] = `\n## Pages\n1: about:blank "
}
]
// ... and 14 more files (download for full content)
About this extraction
This page contains the full source code of the ChromeDevTools/chrome-devtools-mcp GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 214 files (4.5 MB), approximately 1.2M tokens, and a symbol index with 2193 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.