opera-devtools-mcp 0.2.3 → 0.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.
- package/README.md +104 -7
- package/build/src/McpContext.js +365 -365
- package/build/src/McpPage.js +475 -48
- package/build/src/McpResponse.js +462 -288
- package/build/src/SlimMcpResponse.js +1 -1
- package/build/src/TextSnapshot.js +101 -22
- package/build/src/ToolHandler.js +142 -20
- package/build/src/bin/check-latest-version.js +27 -1
- package/build/src/bin/chrome-devtools-cli-options.js +573 -10
- package/build/src/bin/chrome-devtools-mcp-cli-options.js +119 -32
- package/build/src/bin/chrome-devtools-mcp-main.js +50 -7
- package/build/src/bin/chrome-devtools-mcp.js +7 -4
- package/build/src/bin/chrome-devtools.js +57 -14
- package/build/src/bin/opera-devtools-cli-options.js +3 -829
- package/build/src/bin/opera-devtools-mcp-cli-options.js +3 -348
- package/build/src/bin/opera-devtools-mcp-main.js +3 -37
- package/build/src/bin/opera-devtools-mcp.js +4 -19
- package/build/src/bin/opera-devtools.js +4 -185
- package/build/src/browser.js +45 -5
- package/build/src/{PageCollector.js → collectors/PageCollector.js} +64 -133
- package/build/src/collectors/ServiceWorkerCollector.js +171 -0
- package/build/src/daemon/client.js +75 -17
- package/build/src/daemon/daemon.js +92 -30
- package/build/src/daemon/utils.js +24 -8
- package/build/src/{DevtoolsUtils.js → devtools/DevtoolsUtils.js} +94 -88
- package/build/src/devtools/McpHostBindingAdapter.js +165 -0
- package/build/src/{issue-descriptions.js → devtools/issueDescriptions.js} +8 -6
- package/build/src/formatters/ConsoleFormatter.js +44 -11
- package/build/src/formatters/HeapSnapshotFormatter.js +140 -9
- package/build/src/formatters/IssueFormatter.js +7 -7
- package/build/src/formatters/NetworkFormatter.js +10 -8
- package/build/src/index.js +101 -232
- package/build/src/opera/branding.js +34 -0
- package/build/src/opera/browserFlags.js +85 -0
- package/build/src/opera/browserLaunch.js +52 -0
- package/build/src/opera/policy.js +50 -0
- package/build/src/opera/serviceWorkerRetry.js +37 -0
- package/build/src/opera/toolHandlerHooks.js +39 -0
- package/build/src/{tools → opera/tools}/opera.js +9 -21
- package/build/src/processors/HeapSnapshotManager.js +258 -0
- package/build/src/{trace-processing/parse.js → processors/PerformanceTrace.js} +9 -9
- package/build/src/telemetry/ClearcutLogger.js +12 -119
- package/build/src/telemetry/WatchdogClient.js +5 -5
- package/build/src/telemetry/errors.js +1 -1
- package/build/src/telemetry/flagUtils.js +6 -6
- package/build/src/telemetry/{toolMetricsUtils.js → metricsRegistry.js} +4 -11
- package/build/src/telemetry/persistence.js +3 -3
- package/build/src/telemetry/transformation.js +184 -0
- package/build/src/telemetry/watchdog/ClearcutSender.js +11 -11
- package/build/src/telemetry/watchdog/main.js +6 -6
- package/build/src/third_party/THIRD_PARTY_NOTICES +3493 -0
- package/build/src/third_party/bundled-packages.json +9 -0
- package/build/src/third_party/devtools-formatter-worker.js +15340 -7
- package/build/src/third_party/devtools-heap-snapshot-worker.js +10337 -7
- package/build/src/third_party/index.js +179960 -26
- package/build/src/third_party/issue-descriptions/CoepCorpNotSameOrigin.md +2 -2
- package/build/src/third_party/issue-descriptions/CoepCorpNotSameOriginAfterDefaultedToSameOriginByCoep.md +3 -3
- package/build/src/third_party/issue-descriptions/CoepCorpNotSameSite.md +2 -2
- package/build/src/third_party/issue-descriptions/CoepFrameResourceNeedsCoepHeader.md +1 -1
- package/build/src/third_party/issue-descriptions/CompatibilityModeQuirks.md +1 -1
- package/build/src/third_party/issue-descriptions/CookieAttributeValueExceedsMaxSize.md +2 -2
- package/build/src/third_party/issue-descriptions/LowTextContrast.md +1 -1
- package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureErrorRead.md +1 -1
- package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureErrorSet.md +1 -1
- package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureWarnRead.md +1 -1
- package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureWarnSet.md +1 -1
- package/build/src/third_party/issue-descriptions/SameSiteUnspecifiedLaxAllowUnsafeRead.md +3 -3
- package/build/src/third_party/issue-descriptions/SameSiteUnspecifiedLaxAllowUnsafeSet.md +3 -3
- package/build/src/third_party/issue-descriptions/bounceTrackingMitigations.md +1 -1
- package/build/src/third_party/issue-descriptions/connectionAllowlistEmbeddingRequirementNotSatisfied.md +26 -0
- package/build/src/third_party/issue-descriptions/connectionAllowlistIFrameAttributeLoosensEmbeddingRequirement.md +19 -0
- package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidAllowConnectionAllowlistFrom.md +21 -0
- package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidAllowlistItemType.md +2 -2
- package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidHeader.md +2 -2
- package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidUrlPattern.md +3 -3
- package/build/src/third_party/issue-descriptions/connectionAllowlistItemNotInnerList.md +2 -2
- package/build/src/third_party/issue-descriptions/connectionAllowlistMoreThanOneList.md +2 -2
- package/build/src/third_party/issue-descriptions/connectionAllowlistReportingEndpointNotToken.md +1 -1
- package/build/src/third_party/issue-descriptions/cookieCrossSiteRedirectDowngrade.md +3 -3
- package/build/src/third_party/issue-descriptions/cookieExcludeBlockedWithinRelatedWebsiteSet.md +1 -1
- package/build/src/third_party/issue-descriptions/cookieExcludePortMismatch.md +1 -1
- package/build/src/third_party/issue-descriptions/cookieExcludeSchemeMismatch.md +1 -1
- package/build/src/third_party/issue-descriptions/cookieExcludeThirdPartyPhaseoutSet.md +1 -1
- package/build/src/third_party/issue-descriptions/cookieWarnThirdPartyPhaseoutRead.md +1 -1
- package/build/src/third_party/issue-descriptions/corsAllowCredentialsRequired.md +1 -1
- package/build/src/third_party/issue-descriptions/corsDisabledScheme.md +2 -2
- package/build/src/third_party/issue-descriptions/corsDisallowedByMode.md +2 -2
- package/build/src/third_party/issue-descriptions/corsHeaderDisallowedByPreflightResponse.md +1 -1
- package/build/src/third_party/issue-descriptions/corsInvalidHeaderValues.md +3 -3
- package/build/src/third_party/issue-descriptions/corsLocalNetworkAccessPermissionDenied.md +1 -1
- package/build/src/third_party/issue-descriptions/corsMethodDisallowedByPreflightResponse.md +1 -1
- package/build/src/third_party/issue-descriptions/corsNoCorsRedirectModeNotFollow.md +1 -1
- package/build/src/third_party/issue-descriptions/corsOriginMismatch.md +3 -3
- package/build/src/third_party/issue-descriptions/corsPreflightResponseInvalid.md +2 -2
- package/build/src/third_party/issue-descriptions/corsRedirectContainsCredentials.md +3 -3
- package/build/src/third_party/issue-descriptions/corsWildcardOriginNotAllowed.md +4 -3
- package/build/src/third_party/issue-descriptions/cspEvalViolation.md +4 -4
- package/build/src/third_party/issue-descriptions/cspInlineViolation.md +2 -2
- package/build/src/third_party/issue-descriptions/cspTrustedTypesPolicyViolation.md +2 -2
- package/build/src/third_party/issue-descriptions/cspTrustedTypesSinkViolation.md +4 -4
- package/build/src/third_party/issue-descriptions/cspURLViolation.md +4 -4
- package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsEmptyList.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsHttpNotFound.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsInvalidContentType.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsInvalidResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsNoResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestDnsFetchFailed.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestDnsInvalidRecord.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownHttpNotFound.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownInvalidContentType.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownInvalidResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownNoResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestInvalidEmail.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestJwksHttpNotFound.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestJwksInvalidResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestKeyBindingSigningFailed.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestRpOriginIsOpaque.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenHttpNotFound.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenInvalidContentType.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenInvalidResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenInvalidSdJwt.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenMalformedSdJwt.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenNoResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidAudience.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidIssuedAt.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidNonce.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidSdHash.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidTyp.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingAud.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingCnf.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingIat.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingNonce.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingSdHash.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbSignatureFailed.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidEmail.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidEmailVerified.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidHolderKey.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidIssuedAt.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidIssuer.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtJwksMissingKeys.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingCnf.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingEmail.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingIat.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingIss.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtSignatureFailed.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtUnsupportedHeaderAlg.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestUserLoggedOut.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownAccountsEndpointCrossOrigin.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownHttpNotFound.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownInvalidContentType.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownInvalidResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownIssuanceEndpointCrossOrigin.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownListEmpty.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownMissingAccountsEndpoint.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownMissingIssuanceEndpoint.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownNoResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownUnsupportedSigningAlgorithm.md +1 -0
- package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsHttpNotFound.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsInvalidResponse.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsNoResponse.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestApprovalDeclined.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestCanceled.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestErrorFetchingSignin.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestErrorIdToken.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenHttpNotFound.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenInvalidRequest.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenInvalidResponse.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenNoResponse.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestInvalidSigninResponse.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestHttpNotFound.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestInvalidResponse.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestNoResponse.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestTooManyRequests.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestInvalidAccountsResponse.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestInvalidConfigOrWellKnown.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoAccountSharingPermission.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoApiPermission.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoReturningUserFromFetchedAccounts.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotIframe.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotPotentiallyTrustworthy.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotSameOrigin.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotSignedInWithIdp.md +1 -1
- package/build/src/third_party/issue-descriptions/fetchingPartitionedBlobURL.md +2 -2
- package/build/src/third_party/issue-descriptions/genericBackUINavigationWouldSkipAd.md +4 -0
- package/build/src/third_party/issue-descriptions/genericFormAriaLabelledByToNonExistingIdError.md +2 -2
- package/build/src/third_party/issue-descriptions/genericFormAutocompleteAttributeEmptyError.md +1 -1
- package/build/src/third_party/issue-descriptions/genericFormDuplicateIdForInputError.md +1 -1
- package/build/src/third_party/issue-descriptions/genericFormEmptyIdAndNameAttributesForInputError.md +2 -2
- package/build/src/third_party/issue-descriptions/genericFormInputAssignedAutocompleteValueToIdOrNameAttributeError.md +2 -2
- package/build/src/third_party/issue-descriptions/genericFormInputHasWrongButWellIntendedAutocompleteValueError.md +1 -1
- package/build/src/third_party/issue-descriptions/genericFormInputWithNoLabelError.md +1 -1
- package/build/src/third_party/issue-descriptions/genericFormLabelForMatchesNonExistingIdError.md +2 -2
- package/build/src/third_party/issue-descriptions/genericFormLabelForNameError.md +1 -1
- package/build/src/third_party/issue-descriptions/genericFormLabelHasNeitherForNorNestedInputError.md +1 -1
- package/build/src/third_party/issue-descriptions/genericFormModelContextMissingToolName.md +1 -1
- package/build/src/third_party/issue-descriptions/genericFormModelContextParameterMissingName.md +1 -1
- package/build/src/third_party/issue-descriptions/genericFormModelContextRequiredParameterMissingName.md +1 -1
- package/build/src/third_party/issue-descriptions/genericNavigationEntryMarkedSkippable.md +2 -2
- package/build/src/third_party/issue-descriptions/heavyAd.md +1 -1
- package/build/src/third_party/issue-descriptions/lazyLoadImageZeroSize.md +7 -0
- package/build/src/third_party/issue-descriptions/navigatingPartitionedBlobURL.md +3 -3
- package/build/src/third_party/issue-descriptions/permissionElementActivationDisabled.md +1 -1
- package/build/src/third_party/issue-descriptions/permissionElementActivationDisabledWithOccluder.md +1 -1
- package/build/src/third_party/issue-descriptions/permissionElementActivationDisabledWithOccluderParent.md +1 -1
- package/build/src/third_party/issue-descriptions/permissionElementFencedFrameDisallowed.md +2 -2
- package/build/src/third_party/issue-descriptions/permissionElementFontSizeTooLarge.md +2 -2
- package/build/src/third_party/issue-descriptions/permissionElementFontSizeTooSmall.md +2 -2
- package/build/src/third_party/issue-descriptions/permissionElementInsetBoxShadowUnsupported.md +1 -1
- package/build/src/third_party/issue-descriptions/permissionElementInvalidDisplayStyle.md +2 -2
- package/build/src/third_party/issue-descriptions/permissionElementInvalidSizeValue.md +2 -2
- package/build/src/third_party/issue-descriptions/permissionElementInvalidType.md +2 -2
- package/build/src/third_party/issue-descriptions/permissionElementInvalidTypeActivation.md +2 -2
- package/build/src/third_party/issue-descriptions/permissionElementNonOpaqueColor.md +1 -1
- package/build/src/third_party/issue-descriptions/permissionElementPaddingBottomUnsupported.md +2 -2
- package/build/src/third_party/issue-descriptions/permissionElementPaddingRightUnsupported.md +2 -2
- package/build/src/third_party/issue-descriptions/permissionElementRequestInProgress.md +2 -2
- package/build/src/third_party/issue-descriptions/permissionElementSecurityChecksFailed.md +1 -1
- package/build/src/third_party/issue-descriptions/permissionElementTypeNotSupported.md +2 -2
- package/build/src/third_party/issue-descriptions/permissionElementUntrustedEvent.md +1 -1
- package/build/src/third_party/issue-descriptions/placeholderDescriptionForInvisibleIssues.md +1 -1
- package/build/src/third_party/issue-descriptions/selectElementAccessibilityDisallowedOptGroupChild.md +1 -1
- package/build/src/third_party/issue-descriptions/selectElementAccessibilityDisallowedSelectChild.md +1 -1
- package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentAttributesSelectDescendant.md +1 -1
- package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentLegendChild.md +1 -1
- package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentOptionChild.md +1 -1
- package/build/src/third_party/issue-descriptions/selectElementAccessibilityNonPhrasingContentOptionChild.md +1 -1
- package/build/src/third_party/issue-descriptions/selectivePermissionsIntervention.md +3 -3
- package/build/src/third_party/issue-descriptions/sharedArrayBuffer.md +1 -1
- package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorCrossOriginNoCorsRequest.md +1 -1
- package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorMatchingDictionaryNotUsed.md +1 -1
- package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorUnexpectedContentDictionaryHeader.md +1 -1
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorCossOriginNoCorsRequest.md +1 -1
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorDisallowedBySettings.md +1 -1
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorExpiredResponse.md +1 -1
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorFeatureDisabled.md +2 -2
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInvalidStructuredHeader.md +1 -1
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNavigationRequest.md +2 -2
- package/build/src/third_party/issue-descriptions/sriInvalidSignatureHeader.md +4 -4
- package/build/src/third_party/issue-descriptions/sriInvalidSignatureInputHeader.md +4 -4
- package/build/src/third_party/issue-descriptions/sriMissingSignatureHeader.md +1 -1
- package/build/src/third_party/issue-descriptions/sriMissingSignatureInputHeader.md +2 -2
- package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsIncorrectLength.md +2 -2
- package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsNotByteSequence.md +4 -4
- package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsParameterized.md +4 -4
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidComponentName.md +1 -1
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidComponentType.md +2 -2
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidDerivedComponentParameter.md +1 -1
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidHeaderComponentParameter.md +1 -1
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidParameter.md +2 -2
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderKeyIdLength.md +5 -5
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderMissingLabel.md +3 -3
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderMissingRequiredParameters.md +2 -2
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderValueMissingComponents.md +2 -2
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderValueNotInnerList.md +2 -2
- package/build/src/third_party/issue-descriptions/sriValidationFailedIntegrityMismatch.md +4 -4
- package/build/src/third_party/issue-descriptions/sriValidationFailedInvalidLength.md +3 -3
- package/build/src/third_party/issue-descriptions/sriValidationFailedSignatureExpired.md +2 -2
- package/build/src/third_party/issue-descriptions/sriValidationFailedSignatureMismatch.md +2 -2
- package/build/src/third_party/issue-descriptions/stylesheetLateImport.md +1 -1
- package/build/src/third_party/issue-descriptions/summaryElementAccessibilityInteractiveContentSummaryDescendant.md +1 -1
- package/build/src/third_party/issue-descriptions/unencodedDigestIncorrectDigestLength.md +2 -2
- package/build/src/third_party/issue-descriptions/unencodedDigestIncorrectDigestType.md +3 -3
- package/build/src/third_party/issue-descriptions/unencodedDigestMalformedDictionary.md +2 -2
- package/build/src/third_party/issue-descriptions/unencodedDigestUnknownAlgorithm.md +1 -1
- package/build/src/third_party/lighthouse-devtools-mcp-bundle.js +3177 -6340
- package/build/src/tools/ToolDefinition.js +2 -2
- package/build/src/tools/categories.js +3 -0
- package/build/src/tools/console.js +13 -0
- package/build/src/tools/emulation.js +30 -3
- package/build/src/tools/extensions.js +8 -1
- package/build/src/tools/input.js +246 -128
- package/build/src/tools/lighthouse.js +14 -7
- package/build/src/tools/memory.js +289 -25
- package/build/src/tools/network.js +10 -7
- package/build/src/tools/pages.js +33 -92
- package/build/src/tools/performance.js +67 -52
- package/build/src/tools/pwa.js +128 -0
- package/build/src/tools/screencast.js +35 -12
- package/build/src/tools/screenshot.js +234 -75
- package/build/src/tools/script.js +130 -45
- package/build/src/tools/slim/tools.js +3 -0
- package/build/src/tools/snapshot.js +7 -4
- package/build/src/tools/thirdPartyDeveloper.js +19 -9
- package/build/src/tools/tools.js +3 -1
- package/build/src/tools/webmcp.js +3 -1
- package/build/src/utils/WaitForHelper.js +299 -0
- package/build/src/utils/check-for-updates.js +8 -2
- package/build/src/utils/files.js +42 -3
- package/build/src/utils/logger.js +51 -0
- package/build/src/utils/polyfill.js +11 -0
- package/build/src/utils/url.js +43 -0
- package/build/src/version.js +1 -1
- package/package.json +42 -33
- package/build/src/DevToolsConnectionAdapter.js +0 -70
- package/build/src/HeapSnapshotManager.js +0 -110
- package/build/src/Mutex.js +0 -38
- package/build/src/WaitForHelper.js +0 -195
- package/build/src/bin/cliDefinitions.js +0 -616
- package/build/src/logger.js +0 -37
- package/build/src/polyfill.js +0 -8
- package/build/src/telemetry/metricUtils.js +0 -15
- package/build/src/third_party/issue-descriptions/SameSiteExcludeContextDowngradeRead.md +0 -8
- package/build/src/third_party/issue-descriptions/SameSiteExcludeContextDowngradeSet.md +0 -8
- package/build/src/third_party/issue-descriptions/SameSiteExcludeNavigationContextDowngrade.md +0 -8
- package/build/src/third_party/issue-descriptions/SameSiteWarnCrossDowngradeRead.md +0 -8
- package/build/src/third_party/issue-descriptions/SameSiteWarnCrossDowngradeSet.md +0 -8
- package/build/src/third_party/issue-descriptions/SameSiteWarnStrictLaxDowngradeStrict.md +0 -8
- package/build/src/third_party/issue-descriptions/arInsecureContext.md +0 -7
- package/build/src/third_party/issue-descriptions/arInvalidInfoHeader.md +0 -5
- package/build/src/third_party/issue-descriptions/arInvalidRegisterOsSourceHeader.md +0 -5
- package/build/src/third_party/issue-descriptions/arInvalidRegisterOsTriggerHeader.md +0 -5
- package/build/src/third_party/issue-descriptions/arInvalidRegisterSourceHeader.md +0 -5
- package/build/src/third_party/issue-descriptions/arInvalidRegisterTriggerHeader.md +0 -5
- package/build/src/third_party/issue-descriptions/arNavigationRegistrationUniqueScopeAlreadySet.md +0 -5
- package/build/src/third_party/issue-descriptions/arNavigationRegistrationWithoutTransientUserActivation.md +0 -6
- package/build/src/third_party/issue-descriptions/arNoRegisterOsSourceHeader.md +0 -5
- package/build/src/third_party/issue-descriptions/arNoRegisterOsTriggerHeader.md +0 -5
- package/build/src/third_party/issue-descriptions/arNoRegisterSourceHeader.md +0 -5
- package/build/src/third_party/issue-descriptions/arNoRegisterTriggerHeader.md +0 -5
- package/build/src/third_party/issue-descriptions/arNoWebOrOsSupport.md +0 -4
- package/build/src/third_party/issue-descriptions/arOsSourceIgnored.md +0 -18
- package/build/src/third_party/issue-descriptions/arOsTriggerIgnored.md +0 -19
- package/build/src/third_party/issue-descriptions/arPermissionPolicyDisabled.md +0 -8
- package/build/src/third_party/issue-descriptions/arSourceAndTriggerHeaders.md +0 -9
- package/build/src/third_party/issue-descriptions/arSourceIgnored.md +0 -13
- package/build/src/third_party/issue-descriptions/arTriggerIgnored.md +0 -12
- package/build/src/third_party/issue-descriptions/arUntrustworthyReportingOrigin.md +0 -10
- package/build/src/third_party/issue-descriptions/arWebAndOsHeaders.md +0 -11
- package/build/src/utils/string.js +0 -37
- package/build/src/utils/types.js +0 -7
package/build/src/McpResponse.js
CHANGED
|
@@ -6,110 +6,18 @@
|
|
|
6
6
|
* Modified by Opera Software AS.
|
|
7
7
|
*/
|
|
8
8
|
import { ConsoleFormatter } from './formatters/ConsoleFormatter.js';
|
|
9
|
-
import { HeapSnapshotFormatter } from './formatters/HeapSnapshotFormatter.js';
|
|
10
|
-
import { isNodeLike } from './formatters/HeapSnapshotFormatter.js';
|
|
9
|
+
import { HeapSnapshotFormatter, isEdgeLike, isNodeLike, } from './formatters/HeapSnapshotFormatter.js';
|
|
11
10
|
import { IssueFormatter } from './formatters/IssueFormatter.js';
|
|
12
11
|
import { NetworkFormatter } from './formatters/NetworkFormatter.js';
|
|
13
12
|
import { SnapshotFormatter } from './formatters/SnapshotFormatter.js';
|
|
14
|
-
import { UncaughtError } from './PageCollector.js';
|
|
13
|
+
import { UncaughtError } from './collectors/PageCollector.js';
|
|
15
14
|
import { TextSnapshot } from './TextSnapshot.js';
|
|
16
|
-
import { DevTools } from './third_party/index.js';
|
|
17
|
-
import { handleDialog } from './tools/pages.js';
|
|
18
|
-
import { getInsightOutput, getTraceSummary } from './
|
|
15
|
+
import { DevTools, getToonEncode, getGcfEncode } from './third_party/index.js';
|
|
16
|
+
import { handleDialog, listPages } from './tools/pages.js';
|
|
17
|
+
import { getInsightOutput, getTraceSummary, } from './processors/PerformanceTrace.js';
|
|
18
|
+
import { stableIdSymbol } from './utils/id.js';
|
|
19
19
|
import { paginate } from './utils/pagination.js';
|
|
20
|
-
|
|
21
|
-
if (typeof schema === 'boolean') {
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
let isHtmlElement = false;
|
|
25
|
-
for (const [key, value] of Object.entries(schema)) {
|
|
26
|
-
if (key === 'x-mcp-type' && value === 'HTMLElement') {
|
|
27
|
-
isHtmlElement = true;
|
|
28
|
-
break;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
if (isHtmlElement) {
|
|
32
|
-
schema.properties = { uid: { type: 'string' } };
|
|
33
|
-
schema.required = ['uid'];
|
|
34
|
-
}
|
|
35
|
-
if (schema.properties) {
|
|
36
|
-
for (const key of Object.keys(schema.properties)) {
|
|
37
|
-
replaceHtmlElementsWithUids(schema.properties[key]);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
if (schema.items) {
|
|
41
|
-
if (Array.isArray(schema.items)) {
|
|
42
|
-
for (const item of schema.items) {
|
|
43
|
-
replaceHtmlElementsWithUids(item);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
replaceHtmlElementsWithUids(schema.items);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
if (schema.anyOf) {
|
|
51
|
-
for (const s of schema.anyOf) {
|
|
52
|
-
replaceHtmlElementsWithUids(s);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
if (schema.allOf) {
|
|
56
|
-
for (const s of schema.allOf) {
|
|
57
|
-
replaceHtmlElementsWithUids(s);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
if (schema.oneOf) {
|
|
61
|
-
for (const s of schema.oneOf) {
|
|
62
|
-
replaceHtmlElementsWithUids(s);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
async function getToolGroup(page) {
|
|
67
|
-
// Check if there is a `devtoolstooldiscovery` event listener
|
|
68
|
-
const windowHandle = await page.pptrPage.evaluateHandle(() => window);
|
|
69
|
-
// @ts-expect-error internal API
|
|
70
|
-
const client = page.pptrPage._client();
|
|
71
|
-
const { listeners } = await client.send('DOMDebugger.getEventListeners', {
|
|
72
|
-
objectId: windowHandle.remoteObject().objectId,
|
|
73
|
-
});
|
|
74
|
-
if (listeners.find(l => l.type === 'devtoolstooldiscovery') === undefined) {
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
const toolGroup = await page.pptrPage.evaluate(() => {
|
|
78
|
-
return new Promise(resolve => {
|
|
79
|
-
const event = new CustomEvent('devtoolstooldiscovery');
|
|
80
|
-
// @ts-expect-error Adding custom property
|
|
81
|
-
event.respondWith = (toolGroup) => {
|
|
82
|
-
if (!window.__dtmcp) {
|
|
83
|
-
window.__dtmcp = {};
|
|
84
|
-
}
|
|
85
|
-
window.__dtmcp.toolGroup = toolGroup;
|
|
86
|
-
// When receiving a toolGroup for the first time, expose a simple execution helper
|
|
87
|
-
if (!window.__dtmcp.executeTool) {
|
|
88
|
-
window.__dtmcp.executeTool = async (toolName, args) => {
|
|
89
|
-
if (!window.__dtmcp?.toolGroup) {
|
|
90
|
-
throw new Error('No tools found on the page');
|
|
91
|
-
}
|
|
92
|
-
const tool = window.__dtmcp.toolGroup.tools.find(t => t.name === toolName);
|
|
93
|
-
if (!tool) {
|
|
94
|
-
throw new Error(`Tool ${toolName} not found`);
|
|
95
|
-
}
|
|
96
|
-
return await tool.execute(args);
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
resolve(toolGroup);
|
|
100
|
-
};
|
|
101
|
-
window.dispatchEvent(event);
|
|
102
|
-
// If the page does not synchronously call `event.respondWith`, return instead of timing out
|
|
103
|
-
setTimeout(() => {
|
|
104
|
-
resolve(null);
|
|
105
|
-
}, 0);
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
for (const tool of toolGroup?.tools ?? []) {
|
|
109
|
-
replaceHtmlElementsWithUids(tool.inputSchema);
|
|
110
|
-
}
|
|
111
|
-
return toolGroup;
|
|
112
|
-
}
|
|
20
|
+
const { formatBytesToKb } = DevTools.I18n.ByteUtilities;
|
|
113
21
|
export class McpResponse {
|
|
114
22
|
#includePages = false;
|
|
115
23
|
#includeExtensionServiceWorkers = false;
|
|
@@ -136,6 +44,11 @@ export class McpResponse {
|
|
|
136
44
|
#redactNetworkHeaders = true;
|
|
137
45
|
#error;
|
|
138
46
|
#logCallback;
|
|
47
|
+
#attachedWaitForResult;
|
|
48
|
+
#reconnectNotice = false;
|
|
49
|
+
get #deviceScope() {
|
|
50
|
+
return this.#page?.viewport?.isMobile ? 'PHONE' : 'DESKTOP';
|
|
51
|
+
}
|
|
139
52
|
constructor(args, logCallback) {
|
|
140
53
|
this.#args = args;
|
|
141
54
|
this.#logCallback = logCallback;
|
|
@@ -149,6 +62,13 @@ export class McpResponse {
|
|
|
149
62
|
setRedactNetworkHeaders(value) {
|
|
150
63
|
this.#redactNetworkHeaders = value;
|
|
151
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Surfaces a one-time note that the browser reconnected and page ids changed.
|
|
67
|
+
* Set by the tool handler when the context reports a pending reconnect notice.
|
|
68
|
+
*/
|
|
69
|
+
setReconnectNotice() {
|
|
70
|
+
this.#reconnectNotice = true;
|
|
71
|
+
}
|
|
152
72
|
attachDevToolsData(data) {
|
|
153
73
|
this.#devToolsData = data;
|
|
154
74
|
}
|
|
@@ -183,7 +103,7 @@ export class McpResponse {
|
|
|
183
103
|
}
|
|
184
104
|
this.#networkRequestsOptions = {
|
|
185
105
|
include: value,
|
|
186
|
-
pagination: options?.pageSize || options?.pageIdx
|
|
106
|
+
pagination: options?.pageSize !== undefined || options?.pageIdx !== undefined
|
|
187
107
|
? {
|
|
188
108
|
pageSize: options.pageSize,
|
|
189
109
|
pageIdx: options.pageIdx,
|
|
@@ -201,7 +121,7 @@ export class McpResponse {
|
|
|
201
121
|
}
|
|
202
122
|
this.#consoleDataOptions = {
|
|
203
123
|
include: value,
|
|
204
|
-
pagination: options?.pageSize || options?.pageIdx
|
|
124
|
+
pagination: options?.pageSize !== undefined || options?.pageIdx !== undefined
|
|
205
125
|
? {
|
|
206
126
|
pageSize: options.pageSize,
|
|
207
127
|
pageIdx: options.pageIdx,
|
|
@@ -209,6 +129,8 @@ export class McpResponse {
|
|
|
209
129
|
: undefined,
|
|
210
130
|
types: options?.types,
|
|
211
131
|
includePreservedMessages: options?.includePreservedMessages,
|
|
132
|
+
includeStackTraces: options?.includeStackTraces,
|
|
133
|
+
serviceWorkerId: options?.serviceWorkerId,
|
|
212
134
|
};
|
|
213
135
|
}
|
|
214
136
|
setError(error) {
|
|
@@ -270,20 +192,25 @@ export class McpResponse {
|
|
|
270
192
|
appendResponseLine(value) {
|
|
271
193
|
this.#textResponseLines.push(value);
|
|
272
194
|
}
|
|
273
|
-
|
|
195
|
+
attachWaitForResult(result) {
|
|
196
|
+
this.#attachedWaitForResult = result;
|
|
197
|
+
}
|
|
198
|
+
setHeapSnapshotAggregates(aggregateData, options) {
|
|
274
199
|
this.#heapSnapshotOptions = {
|
|
275
200
|
...this.#heapSnapshotOptions,
|
|
276
201
|
include: true,
|
|
277
|
-
|
|
202
|
+
aggregateData,
|
|
278
203
|
pagination: options,
|
|
279
204
|
};
|
|
280
205
|
}
|
|
281
|
-
setHeapSnapshotStats(stats, staticData) {
|
|
206
|
+
setHeapSnapshotStats(stats, staticData, nativeContextSizes, retainedByContextSummary) {
|
|
282
207
|
this.#heapSnapshotOptions = {
|
|
283
208
|
...this.#heapSnapshotOptions,
|
|
284
209
|
include: true,
|
|
285
210
|
stats,
|
|
286
211
|
staticData,
|
|
212
|
+
nativeContextSizes,
|
|
213
|
+
retainedByContextSummary,
|
|
287
214
|
};
|
|
288
215
|
}
|
|
289
216
|
setHeapSnapshotNodes(nodes, options) {
|
|
@@ -294,6 +221,49 @@ export class McpResponse {
|
|
|
294
221
|
pagination: options,
|
|
295
222
|
};
|
|
296
223
|
}
|
|
224
|
+
setHeapSnapshotDuplicateStrings(duplicateStrings, options) {
|
|
225
|
+
this.#heapSnapshotOptions = {
|
|
226
|
+
...this.#heapSnapshotOptions,
|
|
227
|
+
include: true,
|
|
228
|
+
duplicateStrings,
|
|
229
|
+
pagination: options,
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
setHeapSnapshotRetainingPaths(retainingPaths) {
|
|
233
|
+
this.#heapSnapshotOptions = {
|
|
234
|
+
...this.#heapSnapshotOptions,
|
|
235
|
+
include: true,
|
|
236
|
+
retainingPaths,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
setHeapSnapshotDominators(dominators) {
|
|
240
|
+
this.#heapSnapshotOptions = {
|
|
241
|
+
...this.#heapSnapshotOptions,
|
|
242
|
+
include: true,
|
|
243
|
+
dominators,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
setHeapSnapshotClassDiffs(classDiffs) {
|
|
247
|
+
this.#heapSnapshotOptions = {
|
|
248
|
+
...this.#heapSnapshotOptions,
|
|
249
|
+
include: true,
|
|
250
|
+
classDiffs,
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
setHeapSnapshotDetailedClassDiff(detailedClassDiff) {
|
|
254
|
+
this.#heapSnapshotOptions = {
|
|
255
|
+
...this.#heapSnapshotOptions,
|
|
256
|
+
include: true,
|
|
257
|
+
detailedClassDiff,
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
setHeapSnapshotObjectDetails(objectInfo) {
|
|
261
|
+
this.#heapSnapshotOptions = {
|
|
262
|
+
...this.#heapSnapshotOptions,
|
|
263
|
+
include: true,
|
|
264
|
+
objectInfo,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
297
267
|
attachImage(value) {
|
|
298
268
|
this.#images.push(value);
|
|
299
269
|
}
|
|
@@ -309,167 +279,189 @@ export class McpResponse {
|
|
|
309
279
|
get listWebMcpTools() {
|
|
310
280
|
return this.#listWebMcpTools;
|
|
311
281
|
}
|
|
312
|
-
async
|
|
282
|
+
async #handleSnapshot(context) {
|
|
313
283
|
if (this.#includePages) {
|
|
314
284
|
await context.createPagesSnapshot();
|
|
315
285
|
}
|
|
316
|
-
if (this.#
|
|
317
|
-
|
|
286
|
+
if (!this.#snapshotParams) {
|
|
287
|
+
return undefined;
|
|
318
288
|
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
if (!this.#page) {
|
|
322
|
-
throw new Error('Response must have a page');
|
|
323
|
-
}
|
|
324
|
-
this.#page.textSnapshot = await TextSnapshot.create(this.#page, {
|
|
325
|
-
verbose: this.#snapshotParams.verbose,
|
|
326
|
-
devtoolsData: this.#devToolsData,
|
|
327
|
-
});
|
|
328
|
-
const textSnapshot = this.#page.textSnapshot;
|
|
329
|
-
if (textSnapshot) {
|
|
330
|
-
const formatter = new SnapshotFormatter(textSnapshot);
|
|
331
|
-
if (this.#snapshotParams.filePath) {
|
|
332
|
-
const result = await context.saveFile(new TextEncoder().encode(formatter.toString()), this.#snapshotParams.filePath, '.txt');
|
|
333
|
-
snapshot = result.filename;
|
|
334
|
-
}
|
|
335
|
-
else {
|
|
336
|
-
snapshot = formatter;
|
|
337
|
-
}
|
|
338
|
-
}
|
|
289
|
+
if (!this.#page) {
|
|
290
|
+
throw new Error('Response must have a page');
|
|
339
291
|
}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
const
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
292
|
+
this.#page.textSnapshot = await TextSnapshot.create(this.#page, {
|
|
293
|
+
verbose: this.#snapshotParams.verbose,
|
|
294
|
+
devtoolsData: this.#devToolsData,
|
|
295
|
+
});
|
|
296
|
+
const formatter = new SnapshotFormatter(this.#page.textSnapshot);
|
|
297
|
+
if (this.#snapshotParams.filePath) {
|
|
298
|
+
const result = await context.saveFile(new TextEncoder().encode(formatter.toString()), this.#snapshotParams.filePath, '.txt');
|
|
299
|
+
return result.filename;
|
|
300
|
+
}
|
|
301
|
+
else {
|
|
302
|
+
return formatter;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
async #handleAttachedNetworkRequest(context) {
|
|
306
|
+
if (!this.#attachedNetworkRequestId) {
|
|
307
|
+
return undefined;
|
|
308
|
+
}
|
|
309
|
+
if (!this.#page) {
|
|
310
|
+
throw new Error(`Response must have an McpPage`);
|
|
311
|
+
}
|
|
312
|
+
const request = this.#page.getNetworkRequestById(this.#attachedNetworkRequestId);
|
|
313
|
+
return await NetworkFormatter.from(request, {
|
|
314
|
+
requestId: this.#attachedNetworkRequestId,
|
|
315
|
+
requestIdResolver: req => this.getNetworkRequestStableId(req),
|
|
316
|
+
fetchData: true,
|
|
317
|
+
requestFilePath: this.#attachedNetworkRequestOptions?.requestFilePath,
|
|
318
|
+
responseFilePath: this.#attachedNetworkRequestOptions?.responseFilePath,
|
|
319
|
+
saveFile: (data, filename, extension) => context.saveFile(data, filename, extension),
|
|
320
|
+
redactNetworkHeaders: this.#redactNetworkHeaders,
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
async #handleAttachedConsoleMessage() {
|
|
324
|
+
if (!this.#attachedConsoleMessageId) {
|
|
325
|
+
return undefined;
|
|
326
|
+
}
|
|
327
|
+
if (!this.#page) {
|
|
328
|
+
throw new Error(`Response must have an McpPage`);
|
|
329
|
+
}
|
|
330
|
+
const message = this.#page.getConsoleMessageById(this.#attachedConsoleMessageId);
|
|
331
|
+
const consoleMessageStableId = this.#attachedConsoleMessageId;
|
|
332
|
+
if ('args' in message || message instanceof UncaughtError) {
|
|
333
|
+
const consoleMessage = message;
|
|
334
|
+
return await ConsoleFormatter.from(consoleMessage, {
|
|
335
|
+
id: consoleMessageStableId,
|
|
336
|
+
fetchDetailedData: true,
|
|
337
|
+
devTools: this.#page.devtoolsUniverse,
|
|
354
338
|
});
|
|
355
|
-
detailedNetworkRequest = formatter;
|
|
356
339
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
const consoleMessage = message;
|
|
366
|
-
const devTools = context.getDevToolsUniverse(this.#page);
|
|
367
|
-
detailedConsoleMessage = await ConsoleFormatter.from(consoleMessage, {
|
|
368
|
-
id: consoleMessageStableId,
|
|
369
|
-
fetchDetailedData: true,
|
|
370
|
-
devTools: devTools ?? undefined,
|
|
371
|
-
});
|
|
372
|
-
}
|
|
373
|
-
else if (message instanceof DevTools.AggregatedIssue) {
|
|
374
|
-
const formatter = new IssueFormatter(message, {
|
|
375
|
-
id: consoleMessageStableId,
|
|
376
|
-
requestIdResolver: context.resolveCdpRequestId.bind(context, this.#page),
|
|
377
|
-
elementIdResolver: this.#page.resolveCdpElementId.bind(this.#page),
|
|
378
|
-
});
|
|
379
|
-
if (!formatter.isValid()) {
|
|
380
|
-
throw new Error("Can't provide details for the msgid " + consoleMessageStableId);
|
|
381
|
-
}
|
|
382
|
-
detailedConsoleMessage = formatter;
|
|
340
|
+
else if (message instanceof DevTools.AggregatedIssue) {
|
|
341
|
+
const formatter = new IssueFormatter(message, {
|
|
342
|
+
id: consoleMessageStableId,
|
|
343
|
+
requestIdResolver: this.#page.resolveCdpRequestId.bind(this.#page),
|
|
344
|
+
elementIdResolver: this.#page.textSnapshot?.resolveCdpElementId.bind(this.#page.textSnapshot),
|
|
345
|
+
});
|
|
346
|
+
if (!formatter.isValid()) {
|
|
347
|
+
throw new Error("Can't provide details for the msgid " + consoleMessageStableId);
|
|
383
348
|
}
|
|
349
|
+
return formatter;
|
|
384
350
|
}
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
extensions = await context.listExtensions();
|
|
351
|
+
else {
|
|
352
|
+
return undefined;
|
|
388
353
|
}
|
|
389
|
-
|
|
390
|
-
|
|
354
|
+
}
|
|
355
|
+
async #handleThirdPartyDevelopeTools() {
|
|
391
356
|
if (this.#args.categoryExperimentalThirdParty &&
|
|
392
357
|
this.#listThirdPartyDeveloperTools &&
|
|
393
358
|
this.#page) {
|
|
394
|
-
|
|
395
|
-
if (thirdPartyDeveloperTools) {
|
|
396
|
-
this.#page.thirdPartyDeveloperTools = thirdPartyDeveloperTools;
|
|
397
|
-
}
|
|
359
|
+
return await this.#page.getToolGroups();
|
|
398
360
|
}
|
|
399
|
-
|
|
361
|
+
return undefined;
|
|
362
|
+
}
|
|
363
|
+
async #handleWebMCP() {
|
|
400
364
|
if (this.#args.categoryExperimentalWebmcp &&
|
|
401
365
|
this.#listWebMcpTools &&
|
|
402
366
|
this.#page) {
|
|
403
|
-
|
|
367
|
+
return this.#page.getWebMcpTools();
|
|
404
368
|
}
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
369
|
+
return undefined;
|
|
370
|
+
}
|
|
371
|
+
async #handleConsoleList(context) {
|
|
372
|
+
if (!this.#consoleDataOptions?.include) {
|
|
373
|
+
return undefined;
|
|
374
|
+
}
|
|
375
|
+
let messages;
|
|
376
|
+
let page;
|
|
377
|
+
if (this.#consoleDataOptions.serviceWorkerId) {
|
|
378
|
+
messages = context.getServiceWorkerConsoleData(this.#consoleDataOptions.serviceWorkerId);
|
|
379
|
+
}
|
|
380
|
+
else {
|
|
381
|
+
page = this.#page;
|
|
382
|
+
if (!page) {
|
|
408
383
|
throw new Error(`Response must have an McpPage`);
|
|
409
384
|
}
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
}
|
|
418
|
-
if (message instanceof DevTools.AggregatedIssue) {
|
|
419
|
-
return normalizedTypes.has('issue');
|
|
420
|
-
}
|
|
421
|
-
return normalizedTypes.has('error');
|
|
422
|
-
});
|
|
423
|
-
}
|
|
424
|
-
consoleMessages = (await Promise.all(messages.map(async (item) => {
|
|
425
|
-
const consoleMessageStableId = context.getConsoleMessageStableId(item);
|
|
426
|
-
if ('args' in item || item instanceof UncaughtError) {
|
|
427
|
-
const consoleMessage = item;
|
|
428
|
-
const devTools = context.getDevToolsUniverse(page);
|
|
429
|
-
return await ConsoleFormatter.from(consoleMessage, {
|
|
430
|
-
id: consoleMessageStableId,
|
|
431
|
-
fetchDetailedData: false,
|
|
432
|
-
devTools: devTools ?? undefined,
|
|
433
|
-
});
|
|
385
|
+
messages = page.getConsoleData(this.#consoleDataOptions.includePreservedMessages);
|
|
386
|
+
}
|
|
387
|
+
if (this.#consoleDataOptions.types?.length) {
|
|
388
|
+
const normalizedTypes = new Set(this.#consoleDataOptions.types);
|
|
389
|
+
messages = messages.filter(message => {
|
|
390
|
+
if ('type' in message) {
|
|
391
|
+
return normalizedTypes.has(message.type());
|
|
434
392
|
}
|
|
435
|
-
if (
|
|
436
|
-
|
|
437
|
-
id: consoleMessageStableId,
|
|
438
|
-
});
|
|
439
|
-
if (!formatter.isValid()) {
|
|
440
|
-
return null;
|
|
441
|
-
}
|
|
442
|
-
return formatter;
|
|
393
|
+
if (message instanceof DevTools.AggregatedIssue) {
|
|
394
|
+
return normalizedTypes.has('issue');
|
|
443
395
|
}
|
|
444
|
-
return
|
|
445
|
-
})
|
|
396
|
+
return normalizedTypes.has('error');
|
|
397
|
+
});
|
|
446
398
|
}
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
if (
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
requests = requests.filter(request => {
|
|
457
|
-
const type = request.resourceType();
|
|
458
|
-
return normalizedTypes.has(type);
|
|
399
|
+
return (await Promise.all(messages.map(async (item) => {
|
|
400
|
+
const consoleMessageStableId = this.getConsoleMessageStableId(item);
|
|
401
|
+
if ('args' in item || item instanceof UncaughtError) {
|
|
402
|
+
const consoleMessage = item;
|
|
403
|
+
return await ConsoleFormatter.from(consoleMessage, {
|
|
404
|
+
id: consoleMessageStableId,
|
|
405
|
+
fetchDetailedData: false,
|
|
406
|
+
fetchStackTrace: this.#consoleDataOptions?.includeStackTraces,
|
|
407
|
+
devTools: page ? page.devtoolsUniverse : undefined,
|
|
459
408
|
});
|
|
460
409
|
}
|
|
461
|
-
if (
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
})));
|
|
410
|
+
if (item instanceof DevTools.AggregatedIssue) {
|
|
411
|
+
const formatter = new IssueFormatter(item, {
|
|
412
|
+
id: consoleMessageStableId,
|
|
413
|
+
});
|
|
414
|
+
if (!formatter.isValid()) {
|
|
415
|
+
return null;
|
|
416
|
+
}
|
|
417
|
+
return formatter;
|
|
470
418
|
}
|
|
419
|
+
return null;
|
|
420
|
+
}))).filter(item => item !== null);
|
|
421
|
+
}
|
|
422
|
+
async #handleNetworkRequestList(context) {
|
|
423
|
+
if (!this.#networkRequestsOptions?.include) {
|
|
424
|
+
return undefined;
|
|
425
|
+
}
|
|
426
|
+
if (!this.#page) {
|
|
427
|
+
throw new Error(`Response must have an McpPage`);
|
|
428
|
+
}
|
|
429
|
+
let requests = this.#page.getNetworkRequests(this.#networkRequestsOptions?.includePreservedRequests);
|
|
430
|
+
// Apply resource type filtering if specified
|
|
431
|
+
if (this.#networkRequestsOptions.resourceTypes?.length) {
|
|
432
|
+
const normalizedTypes = new Set(this.#networkRequestsOptions.resourceTypes);
|
|
433
|
+
requests = requests.filter(request => {
|
|
434
|
+
const type = request.resourceType();
|
|
435
|
+
return normalizedTypes.has(type);
|
|
436
|
+
});
|
|
471
437
|
}
|
|
472
|
-
return
|
|
438
|
+
return await Promise.all(requests.map(request => NetworkFormatter.from(request, {
|
|
439
|
+
requestId: this.getNetworkRequestStableId(request),
|
|
440
|
+
selectedInDevToolsUI: this.getNetworkRequestStableId(request) ===
|
|
441
|
+
this.#networkRequestsOptions?.networkRequestIdInDevToolsUI,
|
|
442
|
+
fetchData: false,
|
|
443
|
+
saveFile: (data, filename, extension) => context.saveFile(data, filename, extension),
|
|
444
|
+
redactNetworkHeaders: this.#redactNetworkHeaders,
|
|
445
|
+
})));
|
|
446
|
+
}
|
|
447
|
+
async handle(context, dataFormat = 'default') {
|
|
448
|
+
const [snapshot, detailedNetworkRequest, detailedConsoleMessage, thirdPartyDeveloperTools, webmcpTools, consoleMessages, networkRequests,] = await Promise.all([
|
|
449
|
+
this.#handleSnapshot(context),
|
|
450
|
+
this.#handleAttachedNetworkRequest(context),
|
|
451
|
+
this.#handleAttachedConsoleMessage(),
|
|
452
|
+
this.#handleThirdPartyDevelopeTools(),
|
|
453
|
+
this.#handleWebMCP(),
|
|
454
|
+
this.#handleConsoleList(context),
|
|
455
|
+
this.#handleNetworkRequestList(context),
|
|
456
|
+
]);
|
|
457
|
+
if (this.#includeExtensionServiceWorkers) {
|
|
458
|
+
await context.createExtensionServiceWorkersSnapshot();
|
|
459
|
+
}
|
|
460
|
+
let extensions;
|
|
461
|
+
if (this.#listExtensions) {
|
|
462
|
+
extensions = await context.listExtensions();
|
|
463
|
+
}
|
|
464
|
+
return this.format(context, {
|
|
473
465
|
detailedConsoleMessage,
|
|
474
466
|
consoleMessages,
|
|
475
467
|
snapshot,
|
|
@@ -482,15 +474,56 @@ export class McpResponse {
|
|
|
482
474
|
thirdPartyDeveloperTools,
|
|
483
475
|
webmcpTools,
|
|
484
476
|
errorMessage: this.#error?.message,
|
|
485
|
-
});
|
|
477
|
+
}, dataFormat);
|
|
486
478
|
}
|
|
487
|
-
|
|
479
|
+
getConsoleMessageStableId(message) {
|
|
480
|
+
return message[stableIdSymbol] ?? -1;
|
|
481
|
+
}
|
|
482
|
+
getNetworkRequestStableId(request) {
|
|
483
|
+
return request[stableIdSymbol] ?? -1;
|
|
484
|
+
}
|
|
485
|
+
async format(context, data, dataFormat = 'default') {
|
|
488
486
|
const structuredContent = {};
|
|
487
|
+
// Resolve the compact encoder based on the chosen format
|
|
488
|
+
let compactEncode;
|
|
489
|
+
if (dataFormat === 'toon') {
|
|
490
|
+
try {
|
|
491
|
+
compactEncode = await getToonEncode();
|
|
492
|
+
}
|
|
493
|
+
catch {
|
|
494
|
+
throw new Error('The `@toon-format/toon` package is required to use --experimentalDataFormat=toon. ' +
|
|
495
|
+
'Make sure the peer dependency is installed:\n' +
|
|
496
|
+
'- For npx: npx --package chrome-devtools-mcp@latest --package @toon-format/toon@latest chrome-devtools-mcp --experimentalDataFormat=toon\n' +
|
|
497
|
+
'- For npm: npm install @toon-format/toon (add -g if installed globally)');
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
else if (dataFormat === 'gcf') {
|
|
501
|
+
try {
|
|
502
|
+
compactEncode = await getGcfEncode();
|
|
503
|
+
}
|
|
504
|
+
catch {
|
|
505
|
+
throw new Error('The `@blackwell-systems/gcf` package is required to use --experimentalDataFormat=gcf. ' +
|
|
506
|
+
'Make sure the peer dependency is installed:\n' +
|
|
507
|
+
'- For npx: npx --package chrome-devtools-mcp@latest --package @blackwell-systems/gcf@latest chrome-devtools-mcp --experimentalDataFormat=gcf\n' +
|
|
508
|
+
'- For npm: npm install @blackwell-systems/gcf (add -g if installed globally)');
|
|
509
|
+
}
|
|
510
|
+
}
|
|
489
511
|
const response = [];
|
|
512
|
+
if (this.#reconnectNotice) {
|
|
513
|
+
structuredContent.reconnected = true;
|
|
514
|
+
response.push(`Note: the browser was restarted or reconnected since the last call. Page ids have changed. Call ${listPages().name} to see open pages.`);
|
|
515
|
+
}
|
|
490
516
|
if (this.#textResponseLines.length) {
|
|
491
517
|
structuredContent.message = this.#textResponseLines.join('\n');
|
|
492
518
|
response.push(...this.#textResponseLines);
|
|
493
519
|
}
|
|
520
|
+
if (this.#attachedWaitForResult) {
|
|
521
|
+
if (this.#attachedWaitForResult.navigatedToUrl) {
|
|
522
|
+
response.push(`Page navigated to ${this.#attachedWaitForResult.navigatedToUrl}.`);
|
|
523
|
+
structuredContent.navigatedToUrl =
|
|
524
|
+
this.#attachedWaitForResult.navigatedToUrl;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
494
527
|
const networkConditions = this.#page?.networkConditions;
|
|
495
528
|
if (networkConditions) {
|
|
496
529
|
const timeout = this.#page.pptrPage.getDefaultNavigationTimeout();
|
|
@@ -499,6 +532,11 @@ export class McpResponse {
|
|
|
499
532
|
structuredContent.networkConditions = networkConditions;
|
|
500
533
|
structuredContent.navigationTimeout = timeout;
|
|
501
534
|
}
|
|
535
|
+
const geolocation = this.#page?.geolocation;
|
|
536
|
+
if (geolocation) {
|
|
537
|
+
response.push(`Emulating geolocation: latitude=${geolocation.latitude}, longitude=${geolocation.longitude}`);
|
|
538
|
+
structuredContent.geolocation = geolocation;
|
|
539
|
+
}
|
|
502
540
|
const viewport = this.#page?.viewport;
|
|
503
541
|
if (viewport) {
|
|
504
542
|
response.push(`Emulating viewport: ${JSON.stringify(viewport)}`);
|
|
@@ -535,25 +573,40 @@ Call ${handleDialog.name} to handle it before continuing.`);
|
|
|
535
573
|
}
|
|
536
574
|
if (this.#includePages) {
|
|
537
575
|
const allPages = context.getPages();
|
|
538
|
-
const { regularPages, extensionPages } = allPages.reduce((acc,
|
|
539
|
-
if (
|
|
540
|
-
acc.extensionPages.push(
|
|
576
|
+
const { regularPages, extensionPages } = allPages.reduce((acc, mcpPage) => {
|
|
577
|
+
if (mcpPage.pptrPage.url().startsWith('chrome-extension://')) {
|
|
578
|
+
acc.extensionPages.push(mcpPage);
|
|
541
579
|
}
|
|
542
580
|
else {
|
|
543
|
-
acc.regularPages.push(
|
|
581
|
+
acc.regularPages.push(mcpPage);
|
|
544
582
|
}
|
|
545
583
|
return acc;
|
|
546
584
|
}, { regularPages: [], extensionPages: [] });
|
|
585
|
+
const selectionFallback = context.getSelectedPageFallback();
|
|
586
|
+
if (selectionFallback) {
|
|
587
|
+
let selectedPageId;
|
|
588
|
+
try {
|
|
589
|
+
selectedPageId = context.getSelectedMcpPage().id;
|
|
590
|
+
}
|
|
591
|
+
catch {
|
|
592
|
+
selectedPageId = undefined;
|
|
593
|
+
}
|
|
594
|
+
response.push(`Note: the previously selected page ${selectionFallback.wasClosed ? 'was closed' : 'is no longer listed'}.${selectedPageId !== undefined ? ` Page ${selectedPageId} is now selected.` : ''}`);
|
|
595
|
+
}
|
|
547
596
|
if (regularPages.length) {
|
|
548
597
|
const parts = [`## Pages`];
|
|
549
598
|
const structuredPages = [];
|
|
550
|
-
for (const
|
|
551
|
-
const isolatedContextName =
|
|
599
|
+
for (const mcpPage of regularPages) {
|
|
600
|
+
const isolatedContextName = mcpPage.isolatedContextName;
|
|
552
601
|
const contextLabel = isolatedContextName
|
|
553
602
|
? ` isolatedContext=${isolatedContextName}`
|
|
554
603
|
: '';
|
|
555
|
-
|
|
556
|
-
|
|
604
|
+
const title = await fetchPageTitle(mcpPage.pptrPage);
|
|
605
|
+
const pageLabel = title
|
|
606
|
+
? `${truncateTitle(title)} (${mcpPage.pptrPage.url()})`
|
|
607
|
+
: mcpPage.pptrPage.url();
|
|
608
|
+
parts.push(`${mcpPage.id}: ${pageLabel}${context.isPageSelected(mcpPage) ? ' [selected]' : ''}${contextLabel}`);
|
|
609
|
+
structuredPages.push(createStructuredPage(mcpPage, context, title));
|
|
557
610
|
}
|
|
558
611
|
response.push(...parts);
|
|
559
612
|
structuredContent.pages = structuredPages;
|
|
@@ -562,13 +615,17 @@ Call ${handleDialog.name} to handle it before continuing.`);
|
|
|
562
615
|
if (extensionPages.length) {
|
|
563
616
|
response.push(`## Extension Pages`);
|
|
564
617
|
const structuredExtensionPages = [];
|
|
565
|
-
for (const
|
|
566
|
-
const isolatedContextName =
|
|
618
|
+
for (const mcpPage of extensionPages) {
|
|
619
|
+
const isolatedContextName = mcpPage.isolatedContextName;
|
|
567
620
|
const contextLabel = isolatedContextName
|
|
568
621
|
? ` isolatedContext=${isolatedContextName}`
|
|
569
622
|
: '';
|
|
570
|
-
|
|
571
|
-
|
|
623
|
+
const title = await fetchPageTitle(mcpPage.pptrPage);
|
|
624
|
+
const pageLabel = title
|
|
625
|
+
? `${truncateTitle(title)} (${mcpPage.pptrPage.url()})`
|
|
626
|
+
: mcpPage.pptrPage.url();
|
|
627
|
+
response.push(`${mcpPage.id}: ${pageLabel}${context.isPageSelected(mcpPage) ? ' [selected]' : ''}${contextLabel}`);
|
|
628
|
+
structuredExtensionPages.push(createStructuredPage(mcpPage, context, title));
|
|
572
629
|
}
|
|
573
630
|
structuredContent.extensionPages = structuredExtensionPages;
|
|
574
631
|
}
|
|
@@ -594,7 +651,7 @@ Call ${handleDialog.name} to handle it before continuing.`);
|
|
|
594
651
|
structuredContent.tabId = this.#tabId;
|
|
595
652
|
}
|
|
596
653
|
if (data.traceSummary) {
|
|
597
|
-
const summary = getTraceSummary(data.traceSummary);
|
|
654
|
+
const summary = getTraceSummary(data.traceSummary, this.#deviceScope);
|
|
598
655
|
response.push(summary);
|
|
599
656
|
structuredContent.traceSummary = summary;
|
|
600
657
|
structuredContent.traceInsights = [];
|
|
@@ -602,13 +659,17 @@ Call ${handleDialog.name} to handle it before continuing.`);
|
|
|
602
659
|
for (const [insightName, model] of Object.entries(insightSet.model)) {
|
|
603
660
|
structuredContent.traceInsights.push({
|
|
604
661
|
insightName,
|
|
605
|
-
insightKey: model
|
|
662
|
+
insightKey: typeof model === 'object' &&
|
|
663
|
+
model !== null &&
|
|
664
|
+
'insightKey' in model
|
|
665
|
+
? model.insightKey
|
|
666
|
+
: undefined,
|
|
606
667
|
});
|
|
607
668
|
}
|
|
608
669
|
}
|
|
609
670
|
}
|
|
610
671
|
if (data.traceInsight) {
|
|
611
|
-
const insightOutput = getInsightOutput(data.traceInsight.trace, data.traceInsight.insightSetId, data.traceInsight.insightName);
|
|
672
|
+
const insightOutput = getInsightOutput(data.traceInsight.trace, data.traceInsight.insightSetId, data.traceInsight.insightName, this.#deviceScope);
|
|
612
673
|
if ('error' in insightOutput) {
|
|
613
674
|
response.push(insightOutput.error);
|
|
614
675
|
}
|
|
@@ -642,9 +703,11 @@ Call ${handleDialog.name} to handle it before continuing.`);
|
|
|
642
703
|
structuredContent.snapshotFilePath = data.snapshot;
|
|
643
704
|
}
|
|
644
705
|
else {
|
|
645
|
-
response.push('## Latest page snapshot');
|
|
646
|
-
response.push(data.snapshot.toString());
|
|
647
706
|
structuredContent.snapshot = data.snapshot.toJSON();
|
|
707
|
+
response.push('## Latest page snapshot');
|
|
708
|
+
response.push(compactEncode
|
|
709
|
+
? compactEncode(structuredContent.snapshot)
|
|
710
|
+
: data.snapshot.toString());
|
|
648
711
|
}
|
|
649
712
|
}
|
|
650
713
|
if (this.#heapSnapshotOptions?.include) {
|
|
@@ -661,28 +724,125 @@ Call ${handleDialog.name} to handle it before continuing.`);
|
|
|
661
724
|
structuredContent.heapSnapshot = structuredContent.heapSnapshot || {};
|
|
662
725
|
structuredContent.heapSnapshot.staticData = staticData;
|
|
663
726
|
}
|
|
664
|
-
const
|
|
665
|
-
if (
|
|
666
|
-
|
|
727
|
+
const nativeContextSizes = this.#heapSnapshotOptions.nativeContextSizes;
|
|
728
|
+
if (nativeContextSizes) {
|
|
729
|
+
response.push('### Native Contexts');
|
|
730
|
+
response.push(HeapSnapshotFormatter.formatNativeContextSizes(nativeContextSizes));
|
|
731
|
+
structuredContent.heapSnapshot = structuredContent.heapSnapshot || {};
|
|
732
|
+
structuredContent.heapSnapshot.nativeContextSizes = nativeContextSizes;
|
|
733
|
+
}
|
|
734
|
+
const retainedByContextSummary = this.#heapSnapshotOptions.retainedByContextSummary;
|
|
735
|
+
if (retainedByContextSummary) {
|
|
736
|
+
response.push('### Retained by Context Summary');
|
|
737
|
+
response.push(HeapSnapshotFormatter.formatRetainedByContextSummary(retainedByContextSummary));
|
|
738
|
+
structuredContent.heapSnapshot = structuredContent.heapSnapshot || {};
|
|
739
|
+
structuredContent.heapSnapshot.retainedByContextSummary =
|
|
740
|
+
retainedByContextSummary;
|
|
741
|
+
}
|
|
742
|
+
const aggregateData = this.#heapSnapshotOptions.aggregateData;
|
|
743
|
+
if (aggregateData) {
|
|
744
|
+
const sortedEntries = HeapSnapshotFormatter.sort(aggregateData.aggregates);
|
|
667
745
|
const paginationData = this.#dataWithPagination(sortedEntries, this.#heapSnapshotOptions.pagination);
|
|
746
|
+
response.push(`Objects: ${aggregateData.objectCount}`);
|
|
747
|
+
response.push(`Total shallow size: ${formatBytesToKb(aggregateData.totalSelfSize)}`);
|
|
748
|
+
structuredContent.heapSnapshot = structuredContent.heapSnapshot || {};
|
|
749
|
+
structuredContent.heapSnapshot.aggregateStats = {
|
|
750
|
+
objectCount: aggregateData.objectCount,
|
|
751
|
+
totalSelfSize: aggregateData.totalSelfSize,
|
|
752
|
+
};
|
|
668
753
|
structuredContent.pagination = paginationData.pagination;
|
|
669
754
|
response.push(...paginationData.info);
|
|
670
755
|
const paginatedRecord = Object.fromEntries(paginationData.items);
|
|
671
756
|
const formatter = new HeapSnapshotFormatter(paginatedRecord);
|
|
672
|
-
response.push(formatter.toString());
|
|
673
757
|
structuredContent.heapSnapshotData = formatter.toJSON();
|
|
758
|
+
response.push(compactEncode
|
|
759
|
+
? compactEncode(structuredContent.heapSnapshotData)
|
|
760
|
+
: formatter.toString());
|
|
674
761
|
}
|
|
675
762
|
const nodes = this.#heapSnapshotOptions.nodes;
|
|
676
763
|
if (nodes) {
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
764
|
+
let items = Array.from(nodes.items);
|
|
765
|
+
const firstItem = nodes.items[0];
|
|
766
|
+
if (firstItem) {
|
|
767
|
+
if (isNodeLike(firstItem)) {
|
|
768
|
+
items = items
|
|
769
|
+
.filter(isNodeLike)
|
|
770
|
+
.sort((a, b) => b.retainedSize - a.retainedSize);
|
|
771
|
+
}
|
|
772
|
+
else if (isEdgeLike(firstItem)) {
|
|
773
|
+
items = items.filter(isEdgeLike);
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
const paginationData = this.#dataWithPagination(items, this.#heapSnapshotOptions.pagination);
|
|
681
777
|
response.push(HeapSnapshotFormatter.formatNodes(paginationData.items));
|
|
682
778
|
structuredContent.pagination = paginationData.pagination;
|
|
683
779
|
response.push(...paginationData.info);
|
|
684
780
|
structuredContent.heapSnapshotNodes = paginationData.items;
|
|
685
781
|
}
|
|
782
|
+
const retainingPaths = this.#heapSnapshotOptions.retainingPaths;
|
|
783
|
+
if (retainingPaths) {
|
|
784
|
+
response.push('### Retaining Paths');
|
|
785
|
+
const { paths, limitsReached } = retainingPaths;
|
|
786
|
+
if (paths.length === 0) {
|
|
787
|
+
response.push('No retaining paths found.');
|
|
788
|
+
}
|
|
789
|
+
else {
|
|
790
|
+
response.push(HeapSnapshotFormatter.formatRetainingPaths(paths));
|
|
791
|
+
}
|
|
792
|
+
const reached = Object.entries(limitsReached)
|
|
793
|
+
.filter(([, hit]) => hit)
|
|
794
|
+
.map(([limit]) => limit);
|
|
795
|
+
if (reached.length > 0) {
|
|
796
|
+
response.push(`Note: results are truncated, the following limits were reached: ${reached.join(', ')}.`);
|
|
797
|
+
}
|
|
798
|
+
structuredContent.heapSnapshotRetainingPaths =
|
|
799
|
+
retainingPaths;
|
|
800
|
+
}
|
|
801
|
+
const dominators = this.#heapSnapshotOptions.dominators;
|
|
802
|
+
if (dominators) {
|
|
803
|
+
response.push('### Dominator Chain');
|
|
804
|
+
if (dominators.length === 0) {
|
|
805
|
+
response.push('No dominators found.');
|
|
806
|
+
}
|
|
807
|
+
else {
|
|
808
|
+
response.push(HeapSnapshotFormatter.formatDominators(dominators));
|
|
809
|
+
}
|
|
810
|
+
structuredContent.heapSnapshotDominators = dominators;
|
|
811
|
+
}
|
|
812
|
+
const classDiffs = this.#heapSnapshotOptions.classDiffs;
|
|
813
|
+
if (classDiffs) {
|
|
814
|
+
response.push('### Heap Snapshot Diff');
|
|
815
|
+
response.push(compactEncode
|
|
816
|
+
? compactEncode(classDiffs)
|
|
817
|
+
: HeapSnapshotFormatter.formatDiffSummary(classDiffs));
|
|
818
|
+
structuredContent.heapSnapshotClassDiffs = classDiffs;
|
|
819
|
+
}
|
|
820
|
+
const detailedClassDiff = this.#heapSnapshotOptions.detailedClassDiff;
|
|
821
|
+
if (detailedClassDiff) {
|
|
822
|
+
response.push('### Heap Snapshot Detailed Diff');
|
|
823
|
+
response.push(compactEncode
|
|
824
|
+
? compactEncode(detailedClassDiff)
|
|
825
|
+
: HeapSnapshotFormatter.formatDiffDetails(detailedClassDiff));
|
|
826
|
+
structuredContent.heapSnapshotDetailedClassDiff = detailedClassDiff;
|
|
827
|
+
}
|
|
828
|
+
const duplicateStrings = this.#heapSnapshotOptions.duplicateStrings;
|
|
829
|
+
if (duplicateStrings) {
|
|
830
|
+
response.push('### Duplicate Strings');
|
|
831
|
+
const paginationData = this.#dataWithPagination(duplicateStrings, this.#heapSnapshotOptions.pagination);
|
|
832
|
+
structuredContent.pagination = paginationData.pagination;
|
|
833
|
+
response.push(...paginationData.info);
|
|
834
|
+
const formatted = HeapSnapshotFormatter.formatDuplicateStrings(paginationData.items);
|
|
835
|
+
response.push(formatted);
|
|
836
|
+
structuredContent.heapSnapshotDuplicateStrings = paginationData.items;
|
|
837
|
+
}
|
|
838
|
+
const objectInfo = this.#heapSnapshotOptions.objectInfo;
|
|
839
|
+
if (objectInfo) {
|
|
840
|
+
response.push('### Object Details');
|
|
841
|
+
response.push(compactEncode
|
|
842
|
+
? compactEncode(objectInfo)
|
|
843
|
+
: HeapSnapshotFormatter.formatObjectInfo(objectInfo));
|
|
844
|
+
structuredContent.heapSnapshotObjectDetails = objectInfo;
|
|
845
|
+
}
|
|
686
846
|
}
|
|
687
847
|
if (data.detailedNetworkRequest) {
|
|
688
848
|
response.push(data.detailedNetworkRequest.toStringDetailed());
|
|
@@ -710,18 +870,11 @@ Call ${handleDialog.name} to handle it before continuing.`);
|
|
|
710
870
|
response.push(extensionsMessage);
|
|
711
871
|
}
|
|
712
872
|
}
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
data.thirdPartyDeveloperTools;
|
|
717
|
-
}
|
|
873
|
+
const thirdPartyDeveloperTools = data.thirdPartyDeveloperTools;
|
|
874
|
+
if (thirdPartyDeveloperTools?.length) {
|
|
875
|
+
structuredContent.thirdPartyDeveloperTools = thirdPartyDeveloperTools;
|
|
718
876
|
response.push('## Third-party developer tools');
|
|
719
|
-
|
|
720
|
-
!data.thirdPartyDeveloperTools?.tools) {
|
|
721
|
-
response.push('No third-party developer tools available.');
|
|
722
|
-
}
|
|
723
|
-
else {
|
|
724
|
-
const toolGroup = data.thirdPartyDeveloperTools;
|
|
877
|
+
for (const toolGroup of thirdPartyDeveloperTools) {
|
|
725
878
|
response.push(`${toolGroup.name}: ${toolGroup.description}`);
|
|
726
879
|
response.push('Available tools:');
|
|
727
880
|
const toolDefinitionsMessage = toolGroup.tools
|
|
@@ -760,11 +913,10 @@ Call ${handleDialog.name} to handle it before continuing.`);
|
|
|
760
913
|
structuredContent.pagination = paginationData.pagination;
|
|
761
914
|
response.push(...paginationData.info);
|
|
762
915
|
if (data.networkRequests) {
|
|
763
|
-
structuredContent.networkRequests =
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
}
|
|
916
|
+
structuredContent.networkRequests = paginationData.items.map(i => i.toJSON());
|
|
917
|
+
response.push(...(compactEncode
|
|
918
|
+
? [compactEncode(structuredContent.networkRequests)]
|
|
919
|
+
: paginationData.items.map(i => i.toString())));
|
|
768
920
|
}
|
|
769
921
|
}
|
|
770
922
|
else {
|
|
@@ -778,9 +930,17 @@ Call ${handleDialog.name} to handle it before continuing.`);
|
|
|
778
930
|
const grouped = ConsoleFormatter.groupConsecutive(messages);
|
|
779
931
|
const paginationData = this.#dataWithPagination(grouped, this.#consoleDataOptions.pagination);
|
|
780
932
|
structuredContent.pagination = paginationData.pagination;
|
|
781
|
-
response.push(...paginationData.info);
|
|
782
|
-
response.push(...paginationData.items.map(item => item.toString()));
|
|
783
933
|
structuredContent.consoleMessages = paginationData.items.map(item => item.toJSON());
|
|
934
|
+
response.push(...paginationData.info);
|
|
935
|
+
if (compactEncode) {
|
|
936
|
+
response.push(compactEncode(structuredContent.consoleMessages));
|
|
937
|
+
}
|
|
938
|
+
else {
|
|
939
|
+
response.push(...paginationData.items.map(item => item.toString()));
|
|
940
|
+
}
|
|
941
|
+
if (structuredContent.consoleMessages.some(message => 'stackTrace' in message)) {
|
|
942
|
+
response.push('Note: stack trace line and column numbers use 1-based indexing');
|
|
943
|
+
}
|
|
784
944
|
}
|
|
785
945
|
else {
|
|
786
946
|
response.push('<no console messages found>');
|
|
@@ -839,12 +999,26 @@ Call ${handleDialog.name} to handle it before continuing.`);
|
|
|
839
999
|
this.#textResponseLines = [];
|
|
840
1000
|
}
|
|
841
1001
|
}
|
|
842
|
-
function
|
|
843
|
-
|
|
1002
|
+
function truncateTitle(title, maxLength = 50) {
|
|
1003
|
+
if (title.length <= maxLength) {
|
|
1004
|
+
return title;
|
|
1005
|
+
}
|
|
1006
|
+
return title.slice(0, maxLength - 3) + '...';
|
|
1007
|
+
}
|
|
1008
|
+
async function fetchPageTitle(page) {
|
|
1009
|
+
return Promise.race([
|
|
1010
|
+
page.title().catch(() => ''),
|
|
1011
|
+
new Promise(resolve => setTimeout(() => resolve(''), 1000)),
|
|
1012
|
+
]);
|
|
1013
|
+
}
|
|
1014
|
+
function createStructuredPage(mcpPage, context, rawTitle) {
|
|
1015
|
+
const isolatedContextName = mcpPage.isolatedContextName;
|
|
1016
|
+
const title = truncateTitle(rawTitle);
|
|
844
1017
|
const entry = {
|
|
845
|
-
id:
|
|
846
|
-
url:
|
|
847
|
-
|
|
1018
|
+
id: mcpPage.id,
|
|
1019
|
+
url: mcpPage.pptrPage.url(),
|
|
1020
|
+
title,
|
|
1021
|
+
selected: context.isPageSelected(mcpPage),
|
|
848
1022
|
};
|
|
849
1023
|
if (isolatedContextName) {
|
|
850
1024
|
entry.isolatedContext = isolatedContextName;
|