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.
Files changed (109) hide show
  1. package/README.md +33 -4
  2. package/build/src/HeapSnapshotManager.js +30 -16
  3. package/build/src/McpContext.js +63 -9
  4. package/build/src/McpPage.js +9 -9
  5. package/build/src/McpResponse.js +176 -58
  6. package/build/src/PageCollector.js +8 -8
  7. package/build/src/ServiceWorkerCollector.js +171 -0
  8. package/build/src/TextSnapshot.js +1 -1
  9. package/build/src/ToolHandler.js +10 -4
  10. package/build/src/WaitForHelper.js +2 -2
  11. package/build/src/bin/chrome-devtools-cli-options.js +106 -4
  12. package/build/src/bin/chrome-devtools-mcp-cli-options.js +64 -5
  13. package/build/src/bin/chrome-devtools-mcp-main.js +5 -5
  14. package/build/src/browser.js +8 -4
  15. package/build/src/daemon/client.js +7 -7
  16. package/build/src/daemon/daemon.js +12 -12
  17. package/build/src/daemon/utils.js +2 -2
  18. package/build/src/{DevToolsConnectionAdapter.js → devtools/DevToolsConnectionAdapter.js} +1 -1
  19. package/build/src/{DevtoolsUtils.js → devtools/DevtoolsUtils.js} +79 -18
  20. package/build/src/devtools/McpHostBindingAdapter.js +165 -0
  21. package/build/src/formatters/ConsoleFormatter.js +1 -1
  22. package/build/src/formatters/HeapSnapshotFormatter.js +22 -0
  23. package/build/src/formatters/IssueFormatter.js +4 -4
  24. package/build/src/index.js +13 -1
  25. package/build/src/telemetry/ClearcutLogger.js +1 -1
  26. package/build/src/telemetry/WatchdogClient.js +4 -4
  27. package/build/src/telemetry/persistence.js +2 -2
  28. package/build/src/telemetry/watchdog/ClearcutSender.js +10 -10
  29. package/build/src/telemetry/watchdog/main.js +5 -5
  30. package/build/src/third_party/THIRD_PARTY_NOTICES +31 -1
  31. package/build/src/third_party/bundled-packages.json +2 -1
  32. package/build/src/third_party/devtools-formatter-worker.js +1 -1
  33. package/build/src/third_party/devtools-heap-snapshot-worker.js +161 -3
  34. package/build/src/third_party/index.js +7020 -5774
  35. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsEmptyList.md +1 -0
  36. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsHttpNotFound.md +1 -0
  37. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsInvalidContentType.md +1 -0
  38. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsInvalidResponse.md +1 -0
  39. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsNoResponse.md +1 -0
  40. package/build/src/third_party/issue-descriptions/emailVerificationRequestDnsFetchFailed.md +1 -0
  41. package/build/src/third_party/issue-descriptions/emailVerificationRequestDnsInvalidRecord.md +1 -0
  42. package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownHttpNotFound.md +1 -0
  43. package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownInvalidContentType.md +1 -0
  44. package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownInvalidResponse.md +1 -0
  45. package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownNoResponse.md +1 -0
  46. package/build/src/third_party/issue-descriptions/emailVerificationRequestInvalidEmail.md +1 -0
  47. package/build/src/third_party/issue-descriptions/emailVerificationRequestJwksHttpNotFound.md +1 -0
  48. package/build/src/third_party/issue-descriptions/emailVerificationRequestJwksInvalidResponse.md +1 -0
  49. package/build/src/third_party/issue-descriptions/emailVerificationRequestKeyBindingSigningFailed.md +1 -0
  50. package/build/src/third_party/issue-descriptions/emailVerificationRequestRpOriginIsOpaque.md +1 -0
  51. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenHttpNotFound.md +1 -0
  52. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenInvalidContentType.md +1 -0
  53. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenInvalidResponse.md +1 -0
  54. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenInvalidSdJwt.md +1 -0
  55. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenMalformedSdJwt.md +1 -0
  56. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenNoResponse.md +1 -0
  57. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidAudience.md +1 -0
  58. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidIssuedAt.md +1 -0
  59. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidNonce.md +1 -0
  60. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidSdHash.md +1 -0
  61. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidTyp.md +1 -0
  62. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingAud.md +1 -0
  63. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingCnf.md +1 -0
  64. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingIat.md +1 -0
  65. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingNonce.md +1 -0
  66. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingSdHash.md +1 -0
  67. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbSignatureFailed.md +1 -0
  68. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidEmail.md +1 -0
  69. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidEmailVerified.md +1 -0
  70. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidHolderKey.md +1 -0
  71. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidIssuedAt.md +1 -0
  72. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidIssuer.md +1 -0
  73. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtJwksMissingKeys.md +1 -0
  74. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingCnf.md +1 -0
  75. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingEmail.md +1 -0
  76. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingIat.md +1 -0
  77. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingIss.md +1 -0
  78. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtSignatureFailed.md +1 -0
  79. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtUnsupportedHeaderAlg.md +1 -0
  80. package/build/src/third_party/issue-descriptions/emailVerificationRequestUserLoggedOut.md +1 -0
  81. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownAccountsEndpointCrossOrigin.md +1 -0
  82. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownHttpNotFound.md +1 -0
  83. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownInvalidContentType.md +1 -0
  84. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownInvalidResponse.md +1 -0
  85. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownIssuanceEndpointCrossOrigin.md +1 -0
  86. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownListEmpty.md +1 -0
  87. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownMissingAccountsEndpoint.md +1 -0
  88. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownMissingIssuanceEndpoint.md +1 -0
  89. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownNoResponse.md +1 -0
  90. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownUnsupportedSigningAlgorithm.md +1 -0
  91. package/build/src/tools/console.js +7 -0
  92. package/build/src/tools/emulation.js +1 -0
  93. package/build/src/tools/extensions.js +5 -2
  94. package/build/src/tools/input.js +11 -3
  95. package/build/src/tools/lighthouse.js +11 -6
  96. package/build/src/tools/memory.js +109 -10
  97. package/build/src/tools/network.js +2 -2
  98. package/build/src/tools/pages.js +13 -5
  99. package/build/src/tools/performance.js +8 -7
  100. package/build/src/tools/screencast.js +32 -10
  101. package/build/src/tools/screenshot.js +158 -76
  102. package/build/src/tools/script.js +1 -1
  103. package/build/src/tools/slim/tools.js +3 -0
  104. package/build/src/tools/snapshot.js +3 -2
  105. package/build/src/tools/thirdPartyDeveloper.js +12 -2
  106. package/build/src/tools/webmcp.js +2 -0
  107. package/build/src/trace-processing/parse.js +5 -5
  108. package/build/src/version.js +1 -1
  109. package/package.json +4 -3
@@ -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,9 +2844,9 @@ 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";
2849
+ ExperimentName["PLUS_BUTTON"] = "plus-button";
2846
2850
  })(ExperimentName || (ExperimentName = {}));
2847
2851
 
2848
2852
  // Copyright 2021 The Chromium Authors
@@ -5935,6 +5939,9 @@ class HeapSnapshotProxy extends HeapSnapshotProxyObject {
5935
5939
  nodeClassKey(snapshotObjectId) {
5936
5940
  return this.callMethodPromise('nodeClassKey', snapshotObjectId);
5937
5941
  }
5942
+ nodeIndexForId(nodeId) {
5943
+ return this.callMethodPromise('nodeIndexForId', nodeId);
5944
+ }
5938
5945
  createEdgesProvider(nodeIndex) {
5939
5946
  return this.callFactoryMethod('createEdgesProvider', HeapSnapshotProviderProxy, nodeIndex);
5940
5947
  }
@@ -5992,6 +5999,12 @@ class HeapSnapshotProxy extends HeapSnapshotProxyObject {
5992
5999
  ignoreNodeInRetainersView(nodeIndex) {
5993
6000
  return this.callMethodPromise('ignoreNodeInRetainersView', nodeIndex);
5994
6001
  }
6002
+ getRetainingPaths(nodeIndex, maxDepth, maxNodes, maxSiblings) {
6003
+ return this.callMethodPromise('getRetainingPaths', nodeIndex, maxDepth, maxNodes, maxSiblings);
6004
+ }
6005
+ getDominatorsOf(nodeIndex) {
6006
+ return this.callMethodPromise('getDominatorsOf', nodeIndex);
6007
+ }
5995
6008
  unignoreNodeInRetainersView(nodeIndex) {
5996
6009
  return this.callMethodPromise('unignoreNodeInRetainersView', nodeIndex);
5997
6010
  }
@@ -7060,6 +7073,16 @@ class HeapSnapshot {
7060
7073
  }
7061
7074
  this.#progress.updateStatus('Finished processing.');
7062
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
+ }
7063
7086
  startInitStep1InSecondThread(secondWorker) {
7064
7087
  const resultsFromSecondWorker = new Promise((resolve, reject) => {
7065
7088
  const listener = (e) => {
@@ -8283,6 +8306,8 @@ class HeapSnapshot {
8283
8306
  const nodeAId = baseIds[i];
8284
8307
  if (nodeAId < nodeB.id()) {
8285
8308
  diff.deletedIndexes.push(baseIndexes[i]);
8309
+ diff.deletedIds.push(nodeAId);
8310
+ diff.deletedSelfSizes.push(baseSelfSizes[i]);
8286
8311
  diff.removedCount++;
8287
8312
  diff.removedSize += baseSelfSizes[i];
8288
8313
  ++i;
@@ -8290,6 +8315,8 @@ class HeapSnapshot {
8290
8315
  else if (nodeAId >
8291
8316
  nodeB.id()) {
8292
8317
  diff.addedIndexes.push(indexes[j]);
8318
+ diff.addedIds.push(nodeB.id());
8319
+ diff.addedSelfSizes.push(nodeB.selfSize());
8293
8320
  diff.addedCount++;
8294
8321
  diff.addedSize += nodeB.selfSize();
8295
8322
  nodeB.nodeIndex = indexes[++j];
@@ -8301,12 +8328,16 @@ class HeapSnapshot {
8301
8328
  }
8302
8329
  while (i < l) {
8303
8330
  diff.deletedIndexes.push(baseIndexes[i]);
8331
+ diff.deletedIds.push(baseIds[i]);
8332
+ diff.deletedSelfSizes.push(baseSelfSizes[i]);
8304
8333
  diff.removedCount++;
8305
8334
  diff.removedSize += baseSelfSizes[i];
8306
8335
  ++i;
8307
8336
  }
8308
8337
  while (j < m) {
8309
8338
  diff.addedIndexes.push(indexes[j]);
8339
+ diff.addedIds.push(nodeB.id());
8340
+ diff.addedSelfSizes.push(nodeB.selfSize());
8310
8341
  diff.addedCount++;
8311
8342
  diff.addedSize += nodeB.selfSize();
8312
8343
  nodeB.nodeIndex = indexes[++j];
@@ -8359,6 +8390,133 @@ class HeapSnapshot {
8359
8390
  const indexProvider = new HeapSnapshotRetainerEdgeIndexProvider(this);
8360
8391
  return new HeapSnapshotEdgesProvider(this, filter, node.retainers(), indexProvider);
8361
8392
  }
8393
+ getRetainingPaths(nodeIndex, maxDepth = 30, maxNodes = 5000, maxSiblings = 100) {
8394
+ const { nodeFieldCount, firstRetainerIndex, retainingNodes, retainingEdges, edgeTypeOffset, edgeWeakType, containmentEdges } = this;
8395
+ const distances = this.#nodeDistancesForRetainersView ?? this.nodeDistances;
8396
+ let traversedNodesCount = 0;
8397
+ const visiting = new Set();
8398
+ const visited = new Map();
8399
+ const rootDistance = 2;
8400
+ const limitsReached = {};
8401
+ const buildForest = (currentIndex, currentDepth) => {
8402
+ traversedNodesCount++;
8403
+ if (traversedNodesCount > maxNodes) {
8404
+ limitsReached.nodes = true;
8405
+ return [];
8406
+ }
8407
+ if (currentDepth >= maxDepth) {
8408
+ limitsReached.depth = true;
8409
+ return [];
8410
+ }
8411
+ const ordinal = currentIndex / nodeFieldCount;
8412
+ const currentDistance = distances[ordinal];
8413
+ if (currentDistance <= rootDistance) {
8414
+ return [];
8415
+ }
8416
+ if (visiting.has(currentIndex)) {
8417
+ return [];
8418
+ }
8419
+ const cachedDepth = visited.get(currentIndex);
8420
+ if (cachedDepth !== undefined) {
8421
+ if (currentDepth >= cachedDepth) {
8422
+ return [];
8423
+ }
8424
+ }
8425
+ visiting.add(currentIndex);
8426
+ const beginRetainerIndex = firstRetainerIndex[ordinal];
8427
+ const endRetainerIndex = firstRetainerIndex[ordinal + 1];
8428
+ const retainers = [];
8429
+ for (let retainerIndex = beginRetainerIndex; retainerIndex < endRetainerIndex; ++retainerIndex) {
8430
+ const retainerNodeIndex = retainingNodes[retainerIndex];
8431
+ const retainerNodeOrdinal = retainerNodeIndex / nodeFieldCount;
8432
+ const dist = distances[retainerNodeOrdinal];
8433
+ const globalEdgeIndex = retainingEdges[retainerIndex];
8434
+ if (this.isEdgeIgnoredInRetainersView(globalEdgeIndex)) {
8435
+ continue;
8436
+ }
8437
+ const edgeType = containmentEdges.getValue(globalEdgeIndex + edgeTypeOffset);
8438
+ if (edgeType === edgeWeakType) {
8439
+ continue;
8440
+ }
8441
+ if (dist >= 0) {
8442
+ const remainingDepth = maxDepth - currentDepth;
8443
+ const neededDepth = dist - rootDistance;
8444
+ if (neededDepth < remainingDepth) {
8445
+ retainers.push({ retainerIndex, dist, nodeIndex: retainerNodeIndex });
8446
+ }
8447
+ else {
8448
+ limitsReached.depth = true;
8449
+ }
8450
+ }
8451
+ }
8452
+ retainers.sort((a, b) => a.dist - b.dist);
8453
+ const length = Math.min(retainers.length, maxSiblings);
8454
+ if (retainers.length > maxSiblings) {
8455
+ limitsReached.siblings = true;
8456
+ }
8457
+ const forest = [];
8458
+ for (let i = 0; i < length; i++) {
8459
+ const retainer = retainers[i];
8460
+ const edge = this.createRetainingEdge(retainer.retainerIndex);
8461
+ const globalEdgeIndex = retainingEdges[retainer.retainerIndex];
8462
+ const isRoot = retainer.dist === rootDistance;
8463
+ let children = [];
8464
+ if (isRoot) {
8465
+ traversedNodesCount++;
8466
+ if (traversedNodesCount > maxNodes) {
8467
+ limitsReached.nodes = true;
8468
+ break;
8469
+ }
8470
+ }
8471
+ else {
8472
+ children = buildForest(retainer.nodeIndex, currentDepth + 1);
8473
+ if (children.length === 0) {
8474
+ continue;
8475
+ }
8476
+ }
8477
+ const retainerNode = this.createNode(retainer.nodeIndex);
8478
+ forest.push({
8479
+ edgeIndex: globalEdgeIndex,
8480
+ edgeName: edge.name(),
8481
+ edgeType: edge.type(),
8482
+ nodeId: retainerNode.id(),
8483
+ nodeIndex: retainer.nodeIndex,
8484
+ nodeName: retainerNode.name(),
8485
+ distance: retainer.dist,
8486
+ children,
8487
+ });
8488
+ }
8489
+ visiting.delete(currentIndex);
8490
+ visited.set(currentIndex, currentDepth);
8491
+ return forest;
8492
+ };
8493
+ const paths = buildForest(nodeIndex, 0);
8494
+ return { paths, limitsReached };
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
+ }
8362
8520
  createAddedNodesProvider(baseSnapshotId, classKey) {
8363
8521
  const snapshotDiff = this.#snapshotDiffs[baseSnapshotId];
8364
8522
  const diffForClass = snapshotDiff[classKey];