chrome-devtools-mcp 0.21.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +83 -21
  2. package/build/src/HeapSnapshotManager.js +94 -0
  3. package/build/src/McpContext.js +26 -56
  4. package/build/src/McpPage.js +16 -0
  5. package/build/src/McpResponse.js +145 -11
  6. package/build/src/PageCollector.js +10 -24
  7. package/build/src/WaitForHelper.js +31 -0
  8. package/build/src/bin/check-latest-version.js +25 -0
  9. package/build/src/bin/chrome-devtools-mcp-cli-options.js +24 -10
  10. package/build/src/bin/chrome-devtools-mcp-main.js +2 -0
  11. package/build/src/bin/chrome-devtools.js +3 -0
  12. package/build/src/bin/cliDefinitions.js +14 -8
  13. package/build/src/daemon/client.js +1 -1
  14. package/build/src/daemon/daemon.js +0 -4
  15. package/build/src/formatters/HeapSnapshotFormatter.js +38 -0
  16. package/build/src/formatters/NetworkFormatter.js +24 -7
  17. package/build/src/index.js +12 -1
  18. package/build/src/telemetry/ClearcutLogger.js +34 -12
  19. package/build/src/telemetry/flagUtils.js +46 -4
  20. package/build/src/telemetry/toolMetricsUtils.js +88 -0
  21. package/build/src/telemetry/watchdog/ClearcutSender.js +4 -3
  22. package/build/src/third_party/THIRD_PARTY_NOTICES +32 -32
  23. package/build/src/third_party/bundled-packages.json +5 -4
  24. package/build/src/third_party/devtools-formatter-worker.js +61 -64
  25. package/build/src/third_party/devtools-heap-snapshot-worker.js +9690 -0
  26. package/build/src/third_party/index.js +61443 -59378
  27. package/build/src/third_party/lighthouse-devtools-mcp-bundle.js +3501 -2658
  28. package/build/src/tools/categories.js +3 -0
  29. package/build/src/tools/console.js +42 -39
  30. package/build/src/tools/emulation.js +1 -1
  31. package/build/src/tools/extensions.js +5 -11
  32. package/build/src/tools/inPage.js +27 -6
  33. package/build/src/tools/input.js +15 -16
  34. package/build/src/tools/lighthouse.js +2 -2
  35. package/build/src/tools/memory.js +48 -3
  36. package/build/src/tools/network.js +2 -2
  37. package/build/src/tools/pages.js +8 -5
  38. package/build/src/tools/performance.js +1 -1
  39. package/build/src/tools/screencast.js +2 -1
  40. package/build/src/tools/screenshot.js +3 -3
  41. package/build/src/tools/script.js +22 -16
  42. package/build/src/tools/tools.js +2 -0
  43. package/build/src/tools/webmcp.js +63 -0
  44. package/build/src/utils/check-for-updates.js +73 -0
  45. package/build/src/utils/files.js +4 -0
  46. package/build/src/utils/id.js +15 -0
  47. package/build/src/version.js +1 -1
  48. package/package.json +12 -8
  49. package/build/src/utils/ExtensionRegistry.js +0 -35
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { stableIdSymbol } from '../utils/id.js';
7
+ export class HeapSnapshotFormatter {
8
+ #aggregates;
9
+ constructor(aggregates) {
10
+ this.#aggregates = aggregates;
11
+ }
12
+ #getSortedAggregates() {
13
+ return Object.values(this.#aggregates).sort((a, b) => b.self - a.self);
14
+ }
15
+ toString() {
16
+ const sorted = this.#getSortedAggregates();
17
+ const lines = [];
18
+ lines.push('uid,className,count,selfSize,maxRetainedSize');
19
+ for (const info of sorted) {
20
+ const uid = info[stableIdSymbol] ?? '';
21
+ lines.push(`${uid},"${info.name}",${info.count},${info.self},${info.maxRet}`);
22
+ }
23
+ return lines.join('\n');
24
+ }
25
+ toJSON() {
26
+ const sorted = this.#getSortedAggregates();
27
+ return sorted.map(info => ({
28
+ uid: info[stableIdSymbol],
29
+ className: info.name,
30
+ count: info.count,
31
+ selfSize: info.self,
32
+ retainedSize: info.maxRet,
33
+ }));
34
+ }
35
+ static sort(aggregates) {
36
+ return Object.entries(aggregates).sort((a, b) => b[1].self - a[1].self);
37
+ }
38
+ }
@@ -4,6 +4,7 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  * */
6
6
  import { isUtf8 } from 'node:buffer';
7
+ import { DevTools, } from '../third_party/index.js';
7
8
  const BODY_CONTEXT_SIZE_LIMIT = 10000;
8
9
  export class NetworkFormatter {
9
10
  #request;
@@ -40,8 +41,8 @@ export class NetworkFormatter {
40
41
  throw new Error('saveFile is not provided');
41
42
  }
42
43
  if (data) {
43
- await this.#options.saveFile(Buffer.from(data), this.#options.requestFilePath);
44
- this.#requestBodyFilePath = this.#options.requestFilePath;
44
+ const result = await this.#options.saveFile(Buffer.from(data), this.#options.requestFilePath, '.network-request');
45
+ this.#requestBodyFilePath = result.filename;
45
46
  }
46
47
  else {
47
48
  this.#requestBody = requestBodyNotAvailableMessage;
@@ -66,8 +67,8 @@ export class NetworkFormatter {
66
67
  if (!this.#options.saveFile) {
67
68
  throw new Error('saveFile is not provided');
68
69
  }
69
- await this.#options.saveFile(buffer, this.#options.responseFilePath);
70
- this.#responseBodyFilePath = this.#options.responseFilePath;
70
+ const result = await this.#options.saveFile(buffer, this.#options.responseFilePath, '.network-response');
71
+ this.#responseBodyFilePath = result.filename;
71
72
  }
72
73
  catch {
73
74
  // Flatten error handling for buffer() failure and save failure
@@ -96,6 +97,16 @@ export class NetworkFormatter {
96
97
  selectedInDevToolsUI: this.#options.selectedInDevToolsUI,
97
98
  };
98
99
  }
100
+ #redactNetworkHeaders(headers) {
101
+ const headersList = Object.entries(headers).map(item => {
102
+ return { name: item[0], value: item[1] };
103
+ });
104
+ const redacted = DevTools.NetworkRequestFormatter.sanitizeHeaders(headersList);
105
+ return redacted.reduce((acc, item) => {
106
+ acc[item.name] = item.value;
107
+ return acc;
108
+ }, {});
109
+ }
99
110
  toJSONDetailed() {
100
111
  const redirectChain = this.#request.redirectChain();
101
112
  const formattedRedirectChain = redirectChain.reverse().map(request => {
@@ -105,15 +116,21 @@ export class NetworkFormatter {
105
116
  const formatter = new NetworkFormatter(request, {
106
117
  requestId: id,
107
118
  saveFile: this.#options.saveFile,
119
+ redactNetworkHeaders: this.#options.redactNetworkHeaders,
108
120
  });
109
121
  return formatter.toJSON();
110
122
  });
123
+ const responseHeaders = this.#request.response()?.headers();
111
124
  return {
112
125
  ...this.toJSON(),
113
- requestHeaders: this.#request.headers(),
126
+ requestHeaders: this.#options.redactNetworkHeaders
127
+ ? this.#redactNetworkHeaders(this.#request.headers())
128
+ : this.#request.headers(),
114
129
  requestBody: this.#requestBody,
115
130
  requestBodyFilePath: this.#requestBodyFilePath,
116
- responseHeaders: this.#request.response()?.headers(),
131
+ responseHeaders: this.#options.redactNetworkHeaders && responseHeaders
132
+ ? this.#redactNetworkHeaders(responseHeaders)
133
+ : this.#request.response()?.headers(),
117
134
  responseBody: this.#responseBody,
118
135
  responseBodyFilePath: this.#responseBodyFilePath,
119
136
  failure: this.#request.failure()?.errorText,
@@ -210,7 +227,7 @@ function converNetworkRequestDetailedToStringDetailed(data) {
210
227
  response.push(`### Redirect chain`);
211
228
  let indent = 0;
212
229
  for (const request of redirectChain.reverse()) {
213
- response.push(`${' '.repeat(indent)}${convertNetworkRequestConciseToString(request)})}`);
230
+ response.push(`${' '.repeat(indent)}${convertNetworkRequestConciseToString(request)}`);
214
231
  indent++;
215
232
  }
216
233
  }
@@ -101,7 +101,7 @@ export async function createMcpServer(serverArgs, options) {
101
101
  return;
102
102
  }
103
103
  if (tool.annotations.category === ToolCategory.EXTENSIONS &&
104
- !serverArgs.categoryExtensions) {
104
+ serverArgs.categoryExtensions === false) {
105
105
  return;
106
106
  }
107
107
  if (tool.annotations.category === ToolCategory.IN_PAGE &&
@@ -112,6 +112,10 @@ export async function createMcpServer(serverArgs, options) {
112
112
  !serverArgs.experimentalVision) {
113
113
  return;
114
114
  }
115
+ if (tool.annotations.conditions?.includes('experimentalMemory') &&
116
+ !serverArgs.experimentalMemory) {
117
+ return;
118
+ }
115
119
  if (tool.annotations.conditions?.includes('experimentalInteropTools') &&
116
120
  !serverArgs.experimentalInteropTools) {
117
121
  return;
@@ -120,6 +124,10 @@ export async function createMcpServer(serverArgs, options) {
120
124
  !serverArgs.experimentalScreencast) {
121
125
  return;
122
126
  }
127
+ if (tool.annotations.conditions?.includes('experimentalWebmcp') &&
128
+ !serverArgs.experimentalWebmcp) {
129
+ return;
130
+ }
123
131
  const schema = 'pageScoped' in tool &&
124
132
  tool.pageScoped &&
125
133
  serverArgs.experimentalPageIdRouting &&
@@ -142,6 +150,7 @@ export async function createMcpServer(serverArgs, options) {
142
150
  const response = serverArgs.slim
143
151
  ? new SlimMcpResponse(serverArgs)
144
152
  : new McpResponse(serverArgs);
153
+ response.setRedactNetworkHeaders(serverArgs.redactNetworkHeaders);
145
154
  if ('pageScoped' in tool && tool.pageScoped) {
146
155
  const page = serverArgs.experimentalPageIdRouting &&
147
156
  params.pageId &&
@@ -190,6 +199,8 @@ export async function createMcpServer(serverArgs, options) {
190
199
  finally {
191
200
  void clearcutLogger?.logToolInvocation({
192
201
  toolName: tool.name,
202
+ params,
203
+ schema,
193
204
  success,
194
205
  latencyMs: bucketizeLatency(Date.now() - startTime),
195
206
  });
@@ -10,7 +10,7 @@ import { FilePersistence } from './persistence.js';
10
10
  import { McpClient, WatchdogMessageType, OsType, } from './types.js';
11
11
  import { WatchdogClient } from './WatchdogClient.js';
12
12
  const MS_PER_DAY = 24 * 60 * 60 * 1000;
13
- const PARAM_BLOCKLIST = new Set(['uid']);
13
+ export const PARAM_BLOCKLIST = new Set(['uid', 'reqid', 'msgid']);
14
14
  const SUPPORTED_ZOD_TYPES = [
15
15
  'ZodString',
16
16
  'ZodNumber',
@@ -21,7 +21,7 @@ const SUPPORTED_ZOD_TYPES = [
21
21
  function isZodType(type) {
22
22
  return SUPPORTED_ZOD_TYPES.includes(type);
23
23
  }
24
- function getZodType(zodType) {
24
+ export function getZodType(zodType) {
25
25
  const def = zodType._def;
26
26
  const typeName = def.typeName;
27
27
  if (typeName === 'ZodOptional' ||
@@ -37,15 +37,31 @@ function getZodType(zodType) {
37
37
  }
38
38
  throw new Error(`Unsupported zod type for tool parameter: ${typeName}`);
39
39
  }
40
- function transformName(zodType, name) {
40
+ export function transformArgName(zodType, name) {
41
+ const snakeCaseName = name.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);
41
42
  if (zodType === 'ZodString') {
42
- return `${name}_length`;
43
+ return `${snakeCaseName}_length`;
43
44
  }
44
45
  else if (zodType === 'ZodArray') {
45
- return `${name}_count`;
46
+ return `${snakeCaseName}_count`;
46
47
  }
47
48
  else {
48
- return name;
49
+ return snakeCaseName;
50
+ }
51
+ }
52
+ export function transformArgType(zodType) {
53
+ if (zodType === 'ZodString' || zodType === 'ZodArray') {
54
+ return 'number';
55
+ }
56
+ switch (zodType) {
57
+ case 'ZodNumber':
58
+ return 'number';
59
+ case 'ZodBoolean':
60
+ return 'boolean';
61
+ case 'ZodEnum':
62
+ return 'enum';
63
+ default:
64
+ throw new Error(`Unsupported zod type for tool parameter: ${zodType}`);
49
65
  }
50
66
  }
51
67
  function transformValue(zodType, value) {
@@ -91,7 +107,7 @@ export function sanitizeParams(params, schema) {
91
107
  if (!hasEquivalentType(zodType, value)) {
92
108
  throw new Error(`parameter ${name} has type ${zodType} but value ${value} is not of equivalent type`);
93
109
  }
94
- const transformedName = transformName(zodType, name);
110
+ const transformedName = transformArgName(zodType, name);
95
111
  const transformedValue = transformValue(zodType, value);
96
112
  transformed[transformedName] = transformedValue;
97
113
  }
@@ -153,15 +169,21 @@ export class ClearcutLogger {
153
169
  }
154
170
  }
155
171
  async logToolInvocation(args) {
172
+ const tool_invocation = {
173
+ tool_name: args.toolName,
174
+ success: args.success,
175
+ latency_ms: args.latencyMs,
176
+ };
177
+ if (Object.keys(args.params).length > 0) {
178
+ tool_invocation.tool_params = {
179
+ [`${args.toolName}_params`]: sanitizeParams(args.params, args.schema),
180
+ };
181
+ }
156
182
  this.#watchdog.send({
157
183
  type: WatchdogMessageType.LOG_EVENT,
158
184
  payload: {
159
185
  mcp_client: this.#mcpClient,
160
- tool_invocation: {
161
- tool_name: args.toolName,
162
- success: args.success,
163
- latency_ms: args.latencyMs,
164
- },
186
+ tool_invocation: tool_invocation,
165
187
  },
166
188
  });
167
189
  }
@@ -4,6 +4,14 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
  import { toSnakeCase } from '../utils/string.js';
7
+ /**
8
+ * For enums, log the value as uppercase.
9
+ * We're going to have an enum for such flags with choices represented
10
+ * as an `enum` where the keys of the enum will map to the uppercase `choice`.
11
+ */
12
+ function formatEnumChoice(snakeCaseName, choice) {
13
+ return `${snakeCaseName}_${choice}`.toUpperCase();
14
+ }
7
15
  /**
8
16
  * Computes telemetry flag usage from parsed arguments and CLI options.
9
17
  *
@@ -14,6 +22,8 @@ import { toSnakeCase } from '../utils/string.js';
14
22
  * - The provided value differs from the default value.
15
23
  * - Boolean flags are logged with their literal value.
16
24
  * - String flags with defined `choices` (Enums) are logged as their uppercase value.
25
+ *
26
+ * IMPORTANT: keep getPossibleFlagMetrics() in sync with this function.
17
27
  */
18
28
  export function computeFlagUsage(args, options) {
19
29
  const usage = {};
@@ -35,11 +45,43 @@ export function computeFlagUsage(args, options) {
35
45
  typeof value === 'string' &&
36
46
  'choices' in config &&
37
47
  config.choices) {
38
- // For enums, log the value as uppercase
39
- // We're going to have an enum for such flags with choices represented
40
- // as an `enum` where the keys of the enum will map to the uppercase `choice`.
41
- usage[snakeCaseName] = `${snakeCaseName}_${value}`.toUpperCase();
48
+ usage[snakeCaseName] = formatEnumChoice(snakeCaseName, value);
42
49
  }
43
50
  }
44
51
  return usage;
45
52
  }
53
+ /**
54
+ * Computes the list of possible flag metrics based on the CLI options.
55
+ *
56
+ * IMPORTANT: keep this function in sync with computeFlagUsage().
57
+ */
58
+ export function getPossibleFlagMetrics(options) {
59
+ const metrics = [];
60
+ for (const [flagName, config] of Object.entries(options)) {
61
+ const snakeCaseName = toSnakeCase(flagName);
62
+ // _present is always a possible metric
63
+ metrics.push({
64
+ name: `${snakeCaseName}_present`,
65
+ flagType: 'boolean',
66
+ });
67
+ if (config.type === 'boolean') {
68
+ metrics.push({
69
+ name: snakeCaseName,
70
+ flagType: 'boolean',
71
+ });
72
+ }
73
+ else if (config.type === 'string' &&
74
+ 'choices' in config &&
75
+ config.choices) {
76
+ metrics.push({
77
+ name: snakeCaseName,
78
+ flagType: 'enum',
79
+ choices: [
80
+ `${snakeCaseName.toUpperCase()}_UNSPECIFIED`,
81
+ ...config.choices.map(choice => formatEnumChoice(snakeCaseName, choice)),
82
+ ],
83
+ });
84
+ }
85
+ }
86
+ return metrics;
87
+ }
@@ -0,0 +1,88 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { transformArgName, transformArgType, getZodType, PARAM_BLOCKLIST, } from './ClearcutLogger.js';
7
+ /**
8
+ * Validates that all values in an enum are of the homogeneous primitive type.
9
+ * Returns the primitive type string. Throws an error if heterogeneous.
10
+ */
11
+ export function validateEnumHomogeneity(values) {
12
+ const firstType = typeof values[0];
13
+ for (const val of values) {
14
+ if (typeof val !== firstType) {
15
+ throw new Error('Heterogeneous enum types found');
16
+ }
17
+ }
18
+ return firstType;
19
+ }
20
+ export function applyToExistingMetrics(existing, update) {
21
+ const updated = applyToExisting(existing, update);
22
+ const existingByName = new Map(existing.map(tool => [tool.name, tool]));
23
+ const updatedByName = new Map(update.map(tool => [tool.name, tool]));
24
+ return updated.map(tool => {
25
+ const existingTool = existingByName.get(tool.name);
26
+ const updatedTool = updatedByName.get(tool.name);
27
+ // If the tool still exists in the update, we will update the args.
28
+ if (existingTool && updatedTool) {
29
+ const updatedArgs = applyToExisting(existingTool.args, updatedTool.args);
30
+ return { ...tool, args: updatedArgs };
31
+ }
32
+ return tool;
33
+ });
34
+ }
35
+ function applyToExisting(existing, update) {
36
+ const existingNames = new Set(existing.map(item => item.name));
37
+ const updatedNames = new Set(update.map(item => item.name));
38
+ const result = [];
39
+ // Keep the original ordering.
40
+ for (const entry of existing) {
41
+ const toAdd = { ...entry };
42
+ if (!updatedNames.has(entry.name)) {
43
+ toAdd.isDeprecated = true;
44
+ }
45
+ result.push(toAdd);
46
+ }
47
+ // New entries must be added to the very back of the list.
48
+ for (const entry of update) {
49
+ if (!existingNames.has(entry.name)) {
50
+ result.push({ ...entry });
51
+ }
52
+ }
53
+ return result;
54
+ }
55
+ /**
56
+ * Generates tool metrics from tool definitions.
57
+ */
58
+ export function generateToolMetrics(tools) {
59
+ return tools.map(tool => {
60
+ const args = [];
61
+ for (const [name, schema] of Object.entries(tool.schema)) {
62
+ if (PARAM_BLOCKLIST.has(name)) {
63
+ continue;
64
+ }
65
+ const zodType = getZodType(schema);
66
+ const transformedName = transformArgName(zodType, name);
67
+ let argType = transformArgType(zodType);
68
+ if (argType === 'enum') {
69
+ let values;
70
+ if (schema._def.values?.length > 0) {
71
+ values = schema._def.values;
72
+ }
73
+ else {
74
+ values = schema._def.innerType._def.values;
75
+ }
76
+ argType = validateEnumHomogeneity(values);
77
+ }
78
+ args.push({
79
+ name: transformedName,
80
+ argType,
81
+ });
82
+ }
83
+ return {
84
+ name: tool.name,
85
+ args,
86
+ };
87
+ });
88
+ }
@@ -42,13 +42,14 @@ export class ClearcutSender {
42
42
  this.#sessionId = crypto.randomUUID();
43
43
  this.#sessionCreated = Date.now();
44
44
  }
45
- logger('Enqueing telemetry event', JSON.stringify(event, null, 2));
46
- this.#addToBuffer({
45
+ const eventToSend = {
47
46
  ...event,
48
47
  session_id: this.#sessionId,
49
48
  app_version: this.#appVersion,
50
49
  os_type: this.#osType,
51
- });
50
+ };
51
+ logger('Enqueing telemetry event', JSON.stringify(eventToSend, null, 2));
52
+ this.#addToBuffer(eventToSend);
52
53
  if (!this.#timerStarted) {
53
54
  this.#timerStarted = true;
54
55
  this.#scheduleFlush(this.#flushIntervalMs);
@@ -293,6 +293,30 @@ Permission to use, copy, modify, and/or distribute this software for any purpose
293
293
  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
294
294
 
295
295
 
296
+ -------------------- DEPENDENCY DIVIDER --------------------
297
+
298
+ Name: semver
299
+ URL: git+https://github.com/npm/node-semver.git
300
+ Version: 7.7.4
301
+ License: ISC
302
+
303
+ The ISC License
304
+
305
+ Copyright (c) Isaac Z. Schlueter and Contributors
306
+
307
+ Permission to use, copy, modify, and/or distribute this software for any
308
+ purpose with or without fee is hereby granted, provided that the above
309
+ copyright notice and this permission notice appear in all copies.
310
+
311
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
312
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
313
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
314
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
315
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
316
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
317
+ IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
318
+
319
+
296
320
  -------------------- DEPENDENCY DIVIDER --------------------
297
321
 
298
322
  Name: debug
@@ -422,7 +446,7 @@ SOFTWARE.
422
446
 
423
447
  Name: @modelcontextprotocol/sdk
424
448
  URL: https://modelcontextprotocol.io
425
- Version: 1.28.0
449
+ Version: 1.29.0
426
450
  License: MIT
427
451
 
428
452
  MIT License
@@ -818,7 +842,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
818
842
 
819
843
  Name: puppeteer-core
820
844
  URL: https://github.com/puppeteer/puppeteer/tree/main/packages/puppeteer-core
821
- Version: 24.40.0
845
+ Version: 24.42.0
822
846
  License: Apache-2.0
823
847
 
824
848
  -------------------- DEPENDENCY DIVIDER --------------------
@@ -828,30 +852,6 @@ URL: https://github.com/puppeteer/puppeteer/tree/main/packages/browsers
828
852
  Version: 2.13.0
829
853
  License: Apache-2.0
830
854
 
831
- -------------------- DEPENDENCY DIVIDER --------------------
832
-
833
- Name: semver
834
- URL: git+https://github.com/npm/node-semver.git
835
- Version: 7.7.4
836
- License: ISC
837
-
838
- The ISC License
839
-
840
- Copyright (c) Isaac Z. Schlueter and Contributors
841
-
842
- Permission to use, copy, modify, and/or distribute this software for any
843
- purpose with or without fee is hereby granted, provided that the above
844
- copyright notice and this permission notice appear in all copies.
845
-
846
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
847
- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
848
- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
849
- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
850
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
851
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
852
- IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
853
-
854
-
855
855
  -------------------- DEPENDENCY DIVIDER --------------------
856
856
 
857
857
  Name: proxy-agent
@@ -1237,7 +1237,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1237
1237
 
1238
1238
  Name: basic-ftp
1239
1239
  URL: https://github.com/patrickjuchli/basic-ftp.git
1240
- Version: 5.2.0
1240
+ Version: 5.3.0
1241
1241
  License: MIT
1242
1242
 
1243
1243
  Copyright (c) 2019 Patrick Juchli
@@ -2459,7 +2459,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
2459
2459
 
2460
2460
  Name: @paulirish/trace_engine
2461
2461
  URL: N/A
2462
- Version: 0.0.61
2462
+ Version: 0.0.64
2463
2463
  License: BSD-3-Clause
2464
2464
 
2465
2465
  // Copyright 2014 The Chromium Authors
@@ -2525,7 +2525,7 @@ SOFTWARE.
2525
2525
 
2526
2526
  Name: axe-core
2527
2527
  URL: https://www.deque.com/axe/
2528
- Version: 4.11.0
2528
+ Version: 4.11.2
2529
2529
  License: MPL-2.0
2530
2530
 
2531
2531
  Mozilla Public License, version 2.0
@@ -3961,7 +3961,7 @@ SOFTWARE.
3961
3961
 
3962
3962
  Name: puppeteer-core
3963
3963
  URL: https://github.com/puppeteer/puppeteer/tree/main/packages/puppeteer-core
3964
- Version: 24.23.0
3964
+ Version: 24.40.0
3965
3965
  License: Apache-2.0
3966
3966
 
3967
3967
  -------------------- DEPENDENCY DIVIDER --------------------
@@ -4027,7 +4027,7 @@ SOFTWARE.
4027
4027
 
4028
4028
  Name: tldts-core
4029
4029
  URL: https://github.com/remusao/tldts#readme
4030
- Version: 7.0.17
4030
+ Version: 7.0.27
4031
4031
  License: MIT
4032
4032
 
4033
4033
  Copyright (c) 2017 Thomas Parisot, 2018 Rémi Berson
@@ -4049,7 +4049,7 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTH
4049
4049
 
4050
4050
  Name: tldts-icann
4051
4051
  URL: https://github.com/remusao/tldts#readme
4052
- Version: 7.0.17
4052
+ Version: 7.0.27
4053
4053
  License: MIT
4054
4054
 
4055
4055
  Copyright (c) 2017 Thomas Parisot, 2018 Rémi Berson
@@ -1,9 +1,10 @@
1
1
  {
2
- "@modelcontextprotocol/sdk": "1.28.0",
3
- "chrome-devtools-frontend": "1.0.1602348",
2
+ "@modelcontextprotocol/sdk": "1.29.0",
3
+ "chrome-devtools-frontend": "1.0.1613625",
4
4
  "core-js": "3.49.0",
5
5
  "debug": "4.4.3",
6
- "lighthouse": "13.0.3",
6
+ "lighthouse": "13.1.0",
7
+ "semver": "^7.7.4",
7
8
  "yargs": "18.0.0",
8
- "puppeteer-core": "24.40.0"
9
+ "puppeteer-core": "24.42.0"
9
10
  }