@yezack/chrome-devtools-mcp-108 0.0.0-stage → 1.10.2

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 (360) hide show
  1. package/FORK-NOTICE.md +45 -0
  2. package/LICENSE +202 -0
  3. package/README.md +45 -2
  4. package/build/src/BrowserManager.js +401 -0
  5. package/build/src/McpContext.js +642 -0
  6. package/build/src/McpPage.js +850 -0
  7. package/build/src/McpResponse.js +1086 -0
  8. package/build/src/SlimMcpResponse.js +19 -0
  9. package/build/src/TextSnapshot.js +315 -0
  10. package/build/src/ToolHandler.js +322 -0
  11. package/build/src/bin/check-latest-version.js +51 -0
  12. package/build/src/bin/chrome-devtools-mcp-main.js +77 -0
  13. package/build/src/bin/chrome-devtools-mcp.js +23 -0
  14. package/build/src/bin/chrome-devtools.js +222 -0
  15. package/build/src/collectors/PageCollector.js +291 -0
  16. package/build/src/collectors/ServiceWorkerCollector.js +171 -0
  17. package/build/src/config/browser-options.js +125 -0
  18. package/build/src/config/category-options.js +89 -0
  19. package/build/src/config/cli-commands.js +26 -0
  20. package/build/src/config/cli-options.js +1473 -0
  21. package/build/src/config/mcp-options.js +417 -0
  22. package/build/src/daemon/client.js +221 -0
  23. package/build/src/daemon/daemon.js +266 -0
  24. package/build/src/daemon/types.js +7 -0
  25. package/build/src/daemon/utils.js +136 -0
  26. package/build/src/devtools/DevToolsCommentBridge.js +91 -0
  27. package/build/src/devtools/DevtoolsUtils.js +307 -0
  28. package/build/src/devtools/McpHostBindingAdapter.js +165 -0
  29. package/build/src/devtools/issueDescriptions.js +42 -0
  30. package/build/src/formatters/CommentFormatter.js +82 -0
  31. package/build/src/formatters/ConsoleFormatter.js +321 -0
  32. package/build/src/formatters/CssFormatter.js +812 -0
  33. package/build/src/formatters/HeapSnapshotFormatter.js +185 -0
  34. package/build/src/formatters/IssueFormatter.js +193 -0
  35. package/build/src/formatters/NetworkFormatter.js +241 -0
  36. package/build/src/formatters/SnapshotFormatter.js +135 -0
  37. package/build/src/index.js +237 -0
  38. package/build/src/processors/ChunkedTraceParser.js +361 -0
  39. package/build/src/processors/HeapSnapshotManager.js +270 -0
  40. package/build/src/processors/PerformanceTrace.js +132 -0
  41. package/build/src/telemetry/ClearcutLogger.js +242 -0
  42. package/build/src/telemetry/WatchdogClient.js +61 -0
  43. package/build/src/telemetry/errors.js +18 -0
  44. package/build/src/telemetry/flagUtils.js +90 -0
  45. package/build/src/telemetry/metricsRegistry.js +85 -0
  46. package/build/src/telemetry/persistence.js +82 -0
  47. package/build/src/telemetry/transformation.js +233 -0
  48. package/build/src/telemetry/types.js +36 -0
  49. package/build/src/telemetry/watchdog/ClearcutSender.js +205 -0
  50. package/build/src/telemetry/watchdog/main.js +128 -0
  51. package/build/src/third_party/THIRD_PARTY_NOTICES +4077 -0
  52. package/build/src/third_party/bundled-packages.json +12 -0
  53. package/build/src/third_party/devtools-formatter-worker.js +15494 -0
  54. package/build/src/third_party/devtools-heap-snapshot-worker.js +10979 -0
  55. package/build/src/third_party/index.js +200978 -0
  56. package/build/src/third_party/issue-descriptions/CoepCoopSandboxedIframeCannotNavigateToCoopPage.md +4 -0
  57. package/build/src/third_party/issue-descriptions/CoepCorpNotSameOrigin.md +8 -0
  58. package/build/src/third_party/issue-descriptions/CoepCorpNotSameOriginAfterDefaultedToSameOriginByCoep.md +18 -0
  59. package/build/src/third_party/issue-descriptions/CoepCorpNotSameSite.md +7 -0
  60. package/build/src/third_party/issue-descriptions/CoepFrameResourceNeedsCoepHeader.md +10 -0
  61. package/build/src/third_party/issue-descriptions/CompatibilityModeQuirks.md +5 -0
  62. package/build/src/third_party/issue-descriptions/CookieAttributeValueExceedsMaxSize.md +5 -0
  63. package/build/src/third_party/issue-descriptions/LowTextContrast.md +5 -0
  64. package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureErrorRead.md +8 -0
  65. package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureErrorSet.md +8 -0
  66. package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureWarnRead.md +8 -0
  67. package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureWarnSet.md +8 -0
  68. package/build/src/third_party/issue-descriptions/SameSiteUnspecifiedLaxAllowUnsafeRead.md +9 -0
  69. package/build/src/third_party/issue-descriptions/SameSiteUnspecifiedLaxAllowUnsafeSet.md +9 -0
  70. package/build/src/third_party/issue-descriptions/bounceTrackingMitigations.md +3 -0
  71. package/build/src/third_party/issue-descriptions/clientHintMetaTagAllowListInvalidOrigin.md +4 -0
  72. package/build/src/third_party/issue-descriptions/clientHintMetaTagModifiedHTML.md +4 -0
  73. package/build/src/third_party/issue-descriptions/connectionAllowlistEmbeddingRequirementNotSatisfied.md +26 -0
  74. package/build/src/third_party/issue-descriptions/connectionAllowlistIFrameAttributeLoosensEmbeddingRequirement.md +19 -0
  75. package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidAllowConnectionAllowlistFrom.md +21 -0
  76. package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidAllowlistItemType.md +12 -0
  77. package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidHeader.md +12 -0
  78. package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidUrlPattern.md +8 -0
  79. package/build/src/third_party/issue-descriptions/connectionAllowlistItemNotInnerList.md +12 -0
  80. package/build/src/third_party/issue-descriptions/connectionAllowlistMoreThanOneList.md +7 -0
  81. package/build/src/third_party/issue-descriptions/connectionAllowlistReportingEndpointNotToken.md +10 -0
  82. package/build/src/third_party/issue-descriptions/cookieCrossSiteRedirectDowngrade.md +12 -0
  83. package/build/src/third_party/issue-descriptions/cookieExcludeDomainNonAscii.md +11 -0
  84. package/build/src/third_party/issue-descriptions/cookieExcludePortMismatch.md +8 -0
  85. package/build/src/third_party/issue-descriptions/cookieExcludeSchemeMismatch.md +7 -0
  86. package/build/src/third_party/issue-descriptions/cookieExcludeThirdPartyPhaseoutRead.md +6 -0
  87. package/build/src/third_party/issue-descriptions/cookieExcludeThirdPartyPhaseoutSet.md +6 -0
  88. package/build/src/third_party/issue-descriptions/cookieWarnDomainNonAscii.md +11 -0
  89. package/build/src/third_party/issue-descriptions/cookieWarnMetadataGrantRead.md +4 -0
  90. package/build/src/third_party/issue-descriptions/cookieWarnMetadataGrantSet.md +4 -0
  91. package/build/src/third_party/issue-descriptions/cookieWarnThirdPartyPhaseoutRead.md +6 -0
  92. package/build/src/third_party/issue-descriptions/cookieWarnThirdPartyPhaseoutSet.md +6 -0
  93. package/build/src/third_party/issue-descriptions/corsAllowCredentialsRequired.md +6 -0
  94. package/build/src/third_party/issue-descriptions/corsDisabledScheme.md +7 -0
  95. package/build/src/third_party/issue-descriptions/corsDisallowedByMode.md +7 -0
  96. package/build/src/third_party/issue-descriptions/corsHeaderDisallowedByPreflightResponse.md +5 -0
  97. package/build/src/third_party/issue-descriptions/corsInvalidHeaderValues.md +7 -0
  98. package/build/src/third_party/issue-descriptions/corsLocalNetworkAccessPermissionDenied.md +19 -0
  99. package/build/src/third_party/issue-descriptions/corsMethodDisallowedByPreflightResponse.md +5 -0
  100. package/build/src/third_party/issue-descriptions/corsNoCorsRedirectModeNotFollow.md +5 -0
  101. package/build/src/third_party/issue-descriptions/corsOriginMismatch.md +6 -0
  102. package/build/src/third_party/issue-descriptions/corsPreflightResponseInvalid.md +5 -0
  103. package/build/src/third_party/issue-descriptions/corsRedirectContainsCredentials.md +5 -0
  104. package/build/src/third_party/issue-descriptions/corsWildcardOriginNotAllowed.md +9 -0
  105. package/build/src/third_party/issue-descriptions/cspEvalViolation.md +9 -0
  106. package/build/src/third_party/issue-descriptions/cspInlineViolation.md +10 -0
  107. package/build/src/third_party/issue-descriptions/cspTrustedTypesPolicyViolation.md +5 -0
  108. package/build/src/third_party/issue-descriptions/cspTrustedTypesSinkViolation.md +8 -0
  109. package/build/src/third_party/issue-descriptions/cspURLViolation.md +10 -0
  110. package/build/src/third_party/issue-descriptions/deprecation.md +3 -0
  111. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsEmptyList.md +1 -0
  112. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsHttpNotFound.md +1 -0
  113. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsInvalidContentType.md +1 -0
  114. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsInvalidResponse.md +1 -0
  115. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsNoResponse.md +1 -0
  116. package/build/src/third_party/issue-descriptions/emailVerificationRequestDnsFetchFailed.md +1 -0
  117. package/build/src/third_party/issue-descriptions/emailVerificationRequestDnsInvalidRecord.md +1 -0
  118. package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownHttpNotFound.md +1 -0
  119. package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownInvalidContentType.md +1 -0
  120. package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownInvalidResponse.md +1 -0
  121. package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownNoResponse.md +1 -0
  122. package/build/src/third_party/issue-descriptions/emailVerificationRequestInvalidEmail.md +1 -0
  123. package/build/src/third_party/issue-descriptions/emailVerificationRequestJwksHttpNotFound.md +1 -0
  124. package/build/src/third_party/issue-descriptions/emailVerificationRequestJwksInvalidResponse.md +1 -0
  125. package/build/src/third_party/issue-descriptions/emailVerificationRequestKeyBindingSigningFailed.md +1 -0
  126. package/build/src/third_party/issue-descriptions/emailVerificationRequestRpOriginIsOpaque.md +1 -0
  127. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenHttpNotFound.md +1 -0
  128. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenInvalidContentType.md +1 -0
  129. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenInvalidResponse.md +1 -0
  130. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenInvalidSdJwt.md +1 -0
  131. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenMalformedSdJwt.md +1 -0
  132. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenNoResponse.md +1 -0
  133. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidAudience.md +1 -0
  134. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidIssuedAt.md +1 -0
  135. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidNonce.md +1 -0
  136. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidSdHash.md +1 -0
  137. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidTyp.md +1 -0
  138. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingAud.md +1 -0
  139. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingCnf.md +1 -0
  140. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingIat.md +1 -0
  141. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingNonce.md +1 -0
  142. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingSdHash.md +1 -0
  143. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbSignatureFailed.md +1 -0
  144. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidEmail.md +1 -0
  145. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidEmailVerified.md +1 -0
  146. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidHolderKey.md +1 -0
  147. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidIssuedAt.md +1 -0
  148. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidIssuer.md +1 -0
  149. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtJwksMissingKeys.md +1 -0
  150. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingCnf.md +1 -0
  151. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingEmail.md +1 -0
  152. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingIat.md +1 -0
  153. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingIss.md +1 -0
  154. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtSignatureFailed.md +1 -0
  155. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtUnsupportedHeaderAlg.md +1 -0
  156. package/build/src/third_party/issue-descriptions/emailVerificationRequestUserLoggedOut.md +1 -0
  157. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownAccountsEndpointCrossOrigin.md +1 -0
  158. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownHttpNotFound.md +1 -0
  159. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownInvalidContentType.md +1 -0
  160. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownInvalidResponse.md +1 -0
  161. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownIssuanceEndpointCrossOrigin.md +1 -0
  162. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownListEmpty.md +1 -0
  163. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownMissingAccountsEndpoint.md +1 -0
  164. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownMissingIssuanceEndpoint.md +1 -0
  165. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownNoResponse.md +1 -0
  166. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownUnsupportedSigningAlgorithm.md +1 -0
  167. package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsBlockedByConnectionAllowlist.md +1 -0
  168. package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsHttpNotFound.md +1 -0
  169. package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsInvalidResponse.md +1 -0
  170. package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsNoResponse.md +1 -0
  171. package/build/src/third_party/issue-descriptions/federatedAuthRequestApprovalDeclined.md +1 -0
  172. package/build/src/third_party/issue-descriptions/federatedAuthRequestCanceled.md +1 -0
  173. package/build/src/third_party/issue-descriptions/federatedAuthRequestConfigBlockedByConnectionAllowlist.md +1 -0
  174. package/build/src/third_party/issue-descriptions/federatedAuthRequestErrorFetchingSignin.md +1 -0
  175. package/build/src/third_party/issue-descriptions/federatedAuthRequestErrorIdToken.md +1 -0
  176. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenBlockedByConnectionAllowlist.md +1 -0
  177. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenHttpNotFound.md +1 -0
  178. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenInvalidRequest.md +1 -0
  179. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenInvalidResponse.md +1 -0
  180. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenNoResponse.md +1 -0
  181. package/build/src/third_party/issue-descriptions/federatedAuthRequestInvalidSigninResponse.md +1 -0
  182. package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestHttpNotFound.md +1 -0
  183. package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestInvalidResponse.md +1 -0
  184. package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestNoResponse.md +1 -0
  185. package/build/src/third_party/issue-descriptions/federatedAuthRequestTooManyRequests.md +1 -0
  186. package/build/src/third_party/issue-descriptions/federatedAuthRequestWellKnownBlockedByConnectionAllowlist.md +1 -0
  187. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestInvalidAccountsResponse.md +1 -0
  188. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestInvalidConfigOrWellKnown.md +1 -0
  189. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoAccountSharingPermission.md +1 -0
  190. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoApiPermission.md +1 -0
  191. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoReturningUserFromFetchedAccounts.md +1 -0
  192. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotIframe.md +1 -0
  193. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotPotentiallyTrustworthy.md +1 -0
  194. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotSameOrigin.md +1 -0
  195. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotSignedInWithIdp.md +1 -0
  196. package/build/src/third_party/issue-descriptions/fetchingPartitionedBlobURL.md +7 -0
  197. package/build/src/third_party/issue-descriptions/genericBackUINavigationWouldSkipAd.md +4 -0
  198. package/build/src/third_party/issue-descriptions/genericFormAriaLabelledByToNonExistingIdError.md +8 -0
  199. package/build/src/third_party/issue-descriptions/genericFormAutocompleteAttributeEmptyError.md +5 -0
  200. package/build/src/third_party/issue-descriptions/genericFormDuplicateIdForInputError.md +5 -0
  201. package/build/src/third_party/issue-descriptions/genericFormEmptyIdAndNameAttributesForInputError.md +5 -0
  202. package/build/src/third_party/issue-descriptions/genericFormInputAssignedAutocompleteValueToIdOrNameAttributeError.md +5 -0
  203. package/build/src/third_party/issue-descriptions/genericFormInputHasWrongButWellIntendedAutocompleteValueError.md +5 -0
  204. package/build/src/third_party/issue-descriptions/genericFormInputWithNoLabelError.md +5 -0
  205. package/build/src/third_party/issue-descriptions/genericFormLabelForMatchesNonExistingIdError.md +5 -0
  206. package/build/src/third_party/issue-descriptions/genericFormLabelForNameError.md +5 -0
  207. package/build/src/third_party/issue-descriptions/genericFormLabelHasNeitherForNorNestedInputError.md +5 -0
  208. package/build/src/third_party/issue-descriptions/genericFormModelContextMissingToolDescription.md +5 -0
  209. package/build/src/third_party/issue-descriptions/genericFormModelContextMissingToolName.md +5 -0
  210. package/build/src/third_party/issue-descriptions/genericFormModelContextParameterMissingName.md +5 -0
  211. package/build/src/third_party/issue-descriptions/genericFormModelContextParameterMissingTitleAndDescription.md +5 -0
  212. package/build/src/third_party/issue-descriptions/genericFormModelContextRequiredParameterMissingName.md +5 -0
  213. package/build/src/third_party/issue-descriptions/genericNavigationEntryMarkedSkippable.md +7 -0
  214. package/build/src/third_party/issue-descriptions/genericResponseWasBlockedByORB.md +4 -0
  215. package/build/src/third_party/issue-descriptions/heavyAd.md +10 -0
  216. package/build/src/third_party/issue-descriptions/lazyLoadImageZeroSize.md +7 -0
  217. package/build/src/third_party/issue-descriptions/mixedContent.md +5 -0
  218. package/build/src/third_party/issue-descriptions/navigatingPartitionedBlobURL.md +5 -0
  219. package/build/src/third_party/issue-descriptions/permissionElementActivationDisabled.md +7 -0
  220. package/build/src/third_party/issue-descriptions/permissionElementActivationDisabledWithOccluder.md +9 -0
  221. package/build/src/third_party/issue-descriptions/permissionElementActivationDisabledWithOccluderParent.md +9 -0
  222. package/build/src/third_party/issue-descriptions/permissionElementCspFrameAncestorsMissing.md +5 -0
  223. package/build/src/third_party/issue-descriptions/permissionElementFencedFrameDisallowed.md +5 -0
  224. package/build/src/third_party/issue-descriptions/permissionElementFontSizeTooLarge.md +5 -0
  225. package/build/src/third_party/issue-descriptions/permissionElementFontSizeTooSmall.md +5 -0
  226. package/build/src/third_party/issue-descriptions/permissionElementGeolocationDeprecated.md +5 -0
  227. package/build/src/third_party/issue-descriptions/permissionElementInsetBoxShadowUnsupported.md +5 -0
  228. package/build/src/third_party/issue-descriptions/permissionElementInvalidDisplayStyle.md +5 -0
  229. package/build/src/third_party/issue-descriptions/permissionElementInvalidSizeValue.md +5 -0
  230. package/build/src/third_party/issue-descriptions/permissionElementInvalidType.md +5 -0
  231. package/build/src/third_party/issue-descriptions/permissionElementInvalidTypeActivation.md +5 -0
  232. package/build/src/third_party/issue-descriptions/permissionElementLowContrast.md +5 -0
  233. package/build/src/third_party/issue-descriptions/permissionElementNonOpaqueColor.md +5 -0
  234. package/build/src/third_party/issue-descriptions/permissionElementPaddingBottomUnsupported.md +6 -0
  235. package/build/src/third_party/issue-descriptions/permissionElementPaddingRightUnsupported.md +6 -0
  236. package/build/src/third_party/issue-descriptions/permissionElementPermissionsPolicyBlocked.md +5 -0
  237. package/build/src/third_party/issue-descriptions/permissionElementRegistrationFailed.md +5 -0
  238. package/build/src/third_party/issue-descriptions/permissionElementRequestInProgress.md +5 -0
  239. package/build/src/third_party/issue-descriptions/permissionElementSecurityChecksFailed.md +5 -0
  240. package/build/src/third_party/issue-descriptions/permissionElementTypeNotSupported.md +5 -0
  241. package/build/src/third_party/issue-descriptions/permissionElementUntrustedEvent.md +7 -0
  242. package/build/src/third_party/issue-descriptions/placeholderDescriptionForInvisibleIssues.md +3 -0
  243. package/build/src/third_party/issue-descriptions/propertyRuleInvalidNameIssue.md +3 -0
  244. package/build/src/third_party/issue-descriptions/propertyRuleIssue.md +7 -0
  245. package/build/src/third_party/issue-descriptions/selectElementAccessibilityDisallowedOptGroupChild.md +7 -0
  246. package/build/src/third_party/issue-descriptions/selectElementAccessibilityDisallowedSelectChild.md +7 -0
  247. package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentAttributesSelectDescendant.md +3 -0
  248. package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentLegendChild.md +3 -0
  249. package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentOptionChild.md +3 -0
  250. package/build/src/third_party/issue-descriptions/selectElementAccessibilityNonPhrasingContentOptionChild.md +3 -0
  251. package/build/src/third_party/issue-descriptions/selectivePermissionsIntervention.md +7 -0
  252. package/build/src/third_party/issue-descriptions/sharedArrayBuffer.md +7 -0
  253. package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorCrossOriginNoCorsRequest.md +1 -0
  254. package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorDictionaryLoadFailure.md +3 -0
  255. package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorMatchingDictionaryNotUsed.md +3 -0
  256. package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorUnexpectedContentDictionaryHeader.md +1 -0
  257. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorCossOriginNoCorsRequest.md +1 -0
  258. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorDisallowedBySettings.md +1 -0
  259. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorExpiredResponse.md +3 -0
  260. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorFeatureDisabled.md +3 -0
  261. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInsufficientResources.md +1 -0
  262. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInvalidMatchField.md +1 -0
  263. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInvalidStructuredHeader.md +1 -0
  264. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInvalidTTLField.md +1 -0
  265. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNavigationRequest.md +3 -0
  266. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNoMatchField.md +1 -0
  267. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonIntegerTTLField.md +1 -0
  268. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonListMatchDestField.md +1 -0
  269. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonSecureContext.md +3 -0
  270. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonStringIdField.md +1 -0
  271. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonStringInMatchDestList.md +1 -0
  272. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonStringMatchField.md +1 -0
  273. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonTokenTypeField.md +1 -0
  274. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorRequestAborted.md +1 -0
  275. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorShuttingDown.md +1 -0
  276. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorTooLongIdField.md +3 -0
  277. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorUnsupportedType.md +3 -0
  278. package/build/src/third_party/issue-descriptions/sriInvalidSignatureHeader.md +14 -0
  279. package/build/src/third_party/issue-descriptions/sriInvalidSignatureInputHeader.md +15 -0
  280. package/build/src/third_party/issue-descriptions/sriMissingSignatureHeader.md +8 -0
  281. package/build/src/third_party/issue-descriptions/sriMissingSignatureInputHeader.md +7 -0
  282. package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsIncorrectLength.md +11 -0
  283. package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsNotByteSequence.md +14 -0
  284. package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsParameterized.md +15 -0
  285. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidComponentName.md +8 -0
  286. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidComponentType.md +13 -0
  287. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidDerivedComponentParameter.md +4 -0
  288. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidHeaderComponentParameter.md +5 -0
  289. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidParameter.md +11 -0
  290. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderKeyIdLength.md +12 -0
  291. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderMissingLabel.md +6 -0
  292. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderMissingRequiredParameters.md +8 -0
  293. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderValueMissingComponents.md +11 -0
  294. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderValueNotInnerList.md +11 -0
  295. package/build/src/third_party/issue-descriptions/sriValidationFailedIntegrityMismatch.md +10 -0
  296. package/build/src/third_party/issue-descriptions/sriValidationFailedInvalidLength.md +5 -0
  297. package/build/src/third_party/issue-descriptions/sriValidationFailedSignatureExpired.md +6 -0
  298. package/build/src/third_party/issue-descriptions/sriValidationFailedSignatureMismatch.md +11 -0
  299. package/build/src/third_party/issue-descriptions/stylesheetLateImport.md +4 -0
  300. package/build/src/third_party/issue-descriptions/stylesheetRequestFailed.md +3 -0
  301. package/build/src/third_party/issue-descriptions/summaryElementAccessibilityInteractiveContentSummaryDescendant.md +3 -0
  302. package/build/src/third_party/issue-descriptions/unencodedDigestIncorrectDigestLength.md +12 -0
  303. package/build/src/third_party/issue-descriptions/unencodedDigestIncorrectDigestType.md +17 -0
  304. package/build/src/third_party/issue-descriptions/unencodedDigestMalformedDictionary.md +14 -0
  305. package/build/src/third_party/issue-descriptions/unencodedDigestUnknownAlgorithm.md +15 -0
  306. package/build/src/third_party/issue-descriptions/webInstallManifestMissingId.md +3 -0
  307. package/build/src/third_party/issue-descriptions/webInstallManifestMissingNameOrShortName.md +3 -0
  308. package/build/src/third_party/issue-descriptions/webInstallManifestParsingOrNetworkError.md +3 -0
  309. package/build/src/third_party/issue-descriptions/webInstallNoManifest.md +3 -0
  310. package/build/src/third_party/issue-descriptions/webInstallStartUrlInvalid.md +3 -0
  311. package/build/src/third_party/lighthouse-devtools-mcp-bundle.js +58435 -0
  312. package/build/src/tools/ToolDefinition.js +80 -0
  313. package/build/src/tools/categories.js +33 -0
  314. package/build/src/tools/comments.js +169 -0
  315. package/build/src/tools/console.js +104 -0
  316. package/build/src/tools/css.js +45 -0
  317. package/build/src/tools/emulation.js +84 -0
  318. package/build/src/tools/extensions.js +103 -0
  319. package/build/src/tools/input.js +652 -0
  320. package/build/src/tools/lighthouse.js +149 -0
  321. package/build/src/tools/memory.js +424 -0
  322. package/build/src/tools/network.js +128 -0
  323. package/build/src/tools/pages.js +363 -0
  324. package/build/src/tools/performance.js +212 -0
  325. package/build/src/tools/pwa.js +128 -0
  326. package/build/src/tools/screencast.js +119 -0
  327. package/build/src/tools/screenshot.js +277 -0
  328. package/build/src/tools/script.js +232 -0
  329. package/build/src/tools/slim/tools.js +96 -0
  330. package/build/src/tools/snapshot.js +63 -0
  331. package/build/src/tools/thirdPartyDeveloper.js +85 -0
  332. package/build/src/tools/tools.js +55 -0
  333. package/build/src/tools/webmcp.js +66 -0
  334. package/build/src/types.js +10 -0
  335. package/build/src/utils/WaitForHelper.js +316 -0
  336. package/build/src/utils/bytes.js +105 -0
  337. package/build/src/utils/check-for-updates.js +75 -0
  338. package/build/src/utils/files.js +57 -0
  339. package/build/src/utils/id.js +16 -0
  340. package/build/src/utils/keyboard.js +297 -0
  341. package/build/src/utils/logger.js +52 -0
  342. package/build/src/utils/pagination.js +50 -0
  343. package/build/src/utils/polyfill.js +11 -0
  344. package/build/src/utils/url.js +116 -0
  345. package/build/src/version.js +10 -0
  346. package/package.json +41 -4
  347. package/skills/a11y-debugging/SKILL.md +91 -0
  348. package/skills/a11y-debugging/references/a11y-snippets.md +92 -0
  349. package/skills/chrome-devtools/SKILL.md +74 -0
  350. package/skills/chrome-devtools-cli/SKILL.md +194 -0
  351. package/skills/chrome-devtools-cli/references/installation.md +14 -0
  352. package/skills/cookie-debugging/SKILL.md +149 -0
  353. package/skills/debug-optimize-lcp/SKILL.md +121 -0
  354. package/skills/debug-optimize-lcp/references/elements-and-size.md +27 -0
  355. package/skills/debug-optimize-lcp/references/lcp-breakdown.md +23 -0
  356. package/skills/debug-optimize-lcp/references/lcp-snippets.md +79 -0
  357. package/skills/debug-optimize-lcp/references/optimization-strategies.md +38 -0
  358. package/skills/memory-leak-debugging/SKILL.md +58 -0
  359. package/skills/memory-leak-debugging/references/common-leaks.md +33 -0
  360. package/skills/troubleshooting/SKILL.md +99 -0
@@ -0,0 +1,51 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { execSync } from 'node:child_process';
7
+ import fs from 'node:fs/promises';
8
+ import path from 'node:path';
9
+ import process from 'node:process';
10
+ const DEFAULT_REGISTRY = 'https://registry.npmjs.org';
11
+ function getRegistry() {
12
+ // Use the user's configured npm registry so update checks work behind
13
+ // corporate proxies and private registries. `npm config get registry`
14
+ // honors .npmrc files at every scope and respects npm_config_registry,
15
+ // so it covers direct CLI invocations as well as `npx` / `npm run`.
16
+ try {
17
+ const registry = execSync('npm config get registry', {
18
+ encoding: 'utf8',
19
+ stdio: ['ignore', 'pipe', 'ignore'],
20
+ timeout: 5000,
21
+ windowsHide: true,
22
+ })
23
+ .trim()
24
+ .replace(/\/$/, '');
25
+ if (registry && registry !== 'undefined' && /^https?:\/\//.test(registry)) {
26
+ return registry;
27
+ }
28
+ }
29
+ catch {
30
+ // npm not on PATH or other errors, fall back to default.
31
+ }
32
+ return DEFAULT_REGISTRY;
33
+ }
34
+ const cachePath = process.argv[2];
35
+ if (cachePath) {
36
+ try {
37
+ const response = await fetch(`${getRegistry()}/chrome-devtools-mcp/latest`);
38
+ const data = response.ok ? await response.json() : null;
39
+ if (data &&
40
+ typeof data === 'object' &&
41
+ 'version' in data &&
42
+ typeof data.version === 'string') {
43
+ await fs.mkdir(path.dirname(cachePath), { recursive: true });
44
+ await fs.writeFile(cachePath, JSON.stringify({ version: data.version }));
45
+ }
46
+ }
47
+ catch {
48
+ // Ignore errors.
49
+ }
50
+ }
51
+ //# sourceMappingURL=check-latest-version.js.map
@@ -0,0 +1,77 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import '../utils/polyfill.js';
7
+ import process from 'node:process';
8
+ import { BrowserManager } from '../BrowserManager.js';
9
+ import { McpServer, logDisclaimers } from '../index.js';
10
+ import { ClearcutLogger } from '../telemetry/ClearcutLogger.js';
11
+ import { computeFlagUsage } from '../telemetry/flagUtils.js';
12
+ import { StdioServerTransport } from '../third_party/index.js';
13
+ import { checkForUpdates } from '../utils/check-for-updates.js';
14
+ import { logger, saveLogsToFile } from '../utils/logger.js';
15
+ import { VERSION } from '../version.js';
16
+ import { mcpOptions, parseArguments } from '../config/mcp-options.js';
17
+ await checkForUpdates('Run `npm install chrome-devtools-mcp@latest` to update.');
18
+ export const args = parseArguments(VERSION);
19
+ const logFile = args.logFile ? saveLogsToFile(args.logFile) : undefined;
20
+ if (process.env['CHROME_DEVTOOLS_MCP_CRASH_ON_UNCAUGHT'] !== 'true') {
21
+ process.on('unhandledRejection', (reason, promise) => {
22
+ logger?.('Unhandled promise rejection', promise, reason);
23
+ });
24
+ }
25
+ logger?.(`Starting Chrome DevTools MCP Server v${VERSION}`);
26
+ const browserManager = new BrowserManager(args, {
27
+ logFile,
28
+ });
29
+ const serverPromise = McpServer.from(args, {
30
+ browserManager,
31
+ });
32
+ // Shutdown on stdin EOF (stdio MCP convention — the client closes the
33
+ // transport to signal exit) and on standard termination signals. Without
34
+ // this, an active Chrome subprocess keeps the Node event loop ref'd after
35
+ // stdin closes and the server hangs until something else kills it.
36
+ let shuttingDown = false;
37
+ async function shutdown(reason) {
38
+ if (shuttingDown) {
39
+ return;
40
+ }
41
+ shuttingDown = true;
42
+ logger?.(`Shutting down (${reason})`);
43
+ // Backstop in case browser teardown hangs (e.g. unresponsive Chrome,
44
+ // slow beforeunload handlers, many tabs). Exits 0 because we still
45
+ // honored the shutdown request; the log line preserves observability.
46
+ // Unref'd so it doesn't keep the loop alive on the clean path.
47
+ setTimeout(() => {
48
+ logger?.('Shutdown timeout exceeded, forcing exit');
49
+ process.exit(0);
50
+ }, 5000).unref();
51
+ const server = await serverPromise;
52
+ await server.close();
53
+ process.exit(0);
54
+ }
55
+ process.stdin.on('end', () => {
56
+ void shutdown('stdin end');
57
+ });
58
+ process.stdin.on('close', () => {
59
+ void shutdown('stdin close');
60
+ });
61
+ process.on('SIGTERM', () => {
62
+ void shutdown('SIGTERM');
63
+ });
64
+ process.on('SIGINT', () => {
65
+ void shutdown('SIGINT');
66
+ });
67
+ process.on('SIGHUP', () => {
68
+ void shutdown('SIGHUP');
69
+ });
70
+ const server = await serverPromise;
71
+ const transport = new StdioServerTransport();
72
+ await server.connect(transport);
73
+ logger?.('Chrome DevTools MCP Server connected');
74
+ logDisclaimers(args);
75
+ void ClearcutLogger.get()?.logDailyActiveIfNeeded();
76
+ void ClearcutLogger.get()?.logServerStart(computeFlagUsage(args, mcpOptions));
77
+ //# sourceMappingURL=chrome-devtools-mcp-main.js.map
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @license
4
+ * Copyright 2025 Google LLC
5
+ * SPDX-License-Identifier: Apache-2.0
6
+ */
7
+ process.title = 'chrome-devtools-mcp';
8
+ import { version } from 'node:process';
9
+ const [major, minor] = version.substring(1).split('.').map(Number);
10
+ if (major === 20 && minor < 19) {
11
+ console.error(`ERROR: \`chrome-devtools-mcp\` does not support Node ${process.version}. Please upgrade to Node 20.19.0 LTS or a newer LTS.`);
12
+ process.exit(1);
13
+ }
14
+ if (major === 22 && minor < 12) {
15
+ console.error(`ERROR: \`chrome-devtools-mcp\` does not support Node ${process.version}. Please upgrade to Node 22.12.0 LTS or a newer LTS.`);
16
+ process.exit(1);
17
+ }
18
+ if (major < 20) {
19
+ console.error(`ERROR: \`chrome-devtools-mcp\` does not support Node ${process.version}. Please upgrade to Node 20.19.0 LTS or a newer LTS.`);
20
+ process.exit(1);
21
+ }
22
+ await import('./chrome-devtools-mcp-main.js');
23
+ //# sourceMappingURL=chrome-devtools-mcp.js.map
@@ -0,0 +1,222 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @license
4
+ * Copyright 2026 Google LLC
5
+ * SPDX-License-Identifier: Apache-2.0
6
+ */
7
+ process.title = 'chrome-devtools';
8
+ import process from 'node:process';
9
+ import { startDaemon, stopDaemon, sendCommand, handleResponse, verifyDaemonVersion, } from '../daemon/client.js';
10
+ import { isDaemonRunning, serializeArgs, assertValidSessionId, } from '../daemon/utils.js';
11
+ import { logDisclaimers } from '../index.js';
12
+ import { hideBin, yargs } from '../third_party/index.js';
13
+ import { checkForUpdates } from '../utils/check-for-updates.js';
14
+ import { VERSION } from '../version.js';
15
+ import { buildCommand } from '../config/cli-commands.js';
16
+ import { commands } from '../config/cli-options.js';
17
+ import { mcpOptions, parseArguments, getMcpOptionsForViaCli, } from '../config/mcp-options.js';
18
+ await checkForUpdates('Run `npm install -g chrome-devtools-mcp@latest` and `chrome-devtools start` to update and restart the daemon.');
19
+ const DEFAULT_CLI_ARGS = ['--viaCli'];
20
+ async function start(args, sessionId) {
21
+ const combinedArgs = [...DEFAULT_CLI_ARGS, ...args];
22
+ await startDaemon(combinedArgs, sessionId);
23
+ logDisclaimers(parseArguments(VERSION, combinedArgs));
24
+ }
25
+ function getCliOptions() {
26
+ const options = {
27
+ ...getMcpOptionsForViaCli(),
28
+ };
29
+ // Missing CLI serialization.
30
+ delete options.viewport;
31
+ // Change the defaults for the CLI.
32
+ delete options.experimentalStructuredContent;
33
+ delete options.experimentalInteropTools;
34
+ return options;
35
+ }
36
+ const y = yargs(hideBin(process.argv))
37
+ .locale('en') // Force English to ensure error string matching works in .fail, all custom messages we output are in English anyways
38
+ .scriptName('chrome-devtools')
39
+ .showHelpOnFail(true)
40
+ .usage('chrome-devtools <command> [...args] --flags')
41
+ .usage(`Run 'chrome-devtools <command> --help' for help on the specific command.`)
42
+ .option('sessionId', {
43
+ type: 'string',
44
+ description: 'Session ID for daemon scoping',
45
+ default: process.env.CD4A_INTERNAL_DAEMON_SESSION_ID || '',
46
+ hidden: true,
47
+ coerce: (sessionId) => {
48
+ assertValidSessionId(sessionId);
49
+ return sessionId;
50
+ },
51
+ })
52
+ .demandCommand()
53
+ .version(VERSION)
54
+ .strict()
55
+ .help(true)
56
+ .wrap(120)
57
+ .fail((msg, err) => {
58
+ if (msg) {
59
+ console.error('Error:', msg);
60
+ if (msg.includes('Not enough non-option arguments') ||
61
+ msg.includes('Unknown argument') ||
62
+ msg.includes('Unknown arguments')) {
63
+ console.error('\n=========================================');
64
+ console.error('💡 TIP FOR AI AGENT / DEVELOPER:');
65
+ console.error('In the `chrome-devtools` CLI:');
66
+ console.error('1. Required parameters MUST be passed as positional arguments (without flags).');
67
+ console.error(' - INCORRECT: chrome-devtools click --pageId 1 --uid "1_2"');
68
+ console.error(' - CORRECT: chrome-devtools click 1 "1_2"');
69
+ console.error('2. Optional parameters are passed as double-dash options/flags (e.g. --dblClick true).');
70
+ console.error('3. Make sure to escape quotes properly for your shell environment.');
71
+ console.error('Run `chrome-devtools <command> --help` to see exact positional and optional parameters.');
72
+ console.error('=========================================');
73
+ }
74
+ }
75
+ else if (err) {
76
+ console.error(err);
77
+ }
78
+ process.exit(1);
79
+ });
80
+ y.command('start', 'Start or restart chrome-devtools-mcp', y => y
81
+ .options(getCliOptions())
82
+ .example('$0 start --browserUrl http://localhost:9222', 'Start the server connecting to an existing browser')
83
+ .strict(), async (argv) => {
84
+ if (isDaemonRunning(argv.sessionId)) {
85
+ await stopDaemon(argv.sessionId);
86
+ }
87
+ // Defaults but we do not want to affect the yargs conflict resolution.
88
+ if (argv.isolated === undefined &&
89
+ argv.userDataDir === undefined &&
90
+ !argv.autoConnect &&
91
+ !argv.browserUrl &&
92
+ !argv.wsEndpoint) {
93
+ argv.isolated = true;
94
+ }
95
+ if (argv.headless === undefined &&
96
+ !argv.autoConnect &&
97
+ !argv.browserUrl &&
98
+ !argv.wsEndpoint) {
99
+ argv.headless = true;
100
+ }
101
+ const args = serializeArgs(getCliOptions(), argv);
102
+ await start(args, argv.sessionId);
103
+ process.exit(0);
104
+ }).strict(); // Re-enable strict validation for other commands; this is applied to the yargs instance itself
105
+ y.command('status', 'Checks if chrome-devtools-mcp is running', y => y, async (argv) => {
106
+ if (isDaemonRunning(argv.sessionId)) {
107
+ console.log('chrome-devtools-mcp daemon is running.');
108
+ const response = await sendCommand({
109
+ method: 'status',
110
+ }, argv.sessionId);
111
+ if (response.success) {
112
+ const data = JSON.parse(response.result);
113
+ console.log(`pid=${data.pid} socket=${data.socketPath} start-date=${data.startDate} version=${data.version}`);
114
+ console.log(`args=${JSON.stringify(data.args)}`);
115
+ if (data.version !== VERSION) {
116
+ console.warn(`Warning: Daemon server version (${data.version}) does not match CLI version (${VERSION}). Run 'chrome-devtools start' to update and restart the daemon.`);
117
+ }
118
+ }
119
+ else {
120
+ console.error('Error:', response.error);
121
+ process.exit(1);
122
+ }
123
+ }
124
+ else {
125
+ console.log('chrome-devtools-mcp daemon is not running.');
126
+ }
127
+ process.exit(0);
128
+ });
129
+ y.command('stop', 'Stop chrome-devtools-mcp if any', y => y, async (argv) => {
130
+ const sessionId = argv.sessionId;
131
+ if (!isDaemonRunning(sessionId)) {
132
+ process.exit(0);
133
+ }
134
+ await stopDaemon(sessionId);
135
+ process.exit(0);
136
+ });
137
+ for (const [commandName, commandDef] of Object.entries(commands)) {
138
+ const args = commandDef.args;
139
+ const { command, usage } = buildCommand(commandName, args);
140
+ y.command(command, commandDef.description, y => {
141
+ y.usage(usage);
142
+ y.option('output-format', {
143
+ choices: ['md', 'json'],
144
+ default: 'md',
145
+ });
146
+ for (const [argName, opt] of Object.entries(args)) {
147
+ const type = opt.type === 'integer' || opt.type === 'number'
148
+ ? 'number'
149
+ : opt.type === 'boolean'
150
+ ? 'boolean'
151
+ : opt.type === 'array'
152
+ ? 'array'
153
+ : 'string';
154
+ if (opt.required) {
155
+ const options = {
156
+ describe: opt.description,
157
+ type: type,
158
+ };
159
+ if (opt.default !== undefined) {
160
+ options.default = opt.default;
161
+ }
162
+ if (opt.enum) {
163
+ options.choices = opt.enum;
164
+ }
165
+ y.positional(argName, options);
166
+ }
167
+ else {
168
+ const options = {
169
+ describe: opt.description,
170
+ type: type,
171
+ };
172
+ if (opt.default !== undefined) {
173
+ options.default = opt.default;
174
+ }
175
+ if (opt.enum) {
176
+ options.choices = opt.enum;
177
+ }
178
+ y.option(argName, options);
179
+ }
180
+ }
181
+ }, async (argv) => {
182
+ const sessionId = argv.sessionId;
183
+ try {
184
+ const versionWarningPromise = isDaemonRunning(sessionId)
185
+ ? verifyDaemonVersion(sessionId, VERSION)
186
+ : Promise.resolve(undefined);
187
+ if (!isDaemonRunning(sessionId)) {
188
+ await start(serializeArgs(mcpOptions, argv), sessionId);
189
+ }
190
+ const commandArgs = {};
191
+ for (const argName of Object.keys(args)) {
192
+ if (argName in argv) {
193
+ commandArgs[argName] = argv[argName];
194
+ }
195
+ }
196
+ const response = await sendCommand({
197
+ method: 'invoke_tool',
198
+ tool: commandName,
199
+ args: commandArgs,
200
+ }, sessionId);
201
+ if (response.success) {
202
+ console.log(await handleResponse(JSON.parse(response.result), argv['output-format']));
203
+ }
204
+ else {
205
+ console.error('Error:', response.error);
206
+ }
207
+ const versionWarning = await versionWarningPromise;
208
+ if (versionWarning) {
209
+ console.warn(versionWarning);
210
+ }
211
+ if (!response.success) {
212
+ process.exit(1);
213
+ }
214
+ }
215
+ catch (error) {
216
+ console.error('Failed to execute command:', error);
217
+ process.exit(1);
218
+ }
219
+ });
220
+ }
221
+ await y.parse();
222
+ //# sourceMappingURL=chrome-devtools.js.map
@@ -0,0 +1,291 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { FakeIssuesManager } from '../devtools/DevtoolsUtils.js';
7
+ import { DevTools, FrameEvent } from '../third_party/index.js';
8
+ import { createIdGenerator, stableIdSymbol, } from '../utils/id.js';
9
+ import { logger } from '../utils/logger.js';
10
+ export class UncaughtError {
11
+ details;
12
+ targetId;
13
+ constructor(details, targetId) {
14
+ this.details = details;
15
+ this.targetId = targetId;
16
+ }
17
+ }
18
+ export class PageCollector {
19
+ pptrPage;
20
+ #listeners;
21
+ #pendingSameDocumentNavigation = false;
22
+ #frameNavigatedWithinDocumentTarget;
23
+ maxNavigationSaved = 3;
24
+ /**
25
+ * This maps a Page to a list of navigations with a sub-list
26
+ * of all collected resources.
27
+ * The newer navigations come first.
28
+ */
29
+ storage = [[]];
30
+ constructor(page, listeners, maxResourcesPerNavigation) {
31
+ this.pptrPage = page;
32
+ this.#attachFrameNavigatedWithinDocumentListener();
33
+ const idGenerator = createIdGenerator();
34
+ const listenerMap = listeners(value => {
35
+ const withId = value;
36
+ withId[stableIdSymbol] = idGenerator();
37
+ this.storage[0].push(withId);
38
+ if (maxResourcesPerNavigation !== undefined &&
39
+ this.storage[0].length > maxResourcesPerNavigation) {
40
+ this.storage[0].splice(0, this.storage[0].length - maxResourcesPerNavigation);
41
+ }
42
+ });
43
+ listenerMap['framenavigated'] = (frame) => {
44
+ // Only split the storage on main frame navigation
45
+ if (frame !== this.pptrPage.mainFrame()) {
46
+ return;
47
+ }
48
+ // Re-attach the listener to the current main frame: a cross-document
49
+ // navigation may have replaced the frame object, so the reference
50
+ // captured at construction time would be stale.
51
+ this.#attachFrameNavigatedWithinDocumentListener();
52
+ // Same-document (SPA) navigations also emit `framenavigated`, but they
53
+ // must not rotate the retained history. Puppeteer emits
54
+ // `FrameNavigatedWithinDocument` right before `FrameNavigated` for such
55
+ // navigations, so consume the flag here to skip the split.
56
+ if (this.#pendingSameDocumentNavigation) {
57
+ this.#pendingSameDocumentNavigation = false;
58
+ return;
59
+ }
60
+ this.splitAfterNavigation();
61
+ };
62
+ for (const [name, listener] of Object.entries(listenerMap)) {
63
+ this.pptrPage.on(name, listener);
64
+ }
65
+ this.#listeners = listenerMap;
66
+ }
67
+ dispose() {
68
+ this.#detachFrameNavigatedWithinDocumentListener();
69
+ if (this.#listeners) {
70
+ for (const [name, listener] of Object.entries(this.#listeners)) {
71
+ this.pptrPage.off(name, listener);
72
+ }
73
+ }
74
+ }
75
+ // Puppeteer emits this right before the page-level navigation event for
76
+ // same-document (SPA) navigations, which lets `framenavigated` skip the
77
+ // history rotation for those navigations.
78
+ #onFrameNavigatedWithinDocument = () => {
79
+ this.#pendingSameDocumentNavigation = true;
80
+ };
81
+ #attachFrameNavigatedWithinDocumentListener() {
82
+ this.#detachFrameNavigatedWithinDocumentListener();
83
+ this.#frameNavigatedWithinDocumentTarget = this.pptrPage.mainFrame();
84
+ this.#frameNavigatedWithinDocumentTarget.on(FrameEvent.FrameNavigatedWithinDocument, this.#onFrameNavigatedWithinDocument);
85
+ }
86
+ #detachFrameNavigatedWithinDocumentListener() {
87
+ if (this.#frameNavigatedWithinDocumentTarget) {
88
+ this.#frameNavigatedWithinDocumentTarget.off(FrameEvent.FrameNavigatedWithinDocument, this.#onFrameNavigatedWithinDocument);
89
+ this.#frameNavigatedWithinDocumentTarget = undefined;
90
+ }
91
+ }
92
+ splitAfterNavigation() {
93
+ // Add the latest navigation first
94
+ this.storage.unshift([]);
95
+ this.storage.splice(this.maxNavigationSaved);
96
+ }
97
+ getData(includePreservedData) {
98
+ if (!includePreservedData) {
99
+ return this.storage[0];
100
+ }
101
+ const data = [];
102
+ for (let index = this.maxNavigationSaved; index >= 0; index--) {
103
+ if (this.storage[index]) {
104
+ data.push(...this.storage[index]);
105
+ }
106
+ }
107
+ return data;
108
+ }
109
+ getIdForResource(resource) {
110
+ return resource[stableIdSymbol] ?? -1;
111
+ }
112
+ getById(stableId) {
113
+ const item = this.find(item => item[stableIdSymbol] === stableId);
114
+ if (!item) {
115
+ throw new Error('Request not found for selected page');
116
+ }
117
+ return item;
118
+ }
119
+ find(filter) {
120
+ for (const navigation of this.storage) {
121
+ const item = navigation.find(filter);
122
+ if (item) {
123
+ return item;
124
+ }
125
+ }
126
+ return;
127
+ }
128
+ }
129
+ export class ConsoleCollector extends PageCollector {
130
+ static MAX_MESSAGES_PER_NAVIGATION = 10_000;
131
+ #subscriber;
132
+ constructor(page, listeners, maxMessagesPerNavigation = ConsoleCollector.MAX_MESSAGES_PER_NAVIGATION) {
133
+ super(page, listeners, maxMessagesPerNavigation);
134
+ this.#subscriber = new PageEventSubscriber(this.pptrPage);
135
+ this.#subscriber.subscribe();
136
+ }
137
+ dispose() {
138
+ super.dispose();
139
+ this.#subscriber?.unsubscribe();
140
+ }
141
+ }
142
+ class PageEventSubscriber {
143
+ #issueManager = new FakeIssuesManager();
144
+ #issueAggregator = new DevTools.IssueAggregator(this.#issueManager);
145
+ #seenKeys = new Set();
146
+ #seenIssues = new Set();
147
+ #page;
148
+ #session;
149
+ #targetId;
150
+ #pendingSameDocumentNavigation = false;
151
+ #frameNavigatedWithinDocumentTarget;
152
+ constructor(page) {
153
+ this.#page = page;
154
+ // @ts-expect-error use existing CDP client (internal Puppeteer API).
155
+ this.#session = this.#page._client();
156
+ // @ts-expect-error use internal Puppeteer API to get target ID
157
+ this.#targetId = this.#session.target()._targetId;
158
+ }
159
+ #resetIssueAggregator() {
160
+ this.#issueManager = new FakeIssuesManager();
161
+ if (this.#issueAggregator) {
162
+ this.#issueAggregator.removeEventListener("AggregatedIssueUpdated" /* DevTools.IssueAggregatorEvents.AGGREGATED_ISSUE_UPDATED */, this.#onAggregatedIssue);
163
+ }
164
+ this.#issueAggregator = new DevTools.IssueAggregator(this.#issueManager);
165
+ this.#issueAggregator.addEventListener("AggregatedIssueUpdated" /* DevTools.IssueAggregatorEvents.AGGREGATED_ISSUE_UPDATED */, this.#onAggregatedIssue);
166
+ }
167
+ subscribe() {
168
+ this.#resetIssueAggregator();
169
+ this.#page.on('framenavigated', this.#onFrameNavigated);
170
+ this.#page.on('issue', this.#onIssueAdded);
171
+ this.#session.on('Runtime.exceptionThrown', this.#onExceptionThrown);
172
+ this.#attachFrameNavigatedWithinDocumentListener();
173
+ }
174
+ unsubscribe() {
175
+ this.#seenKeys.clear();
176
+ this.#seenIssues.clear();
177
+ this.#detachFrameNavigatedWithinDocumentListener();
178
+ this.#page.off('framenavigated', this.#onFrameNavigated);
179
+ this.#page.off('issue', this.#onIssueAdded);
180
+ this.#session.off('Runtime.exceptionThrown', this.#onExceptionThrown);
181
+ if (this.#issueAggregator) {
182
+ this.#issueAggregator.removeEventListener("AggregatedIssueUpdated" /* DevTools.IssueAggregatorEvents.AGGREGATED_ISSUE_UPDATED */, this.#onAggregatedIssue);
183
+ }
184
+ }
185
+ #onAggregatedIssue = (event) => {
186
+ if (this.#seenIssues.has(event.data)) {
187
+ return;
188
+ }
189
+ this.#seenIssues.add(event.data);
190
+ this.#page.emit('devtoolsAggregatedIssue', event.data);
191
+ };
192
+ #onExceptionThrown = (event) => {
193
+ this.#page.emit('uncaughtError', new UncaughtError(event.exceptionDetails, this.#targetId));
194
+ };
195
+ // On navigation, we reset issue aggregation.
196
+ #onFrameNavigated = (frame) => {
197
+ // Only split the storage on main frame navigation
198
+ if (frame !== frame.page().mainFrame()) {
199
+ return;
200
+ }
201
+ // Re-attach the listener to the current main frame: a cross-document
202
+ // navigation may have replaced the frame object, so the reference
203
+ // captured at construction time would be stale.
204
+ this.#attachFrameNavigatedWithinDocumentListener();
205
+ if (this.#pendingSameDocumentNavigation) {
206
+ this.#pendingSameDocumentNavigation = false;
207
+ return;
208
+ }
209
+ this.#seenKeys.clear();
210
+ this.#seenIssues.clear();
211
+ this.#resetIssueAggregator();
212
+ };
213
+ // Puppeteer emits this right before the page-level navigation event for
214
+ // same-document (SPA) navigations, which lets `framenavigated` skip the
215
+ // issue aggregation reset for those navigations.
216
+ #onFrameNavigatedWithinDocument = () => {
217
+ this.#pendingSameDocumentNavigation = true;
218
+ };
219
+ #attachFrameNavigatedWithinDocumentListener() {
220
+ this.#detachFrameNavigatedWithinDocumentListener();
221
+ this.#frameNavigatedWithinDocumentTarget = this.#page.mainFrame();
222
+ this.#frameNavigatedWithinDocumentTarget.on(FrameEvent.FrameNavigatedWithinDocument, this.#onFrameNavigatedWithinDocument);
223
+ }
224
+ #detachFrameNavigatedWithinDocumentListener() {
225
+ if (this.#frameNavigatedWithinDocumentTarget) {
226
+ this.#frameNavigatedWithinDocumentTarget.off(FrameEvent.FrameNavigatedWithinDocument, this.#onFrameNavigatedWithinDocument);
227
+ this.#frameNavigatedWithinDocumentTarget = undefined;
228
+ }
229
+ }
230
+ #onIssueAdded = (inspectorIssue) => {
231
+ try {
232
+ // @ts-expect-error The types are missmatched but they
233
+ // are coming from CDP
234
+ if (!DevTools.isIssueCodeSupported(inspectorIssue.code)) {
235
+ return;
236
+ }
237
+ const issue = DevTools.createIssuesFromProtocolIssue(null,
238
+ // @ts-expect-error Protocol types diverge.
239
+ inspectorIssue)[0];
240
+ if (!issue) {
241
+ logger?.('No issue mapping for for the issue: ', inspectorIssue.code);
242
+ return;
243
+ }
244
+ const primaryKey = issue.primaryKey();
245
+ if (this.#seenKeys.has(primaryKey)) {
246
+ return;
247
+ }
248
+ this.#seenKeys.add(primaryKey);
249
+ this.#issueManager.dispatchEventToListeners("IssueAdded" /* DevTools.IssuesManagerEvents.ISSUE_ADDED */, {
250
+ issue,
251
+ // @ts-expect-error We don't care that issues model is null
252
+ issuesModel: null,
253
+ });
254
+ }
255
+ catch (error) {
256
+ logger?.('Error creating a new issue', error);
257
+ }
258
+ };
259
+ }
260
+ export class NetworkCollector extends PageCollector {
261
+ static MAX_REQUESTS_PER_NAVIGATION = 1_000;
262
+ constructor(page, maxRequestsPerNavigation = NetworkCollector.MAX_REQUESTS_PER_NAVIGATION, listeners = collect => {
263
+ return {
264
+ request: req => {
265
+ collect(req);
266
+ },
267
+ };
268
+ }) {
269
+ super(page, listeners, maxRequestsPerNavigation);
270
+ }
271
+ splitAfterNavigation() {
272
+ const requests = this.storage[0];
273
+ const lastRequestIdx = requests.findLastIndex(request => {
274
+ return request.frame() === this.pptrPage.mainFrame()
275
+ ? request.isNavigationRequest()
276
+ : false;
277
+ });
278
+ // Keep all requests since the last navigation request including that
279
+ // navigation request itself.
280
+ // Keep the reference
281
+ if (lastRequestIdx !== -1) {
282
+ const fromCurrentNavigation = requests.splice(lastRequestIdx);
283
+ this.storage.unshift(fromCurrentNavigation);
284
+ }
285
+ else {
286
+ this.storage.unshift([]);
287
+ }
288
+ this.storage.splice(this.maxNavigationSaved);
289
+ }
290
+ }
291
+ //# sourceMappingURL=PageCollector.js.map