brave-mcp 0.1.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 (280) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +802 -0
  3. package/build/src/DevToolsConnectionAdapter.js +69 -0
  4. package/build/src/DevtoolsUtils.js +294 -0
  5. package/build/src/McpContext.js +676 -0
  6. package/build/src/McpPage.js +108 -0
  7. package/build/src/McpResponse.js +718 -0
  8. package/build/src/Mutex.js +37 -0
  9. package/build/src/PageCollector.js +310 -0
  10. package/build/src/SlimMcpResponse.js +18 -0
  11. package/build/src/WaitForHelper.js +153 -0
  12. package/build/src/bin/brave-devtools-cli-options.js +651 -0
  13. package/build/src/bin/brave-devtools-mcp-cli-options.js +312 -0
  14. package/build/src/bin/brave-devtools-mcp-main.js +35 -0
  15. package/build/src/bin/brave-devtools-mcp.js +22 -0
  16. package/build/src/bin/brave-devtools.js +190 -0
  17. package/build/src/bin/check-latest-version.js +25 -0
  18. package/build/src/bin/cliDefinitions.js +615 -0
  19. package/build/src/browser.js +295 -0
  20. package/build/src/daemon/client.js +152 -0
  21. package/build/src/daemon/daemon.js +202 -0
  22. package/build/src/daemon/types.js +6 -0
  23. package/build/src/daemon/utils.js +109 -0
  24. package/build/src/formatters/ConsoleFormatter.js +241 -0
  25. package/build/src/formatters/IssueFormatter.js +192 -0
  26. package/build/src/formatters/NetworkFormatter.js +218 -0
  27. package/build/src/formatters/SnapshotFormatter.js +134 -0
  28. package/build/src/index.js +216 -0
  29. package/build/src/issue-descriptions.js +39 -0
  30. package/build/src/logger.js +36 -0
  31. package/build/src/polyfill.js +7 -0
  32. package/build/src/telemetry/ClearcutLogger.js +234 -0
  33. package/build/src/telemetry/WatchdogClient.js +60 -0
  34. package/build/src/telemetry/flagUtils.js +45 -0
  35. package/build/src/telemetry/metricUtils.js +14 -0
  36. package/build/src/telemetry/persistence.js +53 -0
  37. package/build/src/telemetry/toolMetricsUtils.js +88 -0
  38. package/build/src/telemetry/types.js +38 -0
  39. package/build/src/telemetry/watchdog/ClearcutSender.js +203 -0
  40. package/build/src/telemetry/watchdog/main.js +127 -0
  41. package/build/src/third_party/devtools-formatter-worker.js +7 -0
  42. package/build/src/third_party/index.js +28 -0
  43. package/build/src/third_party/issue-descriptions/CoepCoopSandboxedIframeCannotNavigateToCoopPage.md +4 -0
  44. package/build/src/third_party/issue-descriptions/CoepCorpNotSameOrigin.md +8 -0
  45. package/build/src/third_party/issue-descriptions/CoepCorpNotSameOriginAfterDefaultedToSameOriginByCoep.md +18 -0
  46. package/build/src/third_party/issue-descriptions/CoepCorpNotSameSite.md +7 -0
  47. package/build/src/third_party/issue-descriptions/CoepFrameResourceNeedsCoepHeader.md +10 -0
  48. package/build/src/third_party/issue-descriptions/CompatibilityModeQuirks.md +5 -0
  49. package/build/src/third_party/issue-descriptions/CookieAttributeValueExceedsMaxSize.md +5 -0
  50. package/build/src/third_party/issue-descriptions/LowTextContrast.md +5 -0
  51. package/build/src/third_party/issue-descriptions/SameSiteExcludeContextDowngradeRead.md +8 -0
  52. package/build/src/third_party/issue-descriptions/SameSiteExcludeContextDowngradeSet.md +8 -0
  53. package/build/src/third_party/issue-descriptions/SameSiteExcludeNavigationContextDowngrade.md +8 -0
  54. package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureErrorRead.md +8 -0
  55. package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureErrorSet.md +8 -0
  56. package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureWarnRead.md +8 -0
  57. package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureWarnSet.md +8 -0
  58. package/build/src/third_party/issue-descriptions/SameSiteUnspecifiedLaxAllowUnsafeRead.md +9 -0
  59. package/build/src/third_party/issue-descriptions/SameSiteUnspecifiedLaxAllowUnsafeSet.md +9 -0
  60. package/build/src/third_party/issue-descriptions/SameSiteWarnCrossDowngradeRead.md +8 -0
  61. package/build/src/third_party/issue-descriptions/SameSiteWarnCrossDowngradeSet.md +8 -0
  62. package/build/src/third_party/issue-descriptions/SameSiteWarnStrictLaxDowngradeStrict.md +8 -0
  63. package/build/src/third_party/issue-descriptions/arInsecureContext.md +7 -0
  64. package/build/src/third_party/issue-descriptions/arInvalidInfoHeader.md +5 -0
  65. package/build/src/third_party/issue-descriptions/arInvalidRegisterOsSourceHeader.md +5 -0
  66. package/build/src/third_party/issue-descriptions/arInvalidRegisterOsTriggerHeader.md +5 -0
  67. package/build/src/third_party/issue-descriptions/arInvalidRegisterSourceHeader.md +5 -0
  68. package/build/src/third_party/issue-descriptions/arInvalidRegisterTriggerHeader.md +5 -0
  69. package/build/src/third_party/issue-descriptions/arNavigationRegistrationUniqueScopeAlreadySet.md +5 -0
  70. package/build/src/third_party/issue-descriptions/arNavigationRegistrationWithoutTransientUserActivation.md +6 -0
  71. package/build/src/third_party/issue-descriptions/arNoRegisterOsSourceHeader.md +5 -0
  72. package/build/src/third_party/issue-descriptions/arNoRegisterOsTriggerHeader.md +5 -0
  73. package/build/src/third_party/issue-descriptions/arNoRegisterSourceHeader.md +5 -0
  74. package/build/src/third_party/issue-descriptions/arNoRegisterTriggerHeader.md +5 -0
  75. package/build/src/third_party/issue-descriptions/arNoWebOrOsSupport.md +4 -0
  76. package/build/src/third_party/issue-descriptions/arOsSourceIgnored.md +18 -0
  77. package/build/src/third_party/issue-descriptions/arOsTriggerIgnored.md +19 -0
  78. package/build/src/third_party/issue-descriptions/arPermissionPolicyDisabled.md +8 -0
  79. package/build/src/third_party/issue-descriptions/arSourceAndTriggerHeaders.md +9 -0
  80. package/build/src/third_party/issue-descriptions/arSourceIgnored.md +13 -0
  81. package/build/src/third_party/issue-descriptions/arTriggerIgnored.md +12 -0
  82. package/build/src/third_party/issue-descriptions/arUntrustworthyReportingOrigin.md +10 -0
  83. package/build/src/third_party/issue-descriptions/arWebAndOsHeaders.md +11 -0
  84. package/build/src/third_party/issue-descriptions/bounceTrackingMitigations.md +3 -0
  85. package/build/src/third_party/issue-descriptions/clientHintMetaTagAllowListInvalidOrigin.md +4 -0
  86. package/build/src/third_party/issue-descriptions/clientHintMetaTagModifiedHTML.md +4 -0
  87. package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidAllowlistItemType.md +12 -0
  88. package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidHeader.md +12 -0
  89. package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidUrlPattern.md +8 -0
  90. package/build/src/third_party/issue-descriptions/connectionAllowlistItemNotInnerList.md +12 -0
  91. package/build/src/third_party/issue-descriptions/connectionAllowlistMoreThanOneList.md +7 -0
  92. package/build/src/third_party/issue-descriptions/connectionAllowlistReportingEndpointNotToken.md +10 -0
  93. package/build/src/third_party/issue-descriptions/cookieCrossSiteRedirectDowngrade.md +12 -0
  94. package/build/src/third_party/issue-descriptions/cookieExcludeBlockedWithinRelatedWebsiteSet.md +4 -0
  95. package/build/src/third_party/issue-descriptions/cookieExcludeDomainNonAscii.md +11 -0
  96. package/build/src/third_party/issue-descriptions/cookieExcludePortMismatch.md +8 -0
  97. package/build/src/third_party/issue-descriptions/cookieExcludeSchemeMismatch.md +7 -0
  98. package/build/src/third_party/issue-descriptions/cookieExcludeThirdPartyPhaseoutRead.md +6 -0
  99. package/build/src/third_party/issue-descriptions/cookieExcludeThirdPartyPhaseoutSet.md +6 -0
  100. package/build/src/third_party/issue-descriptions/cookieWarnDomainNonAscii.md +11 -0
  101. package/build/src/third_party/issue-descriptions/cookieWarnMetadataGrantRead.md +4 -0
  102. package/build/src/third_party/issue-descriptions/cookieWarnMetadataGrantSet.md +4 -0
  103. package/build/src/third_party/issue-descriptions/cookieWarnThirdPartyPhaseoutRead.md +6 -0
  104. package/build/src/third_party/issue-descriptions/cookieWarnThirdPartyPhaseoutSet.md +6 -0
  105. package/build/src/third_party/issue-descriptions/corsAllowCredentialsRequired.md +6 -0
  106. package/build/src/third_party/issue-descriptions/corsDisabledScheme.md +7 -0
  107. package/build/src/third_party/issue-descriptions/corsDisallowedByMode.md +7 -0
  108. package/build/src/third_party/issue-descriptions/corsHeaderDisallowedByPreflightResponse.md +5 -0
  109. package/build/src/third_party/issue-descriptions/corsInvalidHeaderValues.md +7 -0
  110. package/build/src/third_party/issue-descriptions/corsLocalNetworkAccessPermissionDenied.md +19 -0
  111. package/build/src/third_party/issue-descriptions/corsMethodDisallowedByPreflightResponse.md +5 -0
  112. package/build/src/third_party/issue-descriptions/corsNoCorsRedirectModeNotFollow.md +5 -0
  113. package/build/src/third_party/issue-descriptions/corsOriginMismatch.md +6 -0
  114. package/build/src/third_party/issue-descriptions/corsPreflightResponseInvalid.md +5 -0
  115. package/build/src/third_party/issue-descriptions/corsRedirectContainsCredentials.md +5 -0
  116. package/build/src/third_party/issue-descriptions/corsWildcardOriginNotAllowed.md +8 -0
  117. package/build/src/third_party/issue-descriptions/cspEvalViolation.md +9 -0
  118. package/build/src/third_party/issue-descriptions/cspInlineViolation.md +10 -0
  119. package/build/src/third_party/issue-descriptions/cspTrustedTypesPolicyViolation.md +5 -0
  120. package/build/src/third_party/issue-descriptions/cspTrustedTypesSinkViolation.md +8 -0
  121. package/build/src/third_party/issue-descriptions/cspURLViolation.md +10 -0
  122. package/build/src/third_party/issue-descriptions/deprecation.md +3 -0
  123. package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsHttpNotFound.md +1 -0
  124. package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsInvalidResponse.md +1 -0
  125. package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsNoResponse.md +1 -0
  126. package/build/src/third_party/issue-descriptions/federatedAuthRequestApprovalDeclined.md +1 -0
  127. package/build/src/third_party/issue-descriptions/federatedAuthRequestCanceled.md +1 -0
  128. package/build/src/third_party/issue-descriptions/federatedAuthRequestErrorFetchingSignin.md +1 -0
  129. package/build/src/third_party/issue-descriptions/federatedAuthRequestErrorIdToken.md +1 -0
  130. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenHttpNotFound.md +1 -0
  131. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenInvalidRequest.md +1 -0
  132. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenInvalidResponse.md +1 -0
  133. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenNoResponse.md +1 -0
  134. package/build/src/third_party/issue-descriptions/federatedAuthRequestInvalidSigninResponse.md +1 -0
  135. package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestHttpNotFound.md +1 -0
  136. package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestInvalidResponse.md +1 -0
  137. package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestNoResponse.md +1 -0
  138. package/build/src/third_party/issue-descriptions/federatedAuthRequestTooManyRequests.md +1 -0
  139. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestInvalidAccountsResponse.md +1 -0
  140. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestInvalidConfigOrWellKnown.md +1 -0
  141. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoAccountSharingPermission.md +1 -0
  142. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoApiPermission.md +1 -0
  143. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoReturningUserFromFetchedAccounts.md +1 -0
  144. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotIframe.md +1 -0
  145. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotPotentiallyTrustworthy.md +1 -0
  146. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotSameOrigin.md +1 -0
  147. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotSignedInWithIdp.md +1 -0
  148. package/build/src/third_party/issue-descriptions/fetchingPartitionedBlobURL.md +7 -0
  149. package/build/src/third_party/issue-descriptions/genericFormAriaLabelledByToNonExistingIdError.md +8 -0
  150. package/build/src/third_party/issue-descriptions/genericFormAutocompleteAttributeEmptyError.md +5 -0
  151. package/build/src/third_party/issue-descriptions/genericFormDuplicateIdForInputError.md +5 -0
  152. package/build/src/third_party/issue-descriptions/genericFormEmptyIdAndNameAttributesForInputError.md +5 -0
  153. package/build/src/third_party/issue-descriptions/genericFormInputAssignedAutocompleteValueToIdOrNameAttributeError.md +5 -0
  154. package/build/src/third_party/issue-descriptions/genericFormInputHasWrongButWellIntendedAutocompleteValueError.md +5 -0
  155. package/build/src/third_party/issue-descriptions/genericFormInputWithNoLabelError.md +5 -0
  156. package/build/src/third_party/issue-descriptions/genericFormLabelForMatchesNonExistingIdError.md +5 -0
  157. package/build/src/third_party/issue-descriptions/genericFormLabelForNameError.md +5 -0
  158. package/build/src/third_party/issue-descriptions/genericFormLabelHasNeitherForNorNestedInputError.md +5 -0
  159. package/build/src/third_party/issue-descriptions/genericNavigationEntryMarkedSkippable.md +7 -0
  160. package/build/src/third_party/issue-descriptions/genericResponseWasBlockedByORB.md +4 -0
  161. package/build/src/third_party/issue-descriptions/heavyAd.md +10 -0
  162. package/build/src/third_party/issue-descriptions/mixedContent.md +5 -0
  163. package/build/src/third_party/issue-descriptions/navigatingPartitionedBlobURL.md +5 -0
  164. package/build/src/third_party/issue-descriptions/permissionElementActivationDisabled.md +7 -0
  165. package/build/src/third_party/issue-descriptions/permissionElementActivationDisabledWithOccluder.md +9 -0
  166. package/build/src/third_party/issue-descriptions/permissionElementActivationDisabledWithOccluderParent.md +9 -0
  167. package/build/src/third_party/issue-descriptions/permissionElementCspFrameAncestorsMissing.md +5 -0
  168. package/build/src/third_party/issue-descriptions/permissionElementFencedFrameDisallowed.md +5 -0
  169. package/build/src/third_party/issue-descriptions/permissionElementFontSizeTooLarge.md +5 -0
  170. package/build/src/third_party/issue-descriptions/permissionElementFontSizeTooSmall.md +5 -0
  171. package/build/src/third_party/issue-descriptions/permissionElementGeolocationDeprecated.md +5 -0
  172. package/build/src/third_party/issue-descriptions/permissionElementInsetBoxShadowUnsupported.md +5 -0
  173. package/build/src/third_party/issue-descriptions/permissionElementInvalidDisplayStyle.md +5 -0
  174. package/build/src/third_party/issue-descriptions/permissionElementInvalidSizeValue.md +5 -0
  175. package/build/src/third_party/issue-descriptions/permissionElementInvalidType.md +5 -0
  176. package/build/src/third_party/issue-descriptions/permissionElementInvalidTypeActivation.md +5 -0
  177. package/build/src/third_party/issue-descriptions/permissionElementLowContrast.md +5 -0
  178. package/build/src/third_party/issue-descriptions/permissionElementNonOpaqueColor.md +5 -0
  179. package/build/src/third_party/issue-descriptions/permissionElementPaddingBottomUnsupported.md +6 -0
  180. package/build/src/third_party/issue-descriptions/permissionElementPaddingRightUnsupported.md +6 -0
  181. package/build/src/third_party/issue-descriptions/permissionElementPermissionsPolicyBlocked.md +5 -0
  182. package/build/src/third_party/issue-descriptions/permissionElementRegistrationFailed.md +5 -0
  183. package/build/src/third_party/issue-descriptions/permissionElementRequestInProgress.md +5 -0
  184. package/build/src/third_party/issue-descriptions/permissionElementSecurityChecksFailed.md +5 -0
  185. package/build/src/third_party/issue-descriptions/permissionElementTypeNotSupported.md +5 -0
  186. package/build/src/third_party/issue-descriptions/permissionElementUntrustedEvent.md +7 -0
  187. package/build/src/third_party/issue-descriptions/placeholderDescriptionForInvisibleIssues.md +3 -0
  188. package/build/src/third_party/issue-descriptions/propertyRuleInvalidNameIssue.md +3 -0
  189. package/build/src/third_party/issue-descriptions/propertyRuleIssue.md +7 -0
  190. package/build/src/third_party/issue-descriptions/selectElementAccessibilityDisallowedOptGroupChild.md +7 -0
  191. package/build/src/third_party/issue-descriptions/selectElementAccessibilityDisallowedSelectChild.md +7 -0
  192. package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentAttributesSelectDescendant.md +3 -0
  193. package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentLegendChild.md +3 -0
  194. package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentOptionChild.md +3 -0
  195. package/build/src/third_party/issue-descriptions/selectElementAccessibilityNonPhrasingContentOptionChild.md +3 -0
  196. package/build/src/third_party/issue-descriptions/selectivePermissionsIntervention.md +7 -0
  197. package/build/src/third_party/issue-descriptions/sharedArrayBuffer.md +7 -0
  198. package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorCrossOriginNoCorsRequest.md +1 -0
  199. package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorDictionaryLoadFailure.md +3 -0
  200. package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorMatchingDictionaryNotUsed.md +3 -0
  201. package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorUnexpectedContentDictionaryHeader.md +1 -0
  202. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorCossOriginNoCorsRequest.md +1 -0
  203. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorDisallowedBySettings.md +1 -0
  204. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorExpiredResponse.md +3 -0
  205. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorFeatureDisabled.md +3 -0
  206. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInsufficientResources.md +1 -0
  207. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInvalidMatchField.md +1 -0
  208. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInvalidStructuredHeader.md +1 -0
  209. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInvalidTTLField.md +1 -0
  210. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNavigationRequest.md +3 -0
  211. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNoMatchField.md +1 -0
  212. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonIntegerTTLField.md +1 -0
  213. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonListMatchDestField.md +1 -0
  214. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonSecureContext.md +3 -0
  215. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonStringIdField.md +1 -0
  216. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonStringInMatchDestList.md +1 -0
  217. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonStringMatchField.md +1 -0
  218. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonTokenTypeField.md +1 -0
  219. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorRequestAborted.md +1 -0
  220. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorShuttingDown.md +1 -0
  221. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorTooLongIdField.md +3 -0
  222. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorUnsupportedType.md +3 -0
  223. package/build/src/third_party/issue-descriptions/sriInvalidSignatureHeader.md +14 -0
  224. package/build/src/third_party/issue-descriptions/sriInvalidSignatureInputHeader.md +15 -0
  225. package/build/src/third_party/issue-descriptions/sriMissingSignatureHeader.md +8 -0
  226. package/build/src/third_party/issue-descriptions/sriMissingSignatureInputHeader.md +7 -0
  227. package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsIncorrectLength.md +11 -0
  228. package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsNotByteSequence.md +14 -0
  229. package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsParameterized.md +15 -0
  230. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidComponentName.md +8 -0
  231. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidComponentType.md +13 -0
  232. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidDerivedComponentParameter.md +4 -0
  233. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidHeaderComponentParameter.md +5 -0
  234. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidParameter.md +11 -0
  235. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderKeyIdLength.md +12 -0
  236. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderMissingLabel.md +6 -0
  237. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderMissingRequiredParameters.md +8 -0
  238. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderValueMissingComponents.md +11 -0
  239. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderValueNotInnerList.md +11 -0
  240. package/build/src/third_party/issue-descriptions/sriValidationFailedIntegrityMismatch.md +10 -0
  241. package/build/src/third_party/issue-descriptions/sriValidationFailedInvalidLength.md +5 -0
  242. package/build/src/third_party/issue-descriptions/sriValidationFailedSignatureExpired.md +6 -0
  243. package/build/src/third_party/issue-descriptions/sriValidationFailedSignatureMismatch.md +11 -0
  244. package/build/src/third_party/issue-descriptions/stylesheetLateImport.md +4 -0
  245. package/build/src/third_party/issue-descriptions/stylesheetRequestFailed.md +3 -0
  246. package/build/src/third_party/issue-descriptions/summaryElementAccessibilityInteractiveContentSummaryDescendant.md +3 -0
  247. package/build/src/third_party/issue-descriptions/unencodedDigestIncorrectDigestLength.md +12 -0
  248. package/build/src/third_party/issue-descriptions/unencodedDigestIncorrectDigestType.md +17 -0
  249. package/build/src/third_party/issue-descriptions/unencodedDigestMalformedDictionary.md +14 -0
  250. package/build/src/third_party/issue-descriptions/unencodedDigestUnknownAlgorithm.md +15 -0
  251. package/build/src/third_party/lighthouse-devtools-mcp-bundle.js +59418 -0
  252. package/build/src/tools/ToolDefinition.js +72 -0
  253. package/build/src/tools/categories.js +26 -0
  254. package/build/src/tools/console.js +85 -0
  255. package/build/src/tools/emulation.js +55 -0
  256. package/build/src/tools/extensions.js +96 -0
  257. package/build/src/tools/inPage.js +105 -0
  258. package/build/src/tools/input.js +376 -0
  259. package/build/src/tools/lighthouse.js +123 -0
  260. package/build/src/tools/memory.js +28 -0
  261. package/build/src/tools/network.js +120 -0
  262. package/build/src/tools/pages.js +336 -0
  263. package/build/src/tools/performance.js +190 -0
  264. package/build/src/tools/screencast.js +79 -0
  265. package/build/src/tools/screenshot.js +84 -0
  266. package/build/src/tools/script.js +125 -0
  267. package/build/src/tools/slim/tools.js +81 -0
  268. package/build/src/tools/snapshot.js +56 -0
  269. package/build/src/tools/tools.js +53 -0
  270. package/build/src/trace-processing/parse.js +84 -0
  271. package/build/src/types.js +6 -0
  272. package/build/src/utils/ExtensionRegistry.js +35 -0
  273. package/build/src/utils/check-for-updates.js +72 -0
  274. package/build/src/utils/files.js +19 -0
  275. package/build/src/utils/keyboard.js +296 -0
  276. package/build/src/utils/pagination.js +49 -0
  277. package/build/src/utils/string.js +36 -0
  278. package/build/src/utils/types.js +6 -0
  279. package/build/src/version.js +6 -0
  280. package/package.json +87 -0
@@ -0,0 +1,718 @@
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 { IssueFormatter } from './formatters/IssueFormatter.js';
8
+ import { NetworkFormatter } from './formatters/NetworkFormatter.js';
9
+ import { SnapshotFormatter } from './formatters/SnapshotFormatter.js';
10
+ import { UncaughtError } from './PageCollector.js';
11
+ import { DevTools } from './third_party/index.js';
12
+ import { handleDialog } from './tools/pages.js';
13
+ import { getInsightOutput, getTraceSummary } from './trace-processing/parse.js';
14
+ import { paginate } from './utils/pagination.js';
15
+ export function replaceHtmlElementsWithUids(schema) {
16
+ if (typeof schema === 'boolean') {
17
+ return;
18
+ }
19
+ let isHtmlElement = false;
20
+ for (const [key, value] of Object.entries(schema)) {
21
+ if (key === 'x-mcp-type' && value === 'HTMLElement') {
22
+ isHtmlElement = true;
23
+ break;
24
+ }
25
+ }
26
+ if (isHtmlElement) {
27
+ schema.properties = { uid: { type: 'string' } };
28
+ schema.required = ['uid'];
29
+ }
30
+ if (schema.properties) {
31
+ for (const key of Object.keys(schema.properties)) {
32
+ replaceHtmlElementsWithUids(schema.properties[key]);
33
+ }
34
+ }
35
+ if (schema.items) {
36
+ if (Array.isArray(schema.items)) {
37
+ for (const item of schema.items) {
38
+ replaceHtmlElementsWithUids(item);
39
+ }
40
+ }
41
+ else {
42
+ replaceHtmlElementsWithUids(schema.items);
43
+ }
44
+ }
45
+ if (schema.anyOf) {
46
+ for (const s of schema.anyOf) {
47
+ replaceHtmlElementsWithUids(s);
48
+ }
49
+ }
50
+ if (schema.allOf) {
51
+ for (const s of schema.allOf) {
52
+ replaceHtmlElementsWithUids(s);
53
+ }
54
+ }
55
+ if (schema.oneOf) {
56
+ for (const s of schema.oneOf) {
57
+ replaceHtmlElementsWithUids(s);
58
+ }
59
+ }
60
+ }
61
+ async function getToolGroup(page) {
62
+ // Check if there is a `devtoolstooldiscovery` event listener
63
+ const windowHandle = await page.pptrPage.evaluateHandle(() => window);
64
+ // @ts-expect-error internal API
65
+ const client = page.pptrPage._client();
66
+ const { listeners } = await client.send('DOMDebugger.getEventListeners', {
67
+ objectId: windowHandle.remoteObject().objectId,
68
+ });
69
+ if (listeners.find(l => l.type === 'devtoolstooldiscovery') === undefined) {
70
+ return;
71
+ }
72
+ const toolGroup = await page.pptrPage.evaluate(() => {
73
+ return new Promise(resolve => {
74
+ const event = new CustomEvent('devtoolstooldiscovery');
75
+ // @ts-expect-error Adding custom property
76
+ event.respondWith = (toolGroup) => {
77
+ if (!window.__dtmcp) {
78
+ window.__dtmcp = {};
79
+ }
80
+ window.__dtmcp.toolGroup = toolGroup;
81
+ // When receiving a toolGroup for the first time, expose a simple execution helper
82
+ if (!window.__dtmcp.executeTool) {
83
+ window.__dtmcp.executeTool = async (toolName, args) => {
84
+ if (!window.__dtmcp?.toolGroup) {
85
+ throw new Error('No tools found on the page');
86
+ }
87
+ const tool = window.__dtmcp.toolGroup.tools.find(t => t.name === toolName);
88
+ if (!tool) {
89
+ throw new Error(`Tool ${toolName} not found`);
90
+ }
91
+ return await tool.execute(args);
92
+ };
93
+ }
94
+ resolve(toolGroup);
95
+ };
96
+ window.dispatchEvent(event);
97
+ // If the page does not synchronously call `event.respondWith`, return instead of timing out
98
+ setTimeout(() => {
99
+ resolve(undefined);
100
+ }, 0);
101
+ });
102
+ });
103
+ for (const tool of toolGroup?.tools ?? []) {
104
+ replaceHtmlElementsWithUids(tool.inputSchema);
105
+ }
106
+ return toolGroup;
107
+ }
108
+ export class McpResponse {
109
+ #includePages = false;
110
+ #includeExtensionServiceWorkers = false;
111
+ #includeExtensionPages = false;
112
+ #snapshotParams;
113
+ #attachedNetworkRequestId;
114
+ #attachedNetworkRequestOptions;
115
+ #attachedConsoleMessageId;
116
+ #attachedTraceSummary;
117
+ #attachedTraceInsight;
118
+ #attachedLighthouseResult;
119
+ #textResponseLines = [];
120
+ #images = [];
121
+ #networkRequestsOptions;
122
+ #consoleDataOptions;
123
+ #listExtensions;
124
+ #listInPageTools;
125
+ #devToolsData;
126
+ #tabId;
127
+ #args;
128
+ #page;
129
+ constructor(args) {
130
+ this.#args = args;
131
+ }
132
+ setPage(page) {
133
+ this.#page = page;
134
+ }
135
+ attachDevToolsData(data) {
136
+ this.#devToolsData = data;
137
+ }
138
+ setTabId(tabId) {
139
+ this.#tabId = tabId;
140
+ }
141
+ setIncludePages(value) {
142
+ this.#includePages = value;
143
+ if (this.#args.categoryExtensions) {
144
+ this.#includeExtensionServiceWorkers = value;
145
+ this.#includeExtensionPages = value;
146
+ }
147
+ }
148
+ includeSnapshot(params) {
149
+ this.#snapshotParams = params ?? {
150
+ verbose: false,
151
+ };
152
+ }
153
+ setListExtensions() {
154
+ this.#listExtensions = true;
155
+ }
156
+ setListInPageTools() {
157
+ if (this.#args.categoryInPageTools) {
158
+ this.#listInPageTools = true;
159
+ }
160
+ }
161
+ setIncludeNetworkRequests(value, options) {
162
+ if (!value) {
163
+ this.#networkRequestsOptions = undefined;
164
+ return;
165
+ }
166
+ this.#networkRequestsOptions = {
167
+ include: value,
168
+ pagination: options?.pageSize || options?.pageIdx
169
+ ? {
170
+ pageSize: options.pageSize,
171
+ pageIdx: options.pageIdx,
172
+ }
173
+ : undefined,
174
+ resourceTypes: options?.resourceTypes,
175
+ includePreservedRequests: options?.includePreservedRequests,
176
+ networkRequestIdInDevToolsUI: options?.networkRequestIdInDevToolsUI,
177
+ };
178
+ }
179
+ setIncludeConsoleData(value, options) {
180
+ if (!value) {
181
+ this.#consoleDataOptions = undefined;
182
+ return;
183
+ }
184
+ this.#consoleDataOptions = {
185
+ include: value,
186
+ pagination: options?.pageSize || options?.pageIdx
187
+ ? {
188
+ pageSize: options.pageSize,
189
+ pageIdx: options.pageIdx,
190
+ }
191
+ : undefined,
192
+ types: options?.types,
193
+ includePreservedMessages: options?.includePreservedMessages,
194
+ };
195
+ }
196
+ attachNetworkRequest(reqId, options) {
197
+ this.#attachedNetworkRequestId = reqId;
198
+ this.#attachedNetworkRequestOptions = options;
199
+ }
200
+ attachConsoleMessage(msgid) {
201
+ this.#attachedConsoleMessageId = msgid;
202
+ }
203
+ attachTraceSummary(result) {
204
+ this.#attachedTraceSummary = result;
205
+ }
206
+ attachTraceInsight(trace, insightSetId, insightName) {
207
+ this.#attachedTraceInsight = {
208
+ trace,
209
+ insightSetId,
210
+ insightName,
211
+ };
212
+ }
213
+ attachLighthouseResult(result) {
214
+ this.#attachedLighthouseResult = result;
215
+ }
216
+ get includePages() {
217
+ return this.#includePages;
218
+ }
219
+ get attachedTraceSummary() {
220
+ return this.#attachedTraceSummary;
221
+ }
222
+ get attachedTracedInsight() {
223
+ return this.#attachedTraceInsight;
224
+ }
225
+ get attachedLighthouseResult() {
226
+ return this.#attachedLighthouseResult;
227
+ }
228
+ get includeNetworkRequests() {
229
+ return this.#networkRequestsOptions?.include ?? false;
230
+ }
231
+ get includeConsoleData() {
232
+ return this.#consoleDataOptions?.include ?? false;
233
+ }
234
+ get attachedNetworkRequestId() {
235
+ return this.#attachedNetworkRequestId;
236
+ }
237
+ get networkRequestsPageIdx() {
238
+ return this.#networkRequestsOptions?.pagination?.pageIdx;
239
+ }
240
+ get consoleMessagesPageIdx() {
241
+ return this.#consoleDataOptions?.pagination?.pageIdx;
242
+ }
243
+ get consoleMessagesTypes() {
244
+ return this.#consoleDataOptions?.types;
245
+ }
246
+ appendResponseLine(value) {
247
+ this.#textResponseLines.push(value);
248
+ }
249
+ attachImage(value) {
250
+ this.#images.push(value);
251
+ }
252
+ get responseLines() {
253
+ return this.#textResponseLines;
254
+ }
255
+ get images() {
256
+ return this.#images;
257
+ }
258
+ get snapshotParams() {
259
+ return this.#snapshotParams;
260
+ }
261
+ async handle(toolName, context) {
262
+ if (this.#includePages) {
263
+ await context.createPagesSnapshot();
264
+ }
265
+ if (this.#includeExtensionServiceWorkers) {
266
+ await context.createExtensionServiceWorkersSnapshot();
267
+ }
268
+ let snapshot;
269
+ if (this.#snapshotParams) {
270
+ if (!this.#page) {
271
+ throw new Error('Response must have a page');
272
+ }
273
+ await context.createTextSnapshot(this.#page, this.#snapshotParams.verbose, this.#devToolsData);
274
+ const textSnapshot = this.#page.textSnapshot;
275
+ if (textSnapshot) {
276
+ const formatter = new SnapshotFormatter(textSnapshot);
277
+ if (this.#snapshotParams.filePath) {
278
+ await context.saveFile(new TextEncoder().encode(formatter.toString()), this.#snapshotParams.filePath);
279
+ snapshot = this.#snapshotParams.filePath;
280
+ }
281
+ else {
282
+ snapshot = formatter;
283
+ }
284
+ }
285
+ }
286
+ let detailedNetworkRequest;
287
+ if (this.#attachedNetworkRequestId) {
288
+ if (!this.#page) {
289
+ throw new Error(`Response must have an McpPage`);
290
+ }
291
+ const request = context.getNetworkRequestById(this.#page, this.#attachedNetworkRequestId);
292
+ const formatter = await NetworkFormatter.from(request, {
293
+ requestId: this.#attachedNetworkRequestId,
294
+ requestIdResolver: req => context.getNetworkRequestStableId(req),
295
+ fetchData: true,
296
+ requestFilePath: this.#attachedNetworkRequestOptions?.requestFilePath,
297
+ responseFilePath: this.#attachedNetworkRequestOptions?.responseFilePath,
298
+ saveFile: (data, filename) => context.saveFile(data, filename),
299
+ });
300
+ detailedNetworkRequest = formatter;
301
+ }
302
+ let detailedConsoleMessage;
303
+ if (this.#attachedConsoleMessageId) {
304
+ if (!this.#page) {
305
+ throw new Error(`Response must have an McpPage`);
306
+ }
307
+ const message = context.getConsoleMessageById(this.#page, this.#attachedConsoleMessageId);
308
+ const consoleMessageStableId = this.#attachedConsoleMessageId;
309
+ if ('args' in message || message instanceof UncaughtError) {
310
+ const consoleMessage = message;
311
+ const devTools = context.getDevToolsUniverse(this.#page);
312
+ detailedConsoleMessage = await ConsoleFormatter.from(consoleMessage, {
313
+ id: consoleMessageStableId,
314
+ fetchDetailedData: true,
315
+ devTools: devTools ?? undefined,
316
+ });
317
+ }
318
+ else if (message instanceof DevTools.AggregatedIssue) {
319
+ const formatter = new IssueFormatter(message, {
320
+ id: consoleMessageStableId,
321
+ requestIdResolver: context.resolveCdpRequestId.bind(context, this.#page),
322
+ elementIdResolver: context.resolveCdpElementId.bind(context, this.#page),
323
+ });
324
+ if (!formatter.isValid()) {
325
+ throw new Error("Can't provide details for the msgid " + consoleMessageStableId);
326
+ }
327
+ detailedConsoleMessage = formatter;
328
+ }
329
+ }
330
+ let extensions;
331
+ if (this.#listExtensions) {
332
+ extensions = context.listExtensions();
333
+ }
334
+ let inPageTools;
335
+ if (this.#listInPageTools) {
336
+ const page = this.#page ?? context.getSelectedMcpPage();
337
+ inPageTools = await getToolGroup(page);
338
+ page.inPageTools = inPageTools;
339
+ }
340
+ let consoleMessages;
341
+ if (this.#consoleDataOptions?.include) {
342
+ if (!this.#page) {
343
+ throw new Error(`Response must have an McpPage`);
344
+ }
345
+ const page = this.#page;
346
+ let messages = context.getConsoleData(this.#page, this.#consoleDataOptions.includePreservedMessages);
347
+ if (this.#consoleDataOptions.types?.length) {
348
+ const normalizedTypes = new Set(this.#consoleDataOptions.types);
349
+ messages = messages.filter(message => {
350
+ if ('type' in message) {
351
+ return normalizedTypes.has(message.type());
352
+ }
353
+ if (message instanceof DevTools.AggregatedIssue) {
354
+ return normalizedTypes.has('issue');
355
+ }
356
+ return normalizedTypes.has('error');
357
+ });
358
+ }
359
+ consoleMessages = (await Promise.all(messages.map(async (item) => {
360
+ const consoleMessageStableId = context.getConsoleMessageStableId(item);
361
+ if ('args' in item || item instanceof UncaughtError) {
362
+ const consoleMessage = item;
363
+ const devTools = context.getDevToolsUniverse(page);
364
+ return await ConsoleFormatter.from(consoleMessage, {
365
+ id: consoleMessageStableId,
366
+ fetchDetailedData: false,
367
+ devTools: devTools ?? undefined,
368
+ });
369
+ }
370
+ if (item instanceof DevTools.AggregatedIssue) {
371
+ const formatter = new IssueFormatter(item, {
372
+ id: consoleMessageStableId,
373
+ });
374
+ if (!formatter.isValid()) {
375
+ return null;
376
+ }
377
+ return formatter;
378
+ }
379
+ return null;
380
+ }))).filter(item => item !== null);
381
+ }
382
+ let networkRequests;
383
+ if (this.#networkRequestsOptions?.include) {
384
+ if (!this.#page) {
385
+ throw new Error(`Response must have an McpPage`);
386
+ }
387
+ let requests = context.getNetworkRequests(this.#page, this.#networkRequestsOptions?.includePreservedRequests);
388
+ // Apply resource type filtering if specified
389
+ if (this.#networkRequestsOptions.resourceTypes?.length) {
390
+ const normalizedTypes = new Set(this.#networkRequestsOptions.resourceTypes);
391
+ requests = requests.filter(request => {
392
+ const type = request.resourceType();
393
+ return normalizedTypes.has(type);
394
+ });
395
+ }
396
+ if (requests.length) {
397
+ networkRequests = await Promise.all(requests.map(request => NetworkFormatter.from(request, {
398
+ requestId: context.getNetworkRequestStableId(request),
399
+ selectedInDevToolsUI: context.getNetworkRequestStableId(request) ===
400
+ this.#networkRequestsOptions?.networkRequestIdInDevToolsUI,
401
+ fetchData: false,
402
+ saveFile: (data, filename) => context.saveFile(data, filename),
403
+ })));
404
+ }
405
+ }
406
+ return this.format(toolName, context, {
407
+ detailedConsoleMessage,
408
+ consoleMessages,
409
+ snapshot,
410
+ detailedNetworkRequest,
411
+ networkRequests,
412
+ traceInsight: this.#attachedTraceInsight,
413
+ traceSummary: this.#attachedTraceSummary,
414
+ extensions,
415
+ lighthouseResult: this.#attachedLighthouseResult,
416
+ inPageTools,
417
+ });
418
+ }
419
+ format(toolName, context, data) {
420
+ const structuredContent = {};
421
+ const response = [];
422
+ if (this.#textResponseLines.length) {
423
+ structuredContent.message = this.#textResponseLines.join('\n');
424
+ response.push(...this.#textResponseLines);
425
+ }
426
+ const networkConditions = this.#page?.networkConditions;
427
+ if (networkConditions) {
428
+ const timeout = this.#page.pptrPage.getDefaultNavigationTimeout();
429
+ response.push(`Emulating network conditions: ${networkConditions}`);
430
+ response.push(`Default navigation timeout set to ${timeout} ms`);
431
+ structuredContent.networkConditions = networkConditions;
432
+ structuredContent.navigationTimeout = timeout;
433
+ }
434
+ const viewport = this.#page?.viewport;
435
+ if (viewport) {
436
+ response.push(`Emulating viewport: ${JSON.stringify(viewport)}`);
437
+ structuredContent.viewport = viewport;
438
+ }
439
+ const userAgent = this.#page?.userAgent;
440
+ if (userAgent) {
441
+ response.push(`Emulating user agent: ${userAgent}`);
442
+ structuredContent.userAgent = userAgent;
443
+ }
444
+ const cpuThrottlingRate = this.#page?.cpuThrottlingRate ?? 1;
445
+ if (cpuThrottlingRate > 1) {
446
+ response.push(`Emulating CPU throttling: ${cpuThrottlingRate}x slowdown`);
447
+ structuredContent.cpuThrottlingRate = cpuThrottlingRate;
448
+ }
449
+ const colorScheme = this.#page?.colorScheme;
450
+ if (colorScheme) {
451
+ response.push(`Emulating color scheme: ${colorScheme}`);
452
+ structuredContent.colorScheme = colorScheme;
453
+ }
454
+ const dialog = this.#page?.getDialog();
455
+ if (dialog) {
456
+ const defaultValueIfNeeded = dialog.type() === 'prompt'
457
+ ? ` (default value: "${dialog.defaultValue()}")`
458
+ : '';
459
+ response.push(`# Open dialog
460
+ ${dialog.type()}: ${dialog.message()}${defaultValueIfNeeded}.
461
+ Call ${handleDialog.name} to handle it before continuing.`);
462
+ structuredContent.dialog = {
463
+ type: dialog.type(),
464
+ message: dialog.message(),
465
+ defaultValue: dialog.defaultValue(),
466
+ };
467
+ }
468
+ if (this.#includePages) {
469
+ const allPages = context.getPages();
470
+ const { regularPages, extensionPages } = allPages.reduce((acc, page) => {
471
+ if (page.url().startsWith('chrome-extension://')) {
472
+ acc.extensionPages.push(page);
473
+ }
474
+ else {
475
+ acc.regularPages.push(page);
476
+ }
477
+ return acc;
478
+ }, { regularPages: [], extensionPages: [] });
479
+ if (regularPages.length) {
480
+ const parts = [`## Pages`];
481
+ const structuredPages = [];
482
+ for (const page of regularPages) {
483
+ const isolatedContextName = context.getIsolatedContextName(page);
484
+ const contextLabel = isolatedContextName
485
+ ? ` isolatedContext=${isolatedContextName}`
486
+ : '';
487
+ parts.push(`${context.getPageId(page)}: ${page.url()}${context.isPageSelected(page) ? ' [selected]' : ''}${contextLabel}`);
488
+ structuredPages.push(createStructuredPage(page, context));
489
+ }
490
+ response.push(...parts);
491
+ structuredContent.pages = structuredPages;
492
+ }
493
+ if (this.#includeExtensionPages) {
494
+ if (extensionPages.length) {
495
+ response.push(`## Extension Pages`);
496
+ const structuredExtensionPages = [];
497
+ for (const page of extensionPages) {
498
+ const isolatedContextName = context.getIsolatedContextName(page);
499
+ const contextLabel = isolatedContextName
500
+ ? ` isolatedContext=${isolatedContextName}`
501
+ : '';
502
+ response.push(`${context.getPageId(page)}: ${page.url()}${context.isPageSelected(page) ? ' [selected]' : ''}${contextLabel}`);
503
+ structuredExtensionPages.push(createStructuredPage(page, context));
504
+ }
505
+ structuredContent.extensionPages = structuredExtensionPages;
506
+ }
507
+ }
508
+ }
509
+ if (this.#includeExtensionServiceWorkers) {
510
+ if (context.getExtensionServiceWorkers().length) {
511
+ response.push(`## Extension Service Workers`);
512
+ }
513
+ for (const extensionServiceWorker of context.getExtensionServiceWorkers()) {
514
+ response.push(`${extensionServiceWorker.id}: ${extensionServiceWorker.url}`);
515
+ }
516
+ structuredContent.extensionServiceWorkers = context
517
+ .getExtensionServiceWorkers()
518
+ .map(extensionServiceWorker => {
519
+ return {
520
+ id: extensionServiceWorker.id,
521
+ url: extensionServiceWorker.url,
522
+ };
523
+ });
524
+ }
525
+ if (this.#tabId) {
526
+ structuredContent.tabId = this.#tabId;
527
+ }
528
+ if (data.traceSummary) {
529
+ const summary = getTraceSummary(data.traceSummary);
530
+ response.push(summary);
531
+ structuredContent.traceSummary = summary;
532
+ structuredContent.traceInsights = [];
533
+ for (const insightSet of data.traceSummary.insights?.values() ?? []) {
534
+ for (const [insightName, model] of Object.entries(insightSet.model)) {
535
+ structuredContent.traceInsights.push({
536
+ insightName,
537
+ insightKey: model.insightKey,
538
+ });
539
+ }
540
+ }
541
+ }
542
+ if (data.traceInsight) {
543
+ const insightOutput = getInsightOutput(data.traceInsight.trace, data.traceInsight.insightSetId, data.traceInsight.insightName);
544
+ if ('error' in insightOutput) {
545
+ response.push(insightOutput.error);
546
+ }
547
+ else {
548
+ response.push(insightOutput.output);
549
+ }
550
+ }
551
+ if (data.lighthouseResult) {
552
+ structuredContent.lighthouseResult = data.lighthouseResult;
553
+ const { summary, reports } = data.lighthouseResult;
554
+ response.push('## Lighthouse Audit Results');
555
+ response.push(`Mode: ${summary.mode}`);
556
+ response.push(`Device: ${summary.device}`);
557
+ response.push(`URL: ${summary.url}`);
558
+ response.push('### Category Scores');
559
+ for (const score of summary.scores) {
560
+ response.push(`- ${score.title}: ${(score.score ?? 0) * 100} (${score.id})`);
561
+ }
562
+ response.push('### Audit Summary');
563
+ response.push(`Passed: ${summary.audits.passed}`);
564
+ response.push(`Failed: ${summary.audits.failed}`);
565
+ response.push(`Total Timing: ${summary.timing.total}ms`);
566
+ response.push('### Reports');
567
+ for (const report of reports) {
568
+ response.push(`- ${report}`);
569
+ }
570
+ }
571
+ if (data.snapshot) {
572
+ if (typeof data.snapshot === 'string') {
573
+ response.push(`Saved snapshot to ${data.snapshot}.`);
574
+ structuredContent.snapshotFilePath = data.snapshot;
575
+ }
576
+ else {
577
+ response.push('## Latest page snapshot');
578
+ response.push(data.snapshot.toString());
579
+ structuredContent.snapshot = data.snapshot.toJSON();
580
+ }
581
+ }
582
+ if (data.detailedNetworkRequest) {
583
+ response.push(data.detailedNetworkRequest.toStringDetailed());
584
+ structuredContent.networkRequest =
585
+ data.detailedNetworkRequest.toJSONDetailed();
586
+ }
587
+ if (data.detailedConsoleMessage) {
588
+ response.push(data.detailedConsoleMessage.toStringDetailed());
589
+ structuredContent.consoleMessage =
590
+ data.detailedConsoleMessage.toJSONDetailed();
591
+ }
592
+ if (data.extensions) {
593
+ structuredContent.extensions = data.extensions;
594
+ response.push('## Extensions');
595
+ if (data.extensions.length === 0) {
596
+ response.push('No extensions installed.');
597
+ }
598
+ else {
599
+ const extensionsMessage = data.extensions
600
+ .map(extension => {
601
+ return `id=${extension.id} "${extension.name}" v${extension.version} ${extension.isEnabled ? 'Enabled' : 'Disabled'}`;
602
+ })
603
+ .join('\n');
604
+ response.push(extensionsMessage);
605
+ }
606
+ }
607
+ if (this.#listInPageTools) {
608
+ structuredContent.inPageTools = data.inPageTools ?? undefined;
609
+ response.push('## In-page tools');
610
+ if (!data.inPageTools || !data.inPageTools.tools) {
611
+ response.push('No in-page tools available.');
612
+ }
613
+ else {
614
+ const toolGroup = data.inPageTools;
615
+ response.push(`${toolGroup.name}: ${toolGroup.description}`);
616
+ response.push('Available tools:');
617
+ const toolDefinitionsMessage = toolGroup.tools
618
+ .map(tool => {
619
+ return `name="${tool.name}", description="${tool.description}", inputSchema=${JSON.stringify(tool.inputSchema)}`;
620
+ })
621
+ .join('\n');
622
+ response.push(toolDefinitionsMessage);
623
+ }
624
+ }
625
+ if (this.#networkRequestsOptions?.include && data.networkRequests) {
626
+ const requests = data.networkRequests;
627
+ response.push('## Network requests');
628
+ if (requests.length) {
629
+ const paginationData = this.#dataWithPagination(requests, this.#networkRequestsOptions.pagination);
630
+ structuredContent.pagination = paginationData.pagination;
631
+ response.push(...paginationData.info);
632
+ if (data.networkRequests) {
633
+ structuredContent.networkRequests = [];
634
+ for (const formatter of paginationData.items) {
635
+ response.push(formatter.toString());
636
+ structuredContent.networkRequests.push(formatter.toJSON());
637
+ }
638
+ }
639
+ }
640
+ else {
641
+ response.push('No requests found.');
642
+ }
643
+ }
644
+ if (this.#consoleDataOptions?.include) {
645
+ const messages = data.consoleMessages ?? [];
646
+ response.push('## Console messages');
647
+ if (messages.length) {
648
+ const paginationData = this.#dataWithPagination(messages, this.#consoleDataOptions.pagination);
649
+ structuredContent.pagination = paginationData.pagination;
650
+ response.push(...paginationData.info);
651
+ response.push(...paginationData.items.map(message => message.toString()));
652
+ structuredContent.consoleMessages = paginationData.items.map(message => message.toJSON());
653
+ }
654
+ else {
655
+ response.push('<no console messages found>');
656
+ }
657
+ }
658
+ const text = {
659
+ type: 'text',
660
+ text: response.join('\n'),
661
+ };
662
+ const images = this.#images.map(imageData => {
663
+ return {
664
+ type: 'image',
665
+ ...imageData,
666
+ };
667
+ });
668
+ return {
669
+ content: [text, ...images],
670
+ structuredContent,
671
+ };
672
+ }
673
+ #dataWithPagination(data, pagination) {
674
+ const response = [];
675
+ const paginationResult = paginate(data, pagination);
676
+ if (paginationResult.invalidPage) {
677
+ response.push('Invalid page number provided. Showing first page.');
678
+ }
679
+ const { startIndex, endIndex, currentPage, totalPages } = paginationResult;
680
+ response.push(`Showing ${startIndex + 1}-${endIndex} of ${data.length} (Page ${currentPage + 1} of ${totalPages}).`);
681
+ if (pagination) {
682
+ if (paginationResult.hasNextPage) {
683
+ response.push(`Next page: ${currentPage + 1}`);
684
+ }
685
+ if (paginationResult.hasPreviousPage) {
686
+ response.push(`Previous page: ${currentPage - 1}`);
687
+ }
688
+ }
689
+ return {
690
+ info: response,
691
+ items: paginationResult.items,
692
+ pagination: {
693
+ currentPage: paginationResult.currentPage,
694
+ totalPages: paginationResult.totalPages,
695
+ hasNextPage: paginationResult.hasNextPage,
696
+ hasPreviousPage: paginationResult.hasPreviousPage,
697
+ startIndex: paginationResult.startIndex,
698
+ endIndex: paginationResult.endIndex,
699
+ invalidPage: paginationResult.invalidPage,
700
+ },
701
+ };
702
+ }
703
+ resetResponseLineForTesting() {
704
+ this.#textResponseLines = [];
705
+ }
706
+ }
707
+ function createStructuredPage(page, context) {
708
+ const isolatedContextName = context.getIsolatedContextName(page);
709
+ const entry = {
710
+ id: context.getPageId(page),
711
+ url: page.url(),
712
+ selected: context.isPageSelected(page),
713
+ };
714
+ if (isolatedContextName) {
715
+ entry.isolatedContext = isolatedContextName;
716
+ }
717
+ return entry;
718
+ }