@gabrielbryk/arc-devtools-mcp 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 (367) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +977 -0
  3. package/build/src/HeapSnapshotManager.js +148 -0
  4. package/build/src/McpContext.js +737 -0
  5. package/build/src/McpPage.js +315 -0
  6. package/build/src/McpResponse.js +990 -0
  7. package/build/src/Mutex.js +38 -0
  8. package/build/src/PageCollector.js +297 -0
  9. package/build/src/ServiceWorkerCollector.js +171 -0
  10. package/build/src/SlimMcpResponse.js +19 -0
  11. package/build/src/TextSnapshot.js +236 -0
  12. package/build/src/ToolHandler.js +223 -0
  13. package/build/src/WaitForHelper.js +190 -0
  14. package/build/src/bin/check-latest-version.js +50 -0
  15. package/build/src/bin/chrome-devtools-cli-options.js +978 -0
  16. package/build/src/bin/chrome-devtools-mcp-cli-options.js +412 -0
  17. package/build/src/bin/chrome-devtools-mcp-main.js +72 -0
  18. package/build/src/bin/chrome-devtools-mcp.js +23 -0
  19. package/build/src/bin/chrome-devtools.js +189 -0
  20. package/build/src/browser.js +253 -0
  21. package/build/src/daemon/client.js +160 -0
  22. package/build/src/daemon/daemon.js +261 -0
  23. package/build/src/daemon/types.js +7 -0
  24. package/build/src/daemon/utils.js +115 -0
  25. package/build/src/devtools/DevToolsConnectionAdapter.js +70 -0
  26. package/build/src/devtools/DevtoolsUtils.js +369 -0
  27. package/build/src/devtools/McpHostBindingAdapter.js +165 -0
  28. package/build/src/formatters/ConsoleFormatter.js +288 -0
  29. package/build/src/formatters/HeapSnapshotFormatter.js +97 -0
  30. package/build/src/formatters/IssueFormatter.js +193 -0
  31. package/build/src/formatters/NetworkFormatter.js +238 -0
  32. package/build/src/formatters/SnapshotFormatter.js +135 -0
  33. package/build/src/index.js +153 -0
  34. package/build/src/issue-descriptions.js +40 -0
  35. package/build/src/logger.js +37 -0
  36. package/build/src/polyfill.js +8 -0
  37. package/build/src/telemetry/ClearcutLogger.js +169 -0
  38. package/build/src/telemetry/WatchdogClient.js +61 -0
  39. package/build/src/telemetry/errors.js +18 -0
  40. package/build/src/telemetry/flagUtils.js +89 -0
  41. package/build/src/telemetry/metricsRegistry.js +89 -0
  42. package/build/src/telemetry/persistence.js +72 -0
  43. package/build/src/telemetry/transformation.js +134 -0
  44. package/build/src/telemetry/types.js +31 -0
  45. package/build/src/telemetry/watchdog/ClearcutSender.js +205 -0
  46. package/build/src/telemetry/watchdog/main.js +128 -0
  47. package/build/src/third_party/THIRD_PARTY_NOTICES +3637 -0
  48. package/build/src/third_party/bundled-packages.json +12 -0
  49. package/build/src/third_party/devtools-formatter-worker.js +15301 -0
  50. package/build/src/third_party/devtools-heap-snapshot-worker.js +9870 -0
  51. package/build/src/third_party/index.js +159597 -0
  52. package/build/src/third_party/issue-descriptions/CoepCoopSandboxedIframeCannotNavigateToCoopPage.md +4 -0
  53. package/build/src/third_party/issue-descriptions/CoepCorpNotSameOrigin.md +8 -0
  54. package/build/src/third_party/issue-descriptions/CoepCorpNotSameOriginAfterDefaultedToSameOriginByCoep.md +18 -0
  55. package/build/src/third_party/issue-descriptions/CoepCorpNotSameSite.md +7 -0
  56. package/build/src/third_party/issue-descriptions/CoepFrameResourceNeedsCoepHeader.md +10 -0
  57. package/build/src/third_party/issue-descriptions/CompatibilityModeQuirks.md +5 -0
  58. package/build/src/third_party/issue-descriptions/CookieAttributeValueExceedsMaxSize.md +5 -0
  59. package/build/src/third_party/issue-descriptions/LowTextContrast.md +5 -0
  60. package/build/src/third_party/issue-descriptions/SameSiteExcludeContextDowngradeRead.md +8 -0
  61. package/build/src/third_party/issue-descriptions/SameSiteExcludeContextDowngradeSet.md +8 -0
  62. package/build/src/third_party/issue-descriptions/SameSiteExcludeNavigationContextDowngrade.md +8 -0
  63. package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureErrorRead.md +8 -0
  64. package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureErrorSet.md +8 -0
  65. package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureWarnRead.md +8 -0
  66. package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureWarnSet.md +8 -0
  67. package/build/src/third_party/issue-descriptions/SameSiteUnspecifiedLaxAllowUnsafeRead.md +9 -0
  68. package/build/src/third_party/issue-descriptions/SameSiteUnspecifiedLaxAllowUnsafeSet.md +9 -0
  69. package/build/src/third_party/issue-descriptions/SameSiteWarnCrossDowngradeRead.md +8 -0
  70. package/build/src/third_party/issue-descriptions/SameSiteWarnCrossDowngradeSet.md +8 -0
  71. package/build/src/third_party/issue-descriptions/SameSiteWarnStrictLaxDowngradeStrict.md +8 -0
  72. package/build/src/third_party/issue-descriptions/arInsecureContext.md +7 -0
  73. package/build/src/third_party/issue-descriptions/arInvalidInfoHeader.md +5 -0
  74. package/build/src/third_party/issue-descriptions/arInvalidRegisterOsSourceHeader.md +5 -0
  75. package/build/src/third_party/issue-descriptions/arInvalidRegisterOsTriggerHeader.md +5 -0
  76. package/build/src/third_party/issue-descriptions/arInvalidRegisterSourceHeader.md +5 -0
  77. package/build/src/third_party/issue-descriptions/arInvalidRegisterTriggerHeader.md +5 -0
  78. package/build/src/third_party/issue-descriptions/arNavigationRegistrationUniqueScopeAlreadySet.md +5 -0
  79. package/build/src/third_party/issue-descriptions/arNavigationRegistrationWithoutTransientUserActivation.md +6 -0
  80. package/build/src/third_party/issue-descriptions/arNoRegisterOsSourceHeader.md +5 -0
  81. package/build/src/third_party/issue-descriptions/arNoRegisterOsTriggerHeader.md +5 -0
  82. package/build/src/third_party/issue-descriptions/arNoRegisterSourceHeader.md +5 -0
  83. package/build/src/third_party/issue-descriptions/arNoRegisterTriggerHeader.md +5 -0
  84. package/build/src/third_party/issue-descriptions/arNoWebOrOsSupport.md +4 -0
  85. package/build/src/third_party/issue-descriptions/arOsSourceIgnored.md +18 -0
  86. package/build/src/third_party/issue-descriptions/arOsTriggerIgnored.md +19 -0
  87. package/build/src/third_party/issue-descriptions/arPermissionPolicyDisabled.md +8 -0
  88. package/build/src/third_party/issue-descriptions/arSourceAndTriggerHeaders.md +9 -0
  89. package/build/src/third_party/issue-descriptions/arSourceIgnored.md +13 -0
  90. package/build/src/third_party/issue-descriptions/arTriggerIgnored.md +12 -0
  91. package/build/src/third_party/issue-descriptions/arUntrustworthyReportingOrigin.md +10 -0
  92. package/build/src/third_party/issue-descriptions/arWebAndOsHeaders.md +11 -0
  93. package/build/src/third_party/issue-descriptions/bounceTrackingMitigations.md +3 -0
  94. package/build/src/third_party/issue-descriptions/clientHintMetaTagAllowListInvalidOrigin.md +4 -0
  95. package/build/src/third_party/issue-descriptions/clientHintMetaTagModifiedHTML.md +4 -0
  96. package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidAllowlistItemType.md +12 -0
  97. package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidHeader.md +12 -0
  98. package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidUrlPattern.md +8 -0
  99. package/build/src/third_party/issue-descriptions/connectionAllowlistItemNotInnerList.md +12 -0
  100. package/build/src/third_party/issue-descriptions/connectionAllowlistMoreThanOneList.md +7 -0
  101. package/build/src/third_party/issue-descriptions/connectionAllowlistReportingEndpointNotToken.md +10 -0
  102. package/build/src/third_party/issue-descriptions/cookieCrossSiteRedirectDowngrade.md +12 -0
  103. package/build/src/third_party/issue-descriptions/cookieExcludeBlockedWithinRelatedWebsiteSet.md +4 -0
  104. package/build/src/third_party/issue-descriptions/cookieExcludeDomainNonAscii.md +11 -0
  105. package/build/src/third_party/issue-descriptions/cookieExcludePortMismatch.md +8 -0
  106. package/build/src/third_party/issue-descriptions/cookieExcludeSchemeMismatch.md +7 -0
  107. package/build/src/third_party/issue-descriptions/cookieExcludeThirdPartyPhaseoutRead.md +6 -0
  108. package/build/src/third_party/issue-descriptions/cookieExcludeThirdPartyPhaseoutSet.md +6 -0
  109. package/build/src/third_party/issue-descriptions/cookieWarnDomainNonAscii.md +11 -0
  110. package/build/src/third_party/issue-descriptions/cookieWarnMetadataGrantRead.md +4 -0
  111. package/build/src/third_party/issue-descriptions/cookieWarnMetadataGrantSet.md +4 -0
  112. package/build/src/third_party/issue-descriptions/cookieWarnThirdPartyPhaseoutRead.md +6 -0
  113. package/build/src/third_party/issue-descriptions/cookieWarnThirdPartyPhaseoutSet.md +6 -0
  114. package/build/src/third_party/issue-descriptions/corsAllowCredentialsRequired.md +6 -0
  115. package/build/src/third_party/issue-descriptions/corsDisabledScheme.md +7 -0
  116. package/build/src/third_party/issue-descriptions/corsDisallowedByMode.md +7 -0
  117. package/build/src/third_party/issue-descriptions/corsHeaderDisallowedByPreflightResponse.md +5 -0
  118. package/build/src/third_party/issue-descriptions/corsInvalidHeaderValues.md +7 -0
  119. package/build/src/third_party/issue-descriptions/corsLocalNetworkAccessPermissionDenied.md +19 -0
  120. package/build/src/third_party/issue-descriptions/corsMethodDisallowedByPreflightResponse.md +5 -0
  121. package/build/src/third_party/issue-descriptions/corsNoCorsRedirectModeNotFollow.md +5 -0
  122. package/build/src/third_party/issue-descriptions/corsOriginMismatch.md +6 -0
  123. package/build/src/third_party/issue-descriptions/corsPreflightResponseInvalid.md +5 -0
  124. package/build/src/third_party/issue-descriptions/corsRedirectContainsCredentials.md +5 -0
  125. package/build/src/third_party/issue-descriptions/corsWildcardOriginNotAllowed.md +8 -0
  126. package/build/src/third_party/issue-descriptions/cspEvalViolation.md +9 -0
  127. package/build/src/third_party/issue-descriptions/cspInlineViolation.md +10 -0
  128. package/build/src/third_party/issue-descriptions/cspTrustedTypesPolicyViolation.md +5 -0
  129. package/build/src/third_party/issue-descriptions/cspTrustedTypesSinkViolation.md +8 -0
  130. package/build/src/third_party/issue-descriptions/cspURLViolation.md +10 -0
  131. package/build/src/third_party/issue-descriptions/deprecation.md +3 -0
  132. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsEmptyList.md +1 -0
  133. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsHttpNotFound.md +1 -0
  134. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsInvalidContentType.md +1 -0
  135. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsInvalidResponse.md +1 -0
  136. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsNoResponse.md +1 -0
  137. package/build/src/third_party/issue-descriptions/emailVerificationRequestDnsFetchFailed.md +1 -0
  138. package/build/src/third_party/issue-descriptions/emailVerificationRequestDnsInvalidRecord.md +1 -0
  139. package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownHttpNotFound.md +1 -0
  140. package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownInvalidContentType.md +1 -0
  141. package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownInvalidResponse.md +1 -0
  142. package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownNoResponse.md +1 -0
  143. package/build/src/third_party/issue-descriptions/emailVerificationRequestInvalidEmail.md +1 -0
  144. package/build/src/third_party/issue-descriptions/emailVerificationRequestJwksHttpNotFound.md +1 -0
  145. package/build/src/third_party/issue-descriptions/emailVerificationRequestJwksInvalidResponse.md +1 -0
  146. package/build/src/third_party/issue-descriptions/emailVerificationRequestKeyBindingSigningFailed.md +1 -0
  147. package/build/src/third_party/issue-descriptions/emailVerificationRequestRpOriginIsOpaque.md +1 -0
  148. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenHttpNotFound.md +1 -0
  149. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenInvalidContentType.md +1 -0
  150. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenInvalidResponse.md +1 -0
  151. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenInvalidSdJwt.md +1 -0
  152. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenMalformedSdJwt.md +1 -0
  153. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenNoResponse.md +1 -0
  154. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidAudience.md +1 -0
  155. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidIssuedAt.md +1 -0
  156. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidNonce.md +1 -0
  157. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidSdHash.md +1 -0
  158. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidTyp.md +1 -0
  159. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingAud.md +1 -0
  160. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingCnf.md +1 -0
  161. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingIat.md +1 -0
  162. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingNonce.md +1 -0
  163. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingSdHash.md +1 -0
  164. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbSignatureFailed.md +1 -0
  165. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidEmail.md +1 -0
  166. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidEmailVerified.md +1 -0
  167. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidHolderKey.md +1 -0
  168. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidIssuedAt.md +1 -0
  169. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidIssuer.md +1 -0
  170. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtJwksMissingKeys.md +1 -0
  171. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingCnf.md +1 -0
  172. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingEmail.md +1 -0
  173. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingIat.md +1 -0
  174. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingIss.md +1 -0
  175. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtSignatureFailed.md +1 -0
  176. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtUnsupportedHeaderAlg.md +1 -0
  177. package/build/src/third_party/issue-descriptions/emailVerificationRequestUserLoggedOut.md +1 -0
  178. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownAccountsEndpointCrossOrigin.md +1 -0
  179. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownHttpNotFound.md +1 -0
  180. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownInvalidContentType.md +1 -0
  181. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownInvalidResponse.md +1 -0
  182. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownIssuanceEndpointCrossOrigin.md +1 -0
  183. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownListEmpty.md +1 -0
  184. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownMissingAccountsEndpoint.md +1 -0
  185. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownMissingIssuanceEndpoint.md +1 -0
  186. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownNoResponse.md +1 -0
  187. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownUnsupportedSigningAlgorithm.md +1 -0
  188. package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsHttpNotFound.md +1 -0
  189. package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsInvalidResponse.md +1 -0
  190. package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsNoResponse.md +1 -0
  191. package/build/src/third_party/issue-descriptions/federatedAuthRequestApprovalDeclined.md +1 -0
  192. package/build/src/third_party/issue-descriptions/federatedAuthRequestCanceled.md +1 -0
  193. package/build/src/third_party/issue-descriptions/federatedAuthRequestErrorFetchingSignin.md +1 -0
  194. package/build/src/third_party/issue-descriptions/federatedAuthRequestErrorIdToken.md +1 -0
  195. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenHttpNotFound.md +1 -0
  196. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenInvalidRequest.md +1 -0
  197. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenInvalidResponse.md +1 -0
  198. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenNoResponse.md +1 -0
  199. package/build/src/third_party/issue-descriptions/federatedAuthRequestInvalidSigninResponse.md +1 -0
  200. package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestHttpNotFound.md +1 -0
  201. package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestInvalidResponse.md +1 -0
  202. package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestNoResponse.md +1 -0
  203. package/build/src/third_party/issue-descriptions/federatedAuthRequestTooManyRequests.md +1 -0
  204. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestInvalidAccountsResponse.md +1 -0
  205. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestInvalidConfigOrWellKnown.md +1 -0
  206. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoAccountSharingPermission.md +1 -0
  207. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoApiPermission.md +1 -0
  208. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoReturningUserFromFetchedAccounts.md +1 -0
  209. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotIframe.md +1 -0
  210. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotPotentiallyTrustworthy.md +1 -0
  211. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotSameOrigin.md +1 -0
  212. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotSignedInWithIdp.md +1 -0
  213. package/build/src/third_party/issue-descriptions/fetchingPartitionedBlobURL.md +7 -0
  214. package/build/src/third_party/issue-descriptions/genericBackUINavigationWouldSkipAd.md +4 -0
  215. package/build/src/third_party/issue-descriptions/genericFormAriaLabelledByToNonExistingIdError.md +8 -0
  216. package/build/src/third_party/issue-descriptions/genericFormAutocompleteAttributeEmptyError.md +5 -0
  217. package/build/src/third_party/issue-descriptions/genericFormDuplicateIdForInputError.md +5 -0
  218. package/build/src/third_party/issue-descriptions/genericFormEmptyIdAndNameAttributesForInputError.md +5 -0
  219. package/build/src/third_party/issue-descriptions/genericFormInputAssignedAutocompleteValueToIdOrNameAttributeError.md +5 -0
  220. package/build/src/third_party/issue-descriptions/genericFormInputHasWrongButWellIntendedAutocompleteValueError.md +5 -0
  221. package/build/src/third_party/issue-descriptions/genericFormInputWithNoLabelError.md +5 -0
  222. package/build/src/third_party/issue-descriptions/genericFormLabelForMatchesNonExistingIdError.md +5 -0
  223. package/build/src/third_party/issue-descriptions/genericFormLabelForNameError.md +5 -0
  224. package/build/src/third_party/issue-descriptions/genericFormLabelHasNeitherForNorNestedInputError.md +5 -0
  225. package/build/src/third_party/issue-descriptions/genericFormModelContextMissingToolDescription.md +5 -0
  226. package/build/src/third_party/issue-descriptions/genericFormModelContextMissingToolName.md +5 -0
  227. package/build/src/third_party/issue-descriptions/genericFormModelContextParameterMissingName.md +5 -0
  228. package/build/src/third_party/issue-descriptions/genericFormModelContextParameterMissingTitleAndDescription.md +5 -0
  229. package/build/src/third_party/issue-descriptions/genericFormModelContextRequiredParameterMissingName.md +5 -0
  230. package/build/src/third_party/issue-descriptions/genericNavigationEntryMarkedSkippable.md +7 -0
  231. package/build/src/third_party/issue-descriptions/genericResponseWasBlockedByORB.md +4 -0
  232. package/build/src/third_party/issue-descriptions/heavyAd.md +10 -0
  233. package/build/src/third_party/issue-descriptions/mixedContent.md +5 -0
  234. package/build/src/third_party/issue-descriptions/navigatingPartitionedBlobURL.md +5 -0
  235. package/build/src/third_party/issue-descriptions/permissionElementActivationDisabled.md +7 -0
  236. package/build/src/third_party/issue-descriptions/permissionElementActivationDisabledWithOccluder.md +9 -0
  237. package/build/src/third_party/issue-descriptions/permissionElementActivationDisabledWithOccluderParent.md +9 -0
  238. package/build/src/third_party/issue-descriptions/permissionElementCspFrameAncestorsMissing.md +5 -0
  239. package/build/src/third_party/issue-descriptions/permissionElementFencedFrameDisallowed.md +5 -0
  240. package/build/src/third_party/issue-descriptions/permissionElementFontSizeTooLarge.md +5 -0
  241. package/build/src/third_party/issue-descriptions/permissionElementFontSizeTooSmall.md +5 -0
  242. package/build/src/third_party/issue-descriptions/permissionElementGeolocationDeprecated.md +5 -0
  243. package/build/src/third_party/issue-descriptions/permissionElementInsetBoxShadowUnsupported.md +5 -0
  244. package/build/src/third_party/issue-descriptions/permissionElementInvalidDisplayStyle.md +5 -0
  245. package/build/src/third_party/issue-descriptions/permissionElementInvalidSizeValue.md +5 -0
  246. package/build/src/third_party/issue-descriptions/permissionElementInvalidType.md +5 -0
  247. package/build/src/third_party/issue-descriptions/permissionElementInvalidTypeActivation.md +5 -0
  248. package/build/src/third_party/issue-descriptions/permissionElementLowContrast.md +5 -0
  249. package/build/src/third_party/issue-descriptions/permissionElementNonOpaqueColor.md +5 -0
  250. package/build/src/third_party/issue-descriptions/permissionElementPaddingBottomUnsupported.md +6 -0
  251. package/build/src/third_party/issue-descriptions/permissionElementPaddingRightUnsupported.md +6 -0
  252. package/build/src/third_party/issue-descriptions/permissionElementPermissionsPolicyBlocked.md +5 -0
  253. package/build/src/third_party/issue-descriptions/permissionElementRegistrationFailed.md +5 -0
  254. package/build/src/third_party/issue-descriptions/permissionElementRequestInProgress.md +5 -0
  255. package/build/src/third_party/issue-descriptions/permissionElementSecurityChecksFailed.md +5 -0
  256. package/build/src/third_party/issue-descriptions/permissionElementTypeNotSupported.md +5 -0
  257. package/build/src/third_party/issue-descriptions/permissionElementUntrustedEvent.md +7 -0
  258. package/build/src/third_party/issue-descriptions/placeholderDescriptionForInvisibleIssues.md +3 -0
  259. package/build/src/third_party/issue-descriptions/propertyRuleInvalidNameIssue.md +3 -0
  260. package/build/src/third_party/issue-descriptions/propertyRuleIssue.md +7 -0
  261. package/build/src/third_party/issue-descriptions/selectElementAccessibilityDisallowedOptGroupChild.md +7 -0
  262. package/build/src/third_party/issue-descriptions/selectElementAccessibilityDisallowedSelectChild.md +7 -0
  263. package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentAttributesSelectDescendant.md +3 -0
  264. package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentLegendChild.md +3 -0
  265. package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentOptionChild.md +3 -0
  266. package/build/src/third_party/issue-descriptions/selectElementAccessibilityNonPhrasingContentOptionChild.md +3 -0
  267. package/build/src/third_party/issue-descriptions/selectivePermissionsIntervention.md +7 -0
  268. package/build/src/third_party/issue-descriptions/sharedArrayBuffer.md +7 -0
  269. package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorCrossOriginNoCorsRequest.md +1 -0
  270. package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorDictionaryLoadFailure.md +3 -0
  271. package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorMatchingDictionaryNotUsed.md +3 -0
  272. package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorUnexpectedContentDictionaryHeader.md +1 -0
  273. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorCossOriginNoCorsRequest.md +1 -0
  274. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorDisallowedBySettings.md +1 -0
  275. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorExpiredResponse.md +3 -0
  276. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorFeatureDisabled.md +3 -0
  277. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInsufficientResources.md +1 -0
  278. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInvalidMatchField.md +1 -0
  279. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInvalidStructuredHeader.md +1 -0
  280. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInvalidTTLField.md +1 -0
  281. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNavigationRequest.md +3 -0
  282. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNoMatchField.md +1 -0
  283. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonIntegerTTLField.md +1 -0
  284. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonListMatchDestField.md +1 -0
  285. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonSecureContext.md +3 -0
  286. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonStringIdField.md +1 -0
  287. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonStringInMatchDestList.md +1 -0
  288. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonStringMatchField.md +1 -0
  289. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonTokenTypeField.md +1 -0
  290. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorRequestAborted.md +1 -0
  291. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorShuttingDown.md +1 -0
  292. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorTooLongIdField.md +3 -0
  293. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorUnsupportedType.md +3 -0
  294. package/build/src/third_party/issue-descriptions/sriInvalidSignatureHeader.md +14 -0
  295. package/build/src/third_party/issue-descriptions/sriInvalidSignatureInputHeader.md +15 -0
  296. package/build/src/third_party/issue-descriptions/sriMissingSignatureHeader.md +8 -0
  297. package/build/src/third_party/issue-descriptions/sriMissingSignatureInputHeader.md +7 -0
  298. package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsIncorrectLength.md +11 -0
  299. package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsNotByteSequence.md +14 -0
  300. package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsParameterized.md +15 -0
  301. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidComponentName.md +8 -0
  302. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidComponentType.md +13 -0
  303. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidDerivedComponentParameter.md +4 -0
  304. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidHeaderComponentParameter.md +5 -0
  305. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidParameter.md +11 -0
  306. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderKeyIdLength.md +12 -0
  307. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderMissingLabel.md +6 -0
  308. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderMissingRequiredParameters.md +8 -0
  309. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderValueMissingComponents.md +11 -0
  310. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderValueNotInnerList.md +11 -0
  311. package/build/src/third_party/issue-descriptions/sriValidationFailedIntegrityMismatch.md +10 -0
  312. package/build/src/third_party/issue-descriptions/sriValidationFailedInvalidLength.md +5 -0
  313. package/build/src/third_party/issue-descriptions/sriValidationFailedSignatureExpired.md +6 -0
  314. package/build/src/third_party/issue-descriptions/sriValidationFailedSignatureMismatch.md +11 -0
  315. package/build/src/third_party/issue-descriptions/stylesheetLateImport.md +4 -0
  316. package/build/src/third_party/issue-descriptions/stylesheetRequestFailed.md +3 -0
  317. package/build/src/third_party/issue-descriptions/summaryElementAccessibilityInteractiveContentSummaryDescendant.md +3 -0
  318. package/build/src/third_party/issue-descriptions/unencodedDigestIncorrectDigestLength.md +12 -0
  319. package/build/src/third_party/issue-descriptions/unencodedDigestIncorrectDigestType.md +17 -0
  320. package/build/src/third_party/issue-descriptions/unencodedDigestMalformedDictionary.md +14 -0
  321. package/build/src/third_party/issue-descriptions/unencodedDigestUnknownAlgorithm.md +15 -0
  322. package/build/src/third_party/lighthouse-devtools-mcp-bundle.js +61598 -0
  323. package/build/src/tools/ToolDefinition.js +73 -0
  324. package/build/src/tools/categories.js +36 -0
  325. package/build/src/tools/console.js +98 -0
  326. package/build/src/tools/emulation.js +84 -0
  327. package/build/src/tools/extensions.js +101 -0
  328. package/build/src/tools/input.js +469 -0
  329. package/build/src/tools/lighthouse.js +136 -0
  330. package/build/src/tools/memory.js +227 -0
  331. package/build/src/tools/network.js +125 -0
  332. package/build/src/tools/pages.js +419 -0
  333. package/build/src/tools/performance.js +200 -0
  334. package/build/src/tools/screencast.js +117 -0
  335. package/build/src/tools/screenshot.js +169 -0
  336. package/build/src/tools/script.js +151 -0
  337. package/build/src/tools/slim/tools.js +88 -0
  338. package/build/src/tools/snapshot.js +61 -0
  339. package/build/src/tools/thirdPartyDeveloper.js +85 -0
  340. package/build/src/tools/tools.js +56 -0
  341. package/build/src/tools/webmcp.js +66 -0
  342. package/build/src/trace-processing/parse.js +85 -0
  343. package/build/src/types.js +7 -0
  344. package/build/src/utils/check-for-updates.js +74 -0
  345. package/build/src/utils/files.js +61 -0
  346. package/build/src/utils/id.js +16 -0
  347. package/build/src/utils/keyboard.js +297 -0
  348. package/build/src/utils/pagination.js +50 -0
  349. package/build/src/utils/string.js +37 -0
  350. package/build/src/utils/types.js +7 -0
  351. package/build/src/version.js +10 -0
  352. package/package.json +100 -0
  353. package/skills/a11y-debugging/SKILL.md +89 -0
  354. package/skills/a11y-debugging/references/a11y-snippets.md +92 -0
  355. package/skills/chrome-devtools/SKILL.md +72 -0
  356. package/skills/chrome-devtools-cli/SKILL.md +153 -0
  357. package/skills/chrome-devtools-cli/references/installation.md +14 -0
  358. package/skills/debug-optimize-lcp/SKILL.md +121 -0
  359. package/skills/debug-optimize-lcp/references/elements-and-size.md +27 -0
  360. package/skills/debug-optimize-lcp/references/lcp-breakdown.md +23 -0
  361. package/skills/debug-optimize-lcp/references/lcp-snippets.md +79 -0
  362. package/skills/debug-optimize-lcp/references/optimization-strategies.md +38 -0
  363. package/skills/memory-leak-debugging/SKILL.md +50 -0
  364. package/skills/memory-leak-debugging/references/common-leaks.md +33 -0
  365. package/skills/memory-leak-debugging/references/compare_snapshots.js +109 -0
  366. package/skills/memory-leak-debugging/references/memlab.md +29 -0
  367. package/skills/troubleshooting/SKILL.md +98 -0
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google Inc.
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ export class Mutex {
7
+ static Guard = class Guard {
8
+ #mutex;
9
+ constructor(mutex) {
10
+ this.#mutex = mutex;
11
+ }
12
+ dispose() {
13
+ return this.#mutex.release();
14
+ }
15
+ };
16
+ #locked = false;
17
+ #acquirers = [];
18
+ // This is FIFO.
19
+ async acquire() {
20
+ if (!this.#locked) {
21
+ this.#locked = true;
22
+ return new Mutex.Guard(this);
23
+ }
24
+ const { resolve, promise } = Promise.withResolvers();
25
+ this.#acquirers.push(resolve);
26
+ await promise;
27
+ return new Mutex.Guard(this);
28
+ }
29
+ release() {
30
+ const resolve = this.#acquirers.shift();
31
+ if (!resolve) {
32
+ this.#locked = false;
33
+ return;
34
+ }
35
+ resolve();
36
+ }
37
+ }
38
+ //# sourceMappingURL=Mutex.js.map
@@ -0,0 +1,297 @@
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 { logger } from './logger.js';
8
+ import { DevTools } from './third_party/index.js';
9
+ import { createIdGenerator, stableIdSymbol, } from './utils/id.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
+ #browser;
20
+ #listenersInitializer;
21
+ #listeners = new WeakMap();
22
+ maxNavigationSaved = 3;
23
+ /**
24
+ * This maps a Page to a list of navigations with a sub-list
25
+ * of all collected resources.
26
+ * The newer navigations come first.
27
+ */
28
+ storage = new WeakMap();
29
+ constructor(browser, listeners) {
30
+ this.#browser = browser;
31
+ this.#listenersInitializer = listeners;
32
+ }
33
+ async init(pages) {
34
+ for (const page of pages) {
35
+ this.addPage(page);
36
+ }
37
+ this.#browser.on('targetcreated', this.#onTargetCreated);
38
+ this.#browser.on('targetdestroyed', this.#onTargetDestroyed);
39
+ }
40
+ dispose() {
41
+ this.#browser.off('targetcreated', this.#onTargetCreated);
42
+ this.#browser.off('targetdestroyed', this.#onTargetDestroyed);
43
+ }
44
+ #onTargetCreated = async (target) => {
45
+ try {
46
+ const page = await target.page();
47
+ if (!page) {
48
+ return;
49
+ }
50
+ this.addPage(page);
51
+ }
52
+ catch (err) {
53
+ logger?.('Error getting a page for a target onTargetCreated', err);
54
+ }
55
+ };
56
+ #onTargetDestroyed = async (target) => {
57
+ try {
58
+ const page = await target.page();
59
+ if (!page) {
60
+ return;
61
+ }
62
+ this.cleanupPageDestroyed(page);
63
+ }
64
+ catch (err) {
65
+ logger?.('Error getting a page for a target onTargetDestroyed', err);
66
+ }
67
+ };
68
+ addPage(page) {
69
+ this.#initializePage(page);
70
+ }
71
+ #initializePage(page) {
72
+ if (this.storage.has(page)) {
73
+ return;
74
+ }
75
+ const idGenerator = createIdGenerator();
76
+ const storedLists = [[]];
77
+ this.storage.set(page, storedLists);
78
+ const listeners = this.#listenersInitializer(value => {
79
+ const withId = value;
80
+ withId[stableIdSymbol] = idGenerator();
81
+ const navigations = this.storage.get(page) ?? [[]];
82
+ navigations[0].push(withId);
83
+ });
84
+ listeners['framenavigated'] = (frame) => {
85
+ // Only split the storage on main frame navigation
86
+ if (frame !== page.mainFrame()) {
87
+ return;
88
+ }
89
+ this.splitAfterNavigation(page);
90
+ };
91
+ for (const [name, listener] of Object.entries(listeners)) {
92
+ page.on(name, listener);
93
+ }
94
+ this.#listeners.set(page, listeners);
95
+ }
96
+ splitAfterNavigation(page) {
97
+ const navigations = this.storage.get(page);
98
+ if (!navigations) {
99
+ return;
100
+ }
101
+ // Add the latest navigation first
102
+ navigations.unshift([]);
103
+ navigations.splice(this.maxNavigationSaved);
104
+ }
105
+ cleanupPageDestroyed(page) {
106
+ const listeners = this.#listeners.get(page);
107
+ if (listeners) {
108
+ for (const [name, listener] of Object.entries(listeners)) {
109
+ page.off(name, listener);
110
+ }
111
+ }
112
+ this.storage.delete(page);
113
+ }
114
+ getData(page, includePreservedData) {
115
+ const navigations = this.storage.get(page);
116
+ if (!navigations) {
117
+ return [];
118
+ }
119
+ if (!includePreservedData) {
120
+ return navigations[0];
121
+ }
122
+ const data = [];
123
+ for (let index = this.maxNavigationSaved; index >= 0; index--) {
124
+ if (navigations[index]) {
125
+ data.push(...navigations[index]);
126
+ }
127
+ }
128
+ return data;
129
+ }
130
+ getIdForResource(resource) {
131
+ return resource[stableIdSymbol] ?? -1;
132
+ }
133
+ getById(page, stableId) {
134
+ const navigations = this.storage.get(page);
135
+ if (!navigations) {
136
+ throw new Error('No requests found for selected page');
137
+ }
138
+ const item = this.find(page, item => item[stableIdSymbol] === stableId);
139
+ if (!item) {
140
+ throw new Error('Request not found for selected page');
141
+ }
142
+ return item;
143
+ }
144
+ find(page, filter) {
145
+ const navigations = this.storage.get(page);
146
+ if (!navigations) {
147
+ return;
148
+ }
149
+ for (const navigation of navigations) {
150
+ const item = navigation.find(filter);
151
+ if (item) {
152
+ return item;
153
+ }
154
+ }
155
+ return;
156
+ }
157
+ }
158
+ export class ConsoleCollector extends PageCollector {
159
+ #subscribedPages = new WeakMap();
160
+ addPage(page) {
161
+ super.addPage(page);
162
+ if (!this.#subscribedPages.has(page)) {
163
+ const subscriber = new PageEventSubscriber(page);
164
+ this.#subscribedPages.set(page, subscriber);
165
+ void subscriber.subscribe();
166
+ }
167
+ }
168
+ cleanupPageDestroyed(page) {
169
+ super.cleanupPageDestroyed(page);
170
+ this.#subscribedPages.get(page)?.unsubscribe();
171
+ this.#subscribedPages.delete(page);
172
+ }
173
+ }
174
+ class PageEventSubscriber {
175
+ #issueManager = new FakeIssuesManager();
176
+ #issueAggregator = new DevTools.IssueAggregator(this.#issueManager);
177
+ #seenKeys = new Set();
178
+ #seenIssues = new Set();
179
+ #page;
180
+ #session;
181
+ #targetId;
182
+ constructor(page) {
183
+ this.#page = page;
184
+ // @ts-expect-error use existing CDP client (internal Puppeteer API).
185
+ this.#session = this.#page._client();
186
+ // @ts-expect-error use internal Puppeteer API to get target ID
187
+ this.#targetId = this.#session.target()._targetId;
188
+ }
189
+ #resetIssueAggregator() {
190
+ this.#issueManager = new FakeIssuesManager();
191
+ if (this.#issueAggregator) {
192
+ this.#issueAggregator.removeEventListener("AggregatedIssueUpdated" /* DevTools.IssueAggregatorEvents.AGGREGATED_ISSUE_UPDATED */, this.#onAggregatedIssue);
193
+ }
194
+ this.#issueAggregator = new DevTools.IssueAggregator(this.#issueManager);
195
+ this.#issueAggregator.addEventListener("AggregatedIssueUpdated" /* DevTools.IssueAggregatorEvents.AGGREGATED_ISSUE_UPDATED */, this.#onAggregatedIssue);
196
+ }
197
+ async subscribe() {
198
+ this.#resetIssueAggregator();
199
+ this.#page.on('framenavigated', this.#onFrameNavigated);
200
+ this.#page.on('issue', this.#onIssueAdded);
201
+ this.#session.on('Runtime.exceptionThrown', this.#onExceptionThrown);
202
+ }
203
+ unsubscribe() {
204
+ this.#seenKeys.clear();
205
+ this.#seenIssues.clear();
206
+ this.#page.off('framenavigated', this.#onFrameNavigated);
207
+ this.#page.off('issue', this.#onIssueAdded);
208
+ this.#session.off('Runtime.exceptionThrown', this.#onExceptionThrown);
209
+ if (this.#issueAggregator) {
210
+ this.#issueAggregator.removeEventListener("AggregatedIssueUpdated" /* DevTools.IssueAggregatorEvents.AGGREGATED_ISSUE_UPDATED */, this.#onAggregatedIssue);
211
+ }
212
+ }
213
+ #onAggregatedIssue = (event) => {
214
+ if (this.#seenIssues.has(event.data)) {
215
+ return;
216
+ }
217
+ this.#seenIssues.add(event.data);
218
+ this.#page.emit('devtoolsAggregatedIssue', event.data);
219
+ };
220
+ #onExceptionThrown = (event) => {
221
+ this.#page.emit('uncaughtError', new UncaughtError(event.exceptionDetails, this.#targetId));
222
+ };
223
+ // On navigation, we reset issue aggregation.
224
+ #onFrameNavigated = (frame) => {
225
+ // Only split the storage on main frame navigation
226
+ if (frame !== frame.page().mainFrame()) {
227
+ return;
228
+ }
229
+ this.#seenKeys.clear();
230
+ this.#seenIssues.clear();
231
+ this.#resetIssueAggregator();
232
+ };
233
+ #onIssueAdded = (inspectorIssue) => {
234
+ try {
235
+ // DevTools currently defines this protocol issue code but has no
236
+ // IssuesManager handler for it, so calling into the mapper only warns.
237
+ if (String(inspectorIssue.code) === 'PerformanceIssue') {
238
+ return;
239
+ }
240
+ const issue = DevTools.createIssuesFromProtocolIssue(null,
241
+ // @ts-expect-error Protocol types diverge.
242
+ inspectorIssue)[0];
243
+ if (!issue) {
244
+ logger?.('No issue mapping for for the issue: ', inspectorIssue.code);
245
+ return;
246
+ }
247
+ const primaryKey = issue.primaryKey();
248
+ if (this.#seenKeys.has(primaryKey)) {
249
+ return;
250
+ }
251
+ this.#seenKeys.add(primaryKey);
252
+ this.#issueManager.dispatchEventToListeners("IssueAdded" /* DevTools.IssuesManagerEvents.ISSUE_ADDED */, {
253
+ issue,
254
+ // @ts-expect-error We don't care that issues model is null
255
+ issuesModel: null,
256
+ });
257
+ }
258
+ catch (error) {
259
+ logger?.('Error creating a new issue', error);
260
+ }
261
+ };
262
+ }
263
+ export class NetworkCollector extends PageCollector {
264
+ constructor(browser, listeners = collect => {
265
+ return {
266
+ request: req => {
267
+ collect(req);
268
+ },
269
+ };
270
+ }) {
271
+ super(browser, listeners);
272
+ }
273
+ splitAfterNavigation(page) {
274
+ const navigations = this.storage.get(page) ?? [];
275
+ if (!navigations) {
276
+ return;
277
+ }
278
+ const requests = navigations[0];
279
+ const lastRequestIdx = requests.findLastIndex(request => {
280
+ return request.frame() === page.mainFrame()
281
+ ? request.isNavigationRequest()
282
+ : false;
283
+ });
284
+ // Keep all requests since the last navigation request including that
285
+ // navigation request itself.
286
+ // Keep the reference
287
+ if (lastRequestIdx !== -1) {
288
+ const fromCurrentNavigation = requests.splice(lastRequestIdx);
289
+ navigations.unshift(fromCurrentNavigation);
290
+ }
291
+ else {
292
+ navigations.unshift([]);
293
+ }
294
+ navigations.splice(this.maxNavigationSaved);
295
+ }
296
+ }
297
+ //# sourceMappingURL=PageCollector.js.map
@@ -0,0 +1,171 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { UncaughtError } from './PageCollector.js';
7
+ import { createIdGenerator, stableIdSymbol } from './utils/id.js';
8
+ const CHROME_EXTENSION_PREFIX = 'chrome-extension://';
9
+ export class ServiceWorkerSubscriber {
10
+ #target;
11
+ #callback;
12
+ #session;
13
+ #worker;
14
+ constructor(target, callback) {
15
+ this.#target = target;
16
+ this.#callback = callback;
17
+ }
18
+ async subscribe() {
19
+ this.#session = await this.#target.createCDPSession();
20
+ await this.#session.send('Runtime.enable');
21
+ this.#session.on('Runtime.exceptionThrown', this.#onExceptionThrown);
22
+ this.#worker = (await this.#target.worker()) ?? undefined;
23
+ if (this.#worker) {
24
+ this.#worker.on('console', this.#onConsole);
25
+ }
26
+ }
27
+ async unsubscribe() {
28
+ if (this.#worker) {
29
+ this.#worker.off('console', this.#onConsole);
30
+ }
31
+ await this.#session?.detach();
32
+ }
33
+ #onConsole = (message) => {
34
+ this.#callback(message);
35
+ };
36
+ #onExceptionThrown = (event) => {
37
+ const url = this.#target.url();
38
+ const extensionId = extractExtensionId(url);
39
+ if (extensionId) {
40
+ this.#callback(new UncaughtError(event.exceptionDetails, extensionId));
41
+ }
42
+ };
43
+ }
44
+ export class ServiceWorkerConsoleCollector {
45
+ #storage = new Map();
46
+ #maxLogs;
47
+ #browser;
48
+ #serviceWorkerSubscribers = new Map();
49
+ #idGenerator = createIdGenerator();
50
+ constructor(browser, maxLogs = 1000) {
51
+ this.#browser = browser;
52
+ this.#maxLogs = maxLogs;
53
+ }
54
+ async init(workers) {
55
+ if (!this.#browser) {
56
+ return;
57
+ }
58
+ this.#browser.on('targetcreated', this.#onTargetCreated);
59
+ this.#browser.on('targetdestroyed', this.#onTargetDestroyed);
60
+ for (const worker of workers) {
61
+ void this.#onTargetCreated(worker.target);
62
+ }
63
+ }
64
+ dispose() {
65
+ if (!this.#browser) {
66
+ return;
67
+ }
68
+ this.#browser.off('targetcreated', this.#onTargetCreated);
69
+ this.#browser.off('targetdestroyed', this.#onTargetDestroyed);
70
+ for (const subscriber of this.#serviceWorkerSubscribers.values()) {
71
+ subscriber.unsubscribe().catch(err => {
72
+ if (err instanceof Error &&
73
+ !err.message.includes('Target closed') &&
74
+ !err.message.includes('Session closed')) {
75
+ // Swallow error as we are tearing down the system
76
+ }
77
+ });
78
+ }
79
+ this.#serviceWorkerSubscribers.clear();
80
+ }
81
+ #onTargetCreated = async (target) => {
82
+ if (this.#serviceWorkerSubscribers.has(target)) {
83
+ return;
84
+ }
85
+ const origin = target.url();
86
+ if (target.type() === 'service_worker' && isExtensionOrigin(origin)) {
87
+ const extensionId = extractExtensionId(origin);
88
+ if (!extensionId) {
89
+ return;
90
+ }
91
+ const subscriber = new ServiceWorkerSubscriber(target, item => {
92
+ this.addLog(extensionId, item);
93
+ });
94
+ try {
95
+ await subscriber.subscribe();
96
+ }
97
+ catch (err) {
98
+ if (err instanceof Error &&
99
+ !err.message.includes('Target closed') &&
100
+ !err.message.includes('Session closed')) {
101
+ throw err;
102
+ }
103
+ }
104
+ this.#serviceWorkerSubscribers.set(target, subscriber);
105
+ }
106
+ };
107
+ #onTargetDestroyed = async (target) => {
108
+ const subscriber = this.#serviceWorkerSubscribers.get(target);
109
+ if (subscriber) {
110
+ try {
111
+ await subscriber.unsubscribe();
112
+ }
113
+ catch (err) {
114
+ if (err instanceof Error &&
115
+ !err.message.includes('Target closed') &&
116
+ !err.message.includes('Session closed')) {
117
+ throw err;
118
+ }
119
+ }
120
+ this.#serviceWorkerSubscribers.delete(target);
121
+ }
122
+ };
123
+ addLog(extensionId, log) {
124
+ const logs = this.#storage.get(extensionId) ?? [];
125
+ const withId = log;
126
+ withId[stableIdSymbol] = this.#idGenerator();
127
+ logs.push(withId);
128
+ if (logs.length > this.#maxLogs) {
129
+ logs.shift();
130
+ }
131
+ this.#storage.set(extensionId, logs);
132
+ }
133
+ getData(extensionId) {
134
+ return this.#storage.get(extensionId) ?? [];
135
+ }
136
+ getById(extensionId, stableId) {
137
+ const logs = this.#storage.get(extensionId);
138
+ if (!logs) {
139
+ throw new Error('No logs found for selected extension');
140
+ }
141
+ const item = logs.find(item => item[stableIdSymbol] === stableId);
142
+ if (item) {
143
+ return item;
144
+ }
145
+ throw new Error('Log not found for selected extension');
146
+ }
147
+ find(extensionId, filter) {
148
+ const logs = this.#storage.get(extensionId);
149
+ if (!logs) {
150
+ return;
151
+ }
152
+ return logs.find(filter);
153
+ }
154
+ clearLogs(extensionId) {
155
+ this.#storage.delete(extensionId);
156
+ }
157
+ }
158
+ function extractExtensionId(origin) {
159
+ if (!origin || !isExtensionOrigin(origin)) {
160
+ return null;
161
+ }
162
+ const pathPart = origin.substring(CHROME_EXTENSION_PREFIX.length);
163
+ const slashIndex = pathPart.indexOf('/');
164
+ // if there's no / it means that pathPart is now the extensionId, otherwise
165
+ // we take everything until the first /
166
+ return slashIndex === -1 ? pathPart : pathPart.substring(0, slashIndex);
167
+ }
168
+ function isExtensionOrigin(origin) {
169
+ return origin.startsWith(CHROME_EXTENSION_PREFIX);
170
+ }
171
+ //# sourceMappingURL=ServiceWorkerCollector.js.map
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { McpResponse } from './McpResponse.js';
7
+ export class SlimMcpResponse extends McpResponse {
8
+ async handle(_toolName, _context) {
9
+ const text = {
10
+ type: 'text',
11
+ text: this.responseLines.join('\n'),
12
+ };
13
+ return {
14
+ content: [text],
15
+ structuredContent: text,
16
+ };
17
+ }
18
+ }
19
+ //# sourceMappingURL=SlimMcpResponse.js.map