opera-devtools-mcp 0.2.4 → 0.4.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 +108 -8
- 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 +614 -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 +116 -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 +193 -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 +232 -1061
- package/build/src/third_party/bundled-packages.json +7 -8
- package/build/src/third_party/devtools-formatter-worker.js +63 -22
- package/build/src/third_party/devtools-heap-snapshot-worker.js +809 -182
- package/build/src/third_party/index.js +69558 -74691
- 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 -4
- package/package.json +43 -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/tools/tools.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Modified by Opera Software AS.
|
|
7
7
|
*/
|
|
8
|
+
import * as operaTools from '../opera/tools/opera.js';
|
|
8
9
|
import * as consoleTools from './console.js';
|
|
9
10
|
import * as emulationTools from './emulation.js';
|
|
10
11
|
import * as extensionTools from './extensions.js';
|
|
@@ -12,9 +13,9 @@ import * as inputTools from './input.js';
|
|
|
12
13
|
import * as lighthouseTools from './lighthouse.js';
|
|
13
14
|
import * as memoryTools from './memory.js';
|
|
14
15
|
import * as networkTools from './network.js';
|
|
15
|
-
import * as operaTools from './opera.js';
|
|
16
16
|
import * as pagesTools from './pages.js';
|
|
17
17
|
import * as performanceTools from './performance.js';
|
|
18
|
+
import * as pwaTools from './pwa.js';
|
|
18
19
|
import * as screencastTools from './screencast.js';
|
|
19
20
|
import * as screenshotTools from './screenshot.js';
|
|
20
21
|
import * as scriptTools from './script.js';
|
|
@@ -36,6 +37,7 @@ export const createTools = (args) => {
|
|
|
36
37
|
...Object.values(operaTools),
|
|
37
38
|
...Object.values(pagesTools),
|
|
38
39
|
...Object.values(performanceTools),
|
|
40
|
+
...Object.values(pwaTools),
|
|
39
41
|
...Object.values(screencastTools),
|
|
40
42
|
...Object.values(screenshotTools),
|
|
41
43
|
...Object.values(scriptTools),
|
|
@@ -15,7 +15,8 @@ export const listWebMcpTools = definePageTool({
|
|
|
15
15
|
},
|
|
16
16
|
schema: {},
|
|
17
17
|
blockedByDialog: false,
|
|
18
|
-
|
|
18
|
+
verifyFilesSchema: {},
|
|
19
|
+
handler: async (_request, response) => {
|
|
19
20
|
response.setListWebMcpTools();
|
|
20
21
|
},
|
|
21
22
|
});
|
|
@@ -34,6 +35,7 @@ export const executeWebMcpTool = definePageTool({
|
|
|
34
35
|
.describe('The JSON-stringified parameters to pass to the WebMCP tool'),
|
|
35
36
|
},
|
|
36
37
|
blockedByDialog: false,
|
|
38
|
+
verifyFilesSchema: {},
|
|
37
39
|
handler: async (request, response) => {
|
|
38
40
|
const toolName = request.params.toolName;
|
|
39
41
|
let input = {};
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
|
|
7
|
+
if (value !== null && value !== void 0) {
|
|
8
|
+
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
9
|
+
var dispose, inner;
|
|
10
|
+
if (async) {
|
|
11
|
+
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
12
|
+
dispose = value[Symbol.asyncDispose];
|
|
13
|
+
}
|
|
14
|
+
if (dispose === void 0) {
|
|
15
|
+
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
16
|
+
dispose = value[Symbol.dispose];
|
|
17
|
+
if (async) inner = dispose;
|
|
18
|
+
}
|
|
19
|
+
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
20
|
+
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
21
|
+
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
22
|
+
}
|
|
23
|
+
else if (async) {
|
|
24
|
+
env.stack.push({ async: true });
|
|
25
|
+
}
|
|
26
|
+
return value;
|
|
27
|
+
};
|
|
28
|
+
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
29
|
+
return function (env) {
|
|
30
|
+
function fail(e) {
|
|
31
|
+
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
32
|
+
env.hasError = true;
|
|
33
|
+
}
|
|
34
|
+
var r, s = 0;
|
|
35
|
+
function next() {
|
|
36
|
+
while (r = env.stack.pop()) {
|
|
37
|
+
try {
|
|
38
|
+
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
39
|
+
if (r.dispose) {
|
|
40
|
+
var result = r.dispose.call(r.value);
|
|
41
|
+
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
42
|
+
}
|
|
43
|
+
else s |= 1;
|
|
44
|
+
}
|
|
45
|
+
catch (e) {
|
|
46
|
+
fail(e);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
50
|
+
if (env.hasError) throw env.error;
|
|
51
|
+
}
|
|
52
|
+
return next();
|
|
53
|
+
};
|
|
54
|
+
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
55
|
+
var e = new Error(message);
|
|
56
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
57
|
+
});
|
|
58
|
+
import { logger } from './logger.js';
|
|
59
|
+
export class WaitForHelper {
|
|
60
|
+
#abortController = new AbortController();
|
|
61
|
+
#page;
|
|
62
|
+
#stableDomTimeout;
|
|
63
|
+
#stableDomFor;
|
|
64
|
+
#expectNavigationIn;
|
|
65
|
+
#navigationTimeout;
|
|
66
|
+
#dialogHandled = false;
|
|
67
|
+
/** Track all dialogs as they pause the renderer. */
|
|
68
|
+
#dialogDetected = false;
|
|
69
|
+
#initialUrl;
|
|
70
|
+
constructor(page, cpuTimeoutMultiplier, networkTimeoutMultiplier) {
|
|
71
|
+
this.#stableDomTimeout = 3000 * cpuTimeoutMultiplier;
|
|
72
|
+
this.#stableDomFor = 100 * cpuTimeoutMultiplier;
|
|
73
|
+
this.#expectNavigationIn = 100 * cpuTimeoutMultiplier;
|
|
74
|
+
this.#navigationTimeout = 3000 * networkTimeoutMultiplier;
|
|
75
|
+
this.#page = page;
|
|
76
|
+
this.#initialUrl = page.url();
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* A wrapper that executes a action and waits for
|
|
80
|
+
* a potential navigation, after which it waits
|
|
81
|
+
* for the DOM to be stable before returning.
|
|
82
|
+
*/
|
|
83
|
+
async waitForStableDom() {
|
|
84
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
85
|
+
try {
|
|
86
|
+
// Bound the setup evaluation against the stable-DOM timeout. Without this
|
|
87
|
+
// cap a paused renderer (e.g. an open dialog) would make evaluateHandle
|
|
88
|
+
// hang until protocolTimeout (default 180s) while the tool mutex is held.
|
|
89
|
+
const stableDomObserver = __addDisposableResource(env_1, await Promise.race([
|
|
90
|
+
this.#page.evaluateHandle(timeout => {
|
|
91
|
+
let timeoutId;
|
|
92
|
+
function callback() {
|
|
93
|
+
clearTimeout(timeoutId);
|
|
94
|
+
timeoutId = setTimeout(() => {
|
|
95
|
+
domObserver.resolver.resolve();
|
|
96
|
+
domObserver.observer.disconnect();
|
|
97
|
+
}, timeout);
|
|
98
|
+
}
|
|
99
|
+
const domObserver = {
|
|
100
|
+
resolver: Promise.withResolvers(),
|
|
101
|
+
observer: new MutationObserver(callback),
|
|
102
|
+
};
|
|
103
|
+
// It's possible that the DOM is not gonna change so we
|
|
104
|
+
// need to start the timeout initially.
|
|
105
|
+
callback();
|
|
106
|
+
domObserver.observer.observe(document.body, {
|
|
107
|
+
childList: true,
|
|
108
|
+
subtree: true,
|
|
109
|
+
attributes: true,
|
|
110
|
+
});
|
|
111
|
+
return domObserver;
|
|
112
|
+
}, this.#stableDomFor),
|
|
113
|
+
this.timeout(this.#stableDomTimeout),
|
|
114
|
+
]).catch(() => undefined), false);
|
|
115
|
+
if (!stableDomObserver) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
this.#abortController.signal.addEventListener('abort', async () => {
|
|
119
|
+
try {
|
|
120
|
+
await stableDomObserver.evaluate(observer => {
|
|
121
|
+
observer.observer.disconnect();
|
|
122
|
+
observer.resolver.resolve();
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
// Ignored cleanup errors
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
return Promise.race([
|
|
130
|
+
stableDomObserver.evaluate(async (observer) => {
|
|
131
|
+
return await observer.resolver.promise;
|
|
132
|
+
}),
|
|
133
|
+
this.timeout(this.#stableDomTimeout).then(() => {
|
|
134
|
+
throw new Error('Timeout');
|
|
135
|
+
}),
|
|
136
|
+
]);
|
|
137
|
+
}
|
|
138
|
+
catch (e_1) {
|
|
139
|
+
env_1.error = e_1;
|
|
140
|
+
env_1.hasError = true;
|
|
141
|
+
}
|
|
142
|
+
finally {
|
|
143
|
+
__disposeResources(env_1);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
timeout(time) {
|
|
147
|
+
return new Promise(res => {
|
|
148
|
+
const id = setTimeout(res, time);
|
|
149
|
+
this.#abortController.signal.addEventListener('abort', () => {
|
|
150
|
+
res();
|
|
151
|
+
clearTimeout(id);
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
async waitForEventsAfterAction(action, options) {
|
|
156
|
+
if (this.#abortController.signal.aborted) {
|
|
157
|
+
throw new Error("Can't re-use a WaitForHelper");
|
|
158
|
+
}
|
|
159
|
+
const dialogHandler = (dialog) => {
|
|
160
|
+
this.#dialogDetected = true;
|
|
161
|
+
if (!options?.handleDialog) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
let actionToTake;
|
|
165
|
+
if (typeof options.handleDialog === 'object') {
|
|
166
|
+
actionToTake = options.handleDialog[dialog.type()];
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
actionToTake = options.handleDialog;
|
|
170
|
+
}
|
|
171
|
+
if (actionToTake) {
|
|
172
|
+
this.#dialogHandled = true;
|
|
173
|
+
if (actionToTake === 'dismiss') {
|
|
174
|
+
void dialog.dismiss();
|
|
175
|
+
}
|
|
176
|
+
else if (actionToTake === 'accept') {
|
|
177
|
+
void dialog.accept();
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
void dialog.accept(actionToTake);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
this.#page.on('dialog', dialogHandler);
|
|
185
|
+
this.#abortController.signal.addEventListener('abort', () => {
|
|
186
|
+
this.#page.off('dialog', dialogHandler);
|
|
187
|
+
});
|
|
188
|
+
// A scoped AbortController used to clean up navigation probe listeners.
|
|
189
|
+
// When aborted (either after navigation detection finishes or if this.#abortController
|
|
190
|
+
// aborts), it removes the CDP Page.frameStartedNavigating listener and automatically
|
|
191
|
+
// detaches the abort listener from this.#abortController.signal.
|
|
192
|
+
const navigationAbortController = new AbortController();
|
|
193
|
+
const navigationStartedResolvers = Promise.withResolvers();
|
|
194
|
+
const navigationListener = (event) => {
|
|
195
|
+
if (event.frameId !== this.#page.mainFrame()._id) {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
if (event.navigationType === 'sameDocument' ||
|
|
199
|
+
event.navigationType === 'historySameDocument') {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
navigationStartedResolvers.resolve(true);
|
|
203
|
+
};
|
|
204
|
+
this.#page._client().on('Page.frameStartedNavigating', navigationListener);
|
|
205
|
+
navigationAbortController.signal.addEventListener('abort', () => {
|
|
206
|
+
this.#page
|
|
207
|
+
._client()
|
|
208
|
+
.off('Page.frameStartedNavigating', navigationListener);
|
|
209
|
+
});
|
|
210
|
+
this.#abortController.signal.addEventListener('abort', () => {
|
|
211
|
+
navigationStartedResolvers.resolve(false);
|
|
212
|
+
navigationAbortController.abort();
|
|
213
|
+
}, { signal: navigationAbortController.signal });
|
|
214
|
+
// Puppeteer's waitForNavigation must be started before the action runs so that
|
|
215
|
+
// it captures the pre-action loader ID. If started after the action triggers navigation,
|
|
216
|
+
// it risks recording the new loader ID and hanging until timeout.
|
|
217
|
+
// If no navigation occurs, this.#abortController will cancel it in the finally block.
|
|
218
|
+
const navigationFinished = this.#page
|
|
219
|
+
.waitForNavigation({
|
|
220
|
+
timeout: options?.timeout ?? this.#navigationTimeout,
|
|
221
|
+
signal: this.#abortController.signal,
|
|
222
|
+
ignoreSameDocumentNavigation: true,
|
|
223
|
+
})
|
|
224
|
+
.then(result => {
|
|
225
|
+
navigationStartedResolvers.resolve(true);
|
|
226
|
+
return result;
|
|
227
|
+
})
|
|
228
|
+
.catch(error => {
|
|
229
|
+
if (this.#abortController.signal.aborted ||
|
|
230
|
+
(error instanceof Error && error.name === 'AbortError')) {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
logger?.(error);
|
|
234
|
+
});
|
|
235
|
+
try {
|
|
236
|
+
await action();
|
|
237
|
+
}
|
|
238
|
+
catch (error) {
|
|
239
|
+
// Clear up pending promises
|
|
240
|
+
this.#abortController.abort();
|
|
241
|
+
throw error;
|
|
242
|
+
}
|
|
243
|
+
const expectNavigationIn = options?.expectNavigationIn ?? this.#expectNavigationIn;
|
|
244
|
+
const navigationStarted = await Promise.race([
|
|
245
|
+
navigationStartedResolvers.promise,
|
|
246
|
+
this.timeout(expectNavigationIn).then(() => {
|
|
247
|
+
navigationStartedResolvers.resolve(false);
|
|
248
|
+
return false;
|
|
249
|
+
}),
|
|
250
|
+
]);
|
|
251
|
+
navigationAbortController.abort();
|
|
252
|
+
try {
|
|
253
|
+
// Only await navigation if one was actually initiated; otherwise, the
|
|
254
|
+
// pending waitForNavigation promise will be cancelled when this.#abortController aborts.
|
|
255
|
+
if (navigationStarted) {
|
|
256
|
+
await navigationFinished;
|
|
257
|
+
}
|
|
258
|
+
if (this.#dialogDetected) {
|
|
259
|
+
return this.#getResult();
|
|
260
|
+
}
|
|
261
|
+
// Wait for stable dom after navigation so we execute in
|
|
262
|
+
// the correct context
|
|
263
|
+
if (options?.waitForStableDom !== false) {
|
|
264
|
+
await this.waitForStableDom();
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
catch (error) {
|
|
268
|
+
logger?.(error);
|
|
269
|
+
}
|
|
270
|
+
finally {
|
|
271
|
+
this.#abortController.abort();
|
|
272
|
+
}
|
|
273
|
+
return this.#getResult();
|
|
274
|
+
}
|
|
275
|
+
#getResult() {
|
|
276
|
+
const urlAfterAction = this.#page.url();
|
|
277
|
+
return {
|
|
278
|
+
...(urlAfterAction !== this.#initialUrl
|
|
279
|
+
? { navigatedToUrl: urlAfterAction }
|
|
280
|
+
: {}),
|
|
281
|
+
dialogHandled: this.#dialogHandled,
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
export function getNetworkMultiplierFromString(condition) {
|
|
286
|
+
const puppeteerCondition = condition;
|
|
287
|
+
switch (puppeteerCondition) {
|
|
288
|
+
case 'Fast 4G':
|
|
289
|
+
return 1;
|
|
290
|
+
case 'Slow 4G':
|
|
291
|
+
return 2.5;
|
|
292
|
+
case 'Fast 3G':
|
|
293
|
+
return 5;
|
|
294
|
+
case 'Slow 3G':
|
|
295
|
+
return 10;
|
|
296
|
+
}
|
|
297
|
+
return 1;
|
|
298
|
+
}
|
|
299
|
+
//# sourceMappingURL=WaitForHelper.js.map
|
|
@@ -10,6 +10,7 @@ import fs from 'node:fs/promises';
|
|
|
10
10
|
import os from 'node:os';
|
|
11
11
|
import path from 'node:path';
|
|
12
12
|
import process from 'node:process';
|
|
13
|
+
import { CACHE_DIR_NAME, ENV_NO_UPDATE_CHECKS } from '../opera/branding.js';
|
|
13
14
|
import { VERSION } from '../version.js';
|
|
14
15
|
/**
|
|
15
16
|
* Notifies the user if an update is available.
|
|
@@ -21,11 +22,11 @@ export function resetUpdateCheckFlagForTesting() {
|
|
|
21
22
|
isChecking = false;
|
|
22
23
|
}
|
|
23
24
|
export async function checkForUpdates(message) {
|
|
24
|
-
if (isChecking || process.env[
|
|
25
|
+
if (isChecking || process.env[ENV_NO_UPDATE_CHECKS]) {
|
|
25
26
|
return;
|
|
26
27
|
}
|
|
27
28
|
isChecking = true;
|
|
28
|
-
const cachePath = path.join(os.homedir(), '.cache',
|
|
29
|
+
const cachePath = path.join(os.homedir(), '.cache', CACHE_DIR_NAME, 'latest.json');
|
|
29
30
|
let cachedVersion;
|
|
30
31
|
let stats;
|
|
31
32
|
try {
|
|
@@ -36,6 +37,10 @@ export async function checkForUpdates(message) {
|
|
|
36
37
|
catch {
|
|
37
38
|
// Ignore errors reading cache.
|
|
38
39
|
}
|
|
40
|
+
// NOTE: upstream uses `semver.lt(VERSION, cachedVersion)` here. The fork
|
|
41
|
+
// deliberately compares for inequality, which also reports an "update" when
|
|
42
|
+
// the installed version is *newer* than the cached snapshot (e.g. after a
|
|
43
|
+
// downgrade or when running a local pre-release build).
|
|
39
44
|
if (cachedVersion && cachedVersion !== VERSION) {
|
|
40
45
|
console.warn(`\nUpdate available: ${VERSION} -> ${cachedVersion}\n${message}\n`);
|
|
41
46
|
}
|
|
@@ -65,6 +70,7 @@ export async function checkForUpdates(message) {
|
|
|
65
70
|
const child = child_process.spawn(process.execPath, [scriptPath, cachePath], {
|
|
66
71
|
detached: true,
|
|
67
72
|
stdio: 'ignore',
|
|
73
|
+
windowsHide: true,
|
|
68
74
|
});
|
|
69
75
|
child.unref();
|
|
70
76
|
}
|
package/build/src/utils/files.js
CHANGED
|
@@ -11,8 +11,47 @@ export async function getTempFilePath(filename) {
|
|
|
11
11
|
const filepath = path.join(dir, filename);
|
|
12
12
|
return filepath;
|
|
13
13
|
}
|
|
14
|
-
export function
|
|
15
|
-
const
|
|
16
|
-
|
|
14
|
+
export async function resolveCanonicalPath(filePath) {
|
|
15
|
+
const absolutePath = path.resolve(filePath);
|
|
16
|
+
try {
|
|
17
|
+
// Get the true canonical path, resolving all symlinks.
|
|
18
|
+
return await fs.realpath(absolutePath);
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
if (err &&
|
|
22
|
+
typeof err === 'object' &&
|
|
23
|
+
'code' in err &&
|
|
24
|
+
err.code === 'ENOENT') {
|
|
25
|
+
// Find the nearest existing ancestor directory on the filesystem.
|
|
26
|
+
let current = absolutePath;
|
|
27
|
+
const missingSegments = [];
|
|
28
|
+
while (true) {
|
|
29
|
+
const parent = path.dirname(current);
|
|
30
|
+
if (parent === current) {
|
|
31
|
+
// Reached root directory but still couldn't resolve anything.
|
|
32
|
+
throw err;
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
const canonicalParent = await fs.realpath(parent);
|
|
36
|
+
return path.join(canonicalParent, path.basename(current), ...missingSegments);
|
|
37
|
+
}
|
|
38
|
+
catch (parentErr) {
|
|
39
|
+
if (parentErr &&
|
|
40
|
+
typeof parentErr === 'object' &&
|
|
41
|
+
'code' in parentErr &&
|
|
42
|
+
parentErr.code === 'ENOENT') {
|
|
43
|
+
missingSegments.unshift(path.basename(current));
|
|
44
|
+
current = parent;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
throw parentErr;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
throw err;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
17
56
|
}
|
|
18
57
|
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import fs from 'node:fs';
|
|
7
|
+
import util from 'node:util';
|
|
8
|
+
const mcpDebugNamespace = 'mcp:log';
|
|
9
|
+
let logFileStream;
|
|
10
|
+
const _debugLog = util.debuglog(mcpDebugNamespace);
|
|
11
|
+
export function saveLogsToFile(fileName) {
|
|
12
|
+
const logFile = fs.createWriteStream(fileName, { flags: 'a+' });
|
|
13
|
+
logFile.on('error', function (error) {
|
|
14
|
+
console.error(`Error when opening/writing to log file: ${error.message}`);
|
|
15
|
+
logFile.end();
|
|
16
|
+
process.exit(1);
|
|
17
|
+
});
|
|
18
|
+
logFileStream = logFile;
|
|
19
|
+
return logFile;
|
|
20
|
+
}
|
|
21
|
+
export function flushLogs(logFile, timeoutMs = 2000) {
|
|
22
|
+
return new Promise((resolve, reject) => {
|
|
23
|
+
const timeout = setTimeout(reject, timeoutMs);
|
|
24
|
+
logFile.end(() => {
|
|
25
|
+
clearTimeout(timeout);
|
|
26
|
+
resolve();
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
export const logger = (...args) => {
|
|
31
|
+
if (logFileStream) {
|
|
32
|
+
logFileStream.write(`${new Date().toISOString()} ${mcpDebugNamespace} ${util.format(...args)}\n`);
|
|
33
|
+
}
|
|
34
|
+
else if (_debugLog.enabled) {
|
|
35
|
+
_debugLog('%s %s', new Date().toISOString(), util.format(...args));
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
export const puppeteerLogger = (prefix) => {
|
|
39
|
+
if (logFileStream) {
|
|
40
|
+
return (...args) => {
|
|
41
|
+
logFileStream.write(`${new Date().toISOString()} ${prefix} ${util.format(...args)}\n`);
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
const dbg = util.debuglog(prefix);
|
|
45
|
+
return dbg.enabled
|
|
46
|
+
? (...args) => {
|
|
47
|
+
dbg('%s %s', new Date().toISOString(), util.format(...args));
|
|
48
|
+
}
|
|
49
|
+
: undefined;
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { DisposableStack, AsyncDisposableStack, SuppressedError, } from '../third_party/index.js';
|
|
7
|
+
globalThis.DisposableStack ??= DisposableStack;
|
|
8
|
+
globalThis.AsyncDisposableStack ??= AsyncDisposableStack;
|
|
9
|
+
// @ts-expect-error Type mismatch between puppeteer-core and node for SuppressedError.
|
|
10
|
+
globalThis.SuppressedError ??= SuppressedError;
|
|
11
|
+
//# sourceMappingURL=polyfill.js.map
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
const ALLOWED_PROTOCOLS = new Set(['http:', 'https:', 'ws:', 'wss:']);
|
|
7
|
+
const IPV4_LOOPBACK_REGEX = /^127(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d\d?)){3}$/;
|
|
8
|
+
/**
|
|
9
|
+
* Determines whether a given URL string points to a localhost / loopback address.
|
|
10
|
+
*
|
|
11
|
+
* @param url The URL string to test.
|
|
12
|
+
* @returns true if the URL is a valid network URL pointing to localhost or a loopback IP.
|
|
13
|
+
*/
|
|
14
|
+
export function isLocalhost(url) {
|
|
15
|
+
if (!url || typeof url !== 'string' || url.trim() === '') {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
let parsed;
|
|
19
|
+
try {
|
|
20
|
+
parsed = new URL(url);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
if (!ALLOWED_PROTOCOLS.has(parsed.protocol)) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
const hostname = parsed.hostname.toLowerCase().replace(/\.$/, '');
|
|
29
|
+
// 1. Check localhost and RFC 6761 *.localhost subdomains
|
|
30
|
+
if (hostname === 'localhost' || hostname.endsWith('.localhost')) {
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
// 2. Check IPv6 loopback ([::1] as returned by URL.hostname, or ::1)
|
|
34
|
+
if (hostname === '[::1]' || hostname === '::1') {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
// 3. Check IPv4 loopback (127.0.0.0/8)
|
|
38
|
+
if (IPV4_LOOPBACK_REGEX.test(hostname)) {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=url.js.map
|
package/build/src/version.js
CHANGED