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
@@ -55,7 +55,7 @@ import * as Snippets from '../snippets/snippets.js';
55
55
 
56
56
  import {CallStackSidebarPane} from './CallStackSidebarPane.js';
57
57
  import {DebuggerPausedMessage} from './DebuggerPausedMessage.js';
58
- import {NavigatorView} from './NavigatorView.js';
58
+ import {SourcesNavigatorView} from './SourcesNavigator.js';
59
59
  import sourcesPanelStyles from './sourcesPanel.css.js';
60
60
  import {type EditorClosedEvent, Events, SourcesView} from './SourcesView.js';
61
61
  import {ThreadsSidebarPane} from './ThreadsSidebarPane.js';
@@ -781,12 +781,14 @@ export class SourcesPanel extends UI.Panel.Panel implements
781
781
  const viewManager = UI.ViewManager.ViewManager.instance();
782
782
  for (const view of viewManager.viewsForLocation(UI.ViewManager.ViewLocationValues.NAVIGATOR_VIEW)) {
783
783
  const navigatorView = await view.widget();
784
- if (navigatorView instanceof NavigatorView && navigatorView.acceptProject(uiSourceCode.project())) {
785
- navigatorView.revealUISourceCode(uiSourceCode, true);
784
+ if (navigatorView instanceof SourcesNavigatorView && navigatorView.acceptProject(uiSourceCode.project())) {
786
785
  this.navigatorTabbedLocation.tabbedPane().selectTab(view.viewId(), true);
787
786
  if (!skipReveal) {
788
787
  this.#setNavigatorSidebarOpen(true);
789
- await navigatorView.updateComplete;
788
+ }
789
+ await navigatorView.updateComplete;
790
+ navigatorView.revealUISourceCode(uiSourceCode, true);
791
+ if (!skipReveal) {
790
792
  navigatorView.focus();
791
793
  }
792
794
  break;
@@ -916,7 +918,9 @@ export class SourcesPanel extends UI.Panel.Panel implements
916
918
 
917
919
  #editorClosed({data: {uiSourceCode}}: Common.EventTarget.EventTargetEvent<EditorClosedEvent>): void {
918
920
  const context = UI.Context.Context.instance();
919
- if (context.flavor(Workspace.UISourceCode.UISourceCode) === uiSourceCode) {
921
+ const currentFlavor = context.flavor(Workspace.UISourceCode.UISourceCode);
922
+ const flavorScriptId = currentFlavor?.canonicalScriptId();
923
+ if (currentFlavor === uiSourceCode || (flavorScriptId && flavorScriptId === uiSourceCode.canonicalScriptId())) {
920
924
  context.setFlavor(Workspace.UISourceCode.UISourceCode, null);
921
925
  }
922
926
  }
@@ -346,6 +346,7 @@ export class TabbedEditorContainer extends TabbedEditorContainerBase {
346
346
  const icon = !hasLoadError ?
347
347
  (PanelCommon.PersistenceUtils.PersistenceUtils.iconForUISourceCode(uiSourceCode) ?? undefined) :
348
348
  undefined;
349
+ const viewSourceCode = this.#tabViewSourceCodes.get(tabId) ?? uiSourceCode;
349
350
  return {
350
351
  tabId,
351
352
  title: titleForFile(uiSourceCode),
@@ -357,8 +358,8 @@ export class TabbedEditorContainer extends TabbedEditorContainerBase {
357
358
  disconnectedAutomaticFileSystemRoot,
358
359
  icon,
359
360
  widget: (this.#currentFile?.canonicalScriptId() === uiSourceCode.canonicalScriptId()) ?
360
- this.#getOrCreateSourceView(this.#currentFile) :
361
- this.getCreatedSourceView(uiSourceCode),
361
+ this.#getOrCreateSourceView(viewSourceCode) :
362
+ this.getCreatedSourceView(viewSourceCode),
362
363
  };
363
364
  }),
364
365
  activeTabId: this.#currentFile ? this.#tabIdForUISourceCode(this.#currentFile) : undefined,
@@ -457,6 +458,12 @@ export class TabbedEditorContainer extends TabbedEditorContainerBase {
457
458
  readonly #tabDelegate: EditorContainerTabDelegate;
458
459
  #tabIds: Map<Workspace.UISourceCode.UISourceCode, string>;
459
460
  #files: Map<string, Workspace.UISourceCode.UISourceCode>;
461
+ /**
462
+ * Maps a tab id to the UISourceCode whose view is currently bound to that
463
+ * tab. This can differ from the canonical UISourceCode in `#files` when the
464
+ * tab's view was recycled to show a duplicate script with the same URL.
465
+ */
466
+ readonly #tabViewSourceCodes = new Map<string, Workspace.UISourceCode.UISourceCode>();
460
467
  readonly #loadErrorFiles = new Set<Workspace.UISourceCode.UISourceCode>();
461
468
  #previouslyViewedFilesSetting: Common.Settings.Setting<SerializedHistoryItem[]>;
462
469
  #history: History;
@@ -602,7 +609,9 @@ export class TabbedEditorContainer extends TabbedEditorContainerBase {
602
609
  }
603
610
 
604
611
  fileViews(): UI.Widget.Widget[] {
605
- return Array.from(this.#files.values()).map(getViewByUISourceCode).filter(Boolean) as UI.Widget.Widget[];
612
+ return Array.from(this.#files.entries())
613
+ .map(([tabId, file]) => getViewByUISourceCode(this.#tabViewSourceCodes.get(tabId) ?? file))
614
+ .filter(Boolean) as UI.Widget.Widget[];
606
615
  }
607
616
 
608
617
  showSourceLocation(uiSourceCode: Workspace.UISourceCode.UISourceCode,
@@ -785,13 +794,30 @@ export class TabbedEditorContainer extends TabbedEditorContainerBase {
785
794
  this.#removeViewListeners();
786
795
  this.#currentFile = uiSourceCode;
787
796
 
797
+ let tabId: string;
788
798
  try {
789
799
  // Selecting the tab may cause showFile to be called again, but with the canonical source code,
790
800
  // which is not what we want, so we prevent reentrant calls.
791
801
  this.#reentrantShow = true;
792
- const tabId = this.#tabIds.get(canonicalSourceCode) || this.#appendFileTab(canonicalSourceCode);
802
+ tabId = this.#tabIds.get(canonicalSourceCode) || this.#appendFileTab(canonicalSourceCode);
793
803
  this.#appendHistory(tabId);
794
804
 
805
+ const tabViewSourceCode = this.#tabViewSourceCodes.get(tabId) ?? canonicalSourceCode;
806
+ const tabView = this.#getOrCreateSourceView(tabViewSourceCode);
807
+ if (tabView instanceof UISourceCodeFrame && tabViewSourceCode !== uiSourceCode) {
808
+ // We are showing a different UISourceCode in the same tab (because it has the same URL). This
809
+ // commonly happens when switching between workers or iframes containing the same code, and while the
810
+ // contents are usually identical they may not be and it is important to show users when they aren't.
811
+ this.#recycleUISourceCodeFrame(tabView, uiSourceCode);
812
+ if (uiSourceCode.project().type() !== Workspace.Workspace.projectTypes.FileSystem) {
813
+ // Disable editing, because it may confuse users that only one of the copies of this code changes.
814
+ uiSourceCode.disableEdit();
815
+ }
816
+ } else {
817
+ this.#getOrCreateSourceView(uiSourceCode);
818
+ }
819
+ this.#tabViewSourceCodes.set(tabId, uiSourceCode);
820
+
795
821
  this.#scheduleUpdate();
796
822
  } finally {
797
823
  this.#reentrantShow = false;
@@ -802,23 +828,9 @@ export class TabbedEditorContainer extends TabbedEditorContainerBase {
802
828
  }
803
829
 
804
830
  const previousView = this.#currentView;
805
- if (uiSourceCode) {
806
- this.#getOrCreateSourceView(uiSourceCode);
807
- }
808
831
  this.#currentView = this.visibleView;
809
832
  this.#addViewListeners();
810
833
 
811
- if (this.#currentView instanceof UISourceCodeFrame && this.#currentView.uiSourceCode() !== uiSourceCode) {
812
- // We are showing a different UISourceCode in the same tab (because it has the same URL). This
813
- // commonly happens when switching between workers or iframes containing the same code, and while the
814
- // contents are usually identical they may not be and it is important to show users when they aren't.
815
- this.#recycleUISourceCodeFrame(this.#currentView, uiSourceCode);
816
- if (uiSourceCode.project().type() !== Workspace.Workspace.projectTypes.FileSystem) {
817
- // Disable editing, because it may confuse users that only one of the copies of this code changes.
818
- uiSourceCode.disableEdit();
819
- }
820
- }
821
-
822
834
  const eventData = {
823
835
  currentFile: this.#currentFile,
824
836
  currentView: this.#currentView,
@@ -954,6 +966,11 @@ export class TabbedEditorContainer extends TabbedEditorContainerBase {
954
966
  tabIds.push(tabId);
955
967
  } else {
956
968
  this.#removeSourceFrame(uiSourceCode);
969
+ for (const [k, v] of this.#tabViewSourceCodes) {
970
+ if (v === uiSourceCode) {
971
+ this.#tabViewSourceCodes.delete(k);
972
+ }
973
+ }
957
974
  }
958
975
  for (const [k, v] of this.#uriToUISourceCode) {
959
976
  if (v === uiSourceCode) {
@@ -999,6 +1016,7 @@ export class TabbedEditorContainer extends TabbedEditorContainerBase {
999
1016
  #appendFileTab(uiSourceCode: Workspace.UISourceCode.UISourceCode, index?: number, ignoreHistory?: boolean): string {
1000
1017
  const tabId = this.#generateTabId();
1001
1018
  this.#tabIds.set(uiSourceCode, tabId);
1019
+ this.#tabViewSourceCodes.set(tabId, uiSourceCode);
1002
1020
 
1003
1021
  if (index !== undefined) {
1004
1022
  const entries = Array.from(this.#files.entries());
@@ -1065,6 +1083,11 @@ export class TabbedEditorContainer extends TabbedEditorContainerBase {
1065
1083
  this.#currentView = null;
1066
1084
  this.#currentFile = null;
1067
1085
  }
1086
+ const viewSourceCode = this.#tabViewSourceCodes.get(tabId);
1087
+ if (viewSourceCode) {
1088
+ this.#removeSourceFrame(viewSourceCode);
1089
+ this.#tabViewSourceCodes.delete(tabId);
1090
+ }
1068
1091
  if (uiSourceCode) {
1069
1092
  this.#tabIds.delete(uiSourceCode);
1070
1093
  this.#loadErrorFiles.delete(uiSourceCode);
@@ -337,7 +337,7 @@ export class UISourceCodeFrame extends UISourceCodeFrameBase {
337
337
  private reloadPlugins(): void {
338
338
  this.disposePlugins();
339
339
  this.loadPlugins();
340
- if (!this.loaded) {
340
+ if (!pluginCompartment.get(this.textEditor.state)) {
341
341
  // Until the content is loaded the editor still holds the placeholder
342
342
  // state, which doesn't contain `pluginCompartment` at all. Reconfiguring
343
343
  // a compartment that isn't part of the state is a no-op, so the plugins
@@ -101,7 +101,7 @@ interface ViewInput {
101
101
  onCopyWatchExpression(watchExpression: WatchExpression): void;
102
102
  onDeleteAll(): unknown;
103
103
  onAddExpression(): unknown;
104
- onExpand(e: WatchExpression, expanded: boolean): unknown;
104
+ onExpand(e: WatchExpression, expanded: boolean, recursively?: boolean): unknown;
105
105
  watchExpressions: WatchExpression[];
106
106
  }
107
107
  export interface WatchExpressionPromptViewInput {
@@ -352,7 +352,7 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
352
352
  class=${classMap({'watch-expression-tree-item': true, 'watch-expression-editing': e.editing })}
353
353
  ?open=${Boolean(e.result?.expanded)}
354
354
  @keydown=${onExpressionKeydown.bind(undefined, e)}
355
- @expand=${(event: UI.TreeOutline.TreeViewElement.ExpandEvent) => input.onExpand(e, event.detail.expanded)}
355
+ @expand=${(event: UI.TreeOutline.TreeViewElement.ExpandEvent) => input.onExpand(e, event.detail.expanded, event.detail.recursively)}
356
356
  role=treeitem>
357
357
  <devtools-widget ${widget(WatchExpressionPromptWidget, {
358
358
  expression: e,
@@ -549,10 +549,15 @@ export class WatchExpressionsSidebarPane extends UI.Widget.VBox implements UI.Ac
549
549
  this.saveExpressions();
550
550
  this.requestUpdate();
551
551
  },
552
- onExpand: (e: WatchExpression, expanded: boolean): void => {
553
- if (e.result) {
554
- e.result.expanded = expanded;
552
+ onExpand: (e: WatchExpression, expanded: boolean, recursively = false): void => {
553
+ if (!e.result) {
554
+ return;
555
+ }
556
+ if (expanded && recursively) {
557
+ void e.result.expandRecursively().then(() => this.requestUpdate());
558
+ return;
555
559
  }
560
+ e.result.expanded = expanded;
556
561
  },
557
562
  },
558
563
  {}, this.contentElement);
@@ -227,11 +227,6 @@ const UIStrings = {
227
227
  * @description Title of an action in the sources tool to create a snippet.
228
228
  */
229
229
  createNewSnippet: 'Create new snippet',
230
- /**
231
- * @description Button in the Workspace tab of the Sources panel, used to
232
- * (manually) add a folder to the workspace.
233
- */
234
- addFolderManually: 'Add folder manually',
235
230
  /**
236
231
  * @description Title of an action in the Sources panel command menu to (manually)
237
232
  * add a folder to the workspace.
@@ -564,9 +559,9 @@ UI.ViewManager.registerViewExtension({
564
559
  order: 3,
565
560
  persistence: UI.ViewManager.ViewPersistence.PERMANENT,
566
561
  condition: () => !Root.Runtime.Runtime.isTraceApp(),
567
- async loadView(universe) {
562
+ async loadView() {
568
563
  const Sources = await loadSourcesModule();
569
- return new Sources.SourcesNavigator.FilesNavigatorView(universe.networkProjectManager);
564
+ return new Sources.SourcesNavigator.FilesNavigatorView();
570
565
  },
571
566
  });
572
567
 
@@ -578,9 +573,9 @@ UI.ViewManager.registerViewExtension({
578
573
  order: 6,
579
574
  persistence: UI.ViewManager.ViewPersistence.PERMANENT,
580
575
  condition: () => !Root.Runtime.Runtime.isTraceApp(),
581
- async loadView(universe) {
576
+ async loadView() {
582
577
  const Sources = await loadSourcesModule();
583
- return new Sources.SourcesNavigator.SnippetsNavigatorView(universe.networkProjectManager);
578
+ return new Sources.SourcesNavigator.SnippetsNavigatorView();
584
579
  },
585
580
  });
586
581
 
@@ -2055,12 +2050,6 @@ Common.Revealer.registerRevealer({
2055
2050
  },
2056
2051
  });
2057
2052
 
2058
- UI.Toolbar.registerToolbarItem({
2059
- actionId: 'sources.add-folder-to-workspace',
2060
- location: UI.Toolbar.ToolbarItemLocation.FILES_NAVIGATION_TOOLBAR,
2061
- label: i18nLazyString(UIStrings.addFolderManually),
2062
- });
2063
-
2064
2053
  UI.Context.registerListener({
2065
2054
  contextTypes() {
2066
2055
  return [SDK.DebuggerModel.DebuggerPausedDetails];
@@ -9,6 +9,11 @@
9
9
  flex-shrink: 0;
10
10
  }
11
11
 
12
+ .navigator-toolbar {
13
+ border-bottom: var(--sys-size-1) solid var(--sys-color-divider);
14
+ padding-left: var(--sys-size-5);
15
+ }
16
+
12
17
  .automatic-workspace-infobar {
13
18
  border-top: var(--sys-size-1) solid var(--sys-color-divider);
14
19
  }
@@ -35,7 +35,6 @@ interface ModificationsManagerData {
35
35
  parsedTrace: Trace.TraceModel.ParsedTrace;
36
36
  traceBounds: Trace.Types.Timing.TraceWindowMicro;
37
37
  rawTraceEvents: readonly Trace.Types.Events.Event[];
38
- syntheticEvents: Trace.Types.Events.SyntheticBased[];
39
38
  modifications?: Trace.Types.File.Modifications;
40
39
  }
41
40
 
@@ -90,7 +89,6 @@ export class ModificationsManager extends EventTarget {
90
89
  traceBounds,
91
90
  rawTraceEvents: parsedTrace.traceEvents,
92
91
  modifications: parsedTrace.metadata.modifications,
93
- syntheticEvents: parsedTrace.syntheticEventsManager.getSyntheticTraces(),
94
92
  });
95
93
  modificationsManagerByTraceIndex[traceIndex] = newModificationsManager;
96
94
  activeManager = newModificationsManager;
@@ -185,6 +185,8 @@ Comments on flame chart entries use the shared comments UI from `ui/comments` an
185
185
 
186
186
  The pin and the `COMMENT_PIN` element are separate elements in separate layers, and moving the element fires no DOM scroll or resize event, so step 2 is what keeps the pin on its entry. See the `CustomAnchorResolver` documentation in `ui/comments/CommentAnchorResolver.ts` for the contract.
187
187
 
188
+ Entries without an `EventsSerializer` key, such as JS samples, use a synthetic key and are found again by start time, duration and title.
189
+
188
190
  ## Timeline tree views
189
191
 
190
192
  The `TimelineTreeView` base class provides the foundation for creating various tree-based views within the Performance panel (e.g., Summary, Bottom-Up, Call Tree, Event Log). It handles core functionality like:
@@ -0,0 +1,171 @@
1
+ // Copyright 2026 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ import * as Platform from '../../core/platform/platform.js';
6
+ import * as AIAssistance from '../../models/ai_assistance/ai_assistance.js';
7
+ import * as Trace from '../../models/trace/trace.js';
8
+ import * as SourceMapsResolver from '../../models/trace_source_maps_resolver/trace_source_maps_resolver.js';
9
+
10
+ /**
11
+ * A long call path keeps this many outermost entries, which usually say why
12
+ * the code ran, such as `Task > Event: click > Function call`.
13
+ */
14
+ const CALL_PATH_OUTER_ENTRIES = 3;
15
+ /**
16
+ * A long call path keeps this many innermost entries, ending with the
17
+ * commented entry itself.
18
+ */
19
+ const CALL_PATH_INNER_ENTRIES = 15;
20
+
21
+ /**
22
+ * Returns the English label of a trace warning. These lines are read by the
23
+ * AI agent, not shown in the UI, so they are not localized.
24
+ */
25
+ function labelForWarning(warning: Trace.Handlers.ModelHandlers.Warnings.Warning): string {
26
+ switch (warning) {
27
+ case 'LONG_TASK':
28
+ return 'Long task';
29
+ case 'IDLE_CALLBACK_OVER_TIME':
30
+ return 'Idle callback over time';
31
+ case 'FORCED_REFLOW':
32
+ return 'Forced reflow';
33
+ case 'LONG_INTERACTION':
34
+ return 'Long interaction';
35
+ default:
36
+ Platform.assertNever(warning, `Unknown warning: ${warning}`);
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Returns the location of the entry's code as `url:line:column`, with
42
+ * 1-based line and column numbers as editors show them, or null if the entry
43
+ * has no code location. The location is in the authored source if a source
44
+ * map resolved it.
45
+ *
46
+ * This follows SourceMapsResolver.codeLocationForEntry() but skips its
47
+ * Workspace lookup, which only maps a bare URL to a workspace URL, so that
48
+ * the controller does not need a Workspace.
49
+ *
50
+ * Network requests are skipped: their URL is the request, not code, and a
51
+ * cross-origin request's final URL must be redacted.
52
+ */
53
+ function sourceLocationForEntry(event: Trace.Types.Events.Event, parsedTrace: Trace.TraceModel.ParsedTrace): string|
54
+ null {
55
+ if (Trace.Types.Events.isSyntheticNetworkRequest(event)) {
56
+ return null;
57
+ }
58
+ let url: string|null = null;
59
+ let line: number|undefined;
60
+ let column: number|undefined;
61
+ const uiLocation = SourceMapsResolver.SourceMapsResolver.resolvedCodeLocationForEntry(event)?.devtoolsLocation;
62
+ const rawCallFrame = uiLocation ? null : Trace.Helpers.Trace.rawCallFrameForEntry(event);
63
+ if (uiLocation) {
64
+ url = uiLocation.uiSourceCode.url();
65
+ line = uiLocation.lineNumber;
66
+ column = uiLocation.columnNumber;
67
+ } else if (rawCallFrame) {
68
+ url = rawCallFrame.url;
69
+ line = rawCallFrame.lineNumber >= 0 ? rawCallFrame.lineNumber : undefined;
70
+ column = rawCallFrame.columnNumber >= 0 ? rawCallFrame.columnNumber : undefined;
71
+ } else {
72
+ url = Trace.Handlers.Helpers.getNonResolvedURL(event, parsedTrace.data);
73
+ }
74
+ if (!url) {
75
+ return null;
76
+ }
77
+ if (line === undefined) {
78
+ return url;
79
+ }
80
+ return column === undefined ? `${url}:${line + 1}` : `${url}:${line + 1}:${column + 1}`;
81
+ }
82
+
83
+ /**
84
+ * Returns the names of the entry's ancestors and the entry itself, outermost
85
+ * first, for example `Task > Timer fired > Function call > handleClick`, or
86
+ * null if the entry has no ancestors.
87
+ *
88
+ * JS call stacks can be hundreds of entries deep, so a long call path keeps
89
+ * only its outermost and innermost entries and says how many it skipped, for
90
+ * example `Task > Event: click > Function call > … (240 more) > render > …`.
91
+ */
92
+ function callPathForEntry(event: Trace.Types.Events.Event, parsedTrace: Trace.TraceModel.ParsedTrace): string|null {
93
+ const node = parsedTrace.data.Renderer.entryToNode.get(event) ?? parsedTrace.data.Samples.entryToNode.get(event);
94
+ if (!node?.parent) {
95
+ return null;
96
+ }
97
+ const names: string[] = [];
98
+ for (let current: Trace.Helpers.TreeHelpers.TraceEntryNode|null = node; current; current = current.parent) {
99
+ names.push(Trace.Name.forEntry(current.entry, parsedTrace));
100
+ }
101
+ // The walk goes from the entry up to the root, so reverse it to put the
102
+ // outermost entry first.
103
+ names.reverse();
104
+ const skippedCount = names.length - CALL_PATH_OUTER_ENTRIES - CALL_PATH_INNER_ENTRIES;
105
+ // Replacing a single entry with a placeholder would not shorten the path.
106
+ if (skippedCount > 1) {
107
+ names.splice(CALL_PATH_OUTER_ENTRIES, skippedCount, `… (${skippedCount} more)`);
108
+ }
109
+ return names.join(' > ');
110
+ }
111
+
112
+ /**
113
+ * Describes a flame chart entry for the AI agent that receives comments on
114
+ * it. The entry title is already sent as the anchor's text signature, so the
115
+ * lines add what identifies the entry in the trace and where its code is: the
116
+ * trace event name, the entry's timing, its track, its source location, its
117
+ * call path, its warnings and the page that was traced.
118
+ *
119
+ * Times are relative to the start of the trace, which is where the
120
+ * Performance panel's time ruler starts.
121
+ *
122
+ * Lines without a value are omitted.
123
+ */
124
+ export function agentContextForEntry(
125
+ event: Trace.Types.Events.Event,
126
+ trackName: string|null,
127
+ parsedTrace: Trace.TraceModel.ParsedTrace,
128
+ ): string[] {
129
+ const {micros} = AIAssistance.UnitFormatters;
130
+ const lines: string[] = [];
131
+
132
+ lines.push(`Trace event: ${event.name}`);
133
+
134
+ const timing = [`starts at ${micros(event.ts - parsedTrace.data.Meta.traceBounds.min)}`];
135
+ if (event.dur) {
136
+ timing.push(`duration ${micros(event.dur)}`);
137
+ }
138
+ const selfTime = parsedTrace.data.Renderer.entryToNode.get(event)?.selfTime;
139
+ if (selfTime !== undefined) {
140
+ timing.push(`self time ${micros(selfTime)}`);
141
+ }
142
+ lines.push(`Timing: ${timing.join(', ')}`);
143
+
144
+ if (trackName) {
145
+ lines.push(`Track: ${trackName}`);
146
+ }
147
+
148
+ const sourceLocation = sourceLocationForEntry(event, parsedTrace);
149
+ if (sourceLocation) {
150
+ lines.push(`Source: ${sourceLocation}`);
151
+ }
152
+
153
+ const callPath = callPathForEntry(event, parsedTrace);
154
+ if (callPath) {
155
+ lines.push(`Call path: ${callPath}`);
156
+ }
157
+
158
+ const warnings = parsedTrace.data.Warnings.perEvent.get(event);
159
+ if (warnings?.length) {
160
+ lines.push(`Warnings: ${warnings.map(labelForWarning).join(', ')}`);
161
+ }
162
+
163
+ // The main frame URL is same-origin with the trace by definition, so it
164
+ // does not need redaction.
165
+ const mainFrameURL = parsedTrace.data.Meta.mainFrameURL;
166
+ if (mainFrameURL) {
167
+ lines.push(`Traced page: ${mainFrameURL}`);
168
+ }
169
+
170
+ return lines;
171
+ }