@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.
Files changed (294) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +873 -0
  3. package/build/src/DevToolsConnectionAdapter.js +70 -0
  4. package/build/src/DevtoolsUtils.js +295 -0
  5. package/build/src/HeapSnapshotManager.js +110 -0
  6. package/build/src/McpContext.js +605 -0
  7. package/build/src/McpPage.js +315 -0
  8. package/build/src/McpResponse.js +858 -0
  9. package/build/src/Mutex.js +38 -0
  10. package/build/src/PageCollector.js +297 -0
  11. package/build/src/SlimMcpResponse.js +19 -0
  12. package/build/src/TextSnapshot.js +236 -0
  13. package/build/src/ToolHandler.js +217 -0
  14. package/build/src/WaitForHelper.js +190 -0
  15. package/build/src/bin/check-latest-version.js +50 -0
  16. package/build/src/bin/chrome-devtools-cli-options.js +840 -0
  17. package/build/src/bin/chrome-devtools-mcp-cli-options.js +350 -0
  18. package/build/src/bin/chrome-devtools-mcp-main.js +94 -0
  19. package/build/src/bin/chrome-devtools-mcp.js +31 -0
  20. package/build/src/bin/chrome-devtools.js +189 -0
  21. package/build/src/bin/install-service.js +246 -0
  22. package/build/src/bin/service/chrome-devtools-mcp.service.template +17 -0
  23. package/build/src/bin/service/com.vibebrowser.chrome-devtools-mcp.plist.template +37 -0
  24. package/build/src/browser.js +204 -0
  25. package/build/src/daemon/client.js +154 -0
  26. package/build/src/daemon/daemon.js +204 -0
  27. package/build/src/daemon/types.js +7 -0
  28. package/build/src/daemon/utils.js +115 -0
  29. package/build/src/formatters/ConsoleFormatter.js +288 -0
  30. package/build/src/formatters/HeapSnapshotFormatter.js +54 -0
  31. package/build/src/formatters/IssueFormatter.js +193 -0
  32. package/build/src/formatters/NetworkFormatter.js +236 -0
  33. package/build/src/formatters/SnapshotFormatter.js +135 -0
  34. package/build/src/index.js +140 -0
  35. package/build/src/issue-descriptions.js +40 -0
  36. package/build/src/logger.js +37 -0
  37. package/build/src/polyfill.js +8 -0
  38. package/build/src/telemetry/ClearcutLogger.js +169 -0
  39. package/build/src/telemetry/WatchdogClient.js +61 -0
  40. package/build/src/telemetry/errors.js +18 -0
  41. package/build/src/telemetry/flagUtils.js +89 -0
  42. package/build/src/telemetry/metricsRegistry.js +89 -0
  43. package/build/src/telemetry/persistence.js +72 -0
  44. package/build/src/telemetry/transformation.js +134 -0
  45. package/build/src/telemetry/types.js +31 -0
  46. package/build/src/telemetry/watchdog/ClearcutSender.js +205 -0
  47. package/build/src/telemetry/watchdog/main.js +128 -0
  48. package/build/src/third_party/devtools-formatter-worker.js +8 -0
  49. package/build/src/third_party/devtools-heap-snapshot-worker.js +8 -0
  50. package/build/src/third_party/index.js +32 -0
  51. package/build/src/third_party/issue-descriptions/CoepCoopSandboxedIframeCannotNavigateToCoopPage.md +4 -0
  52. package/build/src/third_party/issue-descriptions/CoepCorpNotSameOrigin.md +8 -0
  53. package/build/src/third_party/issue-descriptions/CoepCorpNotSameOriginAfterDefaultedToSameOriginByCoep.md +18 -0
  54. package/build/src/third_party/issue-descriptions/CoepCorpNotSameSite.md +7 -0
  55. package/build/src/third_party/issue-descriptions/CoepFrameResourceNeedsCoepHeader.md +10 -0
  56. package/build/src/third_party/issue-descriptions/CompatibilityModeQuirks.md +5 -0
  57. package/build/src/third_party/issue-descriptions/CookieAttributeValueExceedsMaxSize.md +5 -0
  58. package/build/src/third_party/issue-descriptions/LowTextContrast.md +5 -0
  59. package/build/src/third_party/issue-descriptions/SameSiteExcludeContextDowngradeRead.md +8 -0
  60. package/build/src/third_party/issue-descriptions/SameSiteExcludeContextDowngradeSet.md +8 -0
  61. package/build/src/third_party/issue-descriptions/SameSiteExcludeNavigationContextDowngrade.md +8 -0
  62. package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureErrorRead.md +8 -0
  63. package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureErrorSet.md +8 -0
  64. package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureWarnRead.md +8 -0
  65. package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureWarnSet.md +8 -0
  66. package/build/src/third_party/issue-descriptions/SameSiteUnspecifiedLaxAllowUnsafeRead.md +9 -0
  67. package/build/src/third_party/issue-descriptions/SameSiteUnspecifiedLaxAllowUnsafeSet.md +9 -0
  68. package/build/src/third_party/issue-descriptions/SameSiteWarnCrossDowngradeRead.md +8 -0
  69. package/build/src/third_party/issue-descriptions/SameSiteWarnCrossDowngradeSet.md +8 -0
  70. package/build/src/third_party/issue-descriptions/SameSiteWarnStrictLaxDowngradeStrict.md +8 -0
  71. package/build/src/third_party/issue-descriptions/arInsecureContext.md +7 -0
  72. package/build/src/third_party/issue-descriptions/arInvalidInfoHeader.md +5 -0
  73. package/build/src/third_party/issue-descriptions/arInvalidRegisterOsSourceHeader.md +5 -0
  74. package/build/src/third_party/issue-descriptions/arInvalidRegisterOsTriggerHeader.md +5 -0
  75. package/build/src/third_party/issue-descriptions/arInvalidRegisterSourceHeader.md +5 -0
  76. package/build/src/third_party/issue-descriptions/arInvalidRegisterTriggerHeader.md +5 -0
  77. package/build/src/third_party/issue-descriptions/arNavigationRegistrationUniqueScopeAlreadySet.md +5 -0
  78. package/build/src/third_party/issue-descriptions/arNavigationRegistrationWithoutTransientUserActivation.md +6 -0
  79. package/build/src/third_party/issue-descriptions/arNoRegisterOsSourceHeader.md +5 -0
  80. package/build/src/third_party/issue-descriptions/arNoRegisterOsTriggerHeader.md +5 -0
  81. package/build/src/third_party/issue-descriptions/arNoRegisterSourceHeader.md +5 -0
  82. package/build/src/third_party/issue-descriptions/arNoRegisterTriggerHeader.md +5 -0
  83. package/build/src/third_party/issue-descriptions/arNoWebOrOsSupport.md +4 -0
  84. package/build/src/third_party/issue-descriptions/arOsSourceIgnored.md +18 -0
  85. package/build/src/third_party/issue-descriptions/arOsTriggerIgnored.md +19 -0
  86. package/build/src/third_party/issue-descriptions/arPermissionPolicyDisabled.md +8 -0
  87. package/build/src/third_party/issue-descriptions/arSourceAndTriggerHeaders.md +9 -0
  88. package/build/src/third_party/issue-descriptions/arSourceIgnored.md +13 -0
  89. package/build/src/third_party/issue-descriptions/arTriggerIgnored.md +12 -0
  90. package/build/src/third_party/issue-descriptions/arUntrustworthyReportingOrigin.md +10 -0
  91. package/build/src/third_party/issue-descriptions/arWebAndOsHeaders.md +11 -0
  92. package/build/src/third_party/issue-descriptions/bounceTrackingMitigations.md +3 -0
  93. package/build/src/third_party/issue-descriptions/clientHintMetaTagAllowListInvalidOrigin.md +4 -0
  94. package/build/src/third_party/issue-descriptions/clientHintMetaTagModifiedHTML.md +4 -0
  95. package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidAllowlistItemType.md +12 -0
  96. package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidHeader.md +12 -0
  97. package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidUrlPattern.md +8 -0
  98. package/build/src/third_party/issue-descriptions/connectionAllowlistItemNotInnerList.md +12 -0
  99. package/build/src/third_party/issue-descriptions/connectionAllowlistMoreThanOneList.md +7 -0
  100. package/build/src/third_party/issue-descriptions/connectionAllowlistReportingEndpointNotToken.md +10 -0
  101. package/build/src/third_party/issue-descriptions/cookieCrossSiteRedirectDowngrade.md +12 -0
  102. package/build/src/third_party/issue-descriptions/cookieExcludeBlockedWithinRelatedWebsiteSet.md +4 -0
  103. package/build/src/third_party/issue-descriptions/cookieExcludeDomainNonAscii.md +11 -0
  104. package/build/src/third_party/issue-descriptions/cookieExcludePortMismatch.md +8 -0
  105. package/build/src/third_party/issue-descriptions/cookieExcludeSchemeMismatch.md +7 -0
  106. package/build/src/third_party/issue-descriptions/cookieExcludeThirdPartyPhaseoutRead.md +6 -0
  107. package/build/src/third_party/issue-descriptions/cookieExcludeThirdPartyPhaseoutSet.md +6 -0
  108. package/build/src/third_party/issue-descriptions/cookieWarnDomainNonAscii.md +11 -0
  109. package/build/src/third_party/issue-descriptions/cookieWarnMetadataGrantRead.md +4 -0
  110. package/build/src/third_party/issue-descriptions/cookieWarnMetadataGrantSet.md +4 -0
  111. package/build/src/third_party/issue-descriptions/cookieWarnThirdPartyPhaseoutRead.md +6 -0
  112. package/build/src/third_party/issue-descriptions/cookieWarnThirdPartyPhaseoutSet.md +6 -0
  113. package/build/src/third_party/issue-descriptions/corsAllowCredentialsRequired.md +6 -0
  114. package/build/src/third_party/issue-descriptions/corsDisabledScheme.md +7 -0
  115. package/build/src/third_party/issue-descriptions/corsDisallowedByMode.md +7 -0
  116. package/build/src/third_party/issue-descriptions/corsHeaderDisallowedByPreflightResponse.md +5 -0
  117. package/build/src/third_party/issue-descriptions/corsInvalidHeaderValues.md +7 -0
  118. package/build/src/third_party/issue-descriptions/corsLocalNetworkAccessPermissionDenied.md +19 -0
  119. package/build/src/third_party/issue-descriptions/corsMethodDisallowedByPreflightResponse.md +5 -0
  120. package/build/src/third_party/issue-descriptions/corsNoCorsRedirectModeNotFollow.md +5 -0
  121. package/build/src/third_party/issue-descriptions/corsOriginMismatch.md +6 -0
  122. package/build/src/third_party/issue-descriptions/corsPreflightResponseInvalid.md +5 -0
  123. package/build/src/third_party/issue-descriptions/corsRedirectContainsCredentials.md +5 -0
  124. package/build/src/third_party/issue-descriptions/corsWildcardOriginNotAllowed.md +8 -0
  125. package/build/src/third_party/issue-descriptions/cspEvalViolation.md +9 -0
  126. package/build/src/third_party/issue-descriptions/cspInlineViolation.md +10 -0
  127. package/build/src/third_party/issue-descriptions/cspTrustedTypesPolicyViolation.md +5 -0
  128. package/build/src/third_party/issue-descriptions/cspTrustedTypesSinkViolation.md +8 -0
  129. package/build/src/third_party/issue-descriptions/cspURLViolation.md +10 -0
  130. package/build/src/third_party/issue-descriptions/deprecation.md +3 -0
  131. package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsHttpNotFound.md +1 -0
  132. package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsInvalidResponse.md +1 -0
  133. package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsNoResponse.md +1 -0
  134. package/build/src/third_party/issue-descriptions/federatedAuthRequestApprovalDeclined.md +1 -0
  135. package/build/src/third_party/issue-descriptions/federatedAuthRequestCanceled.md +1 -0
  136. package/build/src/third_party/issue-descriptions/federatedAuthRequestErrorFetchingSignin.md +1 -0
  137. package/build/src/third_party/issue-descriptions/federatedAuthRequestErrorIdToken.md +1 -0
  138. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenHttpNotFound.md +1 -0
  139. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenInvalidRequest.md +1 -0
  140. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenInvalidResponse.md +1 -0
  141. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenNoResponse.md +1 -0
  142. package/build/src/third_party/issue-descriptions/federatedAuthRequestInvalidSigninResponse.md +1 -0
  143. package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestHttpNotFound.md +1 -0
  144. package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestInvalidResponse.md +1 -0
  145. package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestNoResponse.md +1 -0
  146. package/build/src/third_party/issue-descriptions/federatedAuthRequestTooManyRequests.md +1 -0
  147. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestInvalidAccountsResponse.md +1 -0
  148. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestInvalidConfigOrWellKnown.md +1 -0
  149. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoAccountSharingPermission.md +1 -0
  150. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoApiPermission.md +1 -0
  151. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoReturningUserFromFetchedAccounts.md +1 -0
  152. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotIframe.md +1 -0
  153. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotPotentiallyTrustworthy.md +1 -0
  154. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotSameOrigin.md +1 -0
  155. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotSignedInWithIdp.md +1 -0
  156. package/build/src/third_party/issue-descriptions/fetchingPartitionedBlobURL.md +7 -0
  157. package/build/src/third_party/issue-descriptions/genericFormAriaLabelledByToNonExistingIdError.md +8 -0
  158. package/build/src/third_party/issue-descriptions/genericFormAutocompleteAttributeEmptyError.md +5 -0
  159. package/build/src/third_party/issue-descriptions/genericFormDuplicateIdForInputError.md +5 -0
  160. package/build/src/third_party/issue-descriptions/genericFormEmptyIdAndNameAttributesForInputError.md +5 -0
  161. package/build/src/third_party/issue-descriptions/genericFormInputAssignedAutocompleteValueToIdOrNameAttributeError.md +5 -0
  162. package/build/src/third_party/issue-descriptions/genericFormInputHasWrongButWellIntendedAutocompleteValueError.md +5 -0
  163. package/build/src/third_party/issue-descriptions/genericFormInputWithNoLabelError.md +5 -0
  164. package/build/src/third_party/issue-descriptions/genericFormLabelForMatchesNonExistingIdError.md +5 -0
  165. package/build/src/third_party/issue-descriptions/genericFormLabelForNameError.md +5 -0
  166. package/build/src/third_party/issue-descriptions/genericFormLabelHasNeitherForNorNestedInputError.md +5 -0
  167. package/build/src/third_party/issue-descriptions/genericFormModelContextMissingToolDescription.md +5 -0
  168. package/build/src/third_party/issue-descriptions/genericFormModelContextMissingToolName.md +5 -0
  169. package/build/src/third_party/issue-descriptions/genericFormModelContextParameterMissingName.md +5 -0
  170. package/build/src/third_party/issue-descriptions/genericFormModelContextParameterMissingTitleAndDescription.md +5 -0
  171. package/build/src/third_party/issue-descriptions/genericFormModelContextRequiredParameterMissingName.md +5 -0
  172. package/build/src/third_party/issue-descriptions/genericNavigationEntryMarkedSkippable.md +7 -0
  173. package/build/src/third_party/issue-descriptions/genericResponseWasBlockedByORB.md +4 -0
  174. package/build/src/third_party/issue-descriptions/heavyAd.md +10 -0
  175. package/build/src/third_party/issue-descriptions/mixedContent.md +5 -0
  176. package/build/src/third_party/issue-descriptions/navigatingPartitionedBlobURL.md +5 -0
  177. package/build/src/third_party/issue-descriptions/permissionElementActivationDisabled.md +7 -0
  178. package/build/src/third_party/issue-descriptions/permissionElementActivationDisabledWithOccluder.md +9 -0
  179. package/build/src/third_party/issue-descriptions/permissionElementActivationDisabledWithOccluderParent.md +9 -0
  180. package/build/src/third_party/issue-descriptions/permissionElementCspFrameAncestorsMissing.md +5 -0
  181. package/build/src/third_party/issue-descriptions/permissionElementFencedFrameDisallowed.md +5 -0
  182. package/build/src/third_party/issue-descriptions/permissionElementFontSizeTooLarge.md +5 -0
  183. package/build/src/third_party/issue-descriptions/permissionElementFontSizeTooSmall.md +5 -0
  184. package/build/src/third_party/issue-descriptions/permissionElementGeolocationDeprecated.md +5 -0
  185. package/build/src/third_party/issue-descriptions/permissionElementInsetBoxShadowUnsupported.md +5 -0
  186. package/build/src/third_party/issue-descriptions/permissionElementInvalidDisplayStyle.md +5 -0
  187. package/build/src/third_party/issue-descriptions/permissionElementInvalidSizeValue.md +5 -0
  188. package/build/src/third_party/issue-descriptions/permissionElementInvalidType.md +5 -0
  189. package/build/src/third_party/issue-descriptions/permissionElementInvalidTypeActivation.md +5 -0
  190. package/build/src/third_party/issue-descriptions/permissionElementLowContrast.md +5 -0
  191. package/build/src/third_party/issue-descriptions/permissionElementNonOpaqueColor.md +5 -0
  192. package/build/src/third_party/issue-descriptions/permissionElementPaddingBottomUnsupported.md +6 -0
  193. package/build/src/third_party/issue-descriptions/permissionElementPaddingRightUnsupported.md +6 -0
  194. package/build/src/third_party/issue-descriptions/permissionElementPermissionsPolicyBlocked.md +5 -0
  195. package/build/src/third_party/issue-descriptions/permissionElementRegistrationFailed.md +5 -0
  196. package/build/src/third_party/issue-descriptions/permissionElementRequestInProgress.md +5 -0
  197. package/build/src/third_party/issue-descriptions/permissionElementSecurityChecksFailed.md +5 -0
  198. package/build/src/third_party/issue-descriptions/permissionElementTypeNotSupported.md +5 -0
  199. package/build/src/third_party/issue-descriptions/permissionElementUntrustedEvent.md +7 -0
  200. package/build/src/third_party/issue-descriptions/placeholderDescriptionForInvisibleIssues.md +3 -0
  201. package/build/src/third_party/issue-descriptions/propertyRuleInvalidNameIssue.md +3 -0
  202. package/build/src/third_party/issue-descriptions/propertyRuleIssue.md +7 -0
  203. package/build/src/third_party/issue-descriptions/selectElementAccessibilityDisallowedOptGroupChild.md +7 -0
  204. package/build/src/third_party/issue-descriptions/selectElementAccessibilityDisallowedSelectChild.md +7 -0
  205. package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentAttributesSelectDescendant.md +3 -0
  206. package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentLegendChild.md +3 -0
  207. package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentOptionChild.md +3 -0
  208. package/build/src/third_party/issue-descriptions/selectElementAccessibilityNonPhrasingContentOptionChild.md +3 -0
  209. package/build/src/third_party/issue-descriptions/selectivePermissionsIntervention.md +7 -0
  210. package/build/src/third_party/issue-descriptions/sharedArrayBuffer.md +7 -0
  211. package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorCrossOriginNoCorsRequest.md +1 -0
  212. package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorDictionaryLoadFailure.md +3 -0
  213. package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorMatchingDictionaryNotUsed.md +3 -0
  214. package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorUnexpectedContentDictionaryHeader.md +1 -0
  215. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorCossOriginNoCorsRequest.md +1 -0
  216. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorDisallowedBySettings.md +1 -0
  217. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorExpiredResponse.md +3 -0
  218. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorFeatureDisabled.md +3 -0
  219. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInsufficientResources.md +1 -0
  220. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInvalidMatchField.md +1 -0
  221. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInvalidStructuredHeader.md +1 -0
  222. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInvalidTTLField.md +1 -0
  223. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNavigationRequest.md +3 -0
  224. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNoMatchField.md +1 -0
  225. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonIntegerTTLField.md +1 -0
  226. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonListMatchDestField.md +1 -0
  227. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonSecureContext.md +3 -0
  228. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonStringIdField.md +1 -0
  229. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonStringInMatchDestList.md +1 -0
  230. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonStringMatchField.md +1 -0
  231. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonTokenTypeField.md +1 -0
  232. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorRequestAborted.md +1 -0
  233. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorShuttingDown.md +1 -0
  234. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorTooLongIdField.md +3 -0
  235. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorUnsupportedType.md +3 -0
  236. package/build/src/third_party/issue-descriptions/sriInvalidSignatureHeader.md +14 -0
  237. package/build/src/third_party/issue-descriptions/sriInvalidSignatureInputHeader.md +15 -0
  238. package/build/src/third_party/issue-descriptions/sriMissingSignatureHeader.md +8 -0
  239. package/build/src/third_party/issue-descriptions/sriMissingSignatureInputHeader.md +7 -0
  240. package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsIncorrectLength.md +11 -0
  241. package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsNotByteSequence.md +14 -0
  242. package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsParameterized.md +15 -0
  243. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidComponentName.md +8 -0
  244. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidComponentType.md +13 -0
  245. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidDerivedComponentParameter.md +4 -0
  246. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidHeaderComponentParameter.md +5 -0
  247. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidParameter.md +11 -0
  248. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderKeyIdLength.md +12 -0
  249. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderMissingLabel.md +6 -0
  250. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderMissingRequiredParameters.md +8 -0
  251. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderValueMissingComponents.md +11 -0
  252. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderValueNotInnerList.md +11 -0
  253. package/build/src/third_party/issue-descriptions/sriValidationFailedIntegrityMismatch.md +10 -0
  254. package/build/src/third_party/issue-descriptions/sriValidationFailedInvalidLength.md +5 -0
  255. package/build/src/third_party/issue-descriptions/sriValidationFailedSignatureExpired.md +6 -0
  256. package/build/src/third_party/issue-descriptions/sriValidationFailedSignatureMismatch.md +11 -0
  257. package/build/src/third_party/issue-descriptions/stylesheetLateImport.md +4 -0
  258. package/build/src/third_party/issue-descriptions/stylesheetRequestFailed.md +3 -0
  259. package/build/src/third_party/issue-descriptions/summaryElementAccessibilityInteractiveContentSummaryDescendant.md +3 -0
  260. package/build/src/third_party/issue-descriptions/unencodedDigestIncorrectDigestLength.md +12 -0
  261. package/build/src/third_party/issue-descriptions/unencodedDigestIncorrectDigestType.md +17 -0
  262. package/build/src/third_party/issue-descriptions/unencodedDigestMalformedDictionary.md +14 -0
  263. package/build/src/third_party/issue-descriptions/unencodedDigestUnknownAlgorithm.md +15 -0
  264. package/build/src/third_party/lighthouse-devtools-mcp-bundle.js +61598 -0
  265. package/build/src/tools/ToolDefinition.js +73 -0
  266. package/build/src/tools/categories.js +36 -0
  267. package/build/src/tools/console.js +91 -0
  268. package/build/src/tools/emulation.js +57 -0
  269. package/build/src/tools/extensions.js +96 -0
  270. package/build/src/tools/input.js +461 -0
  271. package/build/src/tools/lighthouse.js +131 -0
  272. package/build/src/tools/memory.js +106 -0
  273. package/build/src/tools/network.js +125 -0
  274. package/build/src/tools/pages.js +411 -0
  275. package/build/src/tools/performance.js +196 -0
  276. package/build/src/tools/screencast.js +95 -0
  277. package/build/src/tools/screenshot.js +87 -0
  278. package/build/src/tools/script.js +151 -0
  279. package/build/src/tools/slim/tools.js +85 -0
  280. package/build/src/tools/snapshot.js +60 -0
  281. package/build/src/tools/thirdPartyDeveloper.js +75 -0
  282. package/build/src/tools/tools.js +56 -0
  283. package/build/src/tools/webmcp.js +64 -0
  284. package/build/src/trace-processing/parse.js +85 -0
  285. package/build/src/types.js +7 -0
  286. package/build/src/utils/check-for-updates.js +74 -0
  287. package/build/src/utils/files.js +18 -0
  288. package/build/src/utils/id.js +16 -0
  289. package/build/src/utils/keyboard.js +297 -0
  290. package/build/src/utils/pagination.js +50 -0
  291. package/build/src/utils/string.js +37 -0
  292. package/build/src/utils/types.js +7 -0
  293. package/build/src/version.js +10 -0
  294. package/package.json +93 -0
@@ -0,0 +1,75 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { zod, ajv } from '../third_party/index.js';
7
+ import { ToolCategory } from './categories.js';
8
+ import { definePageTool } from './ToolDefinition.js';
9
+ export const listThirdPartyDeveloperTools = definePageTool({
10
+ name: 'list_3p_developer_tools',
11
+ description: `Lists all third-party developer tools the page exposes for providing runtime information.
12
+ Third-party developer tools can be called via the 'execute_3p_developer_tool()' MCP tool.
13
+ Alternatively, third-party developer tools can be executed by calling 'evaluate_script' and adding the
14
+ following command to the script:
15
+ 'window.__dtmcp.executeTool(toolName, params)'
16
+ This might be helpful when the third-party developer tools return non-serializable values or when composing
17
+ third-party developer tools with additional functionality.`,
18
+ annotations: {
19
+ category: ToolCategory.THIRD_PARTY,
20
+ readOnlyHint: true,
21
+ },
22
+ schema: {},
23
+ blockedByDialog: false,
24
+ handler: async (_request, response, _context) => {
25
+ response.setListThirdPartyDeveloperTools();
26
+ },
27
+ });
28
+ export const executeThirdPartyDeveloperTool = definePageTool({
29
+ name: 'execute_3p_developer_tool',
30
+ description: `Executes a tool exposed by the page.`,
31
+ annotations: {
32
+ category: ToolCategory.THIRD_PARTY,
33
+ readOnlyHint: false,
34
+ },
35
+ schema: {
36
+ toolName: zod.string().describe('The name of the tool to execute'),
37
+ params: zod
38
+ .string()
39
+ .optional()
40
+ .describe('The JSON-stringified parameters to pass to the tool'),
41
+ },
42
+ blockedByDialog: false,
43
+ handler: async (request, response) => {
44
+ const toolName = request.params.toolName;
45
+ let params = {};
46
+ if (request.params.params) {
47
+ try {
48
+ const parsed = JSON.parse(request.params.params);
49
+ if (typeof parsed === 'object' && parsed !== null) {
50
+ params = parsed;
51
+ }
52
+ else {
53
+ throw new Error('Parsed params is not an object');
54
+ }
55
+ }
56
+ catch (e) {
57
+ const errorMessage = e instanceof Error ? e.message : String(e);
58
+ throw new Error(`Failed to parse params as JSON: ${errorMessage}`);
59
+ }
60
+ }
61
+ const toolGroup = request.page.getThirdPartyDeveloperTools();
62
+ const tool = toolGroup?.tools.find(t => t.name === toolName);
63
+ if (!tool) {
64
+ throw new Error(`Tool ${toolName} not found`);
65
+ }
66
+ const ajvInstance = new ajv();
67
+ const validate = ajvInstance.compile(tool.inputSchema);
68
+ const valid = validate(params);
69
+ if (!valid) {
70
+ throw new Error(`Invalid parameters for tool ${toolName}: ${ajvInstance.errorsText(validate.errors)}`);
71
+ }
72
+ await request.page.executeThirdPartyDeveloperTool(toolName, params, response);
73
+ },
74
+ });
75
+ //# sourceMappingURL=thirdPartyDeveloper.js.map
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import * as consoleTools from './console.js';
7
+ import * as emulationTools from './emulation.js';
8
+ import * as extensionTools from './extensions.js';
9
+ import * as inputTools from './input.js';
10
+ import * as lighthouseTools from './lighthouse.js';
11
+ import * as memoryTools from './memory.js';
12
+ import * as networkTools from './network.js';
13
+ import * as pagesTools from './pages.js';
14
+ import * as performanceTools from './performance.js';
15
+ import * as screencastTools from './screencast.js';
16
+ import * as screenshotTools from './screenshot.js';
17
+ import * as scriptTools from './script.js';
18
+ import * as slimTools from './slim/tools.js';
19
+ import * as snapshotTools from './snapshot.js';
20
+ import * as thirdPartyDeveloperTools from './thirdPartyDeveloper.js';
21
+ import * as webmcpTools from './webmcp.js';
22
+ export const createTools = (args) => {
23
+ const rawTools = args.slim
24
+ ? Object.values(slimTools)
25
+ : [
26
+ ...Object.values(consoleTools),
27
+ ...Object.values(emulationTools),
28
+ ...Object.values(extensionTools),
29
+ ...Object.values(inputTools),
30
+ ...Object.values(lighthouseTools),
31
+ ...Object.values(memoryTools),
32
+ ...Object.values(networkTools),
33
+ ...Object.values(pagesTools),
34
+ ...Object.values(performanceTools),
35
+ ...Object.values(screencastTools),
36
+ ...Object.values(screenshotTools),
37
+ ...Object.values(scriptTools),
38
+ ...Object.values(snapshotTools),
39
+ ...Object.values(thirdPartyDeveloperTools),
40
+ ...Object.values(webmcpTools),
41
+ ];
42
+ const tools = [];
43
+ for (const tool of rawTools) {
44
+ if (typeof tool === 'function') {
45
+ tools.push(tool(args));
46
+ }
47
+ else {
48
+ tools.push(tool);
49
+ }
50
+ }
51
+ tools.sort((a, b) => {
52
+ return a.name.localeCompare(b.name);
53
+ });
54
+ return tools;
55
+ };
56
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1,64 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { zod } from '../third_party/index.js';
7
+ import { ToolCategory } from './categories.js';
8
+ import { definePageTool } from './ToolDefinition.js';
9
+ export const listWebMcpTools = definePageTool({
10
+ name: 'list_webmcp_tools',
11
+ description: `Lists all WebMCP tools the page exposes.`,
12
+ annotations: {
13
+ category: ToolCategory.WEBMCP,
14
+ readOnlyHint: true,
15
+ },
16
+ schema: {},
17
+ blockedByDialog: false,
18
+ handler: async (_request, response, _context) => {
19
+ response.setListWebMcpTools();
20
+ },
21
+ });
22
+ export const executeWebMcpTool = definePageTool({
23
+ name: 'execute_webmcp_tool',
24
+ description: `Executes a WebMCP tool exposed by the page.`,
25
+ annotations: {
26
+ category: ToolCategory.WEBMCP,
27
+ readOnlyHint: false,
28
+ },
29
+ schema: {
30
+ toolName: zod.string().describe('The name of the WebMCP tool to execute'),
31
+ input: zod
32
+ .string()
33
+ .optional()
34
+ .describe('The JSON-stringified parameters to pass to the WebMCP tool'),
35
+ },
36
+ blockedByDialog: false,
37
+ handler: async (request, response) => {
38
+ const toolName = request.params.toolName;
39
+ let input = {};
40
+ if (request.params.input) {
41
+ try {
42
+ const parsed = JSON.parse(request.params.input);
43
+ if (typeof parsed === 'object' && parsed !== null) {
44
+ input = parsed;
45
+ }
46
+ else {
47
+ throw new Error('Parsed input is not an object');
48
+ }
49
+ }
50
+ catch (e) {
51
+ const errorMessage = e instanceof Error ? e.message : String(e);
52
+ throw new Error(`Failed to parse input as JSON: ${errorMessage}`);
53
+ }
54
+ }
55
+ const tools = request.page.pptrPage.webmcp.tools();
56
+ const tool = tools.find(t => t.name === toolName);
57
+ if (!tool) {
58
+ throw new Error(`Tool ${toolName} not found`);
59
+ }
60
+ const { status, output, errorText } = await tool.execute(input);
61
+ response.appendResponseLine(JSON.stringify({ status, output, errorText }, null, 2));
62
+ },
63
+ });
64
+ //# sourceMappingURL=webmcp.js.map
@@ -0,0 +1,85 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { logger } from '../logger.js';
7
+ import { DevTools } from '../third_party/index.js';
8
+ const engine = DevTools.TraceEngine.TraceModel.Model.createWithAllHandlers();
9
+ export function traceResultIsSuccess(x) {
10
+ return 'parsedTrace' in x;
11
+ }
12
+ export async function parseRawTraceBuffer(buffer) {
13
+ engine.resetProcessor();
14
+ if (!buffer) {
15
+ return {
16
+ error: 'No buffer was provided.',
17
+ };
18
+ }
19
+ const asString = new TextDecoder().decode(buffer);
20
+ if (!asString) {
21
+ return {
22
+ error: 'Decoding the trace buffer returned an empty string.',
23
+ };
24
+ }
25
+ try {
26
+ const data = JSON.parse(asString);
27
+ const events = Array.isArray(data) ? data : data.traceEvents;
28
+ await engine.parse(events);
29
+ const parsedTrace = engine.parsedTrace();
30
+ if (!parsedTrace) {
31
+ return {
32
+ error: 'No parsed trace was returned from the trace engine.',
33
+ };
34
+ }
35
+ const insights = parsedTrace?.insights ?? null;
36
+ return {
37
+ parsedTrace,
38
+ insights,
39
+ };
40
+ }
41
+ catch (e) {
42
+ const errorText = e instanceof Error ? e.message : JSON.stringify(e);
43
+ logger(`Unexpected error parsing trace: ${errorText}`);
44
+ return {
45
+ error: errorText,
46
+ };
47
+ }
48
+ }
49
+ const extraFormatDescriptions = `Information on performance traces may contain main thread activity represented as call frames and network requests.
50
+
51
+ ${DevTools.PerformanceTraceFormatter.callFrameDataFormatDescription}
52
+
53
+ ${DevTools.PerformanceTraceFormatter.networkDataFormatDescription}`;
54
+ export function getTraceSummary(result) {
55
+ const focus = DevTools.AgentFocus.fromParsedTrace(result.parsedTrace);
56
+ const formatter = new DevTools.PerformanceTraceFormatter(focus);
57
+ const summaryText = formatter.formatTraceSummary();
58
+ return `## Summary of Performance trace findings:
59
+ ${summaryText}
60
+
61
+ ## Details on call tree & network request formats:
62
+ ${extraFormatDescriptions}`;
63
+ }
64
+ export function getInsightOutput(result, insightSetId, insightName) {
65
+ if (!result.insights) {
66
+ return {
67
+ error: 'No Performance insights are available for this trace.',
68
+ };
69
+ }
70
+ const insightSet = result.insights.get(insightSetId);
71
+ if (!insightSet) {
72
+ return {
73
+ error: 'No Performance Insights for the given insight set id. Only use ids given in the "Available insight sets" list.',
74
+ };
75
+ }
76
+ const matchingInsight = insightName in insightSet.model ? insightSet.model[insightName] : null;
77
+ if (!matchingInsight) {
78
+ return {
79
+ error: `No Insight with the name ${insightName} found. Double check the name you provided is accurate and try again.`,
80
+ };
81
+ }
82
+ const formatter = new DevTools.PerformanceInsightFormatter(DevTools.AgentFocus.fromParsedTrace(result.parsedTrace), matchingInsight);
83
+ return { output: formatter.formatInsight() };
84
+ }
85
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,74 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import child_process from 'node:child_process';
7
+ import fs from 'node:fs/promises';
8
+ import os from 'node:os';
9
+ import path from 'node:path';
10
+ import process from 'node:process';
11
+ import { semver } from '../third_party/index.js';
12
+ import { VERSION } from '../version.js';
13
+ /**
14
+ * Notifies the user if an update is available.
15
+ * @param message The message to display in the update notification.
16
+ */
17
+ let isChecking = false;
18
+ /** @internal Reset flag for tests only. */
19
+ export function resetUpdateCheckFlagForTesting() {
20
+ isChecking = false;
21
+ }
22
+ export async function checkForUpdates(message) {
23
+ if (isChecking || process.env['CHROME_DEVTOOLS_MCP_NO_UPDATE_CHECKS']) {
24
+ return;
25
+ }
26
+ isChecking = true;
27
+ const cachePath = path.join(os.homedir(), '.cache', 'chrome-devtools-mcp', 'latest.json');
28
+ let cachedVersion;
29
+ let stats;
30
+ try {
31
+ stats = await fs.stat(cachePath);
32
+ const data = await fs.readFile(cachePath, 'utf8');
33
+ cachedVersion = JSON.parse(data).version;
34
+ }
35
+ catch {
36
+ // Ignore errors reading cache.
37
+ }
38
+ if (cachedVersion && semver.lt(VERSION, cachedVersion)) {
39
+ console.warn(`\nUpdate available: ${VERSION} -> ${cachedVersion}\n${message}\n`);
40
+ }
41
+ const now = Date.now();
42
+ if (stats && now - stats.mtimeMs < 24 * 60 * 60 * 1000) {
43
+ return;
44
+ }
45
+ // Update mtime immediately to prevent multiple subprocesses.
46
+ try {
47
+ const parentDir = path.dirname(cachePath);
48
+ await fs.mkdir(parentDir, { recursive: true });
49
+ const nowTime = new Date();
50
+ if (stats) {
51
+ await fs.utimes(cachePath, nowTime, nowTime);
52
+ }
53
+ else {
54
+ await fs.writeFile(cachePath, JSON.stringify({ version: VERSION }));
55
+ }
56
+ }
57
+ catch {
58
+ // Ignore errors.
59
+ }
60
+ // In a separate process, check the latest available version number
61
+ // and update the local snapshot accordingly.
62
+ const scriptPath = path.join(import.meta.dirname, '..', 'bin', 'check-latest-version.js');
63
+ try {
64
+ const child = child_process.spawn(process.execPath, [scriptPath, cachePath], {
65
+ detached: true,
66
+ stdio: 'ignore',
67
+ });
68
+ child.unref();
69
+ }
70
+ catch {
71
+ // Fail silently in case of any errors.
72
+ }
73
+ }
74
+ //# sourceMappingURL=check-for-updates.js.map
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import fs from 'node:fs/promises';
7
+ import os from 'node:os';
8
+ import path from 'node:path';
9
+ export async function getTempFilePath(filename) {
10
+ const dir = await fs.mkdtemp(path.join(os.tmpdir(), 'chrome-devtools-mcp-'));
11
+ const filepath = path.join(dir, filename);
12
+ return filepath;
13
+ }
14
+ export function ensureExtension(filepath, extension) {
15
+ const ext = path.extname(filepath);
16
+ return filepath.slice(0, filepath.length - ext.length) + extension;
17
+ }
18
+ //# sourceMappingURL=files.js.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ export function createIdGenerator() {
7
+ let i = 1;
8
+ return () => {
9
+ if (i === Number.MAX_SAFE_INTEGER) {
10
+ i = 0;
11
+ }
12
+ return i++;
13
+ };
14
+ }
15
+ export const stableIdSymbol = Symbol('stableIdSymbol');
16
+ //# sourceMappingURL=id.js.map
@@ -0,0 +1,297 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ // See the KeyInput type for the list of supported keys.
7
+ const validKeys = new Set([
8
+ '0',
9
+ '1',
10
+ '2',
11
+ '3',
12
+ '4',
13
+ '5',
14
+ '6',
15
+ '7',
16
+ '8',
17
+ '9',
18
+ 'Power',
19
+ 'Eject',
20
+ 'Abort',
21
+ 'Help',
22
+ 'Backspace',
23
+ 'Tab',
24
+ 'Numpad5',
25
+ 'NumpadEnter',
26
+ 'Enter',
27
+ '\r',
28
+ '\n',
29
+ 'ShiftLeft',
30
+ 'ShiftRight',
31
+ 'ControlLeft',
32
+ 'ControlRight',
33
+ 'AltLeft',
34
+ 'AltRight',
35
+ 'Pause',
36
+ 'CapsLock',
37
+ 'Escape',
38
+ 'Convert',
39
+ 'NonConvert',
40
+ 'Space',
41
+ 'Numpad9',
42
+ 'PageUp',
43
+ 'Numpad3',
44
+ 'PageDown',
45
+ 'End',
46
+ 'Numpad1',
47
+ 'Home',
48
+ 'Numpad7',
49
+ 'ArrowLeft',
50
+ 'Numpad4',
51
+ 'Numpad8',
52
+ 'ArrowUp',
53
+ 'ArrowRight',
54
+ 'Numpad6',
55
+ 'Numpad2',
56
+ 'ArrowDown',
57
+ 'Select',
58
+ 'Open',
59
+ 'PrintScreen',
60
+ 'Insert',
61
+ 'Numpad0',
62
+ 'Delete',
63
+ 'NumpadDecimal',
64
+ 'Digit0',
65
+ 'Digit1',
66
+ 'Digit2',
67
+ 'Digit3',
68
+ 'Digit4',
69
+ 'Digit5',
70
+ 'Digit6',
71
+ 'Digit7',
72
+ 'Digit8',
73
+ 'Digit9',
74
+ 'KeyA',
75
+ 'KeyB',
76
+ 'KeyC',
77
+ 'KeyD',
78
+ 'KeyE',
79
+ 'KeyF',
80
+ 'KeyG',
81
+ 'KeyH',
82
+ 'KeyI',
83
+ 'KeyJ',
84
+ 'KeyK',
85
+ 'KeyL',
86
+ 'KeyM',
87
+ 'KeyN',
88
+ 'KeyO',
89
+ 'KeyP',
90
+ 'KeyQ',
91
+ 'KeyR',
92
+ 'KeyS',
93
+ 'KeyT',
94
+ 'KeyU',
95
+ 'KeyV',
96
+ 'KeyW',
97
+ 'KeyX',
98
+ 'KeyY',
99
+ 'KeyZ',
100
+ 'MetaLeft',
101
+ 'MetaRight',
102
+ 'ContextMenu',
103
+ 'NumpadMultiply',
104
+ 'NumpadAdd',
105
+ 'NumpadSubtract',
106
+ 'NumpadDivide',
107
+ 'F1',
108
+ 'F2',
109
+ 'F3',
110
+ 'F4',
111
+ 'F5',
112
+ 'F6',
113
+ 'F7',
114
+ 'F8',
115
+ 'F9',
116
+ 'F10',
117
+ 'F11',
118
+ 'F12',
119
+ 'F13',
120
+ 'F14',
121
+ 'F15',
122
+ 'F16',
123
+ 'F17',
124
+ 'F18',
125
+ 'F19',
126
+ 'F20',
127
+ 'F21',
128
+ 'F22',
129
+ 'F23',
130
+ 'F24',
131
+ 'NumLock',
132
+ 'ScrollLock',
133
+ 'AudioVolumeMute',
134
+ 'AudioVolumeDown',
135
+ 'AudioVolumeUp',
136
+ 'MediaTrackNext',
137
+ 'MediaTrackPrevious',
138
+ 'MediaStop',
139
+ 'MediaPlayPause',
140
+ 'Semicolon',
141
+ 'Equal',
142
+ 'NumpadEqual',
143
+ 'Comma',
144
+ 'Minus',
145
+ 'Period',
146
+ 'Slash',
147
+ 'Backquote',
148
+ 'BracketLeft',
149
+ 'Backslash',
150
+ 'BracketRight',
151
+ 'Quote',
152
+ 'AltGraph',
153
+ 'Props',
154
+ 'Cancel',
155
+ 'Clear',
156
+ 'Shift',
157
+ 'Control',
158
+ 'Alt',
159
+ 'Accept',
160
+ 'ModeChange',
161
+ ' ',
162
+ 'Print',
163
+ 'Execute',
164
+ '\u0000',
165
+ 'a',
166
+ 'b',
167
+ 'c',
168
+ 'd',
169
+ 'e',
170
+ 'f',
171
+ 'g',
172
+ 'h',
173
+ 'i',
174
+ 'j',
175
+ 'k',
176
+ 'l',
177
+ 'm',
178
+ 'n',
179
+ 'o',
180
+ 'p',
181
+ 'q',
182
+ 'r',
183
+ 's',
184
+ 't',
185
+ 'u',
186
+ 'v',
187
+ 'w',
188
+ 'x',
189
+ 'y',
190
+ 'z',
191
+ 'Meta',
192
+ '*',
193
+ '+',
194
+ '-',
195
+ '/',
196
+ ';',
197
+ '=',
198
+ ',',
199
+ '.',
200
+ '`',
201
+ '[',
202
+ '\\',
203
+ ']',
204
+ "'",
205
+ 'Attn',
206
+ 'CrSel',
207
+ 'ExSel',
208
+ 'EraseEof',
209
+ 'Play',
210
+ 'ZoomOut',
211
+ ')',
212
+ '!',
213
+ '@',
214
+ '#',
215
+ '$',
216
+ '%',
217
+ '^',
218
+ '&',
219
+ '(',
220
+ 'A',
221
+ 'B',
222
+ 'C',
223
+ 'D',
224
+ 'E',
225
+ 'F',
226
+ 'G',
227
+ 'H',
228
+ 'I',
229
+ 'J',
230
+ 'K',
231
+ 'L',
232
+ 'M',
233
+ 'N',
234
+ 'O',
235
+ 'P',
236
+ 'Q',
237
+ 'R',
238
+ 'S',
239
+ 'T',
240
+ 'U',
241
+ 'V',
242
+ 'W',
243
+ 'X',
244
+ 'Y',
245
+ 'Z',
246
+ ':',
247
+ '<',
248
+ '_',
249
+ '>',
250
+ '?',
251
+ '~',
252
+ '{',
253
+ '|',
254
+ '}',
255
+ '"',
256
+ 'SoftLeft',
257
+ 'SoftRight',
258
+ 'Camera',
259
+ 'Call',
260
+ 'EndCall',
261
+ 'VolumeDown',
262
+ 'VolumeUp',
263
+ ]);
264
+ function throwIfInvalidKey(key) {
265
+ if (validKeys.has(key)) {
266
+ return key;
267
+ }
268
+ throw new Error(`${key} is invalid. Valid keys are: ${Array.from(validKeys.values()).join(',')}.`);
269
+ }
270
+ /**
271
+ * Returns the primary key, followed by modifiers in original order.
272
+ */
273
+ export function parseKey(keyInput) {
274
+ let key = '';
275
+ const result = [];
276
+ for (const ch of keyInput) {
277
+ // Handle cases like Shift++.
278
+ if (ch === '+' && key) {
279
+ result.push(throwIfInvalidKey(key));
280
+ key = '';
281
+ }
282
+ else {
283
+ key += ch;
284
+ }
285
+ }
286
+ if (key) {
287
+ result.push(throwIfInvalidKey(key));
288
+ }
289
+ if (result.length === 0) {
290
+ throw new Error(`Key ${keyInput} could not be parsed.`);
291
+ }
292
+ if (new Set(result).size !== result.length) {
293
+ throw new Error(`Key ${keyInput} contains duplicate keys.`);
294
+ }
295
+ return [result.at(-1), ...result.slice(0, -1)];
296
+ }
297
+ //# sourceMappingURL=keyboard.js.map