Skip to content

Commit 0497ae7

Browse files
authored
Merge branch 'ChromeDevTools:main' into disable-default-args
2 parents 8923bc5 + 8e252dd commit 0497ae7

21 files changed

Lines changed: 437 additions & 306 deletions

docs/tool-reference.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@
130130

131131
**Parameters:**
132132

133-
- **pageIdx** (number) **(required)**: The index of the page to close. Call [`list_pages`](#list_pages) to list pages.
133+
- **pageId** (number) **(required)**: The ID of the page to close. Call [`list_pages`](#list_pages) to list pages.
134134

135135
---
136136

@@ -172,7 +172,7 @@
172172

173173
**Parameters:**
174174

175-
- **pageIdx** (number) **(required)**: The index of the page to select. Call [`list_pages`](#list_pages) to get available pages.
175+
- **pageId** (number) **(required)**: The ID of the page to select. Call [`list_pages`](#list_pages) to get available pages.
176176
- **bringToFront** (boolean) _(optional)_: Whether to focus the page and bring it to the top.
177177

178178
---

package-lock.json

Lines changed: 283 additions & 215 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
"mcpName": "io.github.ChromeDevTools/chrome-devtools-mcp",
4242
"devDependencies": {
4343
"@eslint/js": "^9.35.0",
44-
"@modelcontextprotocol/sdk": "1.24.3",
44+
"@modelcontextprotocol/sdk": "1.25.2",
4545
"@rollup/plugin-commonjs": "^29.0.0",
4646
"@rollup/plugin-json": "^6.1.0",
4747
"@rollup/plugin-node-resolve": "^16.0.3",
@@ -53,16 +53,16 @@
5353
"@types/yargs": "^17.0.33",
5454
"@typescript-eslint/eslint-plugin": "^8.43.0",
5555
"@typescript-eslint/parser": "^8.43.0",
56-
"chrome-devtools-frontend": "1.0.1555430",
56+
"chrome-devtools-frontend": "1.0.1565595",
5757
"core-js": "3.47.0",
5858
"debug": "4.4.3",
5959
"eslint": "^9.35.0",
6060
"eslint-import-resolver-typescript": "^4.4.4",
6161
"eslint-plugin-import": "^2.32.0",
6262
"globals": "^17.0.0",
6363
"prettier": "^3.6.2",
64-
"puppeteer": "24.33.0",
65-
"rollup": "4.54.0",
64+
"puppeteer": "24.34.0",
65+
"rollup": "4.55.1",
6666
"rollup-plugin-cleanup": "^3.2.1",
6767
"rollup-plugin-license": "^3.6.0",
6868
"sinon": "^21.0.0",

scripts/post-build.ts

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
import * as fs from 'node:fs';
88
import * as path from 'node:path';
99

10-
import {sed} from './sed.ts';
11-
1210
const BUILD_DIR = path.join(process.cwd(), 'build');
1311

1412
/**
@@ -73,21 +71,6 @@ export const experiments = {
7371
`;
7472
writeFile(runtimeFile, runtimeContent);
7573

76-
// Update protocol_client to remove:
77-
// 1. self.Protocol assignment
78-
// 2. Call to register backend commands.
79-
const protocolClientDir = path.join(
80-
BUILD_DIR,
81-
devtoolsFrontEndCorePath,
82-
'protocol_client',
83-
);
84-
const clientFile = path.join(protocolClientDir, 'protocol_client.js');
85-
const globalAssignment = /self\.Protocol = self\.Protocol \|\| \{\};/;
86-
const registerCommands =
87-
/InspectorBackendCommands\.registerCommands\(InspectorBackend\.inspectorBackend\);/;
88-
sed(clientFile, globalAssignment, '');
89-
sed(clientFile, registerCommands, '');
90-
9174
copyDevToolsDescriptionFiles();
9275
}
9376

scripts/sed.ts

Lines changed: 0 additions & 27 deletions
This file was deleted.

src/McpContext.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ export class McpContext implements Context {
111111
#geolocationMap = new WeakMap<Page, GeolocationOptions>();
112112
#dialog?: Dialog;
113113

114+
#pageIdMap = new WeakMap<Page, number>();
115+
#nextPageId = 1;
116+
114117
#nextSnapshotId = 1;
115118
#traceResults: TraceResult[] = [];
116119

@@ -246,11 +249,11 @@ export class McpContext implements Context {
246249
this.#consoleCollector.addPage(page);
247250
return page;
248251
}
249-
async closePage(pageIdx: number): Promise<void> {
252+
async closePage(pageId: number): Promise<void> {
250253
if (this.#pages.length === 1) {
251254
throw new Error(CLOSE_PAGE_ERROR);
252255
}
253-
const page = this.getPageByIdx(pageIdx);
256+
const page = this.getPageById(pageId);
254257
await page.close({runBeforeUnload: false});
255258
}
256259

@@ -327,15 +330,18 @@ export class McpContext implements Context {
327330
return page;
328331
}
329332

330-
getPageByIdx(idx: number): Page {
331-
const pages = this.#pages;
332-
const page = pages[idx];
333+
getPageById(pageId: number): Page {
334+
const page = this.#pages.find(p => this.#pageIdMap.get(p) === pageId);
333335
if (!page) {
334336
throw new Error('No page found');
335337
}
336338
return page;
337339
}
338340

341+
getPageId(page: Page): number | undefined {
342+
return this.#pageIdMap.get(page);
343+
}
344+
339345
#dialogHandler = (dialog: Dialog): void => {
340346
this.#dialog = dialog;
341347
};
@@ -417,6 +423,12 @@ export class McpContext implements Context {
417423
this.#options.experimentalIncludeAllPages,
418424
);
419425

426+
for (const page of allPages) {
427+
if (!this.#pageIdMap.has(page)) {
428+
this.#pageIdMap.set(page, this.#nextPageId++);
429+
}
430+
}
431+
420432
this.#pages = allPages.filter(page => {
421433
// If we allow debugging DevTools windows, return all pages.
422434
// If we are in regular mode, the user should only see non-DevTools page.

src/McpResponse.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -385,12 +385,10 @@ Call ${handleDialog.name} to handle it before continuing.`);
385385

386386
if (this.#includePages) {
387387
const parts = [`## Pages`];
388-
let idx = 0;
389388
for (const page of context.getPages()) {
390389
parts.push(
391-
`${idx}: ${page.url()}${context.isPageSelected(page) ? ' [selected]' : ''}`,
390+
`${context.getPageId(page)}: ${page.url()}${context.isPageSelected(page) ? ' [selected]' : ''}`,
392391
);
393-
idx++;
394392
}
395393
response.push(...parts);
396394
}

src/browser.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,6 @@ export async function launch(options: McpLaunchOptions): Promise<Browser> {
213213
}
214214
if (options.viewport) {
215215
const [page] = await browser.pages();
216-
// @ts-expect-error internal API for now.
217216
await page?.resize({
218217
contentWidth: options.viewport.width,
219218
contentHeight: options.viewport.height,

src/formatters/consoleFormatter.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export interface ConsoleMessageData {
1515
count?: number;
1616
description?: string;
1717
args?: string[];
18+
stackTrace?: DevTools.StackTrace.StackTrace.StackTrace;
1819
}
1920

2021
// The short format for a console message, based on a previous format.
@@ -46,6 +47,7 @@ export function formatConsoleEventVerbose(
4647
`ID: ${msg.consoleMessageStableId}`,
4748
`Message: ${msg.type}> ${aggregatedIssue ? formatIssue(aggregatedIssue, msg.description, context) : msg.message}`,
4849
aggregatedIssue ? undefined : formatArgs(msg),
50+
formatStackTrace(msg.stackTrace),
4951
].filter(line => !!line);
5052
return result.join('\n');
5153
}
@@ -163,3 +165,42 @@ export function formatIssue(
163165
if (result.length === 0) return 'No affected resources found';
164166
return result.join('\n');
165167
}
168+
169+
function formatStackTrace(
170+
stackTrace: DevTools.StackTrace.StackTrace.StackTrace | undefined,
171+
): string {
172+
if (!stackTrace) {
173+
return '';
174+
}
175+
176+
return [
177+
'### Stack trace',
178+
formatFragment(stackTrace.syncFragment),
179+
...stackTrace.asyncFragments.map(formatAsyncFragment),
180+
].join('\n');
181+
}
182+
183+
function formatFragment(
184+
fragment: DevTools.StackTrace.StackTrace.Fragment,
185+
): string {
186+
return fragment.frames.map(formatFrame).join('\n');
187+
}
188+
189+
function formatAsyncFragment(
190+
fragment: DevTools.StackTrace.StackTrace.AsyncFragment,
191+
): string {
192+
const separatorLineLength = 40;
193+
const prefix = `--- ${fragment.description || 'async'} `;
194+
const separator = prefix + '-'.repeat(separatorLineLength - prefix.length);
195+
return separator + '\n' + formatFragment(fragment);
196+
}
197+
198+
function formatFrame(frame: DevTools.StackTrace.StackTrace.Frame): string {
199+
let result = `at ${frame.name ?? '<anonymous>'}`;
200+
if (frame.uiSourceCode) {
201+
result += ` (${frame.uiSourceCode.displayName()}:${frame.line}:${frame.column})`;
202+
} else if (frame.url) {
203+
result += ` (${frame.url}:${frame.line}:${frame.column})`;
204+
}
205+
return result;
206+
}

src/third_party/devtools.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
export type {
88
IssuesManagerEventTypes,
99
CDPConnection,
10+
StackTrace,
1011
} from '../../node_modules/chrome-devtools-frontend/mcp/mcp.js';
1112
export {
1213
AgentFocus,

0 commit comments

Comments
 (0)