chrome-devtools-mcp 1.2.0 → 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.
@@ -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
  }
@@ -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.1
327
+ Version: 7.8.3
328
328
  License: ISC
329
329
 
330
330
  The ISC License
@@ -910,7 +910,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
910
910
 
911
911
  Name: @toon-format/toon
912
912
  URL: https://toonformat.dev
913
- Version: 2.2.0
913
+ Version: 2.3.0
914
914
  License: MIT
915
915
 
916
916
  MIT License
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "@modelcontextprotocol/sdk": "1.29.0",
3
3
  "@toon-format/toon": "^2.2.0",
4
- "chrome-devtools-frontend": "1.0.1641723",
4
+ "chrome-devtools-frontend": "1.0.1646286",
5
5
  "core-js": "3.49.0",
6
6
  "debug": "4.4.3",
7
7
  "lighthouse": "13.3.0",
@@ -2645,7 +2645,6 @@ 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";
2651
2650
  ExperimentName["PLUS_BUTTON"] = "plus-button";
@@ -642,10 +642,14 @@ class Diff {
642
642
  removedCount = 0;
643
643
  addedSize = 0;
644
644
  removedSize = 0;
645
- deletedIndexes = [];
646
- addedIndexes = [];
647
645
  countDelta;
648
646
  sizeDelta;
647
+ addedIndexes = [];
648
+ addedIds = [];
649
+ addedSelfSizes = [];
650
+ deletedIndexes = [];
651
+ deletedIds = [];
652
+ deletedSelfSizes = [];
649
653
  constructor(name) {
650
654
  this.name = name;
651
655
  }
@@ -2840,7 +2844,6 @@ var ExperimentName;
2840
2844
  ExperimentName["ALL"] = "*";
2841
2845
  ExperimentName["PROTOCOL_MONITOR"] = "protocol-monitor";
2842
2846
  ExperimentName["INSTRUMENTATION_BREAKPOINTS"] = "instrumentation-breakpoints";
2843
- ExperimentName["USE_SOURCE_MAP_SCOPES"] = "use-source-map-scopes";
2844
2847
  ExperimentName["DURABLE_MESSAGES"] = "durable-messages";
2845
2848
  ExperimentName["JPEG_XL"] = "jpeg-xl";
2846
2849
  ExperimentName["PLUS_BUTTON"] = "plus-button";
@@ -5936,6 +5939,9 @@ class HeapSnapshotProxy extends HeapSnapshotProxyObject {
5936
5939
  nodeClassKey(snapshotObjectId) {
5937
5940
  return this.callMethodPromise('nodeClassKey', snapshotObjectId);
5938
5941
  }
5942
+ nodeIndexForId(nodeId) {
5943
+ return this.callMethodPromise('nodeIndexForId', nodeId);
5944
+ }
5939
5945
  createEdgesProvider(nodeIndex) {
5940
5946
  return this.callFactoryMethod('createEdgesProvider', HeapSnapshotProviderProxy, nodeIndex);
5941
5947
  }
@@ -5996,6 +6002,9 @@ class HeapSnapshotProxy extends HeapSnapshotProxyObject {
5996
6002
  getRetainingPaths(nodeIndex, maxDepth, maxNodes, maxSiblings) {
5997
6003
  return this.callMethodPromise('getRetainingPaths', nodeIndex, maxDepth, maxNodes, maxSiblings);
5998
6004
  }
6005
+ getDominatorsOf(nodeIndex) {
6006
+ return this.callMethodPromise('getDominatorsOf', nodeIndex);
6007
+ }
5999
6008
  unignoreNodeInRetainersView(nodeIndex) {
6000
6009
  return this.callMethodPromise('unignoreNodeInRetainersView', nodeIndex);
6001
6010
  }
@@ -7064,6 +7073,16 @@ class HeapSnapshot {
7064
7073
  }
7065
7074
  this.#progress.updateStatus('Finished processing.');
7066
7075
  }
7076
+ nodeIndexForId(nodeId) {
7077
+ const nodesLength = this.nodes.length;
7078
+ const { nodes, nodeFieldCount, nodeIdOffset } = this;
7079
+ for (let nodeIndex = 0; nodeIndex < nodesLength; nodeIndex += nodeFieldCount) {
7080
+ if (nodes.getValue(nodeIndex + nodeIdOffset) === nodeId) {
7081
+ return nodeIndex;
7082
+ }
7083
+ }
7084
+ return undefined;
7085
+ }
7067
7086
  startInitStep1InSecondThread(secondWorker) {
7068
7087
  const resultsFromSecondWorker = new Promise((resolve, reject) => {
7069
7088
  const listener = (e) => {
@@ -8287,6 +8306,8 @@ class HeapSnapshot {
8287
8306
  const nodeAId = baseIds[i];
8288
8307
  if (nodeAId < nodeB.id()) {
8289
8308
  diff.deletedIndexes.push(baseIndexes[i]);
8309
+ diff.deletedIds.push(nodeAId);
8310
+ diff.deletedSelfSizes.push(baseSelfSizes[i]);
8290
8311
  diff.removedCount++;
8291
8312
  diff.removedSize += baseSelfSizes[i];
8292
8313
  ++i;
@@ -8294,6 +8315,8 @@ class HeapSnapshot {
8294
8315
  else if (nodeAId >
8295
8316
  nodeB.id()) {
8296
8317
  diff.addedIndexes.push(indexes[j]);
8318
+ diff.addedIds.push(nodeB.id());
8319
+ diff.addedSelfSizes.push(nodeB.selfSize());
8297
8320
  diff.addedCount++;
8298
8321
  diff.addedSize += nodeB.selfSize();
8299
8322
  nodeB.nodeIndex = indexes[++j];
@@ -8305,12 +8328,16 @@ class HeapSnapshot {
8305
8328
  }
8306
8329
  while (i < l) {
8307
8330
  diff.deletedIndexes.push(baseIndexes[i]);
8331
+ diff.deletedIds.push(baseIds[i]);
8332
+ diff.deletedSelfSizes.push(baseSelfSizes[i]);
8308
8333
  diff.removedCount++;
8309
8334
  diff.removedSize += baseSelfSizes[i];
8310
8335
  ++i;
8311
8336
  }
8312
8337
  while (j < m) {
8313
8338
  diff.addedIndexes.push(indexes[j]);
8339
+ diff.addedIds.push(nodeB.id());
8340
+ diff.addedSelfSizes.push(nodeB.selfSize());
8314
8341
  diff.addedCount++;
8315
8342
  diff.addedSize += nodeB.selfSize();
8316
8343
  nodeB.nodeIndex = indexes[++j];
@@ -8466,6 +8493,30 @@ class HeapSnapshot {
8466
8493
  const paths = buildForest(nodeIndex, 0);
8467
8494
  return { paths, limitsReached };
8468
8495
  }
8496
+ getDominatorsOf(nodeIndex) {
8497
+ const chain = [];
8498
+ let currentIndex = nodeIndex;
8499
+ const rootIndex = this.rootNodeIndex;
8500
+ while (currentIndex !== undefined) {
8501
+ const node = this.createNode(currentIndex);
8502
+ chain.push({
8503
+ nodeId: node.id(),
8504
+ nodeIndex: currentIndex,
8505
+ nodeName: node.name(),
8506
+ retainedSize: node.retainedSize(),
8507
+ selfSize: node.selfSize(),
8508
+ });
8509
+ if (currentIndex === rootIndex) {
8510
+ break;
8511
+ }
8512
+ const nextIndex = node.dominatorIndex();
8513
+ if (nextIndex === currentIndex) {
8514
+ break;
8515
+ }
8516
+ currentIndex = nextIndex;
8517
+ }
8518
+ return chain;
8519
+ }
8469
8520
  createAddedNodesProvider(baseSnapshotId, classKey) {
8470
8521
  const snapshotDiff = this.#snapshotDiffs[baseSnapshotId];
8471
8522
  const diffForClass = snapshotDiff[classKey];