@gabrielbryk/arc-devtools-mcp 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (367) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +977 -0
  3. package/build/src/HeapSnapshotManager.js +148 -0
  4. package/build/src/McpContext.js +737 -0
  5. package/build/src/McpPage.js +315 -0
  6. package/build/src/McpResponse.js +990 -0
  7. package/build/src/Mutex.js +38 -0
  8. package/build/src/PageCollector.js +297 -0
  9. package/build/src/ServiceWorkerCollector.js +171 -0
  10. package/build/src/SlimMcpResponse.js +19 -0
  11. package/build/src/TextSnapshot.js +236 -0
  12. package/build/src/ToolHandler.js +223 -0
  13. package/build/src/WaitForHelper.js +190 -0
  14. package/build/src/bin/check-latest-version.js +50 -0
  15. package/build/src/bin/chrome-devtools-cli-options.js +978 -0
  16. package/build/src/bin/chrome-devtools-mcp-cli-options.js +412 -0
  17. package/build/src/bin/chrome-devtools-mcp-main.js +72 -0
  18. package/build/src/bin/chrome-devtools-mcp.js +23 -0
  19. package/build/src/bin/chrome-devtools.js +189 -0
  20. package/build/src/browser.js +253 -0
  21. package/build/src/daemon/client.js +160 -0
  22. package/build/src/daemon/daemon.js +261 -0
  23. package/build/src/daemon/types.js +7 -0
  24. package/build/src/daemon/utils.js +115 -0
  25. package/build/src/devtools/DevToolsConnectionAdapter.js +70 -0
  26. package/build/src/devtools/DevtoolsUtils.js +369 -0
  27. package/build/src/devtools/McpHostBindingAdapter.js +165 -0
  28. package/build/src/formatters/ConsoleFormatter.js +288 -0
  29. package/build/src/formatters/HeapSnapshotFormatter.js +97 -0
  30. package/build/src/formatters/IssueFormatter.js +193 -0
  31. package/build/src/formatters/NetworkFormatter.js +238 -0
  32. package/build/src/formatters/SnapshotFormatter.js +135 -0
  33. package/build/src/index.js +153 -0
  34. package/build/src/issue-descriptions.js +40 -0
  35. package/build/src/logger.js +37 -0
  36. package/build/src/polyfill.js +8 -0
  37. package/build/src/telemetry/ClearcutLogger.js +169 -0
  38. package/build/src/telemetry/WatchdogClient.js +61 -0
  39. package/build/src/telemetry/errors.js +18 -0
  40. package/build/src/telemetry/flagUtils.js +89 -0
  41. package/build/src/telemetry/metricsRegistry.js +89 -0
  42. package/build/src/telemetry/persistence.js +72 -0
  43. package/build/src/telemetry/transformation.js +134 -0
  44. package/build/src/telemetry/types.js +31 -0
  45. package/build/src/telemetry/watchdog/ClearcutSender.js +205 -0
  46. package/build/src/telemetry/watchdog/main.js +128 -0
  47. package/build/src/third_party/THIRD_PARTY_NOTICES +3637 -0
  48. package/build/src/third_party/bundled-packages.json +12 -0
  49. package/build/src/third_party/devtools-formatter-worker.js +15301 -0
  50. package/build/src/third_party/devtools-heap-snapshot-worker.js +9870 -0
  51. package/build/src/third_party/index.js +159597 -0
  52. package/build/src/third_party/issue-descriptions/CoepCoopSandboxedIframeCannotNavigateToCoopPage.md +4 -0
  53. package/build/src/third_party/issue-descriptions/CoepCorpNotSameOrigin.md +8 -0
  54. package/build/src/third_party/issue-descriptions/CoepCorpNotSameOriginAfterDefaultedToSameOriginByCoep.md +18 -0
  55. package/build/src/third_party/issue-descriptions/CoepCorpNotSameSite.md +7 -0
  56. package/build/src/third_party/issue-descriptions/CoepFrameResourceNeedsCoepHeader.md +10 -0
  57. package/build/src/third_party/issue-descriptions/CompatibilityModeQuirks.md +5 -0
  58. package/build/src/third_party/issue-descriptions/CookieAttributeValueExceedsMaxSize.md +5 -0
  59. package/build/src/third_party/issue-descriptions/LowTextContrast.md +5 -0
  60. package/build/src/third_party/issue-descriptions/SameSiteExcludeContextDowngradeRead.md +8 -0
  61. package/build/src/third_party/issue-descriptions/SameSiteExcludeContextDowngradeSet.md +8 -0
  62. package/build/src/third_party/issue-descriptions/SameSiteExcludeNavigationContextDowngrade.md +8 -0
  63. package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureErrorRead.md +8 -0
  64. package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureErrorSet.md +8 -0
  65. package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureWarnRead.md +8 -0
  66. package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureWarnSet.md +8 -0
  67. package/build/src/third_party/issue-descriptions/SameSiteUnspecifiedLaxAllowUnsafeRead.md +9 -0
  68. package/build/src/third_party/issue-descriptions/SameSiteUnspecifiedLaxAllowUnsafeSet.md +9 -0
  69. package/build/src/third_party/issue-descriptions/SameSiteWarnCrossDowngradeRead.md +8 -0
  70. package/build/src/third_party/issue-descriptions/SameSiteWarnCrossDowngradeSet.md +8 -0
  71. package/build/src/third_party/issue-descriptions/SameSiteWarnStrictLaxDowngradeStrict.md +8 -0
  72. package/build/src/third_party/issue-descriptions/arInsecureContext.md +7 -0
  73. package/build/src/third_party/issue-descriptions/arInvalidInfoHeader.md +5 -0
  74. package/build/src/third_party/issue-descriptions/arInvalidRegisterOsSourceHeader.md +5 -0
  75. package/build/src/third_party/issue-descriptions/arInvalidRegisterOsTriggerHeader.md +5 -0
  76. package/build/src/third_party/issue-descriptions/arInvalidRegisterSourceHeader.md +5 -0
  77. package/build/src/third_party/issue-descriptions/arInvalidRegisterTriggerHeader.md +5 -0
  78. package/build/src/third_party/issue-descriptions/arNavigationRegistrationUniqueScopeAlreadySet.md +5 -0
  79. package/build/src/third_party/issue-descriptions/arNavigationRegistrationWithoutTransientUserActivation.md +6 -0
  80. package/build/src/third_party/issue-descriptions/arNoRegisterOsSourceHeader.md +5 -0
  81. package/build/src/third_party/issue-descriptions/arNoRegisterOsTriggerHeader.md +5 -0
  82. package/build/src/third_party/issue-descriptions/arNoRegisterSourceHeader.md +5 -0
  83. package/build/src/third_party/issue-descriptions/arNoRegisterTriggerHeader.md +5 -0
  84. package/build/src/third_party/issue-descriptions/arNoWebOrOsSupport.md +4 -0
  85. package/build/src/third_party/issue-descriptions/arOsSourceIgnored.md +18 -0
  86. package/build/src/third_party/issue-descriptions/arOsTriggerIgnored.md +19 -0
  87. package/build/src/third_party/issue-descriptions/arPermissionPolicyDisabled.md +8 -0
  88. package/build/src/third_party/issue-descriptions/arSourceAndTriggerHeaders.md +9 -0
  89. package/build/src/third_party/issue-descriptions/arSourceIgnored.md +13 -0
  90. package/build/src/third_party/issue-descriptions/arTriggerIgnored.md +12 -0
  91. package/build/src/third_party/issue-descriptions/arUntrustworthyReportingOrigin.md +10 -0
  92. package/build/src/third_party/issue-descriptions/arWebAndOsHeaders.md +11 -0
  93. package/build/src/third_party/issue-descriptions/bounceTrackingMitigations.md +3 -0
  94. package/build/src/third_party/issue-descriptions/clientHintMetaTagAllowListInvalidOrigin.md +4 -0
  95. package/build/src/third_party/issue-descriptions/clientHintMetaTagModifiedHTML.md +4 -0
  96. package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidAllowlistItemType.md +12 -0
  97. package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidHeader.md +12 -0
  98. package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidUrlPattern.md +8 -0
  99. package/build/src/third_party/issue-descriptions/connectionAllowlistItemNotInnerList.md +12 -0
  100. package/build/src/third_party/issue-descriptions/connectionAllowlistMoreThanOneList.md +7 -0
  101. package/build/src/third_party/issue-descriptions/connectionAllowlistReportingEndpointNotToken.md +10 -0
  102. package/build/src/third_party/issue-descriptions/cookieCrossSiteRedirectDowngrade.md +12 -0
  103. package/build/src/third_party/issue-descriptions/cookieExcludeBlockedWithinRelatedWebsiteSet.md +4 -0
  104. package/build/src/third_party/issue-descriptions/cookieExcludeDomainNonAscii.md +11 -0
  105. package/build/src/third_party/issue-descriptions/cookieExcludePortMismatch.md +8 -0
  106. package/build/src/third_party/issue-descriptions/cookieExcludeSchemeMismatch.md +7 -0
  107. package/build/src/third_party/issue-descriptions/cookieExcludeThirdPartyPhaseoutRead.md +6 -0
  108. package/build/src/third_party/issue-descriptions/cookieExcludeThirdPartyPhaseoutSet.md +6 -0
  109. package/build/src/third_party/issue-descriptions/cookieWarnDomainNonAscii.md +11 -0
  110. package/build/src/third_party/issue-descriptions/cookieWarnMetadataGrantRead.md +4 -0
  111. package/build/src/third_party/issue-descriptions/cookieWarnMetadataGrantSet.md +4 -0
  112. package/build/src/third_party/issue-descriptions/cookieWarnThirdPartyPhaseoutRead.md +6 -0
  113. package/build/src/third_party/issue-descriptions/cookieWarnThirdPartyPhaseoutSet.md +6 -0
  114. package/build/src/third_party/issue-descriptions/corsAllowCredentialsRequired.md +6 -0
  115. package/build/src/third_party/issue-descriptions/corsDisabledScheme.md +7 -0
  116. package/build/src/third_party/issue-descriptions/corsDisallowedByMode.md +7 -0
  117. package/build/src/third_party/issue-descriptions/corsHeaderDisallowedByPreflightResponse.md +5 -0
  118. package/build/src/third_party/issue-descriptions/corsInvalidHeaderValues.md +7 -0
  119. package/build/src/third_party/issue-descriptions/corsLocalNetworkAccessPermissionDenied.md +19 -0
  120. package/build/src/third_party/issue-descriptions/corsMethodDisallowedByPreflightResponse.md +5 -0
  121. package/build/src/third_party/issue-descriptions/corsNoCorsRedirectModeNotFollow.md +5 -0
  122. package/build/src/third_party/issue-descriptions/corsOriginMismatch.md +6 -0
  123. package/build/src/third_party/issue-descriptions/corsPreflightResponseInvalid.md +5 -0
  124. package/build/src/third_party/issue-descriptions/corsRedirectContainsCredentials.md +5 -0
  125. package/build/src/third_party/issue-descriptions/corsWildcardOriginNotAllowed.md +8 -0
  126. package/build/src/third_party/issue-descriptions/cspEvalViolation.md +9 -0
  127. package/build/src/third_party/issue-descriptions/cspInlineViolation.md +10 -0
  128. package/build/src/third_party/issue-descriptions/cspTrustedTypesPolicyViolation.md +5 -0
  129. package/build/src/third_party/issue-descriptions/cspTrustedTypesSinkViolation.md +8 -0
  130. package/build/src/third_party/issue-descriptions/cspURLViolation.md +10 -0
  131. package/build/src/third_party/issue-descriptions/deprecation.md +3 -0
  132. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsEmptyList.md +1 -0
  133. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsHttpNotFound.md +1 -0
  134. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsInvalidContentType.md +1 -0
  135. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsInvalidResponse.md +1 -0
  136. package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsNoResponse.md +1 -0
  137. package/build/src/third_party/issue-descriptions/emailVerificationRequestDnsFetchFailed.md +1 -0
  138. package/build/src/third_party/issue-descriptions/emailVerificationRequestDnsInvalidRecord.md +1 -0
  139. package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownHttpNotFound.md +1 -0
  140. package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownInvalidContentType.md +1 -0
  141. package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownInvalidResponse.md +1 -0
  142. package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownNoResponse.md +1 -0
  143. package/build/src/third_party/issue-descriptions/emailVerificationRequestInvalidEmail.md +1 -0
  144. package/build/src/third_party/issue-descriptions/emailVerificationRequestJwksHttpNotFound.md +1 -0
  145. package/build/src/third_party/issue-descriptions/emailVerificationRequestJwksInvalidResponse.md +1 -0
  146. package/build/src/third_party/issue-descriptions/emailVerificationRequestKeyBindingSigningFailed.md +1 -0
  147. package/build/src/third_party/issue-descriptions/emailVerificationRequestRpOriginIsOpaque.md +1 -0
  148. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenHttpNotFound.md +1 -0
  149. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenInvalidContentType.md +1 -0
  150. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenInvalidResponse.md +1 -0
  151. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenInvalidSdJwt.md +1 -0
  152. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenMalformedSdJwt.md +1 -0
  153. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenNoResponse.md +1 -0
  154. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidAudience.md +1 -0
  155. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidIssuedAt.md +1 -0
  156. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidNonce.md +1 -0
  157. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidSdHash.md +1 -0
  158. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidTyp.md +1 -0
  159. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingAud.md +1 -0
  160. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingCnf.md +1 -0
  161. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingIat.md +1 -0
  162. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingNonce.md +1 -0
  163. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingSdHash.md +1 -0
  164. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbSignatureFailed.md +1 -0
  165. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidEmail.md +1 -0
  166. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidEmailVerified.md +1 -0
  167. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidHolderKey.md +1 -0
  168. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidIssuedAt.md +1 -0
  169. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidIssuer.md +1 -0
  170. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtJwksMissingKeys.md +1 -0
  171. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingCnf.md +1 -0
  172. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingEmail.md +1 -0
  173. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingIat.md +1 -0
  174. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingIss.md +1 -0
  175. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtSignatureFailed.md +1 -0
  176. package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtUnsupportedHeaderAlg.md +1 -0
  177. package/build/src/third_party/issue-descriptions/emailVerificationRequestUserLoggedOut.md +1 -0
  178. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownAccountsEndpointCrossOrigin.md +1 -0
  179. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownHttpNotFound.md +1 -0
  180. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownInvalidContentType.md +1 -0
  181. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownInvalidResponse.md +1 -0
  182. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownIssuanceEndpointCrossOrigin.md +1 -0
  183. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownListEmpty.md +1 -0
  184. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownMissingAccountsEndpoint.md +1 -0
  185. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownMissingIssuanceEndpoint.md +1 -0
  186. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownNoResponse.md +1 -0
  187. package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownUnsupportedSigningAlgorithm.md +1 -0
  188. package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsHttpNotFound.md +1 -0
  189. package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsInvalidResponse.md +1 -0
  190. package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsNoResponse.md +1 -0
  191. package/build/src/third_party/issue-descriptions/federatedAuthRequestApprovalDeclined.md +1 -0
  192. package/build/src/third_party/issue-descriptions/federatedAuthRequestCanceled.md +1 -0
  193. package/build/src/third_party/issue-descriptions/federatedAuthRequestErrorFetchingSignin.md +1 -0
  194. package/build/src/third_party/issue-descriptions/federatedAuthRequestErrorIdToken.md +1 -0
  195. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenHttpNotFound.md +1 -0
  196. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenInvalidRequest.md +1 -0
  197. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenInvalidResponse.md +1 -0
  198. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenNoResponse.md +1 -0
  199. package/build/src/third_party/issue-descriptions/federatedAuthRequestInvalidSigninResponse.md +1 -0
  200. package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestHttpNotFound.md +1 -0
  201. package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestInvalidResponse.md +1 -0
  202. package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestNoResponse.md +1 -0
  203. package/build/src/third_party/issue-descriptions/federatedAuthRequestTooManyRequests.md +1 -0
  204. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestInvalidAccountsResponse.md +1 -0
  205. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestInvalidConfigOrWellKnown.md +1 -0
  206. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoAccountSharingPermission.md +1 -0
  207. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoApiPermission.md +1 -0
  208. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoReturningUserFromFetchedAccounts.md +1 -0
  209. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotIframe.md +1 -0
  210. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotPotentiallyTrustworthy.md +1 -0
  211. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotSameOrigin.md +1 -0
  212. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotSignedInWithIdp.md +1 -0
  213. package/build/src/third_party/issue-descriptions/fetchingPartitionedBlobURL.md +7 -0
  214. package/build/src/third_party/issue-descriptions/genericBackUINavigationWouldSkipAd.md +4 -0
  215. package/build/src/third_party/issue-descriptions/genericFormAriaLabelledByToNonExistingIdError.md +8 -0
  216. package/build/src/third_party/issue-descriptions/genericFormAutocompleteAttributeEmptyError.md +5 -0
  217. package/build/src/third_party/issue-descriptions/genericFormDuplicateIdForInputError.md +5 -0
  218. package/build/src/third_party/issue-descriptions/genericFormEmptyIdAndNameAttributesForInputError.md +5 -0
  219. package/build/src/third_party/issue-descriptions/genericFormInputAssignedAutocompleteValueToIdOrNameAttributeError.md +5 -0
  220. package/build/src/third_party/issue-descriptions/genericFormInputHasWrongButWellIntendedAutocompleteValueError.md +5 -0
  221. package/build/src/third_party/issue-descriptions/genericFormInputWithNoLabelError.md +5 -0
  222. package/build/src/third_party/issue-descriptions/genericFormLabelForMatchesNonExistingIdError.md +5 -0
  223. package/build/src/third_party/issue-descriptions/genericFormLabelForNameError.md +5 -0
  224. package/build/src/third_party/issue-descriptions/genericFormLabelHasNeitherForNorNestedInputError.md +5 -0
  225. package/build/src/third_party/issue-descriptions/genericFormModelContextMissingToolDescription.md +5 -0
  226. package/build/src/third_party/issue-descriptions/genericFormModelContextMissingToolName.md +5 -0
  227. package/build/src/third_party/issue-descriptions/genericFormModelContextParameterMissingName.md +5 -0
  228. package/build/src/third_party/issue-descriptions/genericFormModelContextParameterMissingTitleAndDescription.md +5 -0
  229. package/build/src/third_party/issue-descriptions/genericFormModelContextRequiredParameterMissingName.md +5 -0
  230. package/build/src/third_party/issue-descriptions/genericNavigationEntryMarkedSkippable.md +7 -0
  231. package/build/src/third_party/issue-descriptions/genericResponseWasBlockedByORB.md +4 -0
  232. package/build/src/third_party/issue-descriptions/heavyAd.md +10 -0
  233. package/build/src/third_party/issue-descriptions/mixedContent.md +5 -0
  234. package/build/src/third_party/issue-descriptions/navigatingPartitionedBlobURL.md +5 -0
  235. package/build/src/third_party/issue-descriptions/permissionElementActivationDisabled.md +7 -0
  236. package/build/src/third_party/issue-descriptions/permissionElementActivationDisabledWithOccluder.md +9 -0
  237. package/build/src/third_party/issue-descriptions/permissionElementActivationDisabledWithOccluderParent.md +9 -0
  238. package/build/src/third_party/issue-descriptions/permissionElementCspFrameAncestorsMissing.md +5 -0
  239. package/build/src/third_party/issue-descriptions/permissionElementFencedFrameDisallowed.md +5 -0
  240. package/build/src/third_party/issue-descriptions/permissionElementFontSizeTooLarge.md +5 -0
  241. package/build/src/third_party/issue-descriptions/permissionElementFontSizeTooSmall.md +5 -0
  242. package/build/src/third_party/issue-descriptions/permissionElementGeolocationDeprecated.md +5 -0
  243. package/build/src/third_party/issue-descriptions/permissionElementInsetBoxShadowUnsupported.md +5 -0
  244. package/build/src/third_party/issue-descriptions/permissionElementInvalidDisplayStyle.md +5 -0
  245. package/build/src/third_party/issue-descriptions/permissionElementInvalidSizeValue.md +5 -0
  246. package/build/src/third_party/issue-descriptions/permissionElementInvalidType.md +5 -0
  247. package/build/src/third_party/issue-descriptions/permissionElementInvalidTypeActivation.md +5 -0
  248. package/build/src/third_party/issue-descriptions/permissionElementLowContrast.md +5 -0
  249. package/build/src/third_party/issue-descriptions/permissionElementNonOpaqueColor.md +5 -0
  250. package/build/src/third_party/issue-descriptions/permissionElementPaddingBottomUnsupported.md +6 -0
  251. package/build/src/third_party/issue-descriptions/permissionElementPaddingRightUnsupported.md +6 -0
  252. package/build/src/third_party/issue-descriptions/permissionElementPermissionsPolicyBlocked.md +5 -0
  253. package/build/src/third_party/issue-descriptions/permissionElementRegistrationFailed.md +5 -0
  254. package/build/src/third_party/issue-descriptions/permissionElementRequestInProgress.md +5 -0
  255. package/build/src/third_party/issue-descriptions/permissionElementSecurityChecksFailed.md +5 -0
  256. package/build/src/third_party/issue-descriptions/permissionElementTypeNotSupported.md +5 -0
  257. package/build/src/third_party/issue-descriptions/permissionElementUntrustedEvent.md +7 -0
  258. package/build/src/third_party/issue-descriptions/placeholderDescriptionForInvisibleIssues.md +3 -0
  259. package/build/src/third_party/issue-descriptions/propertyRuleInvalidNameIssue.md +3 -0
  260. package/build/src/third_party/issue-descriptions/propertyRuleIssue.md +7 -0
  261. package/build/src/third_party/issue-descriptions/selectElementAccessibilityDisallowedOptGroupChild.md +7 -0
  262. package/build/src/third_party/issue-descriptions/selectElementAccessibilityDisallowedSelectChild.md +7 -0
  263. package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentAttributesSelectDescendant.md +3 -0
  264. package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentLegendChild.md +3 -0
  265. package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentOptionChild.md +3 -0
  266. package/build/src/third_party/issue-descriptions/selectElementAccessibilityNonPhrasingContentOptionChild.md +3 -0
  267. package/build/src/third_party/issue-descriptions/selectivePermissionsIntervention.md +7 -0
  268. package/build/src/third_party/issue-descriptions/sharedArrayBuffer.md +7 -0
  269. package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorCrossOriginNoCorsRequest.md +1 -0
  270. package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorDictionaryLoadFailure.md +3 -0
  271. package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorMatchingDictionaryNotUsed.md +3 -0
  272. package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorUnexpectedContentDictionaryHeader.md +1 -0
  273. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorCossOriginNoCorsRequest.md +1 -0
  274. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorDisallowedBySettings.md +1 -0
  275. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorExpiredResponse.md +3 -0
  276. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorFeatureDisabled.md +3 -0
  277. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInsufficientResources.md +1 -0
  278. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInvalidMatchField.md +1 -0
  279. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInvalidStructuredHeader.md +1 -0
  280. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInvalidTTLField.md +1 -0
  281. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNavigationRequest.md +3 -0
  282. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNoMatchField.md +1 -0
  283. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonIntegerTTLField.md +1 -0
  284. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonListMatchDestField.md +1 -0
  285. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonSecureContext.md +3 -0
  286. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonStringIdField.md +1 -0
  287. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonStringInMatchDestList.md +1 -0
  288. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonStringMatchField.md +1 -0
  289. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonTokenTypeField.md +1 -0
  290. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorRequestAborted.md +1 -0
  291. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorShuttingDown.md +1 -0
  292. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorTooLongIdField.md +3 -0
  293. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorUnsupportedType.md +3 -0
  294. package/build/src/third_party/issue-descriptions/sriInvalidSignatureHeader.md +14 -0
  295. package/build/src/third_party/issue-descriptions/sriInvalidSignatureInputHeader.md +15 -0
  296. package/build/src/third_party/issue-descriptions/sriMissingSignatureHeader.md +8 -0
  297. package/build/src/third_party/issue-descriptions/sriMissingSignatureInputHeader.md +7 -0
  298. package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsIncorrectLength.md +11 -0
  299. package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsNotByteSequence.md +14 -0
  300. package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsParameterized.md +15 -0
  301. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidComponentName.md +8 -0
  302. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidComponentType.md +13 -0
  303. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidDerivedComponentParameter.md +4 -0
  304. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidHeaderComponentParameter.md +5 -0
  305. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidParameter.md +11 -0
  306. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderKeyIdLength.md +12 -0
  307. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderMissingLabel.md +6 -0
  308. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderMissingRequiredParameters.md +8 -0
  309. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderValueMissingComponents.md +11 -0
  310. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderValueNotInnerList.md +11 -0
  311. package/build/src/third_party/issue-descriptions/sriValidationFailedIntegrityMismatch.md +10 -0
  312. package/build/src/third_party/issue-descriptions/sriValidationFailedInvalidLength.md +5 -0
  313. package/build/src/third_party/issue-descriptions/sriValidationFailedSignatureExpired.md +6 -0
  314. package/build/src/third_party/issue-descriptions/sriValidationFailedSignatureMismatch.md +11 -0
  315. package/build/src/third_party/issue-descriptions/stylesheetLateImport.md +4 -0
  316. package/build/src/third_party/issue-descriptions/stylesheetRequestFailed.md +3 -0
  317. package/build/src/third_party/issue-descriptions/summaryElementAccessibilityInteractiveContentSummaryDescendant.md +3 -0
  318. package/build/src/third_party/issue-descriptions/unencodedDigestIncorrectDigestLength.md +12 -0
  319. package/build/src/third_party/issue-descriptions/unencodedDigestIncorrectDigestType.md +17 -0
  320. package/build/src/third_party/issue-descriptions/unencodedDigestMalformedDictionary.md +14 -0
  321. package/build/src/third_party/issue-descriptions/unencodedDigestUnknownAlgorithm.md +15 -0
  322. package/build/src/third_party/lighthouse-devtools-mcp-bundle.js +61598 -0
  323. package/build/src/tools/ToolDefinition.js +73 -0
  324. package/build/src/tools/categories.js +36 -0
  325. package/build/src/tools/console.js +98 -0
  326. package/build/src/tools/emulation.js +84 -0
  327. package/build/src/tools/extensions.js +101 -0
  328. package/build/src/tools/input.js +469 -0
  329. package/build/src/tools/lighthouse.js +136 -0
  330. package/build/src/tools/memory.js +227 -0
  331. package/build/src/tools/network.js +125 -0
  332. package/build/src/tools/pages.js +419 -0
  333. package/build/src/tools/performance.js +200 -0
  334. package/build/src/tools/screencast.js +117 -0
  335. package/build/src/tools/screenshot.js +169 -0
  336. package/build/src/tools/script.js +151 -0
  337. package/build/src/tools/slim/tools.js +88 -0
  338. package/build/src/tools/snapshot.js +61 -0
  339. package/build/src/tools/thirdPartyDeveloper.js +85 -0
  340. package/build/src/tools/tools.js +56 -0
  341. package/build/src/tools/webmcp.js +66 -0
  342. package/build/src/trace-processing/parse.js +85 -0
  343. package/build/src/types.js +7 -0
  344. package/build/src/utils/check-for-updates.js +74 -0
  345. package/build/src/utils/files.js +61 -0
  346. package/build/src/utils/id.js +16 -0
  347. package/build/src/utils/keyboard.js +297 -0
  348. package/build/src/utils/pagination.js +50 -0
  349. package/build/src/utils/string.js +37 -0
  350. package/build/src/utils/types.js +7 -0
  351. package/build/src/version.js +10 -0
  352. package/package.json +100 -0
  353. package/skills/a11y-debugging/SKILL.md +89 -0
  354. package/skills/a11y-debugging/references/a11y-snippets.md +92 -0
  355. package/skills/chrome-devtools/SKILL.md +72 -0
  356. package/skills/chrome-devtools-cli/SKILL.md +153 -0
  357. package/skills/chrome-devtools-cli/references/installation.md +14 -0
  358. package/skills/debug-optimize-lcp/SKILL.md +121 -0
  359. package/skills/debug-optimize-lcp/references/elements-and-size.md +27 -0
  360. package/skills/debug-optimize-lcp/references/lcp-breakdown.md +23 -0
  361. package/skills/debug-optimize-lcp/references/lcp-snippets.md +79 -0
  362. package/skills/debug-optimize-lcp/references/optimization-strategies.md +38 -0
  363. package/skills/memory-leak-debugging/SKILL.md +50 -0
  364. package/skills/memory-leak-debugging/references/common-leaks.md +33 -0
  365. package/skills/memory-leak-debugging/references/compare_snapshots.js +109 -0
  366. package/skills/memory-leak-debugging/references/memlab.md +29 -0
  367. package/skills/troubleshooting/SKILL.md +98 -0
@@ -0,0 +1,990 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { ConsoleFormatter } from './formatters/ConsoleFormatter.js';
7
+ import { HeapSnapshotFormatter } from './formatters/HeapSnapshotFormatter.js';
8
+ import { isEdgeLike, isNodeLike } from './formatters/HeapSnapshotFormatter.js';
9
+ import { IssueFormatter } from './formatters/IssueFormatter.js';
10
+ import { NetworkFormatter } from './formatters/NetworkFormatter.js';
11
+ import { SnapshotFormatter } from './formatters/SnapshotFormatter.js';
12
+ import { UncaughtError } from './PageCollector.js';
13
+ import { TextSnapshot } from './TextSnapshot.js';
14
+ import { DevTools, toonEncode } from './third_party/index.js';
15
+ import { handleDialog } from './tools/pages.js';
16
+ import { getInsightOutput, getTraceSummary } from './trace-processing/parse.js';
17
+ import { paginate } from './utils/pagination.js';
18
+ export function replaceHtmlElementsWithUids(schema) {
19
+ if (typeof schema === 'boolean') {
20
+ return;
21
+ }
22
+ let isHtmlElement = false;
23
+ for (const [key, value] of Object.entries(schema)) {
24
+ if (key === 'x-mcp-type' && value === 'HTMLElement') {
25
+ isHtmlElement = true;
26
+ break;
27
+ }
28
+ }
29
+ if (isHtmlElement) {
30
+ schema.properties = { uid: { type: 'string' } };
31
+ schema.required = ['uid'];
32
+ }
33
+ if (schema.properties) {
34
+ for (const key of Object.keys(schema.properties)) {
35
+ replaceHtmlElementsWithUids(schema.properties[key]);
36
+ }
37
+ }
38
+ if (schema.items) {
39
+ if (Array.isArray(schema.items)) {
40
+ for (const item of schema.items) {
41
+ replaceHtmlElementsWithUids(item);
42
+ }
43
+ }
44
+ else {
45
+ replaceHtmlElementsWithUids(schema.items);
46
+ }
47
+ }
48
+ if (schema.anyOf) {
49
+ for (const s of schema.anyOf) {
50
+ replaceHtmlElementsWithUids(s);
51
+ }
52
+ }
53
+ if (schema.allOf) {
54
+ for (const s of schema.allOf) {
55
+ replaceHtmlElementsWithUids(s);
56
+ }
57
+ }
58
+ if (schema.oneOf) {
59
+ for (const s of schema.oneOf) {
60
+ replaceHtmlElementsWithUids(s);
61
+ }
62
+ }
63
+ }
64
+ async function getToolGroups(page) {
65
+ // Check if there is a `devtoolstooldiscovery` event listener
66
+ const windowHandle = await page.pptrPage.evaluateHandle(() => window);
67
+ // @ts-expect-error internal API
68
+ const client = page.pptrPage._client();
69
+ const { listeners } = await client.send('DOMDebugger.getEventListeners', {
70
+ objectId: windowHandle.remoteObject().objectId,
71
+ });
72
+ if (listeners.find(l => l.type === 'devtoolstooldiscovery') === undefined) {
73
+ return [];
74
+ }
75
+ const toolGroups = await page.pptrPage.evaluate(() => {
76
+ if (window.__dtmcp) {
77
+ window.__dtmcp.toolGroups = [];
78
+ }
79
+ return new Promise(resolve => {
80
+ const event = new CustomEvent('devtoolstooldiscovery');
81
+ const groups = [];
82
+ // @ts-expect-error Adding custom property
83
+ event.respondWith = toolGroup => {
84
+ if (!window.__dtmcp) {
85
+ window.__dtmcp = {};
86
+ }
87
+ if (!window.__dtmcp.toolGroups) {
88
+ window.__dtmcp.toolGroups = [];
89
+ }
90
+ if (typeof toolGroup.name !== 'string' ||
91
+ (toolGroup.description &&
92
+ typeof toolGroup.description !== 'string') ||
93
+ !Array.isArray(toolGroup.tools)) {
94
+ console.error('Invalid toolGroup:', toolGroup);
95
+ return;
96
+ }
97
+ for (const tool of toolGroup.tools) {
98
+ if (typeof tool.name !== 'string' ||
99
+ typeof tool.description !== 'string' ||
100
+ typeof tool.inputSchema !== 'object' ||
101
+ typeof tool.execute !== 'function') {
102
+ console.error('Invalid tool:', tool);
103
+ return;
104
+ }
105
+ }
106
+ window.__dtmcp.toolGroups.push(toolGroup);
107
+ // When receiving a toolGroup for the first time, expose a simple execution helper
108
+ if (!window.__dtmcp.executeTool) {
109
+ window.__dtmcp.executeTool = async (toolName, args) => {
110
+ if (!window.__dtmcp?.toolGroups ||
111
+ window.__dtmcp.toolGroups.length === 0) {
112
+ throw new Error('No tools found on the page');
113
+ }
114
+ for (const group of window.__dtmcp.toolGroups) {
115
+ const tool = group.tools?.find(t => t.name === toolName);
116
+ if (tool) {
117
+ return await tool.execute(args);
118
+ }
119
+ }
120
+ throw new Error(`Tool ${toolName} not found`);
121
+ };
122
+ }
123
+ groups.push(toolGroup);
124
+ };
125
+ window.dispatchEvent(event);
126
+ // If at least one toolGroup was added synchronously, resolve with the array.
127
+ // Otherwise, use setTimeout to allow for any microtask/asynchronous respondWith calls, or resolve with an empty array.
128
+ if (groups.length > 0) {
129
+ resolve(groups);
130
+ }
131
+ else {
132
+ setTimeout(() => {
133
+ if (groups.length > 0) {
134
+ resolve(groups);
135
+ }
136
+ else {
137
+ resolve([]);
138
+ }
139
+ }, 0);
140
+ }
141
+ });
142
+ });
143
+ for (const group of toolGroups) {
144
+ for (const tool of group.tools ?? []) {
145
+ replaceHtmlElementsWithUids(tool.inputSchema);
146
+ }
147
+ }
148
+ return toolGroups;
149
+ }
150
+ export class McpResponse {
151
+ #includePages = false;
152
+ #includeExtensionServiceWorkers = false;
153
+ #includeExtensionPages = false;
154
+ #snapshotParams;
155
+ #attachedNetworkRequestId;
156
+ #attachedNetworkRequestOptions;
157
+ #attachedConsoleMessageId;
158
+ #attachedTraceSummary;
159
+ #attachedTraceInsight;
160
+ #attachedLighthouseResult;
161
+ #textResponseLines = [];
162
+ #images = [];
163
+ #heapSnapshotOptions;
164
+ #networkRequestsOptions;
165
+ #consoleDataOptions;
166
+ #listExtensions;
167
+ #listThirdPartyDeveloperTools;
168
+ #listWebMcpTools;
169
+ #devToolsData;
170
+ #tabId;
171
+ #args;
172
+ #page;
173
+ #redactNetworkHeaders = true;
174
+ #error;
175
+ #attachedWaitForResult;
176
+ get #deviceScope() {
177
+ return this.#page?.viewport?.isMobile ? 'PHONE' : 'DESKTOP';
178
+ }
179
+ constructor(args) {
180
+ this.#args = args;
181
+ }
182
+ setPage(page) {
183
+ this.#page = page;
184
+ }
185
+ setRedactNetworkHeaders(value) {
186
+ this.#redactNetworkHeaders = value;
187
+ }
188
+ attachDevToolsData(data) {
189
+ this.#devToolsData = data;
190
+ }
191
+ setTabId(tabId) {
192
+ this.#tabId = tabId;
193
+ }
194
+ setIncludePages(value) {
195
+ this.#includePages = value;
196
+ if (this.#args.categoryExtensions) {
197
+ this.#includeExtensionServiceWorkers = value;
198
+ this.#includeExtensionPages = value;
199
+ }
200
+ }
201
+ includeSnapshot(params) {
202
+ this.#snapshotParams = params ?? {
203
+ verbose: false,
204
+ };
205
+ }
206
+ setListExtensions() {
207
+ this.#listExtensions = true;
208
+ }
209
+ setListThirdPartyDeveloperTools() {
210
+ this.#listThirdPartyDeveloperTools = true;
211
+ }
212
+ setListWebMcpTools() {
213
+ this.#listWebMcpTools = true;
214
+ }
215
+ setIncludeNetworkRequests(value, options) {
216
+ if (!value) {
217
+ this.#networkRequestsOptions = undefined;
218
+ return;
219
+ }
220
+ this.#networkRequestsOptions = {
221
+ include: value,
222
+ pagination: options?.pageSize || options?.pageIdx
223
+ ? {
224
+ pageSize: options.pageSize,
225
+ pageIdx: options.pageIdx,
226
+ }
227
+ : undefined,
228
+ resourceTypes: options?.resourceTypes,
229
+ includePreservedRequests: options?.includePreservedRequests,
230
+ networkRequestIdInDevToolsUI: options?.networkRequestIdInDevToolsUI,
231
+ };
232
+ }
233
+ setIncludeConsoleData(value, options) {
234
+ if (!value) {
235
+ this.#consoleDataOptions = undefined;
236
+ return;
237
+ }
238
+ this.#consoleDataOptions = {
239
+ include: value,
240
+ pagination: options?.pageSize || options?.pageIdx
241
+ ? {
242
+ pageSize: options.pageSize,
243
+ pageIdx: options.pageIdx,
244
+ }
245
+ : undefined,
246
+ types: options?.types,
247
+ includePreservedMessages: options?.includePreservedMessages,
248
+ serviceWorkerId: options?.serviceWorkerId,
249
+ };
250
+ }
251
+ setError(error) {
252
+ this.#error = error;
253
+ }
254
+ attachNetworkRequest(reqId, options) {
255
+ this.#attachedNetworkRequestId = reqId;
256
+ this.#attachedNetworkRequestOptions = options;
257
+ }
258
+ attachConsoleMessage(msgid) {
259
+ this.#attachedConsoleMessageId = msgid;
260
+ }
261
+ attachTraceSummary(result) {
262
+ this.#attachedTraceSummary = result;
263
+ }
264
+ attachTraceInsight(trace, insightSetId, insightName) {
265
+ this.#attachedTraceInsight = {
266
+ trace,
267
+ insightSetId,
268
+ insightName,
269
+ };
270
+ }
271
+ attachLighthouseResult(result) {
272
+ this.#attachedLighthouseResult = result;
273
+ }
274
+ get includePages() {
275
+ return this.#includePages;
276
+ }
277
+ get attachedTraceSummary() {
278
+ return this.#attachedTraceSummary;
279
+ }
280
+ get attachedTracedInsight() {
281
+ return this.#attachedTraceInsight;
282
+ }
283
+ get attachedLighthouseResult() {
284
+ return this.#attachedLighthouseResult;
285
+ }
286
+ get includeNetworkRequests() {
287
+ return this.#networkRequestsOptions?.include ?? false;
288
+ }
289
+ get includeConsoleData() {
290
+ return this.#consoleDataOptions?.include ?? false;
291
+ }
292
+ get attachedNetworkRequestId() {
293
+ return this.#attachedNetworkRequestId;
294
+ }
295
+ get networkRequestsPageIdx() {
296
+ return this.#networkRequestsOptions?.pagination?.pageIdx;
297
+ }
298
+ get consoleMessagesPageIdx() {
299
+ return this.#consoleDataOptions?.pagination?.pageIdx;
300
+ }
301
+ get consoleMessagesTypes() {
302
+ return this.#consoleDataOptions?.types;
303
+ }
304
+ get error() {
305
+ return this.#error;
306
+ }
307
+ appendResponseLine(value) {
308
+ this.#textResponseLines.push(value);
309
+ }
310
+ attachWaitForResult(result) {
311
+ this.#attachedWaitForResult = result;
312
+ }
313
+ setHeapSnapshotAggregates(aggregates, options) {
314
+ this.#heapSnapshotOptions = {
315
+ ...this.#heapSnapshotOptions,
316
+ include: true,
317
+ aggregates,
318
+ pagination: options,
319
+ };
320
+ }
321
+ setHeapSnapshotStats(stats, staticData) {
322
+ this.#heapSnapshotOptions = {
323
+ ...this.#heapSnapshotOptions,
324
+ include: true,
325
+ stats,
326
+ staticData,
327
+ };
328
+ }
329
+ setHeapSnapshotNodes(nodes, options) {
330
+ this.#heapSnapshotOptions = {
331
+ ...this.#heapSnapshotOptions,
332
+ include: true,
333
+ nodes,
334
+ pagination: options,
335
+ };
336
+ }
337
+ setHeapSnapshotRetainingPaths(retainingPaths) {
338
+ this.#heapSnapshotOptions = {
339
+ ...this.#heapSnapshotOptions,
340
+ include: true,
341
+ retainingPaths,
342
+ };
343
+ }
344
+ setHeapSnapshotDominators(dominators) {
345
+ this.#heapSnapshotOptions = {
346
+ ...this.#heapSnapshotOptions,
347
+ include: true,
348
+ dominators,
349
+ };
350
+ }
351
+ attachImage(value) {
352
+ this.#images.push(value);
353
+ }
354
+ get responseLines() {
355
+ return this.#textResponseLines;
356
+ }
357
+ get images() {
358
+ return this.#images;
359
+ }
360
+ get snapshotParams() {
361
+ return this.#snapshotParams;
362
+ }
363
+ get listWebMcpTools() {
364
+ return this.#listWebMcpTools;
365
+ }
366
+ async handle(toolName, context, useToon = false) {
367
+ if (this.#includePages) {
368
+ await context.createPagesSnapshot();
369
+ }
370
+ if (this.#includeExtensionServiceWorkers) {
371
+ await context.createExtensionServiceWorkersSnapshot();
372
+ }
373
+ let snapshot;
374
+ if (this.#snapshotParams) {
375
+ if (!this.#page) {
376
+ throw new Error('Response must have a page');
377
+ }
378
+ this.#page.textSnapshot = await TextSnapshot.create(this.#page, {
379
+ verbose: this.#snapshotParams.verbose,
380
+ devtoolsData: this.#devToolsData,
381
+ });
382
+ const textSnapshot = this.#page.textSnapshot;
383
+ if (textSnapshot) {
384
+ const formatter = new SnapshotFormatter(textSnapshot);
385
+ if (this.#snapshotParams.filePath) {
386
+ const result = await context.saveFile(new TextEncoder().encode(formatter.toString()), this.#snapshotParams.filePath, '.txt');
387
+ snapshot = result.filename;
388
+ }
389
+ else {
390
+ snapshot = formatter;
391
+ }
392
+ }
393
+ }
394
+ let detailedNetworkRequest;
395
+ if (this.#attachedNetworkRequestId) {
396
+ if (!this.#page) {
397
+ throw new Error(`Response must have an McpPage`);
398
+ }
399
+ const request = context.getNetworkRequestById(this.#page, this.#attachedNetworkRequestId);
400
+ const formatter = await NetworkFormatter.from(request, {
401
+ requestId: this.#attachedNetworkRequestId,
402
+ requestIdResolver: req => context.getNetworkRequestStableId(req),
403
+ fetchData: true,
404
+ requestFilePath: this.#attachedNetworkRequestOptions?.requestFilePath,
405
+ responseFilePath: this.#attachedNetworkRequestOptions?.responseFilePath,
406
+ saveFile: (data, filename, extension) => context.saveFile(data, filename, extension),
407
+ redactNetworkHeaders: this.#redactNetworkHeaders,
408
+ });
409
+ detailedNetworkRequest = formatter;
410
+ }
411
+ let detailedConsoleMessage;
412
+ if (this.#attachedConsoleMessageId) {
413
+ if (!this.#page) {
414
+ throw new Error(`Response must have an McpPage`);
415
+ }
416
+ const message = context.getConsoleMessageById(this.#page, this.#attachedConsoleMessageId);
417
+ const consoleMessageStableId = this.#attachedConsoleMessageId;
418
+ if ('args' in message || message instanceof UncaughtError) {
419
+ const consoleMessage = message;
420
+ const devTools = context.getDevToolsUniverse(this.#page);
421
+ detailedConsoleMessage = await ConsoleFormatter.from(consoleMessage, {
422
+ id: consoleMessageStableId,
423
+ fetchDetailedData: true,
424
+ devTools: devTools ?? undefined,
425
+ });
426
+ }
427
+ else if (message instanceof DevTools.AggregatedIssue) {
428
+ const formatter = new IssueFormatter(message, {
429
+ id: consoleMessageStableId,
430
+ requestIdResolver: context.resolveCdpRequestId.bind(context, this.#page),
431
+ elementIdResolver: this.#page.resolveCdpElementId.bind(this.#page),
432
+ });
433
+ if (!formatter.isValid()) {
434
+ throw new Error("Can't provide details for the msgid " + consoleMessageStableId);
435
+ }
436
+ detailedConsoleMessage = formatter;
437
+ }
438
+ }
439
+ let extensions;
440
+ if (this.#listExtensions) {
441
+ extensions = await context.listExtensions();
442
+ }
443
+ let thirdPartyDeveloperTools = [];
444
+ if (this.#args.categoryExperimentalThirdParty &&
445
+ this.#listThirdPartyDeveloperTools &&
446
+ this.#page) {
447
+ thirdPartyDeveloperTools = await getToolGroups(this.#page);
448
+ if (thirdPartyDeveloperTools) {
449
+ this.#page.thirdPartyDeveloperTools = thirdPartyDeveloperTools;
450
+ }
451
+ }
452
+ let webmcpTools;
453
+ if (this.#args.categoryExperimentalWebmcp &&
454
+ this.#listWebMcpTools &&
455
+ this.#page) {
456
+ webmcpTools = this.#page.getWebMcpTools();
457
+ }
458
+ let consoleMessages;
459
+ if (this.#consoleDataOptions?.include) {
460
+ let messages;
461
+ let page;
462
+ if (this.#consoleDataOptions.serviceWorkerId) {
463
+ messages = context.getServiceWorkerConsoleData(this.#consoleDataOptions.serviceWorkerId);
464
+ }
465
+ else {
466
+ page = this.#page;
467
+ if (!page) {
468
+ throw new Error(`Response must have an McpPage`);
469
+ }
470
+ messages = context.getConsoleData(page, this.#consoleDataOptions.includePreservedMessages);
471
+ }
472
+ if (this.#consoleDataOptions.types?.length) {
473
+ const normalizedTypes = new Set(this.#consoleDataOptions.types);
474
+ messages = messages.filter(message => {
475
+ if ('type' in message) {
476
+ return normalizedTypes.has(message.type());
477
+ }
478
+ if (message instanceof DevTools.AggregatedIssue) {
479
+ return normalizedTypes.has('issue');
480
+ }
481
+ return normalizedTypes.has('error');
482
+ });
483
+ }
484
+ consoleMessages = (await Promise.all(messages.map(async (item) => {
485
+ const consoleMessageStableId = context.getConsoleMessageStableId(item);
486
+ if ('args' in item || item instanceof UncaughtError) {
487
+ const consoleMessage = item;
488
+ const devTools = page
489
+ ? context.getDevToolsUniverse(page)
490
+ : null;
491
+ return await ConsoleFormatter.from(consoleMessage, {
492
+ id: consoleMessageStableId,
493
+ fetchDetailedData: false,
494
+ devTools: devTools ?? undefined,
495
+ });
496
+ }
497
+ if (item instanceof DevTools.AggregatedIssue) {
498
+ const formatter = new IssueFormatter(item, {
499
+ id: consoleMessageStableId,
500
+ });
501
+ if (!formatter.isValid()) {
502
+ return null;
503
+ }
504
+ return formatter;
505
+ }
506
+ return null;
507
+ }))).filter(item => item !== null);
508
+ }
509
+ let networkRequests;
510
+ if (this.#networkRequestsOptions?.include) {
511
+ if (!this.#page) {
512
+ throw new Error(`Response must have an McpPage`);
513
+ }
514
+ let requests = context.getNetworkRequests(this.#page, this.#networkRequestsOptions?.includePreservedRequests);
515
+ // Apply resource type filtering if specified
516
+ if (this.#networkRequestsOptions.resourceTypes?.length) {
517
+ const normalizedTypes = new Set(this.#networkRequestsOptions.resourceTypes);
518
+ requests = requests.filter(request => {
519
+ const type = request.resourceType();
520
+ return normalizedTypes.has(type);
521
+ });
522
+ }
523
+ if (requests.length) {
524
+ networkRequests = await Promise.all(requests.map(request => NetworkFormatter.from(request, {
525
+ requestId: context.getNetworkRequestStableId(request),
526
+ selectedInDevToolsUI: context.getNetworkRequestStableId(request) ===
527
+ this.#networkRequestsOptions?.networkRequestIdInDevToolsUI,
528
+ fetchData: false,
529
+ saveFile: (data, filename, extension) => context.saveFile(data, filename, extension),
530
+ redactNetworkHeaders: this.#redactNetworkHeaders,
531
+ })));
532
+ }
533
+ }
534
+ return this.format(toolName, context, {
535
+ detailedConsoleMessage,
536
+ consoleMessages,
537
+ snapshot,
538
+ detailedNetworkRequest,
539
+ networkRequests,
540
+ traceInsight: this.#attachedTraceInsight,
541
+ traceSummary: this.#attachedTraceSummary,
542
+ extensions,
543
+ lighthouseResult: this.#attachedLighthouseResult,
544
+ thirdPartyDeveloperTools,
545
+ webmcpTools,
546
+ errorMessage: this.#error?.message,
547
+ }, useToon);
548
+ }
549
+ async format(toolName, context, data, useToon) {
550
+ const structuredContent = {};
551
+ const response = [];
552
+ if (this.#textResponseLines.length) {
553
+ structuredContent.message = this.#textResponseLines.join('\n');
554
+ response.push(...this.#textResponseLines);
555
+ }
556
+ if (this.#attachedWaitForResult) {
557
+ if (this.#attachedWaitForResult.navigatedToUrl) {
558
+ response.push(`Page navigated to ${this.#attachedWaitForResult.navigatedToUrl}.`);
559
+ structuredContent.navigatedToUrl =
560
+ this.#attachedWaitForResult.navigatedToUrl;
561
+ }
562
+ }
563
+ const networkConditions = this.#page?.networkConditions;
564
+ if (networkConditions) {
565
+ const timeout = this.#page.pptrPage.getDefaultNavigationTimeout();
566
+ response.push(`Emulating network conditions: ${networkConditions}`);
567
+ response.push(`Default navigation timeout set to ${timeout} ms`);
568
+ structuredContent.networkConditions = networkConditions;
569
+ structuredContent.navigationTimeout = timeout;
570
+ }
571
+ const geolocation = this.#page?.geolocation;
572
+ if (geolocation) {
573
+ response.push(`Emulating geolocation: latitude=${geolocation.latitude}, longitude=${geolocation.longitude}`);
574
+ structuredContent.geolocation = geolocation;
575
+ }
576
+ const viewport = this.#page?.viewport;
577
+ if (viewport) {
578
+ response.push(`Emulating viewport: ${JSON.stringify(viewport)}`);
579
+ structuredContent.viewport = viewport;
580
+ }
581
+ const userAgent = this.#page?.userAgent;
582
+ if (userAgent) {
583
+ response.push(`Emulating user agent: ${userAgent}`);
584
+ structuredContent.userAgent = userAgent;
585
+ }
586
+ const cpuThrottlingRate = this.#page?.cpuThrottlingRate ?? 1;
587
+ if (cpuThrottlingRate > 1) {
588
+ response.push(`Emulating CPU throttling: ${cpuThrottlingRate}x slowdown`);
589
+ structuredContent.cpuThrottlingRate = cpuThrottlingRate;
590
+ }
591
+ const colorScheme = this.#page?.colorScheme;
592
+ if (colorScheme) {
593
+ response.push(`Emulating color scheme: ${colorScheme}`);
594
+ structuredContent.colorScheme = colorScheme;
595
+ }
596
+ const dialog = this.#page?.getDialog();
597
+ if (dialog) {
598
+ const defaultValueIfNeeded = dialog.type() === 'prompt'
599
+ ? ` (default value: "${dialog.defaultValue()}")`
600
+ : '';
601
+ response.push(`# Open dialog
602
+ ${dialog.type()}: ${dialog.message()}${defaultValueIfNeeded}.
603
+ Call ${handleDialog.name} to handle it before continuing.`);
604
+ structuredContent.dialog = {
605
+ type: dialog.type(),
606
+ message: dialog.message(),
607
+ defaultValue: dialog.defaultValue(),
608
+ };
609
+ }
610
+ if (this.#includePages) {
611
+ const allPages = context.getPages();
612
+ const { regularPages, extensionPages } = allPages.reduce((acc, page) => {
613
+ if (page.url().startsWith('chrome-extension://')) {
614
+ acc.extensionPages.push(page);
615
+ }
616
+ else {
617
+ acc.regularPages.push(page);
618
+ }
619
+ return acc;
620
+ }, { regularPages: [], extensionPages: [] });
621
+ if (regularPages.length) {
622
+ const parts = [`## Pages`];
623
+ const structuredPages = [];
624
+ for (const page of regularPages) {
625
+ const isolatedContextName = context.getIsolatedContextName(page);
626
+ const contextLabel = isolatedContextName
627
+ ? ` isolatedContext=${isolatedContextName}`
628
+ : '';
629
+ const title = await fetchPageTitle(page);
630
+ const pageLabel = title
631
+ ? `${truncateTitle(title)} (${page.url()})`
632
+ : page.url();
633
+ parts.push(`${context.getPageId(page)}: ${pageLabel}${context.isPageSelected(page) ? ' [selected]' : ''}${contextLabel}`);
634
+ structuredPages.push(createStructuredPage(page, context, title));
635
+ }
636
+ response.push(...parts);
637
+ structuredContent.pages = structuredPages;
638
+ }
639
+ if (this.#includeExtensionPages) {
640
+ if (extensionPages.length) {
641
+ response.push(`## Extension Pages`);
642
+ const structuredExtensionPages = [];
643
+ for (const page of extensionPages) {
644
+ const isolatedContextName = context.getIsolatedContextName(page);
645
+ const contextLabel = isolatedContextName
646
+ ? ` isolatedContext=${isolatedContextName}`
647
+ : '';
648
+ const title = await fetchPageTitle(page);
649
+ const pageLabel = title
650
+ ? `${truncateTitle(title)} (${page.url()})`
651
+ : page.url();
652
+ response.push(`${context.getPageId(page)}: ${pageLabel}${context.isPageSelected(page) ? ' [selected]' : ''}${contextLabel}`);
653
+ structuredExtensionPages.push(createStructuredPage(page, context, title));
654
+ }
655
+ structuredContent.extensionPages = structuredExtensionPages;
656
+ }
657
+ }
658
+ }
659
+ if (this.#includeExtensionServiceWorkers) {
660
+ if (context.getExtensionServiceWorkers().length) {
661
+ response.push(`## Extension Service Workers`);
662
+ }
663
+ for (const extensionServiceWorker of context.getExtensionServiceWorkers()) {
664
+ response.push(`${extensionServiceWorker.id}: ${extensionServiceWorker.url}`);
665
+ }
666
+ structuredContent.extensionServiceWorkers = context
667
+ .getExtensionServiceWorkers()
668
+ .map(extensionServiceWorker => {
669
+ return {
670
+ id: extensionServiceWorker.id,
671
+ url: extensionServiceWorker.url,
672
+ };
673
+ });
674
+ }
675
+ if (this.#tabId) {
676
+ structuredContent.tabId = this.#tabId;
677
+ }
678
+ if (data.traceSummary) {
679
+ const summary = getTraceSummary(data.traceSummary, this.#deviceScope);
680
+ response.push(summary);
681
+ structuredContent.traceSummary = summary;
682
+ structuredContent.traceInsights = [];
683
+ for (const insightSet of data.traceSummary.insights?.values() ?? []) {
684
+ for (const [insightName, model] of Object.entries(insightSet.model)) {
685
+ structuredContent.traceInsights.push({
686
+ insightName,
687
+ insightKey: model.insightKey,
688
+ });
689
+ }
690
+ }
691
+ }
692
+ if (data.traceInsight) {
693
+ const insightOutput = getInsightOutput(data.traceInsight.trace, data.traceInsight.insightSetId, data.traceInsight.insightName, this.#deviceScope);
694
+ if ('error' in insightOutput) {
695
+ response.push(insightOutput.error);
696
+ }
697
+ else {
698
+ response.push(insightOutput.output);
699
+ }
700
+ }
701
+ if (data.lighthouseResult) {
702
+ structuredContent.lighthouseResult = data.lighthouseResult;
703
+ const { summary, reports } = data.lighthouseResult;
704
+ response.push('## Lighthouse Audit Results');
705
+ response.push(`Mode: ${summary.mode}`);
706
+ response.push(`Device: ${summary.device}`);
707
+ response.push(`URL: ${summary.url}`);
708
+ response.push('### Category Scores');
709
+ for (const score of summary.scores) {
710
+ response.push(`- ${score.title}: ${(score.score ?? 0) * 100} (${score.id})`);
711
+ }
712
+ response.push('### Audit Summary');
713
+ response.push(`Passed: ${summary.audits.passed}`);
714
+ response.push(`Failed: ${summary.audits.failed}`);
715
+ response.push(`Total Timing: ${summary.timing.total}ms`);
716
+ response.push('### Reports');
717
+ for (const report of reports) {
718
+ response.push(`- ${report}`);
719
+ }
720
+ }
721
+ if (data.snapshot) {
722
+ if (typeof data.snapshot === 'string') {
723
+ response.push(`Saved snapshot to ${data.snapshot}.`);
724
+ structuredContent.snapshotFilePath = data.snapshot;
725
+ }
726
+ else {
727
+ structuredContent.snapshot = data.snapshot.toJSON();
728
+ response.push('## Latest page snapshot');
729
+ response.push(useToon
730
+ ? toonEncode(structuredContent.snapshot)
731
+ : data.snapshot.toString());
732
+ }
733
+ }
734
+ if (this.#heapSnapshotOptions?.include) {
735
+ response.push('## Heap Snapshot Data');
736
+ const stats = this.#heapSnapshotOptions.stats;
737
+ const staticData = this.#heapSnapshotOptions.staticData;
738
+ if (stats) {
739
+ response.push(`Statistics: ${JSON.stringify(stats, null, 2)}`);
740
+ structuredContent.heapSnapshot = structuredContent.heapSnapshot || {};
741
+ structuredContent.heapSnapshot.stats = stats;
742
+ }
743
+ if (staticData) {
744
+ response.push(`Static Data: ${JSON.stringify(staticData, null, 2)}`);
745
+ structuredContent.heapSnapshot = structuredContent.heapSnapshot || {};
746
+ structuredContent.heapSnapshot.staticData = staticData;
747
+ }
748
+ const aggregates = this.#heapSnapshotOptions.aggregates;
749
+ if (aggregates) {
750
+ const sortedEntries = HeapSnapshotFormatter.sort(aggregates);
751
+ const paginationData = this.#dataWithPagination(sortedEntries, this.#heapSnapshotOptions.pagination);
752
+ structuredContent.pagination = paginationData.pagination;
753
+ response.push(...paginationData.info);
754
+ const paginatedRecord = Object.fromEntries(paginationData.items);
755
+ const formatter = new HeapSnapshotFormatter(paginatedRecord);
756
+ structuredContent.heapSnapshotData = formatter.toJSON();
757
+ response.push(useToon
758
+ ? toonEncode(structuredContent.heapSnapshotData)
759
+ : formatter.toString());
760
+ }
761
+ const nodes = this.#heapSnapshotOptions.nodes;
762
+ if (nodes) {
763
+ let items = Array.from(nodes.items);
764
+ const firstItem = nodes.items[0];
765
+ if (firstItem) {
766
+ if (isNodeLike(firstItem)) {
767
+ items = items
768
+ .filter(isNodeLike)
769
+ .sort((a, b) => b.retainedSize - a.retainedSize);
770
+ }
771
+ else if (isEdgeLike(firstItem)) {
772
+ items = items.filter(isEdgeLike);
773
+ }
774
+ }
775
+ const paginationData = this.#dataWithPagination(items, this.#heapSnapshotOptions.pagination);
776
+ response.push(HeapSnapshotFormatter.formatNodes(paginationData.items));
777
+ structuredContent.pagination = paginationData.pagination;
778
+ response.push(...paginationData.info);
779
+ structuredContent.heapSnapshotNodes = paginationData.items;
780
+ }
781
+ const retainingPaths = this.#heapSnapshotOptions.retainingPaths;
782
+ if (retainingPaths) {
783
+ response.push('### Retaining Paths');
784
+ const { paths, limitsReached } = retainingPaths;
785
+ if (paths.length === 0) {
786
+ response.push('No retaining paths found.');
787
+ }
788
+ else {
789
+ response.push(HeapSnapshotFormatter.formatRetainingPaths(paths));
790
+ }
791
+ const reached = Object.entries(limitsReached)
792
+ .filter(([, hit]) => hit)
793
+ .map(([limit]) => limit);
794
+ if (reached.length > 0) {
795
+ response.push(`Note: results are truncated, the following limits were reached: ${reached.join(', ')}.`);
796
+ }
797
+ structuredContent.heapSnapshotRetainingPaths =
798
+ retainingPaths;
799
+ }
800
+ const dominators = this.#heapSnapshotOptions.dominators;
801
+ if (dominators) {
802
+ response.push('### Dominator Chain');
803
+ if (dominators.length === 0) {
804
+ response.push('No dominators found.');
805
+ }
806
+ else {
807
+ response.push(HeapSnapshotFormatter.formatDominators(dominators));
808
+ }
809
+ structuredContent.heapSnapshotDominators = dominators;
810
+ }
811
+ }
812
+ if (data.detailedNetworkRequest) {
813
+ response.push(data.detailedNetworkRequest.toStringDetailed());
814
+ structuredContent.networkRequest =
815
+ data.detailedNetworkRequest.toJSONDetailed();
816
+ }
817
+ if (data.detailedConsoleMessage) {
818
+ response.push(data.detailedConsoleMessage.toStringDetailed());
819
+ structuredContent.consoleMessage =
820
+ data.detailedConsoleMessage.toJSONDetailed();
821
+ }
822
+ if (data.extensions) {
823
+ const extensionArray = Array.from(data.extensions.values());
824
+ structuredContent.extensions = extensionArray;
825
+ response.push('## Extensions');
826
+ if (extensionArray.length === 0) {
827
+ response.push('No extensions installed.');
828
+ }
829
+ else {
830
+ const extensionsMessage = extensionArray
831
+ .map(extension => {
832
+ return `id=${extension.id} "${extension.name}" v${extension.version} ${extension.enabled ? 'Enabled' : 'Disabled'}`;
833
+ })
834
+ .join('\n');
835
+ response.push(extensionsMessage);
836
+ }
837
+ }
838
+ if (data.thirdPartyDeveloperTools.length) {
839
+ structuredContent.thirdPartyDeveloperTools =
840
+ data.thirdPartyDeveloperTools;
841
+ response.push('## Third-party developer tools');
842
+ for (const toolGroup of data.thirdPartyDeveloperTools) {
843
+ response.push(`${toolGroup.name}: ${toolGroup.description}`);
844
+ response.push('Available tools:');
845
+ const toolDefinitionsMessage = toolGroup.tools
846
+ .map(tool => {
847
+ return `name="${tool.name}", description="${tool.description}", inputSchema=${JSON.stringify(tool.inputSchema)}`;
848
+ })
849
+ .join('\n');
850
+ response.push(toolDefinitionsMessage);
851
+ }
852
+ }
853
+ if (this.#listWebMcpTools && data.webmcpTools) {
854
+ structuredContent.webmcpTools = data.webmcpTools.map(({ name, description, inputSchema, annotations }) => ({
855
+ name,
856
+ description,
857
+ inputSchema,
858
+ annotations,
859
+ }));
860
+ response.push('## WebMCP tools');
861
+ if (data.webmcpTools.length === 0) {
862
+ response.push('No WebMCP tools available.');
863
+ }
864
+ else {
865
+ const webmcpToolsMessage = data.webmcpTools
866
+ .map(tool => {
867
+ return `name="${tool.name}", description="${tool.description}", inputSchema=${JSON.stringify(tool.inputSchema)}, annotations=${JSON.stringify(tool.annotations)}`;
868
+ })
869
+ .join('\n');
870
+ response.push(webmcpToolsMessage);
871
+ }
872
+ }
873
+ if (this.#networkRequestsOptions?.include && data.networkRequests) {
874
+ const requests = data.networkRequests;
875
+ response.push('## Network requests');
876
+ if (requests.length) {
877
+ const paginationData = this.#dataWithPagination(requests, this.#networkRequestsOptions.pagination);
878
+ structuredContent.pagination = paginationData.pagination;
879
+ response.push(...paginationData.info);
880
+ if (data.networkRequests) {
881
+ structuredContent.networkRequests = paginationData.items.map(i => i.toJSON());
882
+ response.push(...(useToon
883
+ ? [toonEncode(structuredContent.networkRequests)]
884
+ : paginationData.items.map(i => i.toString())));
885
+ }
886
+ }
887
+ else {
888
+ response.push('No requests found.');
889
+ }
890
+ }
891
+ if (this.#consoleDataOptions?.include) {
892
+ const messages = data.consoleMessages ?? [];
893
+ response.push('## Console messages');
894
+ if (messages.length) {
895
+ const grouped = ConsoleFormatter.groupConsecutive(messages);
896
+ const paginationData = this.#dataWithPagination(grouped, this.#consoleDataOptions.pagination);
897
+ structuredContent.pagination = paginationData.pagination;
898
+ structuredContent.consoleMessages = paginationData.items.map(item => item.toJSON());
899
+ response.push(...paginationData.info);
900
+ if (useToon) {
901
+ response.push(toonEncode(structuredContent.consoleMessages));
902
+ }
903
+ else {
904
+ response.push(...paginationData.items.map(item => item.toString()));
905
+ }
906
+ }
907
+ else {
908
+ response.push('<no console messages found>');
909
+ }
910
+ }
911
+ if (data.errorMessage) {
912
+ response.push(`Error: ${data.errorMessage}`);
913
+ structuredContent.errorMessage = data.errorMessage;
914
+ }
915
+ const text = {
916
+ type: 'text',
917
+ text: response.join('\n'),
918
+ };
919
+ const images = this.#images.map(imageData => {
920
+ return {
921
+ type: 'image',
922
+ ...imageData,
923
+ };
924
+ });
925
+ return {
926
+ content: [text, ...images],
927
+ structuredContent,
928
+ };
929
+ }
930
+ #dataWithPagination(data, pagination) {
931
+ const response = [];
932
+ const paginationResult = paginate(data, pagination);
933
+ if (paginationResult.invalidPage) {
934
+ response.push('Invalid page number provided. Showing first page.');
935
+ }
936
+ const { startIndex, endIndex, currentPage, totalPages } = paginationResult;
937
+ response.push(`Showing ${startIndex + 1}-${endIndex} of ${data.length} (Page ${currentPage + 1} of ${totalPages}).`);
938
+ if (pagination) {
939
+ if (paginationResult.hasNextPage) {
940
+ response.push(`Next page: ${currentPage + 1}`);
941
+ }
942
+ if (paginationResult.hasPreviousPage) {
943
+ response.push(`Previous page: ${currentPage - 1}`);
944
+ }
945
+ }
946
+ return {
947
+ info: response,
948
+ items: paginationResult.items,
949
+ pagination: {
950
+ currentPage: paginationResult.currentPage,
951
+ totalPages: paginationResult.totalPages,
952
+ hasNextPage: paginationResult.hasNextPage,
953
+ hasPreviousPage: paginationResult.hasPreviousPage,
954
+ startIndex: paginationResult.startIndex,
955
+ endIndex: paginationResult.endIndex,
956
+ invalidPage: paginationResult.invalidPage,
957
+ },
958
+ };
959
+ }
960
+ resetResponseLineForTesting() {
961
+ this.#textResponseLines = [];
962
+ }
963
+ }
964
+ function truncateTitle(title, maxLength = 50) {
965
+ if (title.length <= maxLength) {
966
+ return title;
967
+ }
968
+ return title.slice(0, maxLength - 3) + '...';
969
+ }
970
+ async function fetchPageTitle(page) {
971
+ return Promise.race([
972
+ page.title().catch(() => ''),
973
+ new Promise(resolve => setTimeout(() => resolve(''), 1000)),
974
+ ]);
975
+ }
976
+ function createStructuredPage(page, context, rawTitle) {
977
+ const isolatedContextName = context.getIsolatedContextName(page);
978
+ const title = truncateTitle(rawTitle);
979
+ const entry = {
980
+ id: context.getPageId(page),
981
+ url: page.url(),
982
+ title,
983
+ selected: context.isPageSelected(page),
984
+ };
985
+ if (isolatedContextName) {
986
+ entry.isolatedContext = isolatedContextName;
987
+ }
988
+ return entry;
989
+ }
990
+ //# sourceMappingURL=McpResponse.js.map