chrome-devtools-mcp 0.22.0 → 0.24.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.
- package/README.md +4 -0
- package/build/src/DevToolsConnectionAdapter.js +1 -0
- package/build/src/DevtoolsUtils.js +1 -0
- package/build/src/HeapSnapshotManager.js +16 -0
- package/build/src/McpContext.js +54 -126
- package/build/src/McpPage.js +204 -0
- package/build/src/McpResponse.js +44 -6
- package/build/src/Mutex.js +1 -0
- package/build/src/PageCollector.js +1 -0
- package/build/src/SlimMcpResponse.js +1 -0
- package/build/src/TextSnapshot.js +236 -0
- package/build/src/WaitForHelper.js +6 -0
- package/build/src/bin/check-latest-version.js +1 -0
- package/build/src/bin/chrome-devtools-cli-options.js +206 -46
- package/build/src/bin/chrome-devtools-mcp-cli-options.js +13 -1
- package/build/src/bin/chrome-devtools-mcp-main.js +1 -0
- package/build/src/bin/chrome-devtools-mcp.js +1 -0
- package/build/src/bin/chrome-devtools.js +27 -27
- package/build/src/browser.js +1 -0
- package/build/src/daemon/client.js +14 -12
- package/build/src/daemon/daemon.js +7 -5
- package/build/src/daemon/types.js +1 -0
- package/build/src/daemon/utils.js +20 -14
- package/build/src/formatters/ConsoleFormatter.js +48 -1
- package/build/src/formatters/HeapSnapshotFormatter.js +18 -2
- package/build/src/formatters/IssueFormatter.js +1 -0
- package/build/src/formatters/NetworkFormatter.js +1 -0
- package/build/src/formatters/SnapshotFormatter.js +2 -1
- package/build/src/index.js +114 -51
- package/build/src/issue-descriptions.js +1 -0
- package/build/src/logger.js +1 -0
- package/build/src/polyfill.js +1 -0
- package/build/src/telemetry/ClearcutLogger.js +13 -1
- package/build/src/telemetry/WatchdogClient.js +1 -0
- package/build/src/telemetry/flagUtils.js +1 -0
- package/build/src/telemetry/metricUtils.js +1 -0
- package/build/src/telemetry/persistence.js +1 -0
- package/build/src/telemetry/toolMetricsUtils.js +2 -1
- package/build/src/telemetry/types.js +1 -0
- package/build/src/telemetry/watchdog/ClearcutSender.js +1 -0
- package/build/src/telemetry/watchdog/main.js +1 -0
- package/build/src/third_party/THIRD_PARTY_NOTICES +32 -5
- package/build/src/third_party/bundled-packages.json +3 -2
- package/build/src/third_party/devtools-formatter-worker.js +2451 -2933
- package/build/src/third_party/devtools-heap-snapshot-worker.js +32 -26
- package/build/src/third_party/index.js +1942 -1536
- package/build/src/third_party/lighthouse-devtools-mcp-bundle.js +21717 -20261
- package/build/src/tools/ToolDefinition.js +1 -0
- package/build/src/tools/categories.js +6 -2
- package/build/src/tools/console.js +3 -0
- package/build/src/tools/emulation.js +2 -0
- package/build/src/tools/extensions.js +6 -0
- package/build/src/tools/inPage.js +5 -35
- package/build/src/tools/input.js +13 -2
- package/build/src/tools/lighthouse.js +17 -9
- package/build/src/tools/memory.js +34 -1
- package/build/src/tools/network.js +7 -2
- package/build/src/tools/pages.js +218 -146
- package/build/src/tools/performance.js +6 -0
- package/build/src/tools/screencast.js +25 -10
- package/build/src/tools/screenshot.js +3 -0
- package/build/src/tools/script.js +2 -0
- package/build/src/tools/slim/tools.js +4 -0
- package/build/src/tools/snapshot.js +5 -1
- package/build/src/tools/tools.js +1 -0
- package/build/src/tools/webmcp.js +3 -0
- package/build/src/trace-processing/parse.js +1 -0
- package/build/src/types.js +1 -0
- package/build/src/utils/check-for-updates.js +1 -0
- package/build/src/utils/files.js +5 -10
- package/build/src/utils/id.js +1 -0
- package/build/src/utils/keyboard.js +1 -0
- package/build/src/utils/pagination.js +1 -0
- package/build/src/utils/string.js +1 -0
- package/build/src/utils/types.js +1 -0
- package/build/src/version.js +2 -1
- package/package.json +10 -9
- package/build/src/bin/cliDefinitions.js +0 -621
package/build/src/index.js
CHANGED
|
@@ -12,11 +12,68 @@ import { Mutex } from './Mutex.js';
|
|
|
12
12
|
import { SlimMcpResponse } from './SlimMcpResponse.js';
|
|
13
13
|
import { ClearcutLogger } from './telemetry/ClearcutLogger.js';
|
|
14
14
|
import { bucketizeLatency } from './telemetry/metricUtils.js';
|
|
15
|
-
import { McpServer, SetLevelRequestSchema, } from './third_party/index.js';
|
|
16
|
-
import {
|
|
15
|
+
import { McpServer, SetLevelRequestSchema, ListRootsResultSchema, RootsListChangedNotificationSchema, } from './third_party/index.js';
|
|
16
|
+
import { labels, OFF_BY_DEFAULT_CATEGORIES } from './tools/categories.js';
|
|
17
17
|
import { pageIdSchema } from './tools/ToolDefinition.js';
|
|
18
18
|
import { createTools } from './tools/tools.js';
|
|
19
19
|
import { VERSION } from './version.js';
|
|
20
|
+
export function buildFlag(category) {
|
|
21
|
+
return `category${category.charAt(0).toUpperCase() + category.slice(1)}`;
|
|
22
|
+
}
|
|
23
|
+
function buildDisabledMessage(toolName, flag, categoryLabel) {
|
|
24
|
+
const reason = categoryLabel
|
|
25
|
+
? `is in category ${categoryLabel} which`
|
|
26
|
+
: `requires experimental feature ${flag} and`;
|
|
27
|
+
return `Tool ${toolName} ${reason} is currently disabled. Enable it by running chrome-devtools start ${flag}=true. For more information check the README.`;
|
|
28
|
+
}
|
|
29
|
+
function getCategoryStatus(category, serverArgs) {
|
|
30
|
+
const categoryFlag = buildFlag(category);
|
|
31
|
+
const flagValue = serverArgs[categoryFlag];
|
|
32
|
+
const isDisabled = OFF_BY_DEFAULT_CATEGORIES.includes(category)
|
|
33
|
+
? !flagValue
|
|
34
|
+
: flagValue === false;
|
|
35
|
+
if (isDisabled) {
|
|
36
|
+
return {
|
|
37
|
+
categoryFlag,
|
|
38
|
+
disabled: true,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
disabled: false,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function getConditionStatus(condition, serverArgs) {
|
|
46
|
+
if (condition && !serverArgs[condition]) {
|
|
47
|
+
return { conditionFlag: condition, disabled: true };
|
|
48
|
+
}
|
|
49
|
+
return { disabled: false };
|
|
50
|
+
}
|
|
51
|
+
function getToolStatusInfo(tool, serverArgs) {
|
|
52
|
+
const category = tool.annotations.category;
|
|
53
|
+
const categoryCheck = getCategoryStatus(category, serverArgs);
|
|
54
|
+
if (category && categoryCheck.disabled) {
|
|
55
|
+
if (!categoryCheck.categoryFlag) {
|
|
56
|
+
throw new Error('when the category is disabled there should always be a flag set');
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
disabled: true,
|
|
60
|
+
reason: buildDisabledMessage(tool.name, `--${categoryCheck.categoryFlag}`, labels[category]),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
for (const condition of tool.annotations.conditions || []) {
|
|
64
|
+
const conditionCheck = getConditionStatus(condition, serverArgs);
|
|
65
|
+
if (conditionCheck.disabled) {
|
|
66
|
+
if (!conditionCheck.conditionFlag) {
|
|
67
|
+
throw new Error('when the condition is disabled there should always be a flag set');
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
disabled: true,
|
|
71
|
+
reason: buildDisabledMessage(tool.name, `--${conditionCheck.conditionFlag}`),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return { disabled: false };
|
|
76
|
+
}
|
|
20
77
|
export async function createMcpServer(serverArgs, options) {
|
|
21
78
|
let clearcutLogger;
|
|
22
79
|
if (serverArgs.usageStatistics) {
|
|
@@ -36,11 +93,29 @@ export async function createMcpServer(serverArgs, options) {
|
|
|
36
93
|
server.server.setRequestHandler(SetLevelRequestSchema, () => {
|
|
37
94
|
return {};
|
|
38
95
|
});
|
|
96
|
+
const updateRoots = async () => {
|
|
97
|
+
if (!server.server.getClientCapabilities()?.roots) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
try {
|
|
101
|
+
const roots = await server.server.request({ method: 'roots/list' }, ListRootsResultSchema);
|
|
102
|
+
context?.setRoots(roots.roots);
|
|
103
|
+
}
|
|
104
|
+
catch (e) {
|
|
105
|
+
logger('Failed to list roots', e);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
39
108
|
server.server.oninitialized = () => {
|
|
40
109
|
const clientName = server.server.getClientVersion()?.name;
|
|
41
110
|
if (clientName) {
|
|
42
111
|
clearcutLogger?.setClientName(clientName);
|
|
43
112
|
}
|
|
113
|
+
if (server.server.getClientCapabilities()?.roots) {
|
|
114
|
+
void updateRoots();
|
|
115
|
+
server.server.setNotificationHandler(RootsListChangedNotificationSchema, () => {
|
|
116
|
+
void updateRoots();
|
|
117
|
+
});
|
|
118
|
+
}
|
|
44
119
|
};
|
|
45
120
|
let context;
|
|
46
121
|
async function getContext() {
|
|
@@ -83,49 +158,14 @@ export async function createMcpServer(serverArgs, options) {
|
|
|
83
158
|
experimentalIncludeAllPages: serverArgs.experimentalIncludeAllPages,
|
|
84
159
|
performanceCrux: serverArgs.performanceCrux,
|
|
85
160
|
});
|
|
161
|
+
await updateRoots();
|
|
86
162
|
}
|
|
87
163
|
return context;
|
|
88
164
|
}
|
|
89
165
|
const toolMutex = new Mutex();
|
|
90
166
|
function registerTool(tool) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
if (tool.annotations.category === ToolCategory.PERFORMANCE &&
|
|
96
|
-
serverArgs.categoryPerformance === false) {
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
if (tool.annotations.category === ToolCategory.NETWORK &&
|
|
100
|
-
serverArgs.categoryNetwork === false) {
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
if (tool.annotations.category === ToolCategory.EXTENSIONS &&
|
|
104
|
-
serverArgs.categoryExtensions === false) {
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
if (tool.annotations.category === ToolCategory.IN_PAGE &&
|
|
108
|
-
!serverArgs.categoryInPageTools) {
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
if (tool.annotations.conditions?.includes('computerVision') &&
|
|
112
|
-
!serverArgs.experimentalVision) {
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
if (tool.annotations.conditions?.includes('experimentalMemory') &&
|
|
116
|
-
!serverArgs.experimentalMemory) {
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
if (tool.annotations.conditions?.includes('experimentalInteropTools') &&
|
|
120
|
-
!serverArgs.experimentalInteropTools) {
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
if (tool.annotations.conditions?.includes('screencast') &&
|
|
124
|
-
!serverArgs.experimentalScreencast) {
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
if (tool.annotations.conditions?.includes('experimentalWebmcp') &&
|
|
128
|
-
!serverArgs.experimentalWebmcp) {
|
|
167
|
+
const { disabled, reason: disabledReason } = getToolStatusInfo(tool, serverArgs);
|
|
168
|
+
if (disabled && !serverArgs.viaCli) {
|
|
129
169
|
return;
|
|
130
170
|
}
|
|
131
171
|
const schema = 'pageScoped' in tool &&
|
|
@@ -139,6 +179,17 @@ export async function createMcpServer(serverArgs, options) {
|
|
|
139
179
|
inputSchema: schema,
|
|
140
180
|
annotations: tool.annotations,
|
|
141
181
|
}, async (params) => {
|
|
182
|
+
if (disabledReason) {
|
|
183
|
+
return {
|
|
184
|
+
content: [
|
|
185
|
+
{
|
|
186
|
+
type: 'text',
|
|
187
|
+
text: disabledReason,
|
|
188
|
+
},
|
|
189
|
+
],
|
|
190
|
+
isError: true,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
142
193
|
const guard = await toolMutex.acquire();
|
|
143
194
|
const startTime = Date.now();
|
|
144
195
|
let success = false;
|
|
@@ -151,29 +202,40 @@ export async function createMcpServer(serverArgs, options) {
|
|
|
151
202
|
? new SlimMcpResponse(serverArgs)
|
|
152
203
|
: new McpResponse(serverArgs);
|
|
153
204
|
response.setRedactNetworkHeaders(serverArgs.redactNetworkHeaders);
|
|
154
|
-
|
|
205
|
+
try {
|
|
155
206
|
const page = serverArgs.experimentalPageIdRouting &&
|
|
156
207
|
params.pageId &&
|
|
157
208
|
!serverArgs.slim
|
|
158
209
|
? context.getPageById(params.pageId)
|
|
159
210
|
: context.getSelectedMcpPage();
|
|
160
211
|
response.setPage(page);
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
212
|
+
if (tool.blockedByDialog) {
|
|
213
|
+
page.throwIfDialogOpen();
|
|
214
|
+
}
|
|
215
|
+
if ('pageScoped' in tool && tool.pageScoped) {
|
|
216
|
+
await tool.handler({
|
|
217
|
+
params,
|
|
218
|
+
page,
|
|
219
|
+
}, response, context);
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
await tool.handler(
|
|
223
|
+
// @ts-expect-error types do not match.
|
|
224
|
+
{
|
|
225
|
+
params,
|
|
226
|
+
}, response, context);
|
|
227
|
+
}
|
|
165
228
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
// @ts-expect-error types do not match.
|
|
169
|
-
{
|
|
170
|
-
params,
|
|
171
|
-
}, response, context);
|
|
229
|
+
catch (err) {
|
|
230
|
+
response.setError(err);
|
|
172
231
|
}
|
|
173
232
|
const { content, structuredContent } = await response.handle(tool.name, context);
|
|
174
233
|
const result = {
|
|
175
234
|
content,
|
|
176
235
|
};
|
|
236
|
+
if (response.error) {
|
|
237
|
+
result.isError = true;
|
|
238
|
+
}
|
|
177
239
|
success = true;
|
|
178
240
|
if (serverArgs.experimentalStructuredContent) {
|
|
179
241
|
result.structuredContent = structuredContent;
|
|
@@ -228,3 +290,4 @@ Google collects usage statistics to improve Chrome DevTools MCP. To opt-out, run
|
|
|
228
290
|
For more details, visit: https://github.com/ChromeDevTools/chrome-devtools-mcp#usage-statistics`);
|
|
229
291
|
}
|
|
230
292
|
};
|
|
293
|
+
//# sourceMappingURL=index.js.map
|
package/build/src/logger.js
CHANGED
package/build/src/polyfill.js
CHANGED
|
@@ -64,9 +64,20 @@ export function transformArgType(zodType) {
|
|
|
64
64
|
throw new Error(`Unsupported zod type for tool parameter: ${zodType}`);
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
|
+
const BUCKETS = [
|
|
68
|
+
0, 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000,
|
|
69
|
+
];
|
|
70
|
+
function bucketize(value) {
|
|
71
|
+
for (const bucket of BUCKETS) {
|
|
72
|
+
if (bucket >= value) {
|
|
73
|
+
return bucket;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return BUCKETS[BUCKETS.length - 1];
|
|
77
|
+
}
|
|
67
78
|
function transformValue(zodType, value) {
|
|
68
79
|
if (zodType === 'ZodString') {
|
|
69
|
-
return value.length;
|
|
80
|
+
return bucketize(value.length);
|
|
70
81
|
}
|
|
71
82
|
else if (zodType === 'ZodArray') {
|
|
72
83
|
return value.length;
|
|
@@ -239,3 +250,4 @@ export class ClearcutLogger {
|
|
|
239
250
|
return !isSameDay;
|
|
240
251
|
}
|
|
241
252
|
}
|
|
253
|
+
//# sourceMappingURL=ClearcutLogger.js.map
|
|
@@ -32,7 +32,7 @@ export function applyToExistingMetrics(existing, update) {
|
|
|
32
32
|
return tool;
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
|
-
function applyToExisting(existing, update) {
|
|
35
|
+
export function applyToExisting(existing, update) {
|
|
36
36
|
const existingNames = new Set(existing.map(item => item.name));
|
|
37
37
|
const updatedNames = new Set(update.map(item => item.name));
|
|
38
38
|
const result = [];
|
|
@@ -86,3 +86,4 @@ export function generateToolMetrics(tools) {
|
|
|
86
86
|
};
|
|
87
87
|
});
|
|
88
88
|
}
|
|
89
|
+
//# sourceMappingURL=toolMetricsUtils.js.map
|
|
@@ -1,3 +1,30 @@
|
|
|
1
|
+
Name: urlpattern-polyfill
|
|
2
|
+
URL: https://github.com/kenchris/urlpattern-polyfill
|
|
3
|
+
Version: 10.1.0
|
|
4
|
+
License: MIT
|
|
5
|
+
|
|
6
|
+
Copyright 2020 Intel Corporation
|
|
7
|
+
|
|
8
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
9
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
10
|
+
in the Software without restriction, including without limitation the rights
|
|
11
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
12
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
13
|
+
furnished to do so, subject to the following conditions:
|
|
14
|
+
|
|
15
|
+
The above copyright notice and this permission notice shall be included in
|
|
16
|
+
all copies or substantial portions of the Software.
|
|
17
|
+
|
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
19
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
20
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
21
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
22
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
23
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
24
|
+
THE SOFTWARE.
|
|
25
|
+
|
|
26
|
+
-------------------- DEPENDENCY DIVIDER --------------------
|
|
27
|
+
|
|
1
28
|
Name: core-js
|
|
2
29
|
URL: https://core-js.io
|
|
3
30
|
Version: 3.49.0
|
|
@@ -2525,7 +2552,7 @@ SOFTWARE.
|
|
|
2525
2552
|
|
|
2526
2553
|
Name: axe-core
|
|
2527
2554
|
URL: https://www.deque.com/axe/
|
|
2528
|
-
Version: 4.11.
|
|
2555
|
+
Version: 4.11.4
|
|
2529
2556
|
License: MPL-2.0
|
|
2530
2557
|
|
|
2531
2558
|
Mozilla Public License, version 2.0
|
|
@@ -3961,7 +3988,7 @@ SOFTWARE.
|
|
|
3961
3988
|
|
|
3962
3989
|
Name: puppeteer-core
|
|
3963
3990
|
URL: https://github.com/puppeteer/puppeteer/tree/main/packages/puppeteer-core
|
|
3964
|
-
Version: 24.
|
|
3991
|
+
Version: 24.42.0
|
|
3965
3992
|
License: Apache-2.0
|
|
3966
3993
|
|
|
3967
3994
|
-------------------- DEPENDENCY DIVIDER --------------------
|
|
@@ -4027,7 +4054,7 @@ SOFTWARE.
|
|
|
4027
4054
|
|
|
4028
4055
|
Name: tldts-core
|
|
4029
4056
|
URL: https://github.com/remusao/tldts#readme
|
|
4030
|
-
Version: 7.0.
|
|
4057
|
+
Version: 7.0.29
|
|
4031
4058
|
License: MIT
|
|
4032
4059
|
|
|
4033
4060
|
Copyright (c) 2017 Thomas Parisot, 2018 Rémi Berson
|
|
@@ -4049,7 +4076,7 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTH
|
|
|
4049
4076
|
|
|
4050
4077
|
Name: tldts-icann
|
|
4051
4078
|
URL: https://github.com/remusao/tldts#readme
|
|
4052
|
-
Version: 7.0.
|
|
4079
|
+
Version: 7.0.29
|
|
4053
4080
|
License: MIT
|
|
4054
4081
|
|
|
4055
4082
|
Copyright (c) 2017 Thomas Parisot, 2018 Rémi Berson
|
|
@@ -4091,7 +4118,7 @@ PERFORMANCE OF THIS SOFTWARE.
|
|
|
4091
4118
|
|
|
4092
4119
|
Name: web-features
|
|
4093
4120
|
URL: git+https://github.com/web-platform-dx/web-features.git
|
|
4094
|
-
Version: 3.
|
|
4121
|
+
Version: 3.25.0
|
|
4095
4122
|
License: Apache-2.0
|
|
4096
4123
|
|
|
4097
4124
|
Apache License
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"@modelcontextprotocol/sdk": "1.29.0",
|
|
3
|
-
"chrome-devtools-frontend": "1.0.
|
|
3
|
+
"chrome-devtools-frontend": "1.0.1618066",
|
|
4
4
|
"core-js": "3.49.0",
|
|
5
5
|
"debug": "4.4.3",
|
|
6
|
-
"lighthouse": "13.
|
|
6
|
+
"lighthouse": "13.2.0",
|
|
7
7
|
"semver": "^7.7.4",
|
|
8
|
+
"urlpattern-polyfill": "^10.1.0",
|
|
8
9
|
"yargs": "18.0.0",
|
|
9
10
|
"puppeteer-core": "24.42.0"
|
|
10
11
|
}
|