@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,652 @@
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 { TimeoutError, zod } from '../third_party/index.js';
59
+ import { parseKey } from '../utils/keyboard.js';
60
+ import { logger } from '../utils/logger.js';
61
+ import { ToolCategory } from './categories.js';
62
+ import { definePageTool } from './ToolDefinition.js';
63
+ const dblClickSchema = zod
64
+ .boolean()
65
+ .optional()
66
+ .describe('Set to true for double clicks. Default is false.');
67
+ const includeSnapshotSchema = zod
68
+ .boolean()
69
+ .optional()
70
+ .describe('Whether to include a snapshot in the response. Default is false.');
71
+ const submitKeySchema = zod
72
+ .string()
73
+ .optional()
74
+ .describe('Optional key to press after typing. E.g., "Enter", "Tab", "Escape"');
75
+ /**
76
+ * Locator actions abort or time out while the page is blocked by a JavaScript
77
+ * dialog, even though the action itself was dispatched and opened that dialog.
78
+ * The open dialog is already reported in the response, so treat this as an
79
+ * interruption instead of a failure.
80
+ */
81
+ function handleActionError(error, uid, page) {
82
+ if (page.getDialog()) {
83
+ logger?.('action interrupted by a dialog', error);
84
+ return;
85
+ }
86
+ logger?.('failed to act using a locator', error);
87
+ const reason = error instanceof TimeoutError
88
+ ? 'The element did not become interactive within the configured timeout.'
89
+ : error instanceof Error
90
+ ? error.message
91
+ : String(error);
92
+ throw new Error(`Failed to interact with the element with uid ${uid}. ${reason}`, {
93
+ cause: error,
94
+ });
95
+ }
96
+ async function selectNativeSelectOption(handle, signal) {
97
+ const env_1 = { stack: [], error: void 0, hasError: false };
98
+ try {
99
+ const selectHandle = __addDisposableResource(env_1, await handle.evaluateHandle(node => {
100
+ if (!(node instanceof HTMLOptionElement)) {
101
+ return null;
102
+ }
103
+ const select = node.closest('select');
104
+ if (!select || select.multiple || select.disabled || node.disabled) {
105
+ return null;
106
+ }
107
+ const parentElement = node.parentElement;
108
+ if (parentElement instanceof HTMLOptGroupElement &&
109
+ parentElement.disabled) {
110
+ return null;
111
+ }
112
+ return select;
113
+ }), false);
114
+ const select = __addDisposableResource(env_1, selectHandle.asElement(), false);
115
+ if (!select) {
116
+ return false;
117
+ }
118
+ const valueHandle = __addDisposableResource(env_1, await handle.getProperty('value'), false);
119
+ const value = await valueHandle.jsonValue();
120
+ if (typeof value !== 'string') {
121
+ return false;
122
+ }
123
+ await select.asLocator().fill(value, { signal });
124
+ return true;
125
+ }
126
+ catch (e_1) {
127
+ env_1.error = e_1;
128
+ env_1.hasError = true;
129
+ }
130
+ finally {
131
+ __disposeResources(env_1);
132
+ }
133
+ }
134
+ export const click = definePageTool(() => ({
135
+ name: 'click',
136
+ description: `Clicks on the provided element`,
137
+ annotations: {
138
+ category: ToolCategory.INPUT,
139
+ readOnlyHint: false,
140
+ },
141
+ schema: {
142
+ uid: zod
143
+ .string()
144
+ .describe('The uid of an element on the page from the page content snapshot'),
145
+ dblClick: dblClickSchema,
146
+ includeSnapshot: includeSnapshotSchema,
147
+ },
148
+ blockedByDialog: true,
149
+ verifyFilesSchema: {},
150
+ handler: async (request, response) => {
151
+ const env_2 = { stack: [], error: void 0, hasError: false };
152
+ try {
153
+ const uid = request.params.uid;
154
+ const handle = __addDisposableResource(env_2, await request.page.getElementByUid(uid), false);
155
+ const aXNode = request.page.getAXNodeByUid(uid);
156
+ const shouldSelectNativeOption = !request.params.dblClick && aXNode?.role === 'option';
157
+ try {
158
+ const result = await request.page.waitForEventsAfterAction(async (signal) => {
159
+ if (shouldSelectNativeOption &&
160
+ (await selectNativeSelectOption(handle, signal))) {
161
+ return;
162
+ }
163
+ await handle.asLocator().click({
164
+ count: request.params.dblClick ? 2 : 1,
165
+ signal,
166
+ });
167
+ });
168
+ response.appendResponseLine(request.params.dblClick
169
+ ? `Successfully double clicked on the element`
170
+ : `Successfully clicked on the element`);
171
+ response.attachWaitForResult(result);
172
+ if (request.params.includeSnapshot) {
173
+ response.includeSnapshot();
174
+ }
175
+ }
176
+ catch (error) {
177
+ handleActionError(error, uid, request.page);
178
+ response.appendResponseLine(request.params.dblClick
179
+ ? `The element was double clicked and it opened a dialog.`
180
+ : `The element was clicked and it opened a dialog.`);
181
+ }
182
+ }
183
+ catch (e_2) {
184
+ env_2.error = e_2;
185
+ env_2.hasError = true;
186
+ }
187
+ finally {
188
+ __disposeResources(env_2);
189
+ }
190
+ },
191
+ }));
192
+ export const clickAt = definePageTool(() => ({
193
+ name: 'click_at',
194
+ description: `Clicks at the provided coordinates`,
195
+ annotations: {
196
+ category: ToolCategory.INPUT,
197
+ readOnlyHint: false,
198
+ conditions: ['experimentalVision'],
199
+ },
200
+ schema: {
201
+ x: zod.number().describe('The x coordinate'),
202
+ y: zod.number().describe('The y coordinate'),
203
+ dblClick: dblClickSchema,
204
+ includeSnapshot: includeSnapshotSchema,
205
+ },
206
+ blockedByDialog: true,
207
+ verifyFilesSchema: {},
208
+ handler: async (request, response) => {
209
+ const page = request.page;
210
+ const result = await page.waitForEventsAfterAction(async () => {
211
+ await page.pptrPage.mouse.click(request.params.x, request.params.y, {
212
+ count: request.params.dblClick ? 2 : 1,
213
+ });
214
+ });
215
+ response.appendResponseLine(request.params.dblClick
216
+ ? `Successfully double clicked at the coordinates`
217
+ : `Successfully clicked at the coordinates`);
218
+ response.attachWaitForResult(result);
219
+ if (request.params.includeSnapshot) {
220
+ response.includeSnapshot();
221
+ }
222
+ },
223
+ }));
224
+ export const hover = definePageTool(() => ({
225
+ name: 'hover',
226
+ description: `Hover over the provided element`,
227
+ annotations: {
228
+ category: ToolCategory.INPUT,
229
+ readOnlyHint: false,
230
+ },
231
+ schema: {
232
+ uid: zod
233
+ .string()
234
+ .describe('The uid of an element on the page from the page content snapshot'),
235
+ includeSnapshot: includeSnapshotSchema,
236
+ },
237
+ blockedByDialog: true,
238
+ verifyFilesSchema: {},
239
+ handler: async (request, response) => {
240
+ const env_3 = { stack: [], error: void 0, hasError: false };
241
+ try {
242
+ const uid = request.params.uid;
243
+ const handle = __addDisposableResource(env_3, await request.page.getElementByUid(uid), false);
244
+ try {
245
+ const result = await request.page.waitForEventsAfterAction(async (signal) => {
246
+ await handle.asLocator().hover({ signal });
247
+ });
248
+ response.appendResponseLine(`Successfully hovered over the element`);
249
+ response.attachWaitForResult(result);
250
+ if (request.params.includeSnapshot) {
251
+ response.includeSnapshot();
252
+ }
253
+ }
254
+ catch (error) {
255
+ handleActionError(error, uid, request.page);
256
+ response.appendResponseLine(`The element was hovered and it opened a dialog.`);
257
+ }
258
+ }
259
+ catch (e_3) {
260
+ env_3.error = e_3;
261
+ env_3.hasError = true;
262
+ }
263
+ finally {
264
+ __disposeResources(env_3);
265
+ }
266
+ },
267
+ }));
268
+ function raceWithSignal(promise, signal) {
269
+ if (signal.aborted) {
270
+ return Promise.reject(signal.reason);
271
+ }
272
+ return new Promise((resolve, reject) => {
273
+ const onAbort = () => {
274
+ reject(signal.reason);
275
+ };
276
+ signal.addEventListener('abort', onAbort, { once: true });
277
+ Promise.resolve(promise).then(value => {
278
+ signal.removeEventListener('abort', onAbort);
279
+ resolve(value);
280
+ }, error => {
281
+ signal.removeEventListener('abort', onAbort);
282
+ reject(error);
283
+ });
284
+ });
285
+ }
286
+ // The AXNode for an option doesn't contain its `value`. We set text content of the option as value.
287
+ // If the form is a combobox, we need to find the correct option by its text value.
288
+ // To do that, loop through the children while checking which child's text matches the requested value (requested value is actually the text content).
289
+ // When the correct option is found, use the element handle to get the real value.
290
+ async function selectOption(handle, aXNode, value, signal) {
291
+ let optionFound = false;
292
+ for (const child of aXNode.children) {
293
+ if (child.role === 'option' && child.name === value && child.value) {
294
+ const env_4 = { stack: [], error: void 0, hasError: false };
295
+ try {
296
+ optionFound = true;
297
+ const childHandle = __addDisposableResource(env_4, await raceWithSignal(child.elementHandle(), signal), false);
298
+ if (childHandle) {
299
+ const env_5 = { stack: [], error: void 0, hasError: false };
300
+ try {
301
+ const childValueHandle = __addDisposableResource(env_5, await raceWithSignal(childHandle.getProperty('value'), signal), false);
302
+ const childValue = await raceWithSignal(childValueHandle.jsonValue(), signal);
303
+ if (typeof childValue === 'string') {
304
+ await handle.asLocator().fill(childValue, { signal });
305
+ }
306
+ break;
307
+ }
308
+ catch (e_4) {
309
+ env_5.error = e_4;
310
+ env_5.hasError = true;
311
+ }
312
+ finally {
313
+ __disposeResources(env_5);
314
+ }
315
+ }
316
+ }
317
+ catch (e_5) {
318
+ env_4.error = e_5;
319
+ env_4.hasError = true;
320
+ }
321
+ finally {
322
+ __disposeResources(env_4);
323
+ }
324
+ }
325
+ }
326
+ if (!optionFound) {
327
+ throw new Error(`Could not find option with text "${value}"`);
328
+ }
329
+ }
330
+ function hasOptionChildren(aXNode) {
331
+ return aXNode.children.some(child => child.role === 'option');
332
+ }
333
+ /**
334
+ * Fills one or more form elements and waits for resulting page events in a
335
+ * single `waitForEventsAfterAction` call.
336
+ * If an element opens a JavaScript dialog, returns the `interruptedUid` of that
337
+ * element so the caller can report it without filling remaining elements.
338
+ */
339
+ async function fillFormElements(elements, page) {
340
+ let currentUid;
341
+ try {
342
+ const result = await page.waitForEventsAfterAction(async (signal) => {
343
+ for (const { uid, value } of elements) {
344
+ const env_6 = { stack: [], error: void 0, hasError: false };
345
+ try {
346
+ const previousUid = currentUid;
347
+ currentUid = undefined;
348
+ const handle = __addDisposableResource(env_6, await raceWithSignal(page.getElementByUid(uid), signal).catch(error => {
349
+ if (signal.aborted && previousUid) {
350
+ currentUid = previousUid;
351
+ }
352
+ throw error;
353
+ }), false);
354
+ currentUid = uid;
355
+ const aXNode = page.getAXNodeByUid(uid);
356
+ // We assume that combobox needs to be handled as select if it has
357
+ // role='combobox' and option children.
358
+ if (aXNode && aXNode.role === 'combobox' && hasOptionChildren(aXNode)) {
359
+ await raceWithSignal(selectOption(handle, aXNode, value, signal), signal);
360
+ }
361
+ else {
362
+ const isToggle = await raceWithSignal(handle.evaluate(el => {
363
+ if (el instanceof HTMLInputElement) {
364
+ return el.type === 'checkbox' || el.type === 'radio';
365
+ }
366
+ const role = el.getAttribute('role');
367
+ return (role === 'checkbox' || role === 'radio' || role === 'switch');
368
+ }), signal);
369
+ if (isToggle) {
370
+ if (['true', 'false'].includes(value)) {
371
+ await handle.asLocator().fill(value === 'true', { signal });
372
+ }
373
+ else {
374
+ throw new Error(`Checkboxes, radio boxes and toggles require "true" or "false" value, but ${value} was used`);
375
+ }
376
+ }
377
+ else {
378
+ // Increase timeout for longer input values.
379
+ const timeoutPerChar = 10; // ms
380
+ const fillTimeout = page.pptrPage.getDefaultTimeout() + value.length * timeoutPerChar;
381
+ await handle
382
+ .asLocator()
383
+ .setTimeout(fillTimeout)
384
+ .fill(value, { signal });
385
+ }
386
+ }
387
+ signal.throwIfAborted();
388
+ }
389
+ catch (e_6) {
390
+ env_6.error = e_6;
391
+ env_6.hasError = true;
392
+ }
393
+ finally {
394
+ __disposeResources(env_6);
395
+ }
396
+ }
397
+ });
398
+ return { result };
399
+ }
400
+ catch (error) {
401
+ if (!currentUid) {
402
+ throw error;
403
+ }
404
+ handleActionError(error, currentUid, page);
405
+ return { interruptedUid: currentUid };
406
+ }
407
+ }
408
+ export const fill = definePageTool(() => ({
409
+ name: 'fill',
410
+ description: `Type text into an input, text area or select an option from a <select> element.`,
411
+ annotations: {
412
+ category: ToolCategory.INPUT,
413
+ readOnlyHint: false,
414
+ },
415
+ schema: {
416
+ uid: zod
417
+ .string()
418
+ .describe('The uid of an element on the page from the page content snapshot'),
419
+ value: zod
420
+ .string()
421
+ .describe('The value to fill in. "true" or "false" for checkboxes and toggles, "true" for radio buttons.'),
422
+ includeSnapshot: includeSnapshotSchema,
423
+ },
424
+ blockedByDialog: true,
425
+ verifyFilesSchema: {},
426
+ handler: async (request, response) => {
427
+ const { result } = await fillFormElements([{ uid: request.params.uid, value: request.params.value }], request.page);
428
+ if (!result) {
429
+ response.appendResponseLine(`The element was filled out and it opened a dialog.`);
430
+ return;
431
+ }
432
+ response.appendResponseLine(`Successfully filled out the element`);
433
+ response.attachWaitForResult(result);
434
+ if (request.params.includeSnapshot) {
435
+ response.includeSnapshot();
436
+ }
437
+ },
438
+ }));
439
+ export const typeText = definePageTool(() => ({
440
+ name: 'type_text',
441
+ description: `Type text using keyboard into a previously focused input`,
442
+ annotations: {
443
+ category: ToolCategory.INPUT,
444
+ readOnlyHint: false,
445
+ },
446
+ schema: {
447
+ text: zod.string().describe('The text to type'),
448
+ submitKey: submitKeySchema,
449
+ },
450
+ blockedByDialog: true,
451
+ verifyFilesSchema: {},
452
+ handler: async (request, response) => {
453
+ const page = request.page;
454
+ const result = await page.waitForEventsAfterAction(async () => {
455
+ await page.pptrPage.keyboard.type(request.params.text);
456
+ if (request.params.submitKey) {
457
+ await page.pptrPage.keyboard.press(request.params.submitKey);
458
+ }
459
+ });
460
+ response.appendResponseLine(`Typed text "${request.params.text}${request.params.submitKey ? ` + ${request.params.submitKey}` : ''}"`);
461
+ response.attachWaitForResult(result);
462
+ },
463
+ }));
464
+ export const drag = definePageTool(() => ({
465
+ name: 'drag',
466
+ description: `Drag an element onto another element`,
467
+ annotations: {
468
+ category: ToolCategory.INPUT,
469
+ readOnlyHint: false,
470
+ },
471
+ schema: {
472
+ from_uid: zod.string().describe('The uid of the element to drag'),
473
+ to_uid: zod.string().describe('The uid of the element to drop into'),
474
+ includeSnapshot: includeSnapshotSchema,
475
+ },
476
+ blockedByDialog: true,
477
+ verifyFilesSchema: {},
478
+ handler: async (request, response) => {
479
+ const env_7 = { stack: [], error: void 0, hasError: false };
480
+ try {
481
+ const fromHandle = __addDisposableResource(env_7, await request.page.getElementByUid(request.params.from_uid), false);
482
+ const toHandle = __addDisposableResource(env_7, await request.page.getElementByUid(request.params.to_uid), false);
483
+ const result = await request.page.waitForEventsAfterAction(async () => {
484
+ await fromHandle.drag(toHandle);
485
+ await new Promise(resolve => setTimeout(resolve, 50));
486
+ await toHandle.drop(fromHandle);
487
+ });
488
+ response.appendResponseLine(`Successfully dragged an element`);
489
+ response.attachWaitForResult(result);
490
+ if (request.params.includeSnapshot) {
491
+ response.includeSnapshot();
492
+ }
493
+ }
494
+ catch (e_7) {
495
+ env_7.error = e_7;
496
+ env_7.hasError = true;
497
+ }
498
+ finally {
499
+ __disposeResources(env_7);
500
+ }
501
+ },
502
+ }));
503
+ export const fillForm = definePageTool(() => ({
504
+ name: 'fill_form',
505
+ description: `Fill out multiple form elements (inputs, selects, checkboxes, radios) at once. ALWAYS prefer this tool over multiple individual 'fill' or 'click' calls when interacting with forms. It is significantly faster, more reliable, and reduces turn count. Example: Fill username, password, and check "Remember Me" in one call.`,
506
+ annotations: {
507
+ category: ToolCategory.INPUT,
508
+ readOnlyHint: false,
509
+ },
510
+ schema: {
511
+ elements: zod
512
+ .array(
513
+ /* eslint-disable @local/enforce-zod-schema */
514
+ zod
515
+ .object({
516
+ uid: zod.string().describe('The uid of the element to fill out'),
517
+ value: zod
518
+ .string()
519
+ .describe('Value for the element. "true" or "false" for checkboxes and toggles, "true" for radio buttons.'),
520
+ })
521
+ .describe('An element to fill out'))
522
+ .describe('Elements from snapshot to fill out.'),
523
+ includeSnapshot: includeSnapshotSchema,
524
+ },
525
+ blockedByDialog: true,
526
+ verifyFilesSchema: {},
527
+ handler: async (request, response) => {
528
+ const { result, interruptedUid } = await fillFormElements(request.params.elements, request.page);
529
+ if (!result) {
530
+ // The page is blocked by a dialog, so the remaining elements cannot be
531
+ // filled out until it is handled.
532
+ const hasRemainingElements = interruptedUid !== request.params.elements.at(-1)?.uid;
533
+ response.appendResponseLine(`Filling out the element with uid ${interruptedUid} opened a dialog.${hasRemainingElements
534
+ ? ' The remaining elements were not filled out.'
535
+ : ''}`);
536
+ return;
537
+ }
538
+ response.appendResponseLine(`Successfully filled out the form`);
539
+ response.attachWaitForResult(result);
540
+ if (request.params.includeSnapshot) {
541
+ response.includeSnapshot();
542
+ }
543
+ },
544
+ }));
545
+ export const uploadFile = definePageTool(() => ({
546
+ name: 'upload_file',
547
+ description: 'Upload a file through a provided element.',
548
+ annotations: {
549
+ category: ToolCategory.INPUT,
550
+ readOnlyHint: false,
551
+ },
552
+ schema: {
553
+ uid: zod
554
+ .string()
555
+ .describe('The uid of the file input element or an element that will open file chooser on the page from the page content snapshot'),
556
+ filePaths: zod
557
+ .array(zod.string())
558
+ .min(1)
559
+ .describe('One or more files paths to upload. File paths have to be local to the browser instance (not the MCP).'),
560
+ includeSnapshot: includeSnapshotSchema,
561
+ },
562
+ blockedByDialog: true,
563
+ // We do not validate file paths for remote browser instances
564
+ // because they are on the remote host and not accessed by the MCP server.
565
+ verifyFilesSchema: {
566
+ filePaths: {
567
+ local: true,
568
+ remote: false,
569
+ },
570
+ },
571
+ handler: async (request, response) => {
572
+ const env_8 = { stack: [], error: void 0, hasError: false };
573
+ try {
574
+ const { uid, filePaths } = request.params;
575
+ const handle = __addDisposableResource(env_8, (await request.page.getElementByUid(uid)), false);
576
+ try {
577
+ await handle.uploadFile(...filePaths);
578
+ }
579
+ catch {
580
+ // Some sites use a proxy element to trigger file upload instead of
581
+ // a type=file element. In this case, we want to default to
582
+ // Page.waitForFileChooser() and upload the file this way.
583
+ try {
584
+ const [fileChooser] = await Promise.all([
585
+ request.page.pptrPage.waitForFileChooser({ timeout: 3000 }),
586
+ handle.asLocator().click(),
587
+ ]);
588
+ await fileChooser.accept(filePaths);
589
+ }
590
+ catch {
591
+ throw new Error(`Failed to upload file. The element could not accept the file directly, and clicking it did not trigger a file chooser.`);
592
+ }
593
+ }
594
+ if (request.params.includeSnapshot) {
595
+ response.includeSnapshot();
596
+ }
597
+ response.appendResponseLine(`File uploaded from ${filePaths.join(', ')}.`);
598
+ }
599
+ catch (e_8) {
600
+ env_8.error = e_8;
601
+ env_8.hasError = true;
602
+ }
603
+ finally {
604
+ __disposeResources(env_8);
605
+ }
606
+ },
607
+ }));
608
+ export const pressKey = definePageTool(() => ({
609
+ name: 'press_key',
610
+ description: `Press a key or key combination. Use this when other input methods like fill() cannot be used (e.g., keyboard shortcuts, navigation keys, or special key combinations).`,
611
+ annotations: {
612
+ category: ToolCategory.INPUT,
613
+ readOnlyHint: false,
614
+ },
615
+ schema: {
616
+ key: zod
617
+ .string()
618
+ .describe('A key or a combination (e.g., "Enter", "Control+A", "Control++", "Control+Shift+R"). Modifiers: Control, Shift, Alt, Meta'),
619
+ includeSnapshot: includeSnapshotSchema,
620
+ },
621
+ blockedByDialog: true,
622
+ verifyFilesSchema: {},
623
+ handler: async (request, response) => {
624
+ const page = request.page;
625
+ const tokens = parseKey(request.params.key);
626
+ const [key, ...modifiers] = tokens;
627
+ const result = await page.waitForEventsAfterAction(async () => {
628
+ const heldModifiers = [];
629
+ try {
630
+ for (const modifier of modifiers) {
631
+ await page.pptrPage.keyboard.down(modifier);
632
+ heldModifiers.push(modifier);
633
+ }
634
+ await page.pptrPage.keyboard.press(key);
635
+ }
636
+ finally {
637
+ // Release every modifier that was successfully pressed, even if a
638
+ // later key event throws. Otherwise a failed press leaves modifiers
639
+ // logically held down in the browser (see #2309).
640
+ for (const modifier of heldModifiers.toReversed()) {
641
+ await page.pptrPage.keyboard.up(modifier);
642
+ }
643
+ }
644
+ });
645
+ response.appendResponseLine(`Successfully pressed key: ${request.params.key}`);
646
+ response.attachWaitForResult(result);
647
+ if (request.params.includeSnapshot) {
648
+ response.includeSnapshot();
649
+ }
650
+ },
651
+ }));
652
+ //# sourceMappingURL=input.js.map