chrome-devtools-frontend 1.0.1721762 → 1.0.1726686

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 (273) hide show
  1. package/.agents/skills/review-ui-widgets/SKILL.md +7 -7
  2. package/.agents/skills/ui-eng-vision-local-lit-renderer/SKILL.md +12 -0
  3. package/.agents/skills/ui-eng-vision-widget-promoter/SKILL.md +3 -3
  4. package/.agents/skills/ui-widgets/SKILL.md +2 -1
  5. package/docs/cookbook/dependencies.md +57 -11
  6. package/docs/get_the_code.md +15 -0
  7. package/front_end/core/i18n/collect-ui-strings.js +58 -12
  8. package/front_end/core/i18n/i18nImpl.ts +1 -1
  9. package/front_end/core/root/Runtime.ts +1 -1
  10. package/front_end/core/sdk/ResourceTreeModel.ts +16 -0
  11. package/front_end/core/sdk/WebAuthnModel.ts +17 -10
  12. package/front_end/entrypoints/js_app/js_app.ts +2 -5
  13. package/front_end/entrypoints/node_app/node_app.ts +2 -3
  14. package/front_end/generated/InspectorBackendCommands.ts +3 -3
  15. package/front_end/generated/protocol.ts +17 -0
  16. package/front_end/models/ai_assistance/skills/lighthouse.md +2 -1
  17. package/front_end/models/ai_assistance/skills/network.md +1 -0
  18. package/front_end/models/ai_assistance/tools/ExecuteJavaScript.ts +26 -2
  19. package/front_end/models/ai_assistance/tools/GetLighthouseAudits.ts +1 -1
  20. package/front_end/models/ai_assistance/tools/ListNetworkRequests.ts +2 -7
  21. package/front_end/models/ai_assistance/tools/RunLighthouse.ts +2 -2
  22. package/front_end/models/comment_manager/CD4ABridge.ts +4 -0
  23. package/front_end/models/comment_manager/CommentManager.ts +0 -6
  24. package/front_end/models/comment_manager/CommentThread.ts +39 -19
  25. package/front_end/models/elements/StyleChanges.ts +66 -0
  26. package/front_end/models/trace/EventsSerializer.ts +2 -7
  27. package/front_end/models/trace/ModelImpl.ts +0 -2
  28. package/front_end/models/trace/handlers/FlowsHandler.ts +37 -29
  29. package/front_end/models/trace/handlers/NetworkRequestsHandler.ts +13 -6
  30. package/front_end/models/trace/helpers/SyntheticEvents.ts +10 -37
  31. package/front_end/models/trace/insights/RenderBlocking.ts +3 -1
  32. package/front_end/models/trace/lantern/simulation/Simulator.ts +4 -0
  33. package/front_end/models/trace/lantern/types/Lantern.ts +1 -0
  34. package/front_end/panels/accessibility/AccessibilityAnnouncementRecordingView.ts +92 -0
  35. package/front_end/panels/accessibility/SourceOrderView.ts +1 -1
  36. package/front_end/panels/accessibility/accessibilityAnnouncementRecordingListView.css +3 -1
  37. package/front_end/panels/accessibility/accessibilityAnnouncementRecordingView.css +12 -1
  38. package/front_end/panels/application/ApplicationPanelSidebar.ts +90 -0
  39. package/front_end/panels/application/StorageView.ts +348 -254
  40. package/front_end/panels/application/SubAppsView.ts +159 -0
  41. package/front_end/panels/application/application.ts +2 -0
  42. package/front_end/panels/application/preloading/PreloadingView.ts +360 -336
  43. package/front_end/panels/application/preloading/components/PreloadingDisabledInfobar.ts +3 -3
  44. package/front_end/panels/application/preloading/components/PreloadingGrid.ts +6 -3
  45. package/front_end/panels/application/preloading/components/RuleSetGrid.ts +17 -17
  46. package/front_end/panels/application/preloading/components/UsedPreloadingView.ts +2 -2
  47. package/front_end/panels/application/preloading/preloadingView.css +12 -4
  48. package/front_end/panels/application/preloading/preloadingViewDropDown.css +1 -1
  49. package/front_end/panels/application/storageView.css +16 -21
  50. package/front_end/panels/application/subAppsView.css +21 -0
  51. package/front_end/panels/browser_debugger/CategorizedBreakpointsSidebarPane.ts +2 -2
  52. package/front_end/panels/browser_debugger/browser_debugger-meta.ts +6 -8
  53. package/front_end/panels/comments/CommentsPane.ts +26 -9
  54. package/front_end/panels/comments/commentsPane.css +25 -6
  55. package/front_end/panels/common/CommentThreadWidget.ts +2 -2
  56. package/front_end/panels/common/CommentsOverlayWidget.ts +94 -35
  57. package/front_end/panels/common/commentThreadWidget.css +17 -0
  58. package/front_end/panels/common/commentsOverlay.css +5 -10
  59. package/front_end/panels/common/common-meta.ts +11 -1
  60. package/front_end/panels/elements/ClassesPaneWidget.ts +133 -89
  61. package/front_end/panels/elements/ColorSwatchPopoverIcon.ts +7 -33
  62. package/front_end/panels/elements/DOMTreeElementWidget.ts +3 -1
  63. package/front_end/panels/elements/DOMTreeWidget.ts +19 -3
  64. package/front_end/panels/elements/ElementStatePaneWidget.ts +11 -1
  65. package/front_end/panels/elements/PropertyRenderer.ts +3 -2
  66. package/front_end/panels/elements/StyleEditorWidget.ts +87 -39
  67. package/front_end/panels/elements/StylePropertiesSection.ts +32 -5
  68. package/front_end/panels/elements/StylePropertyTreeElement.ts +227 -162
  69. package/front_end/panels/elements/StylesSidebarPane.ts +1 -0
  70. package/front_end/panels/event_listeners/EventListenersView.ts +11 -8
  71. package/front_end/panels/layer_viewer/Layers3DView.ts +21 -37
  72. package/front_end/panels/linear_memory_inspector/components/ValueInterpreterSettings.ts +1 -1
  73. package/front_end/panels/network/NetworkConfigView.ts +12 -10
  74. package/front_end/panels/network/NetworkDataGridNode.ts +3 -1
  75. package/front_end/panels/network/RequestConditionsDrawer.ts +1 -1
  76. package/front_end/panels/network/RequestPayloadView.ts +12 -5
  77. package/front_end/panels/network/networkConfigView.css +8 -8
  78. package/front_end/panels/profiler/HeapProfileView.ts +28 -6
  79. package/front_end/panels/profiler/HeapSnapshotDataGrids.ts +7 -3
  80. package/front_end/panels/protocol_monitor/JSONEditor.ts +0 -1
  81. package/front_end/panels/recorder/RecorderPanel.ts +2 -2
  82. package/front_end/panels/screencast/ScreencastView.ts +3 -6
  83. package/front_end/panels/security/SecurityPanelSidebar.ts +0 -31
  84. package/front_end/panels/settings/SettingsScreen.ts +1 -1
  85. package/front_end/panels/settings/emulation/DevicesSettingsTab.ts +9 -16
  86. package/front_end/panels/settings/emulation/components/UserAgentClientHintsForm.ts +358 -345
  87. package/front_end/panels/settings/emulation/components/userAgentClientHintsForm.css +136 -121
  88. package/front_end/panels/sources/NavigatorView.ts +105 -45
  89. package/front_end/panels/sources/ScopeChainSidebarPane.ts +8 -5
  90. package/front_end/panels/sources/SourcesNavigator.ts +421 -213
  91. package/front_end/panels/sources/SourcesPanel.ts +9 -5
  92. package/front_end/panels/sources/TabbedEditorContainer.ts +41 -18
  93. package/front_end/panels/sources/UISourceCodeFrame.ts +1 -1
  94. package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +10 -5
  95. package/front_end/panels/sources/sources-meta.ts +4 -15
  96. package/front_end/panels/sources/sourcesNavigator.css +5 -0
  97. package/front_end/panels/timeline/ModificationsManager.ts +0 -2
  98. package/front_end/panels/timeline/README.md +2 -0
  99. package/front_end/panels/timeline/TimelineCommentContext.ts +171 -0
  100. package/front_end/panels/timeline/TimelineCommentController.ts +168 -30
  101. package/front_end/panels/timeline/TimelinePanel.ts +4 -0
  102. package/front_end/panels/timeline/components/IgnoreListSetting.ts +1 -1
  103. package/front_end/panels/timeline/timeline.ts +2 -0
  104. package/front_end/panels/timeline/utils/Treemap.ts +8 -0
  105. package/front_end/panels/webauthn/WebauthnPane.ts +15 -13
  106. package/front_end/third_party/chromium/README.chromium +1 -1
  107. package/front_end/third_party/puppeteer/README.chromium +2 -2
  108. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +113 -3
  109. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +21311 -20981
  110. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.d.ts +36 -0
  111. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.d.ts.map +1 -1
  112. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.js +22 -0
  113. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.js.map +1 -1
  114. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/BrowserContext.d.ts.map +1 -1
  115. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/BrowserContext.js +20 -18
  116. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/BrowserContext.js.map +1 -1
  117. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPRequest.d.ts +20 -1
  118. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPRequest.d.ts.map +1 -1
  119. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPRequest.js +2 -2
  120. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPRequest.js.map +1 -1
  121. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.d.ts +40 -1
  122. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.d.ts.map +1 -1
  123. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.js +3 -1
  124. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.js.map +1 -1
  125. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/locators/locators.d.ts +2 -0
  126. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/locators/locators.d.ts.map +1 -1
  127. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/locators/locators.js +41 -5
  128. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/locators/locators.js.map +1 -1
  129. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/HTTPRequest.d.ts +2 -1
  130. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/HTTPRequest.d.ts.map +1 -1
  131. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/HTTPRequest.js +23 -2
  132. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/HTTPRequest.js.map +1 -1
  133. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Input.js +1 -1
  134. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Page.d.ts +3 -2
  135. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Page.d.ts.map +1 -1
  136. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Page.js +13 -1
  137. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Page.js.map +1 -1
  138. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/Request.d.ts +1 -0
  139. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/Request.d.ts.map +1 -1
  140. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/Request.js +18 -11
  141. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/Request.js.map +1 -1
  142. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Accessibility.d.ts +2 -1
  143. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Accessibility.d.ts.map +1 -1
  144. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Accessibility.js +8 -1
  145. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Accessibility.js.map +1 -1
  146. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.d.ts +2 -1
  147. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.d.ts.map +1 -1
  148. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.js +24 -12
  149. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.js.map +1 -1
  150. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/EmulationManager.d.ts +1 -1
  151. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/EmulationManager.d.ts.map +1 -1
  152. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/EmulationManager.js +13 -7
  153. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/EmulationManager.js.map +1 -1
  154. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Frame.d.ts.map +1 -1
  155. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Frame.js +5 -1
  156. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Frame.js.map +1 -1
  157. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/HTTPRequest.d.ts +22 -1
  158. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/HTTPRequest.d.ts.map +1 -1
  159. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/HTTPRequest.js +75 -9
  160. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/HTTPRequest.js.map +1 -1
  161. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkEventManager.d.ts +18 -4
  162. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkEventManager.d.ts.map +1 -1
  163. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkEventManager.js +8 -4
  164. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkEventManager.js.map +1 -1
  165. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkManager.d.ts.map +1 -1
  166. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkManager.js +65 -26
  167. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkManager.js.map +1 -1
  168. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Page.d.ts +3 -2
  169. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Page.d.ts.map +1 -1
  170. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Page.js +19 -0
  171. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Page.js.map +1 -1
  172. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/ScreenRecording.d.ts.map +1 -1
  173. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/ScreenRecording.js +4 -3
  174. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/ScreenRecording.js.map +1 -1
  175. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Target.d.ts +1 -0
  176. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Target.d.ts.map +1 -1
  177. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Target.js +4 -0
  178. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Target.js.map +1 -1
  179. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/TargetManager.d.ts +2 -0
  180. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/TargetManager.d.ts.map +1 -1
  181. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/TargetManager.js +95 -8
  182. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/TargetManager.js.map +1 -1
  183. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.d.ts +0 -8
  184. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.d.ts.map +1 -1
  185. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.js +8 -24
  186. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.js.map +1 -1
  187. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserWebSocketTransport.d.ts +1 -0
  188. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserWebSocketTransport.d.ts.map +1 -1
  189. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserWebSocketTransport.js +5 -4
  190. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserWebSocketTransport.js.map +1 -1
  191. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/ConnectOptions.d.ts +9 -0
  192. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/ConnectOptions.d.ts.map +1 -1
  193. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/WaitTask.d.ts.map +1 -1
  194. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/WaitTask.js +10 -0
  195. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/WaitTask.js.map +1 -1
  196. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.d.ts +10 -0
  197. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.d.ts.map +1 -1
  198. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.js +30 -5
  199. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.js.map +1 -1
  200. package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.d.ts +1 -1
  201. package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.d.ts.map +1 -1
  202. package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.js +1 -1
  203. package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.js.map +1 -1
  204. package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/Poller.d.ts +2 -0
  205. package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/Poller.d.ts.map +1 -1
  206. package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/Poller.js +33 -3
  207. package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/Poller.js.map +1 -1
  208. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.d.ts.map +1 -1
  209. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.js +1 -2
  210. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.js.map +1 -1
  211. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/NodeWebSocketTransport.d.ts +4 -0
  212. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/NodeWebSocketTransport.d.ts.map +1 -1
  213. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/NodeWebSocketTransport.js +1 -0
  214. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/NodeWebSocketTransport.js.map +1 -1
  215. package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.d.ts +3 -3
  216. package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.js +3 -3
  217. package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.js.map +1 -1
  218. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/encoding.d.ts +2 -2
  219. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/encoding.d.ts.map +1 -1
  220. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/version.d.ts +1 -1
  221. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/version.js +1 -1
  222. package/front_end/third_party/puppeteer/package/lib/types.d.ts +113 -3
  223. package/front_end/third_party/puppeteer/package/package.json +4 -4
  224. package/front_end/third_party/puppeteer/package/src/api/Browser.ts +42 -0
  225. package/front_end/third_party/puppeteer/package/src/api/BrowserContext.ts +25 -22
  226. package/front_end/third_party/puppeteer/package/src/api/HTTPRequest.ts +22 -2
  227. package/front_end/third_party/puppeteer/package/src/api/Page.ts +45 -2
  228. package/front_end/third_party/puppeteer/package/src/api/locators/locators.ts +79 -32
  229. package/front_end/third_party/puppeteer/package/src/bidi/HTTPRequest.ts +32 -12
  230. package/front_end/third_party/puppeteer/package/src/bidi/Input.ts +1 -1
  231. package/front_end/third_party/puppeteer/package/src/bidi/Page.ts +18 -2
  232. package/front_end/third_party/puppeteer/package/src/bidi/core/Request.ts +21 -13
  233. package/front_end/third_party/puppeteer/package/src/cdp/Accessibility.ts +12 -2
  234. package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +37 -16
  235. package/front_end/third_party/puppeteer/package/src/cdp/EmulationManager.ts +14 -11
  236. package/front_end/third_party/puppeteer/package/src/cdp/Frame.ts +7 -1
  237. package/front_end/third_party/puppeteer/package/src/cdp/HTTPRequest.ts +101 -14
  238. package/front_end/third_party/puppeteer/package/src/cdp/NetworkEventManager.ts +26 -6
  239. package/front_end/third_party/puppeteer/package/src/cdp/NetworkManager.ts +111 -29
  240. package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +37 -1
  241. package/front_end/third_party/puppeteer/package/src/cdp/ScreenRecording.ts +5 -4
  242. package/front_end/third_party/puppeteer/package/src/cdp/Target.ts +5 -0
  243. package/front_end/third_party/puppeteer/package/src/cdp/TargetManager.ts +122 -7
  244. package/front_end/third_party/puppeteer/package/src/common/BrowserConnector.ts +13 -33
  245. package/front_end/third_party/puppeteer/package/src/common/BrowserWebSocketTransport.ts +10 -5
  246. package/front_end/third_party/puppeteer/package/src/common/ConnectOptions.ts +10 -0
  247. package/front_end/third_party/puppeteer/package/src/common/WaitTask.ts +12 -0
  248. package/front_end/third_party/puppeteer/package/src/common/util.ts +39 -5
  249. package/front_end/third_party/puppeteer/package/src/generated/injected.ts +1 -1
  250. package/front_end/third_party/puppeteer/package/src/injected/Poller.ts +35 -3
  251. package/front_end/third_party/puppeteer/package/src/node/BrowserLauncher.ts +4 -2
  252. package/front_end/third_party/puppeteer/package/src/node/NodeWebSocketTransport.ts +5 -0
  253. package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
  254. package/front_end/third_party/puppeteer/package/src/util/encoding.ts +2 -2
  255. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  256. package/front_end/ui/comments/CommentAnchorResolver.ts +3 -0
  257. package/front_end/ui/comments/CommentOverlayManager.ts +2 -4
  258. package/front_end/ui/components/lists/List.ts +14 -1
  259. package/front_end/ui/components/panel_feedback/PreviewToggle.ts +1 -1
  260. package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +23 -14
  261. package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +3 -0
  262. package/front_end/ui/helpers/OpenInNewTab.ts +8 -0
  263. package/front_end/ui/legacy/LinkContextMenuProvider.ts +1 -1
  264. package/front_end/ui/legacy/ListWidget.ts +14 -18
  265. package/front_end/ui/legacy/TabbedPane.ts +46 -3
  266. package/front_end/ui/legacy/Toolbar.ts +0 -1
  267. package/front_end/ui/legacy/Treeoutline.ts +10 -3
  268. package/front_end/ui/legacy/UIUtils.ts +5 -2
  269. package/front_end/ui/legacy/components/inline_editor/Swatches.ts +19 -6
  270. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +20 -11
  271. package/front_end/ui/legacy/components/source_frame/XMLView.ts +27 -7
  272. package/front_end/ui/visual_logging/KnownContextValues.ts +5 -0
  273. package/package.json +1 -1
@@ -78,10 +78,10 @@ This skill provides review guidance for Chrome DevTools frontend changes matchin
78
78
  - **Look for**: Unscoped generic selectors in light-DOM `.css` files (or `:host` inside `@scope` blocks instead of `:scope`), or CSS rules combining `vertical-align`, negative `margin-top`, and pixel offsets to center icons and buttons.
79
79
  - **Do not flag**: Shadow DOM component stylesheets where `:host` scoping is native.
80
80
 
81
- ### `UI_VIEW_OUTPUT_AND_CALLBACK_CONTRACTS`: Encapsulate imperative DOM actions in ViewOutput callbacks and pass user actions via semantic ViewInput callbacks instead of raw DOM references
81
+ ### `UI_VIEW_OUTPUT_AND_CALLBACK_CONTRACTS`: Encapsulate imperative DOM and child widget actions in ViewOutput callbacks and pass user actions via semantic ViewInput callbacks instead of raw DOM or Widget references
82
82
  - **Severity**: WARNING
83
- - **Why**: Exposing raw `HTMLElement` references on `ViewOutput` or passing raw `MouseEvent`/`KeyboardEvent` objects to presenter callbacks leaks DOM details into presenters. Views should populate narrow functional closures on `ViewOutput` (e.g. `output.focusInput = () => ...`) and unpack event values before calling `input.onSelect(value)`.
84
- - **Look for**: `ViewOutput` interfaces containing `HTMLElement` or `Element` properties, or `ViewInput` callbacks typed as `(event: Event) => void` instead of semantic domain values.
83
+ - **Why**: Exposing raw `HTMLElement` or `UI.Widget` references on `ViewOutput` (e.g. `output.childWidget = w`) or passing raw `MouseEvent`/`KeyboardEvent` objects to presenter callbacks leaks view implementation details into presenters. Supply all configuration through setters/inputs on the child widget, or if imperative calls are strictly necessary, populate narrow functional closures on `ViewOutput` (e.g. `output.focusInput = () => ...`, `output.scrollWidgetToSomething = () => widgetRef.scrollToSomething()`), and unpack event values before calling `input.onSelect(value)`.
84
+ - **Look for**: `ViewOutput` interfaces containing `HTMLElement`, `Element`, or `UI.Widget` subclass properties (other than temporary intermediate CL bridges), `get*ForTest()` presenter methods backed by `ViewOutput` widget references, or `ViewInput` callbacks typed as `(event: Event) => void` instead of semantic domain values.
85
85
  - **Do not flag**: Third-party editor or canvas host containers that require a raw mount `HTMLElement`.
86
86
 
87
87
  ### `UI_PANEL_AND_META_REGISTRATION`: Follow DevTools panel directory conventions and register settings and views in the appropriate *-meta.ts scope
@@ -102,11 +102,11 @@ This skill provides review guidance for Chrome DevTools frontend changes matchin
102
102
  - **Look for**: Raw string interpolation in `querySelector('[attr="' + val + '"]')` without `CSS.escape`, `href` attribute bindings with unvalidated `javascript:` URLs, Markdown table cell serialization without escaping `|*_<>\`, or raw HTML snippet generation without HTML escaping.
103
103
  - **Do not flag**: Standard Lit `html` text bindings (`${text}`), which escape HTML entities automatically.
104
104
 
105
- ### `UI_DECLARATIVE_CHILD_WIDGET_COMPOSITION`: Compose child UI.Widget instances declaratively in Lit templates using the two-argument widget(ChildWidget, {...}) directive instead of imperative show() calls or single-argument factory callbacks
105
+ ### `UI_DECLARATIVE_CHILD_WIDGET_COMPOSITION`: Compose child UI.Widget instances declaratively in Lit templates using ${widget(ChildWidget, {...})} instead of imperative show() calls, single-argument factory callbacks, or bare <devtools-widget> tags
106
106
  - **Severity**: WARNING
107
- - **Why**: Imperatively instantiating child widgets and calling `child.show(container)` inside presenters or views bypasses Lit reconciliation, complicates lifecycle management, and recreates widgets unnecessarily across renders. Similarly, single-argument factory callbacks `widget(element => ...)` only run on initial creation and fail to propagate updated properties on subsequent re-renders; strongly prefer the two-argument `widget(ChildWidget, {...})` form (converting `setFoo()` methods on the child widget into `set foo()` setters if needed).
108
- - **Look for**: `new ChildWidget()` followed by `.show(...)` or `.appendChild(child.element)` inside Lit view functions or migrated `performUpdate()` methods, or `widget(element => ...)` factory callbacks configuring child widget properties imperatively instead of `<devtools-widget ${widget(ChildWidget, {...})}></devtools-widget>` (or `${widget(ChildWidget, {...})}`).
109
- - **Do not flag**: Top-level legacy split widgets or tabbed panes that have not migrated to Lit views.
107
+ - **Why**: Imperatively instantiating child widgets and calling `child.show(container)` inside presenters or views bypasses Lit reconciliation, complicates lifecycle management, and recreates widgets unnecessarily across renders. Similarly, single-argument factory callbacks `widget(element => ...)` only run on initial creation and fail to propagate updated properties on subsequent re-renders; strongly prefer the two-argument `widget(ChildWidget, {...})` form (converting `setFoo()` methods on the child widget into `set foo()` setters if needed). Prefer `${widget(ChildWidget, {...})}` directly as a child expression over `<devtools-widget ${widget(ChildWidget, {...})}></devtools-widget>`; only use an explicit `<devtools-widget>` tag when setting other attributes, applying other directives (such as `widgetRef` or `ref`), or providing child nodes.
108
+ - **Look for**: `new ChildWidget()` followed by `.show(...)` or `.appendChild(child.element)` inside Lit view functions or migrated `performUpdate()` methods, `widget(element => ...)` factory callbacks configuring child widget properties imperatively instead of `${widget(ChildWidget, {...})}`, or `<devtools-widget ${widget(ChildWidget, {...})}></devtools-widget>` tags that have no other attributes, directives, or child nodes.
109
+ - **Do not flag**: Top-level legacy split widgets or tabbed panes that have not migrated to Lit views, or `<devtools-widget>` tags that set other attributes, use additional directives (e.g. `widgetRef`), or contain child nodes.
110
110
 
111
111
  ### `UI_AWAIT_UPDATE_COMPLETE_POST_RENDER`: Await this.updateComplete before executing post-render DOM measurements, focus changes, or scroll adjustments
112
112
  - **Severity**: ERROR
@@ -126,6 +126,12 @@ existing element containers.
126
126
 
127
127
  12. **Composing Child `UI.Widget`s & Pre-Existing Instances**:
128
128
 
129
+ * **Prefer `${widget(ChildWidgetClass, {params})}` Over `<devtools-widget>`**:
130
+ Prefer `${widget(ChildWidgetClass, {params})}` directly as a child
131
+ expression instead of `<devtools-widget ${widget(ChildWidgetClass, {params})}></devtools-widget>`.
132
+ Only use an explicit `<devtools-widget>` tag when you need to set other
133
+ HTML attributes/classes, apply additional directives (such as `widgetRef`
134
+ or `ref`), or provide child nodes.
129
135
  * **Strongly Prefer Two-Argument `widget(ChildWidgetClass, {params})`**:
130
136
  When instantiating child widgets in a Lit template, strongly prefer the
131
137
  two-argument form `widget(ChildWidgetClass, {propA: input.a, propB: input.b})`
@@ -136,6 +142,12 @@ existing element containers.
136
142
  `setFoo()` methods instead of setters, convert them into `set foo()`
137
143
  setters on the child widget so you can use the two-argument `widget()`
138
144
  directive.
145
+ * **No Widget References on `ViewOutput`**: Do not store child widget
146
+ references on `ViewOutput` (e.g., `output.childWidget = w`) as a final
147
+ result (only acceptable temporarily in intermediate CLs). Supply all
148
+ configuration through setters on the child widget, or if imperative
149
+ actions are strictly required, expose individual functions on `ViewOutput`
150
+ (e.g., `output.doLayout = () => w.doLayout()`).
139
151
  * **Pre-Existing Widget Instances (`UI.Widget.WrapperWidget`)**: Use
140
152
  `${widget(UI.Widget.WrapperWidget, {widget: input.childWidget})}` when
141
153
  embedding widgets owned by `UI.ViewManager`
@@ -66,14 +66,14 @@ clean `UI.Widget` classes that use native update rendering delegates.
66
66
  3. **Clean Up Legacy Wrappers**:
67
67
 
68
68
  * Remove any `LegacyWrapper` bindings or custom wrappable custom elements.
69
- * Replace old panel instantiations with standard `<devtools-widget>`
70
- declarative entries (using `const {widget} = UI.Widget;`):
69
+ * Replace old panel instantiations with declarative `widget` entries (using `const {widget} = UI.Widget;`). Prefer `${widget(MyWidgetClass, {params})}` directly as a child expression over `<devtools-widget ${widget(MyWidgetClass, {params})}></devtools-widget>`; only use an explicit `<devtools-widget>` tag when setting other attributes, applying other directives (such as `widgetRef` or `ref`), or providing child nodes:
71
70
 
72
71
  ```typescript
73
- html`<devtools-widget ${widget(MyWidgetClass, {params})}></devtools-widget>`
72
+ html`${widget(MyWidgetClass, {params})}`
74
73
  ```
75
74
 
76
75
  * **Strongly prefer the two-argument `widget(MyWidgetClass, {params})` form** over the single-argument factory callback `widget(element => new MyWidgetClass(element, ...))`. The single-argument factory only runs on initial creation and does not update properties on subsequent re-renders. If the child widget only exposes `setFoo(...)` methods, convert them into `set foo(...)` setters so they can be passed via the second argument of `widget()`.
76
+ * **No Widget References on `ViewOutput`**: Keeping child `UI.Widget` instances on `ViewOutput` (e.g., `output.childWidget = w`) is not a good practice and must not remain in the final result (it is only acceptable temporarily in intermediate CLs). Either supply all configuration through setters on the child widget, or if imperative action calls are strictly needed, expose individual functions on `ViewOutput` (such as `output.doLayout = () => w.doLayout()` or `output.scrollWidgetToSomething = () => w.scrollToSomething()`). Remove legacy `get*ForTest()` methods that were only used to grab child widgets from `ViewOutput` and update tests to query the DOM (`view.contentElement.querySelector(...)?.getWidget()`) or inspect `ViewInput`.
77
77
  * Inspect instantiator files (e.g., `ApplicationPanelSidebar.ts`) and
78
78
  decouple any direct accesses to `.element`.
79
79
 
@@ -59,6 +59,7 @@ const DEFAULT_VIEW = (input: ViewInput, output: ViewOutput, target: HTMLElement)
59
59
  ### Composition
60
60
 
61
61
  * To render a child widget, the parent's View MUST use the lit-html directive `UI.Widget.widget`.
62
+ * **Prefer `${widget(WidgetClass, {params})}` directly as a child expression** over `<devtools-widget ${widget(WidgetClass, {params})}></devtools-widget>`. Only use an explicit `<devtools-widget>` tag when you need to set other HTML attributes/classes, apply additional directives (such as `widgetRef` or `ref`), or provide child nodes.
62
63
  * **Strongly prefer the two-argument `widget(WidgetClass, {params})` form** over the single-argument factory callback `widget(element => new WidgetClass(element, ...))`. The two-argument form automatically updates properties and calls `requestUpdate()` on subsequent renders, whereas a factory callback only runs once on initial instantiation.
63
64
  * If a child widget currently exposes imperative setter methods (e.g., `setStorageKey(key)` or `setStorageBucket(bucket)`) instead of public properties/setters, convert them into standard TypeScript setters (`set storageKey(key)`, `set storageBucket(bucket)`) on the child widget so it can be instantiated and updated declaratively via the two-argument `widget(WidgetClass, {params})` directive.
64
65
  * Configuration is passed via the parameters.
@@ -110,7 +111,7 @@ render(html`
110
111
 
111
112
  ### Legacy Interop & Refs
112
113
  * **Raw Elements:** Use `Directives.ref` (from `ui/lit/lit.js`) to obtain a reference to a raw `HTMLElement` if needed for imperative APIs (e.g., `splitWidget.installResizer(element)`).
113
- * **Child Widgets:** Use `UI.Widget.widgetRef` to obtain the class instance of a child widget if you need to call methods on it directly (though declarative data flow is preferred).
114
+ * **Child Widgets:** Use `UI.Widget.widgetRef` to obtain the class instance of a child widget inside the view function if you need to call imperative methods on it. **Do NOT store child widget instances on `ViewOutput` as a final result** (doing so is only acceptable temporarily in intermediate migration CLs). Instead, either supply all needed configuration declaratively through setters/inputs on the child widget, or if imperative calls are strictly necessary, expose narrow action functions on `ViewOutput` (e.g., `output.doLayout = () => splitWidget.doLayout()`, `output.revealPosition = pos => childWidget.revealPosition(pos)`). Do not keep `get*ForTest()` methods that return child widget instances via `ViewOutput`; tests should query rendered `<devtools-widget>` elements via `.getWidget()` or assert on `ViewInput` via `createViewFunctionStub`.
114
115
 
115
116
  ### Dependencies
116
117
 
@@ -54,23 +54,69 @@ reviewers and typically avoids inflating the bundle size.
54
54
 
55
55
  For all third-party packages that are used either as part of the DevTools build
56
56
  process or to augment engineers workflows (for example linters), we add them to
57
- `scripts/deps/manage_node_deps.py`. This Python script has been approved by
58
- Chromium licensing to be used, on the basis that it enforces all packages have a
59
- license that is compatible with a set of pre-defined licensees.
60
-
61
- If you want to use a new package as tooling process in engineer workflows, you
62
- can add the package to the `package.json` and run `./dt install-deps` to
63
- check in the new contents.
57
+ `package.json`; `scripts/deps/manage_node_deps.py` installs them. This Python
58
+ script has been approved by Chromium licensing to be used, on the basis that it
59
+ enforces all packages have a license that is compatible with a set of
60
+ pre-defined licensees.
61
+
62
+ `node_modules/` is not checked into git. `gclient sync` downloads it as one
63
+ archive from `gs://chromium-nodejs/devtools-frontend/<sha256>`, pinned by the
64
+ `node_modules` entry in `DEPS`, the same way Chromium's WebUI toolchain and
65
+ chromium-bidi ship their npm dependencies. Local edits inside `node_modules/`
66
+ only last until the next `gclient sync` that changes the pin.
67
+
68
+ gclient decides whether to re-extract the archive from the stamp files it
69
+ keeps in `node_modules/`, not from the extracted tree. Checking out a revision
70
+ from before `node_modules/` left git restores the tracked tree over the
71
+ extracted one and leaves the stamps alone; checking out a later revision again
72
+ deletes the tracked files, and `gclient sync` would consider the now empty
73
+ directory up to date. The `ensure_node_modules` hook
74
+ (`scripts/deps/ensure_node_modules.py`) catches this and re-extracts the
75
+ archive that gclient leaves in `node_modules/node_modules.tar.gz`; if that
76
+ archive is missing, it removes the stamps and asks you to run `gclient sync`
77
+ once more.
78
+
79
+ To add or update a package:
80
+
81
+ 1. Change the version in `package.json`.
82
+ 2. Run `./dt install-deps`. It runs `npm install`, post-processes the tree,
83
+ checks licenses, applies `scripts/deps/npm_exclude.txt`, verifies that
84
+ every `node_modules/` path referenced from GN or Python build files still
85
+ exists and writes a deterministic `out/node_modules.tar.gz` (sorted
86
+ entries, zeroed timestamps and ownership: the same tree always has the
87
+ same sha256).
88
+ 3. Build and test against the new tree: `./dt build && ./dt test`.
89
+ 4. Run `./dt install-deps --upload`. It uploads the archive (a no-op if the
90
+ object exists) and updates `DEPS`. This needs write access to the bucket;
91
+ otherwise ask an infra owner (`config/owner/INFRA_OWNERS`) to run it on
92
+ your branch.
93
+ 5. Upload the CL: `package.json`, `package-lock.json` and the `DEPS` change.
94
+ Presubmit checks that these change together; add a
95
+ `Skip-Node-Modules-Check: <reason>` footer for intentional exceptions.
96
+
97
+ Reviewers can rebuild the archive from the lockfile with `./dt install-deps`
98
+ and compare the printed sha256 with `DEPS`.
64
99
 
65
100
  Only add new license types to `LICENSES` after you received approval from
66
101
  `opensource-licensing@google.com`. Their response time is typically within 24
67
102
  hours, so this typically is not a big hurdle.
68
103
 
69
104
  To avoid excessive package updates, it is typically easiest to update all
70
- packages in `manage_node_deps.py` once a month. Since NPM packages can have a
71
- lot of (shared) transitive dependencies, updating the packages on a specific day
72
- increases the chances that shared dependencies are deduplicated and thus result
73
- in smaller repository sizes.
105
+ packages once a month. Since NPM packages can have a lot of (shared) transitive
106
+ dependencies, updating the packages on a specific day increases the chances
107
+ that shared dependencies are deduplicated and thus result in a smaller archive.
108
+
109
+ #### The exclude list
110
+
111
+ `scripts/deps/npm_exclude.txt` holds rsync filter rules that drop files the
112
+ build and tests don't need (tests, docs, source maps, non-declaration
113
+ TypeScript sources, dotfiles, ...) before the archive is built. Keep rules come
114
+ first and the first matching rule wins. Prefer generic patterns. A
115
+ package-specific rule goes into the "package-specific drops" section with a
116
+ comment saying why the files are unused, and must be measured and verified
117
+ with a full build, test and lint run, because the reference check only knows
118
+ about paths mentioned in GN and Python files, not about what Node resolves at
119
+ runtime. Check such rules again when the package in question is updated.
74
120
 
75
121
  > **WARNING:** Updating tools such as Rollup and TypeScript will cause all build
76
122
  > cache output to be purged, as they are part of all DevTools modules. Whenever
@@ -334,6 +334,14 @@ Follow [instructions](https://www.chromium.org/developers/how-tos/get-the-code)
334
334
  to check out Chromium. The DevTools front-end code is located inside the
335
335
  `third_party/devtools-frontend/src/` folder (after running `gclient sync`).
336
336
 
337
+ `node_modules/` is not part of the devtools-frontend git tree: `gclient sync`,
338
+ run from `chromium/src`, downloads the archive pinned in
339
+ `third_party/devtools-frontend/src/DEPS` and extracts it (see
340
+ [dependencies.md](cookbook/dependencies.md)). Whenever you check out a
341
+ different DevTools revision or branch in `third_party/devtools-frontend/src`,
342
+ run `gclient sync` again before building; `git checkout` or `git rebase`
343
+ alone do not update `node_modules/`.
344
+
337
345
  ### Build
338
346
 
339
347
  The [instructions](https://www.chromium.org/developers/how-tos/get-the-code) on
@@ -438,6 +446,13 @@ git rebase
438
446
  popd
439
447
  ```
440
448
 
449
+ Finish with another `gclient sync` so that `node_modules/` (and the other
450
+ dependencies pinned in the DevTools `DEPS`) match the DevTools revision you
451
+ ended up on. If you switch back and forth across the revision that moved
452
+ `node_modules/` out of git, `gclient sync` repairs the directory on its own
453
+ (`ensure_node_modules` hook); in the worst case it asks you to run it once
454
+ more.
455
+
441
456
  ## Integrated checkout
442
457
 
443
458
  **This solution is experimental, please report any trouble that you run into!**
@@ -2,7 +2,9 @@
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
4
 
5
- import {globSync} from 'node:fs';
5
+ import {createHash} from 'node:crypto';
6
+ import * as fs from 'node:fs';
7
+ import {createRequire} from 'node:module';
6
8
  import * as path from 'node:path';
7
9
  import yargs from 'yargs';
8
10
  import {hideBin} from 'yargs/helpers';
@@ -58,32 +60,56 @@ if (inputDirectories.length === 0) {
58
60
  throw new Error('Provide at least one directory!');
59
61
  }
60
62
 
63
+ const outputDirectory = yargsObject['output-directory'];
64
+
65
+ // The parse results depend on collect-strings.js and the TypeScript version,
66
+ // so a change to either one discards the cache.
67
+ const cachePath = path.join(outputDirectory, 'collected-ui-strings.cache.json');
68
+ const collectStringsSource = fs.readFileSync(new URL('../../../third_party/i18n/collect-strings.js', import.meta.url));
69
+ const typescriptVersion = createRequire(import.meta.url)('typescript/package.json').version;
70
+ const cacheVersion = createHash('sha256').update(collectStringsSource).update(typescriptVersion).digest('hex');
71
+ /** @type {Record<string, {source: string, parsed: object}>} */
72
+ let savedFiles = {};
73
+ try {
74
+ const saved = JSON.parse(fs.readFileSync(cachePath, 'utf8'));
75
+ if (saved.version === cacheVersion) {
76
+ savedFiles = saved.files;
77
+ }
78
+ } catch {
79
+ // Without a cache, all UIStrings get parsed again.
80
+ }
81
+ const cache = new Map(Object.entries(savedFiles));
82
+ const initialCacheSize = cache.size;
83
+
61
84
  /** @type {Record<string, CtcMessage>} */
62
85
  let collectedStrings = {};
63
86
  /** @type {string[]} */
64
87
  const files = [];
65
88
  for (const directory of inputDirectories) {
66
- collectedStrings = {
67
- ...collectedStrings,
68
- ...collectAllStringsInDir(directory),
69
- };
70
-
71
- const fs = globSync('**/*.{js,ts,gn}', {
89
+ const directoryFiles = fs.globSync('**/*.{js,ts,gn}', {
72
90
  cwd: directory,
73
91
  exclude: IGNORED_PATH_COMPONENTS,
74
92
  });
75
- files.push(...fs.map(f => path.join(directory, f)));
93
+ collectedStrings = {
94
+ ...collectedStrings,
95
+ ...collectAllStringsInDir(
96
+ directory,
97
+ directoryFiles.filter(f => !f.endsWith('.gn')),
98
+ cache,
99
+ ),
100
+ };
101
+ files.push(...directoryFiles.map(f => path.join(directory, f)));
76
102
  }
77
103
 
78
- const outputDirectory = yargsObject['output-directory'];
79
- await convertCtcToLhLAndSave(outputDirectory, 'en-US', collectedStrings);
104
+ const tasks = [convertCtcToLhLAndSave(outputDirectory, 'en-US', collectedStrings)];
80
105
  if (yargsObject['include-en-xl']) {
81
- await convertCtcToLhLAndSave(
106
+ tasks.push(convertCtcToLhLAndSave(
82
107
  outputDirectory,
83
108
  'en-XL',
84
109
  createPsuedoLocaleStrings(collectedStrings),
85
- );
110
+ ));
86
111
  }
112
+ await Promise.all(tasks);
87
113
 
88
114
  // Write the depfile. This is necessary to properly rebuild en-US.json/en-XL.json
89
115
  // when any of the input TS files change. We also re-build when any GN file changes,
@@ -93,3 +119,23 @@ ${path.join(outputDirectory, 'en-US.json')}: ${files.join(' ')}
93
119
  `;
94
120
 
95
121
  await writeIfChanged(path.join(outputDirectory, 'collected-ui-strings.d'), depfile);
122
+
123
+ // Drop the entries of deleted files, and save the cache only if it changed.
124
+ let cacheChanged = false;
125
+ await Promise.all(
126
+ Array.from(cache.entries()).map(async ([file, entry]) => {
127
+ if (savedFiles[file] !== entry) {
128
+ cacheChanged = true;
129
+ }
130
+ try {
131
+ await fs.promises.access(file);
132
+ } catch {
133
+ cache.delete(file);
134
+ cacheChanged = true;
135
+ }
136
+ }),
137
+ );
138
+ if (cacheChanged || cache.size !== initialCacheSize) {
139
+ const serialized = JSON.stringify({version: cacheVersion, files: Object.fromEntries(cache)});
140
+ await writeIfChanged(cachePath, serialized);
141
+ }
@@ -49,7 +49,7 @@ export function getAllSupportedDevToolsLocales(): string[] {
49
49
  function getLocaleFetchUrl(locale: Intl.UnicodeBCP47LocaleIdentifier, location: string): string {
50
50
  const remoteBase = Root.Runtime.getRemoteBase(location);
51
51
  if (remoteBase?.version && !BUNDLED_LOCALES.has(locale)) {
52
- return REMOTE_FETCH_PATTERN.replace('@HOST@', 'devtools://devtools')
52
+ return REMOTE_FETCH_PATTERN.replace('@HOST@', 'devtools://devtools-remote')
53
53
  .replace('@VERSION@', remoteBase.version)
54
54
  .replace('@LOCALE@', locale);
55
55
  }
@@ -47,7 +47,7 @@ export function getRemoteBase(location: string = globalObject.self?.location?.to
47
47
  return null;
48
48
  }
49
49
 
50
- return {base: `devtools://devtools/remote/serve_file/${version[1]}/`, version: version[1]};
50
+ return {base: `devtools://devtools-remote/remote/serve_file/${version[1]}/`, version: version[1]};
51
51
  }
52
52
 
53
53
  export function getPathName(): string {
@@ -529,6 +529,22 @@ export class ResourceTreeModel extends SDKModel<EventTypes> {
529
529
  return await this.agent.invoke_getAppId();
530
530
  }
531
531
 
532
+ async getSubApps(): Promise<Protocol.Page.SubApp[]> {
533
+ const response = await this.agent.invoke_getSubApps();
534
+ if (response.getError()) {
535
+ return [];
536
+ }
537
+ return response.subApps ?? [];
538
+ }
539
+
540
+ async getSiblingSubApps(): Promise<Protocol.Page.SubApp[]> {
541
+ const response = await this.agent.invoke_getSiblingSubApps();
542
+ if (response.getError()) {
543
+ return [];
544
+ }
545
+ return response.subApps ?? [];
546
+ }
547
+
532
548
  private executionContextComparator(a: ExecutionContext, b: ExecutionContext): number {
533
549
  function framePath(frame: ResourceTreeFrame|null): ResourceTreeFrame[] {
534
550
  let currentFrame: (ResourceTreeFrame|null) = frame;
@@ -22,6 +22,13 @@ export interface EventTypes {
22
22
  [Events.CREDENTIAL_UPDATED]: Protocol.WebAuthn.CredentialUpdatedEvent;
23
23
  }
24
24
 
25
+ function throwIfError(response: Protocol.ProtocolResponseWithError): void {
26
+ const error = response.getError();
27
+ if (error) {
28
+ throw new Error(error);
29
+ }
30
+ }
31
+
25
32
  export class WebAuthnModel extends SDKModel<EventTypes> {
26
33
  readonly #agent: ProtocolProxyApi.WebAuthnApi;
27
34
  constructor(target: Target) {
@@ -30,44 +37,44 @@ export class WebAuthnModel extends SDKModel<EventTypes> {
30
37
  target.registerWebAuthnDispatcher(new WebAuthnDispatcher(this));
31
38
  }
32
39
 
33
- setVirtualAuthEnvEnabled(enable: boolean, enableUI = true): Promise<Object> {
34
- if (enable) {
35
- return this.#agent.invoke_enable({enableUI});
36
- }
37
- return this.#agent.invoke_disable();
40
+ async setVirtualAuthEnvEnabled(enable: boolean, enableUI = true): Promise<void> {
41
+ const response = enable ? await this.#agent.invoke_enable({enableUI}) : await this.#agent.invoke_disable();
42
+ throwIfError(response);
38
43
  }
39
44
 
40
45
  async addAuthenticator(options: Protocol.WebAuthn.VirtualAuthenticatorOptions):
41
46
  Promise<Protocol.WebAuthn.AuthenticatorId> {
42
47
  const response = await this.#agent.invoke_addVirtualAuthenticator({options});
48
+ throwIfError(response);
43
49
  return response.authenticatorId;
44
50
  }
45
51
 
46
52
  async removeAuthenticator(authenticatorId: Protocol.WebAuthn.AuthenticatorId): Promise<void> {
47
- await this.#agent.invoke_removeVirtualAuthenticator({authenticatorId});
53
+ throwIfError(await this.#agent.invoke_removeVirtualAuthenticator({authenticatorId}));
48
54
  }
49
55
 
50
56
  async setAutomaticPresenceSimulation(authenticatorId: Protocol.WebAuthn.AuthenticatorId, enabled: boolean):
51
57
  Promise<void> {
52
- await this.#agent.invoke_setAutomaticPresenceSimulation({authenticatorId, enabled});
58
+ throwIfError(await this.#agent.invoke_setAutomaticPresenceSimulation({authenticatorId, enabled}));
53
59
  }
54
60
 
55
61
  async setUserVerified(authenticatorId: Protocol.WebAuthn.AuthenticatorId, isUserVerified: boolean): Promise<void> {
56
- await this.#agent.invoke_setUserVerified({authenticatorId, isUserVerified});
62
+ throwIfError(await this.#agent.invoke_setUserVerified({authenticatorId, isUserVerified}));
57
63
  }
58
64
 
59
65
  async addCredential(authenticatorId: Protocol.WebAuthn.AuthenticatorId,
60
66
  credential: Protocol.WebAuthn.Credential): Promise<void> {
61
- await this.#agent.invoke_addCredential({authenticatorId, credential});
67
+ throwIfError(await this.#agent.invoke_addCredential({authenticatorId, credential}));
62
68
  }
63
69
 
64
70
  async getCredentials(authenticatorId: Protocol.WebAuthn.AuthenticatorId): Promise<Protocol.WebAuthn.Credential[]> {
65
71
  const response = await this.#agent.invoke_getCredentials({authenticatorId});
72
+ throwIfError(response);
66
73
  return response.credentials;
67
74
  }
68
75
 
69
76
  async removeCredential(authenticatorId: Protocol.WebAuthn.AuthenticatorId, credentialId: string): Promise<void> {
70
- await this.#agent.invoke_removeCredential({authenticatorId, credentialId});
77
+ throwIfError(await this.#agent.invoke_removeCredential({authenticatorId, credentialId}));
71
78
  }
72
79
 
73
80
  credentialAdded(params: Protocol.WebAuthn.CredentialAddedEvent): void {
@@ -85,12 +85,9 @@ UI.ViewManager.registerViewExtension({
85
85
  commandPrompt: i18nLazyString(UIStrings.showNode),
86
86
  order: 2,
87
87
  persistence: UI.ViewManager.ViewPersistence.PERMANENT,
88
- async loadView(universe) {
88
+ async loadView() {
89
89
  const Sources = await loadSourcesModule();
90
- return Sources.SourcesNavigator.NetworkNavigatorView.instance({
91
- forceNew: null,
92
- networkProjectManager: universe.networkProjectManager,
93
- });
90
+ return Sources.SourcesNavigator.NetworkNavigatorView.instance();
94
91
  },
95
92
  });
96
93
 
@@ -81,10 +81,9 @@ UI.ViewManager.registerViewExtension({
81
81
  commandPrompt: i18nLazyString(UIStrings.showNode),
82
82
  order: 2,
83
83
  persistence: UI.ViewManager.ViewPersistence.PERMANENT,
84
- async loadView(universe) {
84
+ async loadView() {
85
85
  const Sources = await loadSourcesModule();
86
- return Sources.SourcesNavigator.NetworkNavigatorView.instance(
87
- {forceNew: null, networkProjectManager: universe.networkProjectManager});
86
+ return Sources.SourcesNavigator.NetworkNavigatorView.instance();
88
87
  },
89
88
  });
90
89
 
@@ -838,7 +838,7 @@ inspectorBackend.registerEnum("Network.ContentSecurityPolicySource", {HTTP: "HTT
838
838
  inspectorBackend.registerEnum("Network.ReportStatus", {Queued: "Queued", Pending: "Pending", MarkedForRemoval: "MarkedForRemoval", Success: "Success"});
839
839
  inspectorBackend.registerEnum("Network.DeviceBoundSessionWithUsageUsage", {NotInScope: "NotInScope", InScopeRefreshNotYetNeeded: "InScopeRefreshNotYetNeeded", InScopeRefreshNotAllowed: "InScopeRefreshNotAllowed", ProactiveRefreshNotPossible: "ProactiveRefreshNotPossible", ProactiveRefreshAttempted: "ProactiveRefreshAttempted", Deferred: "Deferred"});
840
840
  inspectorBackend.registerEnum("Network.DeviceBoundSessionUrlRuleRuleType", {Exclude: "Exclude", Include: "Include"});
841
- inspectorBackend.registerEnum("Network.DeviceBoundSessionFetchResult", {Success: "Success", SigningKeyGenerationError: "SigningKeyGenerationError", AttestationKeyGenerationError: "AttestationKeyGenerationError", SigningError: "SigningError", TransientSigningError: "TransientSigningError", ServerRequestedTermination: "ServerRequestedTermination", InvalidSessionId: "InvalidSessionId", InvalidChallenge: "InvalidChallenge", TooManyChallenges: "TooManyChallenges", InvalidFetcherUrl: "InvalidFetcherUrl", InvalidRefreshUrl: "InvalidRefreshUrl", TransientHttpError: "TransientHttpError", ScopeOriginSameSiteMismatch: "ScopeOriginSameSiteMismatch", RefreshUrlSameSiteMismatch: "RefreshUrlSameSiteMismatch", MismatchedSessionId: "MismatchedSessionId", MissingScope: "MissingScope", NoCredentials: "NoCredentials", SubdomainRegistrationWellKnownUnavailable: "SubdomainRegistrationWellKnownUnavailable", SubdomainRegistrationUnauthorized: "SubdomainRegistrationUnauthorized", SubdomainRegistrationWellKnownMalformed: "SubdomainRegistrationWellKnownMalformed", SessionProviderWellKnownUnavailable: "SessionProviderWellKnownUnavailable", RelyingPartyWellKnownUnavailable: "RelyingPartyWellKnownUnavailable", FederatedKeyThumbprintMismatch: "FederatedKeyThumbprintMismatch", InvalidFederatedSessionUrl: "InvalidFederatedSessionUrl", InvalidFederatedKey: "InvalidFederatedKey", TooManyRelyingOriginLabels: "TooManyRelyingOriginLabels", BoundCookieSetForbidden: "BoundCookieSetForbidden", NetError: "NetError", ProxyError: "ProxyError", EmptySessionConfig: "EmptySessionConfig", InvalidCredentialsConfig: "InvalidCredentialsConfig", InvalidCredentialsType: "InvalidCredentialsType", InvalidCredentialsEmptyName: "InvalidCredentialsEmptyName", InvalidCredentialsCookie: "InvalidCredentialsCookie", PersistentHttpError: "PersistentHttpError", RegistrationAttemptedChallenge: "RegistrationAttemptedChallenge", InvalidScopeOrigin: "InvalidScopeOrigin", ScopeOriginContainsPath: "ScopeOriginContainsPath", RefreshInitiatorNotString: "RefreshInitiatorNotString", RefreshInitiatorInvalidHostPattern: "RefreshInitiatorInvalidHostPattern", InvalidScopeSpecification: "InvalidScopeSpecification", MissingScopeSpecificationType: "MissingScopeSpecificationType", EmptyScopeSpecificationDomain: "EmptyScopeSpecificationDomain", EmptyScopeSpecificationPath: "EmptyScopeSpecificationPath", InvalidScopeSpecificationType: "InvalidScopeSpecificationType", InvalidScopeIncludeSite: "InvalidScopeIncludeSite", MissingScopeIncludeSite: "MissingScopeIncludeSite", FederatedNotAuthorizedByProvider: "FederatedNotAuthorizedByProvider", FederatedNotAuthorizedByRelyingParty: "FederatedNotAuthorizedByRelyingParty", SessionProviderWellKnownMalformed: "SessionProviderWellKnownMalformed", SessionProviderWellKnownHasProviderOrigin: "SessionProviderWellKnownHasProviderOrigin", RelyingPartyWellKnownMalformed: "RelyingPartyWellKnownMalformed", RelyingPartyWellKnownHasRelyingOrigins: "RelyingPartyWellKnownHasRelyingOrigins", InvalidFederatedSessionProviderSessionMissing: "InvalidFederatedSessionProviderSessionMissing", InvalidFederatedSessionWrongProviderOrigin: "InvalidFederatedSessionWrongProviderOrigin", InvalidCredentialsCookieCreationTime: "InvalidCredentialsCookieCreationTime", InvalidCredentialsCookieName: "InvalidCredentialsCookieName", InvalidCredentialsCookieParsing: "InvalidCredentialsCookieParsing", InvalidCredentialsCookieUnpermittedAttribute: "InvalidCredentialsCookieUnpermittedAttribute", InvalidCredentialsCookieInvalidDomain: "InvalidCredentialsCookieInvalidDomain", InvalidCredentialsCookiePrefix: "InvalidCredentialsCookiePrefix", InvalidScopeRulePath: "InvalidScopeRulePath", InvalidScopeRuleHostPattern: "InvalidScopeRuleHostPattern", ScopeRuleOriginScopedHostPatternMismatch: "ScopeRuleOriginScopedHostPatternMismatch", ScopeRuleSiteScopedHostPatternMismatch: "ScopeRuleSiteScopedHostPatternMismatch", SigningQuotaExceeded: "SigningQuotaExceeded", InvalidConfigJson: "InvalidConfigJson", InvalidFederatedSessionProviderFailedToRestoreKey: "InvalidFederatedSessionProviderFailedToRestoreKey", FailedToUnwrapKey: "FailedToUnwrapKey", SessionDeletedDuringRefresh: "SessionDeletedDuringRefresh", CrossOriginRegistrationSiteNotIncluded: "CrossOriginRegistrationSiteNotIncluded", InvalidPreProvisionedKeyInitiatorMissing: "InvalidPreProvisionedKeyInitiatorMissing", PreProvisionedKeyAccessNotGranted: "PreProvisionedKeyAccessNotGranted", PreProvisionedKeyNotFound: "PreProvisionedKeyNotFound", AttestationCertificationError: "AttestationCertificationError", AttestationSigningError: "AttestationSigningError"});
841
+ inspectorBackend.registerEnum("Network.DeviceBoundSessionFetchResult", {Success: "Success", SigningKeyGenerationError: "SigningKeyGenerationError", AttestationKeyGenerationError: "AttestationKeyGenerationError", SigningError: "SigningError", TransientSigningError: "TransientSigningError", ServerRequestedTermination: "ServerRequestedTermination", InvalidSessionId: "InvalidSessionId", InvalidChallenge: "InvalidChallenge", TooManyChallenges: "TooManyChallenges", InvalidFetcherUrl: "InvalidFetcherUrl", InvalidRefreshUrl: "InvalidRefreshUrl", TransientHttpError: "TransientHttpError", ScopeOriginSameSiteMismatch: "ScopeOriginSameSiteMismatch", RefreshUrlSameSiteMismatch: "RefreshUrlSameSiteMismatch", MismatchedSessionId: "MismatchedSessionId", MissingScope: "MissingScope", NoCredentials: "NoCredentials", SubdomainRegistrationWellKnownUnavailable: "SubdomainRegistrationWellKnownUnavailable", SubdomainRegistrationUnauthorized: "SubdomainRegistrationUnauthorized", SubdomainRegistrationWellKnownMalformed: "SubdomainRegistrationWellKnownMalformed", SessionProviderWellKnownUnavailable: "SessionProviderWellKnownUnavailable", RelyingPartyWellKnownUnavailable: "RelyingPartyWellKnownUnavailable", FederatedKeyThumbprintMismatch: "FederatedKeyThumbprintMismatch", InvalidFederatedSessionUrl: "InvalidFederatedSessionUrl", InvalidFederatedKey: "InvalidFederatedKey", TooManyRelyingOriginLabels: "TooManyRelyingOriginLabels", BoundCookieSetForbidden: "BoundCookieSetForbidden", NetError: "NetError", ProxyError: "ProxyError", EmptySessionConfig: "EmptySessionConfig", InvalidCredentialsConfig: "InvalidCredentialsConfig", InvalidCredentialsType: "InvalidCredentialsType", InvalidCredentialsEmptyName: "InvalidCredentialsEmptyName", InvalidCredentialsCookie: "InvalidCredentialsCookie", PersistentHttpError: "PersistentHttpError", RegistrationAttemptedChallenge: "RegistrationAttemptedChallenge", InvalidScopeOrigin: "InvalidScopeOrigin", ScopeOriginContainsPath: "ScopeOriginContainsPath", RefreshInitiatorNotString: "RefreshInitiatorNotString", RefreshInitiatorInvalidHostPattern: "RefreshInitiatorInvalidHostPattern", InvalidScopeSpecification: "InvalidScopeSpecification", MissingScopeSpecificationType: "MissingScopeSpecificationType", EmptyScopeSpecificationDomain: "EmptyScopeSpecificationDomain", EmptyScopeSpecificationPath: "EmptyScopeSpecificationPath", InvalidScopeSpecificationType: "InvalidScopeSpecificationType", InvalidScopeIncludeSite: "InvalidScopeIncludeSite", MissingScopeIncludeSite: "MissingScopeIncludeSite", FederatedNotAuthorizedByProvider: "FederatedNotAuthorizedByProvider", FederatedNotAuthorizedByRelyingParty: "FederatedNotAuthorizedByRelyingParty", SessionProviderWellKnownMalformed: "SessionProviderWellKnownMalformed", SessionProviderWellKnownHasProviderOrigin: "SessionProviderWellKnownHasProviderOrigin", RelyingPartyWellKnownMalformed: "RelyingPartyWellKnownMalformed", RelyingPartyWellKnownHasRelyingOrigins: "RelyingPartyWellKnownHasRelyingOrigins", InvalidFederatedSessionProviderSessionMissing: "InvalidFederatedSessionProviderSessionMissing", InvalidFederatedSessionWrongProviderOrigin: "InvalidFederatedSessionWrongProviderOrigin", InvalidCredentialsCookieCreationTime: "InvalidCredentialsCookieCreationTime", InvalidCredentialsCookieName: "InvalidCredentialsCookieName", InvalidCredentialsCookieParsing: "InvalidCredentialsCookieParsing", InvalidCredentialsCookieUnpermittedAttribute: "InvalidCredentialsCookieUnpermittedAttribute", InvalidCredentialsCookieInvalidDomain: "InvalidCredentialsCookieInvalidDomain", InvalidCredentialsCookiePrefix: "InvalidCredentialsCookiePrefix", InvalidScopeRulePath: "InvalidScopeRulePath", InvalidScopeRuleHostPattern: "InvalidScopeRuleHostPattern", ScopeRuleOriginScopedHostPatternMismatch: "ScopeRuleOriginScopedHostPatternMismatch", ScopeRuleSiteScopedHostPatternMismatch: "ScopeRuleSiteScopedHostPatternMismatch", SigningQuotaExceeded: "SigningQuotaExceeded", InvalidConfigJson: "InvalidConfigJson", InvalidFederatedSessionProviderFailedToRestoreKey: "InvalidFederatedSessionProviderFailedToRestoreKey", FailedToUnwrapKey: "FailedToUnwrapKey", SessionDeletedDuringRefresh: "SessionDeletedDuringRefresh", CrossOriginRegistrationSiteNotIncluded: "CrossOriginRegistrationSiteNotIncluded", InvalidPreProvisionedKeyInitiatorMissing: "InvalidPreProvisionedKeyInitiatorMissing", PreProvisionedKeyAccessNotGranted: "PreProvisionedKeyAccessNotGranted", PreProvisionedKeyNotFound: "PreProvisionedKeyNotFound", AttestationCertificationError: "AttestationCertificationError", AttestationSigningError: "AttestationSigningError", FederatedRegistrationRedirected: "FederatedRegistrationRedirected"});
842
842
  inspectorBackend.registerEnum("Network.RefreshEventDetailsRefreshResult", {Refreshed: "Refreshed", InitializedService: "InitializedService", Unreachable: "Unreachable", ServerError: "ServerError", FatalError: "FatalError", SigningQuotaExceeded: "SigningQuotaExceeded", RefreshedAsWaiter: "RefreshedAsWaiter", TransientSigningError: "TransientSigningError", InScopeRefreshNotYetNeeded: "InScopeRefreshNotYetNeeded", Canceled: "Canceled"});
843
843
  inspectorBackend.registerEnum("Network.TerminationEventDetailsDeletionReason", {Expired: "Expired", FailedToRestoreKey: "FailedToRestoreKey", FailedToUnwrapKey: "FailedToUnwrapKey", StoragePartitionCleared: "StoragePartitionCleared", ClearBrowsingData: "ClearBrowsingData", ServerRequested: "ServerRequested", InvalidSessionParams: "InvalidSessionParams", RefreshFatalError: "RefreshFatalError", DevTools: "DevTools", Replaced: "Replaced"});
844
844
  inspectorBackend.registerEnum("Network.ChallengeEventDetailsChallengeResult", {Success: "Success", NoSessionId: "NoSessionId", NoSessionMatch: "NoSessionMatch", CantSetBoundCookie: "CantSetBoundCookie"});
@@ -867,8 +867,8 @@ inspectorBackend.registerEvent("Network.directTCPSocketAborted", ["identifier",
867
867
  inspectorBackend.registerEvent("Network.directTCPSocketClosed", ["identifier", "timestamp"]);
868
868
  inspectorBackend.registerEvent("Network.directTCPSocketChunkSent", ["identifier", "data", "timestamp"]);
869
869
  inspectorBackend.registerEvent("Network.directTCPSocketChunkReceived", ["identifier", "data", "timestamp"]);
870
- inspectorBackend.registerEvent("Network.directUDPSocketJoinedMulticastGroup", ["identifier", "IPAddress"]);
871
- inspectorBackend.registerEvent("Network.directUDPSocketLeftMulticastGroup", ["identifier", "IPAddress"]);
870
+ inspectorBackend.registerEvent("Network.directUDPSocketJoinedMulticastGroup", ["identifier", "IPAddress", "sourceAddress"]);
871
+ inspectorBackend.registerEvent("Network.directUDPSocketLeftMulticastGroup", ["identifier", "IPAddress", "sourceAddress"]);
872
872
  inspectorBackend.registerEvent("Network.directUDPSocketCreated", ["identifier", "options", "timestamp", "initiator"]);
873
873
  inspectorBackend.registerEvent("Network.directUDPSocketOpened", ["identifier", "localAddr", "localPort", "timestamp", "remoteAddr", "remotePort"]);
874
874
  inspectorBackend.registerEvent("Network.directUDPSocketAborted", ["identifier", "errorMessage", "timestamp"]);
@@ -12249,6 +12249,7 @@ export namespace Network {
12249
12249
  PreProvisionedKeyNotFound = 'PreProvisionedKeyNotFound',
12250
12250
  AttestationCertificationError = 'AttestationCertificationError',
12251
12251
  AttestationSigningError = 'AttestationSigningError',
12252
+ FederatedRegistrationRedirected = 'FederatedRegistrationRedirected',
12252
12253
  }
12253
12254
 
12254
12255
  /**
@@ -13395,12 +13396,28 @@ export namespace Network {
13395
13396
 
13396
13397
  export interface DirectUDPSocketJoinedMulticastGroupEvent {
13397
13398
  identifier: RequestId;
13399
+ /**
13400
+ * Multicast group address.
13401
+ */
13398
13402
  IPAddress: string;
13403
+ /**
13404
+ * Source address of a source-specific multicast (SSM) membership. Absent
13405
+ * for any-source multicast (ASM) memberships.
13406
+ */
13407
+ sourceAddress?: string;
13399
13408
  }
13400
13409
 
13401
13410
  export interface DirectUDPSocketLeftMulticastGroupEvent {
13402
13411
  identifier: RequestId;
13412
+ /**
13413
+ * Multicast group address.
13414
+ */
13403
13415
  IPAddress: string;
13416
+ /**
13417
+ * Source address of a source-specific multicast (SSM) membership. Absent
13418
+ * for any-source multicast (ASM) memberships.
13419
+ */
13420
+ sourceAddress?: string;
13404
13421
  }
13405
13422
 
13406
13423
  /**
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: lighthouse
3
- description: Analyzing an active Lighthouse report context, running Lighthouse reports and audits (performance, accessibility, best practices, Search Engine Optimization (SEO)), accessibility audits, ARIA properties, accessible tree inspection, color contrast, and screen reader semantics. Not for general page performance measurement without a Lighthouse report; use the performance skill for that.
3
+ description: Analyzing an active Lighthouse report context, running Lighthouse reports and audits (performance, accessibility, best practices, Search Engine Optimization (SEO), and agentic browsing when explicitly requested), accessibility audits, ARIA properties, accessible tree inspection, color contrast, and screen reader semantics. Not for general page performance measurement without a Lighthouse report; use the performance skill for that.
4
4
  allowed-tools:
5
5
  - runLighthouse
6
6
  - getLighthouseAudits
@@ -22,6 +22,7 @@ Your role is to evaluate websites using Lighthouse audits across performance, ac
22
22
  - If no active report exists or a fresh audit is requested, call `runLighthouse`:
23
23
  - If the user asks for a general report or multiple categories, use `categoryId: 'all'`.
24
24
  - For a single category, pass that category ID (e.g. `'accessibility'`).
25
+ - Only pass `categoryId: 'agentic-browsing'` when the user explicitly asks for an agentic browsing audit, such as how ready the page is for AI agents to navigate and use it, or WebMCP checks. `'all'` does not include it, so never pick it for general audits, and never substitute another category (such as `'seo'`) when the user asks for it. Use `"navigation"` mode for `'agentic-browsing'` unless the user explicitly asks for another mode, because its WebMCP audits only run in `"navigation"` mode.
25
26
  - Execution mode:
26
27
  - Use `"navigation"` mode for full page-load audits (default for full site reviews).
27
28
  - Use `"snapshot"` mode to re-evaluate live in-page DOM/CSS modifications without reloading.
@@ -20,3 +20,4 @@ You are an expert network request debugging assistant.
20
20
 
21
21
  * **Privacy**: If the request or response payload contains sensitive personal data, authorization tokens, or API secrets, redact or generalize it in your response.
22
22
  * **Origin Lock**: Only requests belonging to the conversation's established origin can be inspected.
23
+ * **Recording**: DevTools only records requests made while DevTools is open and network recording is enabled (and the log has not been cleared). If `listNetworkRequests` reports that no requests have been recorded, ask the user to ensure network recording is enabled, reload the page or repeat the action that triggers the request, and try again.
@@ -31,6 +31,24 @@ const MAX_TOTAL_CHARACTERS = 2500;
31
31
  const MAX_LONG_LINES_REPORTED = 3;
32
32
  const LONG_LINE_PREVIEW_LENGTH = 60;
33
33
 
34
+ /**
35
+ * Matches the error observations for network requests that the isolated
36
+ * world's CSP (`FREESTYLER_WORLD_CSP`) blocks. When code run by this tool calls
37
+ * `fetch()`, Chrome rejects with exactly "Failed to fetch". A synchronous
38
+ * `XMLHttpRequest.send()` throws "Failed to execute 'send' on 'XMLHttpRequest':
39
+ * Failed to load '<url>'.".
40
+ */
41
+ const BLOCKED_NETWORK_ERROR_PATTERN =
42
+ /^Error: (?:Failed to fetch$|Failed to execute 'send' on 'XMLHttpRequest': Failed to load )/;
43
+ const BLOCKED_NETWORK_HINT =
44
+ 'Network access (e.g., fetch, XMLHttpRequest) is blocked for JavaScript run by this tool, so this error does not mean the page\'s own network requests are failing. Do not retry network requests with this tool.';
45
+ /**
46
+ * Only the V2 agent can load the network tools, so V1 agents do not get this
47
+ * part of the hint.
48
+ */
49
+ const NETWORK_TOOLS_HINT =
50
+ 'To inspect the page\'s network requests, load the `network` skill with `learnSkills` if it is not loaded yet, then use `listNetworkRequests` and `getNetworkRequestDetails`.';
51
+
34
52
  /**
35
53
  * Returns one message per size limit that the formatted code exceeds. Each
36
54
  * message states the actual value, the limit, and how to fix it, so the model
@@ -178,7 +196,8 @@ const data = {
178
196
  return {error: 'Error: Cannot execute JavaScript on cross-origin target.'};
179
197
  }
180
198
 
181
- if (Root.Runtime.hostConfig.devToolsAiV2Architecture?.enabled) {
199
+ const isV2Architecture = Root.Runtime.hostConfig.devToolsAiV2Architecture?.enabled;
200
+ if (isV2Architecture) {
182
201
  const validationResult = await ExecuteJavaScriptTool.validateAndFormatCode(params.code);
183
202
  if (validationResult.error) {
184
203
  return {error: validationResult.error};
@@ -199,6 +218,11 @@ const data = {
199
218
  },
200
219
  context.execJs);
201
220
 
202
- return await executor.executeAction(params.code, options);
221
+ const result = await executor.executeAction(params.code, options);
222
+ if ('result' in result && typeof result.result === 'string' && BLOCKED_NETWORK_ERROR_PATTERN.test(result.result)) {
223
+ const hint = isV2Architecture ? `${BLOCKED_NETWORK_HINT} ${NETWORK_TOOLS_HINT}` : BLOCKED_NETWORK_HINT;
224
+ return {...result, result: `${result.result}\n${hint}`};
225
+ }
226
+ return result;
203
227
  }
204
228
  }
@@ -34,7 +34,7 @@ export class GetLighthouseAuditsTool implements
34
34
  categoryId: {
35
35
  type: Host.AidaClient.ParametersTypes.STRING,
36
36
  description:
37
- 'The category of audits to retrieve. Use "all" to retrieve the full report and all categories, or specify a category: "accessibility", "performance", "best-practices", "seo".',
37
+ 'The category of audits to retrieve. Use "all" to retrieve the full report and all categories, or specify a category: "accessibility", "performance", "best-practices", "seo", or "agentic-browsing" (only present when the active report includes an agentic browsing audit).',
38
38
  nullable: false,
39
39
  },
40
40
  },