chrome-devtools-frontend 1.0.1616061 → 1.0.1621064

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 (318) hide show
  1. package/AUTHORS +1 -0
  2. package/docs/checklist/README.md +8 -7
  3. package/eslint.config.mjs +7 -0
  4. package/front_end/core/common/Object.ts +11 -2
  5. package/front_end/core/dom_extension/DOMExtension.ts +11 -8
  6. package/front_end/core/host/AidaClient.ts +8 -0
  7. package/front_end/core/host/AidaGcaTranslation.ts +1 -0
  8. package/front_end/core/host/UserMetrics.ts +0 -1
  9. package/front_end/core/platform/api/HostRuntime.ts +2 -2
  10. package/front_end/core/platform/browser/HostRuntime.ts +4 -2
  11. package/front_end/core/platform/node/HostRuntime.ts +2 -2
  12. package/front_end/core/root/ExperimentNames.ts +0 -1
  13. package/front_end/core/sdk/NetworkManager.ts +30 -4
  14. package/front_end/core/sdk/NetworkRequest.ts +2 -10
  15. package/front_end/core/sdk/Resource.ts +2 -1
  16. package/front_end/core/sdk/ServerSentEventsProtocol.ts +1 -1
  17. package/front_end/core/sdk/TraceObject.ts +7 -2
  18. package/front_end/entrypoint_template.html +1 -2
  19. package/front_end/entrypoints/greendev_floaty/FloatyEntrypoint.ts +119 -15
  20. package/front_end/entrypoints/greendev_floaty/greendev_floaty.ts +0 -2
  21. package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +43 -33
  22. package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshotLoader.ts +2 -1
  23. package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshotWorkerDispatcher.ts +9 -6
  24. package/front_end/entrypoints/main/MainImpl.ts +0 -2
  25. package/front_end/generated/InspectorBackendCommands.ts +8 -7
  26. package/front_end/generated/SupportedCSSProperties.js +119 -100
  27. package/front_end/generated/protocol-mapping.d.ts +1 -9
  28. package/front_end/generated/protocol-proxy-api.d.ts +1 -9
  29. package/front_end/generated/protocol.ts +24 -1
  30. package/front_end/legacy/legacy-defs.d.ts +1 -1
  31. package/front_end/models/ai_assistance/AiConversation.ts +1 -0
  32. package/front_end/models/ai_assistance/AiHistoryStorage.ts +39 -0
  33. package/front_end/models/ai_assistance/agents/AiAgent.ts +2 -0
  34. package/front_end/models/ai_assistance/agents/ConversationSummaryAgent.ts +28 -16
  35. package/front_end/models/ai_assistance/agents/GreenDevAgent.ts +512 -0
  36. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +112 -145
  37. package/front_end/models/ai_assistance/agents/README.md +0 -5
  38. package/front_end/models/ai_assistance/agents/StylingAgent.ts +9 -16
  39. package/front_end/models/ai_assistance/ai_assistance.ts +2 -0
  40. package/front_end/models/ai_code_completion/AiCodeCompletion.ts +19 -1
  41. package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +48 -13
  42. package/front_end/models/bindings/SymbolizedError.ts +95 -8
  43. package/front_end/models/emulation/DeviceModeModel.ts +42 -13
  44. package/front_end/models/emulation/EmulatedDevices.ts +1 -1
  45. package/front_end/models/issues_manager/IssuesManager.ts +13 -6
  46. package/front_end/models/issues_manager/IssuesManagerEvents.ts +1 -0
  47. package/front_end/models/javascript_metadata/NativeFunctions.js +2 -2
  48. package/front_end/models/live-metrics/web-vitals-injected/web-vitals-injected.ts +1 -0
  49. package/front_end/models/stack_trace/DetailedErrorStackParser.ts +49 -10
  50. package/front_end/models/stack_trace/ErrorStackParser.ts +18 -0
  51. package/front_end/models/stack_trace/StackTraceModel.ts +5 -1
  52. package/front_end/models/text_utils/ContentData.ts +71 -10
  53. package/front_end/models/trace/types/File.ts +8 -1
  54. package/front_end/models/web_mcp/WebMCPModel.ts +22 -0
  55. package/front_end/models/workspace/UISourceCode.ts +4 -4
  56. package/front_end/panels/accessibility/ARIAAttributesView.ts +4 -4
  57. package/front_end/panels/accessibility/AccessibilitySubPane.ts +3 -2
  58. package/front_end/panels/accessibility/SourceOrderView.ts +4 -4
  59. package/front_end/panels/ai_assistance/ai_assistance.ts +1 -0
  60. package/front_end/panels/ai_assistance/components/ChatInput.ts +66 -0
  61. package/front_end/panels/ai_assistance/components/ChatMessage.ts +144 -21
  62. package/front_end/panels/ai_assistance/components/ChatView.ts +43 -8
  63. package/front_end/panels/ai_assistance/components/ExportForAgentsDialog.ts +1 -0
  64. package/front_end/panels/ai_assistance/components/WalkthroughUtils.ts +74 -0
  65. package/front_end/panels/ai_assistance/components/WalkthroughView.ts +34 -5
  66. package/front_end/panels/ai_assistance/components/chatMessage.css +11 -0
  67. package/front_end/panels/ai_assistance/components/walkthroughView.css +7 -0
  68. package/front_end/panels/application/ApplicationPanelTreeElement.ts +1 -1
  69. package/front_end/panels/application/CookieItemsView.ts +8 -9
  70. package/front_end/panels/application/DOMStorageItemsView.ts +3 -3
  71. package/front_end/panels/application/DeviceBoundSessionsModel.ts +7 -0
  72. package/front_end/panels/application/DeviceBoundSessionsTreeElement.ts +21 -0
  73. package/front_end/panels/application/DeviceBoundSessionsView.ts +2 -2
  74. package/front_end/panels/application/ExtensionStorageItemsView.ts +1 -1
  75. package/front_end/panels/application/KeyValueStorageItemsView.ts +32 -14
  76. package/front_end/panels/application/ResourcesPanel.ts +5 -5
  77. package/front_end/panels/application/StorageItemsToolbar.ts +0 -19
  78. package/front_end/panels/application/WebMCPView.ts +285 -86
  79. package/front_end/panels/application/components/BounceTrackingMitigationsView.ts +4 -4
  80. package/front_end/panels/application/preloading/components/MismatchedPreloadingGrid.ts +4 -4
  81. package/front_end/panels/application/webMCPView.css +261 -182
  82. package/front_end/panels/browser_debugger/CategorizedBreakpointsSidebarPane.ts +9 -5
  83. package/front_end/panels/changes/ChangesSidebar.ts +2 -2
  84. package/front_end/panels/changes/ChangesView.ts +9 -14
  85. package/front_end/panels/console/ConsolePanel.ts +10 -3
  86. package/front_end/panels/console/ConsoleSidebar.ts +5 -5
  87. package/front_end/panels/console/ConsoleView.ts +11 -4
  88. package/front_end/panels/console/ConsoleViewMessage.ts +1 -19
  89. package/front_end/panels/coverage/CoverageView.ts +4 -5
  90. package/front_end/panels/elements/ElementsPanel.ts +9 -12
  91. package/front_end/panels/elements/ElementsSidebarPane.ts +4 -5
  92. package/front_end/panels/elements/ElementsTreeElement.ts +61 -0
  93. package/front_end/panels/elements/ElementsTreeOutline.ts +46 -0
  94. package/front_end/panels/elements/LayersWidget.ts +2 -2
  95. package/front_end/panels/elements/MetricsSidebarPane.ts +5 -4
  96. package/front_end/panels/elements/StylePropertiesSection.ts +1 -1
  97. package/front_end/panels/elements/StylePropertyTreeElement.ts +11 -6
  98. package/front_end/panels/elements/StylesSidebarPane.ts +4 -1
  99. package/front_end/panels/elements/components/ElementsBreadcrumbs.ts +19 -20
  100. package/front_end/panels/elements/components/ElementsBreadcrumbsUtils.ts +29 -29
  101. package/front_end/panels/elements/components/QueryContainer.ts +5 -6
  102. package/front_end/panels/elements/components/components.ts +0 -2
  103. package/front_end/panels/emulation/MediaQueryInspector.ts +4 -7
  104. package/front_end/panels/layer_viewer/LayerDetailsView.ts +4 -7
  105. package/front_end/panels/layer_viewer/Layers3DView.ts +2 -2
  106. package/front_end/panels/lighthouse/LighthouseStartView.ts +2 -2
  107. package/front_end/panels/mobile_throttling/NetworkThrottlingSelector.ts +47 -66
  108. package/front_end/panels/network/NetworkConfigView.ts +11 -11
  109. package/front_end/panels/network/RequestConditionsDrawer.ts +6 -4
  110. package/front_end/panels/network/RequestCookiesView.ts +2 -2
  111. package/front_end/panels/network/RequestDeviceBoundSessionsView.ts +2 -2
  112. package/front_end/panels/network/RequestHeadersView.ts +2 -2
  113. package/front_end/panels/network/components/DirectSocketConnectionView.ts +4 -5
  114. package/front_end/panels/performance_monitor/PerformanceMonitor.ts +6 -9
  115. package/front_end/panels/profiler/HeapProfileView.ts +29 -4
  116. package/front_end/panels/profiler/ProfilesPanel.ts +1 -1
  117. package/front_end/panels/protocol_monitor/JSONEditor.css +8 -1
  118. package/front_end/panels/protocol_monitor/JSONEditor.ts +7 -2
  119. package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +6 -4
  120. package/front_end/panels/recorder/components/ControlButton.ts +4 -4
  121. package/front_end/panels/recorder/components/StepView.ts +6 -6
  122. package/front_end/panels/search/SearchView.ts +4 -7
  123. package/front_end/panels/sources/DebuggerPausedMessage.ts +18 -22
  124. package/front_end/panels/sources/SourcesView.ts +1 -1
  125. package/front_end/panels/sources/TabbedEditorContainer.ts +2 -2
  126. package/front_end/panels/sources/ThreadsSidebarPane.ts +2 -4
  127. package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +24 -20
  128. package/front_end/panels/timeline/StatusDialog.ts +5 -8
  129. package/front_end/panels/timeline/ThirdPartyTreeView.ts +10 -0
  130. package/front_end/panels/timeline/TimelineLoader.ts +3 -4
  131. package/front_end/panels/timeline/TimelineSelectorStatsView.ts +2 -2
  132. package/front_end/panels/timeline/components/TimelineRangeSummaryView.ts +2 -0
  133. package/front_end/panels/timeline/components/TimelineSummary.ts +9 -1
  134. package/front_end/panels/timeline/components/timelineSummary.css +4 -0
  135. package/front_end/panels/timeline/overlays/components/TimespanBreakdownOverlay.ts +2 -2
  136. package/front_end/panels/timeline/thirdPartyTreeView.css +8 -1
  137. package/front_end/panels/web_audio/WebAudioView.ts +5 -4
  138. package/front_end/panels/whats_new/ReleaseNoteText.ts +9 -9
  139. package/front_end/panels/whats_new/resources/WNDT.md +9 -6
  140. package/front_end/third_party/chromium/README.chromium +1 -1
  141. package/front_end/third_party/puppeteer/README.chromium +2 -2
  142. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/ElementHandle.d.ts +41 -2
  143. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/ElementHandle.d.ts.map +1 -1
  144. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/ElementHandle.js.map +1 -1
  145. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Extension.d.ts +13 -1
  146. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Extension.d.ts.map +1 -1
  147. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Extension.js +21 -1
  148. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Extension.js.map +1 -1
  149. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/ElementHandle.d.ts.map +1 -1
  150. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/ElementHandle.js +1 -0
  151. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/ElementHandle.js.map +1 -1
  152. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts +2 -2
  153. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts.map +1 -1
  154. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js +5 -5
  155. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js.map +1 -1
  156. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserConnector.d.ts.map +1 -1
  157. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserConnector.js +2 -2
  158. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserConnector.js.map +1 -1
  159. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/ElementHandle.d.ts.map +1 -1
  160. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/ElementHandle.js +1 -0
  161. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/ElementHandle.js.map +1 -1
  162. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Extension.d.ts +1 -1
  163. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Extension.d.ts.map +1 -1
  164. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Extension.js +2 -2
  165. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Extension.js.map +1 -1
  166. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/TargetManager.d.ts +1 -1
  167. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/TargetManager.d.ts.map +1 -1
  168. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/TargetManager.js +52 -1
  169. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/TargetManager.js.map +1 -1
  170. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/WebMCP.d.ts.map +1 -1
  171. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/WebMCP.js.map +1 -1
  172. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/ConnectOptions.d.ts +25 -0
  173. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/ConnectOptions.d.ts.map +1 -1
  174. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
  175. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/BrowserLauncher.d.ts.map +1 -1
  176. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/BrowserLauncher.js +2 -2
  177. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/BrowserLauncher.js.map +1 -1
  178. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/ChromeLauncher.d.ts.map +1 -1
  179. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/ChromeLauncher.js +0 -1
  180. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/ChromeLauncher.js.map +1 -1
  181. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +2 -2
  182. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +2 -2
  183. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
  184. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
  185. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
  186. package/front_end/third_party/puppeteer/package/lib/cjs/third_party/urlpattern-polyfill/urlpattern-polyfill.d.ts +1 -0
  187. package/front_end/third_party/puppeteer/package/lib/cjs/third_party/urlpattern-polyfill/urlpattern-polyfill.js +853 -0
  188. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +91 -11
  189. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +1046 -33
  190. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/ElementHandle.d.ts +41 -2
  191. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/ElementHandle.d.ts.map +1 -1
  192. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/ElementHandle.js.map +1 -1
  193. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Extension.d.ts +13 -1
  194. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Extension.d.ts.map +1 -1
  195. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Extension.js +21 -1
  196. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Extension.js.map +1 -1
  197. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/ElementHandle.d.ts.map +1 -1
  198. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/ElementHandle.js +1 -0
  199. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/ElementHandle.js.map +1 -1
  200. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts +2 -2
  201. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts.map +1 -1
  202. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js +5 -5
  203. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js.map +1 -1
  204. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserConnector.d.ts.map +1 -1
  205. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserConnector.js +2 -2
  206. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserConnector.js.map +1 -1
  207. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/ElementHandle.d.ts.map +1 -1
  208. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/ElementHandle.js +1 -0
  209. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/ElementHandle.js.map +1 -1
  210. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Extension.d.ts +1 -1
  211. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Extension.d.ts.map +1 -1
  212. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Extension.js +2 -2
  213. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Extension.js.map +1 -1
  214. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/TargetManager.d.ts +1 -1
  215. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/TargetManager.d.ts.map +1 -1
  216. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/TargetManager.js +52 -1
  217. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/TargetManager.js.map +1 -1
  218. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/WebMCP.d.ts.map +1 -1
  219. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/WebMCP.js.map +1 -1
  220. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/ConnectOptions.d.ts +25 -0
  221. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/ConnectOptions.d.ts.map +1 -1
  222. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/injected/injected.d.ts +1 -1
  223. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/BrowserLauncher.d.ts.map +1 -1
  224. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/BrowserLauncher.js +2 -2
  225. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/BrowserLauncher.js.map +1 -1
  226. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/ChromeLauncher.d.ts.map +1 -1
  227. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/ChromeLauncher.js +0 -1
  228. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/ChromeLauncher.js.map +1 -1
  229. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +2 -2
  230. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +2 -2
  231. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/Mutex.d.ts +2 -2
  232. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
  233. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
  234. package/front_end/third_party/puppeteer/package/lib/esm/third_party/urlpattern-polyfill/urlpattern-polyfill.d.ts +1 -0
  235. package/front_end/third_party/puppeteer/package/lib/esm/third_party/urlpattern-polyfill/urlpattern-polyfill.js +805 -0
  236. package/front_end/third_party/puppeteer/package/lib/types.d.ts +91 -11
  237. package/front_end/third_party/puppeteer/package/package.json +3 -2
  238. package/front_end/third_party/puppeteer/package/src/api/ElementHandle.ts +53 -11
  239. package/front_end/third_party/puppeteer/package/src/api/Extension.ts +29 -1
  240. package/front_end/third_party/puppeteer/package/src/bidi/ElementHandle.ts +1 -0
  241. package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +6 -0
  242. package/front_end/third_party/puppeteer/package/src/cdp/BrowserConnector.ts +2 -0
  243. package/front_end/third_party/puppeteer/package/src/cdp/ElementHandle.ts +1 -0
  244. package/front_end/third_party/puppeteer/package/src/cdp/Extension.ts +9 -2
  245. package/front_end/third_party/puppeteer/package/src/cdp/TargetManager.ts +59 -0
  246. package/front_end/third_party/puppeteer/package/src/cdp/WebMCP.ts +6 -1
  247. package/front_end/third_party/puppeteer/package/src/common/ConnectOptions.ts +26 -0
  248. package/front_end/third_party/puppeteer/package/src/node/BrowserLauncher.ts +2 -0
  249. package/front_end/third_party/puppeteer/package/src/node/ChromeLauncher.ts +0 -1
  250. package/front_end/third_party/puppeteer/package/src/revisions.ts +2 -2
  251. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  252. package/front_end/third_party/puppeteer/puppeteer-tsconfig.json +2 -1
  253. package/front_end/third_party/web-vitals/README.chromium +2 -2
  254. package/front_end/third_party/web-vitals/package/README.md +21 -10
  255. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onCLS.js +2 -4
  256. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onFCP.js +1 -2
  257. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onINP.d.ts +4 -0
  258. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onINP.js +44 -39
  259. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onLCP.js +25 -19
  260. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onTTFB.js +1 -2
  261. package/front_end/third_party/web-vitals/package/dist/modules/lib/doubleRAF.js +1 -1
  262. package/front_end/third_party/web-vitals/package/dist/modules/lib/getActivationStart.js +1 -2
  263. package/front_end/third_party/web-vitals/package/dist/modules/lib/getLoadState.js +16 -18
  264. package/front_end/third_party/web-vitals/package/dist/modules/lib/getVisibilityWatcher.js +2 -1
  265. package/front_end/third_party/web-vitals/package/dist/modules/lib/initMetric.d.ts +1 -1
  266. package/front_end/third_party/web-vitals/package/dist/modules/lib/observe.js +1 -1
  267. package/front_end/third_party/web-vitals/package/dist/modules/lib/polyfills/interactionCountPolyfill.d.ts +1 -1
  268. package/front_end/third_party/web-vitals/package/dist/modules/lib/polyfills/interactionCountPolyfill.js +1 -3
  269. package/front_end/third_party/web-vitals/package/dist/modules/lib/whenActivated.js +1 -1
  270. package/front_end/third_party/web-vitals/package/dist/modules/lib/whenIdleOrHidden.js +11 -7
  271. package/front_end/third_party/web-vitals/package/dist/modules/onCLS.js +1 -1
  272. package/front_end/third_party/web-vitals/package/dist/modules/types/inp.d.ts +4 -0
  273. package/front_end/third_party/web-vitals/package/dist/modules/types.d.ts +1 -2
  274. package/front_end/third_party/web-vitals/package/dist/modules/types.js +0 -1
  275. package/front_end/third_party/web-vitals/package/package.json +24 -27
  276. package/front_end/third_party/web-vitals/package/src/attribution/onCLS.ts +2 -7
  277. package/front_end/third_party/web-vitals/package/src/attribution/onFCP.ts +1 -2
  278. package/front_end/third_party/web-vitals/package/src/attribution/onINP.ts +49 -43
  279. package/front_end/third_party/web-vitals/package/src/attribution/onLCP.ts +27 -24
  280. package/front_end/third_party/web-vitals/package/src/attribution/onTTFB.ts +1 -2
  281. package/front_end/third_party/web-vitals/package/src/lib/doubleRAF.ts +1 -1
  282. package/front_end/third_party/web-vitals/package/src/lib/getActivationStart.ts +1 -2
  283. package/front_end/third_party/web-vitals/package/src/lib/getLoadState.ts +21 -20
  284. package/front_end/third_party/web-vitals/package/src/lib/getVisibilityWatcher.ts +2 -3
  285. package/front_end/third_party/web-vitals/package/src/lib/observe.ts +1 -1
  286. package/front_end/third_party/web-vitals/package/src/lib/polyfills/interactionCountPolyfill.ts +2 -4
  287. package/front_end/third_party/web-vitals/package/src/lib/whenActivated.ts +1 -1
  288. package/front_end/third_party/web-vitals/package/src/lib/whenIdleOrHidden.ts +13 -7
  289. package/front_end/third_party/web-vitals/package/src/onCLS.ts +1 -1
  290. package/front_end/third_party/web-vitals/package/src/types/inp.ts +4 -0
  291. package/front_end/third_party/web-vitals/package/src/types.ts +1 -2
  292. package/front_end/third_party/web-vitals/patches/0001-Add-onEachInteraction-to-onINP-options.patch +13 -74
  293. package/front_end/third_party/web-vitals/rebuild.sh +3 -3
  294. package/front_end/third_party/web-vitals/web-vitals-tsconfig.json +0 -1
  295. package/front_end/ui/components/icon_button/iconButton.css +1 -0
  296. package/front_end/ui/components/legacy_wrapper/LegacyWrapper.ts +6 -6
  297. package/front_end/ui/components/lists/list.css +4 -0
  298. package/front_end/ui/legacy/Dialog.ts +21 -2
  299. package/front_end/ui/legacy/SoftContextMenu.ts +3 -3
  300. package/front_end/ui/legacy/SplitWidget.ts +9 -9
  301. package/front_end/ui/legacy/TabbedPane.ts +12 -12
  302. package/front_end/ui/legacy/View.ts +24 -22
  303. package/front_end/ui/legacy/ViewManager.ts +12 -12
  304. package/front_end/ui/legacy/ViewRegistration.ts +2 -2
  305. package/front_end/ui/legacy/Widget.ts +165 -119
  306. package/front_end/ui/legacy/components/source_frame/ImageView.ts +10 -5
  307. package/front_end/ui/legacy/components/utils/JSPresentationUtils.ts +9 -6
  308. package/front_end/ui/legacy/components/utils/Linkifier.ts +37 -11
  309. package/front_end/ui/legacy/components/utils/jsUtils.css +1 -0
  310. package/front_end/ui/legacy/inspectorCommon.css +0 -6
  311. package/front_end/ui/lit/render.ts +11 -9
  312. package/front_end/ui/visual_logging/KnownContextValues.ts +36 -0
  313. package/package.json +1 -1
  314. package/front_end/Images/src/dots-circle.svg +0 -10
  315. package/front_end/panels/elements/components/Helper.ts +0 -35
  316. package/front_end/third_party/web-vitals/package/dist/modules/types/polyfills.d.ts +0 -4
  317. package/front_end/third_party/web-vitals/package/dist/modules/types/polyfills.js +0 -16
  318. package/front_end/third_party/web-vitals/package/src/types/polyfills.ts +0 -24
@@ -2,6 +2,8 @@
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 type {JSONSchema7} from 'json-schema';
6
+
5
7
  import type * as Common from '../../core/common/common.js';
6
8
  import * as SDK from '../../core/sdk/sdk.js';
7
9
  import type * as ProtocolProxyApi from '../../generated/protocol-proxy-api.js';
@@ -115,6 +117,18 @@ export class Tool {
115
117
  return this.#protocolTool.description;
116
118
  }
117
119
 
120
+ get inputSchema(): JSONSchema7 {
121
+ let rawSchema = this.#protocolTool.inputSchema;
122
+ if (typeof rawSchema === 'string') {
123
+ try {
124
+ rawSchema = JSON.parse(rawSchema);
125
+ } catch {
126
+ rawSchema = {};
127
+ }
128
+ }
129
+ return (typeof rawSchema === 'object' && rawSchema !== null) ? rawSchema as JSONSchema7 : {};
130
+ }
131
+
118
132
  get frame(): SDK.ResourceTreeModel.ResourceTreeFrame|undefined {
119
133
  return this.#target.deref()
120
134
  ?.model(SDK.ResourceTreeModel.ResourceTreeModel)
@@ -131,6 +145,14 @@ export class Tool {
131
145
  return this.#protocolTool.backendNodeId && target &&
132
146
  new SDK.DOMModel.DeferredDOMNode(target, this.#protocolTool.backendNodeId);
133
147
  }
148
+
149
+ async invoke(input: unknown): Promise<Protocol.WebMCP.InvokeToolResponse|undefined> {
150
+ return await this.#target.deref()?.webMCPAgent().invoke_invokeTool({
151
+ toolName: this.name,
152
+ frameId: this.#protocolTool.frameId,
153
+ input,
154
+ });
155
+ }
134
156
  }
135
157
  export interface EventTypes {
136
158
  [Events.TOOLS_ADDED]: readonly Tool[];
@@ -508,8 +508,8 @@ export class UISourceCode extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
508
508
  return this.#disableEdit;
509
509
  }
510
510
 
511
- isIgnoreListed(): boolean {
512
- return IgnoreListManager.instance().isUserOrSourceMapIgnoreListedUISourceCode(this);
511
+ isIgnoreListed(ignoreListManager: IgnoreListManager = IgnoreListManager.instance()): boolean {
512
+ return ignoreListManager.isUserOrSourceMapIgnoreListedUISourceCode(this);
513
513
  }
514
514
  }
515
515
 
@@ -613,8 +613,8 @@ export class UILocation {
613
613
  return this.columnNumber - other.columnNumber;
614
614
  }
615
615
 
616
- isIgnoreListed(): boolean {
617
- return this.uiSourceCode.isIgnoreListed();
616
+ isIgnoreListed(ignoreListManager: IgnoreListManager = IgnoreListManager.instance()): boolean {
617
+ return this.uiSourceCode.isIgnoreListed(ignoreListManager);
618
618
  }
619
619
  }
620
620
 
@@ -37,7 +37,7 @@ interface ViewInput {
37
37
  attributes: SDK.DOMModel.Attribute[];
38
38
  }
39
39
 
40
- type View = (input: ViewInput, output: object, target: HTMLElement) => void;
40
+ type View = (input: ViewInput, output: object, target: HTMLElement|DocumentFragment) => void;
41
41
  export const DEFAULT_VIEW: View = (input, output, target) => {
42
42
  const MAX_CONTENT_LENGTH = 10000;
43
43
 
@@ -92,10 +92,10 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
92
92
  </ul>
93
93
  `}></devtools-tree>`,
94
94
  // clang-format on
95
- target);
95
+ target, {container: {attributes: {jslog: `${VisualLogging.section('aria-attributes')}`}}});
96
96
  };
97
97
 
98
- export class ARIAAttributesPane extends AccessibilitySubPane {
98
+ export class ARIAAttributesPane extends AccessibilitySubPane<ShadowRoot> {
99
99
  readonly #view: View;
100
100
  #attributeBeingEdited: SDK.DOMModel.Attribute|null = null;
101
101
 
@@ -103,7 +103,7 @@ export class ARIAAttributesPane extends AccessibilitySubPane {
103
103
  super({
104
104
  title: i18nString(UIStrings.ariaAttributes),
105
105
  viewId: 'aria-attributes',
106
- jslog: `${VisualLogging.section('aria-attributes')}`,
106
+ useShadowDom: 'pure',
107
107
  });
108
108
 
109
109
  this.#view = view;
@@ -11,11 +11,12 @@ import * as UI from '../../ui/legacy/legacy.js';
11
11
  import accessibilityNodeStyles from './accessibilityNode.css.js';
12
12
  import accessibilityPropertiesStyles from './accessibilityProperties.css.js';
13
13
 
14
- export class AccessibilitySubPane extends UI.View.SimpleView {
14
+ export class AccessibilitySubPane<ContentTypeT extends HTMLElement|DocumentFragment = HTMLElement> extends
15
+ UI.View.SimpleView<ContentTypeT> {
15
16
  axNode: SDK.AccessibilityModel.AccessibilityNode|null;
16
17
  protected nodeInternal?: SDK.DOMModel.DOMNode|null;
17
18
 
18
- constructor(options: UI.View.SimpleViewOptions) {
19
+ constructor(options: UI.View.SimpleViewOptions<ContentTypeT>) {
19
20
  super(options);
20
21
  this.registerRequiredCSS(accessibilityPropertiesStyles);
21
22
 
@@ -43,7 +43,7 @@ interface ViewInput {
43
43
  onShowSourceOrderChanged: (showSourceOrder: boolean) => void;
44
44
  }
45
45
 
46
- type View = (input: ViewInput, output: unknown, target: HTMLElement) => void;
46
+ type View = (input: ViewInput, output: unknown, target: HTMLElement|DocumentFragment) => void;
47
47
 
48
48
  const DEFAULT_VIEW: View = (input, _output, target) => {
49
49
  function onShowSourceOrderChanged(event: Event): void {
@@ -78,11 +78,11 @@ const DEFAULT_VIEW: View = (input, _output, target) => {
78
78
  </devtools-checkbox>
79
79
  `
80
80
  }
81
- `, target);
81
+ `, target, {container: {attributes: {jslog: `${VisualLogging.section('source-order-viewer')}`}}});
82
82
  // clang-format on
83
83
  };
84
84
 
85
- export class SourceOrderPane extends AccessibilitySubPane {
85
+ export class SourceOrderPane extends AccessibilitySubPane<ShadowRoot> {
86
86
  #childCount = 0;
87
87
  #showSourceOrder: boolean|undefined = undefined;
88
88
  readonly #view: View;
@@ -91,7 +91,7 @@ export class SourceOrderPane extends AccessibilitySubPane {
91
91
  super({
92
92
  title: i18nString(UIStrings.sourceOrderViewer),
93
93
  viewId: 'source-order-viewer',
94
- jslog: `${VisualLogging.section('source-order-viewer')}`,
94
+ useShadowDom: 'pure',
95
95
  });
96
96
  this.#view = view;
97
97
  }
@@ -14,5 +14,6 @@ export * as ExportForAgentsDialog from './components/ExportForAgentsDialog.js';
14
14
  export * as OptInChangeDialog from './components/OptInChangeDialog.js';
15
15
  export * as PatchWidget from './PatchWidget.js';
16
16
  export * as DisabledWidget from './components/DisabledWidget.js';
17
+ export * as WalkthroughUtils from './components/WalkthroughUtils.js';
17
18
  export * as WalkthroughView from './components/WalkthroughView.js';
18
19
  export * as ExportConversation from './ExportConversation.js';
@@ -507,10 +507,23 @@ export class ChatInput extends UI.Widget.Widget implements SDK.TargetManager.Obs
507
507
 
508
508
  #textAreaRef = createRef<HTMLTextAreaElement>();
509
509
  #imageInput?: ImageInputData;
510
+ /**
511
+ * Tracks the user's position when navigating through prompt history.
512
+ * -1 means the user is at the newest "uncommitted" position (the current input).
513
+ * 0 to N-1 are indices into the recent prompts array (newest to oldest).
514
+ */
515
+ #historyOffset = -1;
516
+ /**
517
+ * Stores the text the user had typed before they started navigating through history,
518
+ * so it can be restored if they navigate back to the newest position.
519
+ */
520
+ #uncommittedText = '';
510
521
 
511
522
  setInputValue(text: string): void {
512
523
  if (this.#textAreaRef.value) {
513
524
  this.#textAreaRef.value.value = text;
525
+ // Place the cursor at the end of the new value.
526
+ this.#textAreaRef.value.setSelectionRange(text.length, text.length);
514
527
  }
515
528
  this.performUpdate();
516
529
  }
@@ -529,6 +542,35 @@ export class ChatInput extends UI.Widget.Widget implements SDK.TargetManager.Obs
529
542
  onContextRemoved: (() => void)|null = null;
530
543
  onContextAdd: (() => void)|null = null;
531
544
 
545
+ /**
546
+ * Navigates the prompt history.
547
+ * @param dir direction to navigate. -1 for older, 1 for newer.
548
+ */
549
+ #navigatePromptHistory(dir: -1|1): void {
550
+ const prompts = AiAssistanceModel.AiHistoryStorage.AiHistoryStorage.instance().getRecentPrompts();
551
+ if (!prompts.length) {
552
+ return;
553
+ }
554
+
555
+ if (dir === -1) {
556
+ // ArrowUp
557
+ if (this.#historyOffset === -1) {
558
+ this.#uncommittedText = this.#textAreaRef.value?.value || '';
559
+ }
560
+ if (this.#historyOffset < prompts.length - 1) {
561
+ this.#historyOffset++;
562
+ this.setInputValue(prompts[this.#historyOffset]);
563
+ }
564
+ } else if (this.#historyOffset > 0) {
565
+ // ArrowDown
566
+ this.#historyOffset--;
567
+ this.setInputValue(prompts[this.#historyOffset]);
568
+ } else if (this.#historyOffset === 0) {
569
+ this.#historyOffset = -1;
570
+ this.setInputValue(this.#uncommittedText);
571
+ }
572
+ }
573
+
532
574
  async #handleTakeScreenshot(): Promise<void> {
533
575
  const mainTarget = SDK.TargetManager.TargetManager.instance().primaryPageTarget();
534
576
  if (!mainTarget) {
@@ -730,6 +772,8 @@ export class ChatInput extends UI.Widget.Widget implements SDK.TargetManager.Obs
730
772
  undefined;
731
773
  this.onTextSubmit(this.#textAreaRef.value?.value ?? '', imageInput, this.#imageInput?.inputType);
732
774
  this.#imageInput = undefined;
775
+ this.#historyOffset = -1;
776
+ this.#uncommittedText = '';
733
777
  this.setInputValue('');
734
778
  };
735
779
 
@@ -738,6 +782,26 @@ export class ChatInput extends UI.Widget.Widget implements SDK.TargetManager.Obs
738
782
  return;
739
783
  }
740
784
 
785
+ if (event.key === 'ArrowUp') {
786
+ const {value, selectionStart, selectionEnd} = event.target;
787
+ // Only navigate history if the cursor is on the first line and no text is selected.
788
+ if (selectionStart === selectionEnd && value.lastIndexOf('\n', selectionStart - 1) === -1) {
789
+ event.preventDefault();
790
+ this.#navigatePromptHistory(-1);
791
+ }
792
+ return;
793
+ }
794
+
795
+ if (event.key === 'ArrowDown') {
796
+ const {selectionEnd, selectionStart, value} = event.target;
797
+ // Only navigate history if the cursor is on the last line and no text is selected.
798
+ if (selectionStart === selectionEnd && value.indexOf('\n', selectionEnd) === -1) {
799
+ event.preventDefault();
800
+ this.#navigatePromptHistory(1);
801
+ }
802
+ return;
803
+ }
804
+
741
805
  // Go to a new line on Shift+Enter. On Enter, submit unless the
742
806
  // user is in IME composition.
743
807
  if (event.key === 'Enter' && !event.shiftKey && !event.isComposing) {
@@ -750,6 +814,8 @@ export class ChatInput extends UI.Widget.Widget implements SDK.TargetManager.Obs
750
814
  undefined;
751
815
  this.onTextSubmit(event.target.value, imageInput, this.#imageInput?.inputType);
752
816
  this.#imageInput = undefined;
817
+ this.#historyOffset = -1;
818
+ this.#uncommittedText = '';
753
819
  this.setInputValue('');
754
820
  }
755
821
  };
@@ -37,6 +37,7 @@ import * as TimelineUtils from '../../timeline/utils/utils.js';
37
37
  import {PanelUtils} from '../../utils/utils.js';
38
38
 
39
39
  import chatMessageStyles from './chatMessage.css.js';
40
+ import {getButtonLabel} from './WalkthroughUtils.js';
40
41
  import {walkthroughCloseTitle, walkthroughTitle, WalkthroughView} from './WalkthroughView.js';
41
42
 
42
43
  const {html, Directives: {ref, ifDefined}} = Lit;
@@ -184,6 +185,34 @@ const UIStringsNotTranslate = {
184
185
  * @description Title used for revealing the performance trace.
185
186
  */
186
187
  revealTrace: 'Reveal trace',
188
+ /**
189
+ * @description Accessible label for the reveal button in the computed styles widget.
190
+ */
191
+ revealComputedStyles: 'Reveal computed styles',
192
+ /**
193
+ * @description Accessible label for the reveal button in the core web vitals widget.
194
+ */
195
+ revealCoreWebVitals: 'Reveal Core Web Vitals',
196
+ /**
197
+ * @description Accessible label for the reveal button in the style properties widget.
198
+ */
199
+ revealStyleProperties: 'Reveal style properties',
200
+ /**
201
+ * @description Accessible label for the reveal button in the LCP breakdown widget.
202
+ */
203
+ revealLcpBreakdown: 'Reveal LCP breakdown',
204
+ /**
205
+ * @description Accessible label for the reveal button in the LCP element widget.
206
+ */
207
+ revealLcpElement: 'Reveal LCP element',
208
+ /**
209
+ * @description Accessible label for the reveal button in the performance summary widget.
210
+ */
211
+ revealPerformanceSummary: 'Reveal performance summary',
212
+ /**
213
+ * @description Accessible label for the reveal button in the bottom up thread activity widget.
214
+ */
215
+ revealBottomUpTree: 'Reveal bottom-up thread activity',
187
216
  /**
188
217
  * @description Title for the core web vitals widget.
189
218
  */
@@ -208,14 +237,6 @@ const UIStringsNotTranslate = {
208
237
  * @description Title for the bottom up thread activity widget.
209
238
  */
210
239
  bottomUpTree: 'Bottom-up thread activity',
211
- /**
212
- * @description Accessilility label for the button that shows the walkthrough when there are no widgets in the walkthrough.
213
- */
214
- showThinking: 'Show thinking',
215
- /**
216
- * @description Accessilility label for the button that hides the walkthrough when there are no widgets in the walkthrough.
217
- */
218
- hideThinking: 'Hide thinking',
219
240
  } as const;
220
241
 
221
242
  export interface Step {
@@ -251,6 +272,12 @@ export interface StepPart {
251
272
  step: Step;
252
273
  }
253
274
 
275
+ /**
276
+ * Represents a part of the message that consists of one or more widgets.
277
+ * The agent can yield widgets directly as part of its response, separate
278
+ * from those returned by a specific tool call (which are encapsulated
279
+ * within a StepPart).
280
+ */
254
281
  export interface WidgetPart {
255
282
  type: 'widget';
256
283
  widgets: AiWidget[];
@@ -317,6 +344,8 @@ export interface MessageInput {
317
344
  isReadOnly: boolean;
318
345
  isLastMessage: boolean;
319
346
  isFirstMessage: boolean;
347
+ prompt: string;
348
+ shouldShowCSSChangeSummary: boolean;
320
349
  canShowFeedbackForm: boolean;
321
350
  markdownRenderer: MarkdownLitRenderer;
322
351
  onSuggestionClick: (suggestion: string) => void;
@@ -418,7 +447,7 @@ export const DEFAULT_VIEW = (input: ChatMessageViewInput, output: ViewOutput, ta
418
447
  },
419
448
  )}
420
449
  ${renderError(message)}
421
- ${input.isLastMessage && hasAiV2 && !input.isLoading && input.changeSummary ? html`
450
+ ${input.shouldShowCSSChangeSummary && hasAiV2 && input.changeSummary ? html`
422
451
  <devtools-code-block
423
452
  .code=${input.changeSummary}
424
453
  .codeLang=${'css'}
@@ -475,7 +504,7 @@ function renderTitle(step: Step): Lit.LitTemplate {
475
504
  html`<span class="paused">${lockedString(UIStringsNotTranslate.paused)}: </span>` :
476
505
  Lit.nothing;
477
506
 
478
- return html`<span class="title" aria-label=${titleForStep(step)}>${paused}${titleForStep(step)}</span>`;
507
+ return html`<h3 class="title" aria-label=${titleForStep(step)}>${paused}${titleForStep(step)}</h3>`;
479
508
  }
480
509
 
481
510
  function renderStepCode(step: Step): Lit.LitTemplate {
@@ -584,12 +613,13 @@ function renderWalkthroughSidebarButton(
584
613
  'has-widgets': hasOneStepWithWidget && !input.isLoading,
585
614
  });
586
615
 
587
- let accessibleLabel = title;
588
- // If the agent is still thinking we want the accessibility label to include the current step title followed by Show/Hide thinking.
589
- if (input.isLoading) {
590
- const suffix = isExpanded ? UIStringsNotTranslate.hideThinking : UIStringsNotTranslate.showThinking;
591
- accessibleLabel = `${titleForStep(lastStep)} ${i18n.i18n.lockedString(suffix)}`;
592
- }
616
+ const accessibleLabel = getButtonLabel({
617
+ isExpanded,
618
+ isLoading: input.isLoading,
619
+ hasWidgets: hasOneStepWithWidget,
620
+ prompt: input.prompt,
621
+ stepTitle: titleForStep(lastStep),
622
+ });
593
623
 
594
624
  // clang-format off
595
625
  return html`
@@ -652,6 +682,7 @@ function renderWalkthroughUI(input: ChatMessageViewInput, steps: Step[]): Lit.Li
652
682
  markdownRenderer: input.markdownRenderer,
653
683
  isInlined: true,
654
684
  isExpanded,
685
+ prompt: input.prompt,
655
686
  onToggle: input.walkthrough.onToggle,
656
687
  onOpen: input.walkthrough.onOpen,
657
688
  })}
@@ -756,6 +787,7 @@ interface WidgetMakerResponse {
756
787
  // Can be null if the widget is only used to add the Reveal CTA.
757
788
  title: Lit.LitTemplate|Platform.UIString.LocalizedString|null;
758
789
  jslogContext?: string;
790
+ accessibleRevealLabel: string;
759
791
  }
760
792
 
761
793
  const nodeCache = new Map<Protocol.DOM.BackendNodeId, SDK.DOMModel.DOMNode>();
@@ -811,6 +843,7 @@ async function makeComputedStyleWidget(widgetData: ComputedStyleAiWidget): Promi
811
843
  return {
812
844
  renderedWidget,
813
845
  revealable: new Elements.ElementsPanel.NodeComputedStyles(domNodeForId),
846
+ accessibleRevealLabel: lockedString(UIStringsNotTranslate.revealComputedStyles),
814
847
  // clang-format off
815
848
  title: html`
816
849
  <span class="computed-style-title-wrapper">
@@ -837,6 +870,7 @@ async function makeCoreWebVitalsWidget(widgetData: CoreVitalsAiWidget): Promise<
837
870
  return {
838
871
  renderedWidget,
839
872
  revealable: new TimelineUtils.Helpers.RevealableCoreVitals(widgetData.data.insightSetKey),
873
+ accessibleRevealLabel: lockedString(UIStringsNotTranslate.revealCoreWebVitals),
840
874
  title: lockedString(UIStringsNotTranslate.coreVitals),
841
875
  jslogContext: 'core-web-vitals',
842
876
  };
@@ -870,6 +904,7 @@ async function makeStylePropertiesWidget(widgetData: StylePropertiesAiWidget): P
870
904
  return {
871
905
  renderedWidget,
872
906
  revealable: domNodeForId,
907
+ accessibleRevealLabel: lockedString(UIStringsNotTranslate.revealStyleProperties),
873
908
  title: html`<devtools-widget
874
909
  ${widget(PanelsCommon.DOMLinkifier.DOMNodeLink, {
875
910
  node: domNodeForId,
@@ -898,6 +933,7 @@ async function makePerfInsightWidget(widgetData: PerfInsightAiWidget): Promise<W
898
933
  return {
899
934
  renderedWidget,
900
935
  revealable: new TimelineUtils.Helpers.RevealableInsight(insight),
936
+ accessibleRevealLabel: lockedString(UIStringsNotTranslate.revealLcpBreakdown),
901
937
  title: lockedString(UIStringsNotTranslate.lcpBreakdown),
902
938
  jslogContext: 'lcp-breakdown',
903
939
  };
@@ -932,6 +968,7 @@ async function makeBottomUpTimelineTreeWidget(widgetData: BottomUpTreeAiWidget):
932
968
  return {
933
969
  renderedWidget,
934
970
  revealable: new TimelineUtils.Helpers.RevealableBottomUpProfile(widgetData.data.bounds),
971
+ accessibleRevealLabel: lockedString(UIStringsNotTranslate.revealBottomUpTree),
935
972
  title: lockedString(UIStringsNotTranslate.bottomUpTree),
936
973
  jslogContext: 'bottom-up',
937
974
  };
@@ -957,7 +994,7 @@ function renderWidgetResponse(response: WidgetMakerResponse|null): Lit.LitTempla
957
994
  const revealButton = html`
958
995
  <devtools-button class="widget-reveal-button"
959
996
  .variant=${Buttons.Button.Variant.TEXT}
960
- .accessibleLabel=${lockedString(UIStringsNotTranslate.reveal)}
997
+ .accessibleLabel=${response.accessibleRevealLabel}
961
998
  .jslogContext=${'reveal'}
962
999
  @click=${onReveal}
963
1000
  >
@@ -971,7 +1008,7 @@ function renderWidgetResponse(response: WidgetMakerResponse|null): Lit.LitTempla
971
1008
  <div class=${classes} jslog=${ifDefined(response.jslogContext ? VisualLogging.section(response.jslogContext) : undefined)}>
972
1009
  ${response.title ? html`
973
1010
  <div class="widget-header">
974
- <h3 class="widget-name">${response.title}</h3>
1011
+ <h4 class="widget-name">${response.title}</h4>
975
1012
  <div class="widget-reveal-container">
976
1013
  ${revealButton}
977
1014
  </div>
@@ -993,11 +1030,13 @@ function renderWidgetResponse(response: WidgetMakerResponse|null): Lit.LitTempla
993
1030
  }
994
1031
 
995
1032
  async function makePerformanceTraceWidget(widgetData: PerformanceTraceAiWidget): Promise<WidgetMakerResponse|null> {
1033
+ const customRevealTitle = lockedString(UIStringsNotTranslate.revealTrace);
996
1034
  return {
997
1035
  renderedWidget: null,
998
1036
  title: null,
999
1037
  revealable: new Timeline.TimelinePanel.ParsedTraceRevealable(widgetData.data.parsedTrace),
1000
- customRevealTitle: lockedString(UIStringsNotTranslate.revealTrace),
1038
+ customRevealTitle,
1039
+ accessibleRevealLabel: customRevealTitle,
1001
1040
  jslogContext: 'performance-trace',
1002
1041
  };
1003
1042
  }
@@ -1057,6 +1096,7 @@ async function makeDomTreeWidget(widgetData: DomTreeAiWidget): Promise<WidgetMak
1057
1096
  return {
1058
1097
  renderedWidget,
1059
1098
  revealable: new SDK.DOMModel.DeferredDOMNode(root.domModel().target(), root.backendNodeId()),
1099
+ accessibleRevealLabel: lockedString(UIStringsNotTranslate.revealLcpElement),
1060
1100
  title: lockedString(UIStringsNotTranslate.lcpElement),
1061
1101
  jslogContext: 'dom-snapshot',
1062
1102
  };
@@ -1077,8 +1117,82 @@ async function makeDomTreeWidget(widgetData: DomTreeAiWidget): Promise<WidgetMak
1077
1117
  *
1078
1118
  * This allows for a flexible and extensible system where new widget types
1079
1119
  * can be added to the AI responses and rendered in DevTools by adding
1080
- * corresponding \`make...Widget\` functions and handling them here.
1120
+ * corresponding `make...Widget` functions and handling them here.
1121
+ */
1122
+ /**
1123
+ * Generates a deterministic unique identifier for a given AiWidget based on
1124
+ * its name and identifying data. This signature is used for widget deduplication.
1081
1125
  */
1126
+ export function getWidgetSignature(widget: AiWidget): string {
1127
+ switch (widget.name) {
1128
+ case 'COMPUTED_STYLES':
1129
+ return `${widget.name}:${widget.data.backendNodeId}`;
1130
+ case 'CORE_VITALS':
1131
+ return `${widget.name}:${widget.data.insightSetKey}`;
1132
+ case 'STYLE_PROPERTIES':
1133
+ return `${widget.name}:${widget.data.backendNodeId}:${widget.data.selector ?? ''}`;
1134
+ case 'DOM_TREE':
1135
+ return `${widget.name}:${widget.data.root.backendNodeId()}`;
1136
+ case 'PERFORMANCE_TRACE':
1137
+ return `${widget.name}`;
1138
+ case 'PERF_INSIGHT':
1139
+ return `${widget.name}:${widget.data.insight}:${widget.data.insightData.insightKey}:${
1140
+ widget.data.insightData.navigation?.args?.data?.navigationId ?? 'no-nav-id'}`;
1141
+ case 'TIMELINE_RANGE_SUMMARY':
1142
+ return `${widget.name}:${widget.data.track}:${widget.data.bounds.min}-${widget.data.bounds.max}`;
1143
+ case 'BOTTOM_UP_TREE':
1144
+ return `${widget.name}:${widget.data.bounds.min}-${widget.data.bounds.max}`;
1145
+ default:
1146
+ Platform.assertNever(widget, 'Unknown AiWidget name');
1147
+ }
1148
+ }
1149
+
1150
+ /**
1151
+ * Returns a new ModelChatMessage where widgets have been deduplicated
1152
+ * across all parts and steps of the message. The first occurrence of each
1153
+ * unique widget (determined by its signature) is preserved.
1154
+ */
1155
+ export function getDeduplicatedWidgetsMessage(message: ModelChatMessage): ModelChatMessage {
1156
+ const seenWidgets = new Set<string>();
1157
+
1158
+ const filterWidgets = (widgets: AiWidget[]): AiWidget[] => {
1159
+ return widgets.filter(widget => {
1160
+ const signature = getWidgetSignature(widget);
1161
+ if (seenWidgets.has(signature)) {
1162
+ return false;
1163
+ }
1164
+ seenWidgets.add(signature);
1165
+ return true;
1166
+ });
1167
+ };
1168
+
1169
+ const deduplicatedParts = message.parts.map(part => {
1170
+ if (part.type === 'widget') {
1171
+ return {
1172
+ ...part,
1173
+ widgets: filterWidgets(part.widgets),
1174
+ };
1175
+ }
1176
+
1177
+ if (part.type === 'step' && part.step.widgets) {
1178
+ return {
1179
+ ...part,
1180
+ step: {
1181
+ ...part.step,
1182
+ widgets: filterWidgets(part.step.widgets),
1183
+ },
1184
+ };
1185
+ }
1186
+
1187
+ return part;
1188
+ });
1189
+
1190
+ return {
1191
+ ...message,
1192
+ parts: deduplicatedParts,
1193
+ };
1194
+ }
1195
+
1082
1196
  async function renderWidgets(
1083
1197
  widgets: AiWidget[]|undefined, options: {wrapperClass?: string} = {}): Promise<Lit.LitTemplate> {
1084
1198
  if (!Root.Runtime.hostConfig.devToolsAiAssistanceV2?.enabled || !widgets || widgets.length === 0) {
@@ -1384,9 +1498,11 @@ export class ChatMessage extends UI.Widget.Widget {
1384
1498
  message: Message = {entity: ChatMessageEntity.USER, text: ''};
1385
1499
  isLoading = false;
1386
1500
  isReadOnly = false;
1501
+ prompt = '';
1387
1502
  canShowFeedbackForm = false;
1388
1503
  isLastMessage = false;
1389
1504
  isFirstMessage = false;
1505
+ shouldShowCSSChangeSummary = false;
1390
1506
  markdownRenderer!: MarkdownLitRenderer;
1391
1507
  onSuggestionClick: (suggestion: string) => void = () => {};
1392
1508
  onFeedbackSubmit:
@@ -1428,15 +1544,19 @@ export class ChatMessage extends UI.Widget.Widget {
1428
1544
  }
1429
1545
 
1430
1546
  override performUpdate(): Promise<void>|void {
1547
+ const message =
1548
+ this.message.entity === ChatMessageEntity.MODEL ? getDeduplicatedWidgetsMessage(this.message) : this.message;
1431
1549
  this.#view(
1432
1550
  {
1433
- message: this.message,
1551
+ message,
1434
1552
  isLoading: this.isLoading,
1435
1553
  isReadOnly: this.isReadOnly,
1436
1554
  canShowFeedbackForm: this.canShowFeedbackForm,
1437
1555
  markdownRenderer: this.markdownRenderer,
1438
1556
  isLastMessage: this.isLastMessage,
1439
1557
  isFirstMessage: this.isFirstMessage,
1558
+ prompt: this.prompt,
1559
+ shouldShowCSSChangeSummary: this.shouldShowCSSChangeSummary,
1440
1560
  onSuggestionClick: this.onSuggestionClick,
1441
1561
  onRatingClick: this.#handleRateClick.bind(this),
1442
1562
  onReportClick: () => UIHelpers.openInNewTab(REPORT_URL),
@@ -1597,11 +1717,13 @@ async function makeTimelineRangeSummaryWidget(widgetData: TimelineRangeSummaryAi
1597
1717
  data: {
1598
1718
  parsedTrace,
1599
1719
  events,
1720
+ isInAIWidget: true,
1600
1721
  startTime: Trace.Helpers.Timing.microToMilli(bounds.min),
1601
1722
  endTime: Trace.Helpers.Timing.microToMilli(bounds.max),
1602
1723
  thirdPartyTreeTemplate: html`${
1603
1724
  widget(Timeline.ThirdPartyTreeView.ThirdPartyTreeViewWidget, {
1604
1725
  maxRows: 10,
1726
+ isInAIWidget: true,
1605
1727
  model: {
1606
1728
  selectedEvents: thirdPartyTree.selectedEvents ?? null,
1607
1729
  parsedTrace,
@@ -1620,6 +1742,7 @@ async function makeTimelineRangeSummaryWidget(widgetData: TimelineRangeSummaryAi
1620
1742
  return {
1621
1743
  renderedWidget: template,
1622
1744
  revealable: new TimelineUtils.Helpers.RevealableTimeRange(bounds),
1745
+ accessibleRevealLabel: lockedString(UIStringsNotTranslate.revealPerformanceSummary),
1623
1746
  title: lockedString(UIStringsNotTranslate.performanceSummary),
1624
1747
  jslogContext: 'timeline-range-summary',
1625
1748
  };