@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,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(_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
@@ -0,0 +1,315 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
7
+ if (value !== null && value !== void 0) {
8
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
9
+ var dispose, inner;
10
+ if (async) {
11
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
12
+ dispose = value[Symbol.asyncDispose];
13
+ }
14
+ if (dispose === void 0) {
15
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
16
+ dispose = value[Symbol.dispose];
17
+ if (async) inner = dispose;
18
+ }
19
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
20
+ if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
21
+ env.stack.push({ value: value, dispose: dispose, async: async });
22
+ }
23
+ else if (async) {
24
+ env.stack.push({ async: true });
25
+ }
26
+ return value;
27
+ };
28
+ var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
29
+ return function (env) {
30
+ function fail(e) {
31
+ env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
32
+ env.hasError = true;
33
+ }
34
+ var r, s = 0;
35
+ function next() {
36
+ while (r = env.stack.pop()) {
37
+ try {
38
+ if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
39
+ if (r.dispose) {
40
+ var result = r.dispose.call(r.value);
41
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
42
+ }
43
+ else s |= 1;
44
+ }
45
+ catch (e) {
46
+ fail(e);
47
+ }
48
+ }
49
+ if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
50
+ if (env.hasError) throw env.error;
51
+ }
52
+ return next();
53
+ };
54
+ })(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
55
+ var e = new Error(message);
56
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
57
+ });
58
+ import { logger } from './utils/logger.js';
59
+ export class TextSnapshot {
60
+ static nextSnapshotId = 1;
61
+ static resetCounter() {
62
+ TextSnapshot.nextSnapshotId = 1;
63
+ }
64
+ root;
65
+ idToNode;
66
+ snapshotId;
67
+ selectedElementUid;
68
+ hasSelectedElement;
69
+ verbose;
70
+ constructor(data) {
71
+ this.root = data.root;
72
+ this.idToNode = data.idToNode;
73
+ this.snapshotId = data.snapshotId;
74
+ this.selectedElementUid = data.selectedElementUid;
75
+ this.hasSelectedElement = data.hasSelectedElement;
76
+ this.verbose = data.verbose;
77
+ }
78
+ static async create(page, options = {}) {
79
+ const verbose = options.verbose ?? false;
80
+ const rootNode = await page.pptrPage.accessibility.snapshot({
81
+ includeIframes: true,
82
+ interestingOnly: !verbose,
83
+ });
84
+ if (!rootNode) {
85
+ throw new Error('Failed to create accessibility snapshot');
86
+ }
87
+ const { uniqueBackendNodeIdToMcpId } = page;
88
+ const snapshotId = TextSnapshot.nextSnapshotId++;
89
+ // Iterate through the whole accessibility node tree and assign node ids that
90
+ // will be used for the tree serialization and mapping ids back to nodes.
91
+ let idCounter = 0;
92
+ const idToNode = new Map();
93
+ const seenUniqueIds = new Set();
94
+ const seenBackendNodeIds = new Set();
95
+ const assignIds = (node) => {
96
+ let id = '';
97
+ // @ts-expect-error untyped backendNodeId.
98
+ const backendNodeId = node.backendNodeId;
99
+ // @ts-expect-error untyped loaderId.
100
+ const uniqueBackendId = `${node.loaderId}_${backendNodeId}`;
101
+ const existingMcpId = uniqueBackendNodeIdToMcpId.get(uniqueBackendId);
102
+ if (existingMcpId !== undefined) {
103
+ // Re-use MCP exposed ID if the uniqueId is the same.
104
+ id = existingMcpId;
105
+ }
106
+ else {
107
+ // Only generate a new ID if we have not seen the node before.
108
+ id = `${snapshotId}_${idCounter++}`;
109
+ uniqueBackendNodeIdToMcpId.set(uniqueBackendId, id);
110
+ }
111
+ seenUniqueIds.add(uniqueBackendId);
112
+ seenBackendNodeIds.add(backendNodeId);
113
+ const nodeWithId = {
114
+ ...node,
115
+ id,
116
+ children: node.children
117
+ ? node.children.map(child => assignIds(child))
118
+ : [],
119
+ };
120
+ // The AXNode for an option doesn't contain its `value`.
121
+ // Therefore, set text content of the option as value.
122
+ if (node.role === 'option') {
123
+ const optionText = node.name;
124
+ if (optionText) {
125
+ nodeWithId.value = optionText.toString();
126
+ }
127
+ }
128
+ idToNode.set(nodeWithId.id, nodeWithId);
129
+ return nodeWithId;
130
+ };
131
+ const rootNodeWithId = assignIds(rootNode);
132
+ await TextSnapshot.insertExtraNodes(page, idToNode, seenUniqueIds, snapshotId, idCounter, rootNodeWithId, seenBackendNodeIds, options.extraHandles ?? []);
133
+ const snapshot = new TextSnapshot({
134
+ root: rootNodeWithId,
135
+ snapshotId: String(snapshotId),
136
+ idToNode,
137
+ hasSelectedElement: false,
138
+ verbose,
139
+ });
140
+ const data = options.devtoolsData ?? (await page.getDevToolsData());
141
+ if (data?.cdpBackendNodeId) {
142
+ snapshot.hasSelectedElement = true;
143
+ snapshot.selectedElementUid = snapshot.resolveCdpElementId(data.cdpBackendNodeId);
144
+ }
145
+ // Clean up unique IDs that we did not see anymore.
146
+ for (const key of uniqueBackendNodeIdToMcpId.keys()) {
147
+ if (!seenUniqueIds.has(key)) {
148
+ uniqueBackendNodeIdToMcpId.delete(key);
149
+ }
150
+ }
151
+ return snapshot;
152
+ }
153
+ resolveCdpElementId(cdpBackendNodeId) {
154
+ if (!cdpBackendNodeId) {
155
+ logger?.('no cdpBackendNodeId');
156
+ return;
157
+ }
158
+ // TODO: index by backendNodeId instead.
159
+ const queue = [this.root];
160
+ while (queue.length) {
161
+ const current = queue.pop();
162
+ if (current.backendNodeId === cdpBackendNodeId) {
163
+ return current.id;
164
+ }
165
+ for (const child of current.children) {
166
+ queue.push(child);
167
+ }
168
+ }
169
+ return;
170
+ }
171
+ // ExtraHandles represent DOM nodes which might not be part of the accessibility tree, e.g. DOM nodes
172
+ // returned by third-party developer tools. We insert them into the tree by finding the closest ancestor
173
+ // in the tree and inserting the node as a child. The ancestor's child nodes are re-parented if necessary.
174
+ static async insertExtraNodes(page, idToNode, seenUniqueIds, snapshotId, idCounter, rootNodeWithId, seenBackendNodeIds, extraHandles) {
175
+ const { uniqueBackendNodeIdToMcpId } = page;
176
+ const createExtraNode = async (handle) => {
177
+ const backendNodeId = await handle.backendNodeId();
178
+ if (!backendNodeId || seenBackendNodeIds.has(backendNodeId)) {
179
+ return null;
180
+ }
181
+ const uniqueBackendId = `custom_${backendNodeId}`;
182
+ if (seenUniqueIds.has(uniqueBackendId)) {
183
+ return null;
184
+ }
185
+ seenBackendNodeIds.add(backendNodeId);
186
+ let id = '';
187
+ const mcpId = uniqueBackendNodeIdToMcpId.get(uniqueBackendId);
188
+ if (mcpId !== undefined) {
189
+ id = mcpId;
190
+ }
191
+ else {
192
+ id = `${snapshotId}_${idCounter++}`;
193
+ uniqueBackendNodeIdToMcpId.set(uniqueBackendId, id);
194
+ }
195
+ seenUniqueIds.add(uniqueBackendId);
196
+ const tagHandle = await handle.getProperty('localName');
197
+ const tagValue = await tagHandle.jsonValue();
198
+ const extraNode = {
199
+ role: tagValue,
200
+ id,
201
+ backendNodeId,
202
+ children: [],
203
+ elementHandle: async () => handle,
204
+ };
205
+ return extraNode;
206
+ };
207
+ const findAncestorNode = async (handle) => {
208
+ const env_1 = { stack: [], error: void 0, hasError: false };
209
+ try {
210
+ let ancestorHandle = await handle.evaluateHandle(el => el.parentElement);
211
+ const stack = __addDisposableResource(env_1, new DisposableStack(), false);
212
+ while (ancestorHandle) {
213
+ stack.use(ancestorHandle);
214
+ const ancestorElement = ancestorHandle.asElement();
215
+ if (!ancestorElement) {
216
+ return null;
217
+ }
218
+ const ancestorBackendId = await ancestorElement.backendNodeId();
219
+ if (ancestorBackendId) {
220
+ const ancestorNode = idToNode
221
+ .values()
222
+ .find(node => node.backendNodeId === ancestorBackendId);
223
+ if (ancestorNode) {
224
+ return ancestorNode;
225
+ }
226
+ }
227
+ const nextHandle = await ancestorElement.evaluateHandle(el => el.parentElement);
228
+ ancestorHandle = nextHandle;
229
+ }
230
+ return null;
231
+ }
232
+ catch (e_1) {
233
+ env_1.error = e_1;
234
+ env_1.hasError = true;
235
+ }
236
+ finally {
237
+ __disposeResources(env_1);
238
+ }
239
+ };
240
+ const findDescendantNodes = async (backendNodeId) => {
241
+ const descendantIds = new Set();
242
+ if (!backendNodeId) {
243
+ return descendantIds;
244
+ }
245
+ try {
246
+ // @ts-expect-error internal API
247
+ const client = page.pptrPage._client();
248
+ if (client) {
249
+ const { node } = await client.send('DOM.describeNode', {
250
+ backendNodeId,
251
+ depth: -1,
252
+ pierce: true,
253
+ });
254
+ const collect = (node) => {
255
+ if (node.backendNodeId && node.backendNodeId !== backendNodeId) {
256
+ descendantIds.add(node.backendNodeId);
257
+ }
258
+ if (node.children) {
259
+ for (const child of node.children) {
260
+ collect(child);
261
+ }
262
+ }
263
+ };
264
+ collect(node);
265
+ }
266
+ }
267
+ catch (e) {
268
+ logger?.(`Failed to collect descendants for backend node ${backendNodeId}`, e);
269
+ }
270
+ return descendantIds;
271
+ };
272
+ const moveChildNodes = (attachTarget, extraNode, descendantIds) => {
273
+ let firstMovedIndex = -1;
274
+ if (descendantIds.size > 0 && attachTarget.children) {
275
+ const remainingChildren = [];
276
+ for (const child of attachTarget.children) {
277
+ if (child.backendNodeId && descendantIds.has(child.backendNodeId)) {
278
+ if (firstMovedIndex === -1) {
279
+ firstMovedIndex = remainingChildren.length;
280
+ }
281
+ extraNode.children.push(child);
282
+ }
283
+ else {
284
+ remainingChildren.push(child);
285
+ }
286
+ }
287
+ attachTarget.children = remainingChildren;
288
+ }
289
+ return firstMovedIndex !== -1
290
+ ? firstMovedIndex
291
+ : attachTarget.children
292
+ ? attachTarget.children.length
293
+ : 0;
294
+ };
295
+ if (extraHandles.length) {
296
+ page.extraHandles = extraHandles;
297
+ }
298
+ const reorgInfo = [];
299
+ for (const handle of page.extraHandles) {
300
+ const extraNode = await createExtraNode(handle);
301
+ if (!extraNode) {
302
+ continue;
303
+ }
304
+ idToNode.set(extraNode.id, extraNode);
305
+ const attachTarget = (await findAncestorNode(handle)) || rootNodeWithId;
306
+ const descendantIds = await findDescendantNodes(extraNode.backendNodeId);
307
+ reorgInfo.push({ extraNode, attachTarget, descendantIds });
308
+ }
309
+ for (const { extraNode, attachTarget, descendantIds } of reorgInfo) {
310
+ const index = moveChildNodes(attachTarget, extraNode, descendantIds);
311
+ attachTarget.children.splice(index, 0, extraNode);
312
+ }
313
+ }
314
+ }
315
+ //# sourceMappingURL=TextSnapshot.js.map
@@ -0,0 +1,322 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
7
+ if (value !== null && value !== void 0) {
8
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
9
+ var dispose, inner;
10
+ if (async) {
11
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
12
+ dispose = value[Symbol.asyncDispose];
13
+ }
14
+ if (dispose === void 0) {
15
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
16
+ dispose = value[Symbol.dispose];
17
+ if (async) inner = dispose;
18
+ }
19
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
20
+ if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
21
+ env.stack.push({ value: value, dispose: dispose, async: async });
22
+ }
23
+ else if (async) {
24
+ env.stack.push({ async: true });
25
+ }
26
+ return value;
27
+ };
28
+ var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
29
+ return function (env) {
30
+ function fail(e) {
31
+ env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
32
+ env.hasError = true;
33
+ }
34
+ var r, s = 0;
35
+ function next() {
36
+ while (r = env.stack.pop()) {
37
+ try {
38
+ if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
39
+ if (r.dispose) {
40
+ var result = r.dispose.call(r.value);
41
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
42
+ }
43
+ else s |= 1;
44
+ }
45
+ catch (e) {
46
+ fail(e);
47
+ }
48
+ }
49
+ if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
50
+ if (env.hasError) throw env.error;
51
+ }
52
+ return next();
53
+ };
54
+ })(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
55
+ var e = new Error(message);
56
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
57
+ });
58
+ import { McpResponse } from './McpResponse.js';
59
+ import { SlimMcpResponse } from './SlimMcpResponse.js';
60
+ import { ClearcutLogger } from './telemetry/ClearcutLogger.js';
61
+ import { zod } from './third_party/index.js';
62
+ import { labels } from './tools/categories.js';
63
+ import { categoryToFlagName } from './config/category-options.js';
64
+ import { logger } from './utils/logger.js';
65
+ import { fileURLToPath, pathToFileURL } from 'node:url';
66
+ import { isLocalhost } from './utils/url.js';
67
+ function buildDisabledMessage(toolName, flag, categoryLabel) {
68
+ const reason = categoryLabel
69
+ ? `is in category ${categoryLabel} which`
70
+ : `requires ${flag.startsWith('--experimental') ? 'experimental feature' : 'flag'} ${flag} and`;
71
+ return `Tool ${toolName} ${reason} is currently disabled. Enable it by running chrome-devtools start ${flag}=true. For more information check the README.`;
72
+ }
73
+ function getToolStatusInfo(tool, serverArgs) {
74
+ const category = tool.annotations.category;
75
+ if (category) {
76
+ const flag = categoryToFlagName(category);
77
+ if (!serverArgs[flag]) {
78
+ return {
79
+ disabled: true,
80
+ reason: buildDisabledMessage(tool.name, `--${flag}`, labels[category]),
81
+ };
82
+ }
83
+ }
84
+ for (const condition of tool.annotations.conditions || []) {
85
+ if (!serverArgs[condition]) {
86
+ return {
87
+ disabled: true,
88
+ reason: buildDisabledMessage(tool.name, `--${condition}`),
89
+ };
90
+ }
91
+ }
92
+ return { disabled: false };
93
+ }
94
+ function isPageScopedTool(tool) {
95
+ return 'pageScoped' in tool && tool.pageScoped === true;
96
+ }
97
+ function formatArgumentNames(names) {
98
+ return names.map(name => `"${name}"`).join(', ');
99
+ }
100
+ function buildUnknownArgumentsMessage(toolName, unknownArgumentNames, expectedArgumentNames) {
101
+ const unknownLabel = unknownArgumentNames.length === 1 ? 'argument' : 'arguments';
102
+ const expectedArguments = expectedArgumentNames.length
103
+ ? `Expected arguments: ${formatArgumentNames(expectedArgumentNames)}.`
104
+ : 'This tool does not accept any arguments.';
105
+ const correction = unknownArgumentNames.length === 1 ? 'Remove it' : 'Remove them';
106
+ return `Unknown ${unknownLabel} for tool "${toolName}": ${formatArgumentNames(unknownArgumentNames)}. ${expectedArguments} ${correction} and retry.`;
107
+ }
108
+ async function validateAndResolvePathOrUrl(filePathOrUrl, context) {
109
+ try {
110
+ const url = new URL(filePathOrUrl);
111
+ if (url.protocol === 'file:') {
112
+ return pathToFileURL(await context.validatePath(fileURLToPath(url))).href;
113
+ }
114
+ else if (['http:', 'https:', 'ws:', 'wss:'].includes(url.protocol)) {
115
+ return filePathOrUrl;
116
+ }
117
+ }
118
+ catch {
119
+ // Suppress parsing errors for regular file paths.
120
+ }
121
+ return await context.validatePath(filePathOrUrl);
122
+ }
123
+ function isLocalBrowser(context) {
124
+ if (context.browser.process()) {
125
+ return true;
126
+ }
127
+ const wsEndpoint = context.browser.wsEndpoint();
128
+ if (wsEndpoint && isLocalhost(wsEndpoint)) {
129
+ return true;
130
+ }
131
+ return false;
132
+ }
133
+ function shouldValidateFile(option, isLocal) {
134
+ if (option === true) {
135
+ return true;
136
+ }
137
+ if (typeof option === 'object' && option !== null) {
138
+ if (isLocal) {
139
+ return Boolean(option.local);
140
+ }
141
+ return Boolean(option.remote);
142
+ }
143
+ return false;
144
+ }
145
+ async function validateToolFiles(tool, params, context) {
146
+ const isLocal = isLocalBrowser(context);
147
+ for (const [key, option] of Object.entries(tool.verifyFilesSchema)) {
148
+ if (shouldValidateFile(option, isLocal)) {
149
+ const val = params[key];
150
+ if (typeof val === 'string') {
151
+ params[key] = await validateAndResolvePathOrUrl(val, context);
152
+ }
153
+ else if (Array.isArray(val)) {
154
+ const updated = [];
155
+ for (const item of val) {
156
+ if (typeof item === 'string') {
157
+ updated.push(await validateAndResolvePathOrUrl(item, context));
158
+ }
159
+ else {
160
+ throw new Error('Unexpected non-string value as a file path or URL');
161
+ }
162
+ }
163
+ params[key] = updated;
164
+ }
165
+ }
166
+ }
167
+ }
168
+ export class ToolHandler {
169
+ tool;
170
+ serverArgs;
171
+ getContext;
172
+ toolMutex;
173
+ inputSchema;
174
+ registeredInputSchema;
175
+ disabled;
176
+ disabledReason;
177
+ constructor(tool, serverArgs, getContext, toolMutex) {
178
+ this.tool = tool;
179
+ this.serverArgs = serverArgs;
180
+ this.getContext = getContext;
181
+ this.toolMutex = toolMutex;
182
+ const { disabled, reason } = getToolStatusInfo(tool, serverArgs);
183
+ this.disabledReason = reason;
184
+ this.disabled = disabled && !serverArgs.viaCli;
185
+ this.inputSchema = tool.schema;
186
+ this.registeredInputSchema = zod.object(this.inputSchema).loose();
187
+ }
188
+ unknownArgumentNames(params) {
189
+ return Object.keys(params).filter(key => !Object.hasOwn(this.inputSchema, key));
190
+ }
191
+ handle = async (params) => {
192
+ const env_1 = { stack: [], error: void 0, hasError: false };
193
+ try {
194
+ const _guard = __addDisposableResource(env_1, await this.toolMutex.acquire(), false);
195
+ if (this.disabledReason) {
196
+ return {
197
+ content: [
198
+ {
199
+ type: 'text',
200
+ text: this.disabledReason,
201
+ },
202
+ ],
203
+ isError: true,
204
+ };
205
+ }
206
+ const unknownArgumentNames = this.unknownArgumentNames(params);
207
+ if (unknownArgumentNames.length) {
208
+ return {
209
+ content: [
210
+ {
211
+ type: 'text',
212
+ text: buildUnknownArgumentsMessage(this.tool.name, unknownArgumentNames, Object.keys(this.inputSchema)),
213
+ },
214
+ ],
215
+ isError: true,
216
+ };
217
+ }
218
+ const startTime = Date.now();
219
+ let success = false;
220
+ let devToolsData;
221
+ let pageUrl;
222
+ try {
223
+ logger?.(`${this.tool.name} request: ${JSON.stringify(params, null, ' ')}`);
224
+ const context = await this.getContext();
225
+ logger?.(`${this.tool.name} context: resolved`);
226
+ const response = this.serverArgs.slim
227
+ ? new SlimMcpResponse(this.serverArgs)
228
+ : new McpResponse(this.serverArgs);
229
+ response.setRedactNetworkHeaders(this.serverArgs.redactNetworkHeaders);
230
+ if (context.consumeReconnectNotice()) {
231
+ response.setReconnectNotice();
232
+ }
233
+ let page;
234
+ try {
235
+ await validateToolFiles(this.tool, params, context);
236
+ if (isPageScopedTool(this.tool)) {
237
+ const pageId = typeof params.pageId === 'number' ? params.pageId : undefined;
238
+ page =
239
+ this.serverArgs.pageIdRouting &&
240
+ pageId !== undefined &&
241
+ !this.serverArgs.slim
242
+ ? context.getPageById(pageId)
243
+ : context.getSelectedMcpPage();
244
+ response.setPage(page);
245
+ if (this.tool.blockedByDialog) {
246
+ page.throwIfDialogOpen();
247
+ }
248
+ await this.tool.handler({
249
+ params,
250
+ page,
251
+ }, response, context);
252
+ }
253
+ else {
254
+ await this.tool.handler({
255
+ params,
256
+ }, response, context);
257
+ }
258
+ }
259
+ catch (err) {
260
+ response.setError(err);
261
+ }
262
+ devToolsData = await context.getDevToolsData(page);
263
+ pageUrl = context.getSelectedMcpPageUrl(page);
264
+ // Resolve data format: --experimentalDataFormat takes precedence, fall back to legacy --experimentalToonFormat
265
+ let dataFormat = 'default';
266
+ if (this.serverArgs.experimentalDataFormat) {
267
+ dataFormat = this.serverArgs.experimentalDataFormat;
268
+ }
269
+ else if (this.serverArgs.experimentalToonFormat) {
270
+ dataFormat = 'toon';
271
+ }
272
+ const { content, structuredContent } = await response.handle(context, dataFormat);
273
+ const result = {
274
+ content,
275
+ };
276
+ if (response.error) {
277
+ result.isError = true;
278
+ }
279
+ success = true;
280
+ if (this.serverArgs.experimentalStructuredContent) {
281
+ result.structuredContent = structuredContent;
282
+ }
283
+ return result;
284
+ }
285
+ catch (err) {
286
+ logger?.(`${this.tool.name} error:`, err, err?.stack);
287
+ let errorText = err && 'message' in err ? err.message : String(err);
288
+ if ('cause' in err && err.cause) {
289
+ errorText += `\nCause: ${err.cause.message}`;
290
+ }
291
+ return {
292
+ content: [
293
+ {
294
+ type: 'text',
295
+ text: errorText,
296
+ },
297
+ ],
298
+ isError: true,
299
+ };
300
+ }
301
+ finally {
302
+ void ClearcutLogger.get()?.logToolInvocation({
303
+ toolName: this.tool.name,
304
+ params,
305
+ schema: this.inputSchema,
306
+ success,
307
+ latencyMs: Date.now() - startTime,
308
+ devToolsData,
309
+ pageUrl,
310
+ });
311
+ }
312
+ }
313
+ catch (e_1) {
314
+ env_1.error = e_1;
315
+ env_1.hasError = true;
316
+ }
317
+ finally {
318
+ __disposeResources(env_1);
319
+ }
320
+ };
321
+ }
322
+ //# sourceMappingURL=ToolHandler.js.map