@vibebrowser/chrome-devtools-mcp 0.26.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/LICENSE +202 -0
- package/README.md +873 -0
- package/build/src/DevToolsConnectionAdapter.js +70 -0
- package/build/src/DevtoolsUtils.js +295 -0
- package/build/src/HeapSnapshotManager.js +110 -0
- package/build/src/McpContext.js +605 -0
- package/build/src/McpPage.js +315 -0
- package/build/src/McpResponse.js +858 -0
- package/build/src/Mutex.js +38 -0
- package/build/src/PageCollector.js +297 -0
- package/build/src/SlimMcpResponse.js +19 -0
- package/build/src/TextSnapshot.js +236 -0
- package/build/src/ToolHandler.js +217 -0
- package/build/src/WaitForHelper.js +190 -0
- package/build/src/bin/check-latest-version.js +50 -0
- package/build/src/bin/chrome-devtools-cli-options.js +840 -0
- package/build/src/bin/chrome-devtools-mcp-cli-options.js +350 -0
- package/build/src/bin/chrome-devtools-mcp-main.js +94 -0
- package/build/src/bin/chrome-devtools-mcp.js +31 -0
- package/build/src/bin/chrome-devtools.js +189 -0
- package/build/src/bin/install-service.js +246 -0
- package/build/src/bin/service/chrome-devtools-mcp.service.template +17 -0
- package/build/src/bin/service/com.vibebrowser.chrome-devtools-mcp.plist.template +37 -0
- package/build/src/browser.js +204 -0
- package/build/src/daemon/client.js +154 -0
- package/build/src/daemon/daemon.js +204 -0
- package/build/src/daemon/types.js +7 -0
- package/build/src/daemon/utils.js +115 -0
- package/build/src/formatters/ConsoleFormatter.js +288 -0
- package/build/src/formatters/HeapSnapshotFormatter.js +54 -0
- package/build/src/formatters/IssueFormatter.js +193 -0
- package/build/src/formatters/NetworkFormatter.js +236 -0
- package/build/src/formatters/SnapshotFormatter.js +135 -0
- package/build/src/index.js +140 -0
- package/build/src/issue-descriptions.js +40 -0
- package/build/src/logger.js +37 -0
- package/build/src/polyfill.js +8 -0
- package/build/src/telemetry/ClearcutLogger.js +169 -0
- package/build/src/telemetry/WatchdogClient.js +61 -0
- package/build/src/telemetry/errors.js +18 -0
- package/build/src/telemetry/flagUtils.js +89 -0
- package/build/src/telemetry/metricsRegistry.js +89 -0
- package/build/src/telemetry/persistence.js +72 -0
- package/build/src/telemetry/transformation.js +134 -0
- package/build/src/telemetry/types.js +31 -0
- package/build/src/telemetry/watchdog/ClearcutSender.js +205 -0
- package/build/src/telemetry/watchdog/main.js +128 -0
- package/build/src/third_party/devtools-formatter-worker.js +8 -0
- package/build/src/third_party/devtools-heap-snapshot-worker.js +8 -0
- package/build/src/third_party/index.js +32 -0
- package/build/src/third_party/issue-descriptions/CoepCoopSandboxedIframeCannotNavigateToCoopPage.md +4 -0
- package/build/src/third_party/issue-descriptions/CoepCorpNotSameOrigin.md +8 -0
- package/build/src/third_party/issue-descriptions/CoepCorpNotSameOriginAfterDefaultedToSameOriginByCoep.md +18 -0
- package/build/src/third_party/issue-descriptions/CoepCorpNotSameSite.md +7 -0
- package/build/src/third_party/issue-descriptions/CoepFrameResourceNeedsCoepHeader.md +10 -0
- package/build/src/third_party/issue-descriptions/CompatibilityModeQuirks.md +5 -0
- package/build/src/third_party/issue-descriptions/CookieAttributeValueExceedsMaxSize.md +5 -0
- package/build/src/third_party/issue-descriptions/LowTextContrast.md +5 -0
- package/build/src/third_party/issue-descriptions/SameSiteExcludeContextDowngradeRead.md +8 -0
- package/build/src/third_party/issue-descriptions/SameSiteExcludeContextDowngradeSet.md +8 -0
- package/build/src/third_party/issue-descriptions/SameSiteExcludeNavigationContextDowngrade.md +8 -0
- package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureErrorRead.md +8 -0
- package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureErrorSet.md +8 -0
- package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureWarnRead.md +8 -0
- package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureWarnSet.md +8 -0
- package/build/src/third_party/issue-descriptions/SameSiteUnspecifiedLaxAllowUnsafeRead.md +9 -0
- package/build/src/third_party/issue-descriptions/SameSiteUnspecifiedLaxAllowUnsafeSet.md +9 -0
- package/build/src/third_party/issue-descriptions/SameSiteWarnCrossDowngradeRead.md +8 -0
- package/build/src/third_party/issue-descriptions/SameSiteWarnCrossDowngradeSet.md +8 -0
- package/build/src/third_party/issue-descriptions/SameSiteWarnStrictLaxDowngradeStrict.md +8 -0
- package/build/src/third_party/issue-descriptions/arInsecureContext.md +7 -0
- package/build/src/third_party/issue-descriptions/arInvalidInfoHeader.md +5 -0
- package/build/src/third_party/issue-descriptions/arInvalidRegisterOsSourceHeader.md +5 -0
- package/build/src/third_party/issue-descriptions/arInvalidRegisterOsTriggerHeader.md +5 -0
- package/build/src/third_party/issue-descriptions/arInvalidRegisterSourceHeader.md +5 -0
- package/build/src/third_party/issue-descriptions/arInvalidRegisterTriggerHeader.md +5 -0
- package/build/src/third_party/issue-descriptions/arNavigationRegistrationUniqueScopeAlreadySet.md +5 -0
- package/build/src/third_party/issue-descriptions/arNavigationRegistrationWithoutTransientUserActivation.md +6 -0
- package/build/src/third_party/issue-descriptions/arNoRegisterOsSourceHeader.md +5 -0
- package/build/src/third_party/issue-descriptions/arNoRegisterOsTriggerHeader.md +5 -0
- package/build/src/third_party/issue-descriptions/arNoRegisterSourceHeader.md +5 -0
- package/build/src/third_party/issue-descriptions/arNoRegisterTriggerHeader.md +5 -0
- package/build/src/third_party/issue-descriptions/arNoWebOrOsSupport.md +4 -0
- package/build/src/third_party/issue-descriptions/arOsSourceIgnored.md +18 -0
- package/build/src/third_party/issue-descriptions/arOsTriggerIgnored.md +19 -0
- package/build/src/third_party/issue-descriptions/arPermissionPolicyDisabled.md +8 -0
- package/build/src/third_party/issue-descriptions/arSourceAndTriggerHeaders.md +9 -0
- package/build/src/third_party/issue-descriptions/arSourceIgnored.md +13 -0
- package/build/src/third_party/issue-descriptions/arTriggerIgnored.md +12 -0
- package/build/src/third_party/issue-descriptions/arUntrustworthyReportingOrigin.md +10 -0
- package/build/src/third_party/issue-descriptions/arWebAndOsHeaders.md +11 -0
- package/build/src/third_party/issue-descriptions/bounceTrackingMitigations.md +3 -0
- package/build/src/third_party/issue-descriptions/clientHintMetaTagAllowListInvalidOrigin.md +4 -0
- package/build/src/third_party/issue-descriptions/clientHintMetaTagModifiedHTML.md +4 -0
- package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidAllowlistItemType.md +12 -0
- package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidHeader.md +12 -0
- package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidUrlPattern.md +8 -0
- package/build/src/third_party/issue-descriptions/connectionAllowlistItemNotInnerList.md +12 -0
- package/build/src/third_party/issue-descriptions/connectionAllowlistMoreThanOneList.md +7 -0
- package/build/src/third_party/issue-descriptions/connectionAllowlistReportingEndpointNotToken.md +10 -0
- package/build/src/third_party/issue-descriptions/cookieCrossSiteRedirectDowngrade.md +12 -0
- package/build/src/third_party/issue-descriptions/cookieExcludeBlockedWithinRelatedWebsiteSet.md +4 -0
- package/build/src/third_party/issue-descriptions/cookieExcludeDomainNonAscii.md +11 -0
- package/build/src/third_party/issue-descriptions/cookieExcludePortMismatch.md +8 -0
- package/build/src/third_party/issue-descriptions/cookieExcludeSchemeMismatch.md +7 -0
- package/build/src/third_party/issue-descriptions/cookieExcludeThirdPartyPhaseoutRead.md +6 -0
- package/build/src/third_party/issue-descriptions/cookieExcludeThirdPartyPhaseoutSet.md +6 -0
- package/build/src/third_party/issue-descriptions/cookieWarnDomainNonAscii.md +11 -0
- package/build/src/third_party/issue-descriptions/cookieWarnMetadataGrantRead.md +4 -0
- package/build/src/third_party/issue-descriptions/cookieWarnMetadataGrantSet.md +4 -0
- package/build/src/third_party/issue-descriptions/cookieWarnThirdPartyPhaseoutRead.md +6 -0
- package/build/src/third_party/issue-descriptions/cookieWarnThirdPartyPhaseoutSet.md +6 -0
- package/build/src/third_party/issue-descriptions/corsAllowCredentialsRequired.md +6 -0
- package/build/src/third_party/issue-descriptions/corsDisabledScheme.md +7 -0
- package/build/src/third_party/issue-descriptions/corsDisallowedByMode.md +7 -0
- package/build/src/third_party/issue-descriptions/corsHeaderDisallowedByPreflightResponse.md +5 -0
- package/build/src/third_party/issue-descriptions/corsInvalidHeaderValues.md +7 -0
- package/build/src/third_party/issue-descriptions/corsLocalNetworkAccessPermissionDenied.md +19 -0
- package/build/src/third_party/issue-descriptions/corsMethodDisallowedByPreflightResponse.md +5 -0
- package/build/src/third_party/issue-descriptions/corsNoCorsRedirectModeNotFollow.md +5 -0
- package/build/src/third_party/issue-descriptions/corsOriginMismatch.md +6 -0
- package/build/src/third_party/issue-descriptions/corsPreflightResponseInvalid.md +5 -0
- package/build/src/third_party/issue-descriptions/corsRedirectContainsCredentials.md +5 -0
- package/build/src/third_party/issue-descriptions/corsWildcardOriginNotAllowed.md +8 -0
- package/build/src/third_party/issue-descriptions/cspEvalViolation.md +9 -0
- package/build/src/third_party/issue-descriptions/cspInlineViolation.md +10 -0
- package/build/src/third_party/issue-descriptions/cspTrustedTypesPolicyViolation.md +5 -0
- package/build/src/third_party/issue-descriptions/cspTrustedTypesSinkViolation.md +8 -0
- package/build/src/third_party/issue-descriptions/cspURLViolation.md +10 -0
- package/build/src/third_party/issue-descriptions/deprecation.md +3 -0
- package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsHttpNotFound.md +1 -0
- package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsInvalidResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsNoResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/federatedAuthRequestApprovalDeclined.md +1 -0
- package/build/src/third_party/issue-descriptions/federatedAuthRequestCanceled.md +1 -0
- package/build/src/third_party/issue-descriptions/federatedAuthRequestErrorFetchingSignin.md +1 -0
- package/build/src/third_party/issue-descriptions/federatedAuthRequestErrorIdToken.md +1 -0
- package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenHttpNotFound.md +1 -0
- package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenInvalidRequest.md +1 -0
- package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenInvalidResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenNoResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/federatedAuthRequestInvalidSigninResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestHttpNotFound.md +1 -0
- package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestInvalidResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestNoResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/federatedAuthRequestTooManyRequests.md +1 -0
- package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestInvalidAccountsResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestInvalidConfigOrWellKnown.md +1 -0
- package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoAccountSharingPermission.md +1 -0
- package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoApiPermission.md +1 -0
- package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoReturningUserFromFetchedAccounts.md +1 -0
- package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotIframe.md +1 -0
- package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotPotentiallyTrustworthy.md +1 -0
- package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotSameOrigin.md +1 -0
- package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotSignedInWithIdp.md +1 -0
- package/build/src/third_party/issue-descriptions/fetchingPartitionedBlobURL.md +7 -0
- package/build/src/third_party/issue-descriptions/genericFormAriaLabelledByToNonExistingIdError.md +8 -0
- package/build/src/third_party/issue-descriptions/genericFormAutocompleteAttributeEmptyError.md +5 -0
- package/build/src/third_party/issue-descriptions/genericFormDuplicateIdForInputError.md +5 -0
- package/build/src/third_party/issue-descriptions/genericFormEmptyIdAndNameAttributesForInputError.md +5 -0
- package/build/src/third_party/issue-descriptions/genericFormInputAssignedAutocompleteValueToIdOrNameAttributeError.md +5 -0
- package/build/src/third_party/issue-descriptions/genericFormInputHasWrongButWellIntendedAutocompleteValueError.md +5 -0
- package/build/src/third_party/issue-descriptions/genericFormInputWithNoLabelError.md +5 -0
- package/build/src/third_party/issue-descriptions/genericFormLabelForMatchesNonExistingIdError.md +5 -0
- package/build/src/third_party/issue-descriptions/genericFormLabelForNameError.md +5 -0
- package/build/src/third_party/issue-descriptions/genericFormLabelHasNeitherForNorNestedInputError.md +5 -0
- package/build/src/third_party/issue-descriptions/genericFormModelContextMissingToolDescription.md +5 -0
- package/build/src/third_party/issue-descriptions/genericFormModelContextMissingToolName.md +5 -0
- package/build/src/third_party/issue-descriptions/genericFormModelContextParameterMissingName.md +5 -0
- package/build/src/third_party/issue-descriptions/genericFormModelContextParameterMissingTitleAndDescription.md +5 -0
- package/build/src/third_party/issue-descriptions/genericFormModelContextRequiredParameterMissingName.md +5 -0
- package/build/src/third_party/issue-descriptions/genericNavigationEntryMarkedSkippable.md +7 -0
- package/build/src/third_party/issue-descriptions/genericResponseWasBlockedByORB.md +4 -0
- package/build/src/third_party/issue-descriptions/heavyAd.md +10 -0
- package/build/src/third_party/issue-descriptions/mixedContent.md +5 -0
- package/build/src/third_party/issue-descriptions/navigatingPartitionedBlobURL.md +5 -0
- package/build/src/third_party/issue-descriptions/permissionElementActivationDisabled.md +7 -0
- package/build/src/third_party/issue-descriptions/permissionElementActivationDisabledWithOccluder.md +9 -0
- package/build/src/third_party/issue-descriptions/permissionElementActivationDisabledWithOccluderParent.md +9 -0
- package/build/src/third_party/issue-descriptions/permissionElementCspFrameAncestorsMissing.md +5 -0
- package/build/src/third_party/issue-descriptions/permissionElementFencedFrameDisallowed.md +5 -0
- package/build/src/third_party/issue-descriptions/permissionElementFontSizeTooLarge.md +5 -0
- package/build/src/third_party/issue-descriptions/permissionElementFontSizeTooSmall.md +5 -0
- package/build/src/third_party/issue-descriptions/permissionElementGeolocationDeprecated.md +5 -0
- package/build/src/third_party/issue-descriptions/permissionElementInsetBoxShadowUnsupported.md +5 -0
- package/build/src/third_party/issue-descriptions/permissionElementInvalidDisplayStyle.md +5 -0
- package/build/src/third_party/issue-descriptions/permissionElementInvalidSizeValue.md +5 -0
- package/build/src/third_party/issue-descriptions/permissionElementInvalidType.md +5 -0
- package/build/src/third_party/issue-descriptions/permissionElementInvalidTypeActivation.md +5 -0
- package/build/src/third_party/issue-descriptions/permissionElementLowContrast.md +5 -0
- package/build/src/third_party/issue-descriptions/permissionElementNonOpaqueColor.md +5 -0
- package/build/src/third_party/issue-descriptions/permissionElementPaddingBottomUnsupported.md +6 -0
- package/build/src/third_party/issue-descriptions/permissionElementPaddingRightUnsupported.md +6 -0
- package/build/src/third_party/issue-descriptions/permissionElementPermissionsPolicyBlocked.md +5 -0
- package/build/src/third_party/issue-descriptions/permissionElementRegistrationFailed.md +5 -0
- package/build/src/third_party/issue-descriptions/permissionElementRequestInProgress.md +5 -0
- package/build/src/third_party/issue-descriptions/permissionElementSecurityChecksFailed.md +5 -0
- package/build/src/third_party/issue-descriptions/permissionElementTypeNotSupported.md +5 -0
- package/build/src/third_party/issue-descriptions/permissionElementUntrustedEvent.md +7 -0
- package/build/src/third_party/issue-descriptions/placeholderDescriptionForInvisibleIssues.md +3 -0
- package/build/src/third_party/issue-descriptions/propertyRuleInvalidNameIssue.md +3 -0
- package/build/src/third_party/issue-descriptions/propertyRuleIssue.md +7 -0
- package/build/src/third_party/issue-descriptions/selectElementAccessibilityDisallowedOptGroupChild.md +7 -0
- package/build/src/third_party/issue-descriptions/selectElementAccessibilityDisallowedSelectChild.md +7 -0
- package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentAttributesSelectDescendant.md +3 -0
- package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentLegendChild.md +3 -0
- package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentOptionChild.md +3 -0
- package/build/src/third_party/issue-descriptions/selectElementAccessibilityNonPhrasingContentOptionChild.md +3 -0
- package/build/src/third_party/issue-descriptions/selectivePermissionsIntervention.md +7 -0
- package/build/src/third_party/issue-descriptions/sharedArrayBuffer.md +7 -0
- package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorCrossOriginNoCorsRequest.md +1 -0
- package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorDictionaryLoadFailure.md +3 -0
- package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorMatchingDictionaryNotUsed.md +3 -0
- package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorUnexpectedContentDictionaryHeader.md +1 -0
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorCossOriginNoCorsRequest.md +1 -0
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorDisallowedBySettings.md +1 -0
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorExpiredResponse.md +3 -0
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorFeatureDisabled.md +3 -0
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInsufficientResources.md +1 -0
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInvalidMatchField.md +1 -0
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInvalidStructuredHeader.md +1 -0
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInvalidTTLField.md +1 -0
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNavigationRequest.md +3 -0
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNoMatchField.md +1 -0
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonIntegerTTLField.md +1 -0
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonListMatchDestField.md +1 -0
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonSecureContext.md +3 -0
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonStringIdField.md +1 -0
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonStringInMatchDestList.md +1 -0
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonStringMatchField.md +1 -0
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonTokenTypeField.md +1 -0
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorRequestAborted.md +1 -0
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorShuttingDown.md +1 -0
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorTooLongIdField.md +3 -0
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorUnsupportedType.md +3 -0
- package/build/src/third_party/issue-descriptions/sriInvalidSignatureHeader.md +14 -0
- package/build/src/third_party/issue-descriptions/sriInvalidSignatureInputHeader.md +15 -0
- package/build/src/third_party/issue-descriptions/sriMissingSignatureHeader.md +8 -0
- package/build/src/third_party/issue-descriptions/sriMissingSignatureInputHeader.md +7 -0
- package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsIncorrectLength.md +11 -0
- package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsNotByteSequence.md +14 -0
- package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsParameterized.md +15 -0
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidComponentName.md +8 -0
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidComponentType.md +13 -0
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidDerivedComponentParameter.md +4 -0
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidHeaderComponentParameter.md +5 -0
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidParameter.md +11 -0
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderKeyIdLength.md +12 -0
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderMissingLabel.md +6 -0
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderMissingRequiredParameters.md +8 -0
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderValueMissingComponents.md +11 -0
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderValueNotInnerList.md +11 -0
- package/build/src/third_party/issue-descriptions/sriValidationFailedIntegrityMismatch.md +10 -0
- package/build/src/third_party/issue-descriptions/sriValidationFailedInvalidLength.md +5 -0
- package/build/src/third_party/issue-descriptions/sriValidationFailedSignatureExpired.md +6 -0
- package/build/src/third_party/issue-descriptions/sriValidationFailedSignatureMismatch.md +11 -0
- package/build/src/third_party/issue-descriptions/stylesheetLateImport.md +4 -0
- package/build/src/third_party/issue-descriptions/stylesheetRequestFailed.md +3 -0
- package/build/src/third_party/issue-descriptions/summaryElementAccessibilityInteractiveContentSummaryDescendant.md +3 -0
- package/build/src/third_party/issue-descriptions/unencodedDigestIncorrectDigestLength.md +12 -0
- package/build/src/third_party/issue-descriptions/unencodedDigestIncorrectDigestType.md +17 -0
- package/build/src/third_party/issue-descriptions/unencodedDigestMalformedDictionary.md +14 -0
- package/build/src/third_party/issue-descriptions/unencodedDigestUnknownAlgorithm.md +15 -0
- package/build/src/third_party/lighthouse-devtools-mcp-bundle.js +61598 -0
- package/build/src/tools/ToolDefinition.js +73 -0
- package/build/src/tools/categories.js +36 -0
- package/build/src/tools/console.js +91 -0
- package/build/src/tools/emulation.js +57 -0
- package/build/src/tools/extensions.js +96 -0
- package/build/src/tools/input.js +461 -0
- package/build/src/tools/lighthouse.js +131 -0
- package/build/src/tools/memory.js +106 -0
- package/build/src/tools/network.js +125 -0
- package/build/src/tools/pages.js +411 -0
- package/build/src/tools/performance.js +196 -0
- package/build/src/tools/screencast.js +95 -0
- package/build/src/tools/screenshot.js +87 -0
- package/build/src/tools/script.js +151 -0
- package/build/src/tools/slim/tools.js +85 -0
- package/build/src/tools/snapshot.js +60 -0
- package/build/src/tools/thirdPartyDeveloper.js +75 -0
- package/build/src/tools/tools.js +56 -0
- package/build/src/tools/webmcp.js +64 -0
- package/build/src/trace-processing/parse.js +85 -0
- package/build/src/types.js +7 -0
- package/build/src/utils/check-for-updates.js +74 -0
- package/build/src/utils/files.js +18 -0
- package/build/src/utils/id.js +16 -0
- package/build/src/utils/keyboard.js +297 -0
- package/build/src/utils/pagination.js +50 -0
- package/build/src/utils/string.js +37 -0
- package/build/src/utils/types.js +7 -0
- package/build/src/version.js +10 -0
- package/package.json +93 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
const LATENCY_BUCKETS = [50, 100, 250, 500, 1000, 2500, 5000, 10000];
|
|
7
|
+
export function bucketizeLatency(latencyMs) {
|
|
8
|
+
for (const bucket of LATENCY_BUCKETS) {
|
|
9
|
+
if (latencyMs <= bucket) {
|
|
10
|
+
return bucket;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return LATENCY_BUCKETS[LATENCY_BUCKETS.length - 1];
|
|
14
|
+
}
|
|
15
|
+
export const PARAM_BLOCKLIST = new Set(['uid', 'reqid', 'msgid']);
|
|
16
|
+
const SUPPORTED_ZOD_TYPES = [
|
|
17
|
+
'ZodString',
|
|
18
|
+
'ZodNumber',
|
|
19
|
+
'ZodBoolean',
|
|
20
|
+
'ZodArray',
|
|
21
|
+
'ZodEnum',
|
|
22
|
+
];
|
|
23
|
+
function isZodType(type) {
|
|
24
|
+
return SUPPORTED_ZOD_TYPES.includes(type);
|
|
25
|
+
}
|
|
26
|
+
export function getZodType(zodType) {
|
|
27
|
+
const def = zodType._def;
|
|
28
|
+
const typeName = def.typeName;
|
|
29
|
+
if (typeName === 'ZodOptional' ||
|
|
30
|
+
typeName === 'ZodDefault' ||
|
|
31
|
+
typeName === 'ZodNullable') {
|
|
32
|
+
return getZodType(def.innerType);
|
|
33
|
+
}
|
|
34
|
+
if (typeName === 'ZodEffects') {
|
|
35
|
+
return getZodType(def.schema);
|
|
36
|
+
}
|
|
37
|
+
if (isZodType(typeName)) {
|
|
38
|
+
return typeName;
|
|
39
|
+
}
|
|
40
|
+
throw new Error(`Unsupported zod type for tool parameter: ${typeName}`);
|
|
41
|
+
}
|
|
42
|
+
export function stripUnderscoreBeforeNumber(name) {
|
|
43
|
+
return name.replace(/_([0-9])/g, '$1');
|
|
44
|
+
}
|
|
45
|
+
export function transformArgName(zodType, name) {
|
|
46
|
+
const snakeCaseName = name.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);
|
|
47
|
+
let transformed;
|
|
48
|
+
if (zodType === 'ZodString') {
|
|
49
|
+
transformed = `${snakeCaseName}_length`;
|
|
50
|
+
}
|
|
51
|
+
else if (zodType === 'ZodArray') {
|
|
52
|
+
transformed = `${snakeCaseName}_count`;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
transformed = snakeCaseName;
|
|
56
|
+
}
|
|
57
|
+
return stripUnderscoreBeforeNumber(transformed);
|
|
58
|
+
}
|
|
59
|
+
export function transformArgType(zodType) {
|
|
60
|
+
if (zodType === 'ZodString' || zodType === 'ZodArray') {
|
|
61
|
+
return 'number';
|
|
62
|
+
}
|
|
63
|
+
switch (zodType) {
|
|
64
|
+
case 'ZodNumber':
|
|
65
|
+
return 'number';
|
|
66
|
+
case 'ZodBoolean':
|
|
67
|
+
return 'boolean';
|
|
68
|
+
case 'ZodEnum':
|
|
69
|
+
return 'enum';
|
|
70
|
+
default:
|
|
71
|
+
throw new Error(`Unsupported zod type for tool parameter: ${zodType}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const BUCKETS = [
|
|
75
|
+
0, 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000,
|
|
76
|
+
];
|
|
77
|
+
function bucketize(value) {
|
|
78
|
+
for (const bucket of BUCKETS) {
|
|
79
|
+
if (bucket >= value) {
|
|
80
|
+
return bucket;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return BUCKETS[BUCKETS.length - 1];
|
|
84
|
+
}
|
|
85
|
+
function transformValue(zodType, value) {
|
|
86
|
+
if (zodType === 'ZodString') {
|
|
87
|
+
return bucketize(value.length);
|
|
88
|
+
}
|
|
89
|
+
else if (zodType === 'ZodArray') {
|
|
90
|
+
return value.length;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
return value;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function hasEquivalentType(zodType, value) {
|
|
97
|
+
if (zodType === 'ZodString') {
|
|
98
|
+
return typeof value === 'string';
|
|
99
|
+
}
|
|
100
|
+
else if (zodType === 'ZodArray') {
|
|
101
|
+
return Array.isArray(value);
|
|
102
|
+
}
|
|
103
|
+
else if (zodType === 'ZodNumber') {
|
|
104
|
+
return typeof value === 'number';
|
|
105
|
+
}
|
|
106
|
+
else if (zodType === 'ZodBoolean') {
|
|
107
|
+
return typeof value === 'boolean';
|
|
108
|
+
}
|
|
109
|
+
else if (zodType === 'ZodEnum') {
|
|
110
|
+
return (typeof value === 'string' ||
|
|
111
|
+
typeof value === 'number' ||
|
|
112
|
+
typeof value === 'boolean');
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
export function sanitizeParams(params, schema) {
|
|
119
|
+
const transformed = {};
|
|
120
|
+
for (const [name, value] of Object.entries(params)) {
|
|
121
|
+
if (PARAM_BLOCKLIST.has(name)) {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
const zodType = getZodType(schema[name]);
|
|
125
|
+
if (!hasEquivalentType(zodType, value)) {
|
|
126
|
+
throw new Error(`parameter ${name} has type ${zodType} but value ${value} is not of equivalent type`);
|
|
127
|
+
}
|
|
128
|
+
const transformedName = transformArgName(zodType, name);
|
|
129
|
+
const transformedValue = transformValue(zodType, value);
|
|
130
|
+
transformed[transformedName] = transformedValue;
|
|
131
|
+
}
|
|
132
|
+
return transformed;
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=transformation.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
// Enums
|
|
7
|
+
export var OsType;
|
|
8
|
+
(function (OsType) {
|
|
9
|
+
OsType[OsType["OS_TYPE_UNSPECIFIED"] = 0] = "OS_TYPE_UNSPECIFIED";
|
|
10
|
+
OsType[OsType["OS_TYPE_WINDOWS"] = 1] = "OS_TYPE_WINDOWS";
|
|
11
|
+
OsType[OsType["OS_TYPE_MACOS"] = 2] = "OS_TYPE_MACOS";
|
|
12
|
+
OsType[OsType["OS_TYPE_LINUX"] = 3] = "OS_TYPE_LINUX";
|
|
13
|
+
})(OsType || (OsType = {}));
|
|
14
|
+
export var McpClient;
|
|
15
|
+
(function (McpClient) {
|
|
16
|
+
McpClient[McpClient["MCP_CLIENT_UNSPECIFIED"] = 0] = "MCP_CLIENT_UNSPECIFIED";
|
|
17
|
+
McpClient[McpClient["MCP_CLIENT_CLAUDE_CODE"] = 1] = "MCP_CLIENT_CLAUDE_CODE";
|
|
18
|
+
McpClient[McpClient["MCP_CLIENT_GEMINI_CLI"] = 2] = "MCP_CLIENT_GEMINI_CLI";
|
|
19
|
+
McpClient[McpClient["MCP_CLIENT_DT_MCP_CLI"] = 4] = "MCP_CLIENT_DT_MCP_CLI";
|
|
20
|
+
McpClient[McpClient["MCP_CLIENT_OPENCLAW"] = 5] = "MCP_CLIENT_OPENCLAW";
|
|
21
|
+
McpClient[McpClient["MCP_CLIENT_CODEX"] = 6] = "MCP_CLIENT_CODEX";
|
|
22
|
+
McpClient[McpClient["MCP_CLIENT_ANTIGRAVITY"] = 7] = "MCP_CLIENT_ANTIGRAVITY";
|
|
23
|
+
McpClient[McpClient["MCP_CLIENT_OTHER"] = 3] = "MCP_CLIENT_OTHER";
|
|
24
|
+
})(McpClient || (McpClient = {}));
|
|
25
|
+
// IPC types for messages between the main process and the
|
|
26
|
+
// telemetry watchdog process.
|
|
27
|
+
export var WatchdogMessageType;
|
|
28
|
+
(function (WatchdogMessageType) {
|
|
29
|
+
WatchdogMessageType["LOG_EVENT"] = "log-event";
|
|
30
|
+
})(WatchdogMessageType || (WatchdogMessageType = {}));
|
|
31
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import crypto from 'node:crypto';
|
|
7
|
+
import { logger } from '../../logger.js';
|
|
8
|
+
const MAX_BUFFER_SIZE = 1000;
|
|
9
|
+
const DEFAULT_CLEARCUT_ENDPOINT = 'https://play.googleapis.com/log?format=json_proto';
|
|
10
|
+
const DEFAULT_FLUSH_INTERVAL_MS = 15 * 60 * 1000;
|
|
11
|
+
const LOG_SOURCE = 2839;
|
|
12
|
+
const CLIENT_TYPE = 47;
|
|
13
|
+
const MIN_RATE_LIMIT_WAIT_MS = 30_000;
|
|
14
|
+
const REQUEST_TIMEOUT_MS = 30_000;
|
|
15
|
+
const SHUTDOWN_TIMEOUT_MS = 5_000;
|
|
16
|
+
const SESSION_ROTATION_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
17
|
+
export class ClearcutSender {
|
|
18
|
+
#appVersion;
|
|
19
|
+
#osType;
|
|
20
|
+
#clearcutEndpoint;
|
|
21
|
+
#flushIntervalMs;
|
|
22
|
+
#includePidHeader;
|
|
23
|
+
#sessionId;
|
|
24
|
+
#sessionCreated;
|
|
25
|
+
#buffer = [];
|
|
26
|
+
#flushTimer = null;
|
|
27
|
+
#isFlushing = false;
|
|
28
|
+
#timerStarted = false;
|
|
29
|
+
constructor(config) {
|
|
30
|
+
this.#appVersion = config.appVersion;
|
|
31
|
+
this.#osType = config.osType;
|
|
32
|
+
this.#clearcutEndpoint =
|
|
33
|
+
config.clearcutEndpoint ?? DEFAULT_CLEARCUT_ENDPOINT;
|
|
34
|
+
this.#flushIntervalMs =
|
|
35
|
+
config.forceFlushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS;
|
|
36
|
+
this.#includePidHeader = config.includePidHeader ?? false;
|
|
37
|
+
this.#sessionId = crypto.randomUUID();
|
|
38
|
+
this.#sessionCreated = Date.now();
|
|
39
|
+
}
|
|
40
|
+
enqueueEvent(event) {
|
|
41
|
+
if (Date.now() - this.#sessionCreated > SESSION_ROTATION_INTERVAL_MS) {
|
|
42
|
+
this.#sessionId = crypto.randomUUID();
|
|
43
|
+
this.#sessionCreated = Date.now();
|
|
44
|
+
}
|
|
45
|
+
const eventToSend = {
|
|
46
|
+
...event,
|
|
47
|
+
session_id: this.#sessionId,
|
|
48
|
+
app_version: this.#appVersion,
|
|
49
|
+
os_type: this.#osType,
|
|
50
|
+
};
|
|
51
|
+
logger('Enqueing telemetry event', JSON.stringify(eventToSend, null, 2));
|
|
52
|
+
this.#addToBuffer(eventToSend);
|
|
53
|
+
if (!this.#timerStarted) {
|
|
54
|
+
this.#timerStarted = true;
|
|
55
|
+
this.#scheduleFlush(this.#flushIntervalMs);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async sendShutdownEvent() {
|
|
59
|
+
if (this.#flushTimer) {
|
|
60
|
+
clearTimeout(this.#flushTimer);
|
|
61
|
+
this.#flushTimer = null;
|
|
62
|
+
}
|
|
63
|
+
const shutdownEvent = {
|
|
64
|
+
server_shutdown: {},
|
|
65
|
+
};
|
|
66
|
+
this.enqueueEvent(shutdownEvent);
|
|
67
|
+
try {
|
|
68
|
+
await Promise.race([
|
|
69
|
+
this.#finalFlush(),
|
|
70
|
+
new Promise(resolve => setTimeout(resolve, SHUTDOWN_TIMEOUT_MS)),
|
|
71
|
+
]);
|
|
72
|
+
logger('Final flush completed');
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
logger('Final flush failed:', error);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
async #flush() {
|
|
79
|
+
if (this.#isFlushing) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (this.#buffer.length === 0) {
|
|
83
|
+
this.#scheduleFlush(this.#flushIntervalMs);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
this.#isFlushing = true;
|
|
87
|
+
let nextDelayMs = this.#flushIntervalMs;
|
|
88
|
+
// Optimistically remove events from buffer before sending.
|
|
89
|
+
// This prevents race conditions where a simultaneous #finalFlush would include these same events.
|
|
90
|
+
const eventsToSend = [...this.#buffer];
|
|
91
|
+
this.#buffer = [];
|
|
92
|
+
try {
|
|
93
|
+
const result = await this.#sendBatch(eventsToSend);
|
|
94
|
+
if (result.success) {
|
|
95
|
+
if (result.nextRequestWaitMs !== undefined) {
|
|
96
|
+
nextDelayMs = Math.max(result.nextRequestWaitMs, MIN_RATE_LIMIT_WAIT_MS);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else if (result.isPermanentError) {
|
|
100
|
+
logger('Permanent error, dropped batch of', eventsToSend.length, 'events');
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
// Transient error: Requeue events at the front of the buffer
|
|
104
|
+
// to maintain order and retry them later.
|
|
105
|
+
this.#buffer = [...eventsToSend, ...this.#buffer];
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
// Safety catch for unexpected errors, requeue events
|
|
110
|
+
this.#buffer = [...eventsToSend, ...this.#buffer];
|
|
111
|
+
logger('Flush failed unexpectedly:', error);
|
|
112
|
+
}
|
|
113
|
+
finally {
|
|
114
|
+
this.#isFlushing = false;
|
|
115
|
+
this.#scheduleFlush(nextDelayMs);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
#addToBuffer(event) {
|
|
119
|
+
if (this.#buffer.length >= MAX_BUFFER_SIZE) {
|
|
120
|
+
this.#buffer.shift();
|
|
121
|
+
logger('Telemetry buffer overflow: dropped oldest event');
|
|
122
|
+
}
|
|
123
|
+
this.#buffer.push({
|
|
124
|
+
event,
|
|
125
|
+
timestamp: Date.now(),
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
#scheduleFlush(delayMs) {
|
|
129
|
+
logger(`Scheduling flush in ${delayMs}`);
|
|
130
|
+
if (this.#flushTimer) {
|
|
131
|
+
clearTimeout(this.#flushTimer);
|
|
132
|
+
}
|
|
133
|
+
this.#flushTimer = setTimeout(() => {
|
|
134
|
+
this.#flush().catch(err => {
|
|
135
|
+
logger('Flush error:', err);
|
|
136
|
+
});
|
|
137
|
+
}, delayMs);
|
|
138
|
+
}
|
|
139
|
+
async #sendBatch(events) {
|
|
140
|
+
logger(`Sending batch of ${events.length}`);
|
|
141
|
+
const requestBody = {
|
|
142
|
+
log_source: LOG_SOURCE,
|
|
143
|
+
request_time_ms: Date.now().toString(),
|
|
144
|
+
client_info: {
|
|
145
|
+
client_type: CLIENT_TYPE,
|
|
146
|
+
},
|
|
147
|
+
log_event: events.map(({ event, timestamp }) => ({
|
|
148
|
+
event_time_ms: timestamp.toString(),
|
|
149
|
+
source_extension_json: JSON.stringify(event),
|
|
150
|
+
})),
|
|
151
|
+
};
|
|
152
|
+
const controller = new AbortController();
|
|
153
|
+
const timeoutId = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
154
|
+
try {
|
|
155
|
+
const response = await fetch(this.#clearcutEndpoint, {
|
|
156
|
+
method: 'POST',
|
|
157
|
+
headers: {
|
|
158
|
+
'Content-Type': 'application/json',
|
|
159
|
+
// Used in E2E tests to confirm that the watchdog process is killed
|
|
160
|
+
...(this.#includePidHeader
|
|
161
|
+
? { 'X-Watchdog-Pid': process.pid.toString() }
|
|
162
|
+
: {}),
|
|
163
|
+
},
|
|
164
|
+
body: JSON.stringify(requestBody),
|
|
165
|
+
signal: controller.signal,
|
|
166
|
+
});
|
|
167
|
+
clearTimeout(timeoutId);
|
|
168
|
+
if (response.ok) {
|
|
169
|
+
const data = (await response.json());
|
|
170
|
+
return {
|
|
171
|
+
success: true,
|
|
172
|
+
nextRequestWaitMs: data.next_request_wait_millis,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
const status = response.status;
|
|
176
|
+
if (status >= 500 || status === 429) {
|
|
177
|
+
return { success: false };
|
|
178
|
+
}
|
|
179
|
+
logger('Telemetry permanent error:', status);
|
|
180
|
+
return { success: false, isPermanentError: true };
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
clearTimeout(timeoutId);
|
|
184
|
+
return { success: false };
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
async #finalFlush() {
|
|
188
|
+
if (this.#buffer.length === 0) {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
const eventsToSend = [...this.#buffer];
|
|
192
|
+
await this.#sendBatch(eventsToSend);
|
|
193
|
+
}
|
|
194
|
+
stopForTesting() {
|
|
195
|
+
if (this.#flushTimer) {
|
|
196
|
+
clearTimeout(this.#flushTimer);
|
|
197
|
+
this.#flushTimer = null;
|
|
198
|
+
}
|
|
199
|
+
this.#timerStarted = false;
|
|
200
|
+
}
|
|
201
|
+
get bufferSizeForTesting() {
|
|
202
|
+
return this.#buffer.length;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=ClearcutSender.js.map
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import process from 'node:process';
|
|
7
|
+
import readline from 'node:readline';
|
|
8
|
+
import { parseArgs } from 'node:util';
|
|
9
|
+
import { logger, flushLogs, saveLogsToFile } from '../../logger.js';
|
|
10
|
+
import { WatchdogMessageType } from '../types.js';
|
|
11
|
+
import { ClearcutSender } from './ClearcutSender.js';
|
|
12
|
+
function parseWatchdogArgs() {
|
|
13
|
+
const { values } = parseArgs({
|
|
14
|
+
options: {
|
|
15
|
+
'parent-pid': { type: 'string' },
|
|
16
|
+
'app-version': { type: 'string' },
|
|
17
|
+
'os-type': { type: 'string' },
|
|
18
|
+
'log-file': { type: 'string' },
|
|
19
|
+
'clearcut-endpoint': { type: 'string' },
|
|
20
|
+
'clearcut-force-flush-interval-ms': { type: 'string' },
|
|
21
|
+
'clearcut-include-pid-header': { type: 'boolean' },
|
|
22
|
+
},
|
|
23
|
+
strict: true,
|
|
24
|
+
});
|
|
25
|
+
// Verify required arguments
|
|
26
|
+
const parentPid = parseInt(values['parent-pid'] ?? '', 10);
|
|
27
|
+
const appVersion = values['app-version'];
|
|
28
|
+
const osType = parseInt(values['os-type'] ?? '', 10);
|
|
29
|
+
if (isNaN(parentPid) || !appVersion || isNaN(osType)) {
|
|
30
|
+
console.error('Invalid arguments provided for watchdog process: ', JSON.stringify({ parentPid, appVersion, osType }));
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
// Parse Optional Arguments
|
|
34
|
+
const logFile = values['log-file'];
|
|
35
|
+
const clearcutEndpoint = values['clearcut-endpoint'];
|
|
36
|
+
const clearcutIncludePidHeader = values['clearcut-include-pid-header'];
|
|
37
|
+
let clearcutForceFlushIntervalMs;
|
|
38
|
+
if (values['clearcut-force-flush-interval-ms']) {
|
|
39
|
+
const parsed = parseInt(values['clearcut-force-flush-interval-ms'], 10);
|
|
40
|
+
if (!isNaN(parsed)) {
|
|
41
|
+
clearcutForceFlushIntervalMs = parsed;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
parentPid,
|
|
46
|
+
appVersion,
|
|
47
|
+
osType,
|
|
48
|
+
logFile,
|
|
49
|
+
clearcutEndpoint,
|
|
50
|
+
clearcutForceFlushIntervalMs,
|
|
51
|
+
clearcutIncludePidHeader,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function main() {
|
|
55
|
+
const { parentPid, appVersion, osType, logFile, clearcutEndpoint, clearcutForceFlushIntervalMs, clearcutIncludePidHeader, } = parseWatchdogArgs();
|
|
56
|
+
let logStream;
|
|
57
|
+
if (logFile) {
|
|
58
|
+
logStream = saveLogsToFile(logFile);
|
|
59
|
+
}
|
|
60
|
+
const exit = (code) => {
|
|
61
|
+
if (!logStream) {
|
|
62
|
+
process.exit(code);
|
|
63
|
+
}
|
|
64
|
+
void flushLogs(logStream).finally(() => {
|
|
65
|
+
process.exit(code);
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
logger('Watchdog started', JSON.stringify({
|
|
69
|
+
pid: process.pid,
|
|
70
|
+
parentPid,
|
|
71
|
+
version: appVersion,
|
|
72
|
+
osType,
|
|
73
|
+
}, null, 2));
|
|
74
|
+
const sender = new ClearcutSender({
|
|
75
|
+
appVersion,
|
|
76
|
+
osType: osType,
|
|
77
|
+
clearcutEndpoint,
|
|
78
|
+
forceFlushIntervalMs: clearcutForceFlushIntervalMs,
|
|
79
|
+
includePidHeader: clearcutIncludePidHeader,
|
|
80
|
+
});
|
|
81
|
+
let isShuttingDown = false;
|
|
82
|
+
function onParentDeath(reason) {
|
|
83
|
+
if (isShuttingDown) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
isShuttingDown = true;
|
|
87
|
+
logger(`Parent death detected (${reason}). Sending shutdown event...`);
|
|
88
|
+
sender
|
|
89
|
+
.sendShutdownEvent()
|
|
90
|
+
.then(() => {
|
|
91
|
+
logger('Shutdown event sent. Exiting.');
|
|
92
|
+
exit(0);
|
|
93
|
+
})
|
|
94
|
+
.catch(err => {
|
|
95
|
+
logger('Failed to send shutdown event', err);
|
|
96
|
+
exit(1);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
process.stdin.on('end', () => onParentDeath('stdin end'));
|
|
100
|
+
process.stdin.on('close', () => onParentDeath('stdin close'));
|
|
101
|
+
process.on('disconnect', () => onParentDeath('ipc disconnect'));
|
|
102
|
+
const rl = readline.createInterface({
|
|
103
|
+
input: process.stdin,
|
|
104
|
+
terminal: false,
|
|
105
|
+
});
|
|
106
|
+
rl.on('line', line => {
|
|
107
|
+
try {
|
|
108
|
+
if (!line.trim()) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const msg = JSON.parse(line);
|
|
112
|
+
if (msg.type === WatchdogMessageType.LOG_EVENT && msg.payload) {
|
|
113
|
+
sender.enqueueEvent(msg.payload);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
logger('Failed to parse IPC message', err);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
try {
|
|
122
|
+
main();
|
|
123
|
+
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
console.error('Watchdog fatal error:', err);
|
|
126
|
+
process.exit(1);
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
// eslint-disable-next-line no-restricted-imports
|
|
7
|
+
import '../../node_modules/chrome-devtools-frontend/front_end/entrypoints/formatter_worker/formatter_worker-entrypoint.js';
|
|
8
|
+
//# sourceMappingURL=devtools-formatter-worker.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
// eslint-disable-next-line no-restricted-imports
|
|
7
|
+
import '../../node_modules/chrome-devtools-frontend/front_end/entrypoints/heap_snapshot_worker/heap_snapshot_worker-entrypoint.js';
|
|
8
|
+
//# sourceMappingURL=devtools-heap-snapshot-worker.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import 'urlpattern-polyfill';
|
|
7
|
+
import 'core-js/modules/es.promise.with-resolvers.js';
|
|
8
|
+
import 'core-js/modules/es.set.union.v2.js';
|
|
9
|
+
import 'core-js/proposals/iterator-helpers.js';
|
|
10
|
+
export { default as yargs } from 'yargs';
|
|
11
|
+
export { hideBin } from 'yargs/helpers';
|
|
12
|
+
export { default as semver } from 'semver';
|
|
13
|
+
export { default as debug } from 'debug';
|
|
14
|
+
export { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
15
|
+
export { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
16
|
+
export { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
17
|
+
export { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
18
|
+
export { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
19
|
+
export { SetLevelRequestSchema, ListRootsRequestSchema, RootsListChangedNotificationSchema, ListRootsResultSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
20
|
+
export { z as zod } from 'zod';
|
|
21
|
+
export { default as ajv } from 'ajv';
|
|
22
|
+
export { Locator, PredefinedNetworkConditions, KnownDevices, CDPSessionEvent, } from 'puppeteer-core';
|
|
23
|
+
export { default as puppeteer } from 'puppeteer-core';
|
|
24
|
+
export { PipeTransport } from 'puppeteer-core/internal/node/PipeTransport.js';
|
|
25
|
+
export { resolveDefaultUserDataDir, detectBrowserPlatform, Browser as BrowserEnum, } from '@puppeteer/browsers';
|
|
26
|
+
import { snapshot as snapshotImpl, navigation as navigationImpl, generateReport as generateReportImpl, } from './lighthouse-devtools-mcp-bundle.js';
|
|
27
|
+
export const snapshot = snapshotImpl;
|
|
28
|
+
export const navigation = navigationImpl;
|
|
29
|
+
export const generateReport = generateReportImpl;
|
|
30
|
+
import * as DevTools_1 from '../../node_modules/chrome-devtools-frontend/mcp/mcp.js';
|
|
31
|
+
export { DevTools_1 as DevTools };
|
|
32
|
+
//# sourceMappingURL=index.js.map
|
package/build/src/third_party/issue-descriptions/CoepCoopSandboxedIframeCannotNavigateToCoopPage.md
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
# An iframe navigation to a document with a Cross-Origin Opener Policy was blocked
|
|
2
|
+
|
|
3
|
+
A document with a Cross-Origin Opener Policy (COOP) was blocked from loading in an iframe, because the iframe specifies a sandbox attribute.
|
|
4
|
+
This protects COOP-enabled documents from inheriting properties from its opener.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Specify a more permissive Cross-Origin Resource Policy to prevent a resource from being blocked
|
|
2
|
+
|
|
3
|
+
Your site tries to access an external resource that only allows same-origin usage.
|
|
4
|
+
This behavior prevents a document from loading any non-same-origin resources which don’t explicitly grant permission to be loaded.
|
|
5
|
+
|
|
6
|
+
To solve this, add the following to the resource’s HTML response header:
|
|
7
|
+
* `Cross-Origin-Resource-Policy: same-site` if the resource and your site are served from the same site.
|
|
8
|
+
* `Cross-Origin-Resource-Policy: cross-origin` if the resource is served from another location than your website. ⚠️If you set this header, any website can embed this resource.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Specify a Cross-Origin Resource Policy to prevent a resource from being blocked
|
|
2
|
+
|
|
3
|
+
Because your site has the Cross-Origin Embedder Policy (COEP) enabled, each
|
|
4
|
+
resource must specify a suitable Cross-Origin Resource Policy (CORP). This
|
|
5
|
+
behavior prevents a document from loading cross-origin resources which don’t
|
|
6
|
+
explicitly grant permission to be loaded.
|
|
7
|
+
|
|
8
|
+
To solve this, add the following to the resource’ response header:
|
|
9
|
+
* `Cross-Origin-Resource-Policy: same-site` if the resource and your site are
|
|
10
|
+
served from the same site.
|
|
11
|
+
* `Cross-Origin-Resource-Policy: cross-origin` if the resource is served from
|
|
12
|
+
another location than your website. ⚠️If you set this header, any website can
|
|
13
|
+
embed this resource.
|
|
14
|
+
|
|
15
|
+
Alternatively, the document can use the variant: `Cross-Origin-Embedder-Policy:
|
|
16
|
+
credentialless` instead of `require-corp`. It allows loading the resource,
|
|
17
|
+
despite the missing CORP header, at the cost of requesting it without
|
|
18
|
+
credentials like Cookies.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Specify a more permissive Cross-Origin Resource Policy to prevent a resource from being blocked
|
|
2
|
+
|
|
3
|
+
Your site tries to access an external resource that only allows same-site usage.
|
|
4
|
+
This behavior prevents a document from loading any non-same-site resources which don’t explicitly grant permission to be loaded.
|
|
5
|
+
|
|
6
|
+
To solve this, add the following to the resource’s HTML response header: `Cross-Origin-Resource-Policy: cross-origin`
|
|
7
|
+
⚠️If you set this header, any website can embed this resource.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Specify a Cross-Origin Embedder Policy to prevent this frame from being blocked
|
|
2
|
+
|
|
3
|
+
Because your site has the Cross-Origin Embedder Policy (COEP) enabled, each
|
|
4
|
+
embedded iframe must also specify this policy. This behavior protects private
|
|
5
|
+
data from being exposed to untrusted third party sites.
|
|
6
|
+
|
|
7
|
+
To solve this, add one of following to the embedded frame’s HTML response
|
|
8
|
+
header:
|
|
9
|
+
* `Cross-Origin-Embedder-Policy: require-corp`
|
|
10
|
+
* `Cross-Origin-Embedder-Policy: credentialless` (Chrome > 96)
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Page layout may be unexpected due to Quirks Mode
|
|
2
|
+
|
|
3
|
+
One or more documents in this page is in Quirks Mode, which will render the affected document(s) with quirks incompatible with the current HTML and CSS specifications.
|
|
4
|
+
|
|
5
|
+
Quirks Mode exists mostly due to historical reasons. If this is not intentional, you can [add or modify the DOCTYPE to be `<!DOCTYPE html>`](issueQuirksModeDoctype) to render the page in No Quirks Mode.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Ensure cookie attribute values don’t exceed 1024 characters
|
|
2
|
+
|
|
3
|
+
Cookie attribute values exceeding 1024 characters in size will result in the attribute being ignored. This could lead to unexpected behavior since the cookie will be processed as if the offending attribute / attribute value pair were not present.
|
|
4
|
+
|
|
5
|
+
Resolve this issue by ensuring that cookie attribute values don’t exceed 1024 characters.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Users may have difficulties reading text content due to insufficient color contrast
|
|
2
|
+
|
|
3
|
+
Low-contrast text is difficult or impossible for users to read. A [minimum contrast ratio (AA) of 4.5](issuesContrastWCAG21AA) is recommended for all text. Since font size and weight affect color perception, an exception is made for very large or bold text — in this case, a contrast ratio of 3.0 is allowed. The [enhanced conformance level (AAA)](issuesContrastWCAG21AAA) requires the contrast ratio to be above 7.0 for regular text and 4.5 for large text.
|
|
4
|
+
|
|
5
|
+
Update colors or change the font size or weight to achieve sufficient contrast. You can use the [“Suggest color” feature](issuesContrastSuggestColor) in the DevTools color picker to automatically select a better text color.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Migrate entirely to HTTPS to have cookies sent to same-site subresources
|
|
2
|
+
|
|
3
|
+
A cookie was not sent to {PLACEHOLDER_destination} origin from {PLACEHOLDER_origin} context.
|
|
4
|
+
Because this cookie would have been sent across schemes on the same site, it was not sent.
|
|
5
|
+
This behavior enhances the `SameSite` attribute’s protection of user data from request forgery by network attackers.
|
|
6
|
+
|
|
7
|
+
Resolve this issue by migrating your site (as defined by the eTLD+1) entirely to HTTPS.
|
|
8
|
+
It is also recommended to mark the cookie with the `Secure` attribute if that is not already the case.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Migrate entirely to HTTPS to allow cookies to be set by same-site subresources
|
|
2
|
+
|
|
3
|
+
A cookie was not set by {PLACEHOLDER_origin} origin in {PLACEHOLDER_destination} context.
|
|
4
|
+
Because this cookie would have been set across schemes on the same site, it was blocked.
|
|
5
|
+
This behavior enhances the `SameSite` attribute’s protection of user data from request forgery by network attackers.
|
|
6
|
+
|
|
7
|
+
Resolve this issue by migrating your site (as defined by the eTLD+1) entirely to HTTPS.
|
|
8
|
+
It is also recommended to mark the cookie with the `Secure` attribute if that is not already the case.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Migrate entirely to HTTPS to have cookies sent on same-site requests
|
|
2
|
+
|
|
3
|
+
A cookie was not sent to {PLACEHOLDER_destination} origin from {PLACEHOLDER_origin} context on a navigation.
|
|
4
|
+
Because this cookie would have been sent across schemes on the same site, it was not sent.
|
|
5
|
+
This behavior enhances the `SameSite` attribute’s protection of user data from request forgery by network attackers.
|
|
6
|
+
|
|
7
|
+
Resolve this issue by migrating your site (as defined by the eTLD+1) entirely to HTTPS.
|
|
8
|
+
It is also recommended to mark the cookie with the `Secure` attribute if that is not already the case.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Mark cross-site cookies as Secure to allow them to be sent in cross-site requests
|
|
2
|
+
|
|
3
|
+
Cookies marked with `SameSite=None` must also be marked with `Secure` to get sent in cross-site requests.
|
|
4
|
+
This behavior protects user data from being sent over an insecure connection.
|
|
5
|
+
|
|
6
|
+
Resolve this issue by updating the attributes of the cookie:
|
|
7
|
+
* Specify `SameSite=None` and `Secure` if the cookie should be sent in cross-site requests. This enables third-party use.
|
|
8
|
+
* Specify `SameSite=Strict` or `SameSite=Lax` if the cookie should not be sent in cross-site requests.
|