chrome-devtools-mcp 1.1.1 → 1.3.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 +33 -4
- package/build/src/HeapSnapshotManager.js +30 -16
- package/build/src/McpContext.js +63 -9
- package/build/src/McpPage.js +9 -9
- package/build/src/McpResponse.js +176 -58
- package/build/src/PageCollector.js +8 -8
- package/build/src/ServiceWorkerCollector.js +171 -0
- package/build/src/TextSnapshot.js +1 -1
- package/build/src/ToolHandler.js +10 -4
- package/build/src/WaitForHelper.js +2 -2
- package/build/src/bin/chrome-devtools-cli-options.js +106 -4
- package/build/src/bin/chrome-devtools-mcp-cli-options.js +64 -5
- package/build/src/bin/chrome-devtools-mcp-main.js +5 -5
- package/build/src/browser.js +8 -4
- package/build/src/daemon/client.js +7 -7
- package/build/src/daemon/daemon.js +12 -12
- package/build/src/daemon/utils.js +2 -2
- package/build/src/{DevToolsConnectionAdapter.js → devtools/DevToolsConnectionAdapter.js} +1 -1
- package/build/src/{DevtoolsUtils.js → devtools/DevtoolsUtils.js} +79 -18
- package/build/src/devtools/McpHostBindingAdapter.js +165 -0
- package/build/src/formatters/ConsoleFormatter.js +1 -1
- package/build/src/formatters/HeapSnapshotFormatter.js +22 -0
- package/build/src/formatters/IssueFormatter.js +4 -4
- package/build/src/index.js +13 -1
- package/build/src/telemetry/ClearcutLogger.js +1 -1
- package/build/src/telemetry/WatchdogClient.js +4 -4
- package/build/src/telemetry/persistence.js +2 -2
- package/build/src/telemetry/watchdog/ClearcutSender.js +10 -10
- package/build/src/telemetry/watchdog/main.js +5 -5
- package/build/src/third_party/THIRD_PARTY_NOTICES +31 -1
- package/build/src/third_party/bundled-packages.json +2 -1
- package/build/src/third_party/devtools-formatter-worker.js +1 -1
- package/build/src/third_party/devtools-heap-snapshot-worker.js +161 -3
- package/build/src/third_party/index.js +7020 -5774
- package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsEmptyList.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsHttpNotFound.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsInvalidContentType.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsInvalidResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsNoResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestDnsFetchFailed.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestDnsInvalidRecord.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownHttpNotFound.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownInvalidContentType.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownInvalidResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownNoResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestInvalidEmail.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestJwksHttpNotFound.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestJwksInvalidResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestKeyBindingSigningFailed.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestRpOriginIsOpaque.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenHttpNotFound.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenInvalidContentType.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenInvalidResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenInvalidSdJwt.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenMalformedSdJwt.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenNoResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidAudience.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidIssuedAt.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidNonce.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidSdHash.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidTyp.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingAud.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingCnf.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingIat.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingNonce.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingSdHash.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbSignatureFailed.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidEmail.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidEmailVerified.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidHolderKey.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidIssuedAt.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidIssuer.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtJwksMissingKeys.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingCnf.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingEmail.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingIat.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingIss.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtSignatureFailed.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtUnsupportedHeaderAlg.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestUserLoggedOut.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownAccountsEndpointCrossOrigin.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownHttpNotFound.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownInvalidContentType.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownInvalidResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownIssuanceEndpointCrossOrigin.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownListEmpty.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownMissingAccountsEndpoint.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownMissingIssuanceEndpoint.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownNoResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownUnsupportedSigningAlgorithm.md +1 -0
- package/build/src/tools/console.js +7 -0
- package/build/src/tools/emulation.js +1 -0
- package/build/src/tools/extensions.js +5 -2
- package/build/src/tools/input.js +11 -3
- package/build/src/tools/lighthouse.js +11 -6
- package/build/src/tools/memory.js +109 -10
- package/build/src/tools/network.js +2 -2
- package/build/src/tools/pages.js +13 -5
- package/build/src/tools/performance.js +8 -7
- package/build/src/tools/screencast.js +32 -10
- package/build/src/tools/screenshot.js +158 -76
- package/build/src/tools/script.js +1 -1
- package/build/src/tools/slim/tools.js +3 -0
- package/build/src/tools/snapshot.js +3 -2
- package/build/src/tools/thirdPartyDeveloper.js +12 -2
- package/build/src/tools/webmcp.js +2 -0
- package/build/src/trace-processing/parse.js +5 -5
- package/build/src/version.js +1 -1
- package/package.json +4 -3
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
* Copyright 2025 Google LLC
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
+
import { Mutex } from '../Mutex.js';
|
|
7
|
+
import { DevTools } from '../third_party/index.js';
|
|
6
8
|
import { PuppeteerDevToolsConnection } from './DevToolsConnectionAdapter.js';
|
|
7
|
-
import {
|
|
8
|
-
import { DevTools } from './third_party/index.js';
|
|
9
|
+
import { McpHostBindingAdapter } from './McpHostBindingAdapter.js';
|
|
9
10
|
/**
|
|
10
11
|
* A mock implementation of an issues manager that only implements the methods
|
|
11
12
|
* that are actually used by the IssuesAggregator
|
|
@@ -16,22 +17,82 @@ export class FakeIssuesManager extends DevTools.Common.ObjectWrapper
|
|
|
16
17
|
return [];
|
|
17
18
|
}
|
|
18
19
|
}
|
|
19
|
-
|
|
20
|
-
DevTools.
|
|
21
|
-
DevTools.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
20
|
+
export function overrideDevToolsGlobals({ loadResource, }) {
|
|
21
|
+
DevTools.Host.InspectorFrontendHost.installInspectorFrontendHost(new McpHostBindingAdapter(loadResource));
|
|
22
|
+
// DevTools CDP errors can get noisy.
|
|
23
|
+
DevTools.ProtocolClient.InspectorBackend.test.suppressRequestErrors = true;
|
|
24
|
+
// Stub out Network emulation commands on the DevTools Agent prototype globally.
|
|
25
|
+
// This prevents the DevTools Frontend from ever resetting/clearing Puppeteer's
|
|
26
|
+
// active network blocking/throttling rules during target setup or session lifetime.
|
|
27
|
+
const networkAgentPrototype = DevTools.ProtocolClient.InspectorBackend.inspectorBackend.agentPrototypes.get('Network');
|
|
28
|
+
if (networkAgentPrototype) {
|
|
29
|
+
Object.defineProperty(networkAgentPrototype, 'invoke_emulateNetworkConditionsByRule', {
|
|
30
|
+
value: () => {
|
|
31
|
+
return Promise.resolve({
|
|
32
|
+
ruleIds: [],
|
|
33
|
+
getError: () => undefined,
|
|
34
|
+
});
|
|
35
|
+
},
|
|
36
|
+
writable: true,
|
|
37
|
+
configurable: true,
|
|
38
|
+
enumerable: true,
|
|
39
|
+
});
|
|
40
|
+
Object.defineProperty(networkAgentPrototype, 'invoke_overrideNetworkState', {
|
|
41
|
+
value: () => {
|
|
42
|
+
return Promise.resolve({
|
|
43
|
+
getError: () => undefined,
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
writable: true,
|
|
47
|
+
configurable: true,
|
|
48
|
+
enumerable: true,
|
|
49
|
+
});
|
|
50
|
+
Object.defineProperty(networkAgentPrototype, 'invoke_enable', {
|
|
51
|
+
value: () => {
|
|
52
|
+
return Promise.resolve({
|
|
53
|
+
getError: () => undefined,
|
|
54
|
+
});
|
|
55
|
+
},
|
|
56
|
+
writable: true,
|
|
57
|
+
configurable: true,
|
|
58
|
+
enumerable: true,
|
|
59
|
+
});
|
|
60
|
+
Object.defineProperty(networkAgentPrototype, 'invoke_disable', {
|
|
61
|
+
value: () => {
|
|
62
|
+
return Promise.resolve({
|
|
63
|
+
getError: () => undefined,
|
|
64
|
+
});
|
|
65
|
+
},
|
|
66
|
+
writable: true,
|
|
67
|
+
configurable: true,
|
|
68
|
+
enumerable: true,
|
|
69
|
+
});
|
|
70
|
+
Object.defineProperty(networkAgentPrototype, 'invoke_setBlockedURLs', {
|
|
71
|
+
value: () => {
|
|
72
|
+
return Promise.resolve({
|
|
73
|
+
getError: () => undefined,
|
|
74
|
+
});
|
|
75
|
+
},
|
|
76
|
+
writable: true,
|
|
77
|
+
configurable: true,
|
|
78
|
+
enumerable: true,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
DevTools.I18n.DevToolsLocale.DevToolsLocale.instance({
|
|
82
|
+
create: true,
|
|
83
|
+
data: {
|
|
84
|
+
navigatorLanguage: 'en-US',
|
|
85
|
+
settingLanguage: 'en-US',
|
|
86
|
+
lookupClosestDevToolsLocale: l => l,
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
DevTools.I18n.i18n.registerLocaleDataForTest('en-US', {});
|
|
90
|
+
DevTools.Formatter.FormatterWorkerPool.FormatterWorkerPool.instance({
|
|
91
|
+
forceNew: true,
|
|
92
|
+
entrypointURL: import.meta
|
|
93
|
+
.resolve('../third_party/devtools-formatter-worker.js'),
|
|
94
|
+
});
|
|
95
|
+
}
|
|
35
96
|
export class UniverseManager {
|
|
36
97
|
#browser;
|
|
37
98
|
#createUniverseFor;
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
7
|
+
import { DevTools } from '../third_party/index.js';
|
|
8
|
+
/**
|
|
9
|
+
* BaseClass that is noop or throws for methods.
|
|
10
|
+
* the McpHostBindingAdapter should only implement methods
|
|
11
|
+
* that it needs to support.
|
|
12
|
+
*/
|
|
13
|
+
class BaseMcpHostBindingAdapter {
|
|
14
|
+
connectAutomaticFileSystem() { }
|
|
15
|
+
disconnectAutomaticFileSystem() { }
|
|
16
|
+
addFileSystem() { }
|
|
17
|
+
loadCompleted() { }
|
|
18
|
+
indexPath() { }
|
|
19
|
+
setInspectedPageBounds() { }
|
|
20
|
+
showCertificateViewer() { }
|
|
21
|
+
setWhitelistedShortcuts() { }
|
|
22
|
+
setEyeDropperActive() { }
|
|
23
|
+
inspectElementCompleted() { }
|
|
24
|
+
openInNewTab() { }
|
|
25
|
+
openSearchResultsInNewTab() { }
|
|
26
|
+
showItemInFolder() { }
|
|
27
|
+
removeFileSystem() { }
|
|
28
|
+
requestFileSystems() { }
|
|
29
|
+
save() { }
|
|
30
|
+
append() { }
|
|
31
|
+
close() { }
|
|
32
|
+
searchInPath() { }
|
|
33
|
+
stopIndexing() { }
|
|
34
|
+
bringToFront() { }
|
|
35
|
+
closeWindow() { }
|
|
36
|
+
copyText() { }
|
|
37
|
+
inspectedURLChanged() { }
|
|
38
|
+
isolatedFileSystem() {
|
|
39
|
+
throw new Error('Not implemented');
|
|
40
|
+
}
|
|
41
|
+
registerPreference() { }
|
|
42
|
+
getPreferences() { }
|
|
43
|
+
getPreference() { }
|
|
44
|
+
setPreference() { }
|
|
45
|
+
removePreference() { }
|
|
46
|
+
clearPreferences() { }
|
|
47
|
+
getSyncInformation() { }
|
|
48
|
+
getHostConfig() { }
|
|
49
|
+
upgradeDraggedFileSystemPermissions() { }
|
|
50
|
+
platform() {
|
|
51
|
+
throw new Error('Not implemented');
|
|
52
|
+
}
|
|
53
|
+
recordCountHistogram() { }
|
|
54
|
+
recordEnumeratedHistogram() { }
|
|
55
|
+
recordPerformanceHistogram() { }
|
|
56
|
+
recordPerformanceHistogramMedium() { }
|
|
57
|
+
recordUserMetricsAction() { }
|
|
58
|
+
recordNewBadgeUsage() { }
|
|
59
|
+
sendMessageToBackend() { }
|
|
60
|
+
setDevicesDiscoveryConfig() { }
|
|
61
|
+
setDevicesUpdatesEnabled() { }
|
|
62
|
+
openRemotePage() { }
|
|
63
|
+
openNodeFrontend() { }
|
|
64
|
+
setInjectedScriptForOrigin() { }
|
|
65
|
+
setIsDocked() { }
|
|
66
|
+
showSurvey() { }
|
|
67
|
+
canShowSurvey() { }
|
|
68
|
+
zoomFactor() {
|
|
69
|
+
throw new Error('Not implemented');
|
|
70
|
+
}
|
|
71
|
+
zoomIn() { }
|
|
72
|
+
zoomOut() { }
|
|
73
|
+
resetZoom() { }
|
|
74
|
+
showContextMenuAtPoint() { }
|
|
75
|
+
reattach() { }
|
|
76
|
+
readyForTest() { }
|
|
77
|
+
connectionReady() { }
|
|
78
|
+
setOpenNewWindowForPopups() { }
|
|
79
|
+
isHostedMode() {
|
|
80
|
+
throw new Error('Not implemented');
|
|
81
|
+
}
|
|
82
|
+
setAddExtensionCallback() { }
|
|
83
|
+
initialTargetId() {
|
|
84
|
+
throw new Error('Not implemented');
|
|
85
|
+
}
|
|
86
|
+
doAidaConversation(_request, _streamId, cb) {
|
|
87
|
+
cb({
|
|
88
|
+
error: 'Not implemented',
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
registerAidaClientEvent(_request, cb) {
|
|
92
|
+
cb({
|
|
93
|
+
error: 'Not implemented',
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
aidaCodeComplete(_request, cb) {
|
|
97
|
+
cb({
|
|
98
|
+
error: 'Not implemented',
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
dispatchHttpRequest(_request, cb) {
|
|
102
|
+
cb({
|
|
103
|
+
error: 'Not implemented',
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
recordImpression() { }
|
|
107
|
+
recordResize() { }
|
|
108
|
+
recordClick() { }
|
|
109
|
+
recordHover() { }
|
|
110
|
+
recordDrag() { }
|
|
111
|
+
recordChange() { }
|
|
112
|
+
recordKeyDown() { }
|
|
113
|
+
recordSettingAccess() { }
|
|
114
|
+
recordFunctionCall() { }
|
|
115
|
+
setChromeFlag() { }
|
|
116
|
+
requestRestart() { }
|
|
117
|
+
loadNetworkResource(_urlString, _headers, _streamId, _callback) { }
|
|
118
|
+
}
|
|
119
|
+
export class McpHostBindingAdapter extends BaseMcpHostBindingAdapter {
|
|
120
|
+
#loadResource;
|
|
121
|
+
constructor(loadResource) {
|
|
122
|
+
super();
|
|
123
|
+
this.#loadResource = loadResource;
|
|
124
|
+
}
|
|
125
|
+
isolatedFileSystem() {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
platform() {
|
|
129
|
+
switch (process.platform) {
|
|
130
|
+
case 'darwin':
|
|
131
|
+
return 'mac';
|
|
132
|
+
case 'win32':
|
|
133
|
+
return 'windows';
|
|
134
|
+
default:
|
|
135
|
+
return 'linux';
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
zoomFactor() {
|
|
139
|
+
return 1;
|
|
140
|
+
}
|
|
141
|
+
isHostedMode() {
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
initialTargetId() {
|
|
145
|
+
return Promise.resolve(null);
|
|
146
|
+
}
|
|
147
|
+
loadNetworkResource(urlString, _headers, streamId, callback) {
|
|
148
|
+
if (!URL.canParse(urlString)) {
|
|
149
|
+
callback({
|
|
150
|
+
statusCode: 404,
|
|
151
|
+
urlValid: false,
|
|
152
|
+
});
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
this.#loadResource(urlString)
|
|
156
|
+
.then(content => {
|
|
157
|
+
DevTools.Host.ResourceLoader.streamWrite(streamId, content);
|
|
158
|
+
callback({ statusCode: 200 });
|
|
159
|
+
})
|
|
160
|
+
.catch(() => {
|
|
161
|
+
callback({ statusCode: 404 });
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=McpHostBindingAdapter.js.map
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Copyright 2026 Google LLC
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import { createStackTraceForConsoleMessage, SymbolizedError, } from '../DevtoolsUtils.js';
|
|
6
|
+
import { createStackTraceForConsoleMessage, SymbolizedError, } from '../devtools/DevtoolsUtils.js';
|
|
7
7
|
import { UncaughtError } from '../PageCollector.js';
|
|
8
8
|
import * as DevTools from '../third_party/index.js';
|
|
9
9
|
export class ConsoleFormatter {
|
|
@@ -45,6 +45,28 @@ export class HeapSnapshotFormatter {
|
|
|
45
45
|
}
|
|
46
46
|
return lines.join('\n');
|
|
47
47
|
}
|
|
48
|
+
static formatRetainingPaths(retainingPaths) {
|
|
49
|
+
const lines = [];
|
|
50
|
+
function formatEdge(edge, depth) {
|
|
51
|
+
const indent = ' '.repeat(depth);
|
|
52
|
+
lines.push(`${indent}<- @${edge.nodeId} ${edge.nodeName} via ${edge.edgeType} ${edge.edgeName} (distance: ${edge.distance})`);
|
|
53
|
+
for (const child of edge.children) {
|
|
54
|
+
formatEdge(child, depth + 1);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
for (const path of retainingPaths) {
|
|
58
|
+
formatEdge(path, 0);
|
|
59
|
+
}
|
|
60
|
+
return lines.join('\n');
|
|
61
|
+
}
|
|
62
|
+
static formatDominators(dominators) {
|
|
63
|
+
const lines = [];
|
|
64
|
+
lines.push('nodeId,nodeName,selfSize,retainedSize');
|
|
65
|
+
for (const node of dominators) {
|
|
66
|
+
lines.push(`${node.nodeId},${node.nodeName},${DevTools.I18n.ByteUtilities.formatBytesToKb(node.selfSize)},${DevTools.I18n.ByteUtilities.formatBytesToKb(node.retainedSize)}`);
|
|
67
|
+
}
|
|
68
|
+
return lines.join('\n');
|
|
69
|
+
}
|
|
48
70
|
#getSortedAggregates() {
|
|
49
71
|
return Object.values(this.#aggregates).sort((a, b) => b.maxRet - a.maxRet);
|
|
50
72
|
}
|
|
@@ -99,7 +99,7 @@ export class IssueFormatter {
|
|
|
99
99
|
const markdownDescription = this.#issue.getDescription();
|
|
100
100
|
const filename = markdownDescription?.file;
|
|
101
101
|
if (!filename) {
|
|
102
|
-
logger(`no description found for issue:` + this.#issue.code());
|
|
102
|
+
logger?.(`no description found for issue:` + this.#issue.code());
|
|
103
103
|
return undefined;
|
|
104
104
|
}
|
|
105
105
|
// We already have the description logic in #getDescription, but title extraction is separate
|
|
@@ -107,7 +107,7 @@ export class IssueFormatter {
|
|
|
107
107
|
// Ideally we should process markdown once.
|
|
108
108
|
const rawMarkdown = ISSUE_UTILS.getIssueDescription(filename);
|
|
109
109
|
if (!rawMarkdown) {
|
|
110
|
-
logger(`no markdown ${filename} found for issue:` + this.#issue.code());
|
|
110
|
+
logger?.(`no markdown ${filename} found for issue:` + this.#issue.code());
|
|
111
111
|
return undefined;
|
|
112
112
|
}
|
|
113
113
|
try {
|
|
@@ -115,13 +115,13 @@ export class IssueFormatter {
|
|
|
115
115
|
const markdownAst = DevTools.Marked.Marked.lexer(processedMarkdown);
|
|
116
116
|
const title = DevTools.MarkdownIssueDescription.findTitleFromMarkdownAst(markdownAst);
|
|
117
117
|
if (!title) {
|
|
118
|
-
logger('cannot read issue title from ' + filename);
|
|
118
|
+
logger?.('cannot read issue title from ' + filename);
|
|
119
119
|
return undefined;
|
|
120
120
|
}
|
|
121
121
|
return title;
|
|
122
122
|
}
|
|
123
123
|
catch {
|
|
124
|
-
logger('error parsing markdown for issue ' + this.#issue.code());
|
|
124
|
+
logger?.('error parsing markdown for issue ' + this.#issue.code());
|
|
125
125
|
return undefined;
|
|
126
126
|
}
|
|
127
127
|
}
|
package/build/src/index.js
CHANGED
|
@@ -43,7 +43,7 @@ export async function createMcpServer(serverArgs, options) {
|
|
|
43
43
|
context?.setRoots(roots.roots);
|
|
44
44
|
}
|
|
45
45
|
catch (e) {
|
|
46
|
-
logger('Failed to list roots', e);
|
|
46
|
+
logger?.('Failed to list roots', e);
|
|
47
47
|
}
|
|
48
48
|
};
|
|
49
49
|
server.server.oninitialized = () => {
|
|
@@ -66,6 +66,12 @@ export async function createMcpServer(serverArgs, options) {
|
|
|
66
66
|
chromeArgs.push(`--proxy-server=${serverArgs.proxyServer}`);
|
|
67
67
|
}
|
|
68
68
|
const devtools = serverArgs.experimentalDevtools ?? false;
|
|
69
|
+
const blocklist = serverArgs.blockedUrlPattern
|
|
70
|
+
? serverArgs.blockedUrlPattern.map(String)
|
|
71
|
+
: undefined;
|
|
72
|
+
const allowlist = serverArgs.allowedUrlPattern
|
|
73
|
+
? serverArgs.allowedUrlPattern.map(String)
|
|
74
|
+
: undefined;
|
|
69
75
|
const browser = serverArgs.browserUrl || serverArgs.wsEndpoint || serverArgs.autoConnect
|
|
70
76
|
? await ensureBrowserConnected({
|
|
71
77
|
browserURL: serverArgs.browserUrl,
|
|
@@ -77,6 +83,8 @@ export async function createMcpServer(serverArgs, options) {
|
|
|
77
83
|
: undefined,
|
|
78
84
|
userDataDir: serverArgs.userDataDir,
|
|
79
85
|
devtools,
|
|
86
|
+
blocklist,
|
|
87
|
+
allowlist,
|
|
80
88
|
})
|
|
81
89
|
: await ensureBrowserLaunched({
|
|
82
90
|
headless: serverArgs.headless,
|
|
@@ -92,12 +100,16 @@ export async function createMcpServer(serverArgs, options) {
|
|
|
92
100
|
devtools,
|
|
93
101
|
enableExtensions: serverArgs.categoryExtensions,
|
|
94
102
|
viaCli: serverArgs.viaCli,
|
|
103
|
+
blocklist,
|
|
104
|
+
allowlist,
|
|
95
105
|
});
|
|
96
106
|
if (context?.browser !== browser) {
|
|
97
107
|
context = await McpContext.from(browser, logger, {
|
|
98
108
|
experimentalDevToolsDebugging: devtools,
|
|
99
109
|
experimentalIncludeAllPages: serverArgs.experimentalIncludeAllPages,
|
|
100
110
|
performanceCrux: serverArgs.performanceCrux,
|
|
111
|
+
hasNetworkBlockOrAllowlist: Boolean((blocklist && blocklist.length > 0) ||
|
|
112
|
+
(allowlist && allowlist.length > 0)),
|
|
101
113
|
});
|
|
102
114
|
await updateRoots();
|
|
103
115
|
}
|
|
@@ -35,10 +35,10 @@ export class WatchdogClient {
|
|
|
35
35
|
});
|
|
36
36
|
this.#childProcess.unref();
|
|
37
37
|
this.#childProcess.on('error', err => {
|
|
38
|
-
logger('Watchdog process error:', err);
|
|
38
|
+
logger?.('Watchdog process error:', err);
|
|
39
39
|
});
|
|
40
40
|
this.#childProcess.on('exit', (code, signal) => {
|
|
41
|
-
logger(`Watchdog exited with code ${code} and signal ${signal}`);
|
|
41
|
+
logger?.(`Watchdog exited with code ${code} and signal ${signal}`);
|
|
42
42
|
});
|
|
43
43
|
}
|
|
44
44
|
send(message) {
|
|
@@ -50,11 +50,11 @@ export class WatchdogClient {
|
|
|
50
50
|
this.#childProcess.stdin.write(line);
|
|
51
51
|
}
|
|
52
52
|
catch (err) {
|
|
53
|
-
logger('Failed to write to watchdog stdin', err);
|
|
53
|
+
logger?.('Failed to write to watchdog stdin', err);
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
else {
|
|
57
|
-
logger('Watchdog stdin not available, dropping message');
|
|
57
|
+
logger?.('Watchdog stdin not available, dropping message');
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
}
|
|
@@ -45,7 +45,7 @@ export class FilePersistence {
|
|
|
45
45
|
return JSON.parse(content);
|
|
46
46
|
}
|
|
47
47
|
catch (error) {
|
|
48
|
-
logger(`Failed to read telemetry state from ${filePath}:`, error);
|
|
48
|
+
logger?.(`Failed to read telemetry state from ${filePath}:`, error);
|
|
49
49
|
void ClearcutLogger.get()?.logServerError({
|
|
50
50
|
errorCode: ErrorCode.ERROR_CODE_PERSISTENCE_FILE_READ_FAILED,
|
|
51
51
|
});
|
|
@@ -62,7 +62,7 @@ export class FilePersistence {
|
|
|
62
62
|
}
|
|
63
63
|
catch (error) {
|
|
64
64
|
// Ignore errors during state saving to avoid crashing the server
|
|
65
|
-
logger(`Failed to save telemetry state to ${filePath}:`, error);
|
|
65
|
+
logger?.(`Failed to save telemetry state to ${filePath}:`, error);
|
|
66
66
|
void ClearcutLogger.get()?.logServerError({
|
|
67
67
|
errorCode: ErrorCode.ERROR_CODE_PERSISTENCE_FILE_SAVE_FAILED,
|
|
68
68
|
});
|
|
@@ -48,7 +48,7 @@ export class ClearcutSender {
|
|
|
48
48
|
app_version: this.#appVersion,
|
|
49
49
|
os_type: this.#osType,
|
|
50
50
|
};
|
|
51
|
-
logger('Enqueing telemetry event', JSON.stringify(eventToSend, null, 2));
|
|
51
|
+
logger?.('Enqueing telemetry event', JSON.stringify(eventToSend, null, 2));
|
|
52
52
|
this.#addToBuffer(eventToSend);
|
|
53
53
|
if (!this.#timerStarted) {
|
|
54
54
|
this.#timerStarted = true;
|
|
@@ -69,10 +69,10 @@ export class ClearcutSender {
|
|
|
69
69
|
this.#finalFlush(),
|
|
70
70
|
new Promise(resolve => setTimeout(resolve, SHUTDOWN_TIMEOUT_MS)),
|
|
71
71
|
]);
|
|
72
|
-
logger('Final flush completed');
|
|
72
|
+
logger?.('Final flush completed');
|
|
73
73
|
}
|
|
74
74
|
catch (error) {
|
|
75
|
-
logger('Final flush failed:', error);
|
|
75
|
+
logger?.('Final flush failed:', error);
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
async #flush() {
|
|
@@ -97,7 +97,7 @@ export class ClearcutSender {
|
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
else if (result.isPermanentError) {
|
|
100
|
-
logger('Permanent error, dropped batch of', eventsToSend.length, 'events');
|
|
100
|
+
logger?.('Permanent error, dropped batch of', eventsToSend.length, 'events');
|
|
101
101
|
}
|
|
102
102
|
else {
|
|
103
103
|
// Transient error: Requeue events at the front of the buffer
|
|
@@ -108,7 +108,7 @@ export class ClearcutSender {
|
|
|
108
108
|
catch (error) {
|
|
109
109
|
// Safety catch for unexpected errors, requeue events
|
|
110
110
|
this.#buffer = [...eventsToSend, ...this.#buffer];
|
|
111
|
-
logger('Flush failed unexpectedly:', error);
|
|
111
|
+
logger?.('Flush failed unexpectedly:', error);
|
|
112
112
|
}
|
|
113
113
|
finally {
|
|
114
114
|
this.#isFlushing = false;
|
|
@@ -118,7 +118,7 @@ export class ClearcutSender {
|
|
|
118
118
|
#addToBuffer(event) {
|
|
119
119
|
if (this.#buffer.length >= MAX_BUFFER_SIZE) {
|
|
120
120
|
this.#buffer.shift();
|
|
121
|
-
logger('Telemetry buffer overflow: dropped oldest event');
|
|
121
|
+
logger?.('Telemetry buffer overflow: dropped oldest event');
|
|
122
122
|
}
|
|
123
123
|
this.#buffer.push({
|
|
124
124
|
event,
|
|
@@ -126,18 +126,18 @@ export class ClearcutSender {
|
|
|
126
126
|
});
|
|
127
127
|
}
|
|
128
128
|
#scheduleFlush(delayMs) {
|
|
129
|
-
logger(`Scheduling flush in ${delayMs}`);
|
|
129
|
+
logger?.(`Scheduling flush in ${delayMs}`);
|
|
130
130
|
if (this.#flushTimer) {
|
|
131
131
|
clearTimeout(this.#flushTimer);
|
|
132
132
|
}
|
|
133
133
|
this.#flushTimer = setTimeout(() => {
|
|
134
134
|
this.#flush().catch(err => {
|
|
135
|
-
logger('Flush error:', err);
|
|
135
|
+
logger?.('Flush error:', err);
|
|
136
136
|
});
|
|
137
137
|
}, delayMs);
|
|
138
138
|
}
|
|
139
139
|
async #sendBatch(events) {
|
|
140
|
-
logger(`Sending batch of ${events.length}`);
|
|
140
|
+
logger?.(`Sending batch of ${events.length}`);
|
|
141
141
|
const requestBody = {
|
|
142
142
|
log_source: LOG_SOURCE,
|
|
143
143
|
request_time_ms: Date.now().toString(),
|
|
@@ -176,7 +176,7 @@ export class ClearcutSender {
|
|
|
176
176
|
if (status >= 500 || status === 429) {
|
|
177
177
|
return { success: false };
|
|
178
178
|
}
|
|
179
|
-
logger('Telemetry permanent error:', status);
|
|
179
|
+
logger?.('Telemetry permanent error:', status);
|
|
180
180
|
return { success: false, isPermanentError: true };
|
|
181
181
|
}
|
|
182
182
|
catch {
|
|
@@ -65,7 +65,7 @@ function main() {
|
|
|
65
65
|
process.exit(code);
|
|
66
66
|
});
|
|
67
67
|
};
|
|
68
|
-
logger('Watchdog started', JSON.stringify({
|
|
68
|
+
logger?.('Watchdog started', JSON.stringify({
|
|
69
69
|
pid: process.pid,
|
|
70
70
|
parentPid,
|
|
71
71
|
version: appVersion,
|
|
@@ -84,15 +84,15 @@ function main() {
|
|
|
84
84
|
return;
|
|
85
85
|
}
|
|
86
86
|
isShuttingDown = true;
|
|
87
|
-
logger(`Parent death detected (${reason}). Sending shutdown event...`);
|
|
87
|
+
logger?.(`Parent death detected (${reason}). Sending shutdown event...`);
|
|
88
88
|
sender
|
|
89
89
|
.sendShutdownEvent()
|
|
90
90
|
.then(() => {
|
|
91
|
-
logger('Shutdown event sent. Exiting.');
|
|
91
|
+
logger?.('Shutdown event sent. Exiting.');
|
|
92
92
|
exit(0);
|
|
93
93
|
})
|
|
94
94
|
.catch(err => {
|
|
95
|
-
logger('Failed to send shutdown event', err);
|
|
95
|
+
logger?.('Failed to send shutdown event', err);
|
|
96
96
|
exit(1);
|
|
97
97
|
});
|
|
98
98
|
}
|
|
@@ -114,7 +114,7 @@ function main() {
|
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
catch (err) {
|
|
117
|
-
logger('Failed to parse IPC message', err);
|
|
117
|
+
logger?.('Failed to parse IPC message', err);
|
|
118
118
|
}
|
|
119
119
|
});
|
|
120
120
|
}
|
|
@@ -324,7 +324,7 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH RE
|
|
|
324
324
|
|
|
325
325
|
Name: semver
|
|
326
326
|
URL: git+https://github.com/npm/node-semver.git
|
|
327
|
-
Version: 7.8.
|
|
327
|
+
Version: 7.8.3
|
|
328
328
|
License: ISC
|
|
329
329
|
|
|
330
330
|
The ISC License
|
|
@@ -906,6 +906,36 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
|
906
906
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
907
907
|
|
|
908
908
|
|
|
909
|
+
-------------------- DEPENDENCY DIVIDER --------------------
|
|
910
|
+
|
|
911
|
+
Name: @toon-format/toon
|
|
912
|
+
URL: https://toonformat.dev
|
|
913
|
+
Version: 2.3.0
|
|
914
|
+
License: MIT
|
|
915
|
+
|
|
916
|
+
MIT License
|
|
917
|
+
|
|
918
|
+
Copyright (c) 2025-PRESENT Johann Schopplich
|
|
919
|
+
|
|
920
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
921
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
922
|
+
in the Software without restriction, including without limitation the rights
|
|
923
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
924
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
925
|
+
furnished to do so, subject to the following conditions:
|
|
926
|
+
|
|
927
|
+
The above copyright notice and this permission notice shall be included in all
|
|
928
|
+
copies or substantial portions of the Software.
|
|
929
|
+
|
|
930
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
931
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
932
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
933
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
934
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
935
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
936
|
+
SOFTWARE.
|
|
937
|
+
|
|
938
|
+
|
|
909
939
|
-------------------- DEPENDENCY DIVIDER --------------------
|
|
910
940
|
|
|
911
941
|
Name: chrome-devtools-frontend
|
|
@@ -2645,9 +2645,9 @@ var ExperimentName;
|
|
|
2645
2645
|
ExperimentName["ALL"] = "*";
|
|
2646
2646
|
ExperimentName["PROTOCOL_MONITOR"] = "protocol-monitor";
|
|
2647
2647
|
ExperimentName["INSTRUMENTATION_BREAKPOINTS"] = "instrumentation-breakpoints";
|
|
2648
|
-
ExperimentName["USE_SOURCE_MAP_SCOPES"] = "use-source-map-scopes";
|
|
2649
2648
|
ExperimentName["DURABLE_MESSAGES"] = "durable-messages";
|
|
2650
2649
|
ExperimentName["JPEG_XL"] = "jpeg-xl";
|
|
2650
|
+
ExperimentName["PLUS_BUTTON"] = "plus-button";
|
|
2651
2651
|
})(ExperimentName || (ExperimentName = {}));
|
|
2652
2652
|
|
|
2653
2653
|
// Copyright 2016 The Chromium Authors
|