chrome-devtools-mcp 0.17.0 → 0.17.2

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 (258) hide show
  1. package/README.md +49 -10
  2. package/package.json +5 -4
  3. package/build/src/DevToolsConnectionAdapter.js +0 -69
  4. package/build/src/DevtoolsUtils.js +0 -340
  5. package/build/src/McpContext.js +0 -603
  6. package/build/src/McpResponse.js +0 -490
  7. package/build/src/Mutex.js +0 -37
  8. package/build/src/PageCollector.js +0 -309
  9. package/build/src/WaitForHelper.js +0 -139
  10. package/build/src/browser.js +0 -182
  11. package/build/src/cli.js +0 -295
  12. package/build/src/formatters/ConsoleFormatter.js +0 -240
  13. package/build/src/formatters/IssueFormatter.js +0 -190
  14. package/build/src/formatters/NetworkFormatter.js +0 -226
  15. package/build/src/formatters/SnapshotFormatter.js +0 -134
  16. package/build/src/index.js +0 -21
  17. package/build/src/issue-descriptions.js +0 -39
  18. package/build/src/logger.js +0 -36
  19. package/build/src/main.js +0 -196
  20. package/build/src/polyfill.js +0 -7
  21. package/build/src/telemetry/clearcut-logger.js +0 -102
  22. package/build/src/telemetry/flag-utils.js +0 -45
  23. package/build/src/telemetry/metric-utils.js +0 -14
  24. package/build/src/telemetry/persistence.js +0 -53
  25. package/build/src/telemetry/types.js +0 -33
  26. package/build/src/telemetry/watchdog/clearcut-sender.js +0 -201
  27. package/build/src/telemetry/watchdog/main.js +0 -127
  28. package/build/src/telemetry/watchdog-client.js +0 -60
  29. package/build/src/third_party/THIRD_PARTY_NOTICES +0 -2011
  30. package/build/src/third_party/bundled-packages.json +0 -8
  31. package/build/src/third_party/devtools-formatter-worker.js +0 -15449
  32. package/build/src/third_party/index.js +0 -172770
  33. package/build/src/third_party/issue-descriptions/CoepCoopSandboxedIframeCannotNavigateToCoopPage.md +0 -4
  34. package/build/src/third_party/issue-descriptions/CoepCorpNotSameOrigin.md +0 -8
  35. package/build/src/third_party/issue-descriptions/CoepCorpNotSameOriginAfterDefaultedToSameOriginByCoep.md +0 -18
  36. package/build/src/third_party/issue-descriptions/CoepCorpNotSameSite.md +0 -7
  37. package/build/src/third_party/issue-descriptions/CoepFrameResourceNeedsCoepHeader.md +0 -10
  38. package/build/src/third_party/issue-descriptions/CompatibilityModeQuirks.md +0 -5
  39. package/build/src/third_party/issue-descriptions/CookieAttributeValueExceedsMaxSize.md +0 -5
  40. package/build/src/third_party/issue-descriptions/LowTextContrast.md +0 -5
  41. package/build/src/third_party/issue-descriptions/SameSiteExcludeContextDowngradeRead.md +0 -8
  42. package/build/src/third_party/issue-descriptions/SameSiteExcludeContextDowngradeSet.md +0 -8
  43. package/build/src/third_party/issue-descriptions/SameSiteExcludeNavigationContextDowngrade.md +0 -8
  44. package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureErrorRead.md +0 -8
  45. package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureErrorSet.md +0 -8
  46. package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureWarnRead.md +0 -8
  47. package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureWarnSet.md +0 -8
  48. package/build/src/third_party/issue-descriptions/SameSiteUnspecifiedLaxAllowUnsafeRead.md +0 -9
  49. package/build/src/third_party/issue-descriptions/SameSiteUnspecifiedLaxAllowUnsafeSet.md +0 -9
  50. package/build/src/third_party/issue-descriptions/SameSiteWarnCrossDowngradeRead.md +0 -8
  51. package/build/src/third_party/issue-descriptions/SameSiteWarnCrossDowngradeSet.md +0 -8
  52. package/build/src/third_party/issue-descriptions/SameSiteWarnStrictLaxDowngradeStrict.md +0 -8
  53. package/build/src/third_party/issue-descriptions/arInsecureContext.md +0 -7
  54. package/build/src/third_party/issue-descriptions/arInvalidInfoHeader.md +0 -5
  55. package/build/src/third_party/issue-descriptions/arInvalidRegisterOsSourceHeader.md +0 -5
  56. package/build/src/third_party/issue-descriptions/arInvalidRegisterOsTriggerHeader.md +0 -5
  57. package/build/src/third_party/issue-descriptions/arInvalidRegisterSourceHeader.md +0 -5
  58. package/build/src/third_party/issue-descriptions/arInvalidRegisterTriggerHeader.md +0 -5
  59. package/build/src/third_party/issue-descriptions/arNavigationRegistrationUniqueScopeAlreadySet.md +0 -5
  60. package/build/src/third_party/issue-descriptions/arNavigationRegistrationWithoutTransientUserActivation.md +0 -6
  61. package/build/src/third_party/issue-descriptions/arNoRegisterOsSourceHeader.md +0 -5
  62. package/build/src/third_party/issue-descriptions/arNoRegisterOsTriggerHeader.md +0 -5
  63. package/build/src/third_party/issue-descriptions/arNoRegisterSourceHeader.md +0 -5
  64. package/build/src/third_party/issue-descriptions/arNoRegisterTriggerHeader.md +0 -5
  65. package/build/src/third_party/issue-descriptions/arNoWebOrOsSupport.md +0 -4
  66. package/build/src/third_party/issue-descriptions/arOsSourceIgnored.md +0 -18
  67. package/build/src/third_party/issue-descriptions/arOsTriggerIgnored.md +0 -19
  68. package/build/src/third_party/issue-descriptions/arPermissionPolicyDisabled.md +0 -8
  69. package/build/src/third_party/issue-descriptions/arSourceAndTriggerHeaders.md +0 -9
  70. package/build/src/third_party/issue-descriptions/arSourceIgnored.md +0 -13
  71. package/build/src/third_party/issue-descriptions/arTriggerIgnored.md +0 -12
  72. package/build/src/third_party/issue-descriptions/arUntrustworthyReportingOrigin.md +0 -10
  73. package/build/src/third_party/issue-descriptions/arWebAndOsHeaders.md +0 -11
  74. package/build/src/third_party/issue-descriptions/bounceTrackingMitigations.md +0 -3
  75. package/build/src/third_party/issue-descriptions/clientHintMetaTagAllowListInvalidOrigin.md +0 -4
  76. package/build/src/third_party/issue-descriptions/clientHintMetaTagModifiedHTML.md +0 -4
  77. package/build/src/third_party/issue-descriptions/cookieCrossSiteRedirectDowngrade.md +0 -12
  78. package/build/src/third_party/issue-descriptions/cookieExcludeBlockedWithinRelatedWebsiteSet.md +0 -4
  79. package/build/src/third_party/issue-descriptions/cookieExcludeDomainNonAscii.md +0 -11
  80. package/build/src/third_party/issue-descriptions/cookieExcludePortMismatch.md +0 -8
  81. package/build/src/third_party/issue-descriptions/cookieExcludeSchemeMismatch.md +0 -7
  82. package/build/src/third_party/issue-descriptions/cookieExcludeThirdPartyPhaseoutRead.md +0 -6
  83. package/build/src/third_party/issue-descriptions/cookieExcludeThirdPartyPhaseoutSet.md +0 -6
  84. package/build/src/third_party/issue-descriptions/cookieWarnDomainNonAscii.md +0 -11
  85. package/build/src/third_party/issue-descriptions/cookieWarnMetadataGrantRead.md +0 -4
  86. package/build/src/third_party/issue-descriptions/cookieWarnMetadataGrantSet.md +0 -4
  87. package/build/src/third_party/issue-descriptions/cookieWarnThirdPartyPhaseoutRead.md +0 -6
  88. package/build/src/third_party/issue-descriptions/cookieWarnThirdPartyPhaseoutSet.md +0 -6
  89. package/build/src/third_party/issue-descriptions/corsAllowCredentialsRequired.md +0 -6
  90. package/build/src/third_party/issue-descriptions/corsDisabledScheme.md +0 -7
  91. package/build/src/third_party/issue-descriptions/corsDisallowedByMode.md +0 -7
  92. package/build/src/third_party/issue-descriptions/corsHeaderDisallowedByPreflightResponse.md +0 -5
  93. package/build/src/third_party/issue-descriptions/corsInsecurePrivateNetwork.md +0 -10
  94. package/build/src/third_party/issue-descriptions/corsInvalidHeaderValues.md +0 -7
  95. package/build/src/third_party/issue-descriptions/corsLocalNetworkAccessPermissionDenied.md +0 -19
  96. package/build/src/third_party/issue-descriptions/corsMethodDisallowedByPreflightResponse.md +0 -5
  97. package/build/src/third_party/issue-descriptions/corsNoCorsRedirectModeNotFollow.md +0 -5
  98. package/build/src/third_party/issue-descriptions/corsOriginMismatch.md +0 -6
  99. package/build/src/third_party/issue-descriptions/corsPreflightAllowPrivateNetworkError.md +0 -10
  100. package/build/src/third_party/issue-descriptions/corsPreflightResponseInvalid.md +0 -5
  101. package/build/src/third_party/issue-descriptions/corsPrivateNetworkPermissionDenied.md +0 -10
  102. package/build/src/third_party/issue-descriptions/corsRedirectContainsCredentials.md +0 -5
  103. package/build/src/third_party/issue-descriptions/corsWildcardOriginNotAllowed.md +0 -8
  104. package/build/src/third_party/issue-descriptions/cspEvalViolation.md +0 -9
  105. package/build/src/third_party/issue-descriptions/cspInlineViolation.md +0 -10
  106. package/build/src/third_party/issue-descriptions/cspTrustedTypesPolicyViolation.md +0 -5
  107. package/build/src/third_party/issue-descriptions/cspTrustedTypesSinkViolation.md +0 -8
  108. package/build/src/third_party/issue-descriptions/cspURLViolation.md +0 -10
  109. package/build/src/third_party/issue-descriptions/deprecation.md +0 -3
  110. package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsHttpNotFound.md +0 -1
  111. package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsInvalidResponse.md +0 -1
  112. package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsNoResponse.md +0 -1
  113. package/build/src/third_party/issue-descriptions/federatedAuthRequestApprovalDeclined.md +0 -1
  114. package/build/src/third_party/issue-descriptions/federatedAuthRequestCanceled.md +0 -1
  115. package/build/src/third_party/issue-descriptions/federatedAuthRequestClientMetadataHttpNotFound.md +0 -1
  116. package/build/src/third_party/issue-descriptions/federatedAuthRequestClientMetadataInvalidResponse.md +0 -1
  117. package/build/src/third_party/issue-descriptions/federatedAuthRequestClientMetadataNoResponse.md +0 -1
  118. package/build/src/third_party/issue-descriptions/federatedAuthRequestErrorFetchingSignin.md +0 -1
  119. package/build/src/third_party/issue-descriptions/federatedAuthRequestErrorIdToken.md +0 -1
  120. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenHttpNotFound.md +0 -1
  121. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenInvalidRequest.md +0 -1
  122. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenInvalidResponse.md +0 -1
  123. package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenNoResponse.md +0 -1
  124. package/build/src/third_party/issue-descriptions/federatedAuthRequestInvalidSigninResponse.md +0 -1
  125. package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestHttpNotFound.md +0 -1
  126. package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestInvalidResponse.md +0 -1
  127. package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestNoResponse.md +0 -1
  128. package/build/src/third_party/issue-descriptions/federatedAuthRequestTooManyRequests.md +0 -1
  129. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestInvalidAccountsResponse.md +0 -1
  130. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestInvalidConfigOrWellKnown.md +0 -1
  131. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoAccountSharingPermission.md +0 -1
  132. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoApiPermission.md +0 -1
  133. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoReturningUserFromFetchedAccounts.md +0 -1
  134. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotIframe.md +0 -1
  135. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotPotentiallyTrustworthy.md +0 -1
  136. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotSameOrigin.md +0 -1
  137. package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotSignedInWithIdp.md +0 -1
  138. package/build/src/third_party/issue-descriptions/fetchingPartitionedBlobURL.md +0 -7
  139. package/build/src/third_party/issue-descriptions/genericFormAriaLabelledByToNonExistingIdError.md +0 -8
  140. package/build/src/third_party/issue-descriptions/genericFormAutocompleteAttributeEmptyError.md +0 -5
  141. package/build/src/third_party/issue-descriptions/genericFormDuplicateIdForInputError.md +0 -5
  142. package/build/src/third_party/issue-descriptions/genericFormEmptyIdAndNameAttributesForInputError.md +0 -5
  143. package/build/src/third_party/issue-descriptions/genericFormInputAssignedAutocompleteValueToIdOrNameAttributeError.md +0 -5
  144. package/build/src/third_party/issue-descriptions/genericFormInputHasWrongButWellIntendedAutocompleteValueError.md +0 -5
  145. package/build/src/third_party/issue-descriptions/genericFormInputWithNoLabelError.md +0 -5
  146. package/build/src/third_party/issue-descriptions/genericFormLabelForMatchesNonExistingIdError.md +0 -5
  147. package/build/src/third_party/issue-descriptions/genericFormLabelForNameError.md +0 -5
  148. package/build/src/third_party/issue-descriptions/genericFormLabelHasNeitherForNorNestedInputError.md +0 -5
  149. package/build/src/third_party/issue-descriptions/genericNavigationEntryMarkedSkippable.md +0 -7
  150. package/build/src/third_party/issue-descriptions/genericResponseWasBlockedByORB.md +0 -4
  151. package/build/src/third_party/issue-descriptions/heavyAd.md +0 -10
  152. package/build/src/third_party/issue-descriptions/mixedContent.md +0 -5
  153. package/build/src/third_party/issue-descriptions/navigatingPartitionedBlobURL.md +0 -5
  154. package/build/src/third_party/issue-descriptions/permissionElementActivationDisabled.md +0 -7
  155. package/build/src/third_party/issue-descriptions/permissionElementActivationDisabledWithOccluder.md +0 -9
  156. package/build/src/third_party/issue-descriptions/permissionElementActivationDisabledWithOccluderParent.md +0 -9
  157. package/build/src/third_party/issue-descriptions/permissionElementCspFrameAncestorsMissing.md +0 -5
  158. package/build/src/third_party/issue-descriptions/permissionElementFencedFrameDisallowed.md +0 -5
  159. package/build/src/third_party/issue-descriptions/permissionElementFontSizeTooLarge.md +0 -5
  160. package/build/src/third_party/issue-descriptions/permissionElementFontSizeTooSmall.md +0 -5
  161. package/build/src/third_party/issue-descriptions/permissionElementGeolocationDeprecated.md +0 -5
  162. package/build/src/third_party/issue-descriptions/permissionElementInsetBoxShadowUnsupported.md +0 -5
  163. package/build/src/third_party/issue-descriptions/permissionElementInvalidDisplayStyle.md +0 -5
  164. package/build/src/third_party/issue-descriptions/permissionElementInvalidSizeValue.md +0 -5
  165. package/build/src/third_party/issue-descriptions/permissionElementInvalidType.md +0 -5
  166. package/build/src/third_party/issue-descriptions/permissionElementInvalidTypeActivation.md +0 -5
  167. package/build/src/third_party/issue-descriptions/permissionElementLowContrast.md +0 -5
  168. package/build/src/third_party/issue-descriptions/permissionElementNonOpaqueColor.md +0 -5
  169. package/build/src/third_party/issue-descriptions/permissionElementPaddingBottomUnsupported.md +0 -6
  170. package/build/src/third_party/issue-descriptions/permissionElementPaddingRightUnsupported.md +0 -6
  171. package/build/src/third_party/issue-descriptions/permissionElementPermissionsPolicyBlocked.md +0 -5
  172. package/build/src/third_party/issue-descriptions/permissionElementRegistrationFailed.md +0 -5
  173. package/build/src/third_party/issue-descriptions/permissionElementRequestInProgress.md +0 -5
  174. package/build/src/third_party/issue-descriptions/permissionElementSecurityChecksFailed.md +0 -5
  175. package/build/src/third_party/issue-descriptions/permissionElementTypeNotSupported.md +0 -5
  176. package/build/src/third_party/issue-descriptions/permissionElementUntrustedEvent.md +0 -7
  177. package/build/src/third_party/issue-descriptions/placeholderDescriptionForInvisibleIssues.md +0 -3
  178. package/build/src/third_party/issue-descriptions/propertyRuleInvalidNameIssue.md +0 -3
  179. package/build/src/third_party/issue-descriptions/propertyRuleIssue.md +0 -7
  180. package/build/src/third_party/issue-descriptions/selectElementAccessibilityDisallowedOptGroupChild.md +0 -7
  181. package/build/src/third_party/issue-descriptions/selectElementAccessibilityDisallowedSelectChild.md +0 -7
  182. package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentAttributesSelectDescendant.md +0 -3
  183. package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentLegendChild.md +0 -3
  184. package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentOptionChild.md +0 -3
  185. package/build/src/third_party/issue-descriptions/selectElementAccessibilityNonPhrasingContentOptionChild.md +0 -3
  186. package/build/src/third_party/issue-descriptions/sharedArrayBuffer.md +0 -7
  187. package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorCrossOriginNoCorsRequest.md +0 -1
  188. package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorDictionaryLoadFailure.md +0 -3
  189. package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorMatchingDictionaryNotUsed.md +0 -3
  190. package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorUnexpectedContentDictionaryHeader.md +0 -1
  191. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorCossOriginNoCorsRequest.md +0 -1
  192. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorDisallowedBySettings.md +0 -1
  193. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorExpiredResponse.md +0 -3
  194. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorFeatureDisabled.md +0 -3
  195. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInsufficientResources.md +0 -1
  196. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInvalidMatchField.md +0 -1
  197. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInvalidStructuredHeader.md +0 -1
  198. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInvalidTTLField.md +0 -1
  199. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNavigationRequest.md +0 -3
  200. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNoMatchField.md +0 -1
  201. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonIntegerTTLField.md +0 -1
  202. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonListMatchDestField.md +0 -1
  203. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonSecureContext.md +0 -3
  204. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonStringIdField.md +0 -1
  205. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonStringInMatchDestList.md +0 -1
  206. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonStringMatchField.md +0 -1
  207. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNonTokenTypeField.md +0 -1
  208. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorRequestAborted.md +0 -1
  209. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorShuttingDown.md +0 -1
  210. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorTooLongIdField.md +0 -3
  211. package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorUnsupportedType.md +0 -3
  212. package/build/src/third_party/issue-descriptions/sriInvalidSignatureHeader.md +0 -14
  213. package/build/src/third_party/issue-descriptions/sriInvalidSignatureInputHeader.md +0 -15
  214. package/build/src/third_party/issue-descriptions/sriMissingSignatureHeader.md +0 -8
  215. package/build/src/third_party/issue-descriptions/sriMissingSignatureInputHeader.md +0 -7
  216. package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsIncorrectLength.md +0 -11
  217. package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsNotByteSequence.md +0 -14
  218. package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsParameterized.md +0 -15
  219. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidComponentName.md +0 -8
  220. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidComponentType.md +0 -13
  221. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidDerivedComponentParameter.md +0 -4
  222. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidHeaderComponentParameter.md +0 -5
  223. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidParameter.md +0 -11
  224. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderKeyIdLength.md +0 -12
  225. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderMissingLabel.md +0 -6
  226. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderMissingRequiredParameters.md +0 -8
  227. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderValueMissingComponents.md +0 -11
  228. package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderValueNotInnerList.md +0 -11
  229. package/build/src/third_party/issue-descriptions/sriValidationFailedIntegrityMismatch.md +0 -10
  230. package/build/src/third_party/issue-descriptions/sriValidationFailedInvalidLength.md +0 -5
  231. package/build/src/third_party/issue-descriptions/sriValidationFailedSignatureExpired.md +0 -6
  232. package/build/src/third_party/issue-descriptions/sriValidationFailedSignatureMismatch.md +0 -11
  233. package/build/src/third_party/issue-descriptions/stylesheetLateImport.md +0 -4
  234. package/build/src/third_party/issue-descriptions/stylesheetRequestFailed.md +0 -3
  235. package/build/src/third_party/issue-descriptions/summaryElementAccessibilityInteractiveContentSummaryDescendant.md +0 -3
  236. package/build/src/third_party/issue-descriptions/unencodedDigestIncorrectDigestLength.md +0 -12
  237. package/build/src/third_party/issue-descriptions/unencodedDigestIncorrectDigestType.md +0 -17
  238. package/build/src/third_party/issue-descriptions/unencodedDigestMalformedDictionary.md +0 -14
  239. package/build/src/third_party/issue-descriptions/unencodedDigestUnknownAlgorithm.md +0 -15
  240. package/build/src/tools/ToolDefinition.js +0 -20
  241. package/build/src/tools/categories.js +0 -24
  242. package/build/src/tools/console.js +0 -85
  243. package/build/src/tools/emulation.js +0 -169
  244. package/build/src/tools/extensions.js +0 -79
  245. package/build/src/tools/input.js +0 -343
  246. package/build/src/tools/network.js +0 -120
  247. package/build/src/tools/pages.js +0 -323
  248. package/build/src/tools/performance.js +0 -188
  249. package/build/src/tools/screenshot.js +0 -84
  250. package/build/src/tools/script.js +0 -71
  251. package/build/src/tools/snapshot.js +0 -52
  252. package/build/src/tools/tools.js +0 -31
  253. package/build/src/trace-processing/parse.js +0 -84
  254. package/build/src/utils/ExtensionRegistry.js +0 -35
  255. package/build/src/utils/keyboard.js +0 -296
  256. package/build/src/utils/pagination.js +0 -49
  257. package/build/src/utils/string.js +0 -36
  258. package/build/src/utils/types.js +0 -6
@@ -1,190 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2026 Google LLC
4
- * SPDX-License-Identifier: Apache-2.0
5
- */
6
- import { ISSUE_UTILS } from '../issue-descriptions.js';
7
- import { logger } from '../logger.js';
8
- import { DevTools } from '../third_party/index.js';
9
- export class IssueFormatter {
10
- #issue;
11
- #options;
12
- constructor(issue, options) {
13
- this.#issue = issue;
14
- this.#options = options;
15
- }
16
- toString() {
17
- const title = this.#getTitle();
18
- const count = this.#issue.getAggregatedIssuesCount();
19
- const idPart = this.#options.id !== undefined ? `msgid=${this.#options.id} ` : '';
20
- return `${idPart}[issue] ${title} (count: ${count})`;
21
- }
22
- toStringDetailed() {
23
- const result = [];
24
- if (this.#options.id !== undefined) {
25
- result.push(`ID: ${this.#options.id}`);
26
- }
27
- const bodyParts = [];
28
- const description = this.#getDescription();
29
- let processedMarkdown = description?.trim();
30
- // Remove heading in order not to conflict with the whole console message response markdown
31
- if (processedMarkdown?.startsWith('# ')) {
32
- processedMarkdown = processedMarkdown.substring(2).trimStart();
33
- }
34
- if (processedMarkdown) {
35
- bodyParts.push(processedMarkdown);
36
- }
37
- else {
38
- bodyParts.push(this.#getTitle() ?? 'Unknown Issue');
39
- }
40
- const links = this.#issue.getDescription()?.links;
41
- if (links && links.length > 0) {
42
- bodyParts.push('Learn more:');
43
- for (const link of links) {
44
- bodyParts.push(`[${link.linkTitle}](${link.link})`);
45
- }
46
- }
47
- const affectedResources = this.#getAffectedResources();
48
- if (affectedResources.length) {
49
- bodyParts.push('### Affected resources');
50
- bodyParts.push(...affectedResources.map(item => {
51
- const details = [];
52
- if (item.uid) {
53
- details.push(`uid=${item.uid}`);
54
- }
55
- if (item.request) {
56
- details.push((typeof item.request === 'number' ? `reqid=` : 'url=') +
57
- item.request);
58
- }
59
- if (item.data) {
60
- details.push(`data=${JSON.stringify(item.data)}`);
61
- }
62
- return details.join(' ');
63
- }));
64
- }
65
- result.push(`Message: issue> ${bodyParts.join('\n')}`);
66
- return result.join('\n');
67
- }
68
- toJSON() {
69
- return {
70
- type: 'issue',
71
- title: this.#getTitle(),
72
- count: this.#issue.getAggregatedIssuesCount(),
73
- id: this.#options.id,
74
- };
75
- }
76
- toJSONDetailed() {
77
- return {
78
- id: this.#options.id,
79
- type: 'issue',
80
- title: this.#getTitle(),
81
- description: this.#getDescription(),
82
- links: this.#issue.getDescription()?.links,
83
- affectedResources: this.#getAffectedResources(),
84
- };
85
- }
86
- #getAffectedResources() {
87
- const issues = this.#issue.getAllIssues();
88
- const affectedResources = [];
89
- for (const singleIssue of issues) {
90
- const details = singleIssue.details();
91
- if (!details) {
92
- continue;
93
- }
94
- // We send the remaining details as untyped JSON because the DevTools
95
- // frontend code is currently not re-usable.
96
- const data = structuredClone(details);
97
- let uid;
98
- let request;
99
- if ('violatingNodeId' in details &&
100
- details.violatingNodeId &&
101
- this.#options.elementIdResolver) {
102
- uid = this.#options.elementIdResolver(details.violatingNodeId);
103
- delete data.violatingNodeId;
104
- }
105
- if ('nodeId' in details &&
106
- details.nodeId &&
107
- this.#options.elementIdResolver) {
108
- uid = this.#options.elementIdResolver(details.nodeId);
109
- delete data.nodeId;
110
- }
111
- if ('documentNodeId' in details &&
112
- details.documentNodeId &&
113
- this.#options.elementIdResolver) {
114
- uid = this.#options.elementIdResolver(details.documentNodeId);
115
- delete data.documentNodeId;
116
- }
117
- if ('request' in details && details.request) {
118
- request = details.request.url;
119
- if (details.request.requestId && this.#options.requestIdResolver) {
120
- const resolvedId = this.#options.requestIdResolver(details.request.requestId);
121
- if (resolvedId) {
122
- request = resolvedId;
123
- const requestData = data.request;
124
- delete requestData.requestId;
125
- }
126
- }
127
- }
128
- // These fields has no use for the MCP client (redundant or irrelevant).
129
- delete data.errorType;
130
- delete data.frameId;
131
- affectedResources.push({
132
- uid,
133
- data: data,
134
- request,
135
- });
136
- }
137
- return affectedResources;
138
- }
139
- isValid() {
140
- return this.#getTitle() !== undefined;
141
- }
142
- // Helper to extract title
143
- #getTitle() {
144
- const markdownDescription = this.#issue.getDescription();
145
- const filename = markdownDescription?.file;
146
- if (!filename) {
147
- logger(`no description found for issue:` + this.#issue.code());
148
- return undefined;
149
- }
150
- // We already have the description logic in #getDescription, but title extraction is separate
151
- // We can reuse the logic or cache it.
152
- // Ideally we should process markdown once.
153
- const rawMarkdown = ISSUE_UTILS.getIssueDescription(filename);
154
- if (!rawMarkdown) {
155
- logger(`no markdown ${filename} found for issue:` + this.#issue.code());
156
- return undefined;
157
- }
158
- try {
159
- const processedMarkdown = DevTools.MarkdownIssueDescription.substitutePlaceholders(rawMarkdown, markdownDescription?.substitutions);
160
- const markdownAst = DevTools.Marked.Marked.lexer(processedMarkdown);
161
- const title = DevTools.MarkdownIssueDescription.findTitleFromMarkdownAst(markdownAst);
162
- if (!title) {
163
- logger('cannot read issue title from ' + filename);
164
- return undefined;
165
- }
166
- return title;
167
- }
168
- catch {
169
- logger('error parsing markdown for issue ' + this.#issue.code());
170
- return undefined;
171
- }
172
- }
173
- #getDescription() {
174
- const markdownDescription = this.#issue.getDescription();
175
- const filename = markdownDescription?.file;
176
- if (!filename) {
177
- return undefined;
178
- }
179
- const rawMarkdown = ISSUE_UTILS.getIssueDescription(filename);
180
- if (!rawMarkdown) {
181
- return undefined;
182
- }
183
- try {
184
- return DevTools.MarkdownIssueDescription.substitutePlaceholders(rawMarkdown, markdownDescription?.substitutions);
185
- }
186
- catch {
187
- return undefined;
188
- }
189
- }
190
- }
@@ -1,226 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2025 Google LLC
4
- * SPDX-License-Identifier: Apache-2.0
5
- * */
6
- import { isUtf8 } from 'node:buffer';
7
- const BODY_CONTEXT_SIZE_LIMIT = 10000;
8
- export class NetworkFormatter {
9
- #request;
10
- #options;
11
- #requestBody;
12
- #responseBody;
13
- #requestBodyFilePath;
14
- #responseBodyFilePath;
15
- constructor(request, options) {
16
- this.#request = request;
17
- this.#options = options;
18
- }
19
- static async from(request, options) {
20
- const instance = new NetworkFormatter(request, options);
21
- if (options.fetchData) {
22
- await instance.#loadDetailedData();
23
- }
24
- return instance;
25
- }
26
- async #loadDetailedData() {
27
- // Load Request Body
28
- if (this.#request.hasPostData()) {
29
- let data;
30
- try {
31
- data =
32
- this.#request.postData() ?? (await this.#request.fetchPostData());
33
- }
34
- catch {
35
- // Ignore parsing errors
36
- }
37
- const requestBodyNotAvailableMessage = '<Request body not available anymore>';
38
- if (this.#options.requestFilePath) {
39
- if (!this.#options.saveFile) {
40
- throw new Error('saveFile is not provided');
41
- }
42
- if (data) {
43
- await this.#options.saveFile(Buffer.from(data), this.#options.requestFilePath);
44
- this.#requestBodyFilePath = this.#options.requestFilePath;
45
- }
46
- else {
47
- this.#requestBody = requestBodyNotAvailableMessage;
48
- }
49
- }
50
- else {
51
- if (data) {
52
- this.#requestBody = getSizeLimitedString(data, BODY_CONTEXT_SIZE_LIMIT);
53
- }
54
- else {
55
- this.#requestBody = requestBodyNotAvailableMessage;
56
- }
57
- }
58
- }
59
- // Load Response Body
60
- const response = this.#request.response();
61
- if (response) {
62
- const responseBodyNotAvailableMessage = '<Response body not available anymore>';
63
- if (this.#options.responseFilePath) {
64
- try {
65
- const buffer = await response.buffer();
66
- if (!this.#options.saveFile) {
67
- throw new Error('saveFile is not provided');
68
- }
69
- await this.#options.saveFile(buffer, this.#options.responseFilePath);
70
- this.#responseBodyFilePath = this.#options.responseFilePath;
71
- }
72
- catch {
73
- // Flatten error handling for buffer() failure and save failure
74
- }
75
- if (!this.#responseBodyFilePath) {
76
- this.#responseBody = responseBodyNotAvailableMessage;
77
- }
78
- }
79
- else {
80
- this.#responseBody = await this.#getFormattedResponseBody(response, BODY_CONTEXT_SIZE_LIMIT);
81
- }
82
- }
83
- }
84
- toString() {
85
- // TODO truncate the URL
86
- return `reqid=${this.#options.requestId} ${this.#request.method()} ${this.#request.url()} ${this.#getStatusFromRequest(this.#request)}${this.#options.selectedInDevToolsUI ? ` [selected in the DevTools Network panel]` : ''}`;
87
- }
88
- toStringDetailed() {
89
- const response = [];
90
- response.push(`## Request ${this.#request.url()}`);
91
- response.push(`Status: ${this.#getStatusFromRequest(this.#request)}`);
92
- response.push(`### Request Headers`);
93
- for (const line of this.#getFormattedHeaderValue(this.#request.headers())) {
94
- response.push(line);
95
- }
96
- if (this.#requestBody) {
97
- response.push(`### Request Body`);
98
- response.push(this.#requestBody);
99
- }
100
- else if (this.#requestBodyFilePath) {
101
- response.push(`### Request Body`);
102
- response.push(`Saved to ${this.#requestBodyFilePath}.`);
103
- }
104
- const httpResponse = this.#request.response();
105
- if (httpResponse) {
106
- response.push(`### Response Headers`);
107
- for (const line of this.#getFormattedHeaderValue(httpResponse.headers())) {
108
- response.push(line);
109
- }
110
- }
111
- if (this.#responseBody) {
112
- response.push(`### Response Body`);
113
- response.push(this.#responseBody);
114
- }
115
- else if (this.#responseBodyFilePath) {
116
- response.push(`### Response Body`);
117
- response.push(`Saved to ${this.#responseBodyFilePath}.`);
118
- }
119
- const httpFailure = this.#request.failure();
120
- if (httpFailure) {
121
- response.push(`### Request failed with`);
122
- response.push(httpFailure.errorText);
123
- }
124
- const redirectChain = this.#request.redirectChain();
125
- if (redirectChain.length) {
126
- response.push(`### Redirect chain`);
127
- let indent = 0;
128
- for (const request of redirectChain.reverse()) {
129
- const id = this.#options.requestIdResolver
130
- ? this.#options.requestIdResolver(request)
131
- : undefined;
132
- // We create a temporary synchronous instance just for toString
133
- const formatter = new NetworkFormatter(request, {
134
- requestId: id,
135
- saveFile: this.#options.saveFile,
136
- });
137
- response.push(`${' '.repeat(indent)}${formatter.toString()}`);
138
- indent++;
139
- }
140
- }
141
- return response.join('\n');
142
- }
143
- toJSON() {
144
- return {
145
- requestId: this.#options.requestId,
146
- method: this.#request.method(),
147
- url: this.#request.url(),
148
- status: this.#getStatusFromRequest(this.#request),
149
- selectedInDevToolsUI: this.#options.selectedInDevToolsUI,
150
- };
151
- }
152
- toJSONDetailed() {
153
- const redirectChain = this.#request.redirectChain();
154
- const formattedRedirectChain = redirectChain.reverse().map(request => {
155
- const id = this.#options.requestIdResolver
156
- ? this.#options.requestIdResolver(request)
157
- : undefined;
158
- const formatter = new NetworkFormatter(request, {
159
- requestId: id,
160
- saveFile: this.#options.saveFile,
161
- });
162
- return formatter.toJSON();
163
- });
164
- return {
165
- ...this.toJSON(),
166
- requestHeaders: this.#request.headers(),
167
- requestBody: this.#requestBody,
168
- requestBodyFilePath: this.#requestBodyFilePath,
169
- responseHeaders: this.#request.response()?.headers(),
170
- responseBody: this.#responseBody,
171
- responseBodyFilePath: this.#responseBodyFilePath,
172
- failure: this.#request.failure()?.errorText,
173
- redirectChain: formattedRedirectChain.length
174
- ? formattedRedirectChain
175
- : undefined,
176
- };
177
- }
178
- #getStatusFromRequest(request) {
179
- const httpResponse = request.response();
180
- const failure = request.failure();
181
- let status;
182
- if (httpResponse) {
183
- const responseStatus = httpResponse.status();
184
- status =
185
- responseStatus >= 200 && responseStatus <= 299
186
- ? `[success - ${responseStatus}]`
187
- : `[failed - ${responseStatus}]`;
188
- }
189
- else if (failure) {
190
- status = `[failed - ${failure.errorText}]`;
191
- }
192
- else {
193
- status = '[pending]';
194
- }
195
- return status;
196
- }
197
- #getFormattedHeaderValue(headers) {
198
- const response = [];
199
- for (const [name, value] of Object.entries(headers)) {
200
- response.push(`- ${name}:${value}`);
201
- }
202
- return response;
203
- }
204
- async #getFormattedResponseBody(httpResponse, sizeLimit = BODY_CONTEXT_SIZE_LIMIT) {
205
- try {
206
- const responseBuffer = await httpResponse.buffer();
207
- if (isUtf8(responseBuffer)) {
208
- const responseAsTest = responseBuffer.toString('utf-8');
209
- if (responseAsTest.length === 0) {
210
- return '<empty response>';
211
- }
212
- return getSizeLimitedString(responseAsTest, sizeLimit);
213
- }
214
- return '<binary data>';
215
- }
216
- catch {
217
- return '<not available anymore>';
218
- }
219
- }
220
- }
221
- function getSizeLimitedString(text, sizeLimit) {
222
- if (text.length > sizeLimit) {
223
- return text.substring(0, sizeLimit) + '... <truncated>';
224
- }
225
- return text;
226
- }
@@ -1,134 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2025 Google LLC
4
- * SPDX-License-Identifier: Apache-2.0
5
- */
6
- export class SnapshotFormatter {
7
- #snapshot;
8
- constructor(snapshot) {
9
- this.#snapshot = snapshot;
10
- }
11
- toString() {
12
- const chunks = [];
13
- const root = this.#snapshot.root;
14
- // Top-level content of the snapshot.
15
- if (this.#snapshot.verbose &&
16
- this.#snapshot.hasSelectedElement &&
17
- !this.#snapshot.selectedElementUid) {
18
- chunks.push(`Note: there is a selected element in the DevTools Elements panel but it is not included into the current a11y tree snapshot.
19
- Get a verbose snapshot to include all elements if you are interested in the selected element.\n\n`);
20
- }
21
- chunks.push(this.#formatNode(root, 0));
22
- return chunks.join('');
23
- }
24
- toJSON() {
25
- return this.#nodeToJSON(this.#snapshot.root);
26
- }
27
- #formatNode(node, depth = 0) {
28
- const chunks = [];
29
- const attributes = this.#getAttributes(node);
30
- const line = ' '.repeat(depth * 2) +
31
- attributes.join(' ') +
32
- (node.id === this.#snapshot.selectedElementUid
33
- ? ' [selected in the DevTools Elements panel]'
34
- : '') +
35
- '\n';
36
- chunks.push(line);
37
- for (const child of node.children) {
38
- chunks.push(this.#formatNode(child, depth + 1));
39
- }
40
- return chunks.join('');
41
- }
42
- #nodeToJSON(node) {
43
- const rawAttrs = this.#getAttributesMap(node);
44
- const children = node.children.map(child => this.#nodeToJSON(child));
45
- const result = structuredClone(rawAttrs);
46
- if (children.length > 0) {
47
- result.children = children;
48
- }
49
- return result;
50
- }
51
- #getAttributes(serializedAXNodeRoot) {
52
- const attributes = [`uid=${serializedAXNodeRoot.id}`];
53
- if (serializedAXNodeRoot.role) {
54
- attributes.push(serializedAXNodeRoot.role === 'none'
55
- ? 'ignored'
56
- : serializedAXNodeRoot.role);
57
- }
58
- if (serializedAXNodeRoot.name) {
59
- attributes.push(`"${serializedAXNodeRoot.name}"`);
60
- }
61
- const simpleAttrs = this.#getAttributesMap(serializedAXNodeRoot,
62
- /* excludeSpecial */ true);
63
- for (const attr of Object.keys(serializedAXNodeRoot).sort()) {
64
- if (excludedAttributes.has(attr)) {
65
- continue;
66
- }
67
- const mapped = booleanPropertyMap[attr];
68
- if (mapped && simpleAttrs[mapped]) {
69
- attributes.push(mapped);
70
- }
71
- const val = simpleAttrs[attr];
72
- if (val === true) {
73
- attributes.push(attr);
74
- }
75
- else if (typeof val === 'string' || typeof val === 'number') {
76
- attributes.push(`${attr}="${val}"`);
77
- }
78
- }
79
- return attributes;
80
- }
81
- #getAttributesMap(node, excludeSpecial = false) {
82
- const result = {};
83
- if (!excludeSpecial) {
84
- result.id = node.id;
85
- if (node.role) {
86
- result.role = node.role;
87
- }
88
- if (node.name) {
89
- result.name = node.name;
90
- }
91
- }
92
- // Re-implementing the exact logic from original function for #getAttributes to be safe:
93
- return {
94
- ...result,
95
- ...this.#extractedAttributes(node),
96
- };
97
- }
98
- #extractedAttributes(node) {
99
- const result = {};
100
- for (const attr of Object.keys(node).sort()) {
101
- if (excludedAttributes.has(attr)) {
102
- continue;
103
- }
104
- const value = node[attr];
105
- if (typeof value === 'boolean') {
106
- if (booleanPropertyMap[attr]) {
107
- result[booleanPropertyMap[attr]] = true;
108
- }
109
- if (value) {
110
- result[attr] = true;
111
- }
112
- }
113
- else if (typeof value === 'string' || typeof value === 'number') {
114
- result[attr] = value;
115
- }
116
- }
117
- return result;
118
- }
119
- }
120
- const booleanPropertyMap = {
121
- disabled: 'disableable',
122
- expanded: 'expandable',
123
- focused: 'focusable',
124
- selected: 'selectable',
125
- };
126
- const excludedAttributes = new Set([
127
- 'id',
128
- 'role',
129
- 'name',
130
- 'elementHandle',
131
- 'children',
132
- 'backendNodeId',
133
- 'loaderId',
134
- ]);
@@ -1,21 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * @license
4
- * Copyright 2025 Google LLC
5
- * SPDX-License-Identifier: Apache-2.0
6
- */
7
- import { version } from 'node:process';
8
- const [major, minor] = version.substring(1).split('.').map(Number);
9
- if (major === 20 && minor < 19) {
10
- console.error(`ERROR: \`chrome-devtools-mcp\` does not support Node ${process.version}. Please upgrade to Node 20.19.0 LTS or a newer LTS.`);
11
- process.exit(1);
12
- }
13
- if (major === 22 && minor < 12) {
14
- console.error(`ERROR: \`chrome-devtools-mcp\` does not support Node ${process.version}. Please upgrade to Node 22.12.0 LTS or a newer LTS.`);
15
- process.exit(1);
16
- }
17
- if (major < 20) {
18
- console.error(`ERROR: \`chrome-devtools-mcp\` does not support Node ${process.version}. Please upgrade to Node 20.19.0 LTS or a newer LTS.`);
19
- process.exit(1);
20
- }
21
- await import('./main.js');
@@ -1,39 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2025 Google LLC
4
- * SPDX-License-Identifier: Apache-2.0
5
- */
6
- import * as fs from 'node:fs';
7
- import * as path from 'node:path';
8
- const DESCRIPTIONS_PATH = path.join(import.meta.dirname, 'third_party/issue-descriptions');
9
- let issueDescriptions = {};
10
- /**
11
- * Reads all issue descriptions from the filesystem into memory.
12
- */
13
- export async function loadIssueDescriptions() {
14
- if (Object.keys(issueDescriptions).length > 0) {
15
- return;
16
- }
17
- const files = await fs.promises.readdir(DESCRIPTIONS_PATH);
18
- const descriptions = {};
19
- for (const file of files) {
20
- if (!file.endsWith('.md')) {
21
- continue;
22
- }
23
- const content = await fs.promises.readFile(path.join(DESCRIPTIONS_PATH, file), 'utf-8');
24
- descriptions[file] = content;
25
- }
26
- issueDescriptions = descriptions;
27
- }
28
- /**
29
- * Gets an issue description from the in-memory cache.
30
- * @param fileName The file name of the issue description.
31
- * @returns The description of the issue, or null if it doesn't exist.
32
- */
33
- export function getIssueDescription(fileName) {
34
- return issueDescriptions[fileName] ?? null;
35
- }
36
- export const ISSUE_UTILS = {
37
- loadIssueDescriptions,
38
- getIssueDescription,
39
- };
@@ -1,36 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright 2025 Google LLC
4
- * SPDX-License-Identifier: Apache-2.0
5
- */
6
- import fs from 'node:fs';
7
- import { debug } from './third_party/index.js';
8
- const mcpDebugNamespace = 'mcp:log';
9
- const namespacesToEnable = [
10
- mcpDebugNamespace,
11
- ...(process.env['DEBUG'] ? [process.env['DEBUG']] : []),
12
- ];
13
- export function saveLogsToFile(fileName) {
14
- // Enable overrides everything so we need to add them
15
- debug.enable(namespacesToEnable.join(','));
16
- const logFile = fs.createWriteStream(fileName, { flags: 'a+' });
17
- debug.log = function (...chunks) {
18
- logFile.write(`${chunks.join(' ')}\n`);
19
- };
20
- logFile.on('error', function (error) {
21
- console.error(`Error when opening/writing to log file: ${error.message}`);
22
- logFile.end();
23
- process.exit(1);
24
- });
25
- return logFile;
26
- }
27
- export function flushLogs(logFile, timeoutMs = 2000) {
28
- return new Promise((resolve, reject) => {
29
- const timeout = setTimeout(reject, timeoutMs);
30
- logFile.end(() => {
31
- clearTimeout(timeout);
32
- resolve();
33
- });
34
- });
35
- }
36
- export const logger = debug(mcpDebugNamespace);