chrome-devtools-frontend 1.0.1664496 → 1.0.1665921

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 (407) hide show
  1. package/.agents/skills/devtools-testing-guidance/SKILL.md +48 -0
  2. package/.agents/skills/devtools-ux-writing-refactor/SKILL.md +3 -3
  3. package/.agents/skills/repro-flaky-tests/SKILL.md +2 -2
  4. package/.agents/skills/ui-eng-vision-local-lit-renderer/SKILL.md +7 -1
  5. package/.agents/skills/ui-eng-vision-widget-promoter/SKILL.md +2 -0
  6. package/.agents/skills/version-control/SKILL.md +4 -3
  7. package/docs/ui_engineering.md +89 -0
  8. package/eslint.config.mjs +9 -2
  9. package/front_end/Images/rollup.config.mjs +1 -1
  10. package/front_end/Tests.js +15 -16
  11. package/front_end/core/common/Gzip.ts +2 -2
  12. package/front_end/core/common/Settings.ts +4 -20
  13. package/front_end/core/common/Srcset.ts +1 -1
  14. package/front_end/core/common/VersionController.ts +1 -1
  15. package/front_end/core/host/AidaClient.ts +19 -4
  16. package/front_end/core/host/AidaGcaTranslation.ts +2 -2
  17. package/front_end/core/host/GcaClient.ts +2 -2
  18. package/front_end/core/host/GdpClient.ts +3 -3
  19. package/front_end/core/host/InspectorFrontendHostStub.ts +1 -1
  20. package/front_end/core/host/ResourceLoader.ts +15 -15
  21. package/front_end/core/protocol_client/DevToolsCDPConnection.ts +2 -2
  22. package/front_end/core/protocol_client/InspectorBackend.ts +1 -1
  23. package/front_end/core/root/Runtime.ts +0 -1
  24. package/front_end/core/sdk/CSSMatchedStyles.ts +78 -3
  25. package/front_end/core/sdk/CSSMetadata.ts +17 -12
  26. package/front_end/core/sdk/CSSProperty.ts +1 -1
  27. package/front_end/core/sdk/CSSPropertyParserMatchers.ts +2 -2
  28. package/front_end/core/sdk/CSSRule.ts +3 -3
  29. package/front_end/core/sdk/CSSStyleSheetHeader.ts +3 -3
  30. package/front_end/core/sdk/CompilerSourceMappingContentProvider.ts +1 -1
  31. package/front_end/core/sdk/Connections.ts +1 -1
  32. package/front_end/core/sdk/DebuggerModel.ts +13 -13
  33. package/front_end/core/sdk/NetworkManager.ts +19 -19
  34. package/front_end/core/sdk/NetworkRequest.ts +57 -57
  35. package/front_end/core/sdk/OverlayModel.ts +1 -1
  36. package/front_end/core/sdk/PageResourceLoader.ts +2 -2
  37. package/front_end/core/sdk/RehydratingConnection.ts +5 -5
  38. package/front_end/core/sdk/ScreenCaptureModel.ts +1 -1
  39. package/front_end/core/sdk/Script.ts +2 -2
  40. package/front_end/core/sdk/ServerTiming.ts +7 -7
  41. package/front_end/core/sdk/ServiceWorkerCacheModel.ts +1 -1
  42. package/front_end/core/sdk/ServiceWorkerManager.ts +11 -11
  43. package/front_end/core/sdk/SourceMapScopeChainEntry.ts +2 -2
  44. package/front_end/core/sdk/SourceMapScopesInfo.ts +1 -1
  45. package/front_end/core/sdk/StorageKeyManager.ts +1 -1
  46. package/front_end/core/sdk/sdk-meta.ts +98 -98
  47. package/front_end/devtools_compatibility.js +15 -13
  48. package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +4 -8
  49. package/front_end/entrypoints/main/MainImpl.ts +2 -3
  50. package/front_end/entrypoints/main/main-meta.ts +1 -16
  51. package/front_end/entrypoints/shell/shell.ts +1 -0
  52. package/front_end/entrypoints/trace_app/trace_app.ts +1 -0
  53. package/front_end/foundation/README.md +1 -1
  54. package/front_end/foundation/Universe.test.api.ts +73 -0
  55. package/front_end/foundation/Universe.ts +22 -0
  56. package/front_end/generated/InspectorBackendCommands.ts +2 -2
  57. package/front_end/generated/SupportedCSSProperties.js +1 -1
  58. package/front_end/generated/protocol.ts +19 -0
  59. package/front_end/models/ai_assistance/AiAgent2.ts +1 -1
  60. package/front_end/models/ai_assistance/AiConversation.ts +1 -1
  61. package/front_end/models/ai_assistance/BuiltInAi.ts +1 -1
  62. package/front_end/models/ai_assistance/ChangeManager.ts +0 -70
  63. package/front_end/models/ai_assistance/ExtensionScope.ts +2 -36
  64. package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +9 -9
  65. package/front_end/models/ai_assistance/agents/AiAgent.ts +10 -2
  66. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +4 -4
  67. package/front_end/models/ai_assistance/agents/ExecuteJavascript.ts +1 -1
  68. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +21 -21
  69. package/front_end/models/ai_assistance/agents/StorageAgent.ts +4 -4
  70. package/front_end/models/ai_assistance/agents/StylingAgent.ts +1 -1
  71. package/front_end/models/ai_assistance/ai_assistance.ts +0 -5
  72. package/front_end/models/ai_assistance/data_formatters/FileFormatter.ts +11 -4
  73. package/front_end/models/ai_assistance/data_formatters/NetworkRequestFormatter.ts +8 -2
  74. package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.ts +14 -11
  75. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +2 -2
  76. package/front_end/models/ai_assistance/performance/AICallTree.ts +2 -2
  77. package/front_end/models/ai_assistance/tools/ExecuteJavaScript.ts +1 -1
  78. package/front_end/models/ai_assistance/tools/GetNetworkRequestDetails.ts +9 -2
  79. package/front_end/models/ai_assistance/tools/GetStyles.ts +4 -4
  80. package/front_end/models/ai_assistance/tools/ListNetworkRequests.ts +2 -5
  81. package/front_end/models/ai_code_completion/AiCodeCompletion.ts +2 -2
  82. package/front_end/models/ai_code_generation/AiCodeGeneration.ts +2 -2
  83. package/front_end/models/badges/badges-meta.ts +27 -0
  84. package/front_end/models/bindings/CSSWorkspaceBinding.ts +4 -3
  85. package/front_end/models/bindings/ContentProviderBasedProject.ts +1 -1
  86. package/front_end/models/bindings/DebuggerLanguagePlugins.ts +6 -7
  87. package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +5 -4
  88. package/front_end/models/bindings/PresentationConsoleMessageHelper.ts +72 -29
  89. package/front_end/models/bindings/ResourceMapping.ts +38 -32
  90. package/front_end/models/bindings/ResourceScriptMapping.ts +5 -7
  91. package/front_end/models/breakpoints/BreakpointManager.ts +2 -1
  92. package/front_end/models/har/Writer.ts +2 -2
  93. package/front_end/models/issues_manager/ElementAccessibilityIssue.ts +1 -1
  94. package/front_end/models/issues_manager/GenericIssue.ts +1 -1
  95. package/front_end/models/issues_manager/IssuesManager.ts +14 -5
  96. package/front_end/models/issues_manager/PartitioningBlobURLIssue.ts +1 -1
  97. package/front_end/models/issues_manager/SRIMessageSignatureIssue.ts +2 -2
  98. package/front_end/models/issues_manager/SourceFrameIssuesManager.ts +13 -2
  99. package/front_end/models/issues_manager/issues_manager.ts +0 -2
  100. package/front_end/models/live-metrics/LiveMetrics.ts +22 -5
  101. package/front_end/models/live-metrics/web-vitals-injected/rollup.config.mjs +1 -1
  102. package/front_end/models/live-metrics/web-vitals-injected/spec/spec.ts +10 -4
  103. package/front_end/models/logs/logs-meta.ts +23 -16
  104. package/front_end/models/persistence/AutomaticFileSystemWorkspaceBinding.ts +2 -2
  105. package/front_end/models/persistence/IsolatedFileSystem.ts +1 -1
  106. package/front_end/models/persistence/IsolatedFileSystemManager.ts +1 -1
  107. package/front_end/models/source_map_scopes/NamesResolver.ts +104 -86
  108. package/front_end/models/source_map_scopes/ScopeChainModel.ts +6 -2
  109. package/front_end/models/stack_trace/StackTraceModel.ts +1 -1
  110. package/front_end/models/trace/handlers/ExtensionTraceDataHandler.ts +1 -1
  111. package/front_end/models/trace/handlers/UserTimingsHandler.ts +17 -6
  112. package/front_end/models/trace/helpers/SamplesIntegrator.ts +1 -1
  113. package/front_end/models/trace/helpers/Timing.ts +1 -1
  114. package/front_end/models/trace/insights/Common.ts +1 -1
  115. package/front_end/models/trace/insights/DocumentLatency.ts +3 -3
  116. package/front_end/models/trace/insights/LCPDiscovery.ts +1 -1
  117. package/front_end/models/trace/insights/ModernHTTP.ts +1 -1
  118. package/front_end/models/trace_source_maps_resolver/SourceMapsResolver.ts +2 -2
  119. package/front_end/models/workspace_diff/WorkspaceDiff.ts +14 -9
  120. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +2 -15
  121. package/front_end/panels/ai_assistance/ai_assistance.ts +1 -2
  122. package/front_end/panels/ai_assistance/components/ChatInput.ts +23 -19
  123. package/front_end/panels/ai_assistance/components/ChatMessage.ts +9 -18
  124. package/front_end/panels/ai_assistance/components/ChatView.ts +2 -35
  125. package/front_end/panels/ai_assistance/components/DisabledWidget.ts +1 -1
  126. package/front_end/panels/ai_assistance/components/ExploreWidget.ts +4 -4
  127. package/front_end/panels/ai_assistance/components/ImageResize.ts +74 -0
  128. package/front_end/panels/ai_assistance/components/WalkthroughView.ts +2 -2
  129. package/front_end/panels/animation/AnimationGroupPreviewUI.ts +28 -29
  130. package/front_end/panels/animation/AnimationTimeline.ts +3 -3
  131. package/front_end/panels/animation/animationTimeline.css +0 -2
  132. package/front_end/panels/application/AppManifestView.ts +1 -1
  133. package/front_end/panels/application/ApplicationPanelSidebar.ts +1 -1
  134. package/front_end/panels/application/CookieItemsView.ts +1 -1
  135. package/front_end/panels/application/CrashReportContextView.ts +3 -3
  136. package/front_end/panels/application/DeviceBoundSessionsModel.ts +1 -1
  137. package/front_end/panels/application/DeviceBoundSessionsTreeElement.ts +1 -1
  138. package/front_end/panels/application/DeviceBoundSessionsView.ts +1 -1
  139. package/front_end/panels/application/IndexedDBViews.ts +1 -1
  140. package/front_end/panels/application/KeyValueStorageItemsView.ts +1 -1
  141. package/front_end/panels/application/OriginTrialTreeView.ts +1 -1
  142. package/front_end/panels/application/ServiceWorkersView.ts +6 -6
  143. package/front_end/panels/application/StorageBucketsTreeElement.ts +1 -1
  144. package/front_end/panels/application/StorageItemsToolbar.ts +3 -3
  145. package/front_end/panels/application/WebMCPView.ts +7 -5
  146. package/front_end/panels/application/components/AdsView.ts +21 -6
  147. package/front_end/panels/application/components/BackForwardCacheView.ts +2 -2
  148. package/front_end/panels/application/components/ProtocolHandlersView.ts +1 -1
  149. package/front_end/panels/application/components/StorageMetadataView.ts +1 -1
  150. package/front_end/panels/application/preloading/components/MismatchedPreloadingGrid.ts +2 -2
  151. package/front_end/panels/application/preloading/components/PreloadingDetailsReportView.ts +2 -1
  152. package/front_end/panels/application/preloading/components/PreloadingString.ts +3 -3
  153. package/front_end/panels/application/preloading/components/UsedPreloadingView.ts +2 -1
  154. package/front_end/panels/autofill/AutofillView.ts +1 -1
  155. package/front_end/panels/browser_debugger/DOMBreakpointsSidebarPane.ts +1 -1
  156. package/front_end/panels/browser_debugger/XHRBreakpointsSidebarPane.ts +2 -2
  157. package/front_end/panels/changes/ChangesSidebar.ts +2 -2
  158. package/front_end/panels/changes/ChangesView.ts +4 -5
  159. package/front_end/panels/changes/CombinedDiffView.ts +3 -3
  160. package/front_end/panels/changes/changes-meta.ts +2 -2
  161. package/front_end/panels/common/AiCodeCompletionTeaser.ts +1 -1
  162. package/front_end/panels/common/AiCodeGenerationTeaser.ts +3 -3
  163. package/front_end/panels/common/BadgeNotification.ts +8 -8
  164. package/front_end/panels/common/DOMLinkifier.ts +1 -1
  165. package/front_end/panels/common/GdpSignUpDialog.ts +2 -2
  166. package/front_end/panels/common/GeminiRebrandPromoDialog.ts +1 -1
  167. package/front_end/panels/common/aiCodeCompletionDisclaimer.css +0 -1
  168. package/front_end/panels/console/ConsoleInsightTeaser.ts +1 -1
  169. package/front_end/panels/console/ConsolePinPane.ts +3 -3
  170. package/front_end/panels/console/ConsolePrompt.ts +6 -4
  171. package/front_end/panels/console/ConsoleSidebar.ts +8 -10
  172. package/front_end/panels/console_counters/WarningErrorCounter.ts +10 -11
  173. package/front_end/panels/coverage/CoverageView.ts +2 -2
  174. package/front_end/panels/css_overview/CSSOverviewCompletedView.ts +3 -3
  175. package/front_end/panels/css_overview/CSSOverviewSidebarPanel.ts +1 -1
  176. package/front_end/panels/developer_resources/DeveloperResourcesView.ts +1 -1
  177. package/front_end/panels/elements/CSSRuleValidator.ts +1 -1
  178. package/front_end/panels/elements/ComputedStyleWidget.ts +3 -2
  179. package/front_end/panels/elements/ElementsTreeElement.ts +3 -3
  180. package/front_end/panels/elements/EventListenersWidget.ts +1 -3
  181. package/front_end/panels/elements/LayoutPane.ts +23 -13
  182. package/front_end/panels/elements/StandaloneStylesContainer.ts +7 -7
  183. package/front_end/panels/elements/StylePropertiesSection.ts +33 -5
  184. package/front_end/panels/elements/StylePropertyTreeElement.ts +5 -5
  185. package/front_end/panels/elements/StylesAiCodeCompletionProvider.ts +6 -6
  186. package/front_end/panels/elements/StylesSidebarPane.ts +4 -3
  187. package/front_end/panels/elements/elements-meta.ts +18 -2
  188. package/front_end/panels/emulation/DeviceModeToolbar.ts +100 -40
  189. package/front_end/panels/emulation/DeviceModeView.ts +5 -4
  190. package/front_end/panels/emulation/MediaQueryInspector.ts +35 -19
  191. package/front_end/panels/event_listeners/EventListenersView.ts +4 -4
  192. package/front_end/panels/explain/components/ConsoleInsight.ts +8 -9
  193. package/front_end/panels/explain/explain-meta.ts +3 -3
  194. package/front_end/panels/layer_viewer/LayerTreeOutline.ts +135 -167
  195. package/front_end/panels/layer_viewer/Layers3DView.ts +10 -23
  196. package/front_end/panels/layer_viewer/layer_viewer-meta.ts +27 -0
  197. package/front_end/panels/lighthouse/LighthouseController.ts +44 -55
  198. package/front_end/panels/lighthouse/LighthousePanel.ts +9 -9
  199. package/front_end/panels/lighthouse/LighthouseReportSelector.ts +2 -2
  200. package/front_end/panels/lighthouse/LighthouseStartView.ts +9 -12
  201. package/front_end/panels/lighthouse/LighthouseStatusView.ts +33 -33
  202. package/front_end/panels/lighthouse/RadioSetting.ts +1 -1
  203. package/front_end/panels/lighthouse/lighthouse-meta.ts +131 -1
  204. package/front_end/panels/media/EventDisplayTable.ts +67 -94
  205. package/front_end/panels/media/PlayerListView.ts +1 -1
  206. package/front_end/panels/media/eventDisplayTable.css +9 -4
  207. package/front_end/panels/mobile_throttling/NetworkThrottlingSelector.ts +5 -5
  208. package/front_end/panels/mobile_throttling/ThrottlingSettingsTab.ts +1 -1
  209. package/front_end/panels/network/EventSourceMessagesView.ts +98 -107
  210. package/front_end/panels/network/NetworkLogViewColumns.ts +1 -1
  211. package/front_end/panels/network/NetworkWaterfallColumn.ts +1 -1
  212. package/front_end/panels/network/RequestConditionsDrawer.ts +2 -2
  213. package/front_end/panels/network/RequestCookiesView.ts +2 -2
  214. package/front_end/panels/network/RequestHeadersView.ts +5 -5
  215. package/front_end/panels/network/RequestPayloadView.ts +4 -4
  216. package/front_end/panels/network/RequestTimingView.ts +2 -2
  217. package/front_end/panels/network/components/DirectSocketConnectionView.ts +1 -1
  218. package/front_end/panels/network/eventSourceMessagesView.css +12 -3
  219. package/front_end/panels/network/networkTimingTable.css +2 -2
  220. package/front_end/panels/performance_monitor/PerformanceMonitor.ts +1 -1
  221. package/front_end/panels/profiler/BottomUpProfileDataGrid.ts +25 -29
  222. package/front_end/panels/profiler/HeapProfileView.ts +308 -247
  223. package/front_end/panels/profiler/HeapSnapshotDataGrids.ts +13 -3
  224. package/front_end/panels/profiler/HeapSnapshotView.ts +30 -10
  225. package/front_end/panels/profiler/HeapTimelineOverview.ts +5 -2
  226. package/front_end/panels/profiler/ProfileDataGrid.ts +128 -157
  227. package/front_end/panels/profiler/ProfileFlameChartDataProvider.ts +17 -5
  228. package/front_end/panels/profiler/ProfilesPanel.ts +2 -2
  229. package/front_end/panels/profiler/TopDownProfileDataGrid.ts +17 -21
  230. package/front_end/panels/profiler/profilesPanel.css +9 -13
  231. package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +2 -2
  232. package/front_end/panels/recorder/CreateRecordingView.ts +4 -4
  233. package/front_end/panels/recorder/RecorderPanel.ts +6 -6
  234. package/front_end/panels/recorder/RecordingView.ts +1 -1
  235. package/front_end/panels/recorder/ReplaySection.ts +1 -1
  236. package/front_end/panels/recorder/StepView.ts +1 -1
  237. package/front_end/panels/recorder/injected/rollup.config.mjs +1 -1
  238. package/front_end/panels/search/SearchView.ts +1 -1
  239. package/front_end/panels/security/SecurityPanel.ts +54 -41
  240. package/front_end/panels/sensors/LocationsSettingsTab.ts +246 -233
  241. package/front_end/panels/sensors/SensorsView.ts +1 -1
  242. package/front_end/panels/settings/AISettingsTab.ts +11 -10
  243. package/front_end/panels/settings/SettingsScreen.ts +29 -24
  244. package/front_end/panels/settings/emulation/components/UserAgentClientHintsForm.ts +2 -2
  245. package/front_end/panels/sources/AiCodeCompletionPlugin.ts +5 -5
  246. package/front_end/panels/sources/BreakpointEditDialog.ts +2 -2
  247. package/front_end/panels/sources/BreakpointsView.ts +1 -1
  248. package/front_end/panels/sources/CallStackSidebarPane.ts +2 -2
  249. package/front_end/panels/sources/DebuggerPausedMessage.ts +2 -2
  250. package/front_end/panels/sources/DebuggerPlugin.ts +25 -22
  251. package/front_end/panels/sources/ScopeChainSidebarPane.ts +3 -1
  252. package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +7 -5
  253. package/front_end/panels/sources/sources-meta.ts +1 -1
  254. package/front_end/panels/timeline/CountersGraph.ts +1 -2
  255. package/front_end/panels/timeline/ExtensionTrackAppender.ts +1 -1
  256. package/front_end/panels/timeline/TimelineDetailsView.ts +2 -2
  257. package/front_end/panels/timeline/TimelineFlameChartDataProvider.ts +2 -2
  258. package/front_end/panels/timeline/TimelineFlameChartView.ts +4 -4
  259. package/front_end/panels/timeline/TimelinePaintProfilerView.ts +1 -1
  260. package/front_end/panels/timeline/TimelinePanel.ts +53 -81
  261. package/front_end/panels/timeline/TimelineSelectorStatsView.ts +10 -3
  262. package/front_end/panels/timeline/TimelineUIUtils.ts +18 -4
  263. package/front_end/panels/timeline/TrackConfigBanner.ts +1 -1
  264. package/front_end/panels/timeline/components/ExportTraceOptions.ts +1 -1
  265. package/front_end/panels/timeline/components/LayoutShiftDetails.ts +8 -9
  266. package/front_end/panels/timeline/components/NetworkRequestTooltip.ts +1 -1
  267. package/front_end/panels/timeline/components/TimelineRangeSummaryView.ts +1 -1
  268. package/front_end/panels/timeline/components/insights/DuplicatedJavaScript.ts +2 -2
  269. package/front_end/panels/timeline/components/insights/LCPBreakdown.ts +1 -1
  270. package/front_end/panels/timeline/components/insights/LegacyJavaScript.ts +1 -1
  271. package/front_end/panels/timeline/components/insights/SlowCSSSelector.ts +2 -2
  272. package/front_end/panels/timeline/overlays/OverlaysImpl.ts +5 -0
  273. package/front_end/panels/timeline/overlays/components/TimespanBreakdownOverlay.ts +13 -8
  274. package/front_end/panels/timeline/overlays/components/timespanBreakdownOverlay.css +1 -0
  275. package/front_end/panels/timeline/timeline-meta.ts +169 -0
  276. package/front_end/panels/timeline/timelineFlameChartView.css +5 -0
  277. package/front_end/panels/webauthn/WebauthnPane.ts +1 -1
  278. package/front_end/panels/whats_new/ReleaseNoteText.ts +9 -9
  279. package/front_end/panels/whats_new/resources/WNDT.md +7 -8
  280. package/front_end/third_party/chromium/README.chromium +1 -1
  281. package/front_end/third_party/web-vitals/README.chromium +2 -2
  282. package/front_end/third_party/web-vitals/package/README.md +120 -19
  283. package/front_end/third_party/web-vitals/package/attribution.d.ts +16 -0
  284. package/front_end/third_party/web-vitals/package/attribution.js +18 -0
  285. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onCLS.d.ts +1 -1
  286. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onFCP.d.ts +1 -7
  287. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onFCP.js +53 -32
  288. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onINP.d.ts +2 -2
  289. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onINP.js +43 -12
  290. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onLCP.d.ts +1 -1
  291. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onLCP.js +21 -3
  292. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onTTFB.d.ts +1 -1
  293. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onTTFB.js +30 -24
  294. package/front_end/third_party/web-vitals/package/dist/modules/lib/FCPEntryManager.d.ts +3 -0
  295. package/front_end/third_party/web-vitals/package/dist/modules/lib/FCPEntryManager.js +18 -0
  296. package/front_end/third_party/web-vitals/package/dist/modules/lib/InteractionManager.d.ts +2 -1
  297. package/front_end/third_party/web-vitals/package/dist/modules/lib/InteractionManager.js +18 -2
  298. package/front_end/third_party/web-vitals/package/dist/modules/lib/LCPEntryManager.d.ts +1 -0
  299. package/front_end/third_party/web-vitals/package/dist/modules/lib/LCPEntryManager.js +1 -0
  300. package/front_end/third_party/web-vitals/package/dist/modules/lib/bindReporter.d.ts +1 -1
  301. package/front_end/third_party/web-vitals/package/dist/modules/lib/generateUniqueID.js +1 -1
  302. package/front_end/third_party/web-vitals/package/dist/modules/lib/getLoadState.d.ts +1 -1
  303. package/front_end/third_party/web-vitals/package/dist/modules/lib/getLoadState.js +7 -7
  304. package/front_end/third_party/web-vitals/package/dist/modules/lib/getSelector.js +1 -1
  305. package/front_end/third_party/web-vitals/package/dist/modules/lib/getVisibilityWatcher.d.ts +1 -1
  306. package/front_end/third_party/web-vitals/package/dist/modules/lib/getVisibilityWatcher.js +4 -1
  307. package/front_end/third_party/web-vitals/package/dist/modules/lib/initMetric.d.ts +7 -3
  308. package/front_end/third_party/web-vitals/package/dist/modules/lib/initMetric.js +20 -11
  309. package/front_end/third_party/web-vitals/package/dist/modules/lib/initUnique.js +8 -3
  310. package/front_end/third_party/web-vitals/package/dist/modules/lib/observe.d.ts +3 -1
  311. package/front_end/third_party/web-vitals/package/dist/modules/lib/observe.js +19 -4
  312. package/front_end/third_party/web-vitals/package/dist/modules/lib/polyfills/interactionCountPolyfill.js +1 -1
  313. package/front_end/third_party/web-vitals/package/dist/modules/lib/softNavs.d.ts +3 -0
  314. package/front_end/third_party/web-vitals/package/dist/modules/lib/softNavs.js +38 -0
  315. package/front_end/third_party/web-vitals/package/dist/modules/lib/whenIdleOrHidden.js +5 -1
  316. package/front_end/third_party/web-vitals/package/dist/modules/onCLS.d.ts +1 -1
  317. package/front_end/third_party/web-vitals/package/dist/modules/onCLS.js +30 -11
  318. package/front_end/third_party/web-vitals/package/dist/modules/onFCP.d.ts +1 -1
  319. package/front_end/third_party/web-vitals/package/dist/modules/onFCP.js +36 -4
  320. package/front_end/third_party/web-vitals/package/dist/modules/onINP.d.ts +1 -1
  321. package/front_end/third_party/web-vitals/package/dist/modules/onINP.js +42 -22
  322. package/front_end/third_party/web-vitals/package/dist/modules/onLCP.d.ts +1 -1
  323. package/front_end/third_party/web-vitals/package/dist/modules/onLCP.js +109 -30
  324. package/front_end/third_party/web-vitals/package/dist/modules/onTTFB.d.ts +1 -1
  325. package/front_end/third_party/web-vitals/package/dist/modules/onTTFB.js +25 -7
  326. package/front_end/third_party/web-vitals/package/dist/modules/types/base.d.ts +24 -1
  327. package/front_end/third_party/web-vitals/package/dist/modules/types/fcp.d.ts +1 -1
  328. package/front_end/third_party/web-vitals/package/dist/modules/types/inp.d.ts +14 -6
  329. package/front_end/third_party/web-vitals/package/dist/modules/types/lcp.d.ts +1 -1
  330. package/front_end/third_party/web-vitals/package/dist/modules/types/ttfb.d.ts +2 -2
  331. package/front_end/third_party/web-vitals/package/dist/modules/types.d.ts +26 -4
  332. package/front_end/third_party/web-vitals/package/package.json +21 -22
  333. package/front_end/third_party/web-vitals/package/src/attribution/onCLS.ts +1 -1
  334. package/front_end/third_party/web-vitals/package/src/attribution/onFCP.ts +62 -39
  335. package/front_end/third_party/web-vitals/package/src/attribution/onINP.ts +52 -15
  336. package/front_end/third_party/web-vitals/package/src/attribution/onLCP.ts +25 -7
  337. package/front_end/third_party/web-vitals/package/src/attribution/onTTFB.ts +43 -37
  338. package/front_end/third_party/web-vitals/package/src/lib/{polyfills/getFirstHiddenTimePolyfill.ts → FCPEntryManager.ts} +4 -14
  339. package/front_end/third_party/web-vitals/package/src/lib/InteractionManager.ts +22 -2
  340. package/front_end/third_party/web-vitals/package/src/lib/LCPEntryManager.ts +1 -0
  341. package/front_end/third_party/web-vitals/package/src/lib/bindReporter.ts +1 -1
  342. package/front_end/third_party/web-vitals/package/src/lib/generateUniqueID.ts +1 -1
  343. package/front_end/third_party/web-vitals/package/src/lib/getLoadState.ts +11 -12
  344. package/front_end/third_party/web-vitals/package/src/lib/getSelector.ts +1 -1
  345. package/front_end/third_party/web-vitals/package/src/lib/getVisibilityWatcher.ts +4 -1
  346. package/front_end/third_party/web-vitals/package/src/lib/initMetric.ts +24 -11
  347. package/front_end/third_party/web-vitals/package/src/lib/initUnique.ts +12 -4
  348. package/front_end/third_party/web-vitals/package/src/lib/observe.ts +26 -5
  349. package/front_end/third_party/web-vitals/package/src/lib/polyfills/interactionCountPolyfill.ts +1 -1
  350. package/front_end/third_party/web-vitals/package/src/lib/softNavs.ts +48 -0
  351. package/front_end/third_party/web-vitals/package/src/lib/whenIdleOrHidden.ts +12 -4
  352. package/front_end/third_party/web-vitals/package/src/onCLS.ts +75 -18
  353. package/front_end/third_party/web-vitals/package/src/onFCP.ts +66 -7
  354. package/front_end/third_party/web-vitals/package/src/onINP.ts +100 -39
  355. package/front_end/third_party/web-vitals/package/src/onLCP.ts +169 -34
  356. package/front_end/third_party/web-vitals/package/src/onTTFB.ts +50 -13
  357. package/front_end/third_party/web-vitals/package/src/types/base.ts +31 -10
  358. package/front_end/third_party/web-vitals/package/src/types/fcp.ts +1 -1
  359. package/front_end/third_party/web-vitals/package/src/types/inp.ts +14 -6
  360. package/front_end/third_party/web-vitals/package/src/types/lcp.ts +1 -1
  361. package/front_end/third_party/web-vitals/package/src/types/ttfb.ts +2 -2
  362. package/front_end/third_party/web-vitals/package/src/types.ts +32 -9
  363. package/front_end/third_party/web-vitals/patches/0001-Add-onEachInteraction-to-onINP-options.patch +11 -11
  364. package/front_end/third_party/web-vitals/rebuild.sh +2 -2
  365. package/front_end/third_party/web-vitals/web-vitals-tsconfig.json +2 -0
  366. package/front_end/ui/components/buttons/Button.ts +16 -0
  367. package/front_end/ui/components/dialogs/Dialog.ts +1 -1
  368. package/front_end/ui/components/highlighting/HighlightManager.ts +6 -1
  369. package/front_end/ui/components/highlighting/highlighting.ts +1 -1
  370. package/front_end/ui/components/icon_button/FileSourceIcon.ts +1 -1
  371. package/front_end/ui/components/linkifier/LinkifierImpl.ts +1 -1
  372. package/front_end/ui/components/markdown_view/MarkdownLinksMap.ts +2 -2
  373. package/front_end/ui/components/settings/SettingCheckbox.ts +12 -7
  374. package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +2 -2
  375. package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +6 -6
  376. package/front_end/ui/components/text_editor/javascript.ts +3 -1
  377. package/front_end/ui/components/tooltips/Tooltip.ts +1 -1
  378. package/front_end/ui/legacy/ContextMenu.ts +12 -2
  379. package/front_end/ui/legacy/ListControl.ts +1 -1
  380. package/front_end/ui/legacy/SelectMenu.docs.ts +17 -19
  381. package/front_end/ui/legacy/Toolbar.ts +4 -1
  382. package/front_end/ui/legacy/Treeoutline.ts +1 -1
  383. package/front_end/ui/legacy/components/color_picker/spectrum.css +1 -2
  384. package/front_end/ui/legacy/components/data_grid/DataGrid.ts +1 -1
  385. package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +50 -4
  386. package/front_end/ui/legacy/components/object_ui/JavaScriptREPL.ts +3 -1
  387. package/front_end/ui/legacy/components/perf_ui/ChartViewport.ts +4 -4
  388. package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +8 -7
  389. package/front_end/ui/legacy/components/quick_open/CommandMenu.ts +14 -11
  390. package/front_end/ui/legacy/components/quick_open/QuickOpen.ts +1 -1
  391. package/front_end/ui/legacy/components/settings_ui/SettingsUI.ts +15 -5
  392. package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +4 -4
  393. package/front_end/ui/legacy/components/utils/Linkifier.ts +5 -1
  394. package/front_end/ui/lit/render.ts +1 -1
  395. package/front_end/ui/settings/SettingUIRegistration.ts +8 -3
  396. package/front_end/ui/visual_logging/KnownContextValues.ts +8 -0
  397. package/front_end/ui/visual_logging/LoggingEvents.ts +1 -1
  398. package/inspector_overlay/main.ts +1 -1
  399. package/mcp/mcp.ts +5 -4
  400. package/package.json +13 -13
  401. package/front_end/models/ai_assistance/AgentProject.ts +0 -261
  402. package/front_end/models/ai_assistance/agents/PatchAgent.ts +0 -306
  403. package/front_end/models/issues_manager/CheckFormsIssuesTrigger.ts +0 -45
  404. package/front_end/models/text_utils/text_utils.ts +0 -5
  405. package/front_end/panels/ai_assistance/PatchWidget.ts +0 -867
  406. package/front_end/panels/ai_assistance/SelectWorkspaceDialog.ts +0 -368
  407. package/front_end/panels/ai_assistance/selectWorkspaceDialog.css +0 -92
@@ -1,867 +0,0 @@
1
- // Copyright 2025 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 '../../ui/legacy/legacy.js';
6
- import '../../ui/components/markdown_view/markdown_view.js';
7
- import '../../ui/components/spinners/spinners.js';
8
- import '../../ui/kit/kit.js';
9
-
10
- import * as Common from '../../core/common/common.js';
11
- import * as Host from '../../core/host/host.js';
12
- import * as i18n from '../../core/i18n/i18n.js';
13
- import * as Platform from '../../core/platform/platform.js';
14
- import * as Root from '../../core/root/root.js';
15
- import * as AiAssistanceModel from '../../models/ai_assistance/ai_assistance.js';
16
- import * as Persistence from '../../models/persistence/persistence.js';
17
- import * as Workspace from '../../models/workspace/workspace.js';
18
- import * as WorkspaceDiff from '../../models/workspace_diff/workspace_diff.js';
19
- import * as Buttons from '../../ui/components/buttons/buttons.js';
20
- import * as UI from '../../ui/legacy/legacy.js';
21
- import {Directives, html, type LitTemplate, nothing, render} from '../../ui/lit/lit.js';
22
- import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
23
- import * as ChangesPanel from '../changes/changes.js';
24
- import * as PanelCommon from '../common/common.js';
25
-
26
- import {SelectWorkspaceDialog} from './SelectWorkspaceDialog.js';
27
-
28
- /*
29
- * Strings that don't need to be translated at this time.
30
- */
31
- const UIStringsNotTranslate = {
32
- /**
33
- * @description Text displayed for showing patch widget view.
34
- */
35
- unsavedChanges: 'Unsaved changes',
36
- /**
37
- * @description Loading text displayed as a summary title when the patch suggestion is getting loaded
38
- */
39
- applyingToWorkspace: 'Applying to workspace…',
40
- /**
41
- * @description Button text for staging changes to workspace.
42
- */
43
- applyToWorkspace: 'Apply to workspace',
44
- /**
45
- * @description Button text to change the selected workspace
46
- */
47
- change: 'Change',
48
- /**
49
- * @description Accessible title of the Change button to indicate that
50
- * the button can be used to change the root folder.
51
- */
52
- changeRootFolder: 'Change project root folder',
53
- /**
54
- * @description Button text to cancel applying to workspace
55
- */
56
- cancel: 'Cancel',
57
- /**
58
- * @description Button text to discard the suggested changes and not save them to file system
59
- */
60
- discard: 'Discard',
61
- /**
62
- * @description Button text to save all the suggested changes to file system
63
- */
64
- saveAll: 'Save all',
65
- /**
66
- * @description Header text after the user saved the changes to the disk.
67
- */
68
- savedToDisk: 'Saved to disk',
69
- /**
70
- * @description Disclaimer text shown for using code snippets with caution
71
- */
72
- codeDisclaimer: 'Use code snippets with caution',
73
- /**
74
- * @description Tooltip text for the info icon beside the "Apply to workspace" button
75
- */
76
- applyToWorkspaceTooltip: 'Source code from the selected folder is sent to Google to generate code suggestions.',
77
- /**
78
- * @description Tooltip text for the info icon beside the "Apply to workspace" button when enterprise logging is off
79
- */
80
- applyToWorkspaceTooltipNoLogging:
81
- 'Source code from the selected folder is sent to Google to generate code suggestions. This data will not be used to improve Google’s AI models.',
82
- /**
83
- * @description The footer disclaimer that links to more information
84
- * about the AI feature. Same text as in ChatView.
85
- */
86
- learnMore: 'Learn more',
87
- /**
88
- * @description Header text for the AI-powered code suggestions disclaimer dialog.
89
- */
90
- freDisclaimerHeader: 'Apply changes directly to your project’s source code',
91
- /**
92
- * @description First disclaimer item text for the fre dialog.
93
- */
94
- freDisclaimerTextAiWontAlwaysGetItRight: 'This feature uses AI and won’t always get it right',
95
- /**
96
- * @description Second disclaimer item text for the fre dialog.
97
- */
98
- freDisclaimerTextPrivacy:
99
- 'To generate code suggestions, source code from the selected folder is sent to Google. This data may be seen by human reviewers to improve this feature.',
100
- /**
101
- * @description Second disclaimer item text for the fre dialog when enterprise logging is off.
102
- */
103
- freDisclaimerTextPrivacyNoLogging:
104
- 'To generate code suggestions, source code from the selected folder is sent to Google. This data will not be used to improve Google’s AI models. Your organization may change these settings at any time.',
105
- /**
106
- * @description Third disclaimer item text for the fre dialog.
107
- */
108
- freDisclaimerTextUseWithCaution: 'Use generated code snippets with caution',
109
- /**
110
- * @description Title of the link opening data that was used to
111
- * produce a code suggestion.
112
- */
113
- viewUploadedFiles: 'View data sent to Google',
114
- /**
115
- * @description Text indicating that a link opens in a new tab (for a11y).
116
- */
117
- opensInNewTab: '(opens in a new tab)',
118
- /**
119
- * @description Generic error text for the case the changes were not applied to the workspace.
120
- */
121
- genericErrorMessage: 'Changes couldn’t be applied to your workspace.',
122
- } as const;
123
-
124
- const lockedString = i18n.i18n.lockedString;
125
-
126
- const CODE_SNIPPET_WARNING_URL = 'https://support.google.com/legal/answer/13505487';
127
- const {widget} = UI.Widget;
128
-
129
- export enum PatchSuggestionState {
130
- /**
131
- * The user did not attempt patching yet
132
- */
133
- INITIAL = 'initial',
134
- /**
135
- * Applying to page tree is in progress
136
- */
137
- LOADING = 'loading',
138
- /**
139
- * Applying to page tree succeeded
140
- */
141
- SUCCESS = 'success',
142
- /**
143
- * Applying to page tree failed
144
- */
145
- ERROR = 'error',
146
- }
147
-
148
- enum SelectedProjectType {
149
- /**
150
- * No project selected
151
- */
152
- NONE = 'none',
153
- /**
154
- * The selected project is not an automatic workspace project
155
- */
156
- REGULAR = 'regular',
157
- /**
158
- * The selected project is a disconnected automatic workspace project
159
- */
160
- AUTOMATIC_DISCONNECTED = 'automaticDisconnected',
161
- /**
162
- * The selected project is a connected automatic workspace project
163
- */
164
- AUTOMATIC_CONNECTED = 'automaticConnected',
165
- }
166
-
167
- export interface ViewInput {
168
- workspaceDiff: WorkspaceDiff.WorkspaceDiff.WorkspaceDiffImpl;
169
- patchSuggestionState: PatchSuggestionState;
170
- changeSummary?: string;
171
- sources?: string;
172
- projectName: string;
173
- projectPath: Platform.DevToolsPath.RawPathString;
174
- projectType: SelectedProjectType;
175
- savedToDisk?: boolean;
176
- applyToWorkspaceTooltipText: Platform.UIString.LocalizedString;
177
- onLearnMoreTooltipClick: () => void;
178
- onApplyToWorkspace: () => void;
179
- onCancel: () => void;
180
- onDiscard: () => void;
181
- onSaveAll: () => void;
182
- onChangeWorkspaceClick?: () => void;
183
- }
184
-
185
- export interface ViewOutput {
186
- changeRef?: Directives.Ref<HTMLElement>;
187
- summaryRef?: Directives.Ref<HTMLElement>;
188
- }
189
-
190
- type View = (input: ViewInput, output: ViewOutput, target: HTMLElement) => void;
191
- const DEFAULT_VIEW: View = (input, output, target) => {
192
- if (!input.changeSummary && input.patchSuggestionState === PatchSuggestionState.INITIAL) {
193
- return;
194
- }
195
-
196
- output.changeRef = output.changeRef ?? Directives.createRef<HTMLElement>();
197
- output.summaryRef = output.summaryRef ?? Directives.createRef<HTMLElement>();
198
-
199
- function renderSourcesLink(): LitTemplate {
200
- if (!input.sources) {
201
- return nothing;
202
- }
203
-
204
- return html`<devtools-link
205
- class="link"
206
- title="${UIStringsNotTranslate.viewUploadedFiles} ${UIStringsNotTranslate.opensInNewTab}"
207
- href="data:text/plain;charset=utf-8,${encodeURIComponent(input.sources)}"
208
- jslogcontext="files-used-in-patching">
209
- ${UIStringsNotTranslate.viewUploadedFiles}
210
- </devtools-link>`;
211
- }
212
-
213
- function renderHeader(): LitTemplate {
214
- if (input.savedToDisk) {
215
- return html`
216
- <devtools-icon class="green-bright-icon summary-badge" name="check-circle"></devtools-icon>
217
- <span class="header-text">
218
- ${lockedString(UIStringsNotTranslate.savedToDisk)}
219
- </span>
220
- `;
221
- }
222
-
223
- if (input.patchSuggestionState === PatchSuggestionState.SUCCESS) {
224
- return html`
225
- <devtools-icon class="on-tonal-icon summary-badge" name="difference"></devtools-icon>
226
- <span class="header-text">
227
- ${lockedString(`File changes in ${input.projectName}`)}
228
- </span>
229
- <devtools-icon
230
- class="arrow"
231
- name="chevron-down"
232
- ></devtools-icon>
233
- `;
234
- }
235
-
236
- return html`
237
- <devtools-icon class="on-tonal-icon summary-badge" name="pen-spark"></devtools-icon>
238
- <span class="header-text">
239
- ${lockedString(UIStringsNotTranslate.unsavedChanges)}
240
- </span>
241
- <devtools-icon
242
- class="arrow"
243
- name="chevron-down"
244
- ></devtools-icon>
245
- `;
246
- }
247
-
248
- function renderContent(): LitTemplate {
249
- if ((!input.changeSummary && input.patchSuggestionState === PatchSuggestionState.INITIAL) || input.savedToDisk) {
250
- return nothing;
251
- }
252
-
253
- if (input.patchSuggestionState === PatchSuggestionState.SUCCESS) {
254
- return html`${widget(ChangesPanel.CombinedDiffView.CombinedDiffView, {
255
- workspaceDiff: input.workspaceDiff,
256
- // Ignore user creates inspector-stylesheets
257
- ignoredUrls: ['inspector://']
258
- })}`;
259
- }
260
-
261
- return html`<devtools-code-block
262
- .code=${input.changeSummary ?? ''}
263
- .codeLang=${'css'}
264
- .displayNotice=${true}
265
- ></devtools-code-block>
266
- ${
267
- input.patchSuggestionState === PatchSuggestionState.ERROR ?
268
- html`<div class="error-container">
269
- <devtools-icon name="cross-circle-filled"></devtools-icon>${
270
- lockedString(UIStringsNotTranslate.genericErrorMessage)} ${renderSourcesLink()}
271
- </div>` :
272
- nothing}`;
273
- }
274
-
275
- function renderFooter(): LitTemplate {
276
- if (input.savedToDisk) {
277
- return nothing;
278
- }
279
-
280
- if (input.patchSuggestionState === PatchSuggestionState.SUCCESS) {
281
- return html`
282
- <div class="footer">
283
- <div class="left-side">
284
- <devtools-link class="link disclaimer-link" href="https://support.google.com/legal/answer/13505487" jslogcontext="code-disclaimer">
285
- ${lockedString(UIStringsNotTranslate.codeDisclaimer)}
286
- </devtools-link>
287
- ${renderSourcesLink()}
288
- </div>
289
- <div class="save-or-discard-buttons">
290
- <devtools-button
291
- @click=${input.onDiscard}
292
- .jslogContext=${'patch-widget.discard'}
293
- .variant=${Buttons.Button.Variant.OUTLINED}>
294
- ${lockedString(UIStringsNotTranslate.discard)}
295
- </devtools-button>
296
- <devtools-button
297
- @click=${input.onSaveAll}
298
- .jslogContext=${'patch-widget.save-all'}
299
- .variant=${Buttons.Button.Variant.PRIMARY}>
300
- ${lockedString(UIStringsNotTranslate.saveAll)}
301
- </devtools-button>
302
- </div>
303
- </div>
304
- `;
305
- }
306
-
307
- const iconName = input.projectType === SelectedProjectType.AUTOMATIC_DISCONNECTED ? 'folder-off' :
308
- input.projectType === SelectedProjectType.AUTOMATIC_CONNECTED ? 'folder-asterisk' :
309
- 'folder';
310
- return html`
311
- <div class="footer">
312
- ${
313
- input.projectName ? html`
314
- <div class="change-workspace" jslog=${VisualLogging.section('patch-widget.workspace')}>
315
- <devtools-icon .name=${iconName}></devtools-icon>
316
- <span class="folder-name" title=${input.projectPath}>${input.projectName}</span>
317
- ${
318
- input.onChangeWorkspaceClick ? html`
319
- <devtools-button
320
- @click=${input.onChangeWorkspaceClick}
321
- .jslogContext=${'change-workspace'}
322
- .variant=${Buttons.Button.Variant.TEXT}
323
- .title=${lockedString(UIStringsNotTranslate.changeRootFolder)}
324
- .disabled=${input.patchSuggestionState === PatchSuggestionState.LOADING}
325
- ${Directives.ref(output.changeRef)}
326
- >${lockedString(UIStringsNotTranslate.change)}</devtools-button>
327
- ` :
328
- nothing}
329
- </div>
330
- ` :
331
- nothing}
332
- <div class="apply-to-workspace-container" aria-live="polite">
333
- ${
334
- input.patchSuggestionState === PatchSuggestionState.LOADING ?
335
- html`
336
- <div class="loading-text-container" jslog=${
337
- VisualLogging.section('patch-widget.apply-to-workspace-loading')}>
338
- <devtools-spinner></devtools-spinner>
339
- <span>
340
- ${lockedString(UIStringsNotTranslate.applyingToWorkspace)}
341
- </span>
342
- </div>
343
- ` :
344
- html`
345
- <devtools-button
346
- @click=${input.onApplyToWorkspace}
347
- .jslogContext=${'patch-widget.apply-to-workspace'}
348
- .variant=${Buttons.Button.Variant.OUTLINED}>
349
- ${lockedString(UIStringsNotTranslate.applyToWorkspace)}
350
- </devtools-button>
351
- `}
352
- ${
353
- input.patchSuggestionState === PatchSuggestionState.LOADING ? html`<devtools-button
354
- @click=${input.onCancel}
355
- .jslogContext=${'cancel'}
356
- .variant=${Buttons.Button.Variant.OUTLINED}>
357
- ${lockedString(UIStringsNotTranslate.cancel)}
358
- </devtools-button>` :
359
- nothing}
360
- <devtools-button
361
- aria-details="info-tooltip"
362
- .jslogContext=${'patch-widget.info-tooltip-trigger'}
363
- .iconName=${'info'}
364
- .variant=${Buttons.Button.Variant.ICON}
365
- ></devtools-button>
366
- <devtools-tooltip
367
- id="info-tooltip"
368
- variant="rich"
369
- >
370
- <div class="info-tooltip-container">
371
- ${input.applyToWorkspaceTooltipText}
372
- <button
373
- class="link tooltip-link"
374
- role="link"
375
- jslog=${VisualLogging.link('open-ai-settings').track({
376
- click: true,
377
- })}
378
- @click=${input.onLearnMoreTooltipClick}
379
- >${lockedString(UIStringsNotTranslate.learnMore)}</button>
380
- </div>
381
- </devtools-tooltip>
382
- </div>
383
- </div>`;
384
- }
385
-
386
- // Use a simple div for the "Saved to disk" state as it's not expandable,
387
- // otherwise use the interactive <details> element.
388
- const template = input.savedToDisk ? html`
389
- <div class="change-summary saved-to-disk" role="status" aria-live="polite">
390
- <div class="header-container">
391
- ${renderHeader()}
392
- </div>
393
- </div>` :
394
- html`
395
- <details class="change-summary" jslog=${VisualLogging.section('patch-widget')}>
396
- <summary class="header-container" ${Directives.ref(output.summaryRef)}>
397
- ${renderHeader()}
398
- </summary>
399
- ${renderContent()}
400
- ${renderFooter()}
401
- </details>
402
- `;
403
-
404
- render(template, target);
405
- };
406
-
407
- export class PatchWidget extends UI.Widget.Widget {
408
- changeSummary = '';
409
- changeManager: AiAssistanceModel.ChangeManager.ChangeManager|undefined;
410
- // Whether the user completed first run experience dialog or not.
411
- #aiPatchingFreCompletedSetting =
412
- Common.Settings.Settings.instance().createSetting('ai-assistance-patching-fre-completed', false);
413
- #projectIdSetting =
414
- Common.Settings.Settings.instance().createSetting('ai-assistance-patching-selected-project-id', '');
415
- #view: View;
416
- #viewOutput: ViewOutput = {};
417
- #aidaClient: Host.AidaClient.AidaClient;
418
- #applyPatchAbortController?: AbortController;
419
- #project?: Workspace.Workspace.Project;
420
- #patchSources?: string;
421
- #savedToDisk?: boolean;
422
- #loggingEnabled: boolean; // Whether the enterprise setting is `ALLOW_WITHOUT_LOGGING` or not.
423
- #patchSuggestionState = PatchSuggestionState.INITIAL;
424
- #workspaceDiff = WorkspaceDiff.WorkspaceDiff.workspaceDiff();
425
- #workspace = Workspace.Workspace.WorkspaceImpl.instance();
426
- #automaticFileSystem =
427
- Persistence.AutomaticFileSystemManager.AutomaticFileSystemManager.instance().automaticFileSystem;
428
- #applyToDisconnectedAutomaticWorkspace = false;
429
- // `rpcId` from the `applyPatch` request
430
- #rpcId: Host.AidaClient.RpcGlobalId|null = null;
431
-
432
- constructor(element?: HTMLElement, view = DEFAULT_VIEW, opts?: {
433
- aidaClient: Host.AidaClient.AidaClient,
434
- }) {
435
- super(element);
436
- this.#aidaClient = opts?.aidaClient ?? new Host.AidaClient.AidaClient();
437
- this.#loggingEnabled = Root.Runtime.hostConfig.aidaAvailability?.enterprisePolicyValue !==
438
- Root.Runtime.GenAiEnterprisePolicyValue.ALLOW_WITHOUT_LOGGING;
439
- this.#view = view;
440
-
441
- this.requestUpdate();
442
- }
443
-
444
- #onLearnMoreTooltipClick(): void {
445
- void UI.ViewManager.ViewManager.instance().showView('chrome-ai');
446
- }
447
-
448
- #getDisplayedProject(): {projectName: string, projectPath: Platform.DevToolsPath.RawPathString} {
449
- if (this.#project) {
450
- return {
451
- projectName: Common.ParsedURL.ParsedURL.encodedPathToRawPathString(
452
- this.#project.displayName() as Platform.DevToolsPath.EncodedPathString),
453
- projectPath: Common.ParsedURL.ParsedURL.urlToRawPathString(
454
- this.#project.id() as Platform.DevToolsPath.UrlString, Host.Platform.isWin()),
455
- };
456
- }
457
- if (this.#automaticFileSystem) {
458
- return {
459
- projectName: Common.ParsedURL.ParsedURL.extractName(this.#automaticFileSystem.root),
460
- projectPath: this.#automaticFileSystem.root,
461
- };
462
- }
463
- return {
464
- projectName: '',
465
- projectPath: Platform.DevToolsPath.EmptyRawPathString,
466
- };
467
- }
468
-
469
- #shouldShowChangeButton(): boolean {
470
- const automaticFileSystemProject =
471
- this.#automaticFileSystem ? this.#workspace.projectForFileSystemRoot(this.#automaticFileSystem.root) : null;
472
- const regularProjects = this.#workspace.projectsForType(Workspace.Workspace.projectTypes.FileSystem)
473
- .filter(
474
- project => project instanceof Persistence.FileSystemWorkspaceBinding.FileSystem &&
475
- project.fileSystem().type() ===
476
- Persistence.PlatformFileSystem.PlatformFileSystemType.WORKSPACE_PROJECT)
477
- .filter(project => project !== automaticFileSystemProject);
478
- return regularProjects.length > 0;
479
- }
480
-
481
- #getSelectedProjectType(projectPath: Platform.DevToolsPath.RawPathString): SelectedProjectType {
482
- if (this.#automaticFileSystem && this.#automaticFileSystem.root === projectPath) {
483
- return this.#project ? SelectedProjectType.AUTOMATIC_CONNECTED : SelectedProjectType.AUTOMATIC_DISCONNECTED;
484
- }
485
- return this.#project ? SelectedProjectType.NONE : SelectedProjectType.REGULAR;
486
- }
487
-
488
- override performUpdate(): void {
489
- const {projectName, projectPath} = this.#getDisplayedProject();
490
-
491
- this.#view(
492
- {
493
- workspaceDiff: this.#workspaceDiff,
494
- changeSummary: this.changeSummary,
495
- patchSuggestionState: this.#patchSuggestionState,
496
- sources: this.#patchSources,
497
- projectName,
498
- projectPath,
499
- projectType: this.#getSelectedProjectType(projectPath),
500
- savedToDisk: this.#savedToDisk,
501
- applyToWorkspaceTooltipText: this.#loggingEnabled ?
502
- lockedString(UIStringsNotTranslate.applyToWorkspaceTooltip) :
503
- lockedString(UIStringsNotTranslate.applyToWorkspaceTooltipNoLogging),
504
- onLearnMoreTooltipClick: this.#onLearnMoreTooltipClick.bind(this),
505
- onApplyToWorkspace: this.#onApplyToWorkspace.bind(this),
506
- onCancel: () => {
507
- this.#applyPatchAbortController?.abort();
508
- },
509
- onDiscard: this.#onDiscard.bind(this),
510
- onSaveAll: this.#onSaveAll.bind(this),
511
- onChangeWorkspaceClick: this.#shouldShowChangeButton() ?
512
- this.#showSelectWorkspaceDialog.bind(this, {applyPatch: false}) :
513
- undefined,
514
- },
515
- this.#viewOutput, this.contentElement);
516
- }
517
-
518
- override wasShown(): void {
519
- super.wasShown();
520
- this.#selectDefaultProject();
521
-
522
- if (isAiAssistancePatchingEnabled()) {
523
- this.#workspace.addEventListener(Workspace.Workspace.Events.ProjectAdded, this.#onProjectAdded, this);
524
- this.#workspace.addEventListener(Workspace.Workspace.Events.ProjectRemoved, this.#onProjectRemoved, this);
525
- }
526
- }
527
-
528
- override willHide(): void {
529
- super.willHide();
530
- this.#applyToDisconnectedAutomaticWorkspace = false;
531
- if (isAiAssistancePatchingEnabled()) {
532
- this.#workspace.removeEventListener(Workspace.Workspace.Events.ProjectAdded, this.#onProjectAdded, this);
533
- this.#workspace.removeEventListener(Workspace.Workspace.Events.ProjectRemoved, this.#onProjectRemoved, this);
534
- }
535
- }
536
-
537
- async #showFreDisclaimerIfNeeded(): Promise<boolean> {
538
- const isAiPatchingFreCompleted = this.#aiPatchingFreCompletedSetting.get();
539
- if (isAiPatchingFreCompleted) {
540
- return true;
541
- }
542
-
543
- const iconName = AiAssistanceModel.AiUtils.getIconName();
544
- const result = await PanelCommon.FreDialog.show({
545
- header: {iconName, text: lockedString(UIStringsNotTranslate.freDisclaimerHeader)},
546
- reminderItems: [
547
- {
548
- iconName: 'psychiatry',
549
- content: lockedString(UIStringsNotTranslate.freDisclaimerTextAiWontAlwaysGetItRight),
550
- },
551
- {
552
- iconName: 'google',
553
- content: this.#loggingEnabled ? lockedString(UIStringsNotTranslate.freDisclaimerTextPrivacy) :
554
- lockedString(UIStringsNotTranslate.freDisclaimerTextPrivacyNoLogging),
555
- },
556
- {
557
- iconName: 'warning',
558
- // clang-format off
559
- content: html`<devtools-link
560
- href=${CODE_SNIPPET_WARNING_URL}
561
- class="link devtools-link"
562
- jslogcontext="code-snippets-explainer.patch-widget"
563
- >${lockedString(UIStringsNotTranslate.freDisclaimerTextUseWithCaution)}</devtools-link>`,
564
- // clang-format on
565
- }
566
- ],
567
- onLearnMoreClick: () => {
568
- void UI.ViewManager.ViewManager.instance().showView('chrome-ai');
569
- },
570
- ariaLabel: lockedString(UIStringsNotTranslate.freDisclaimerHeader),
571
- learnMoreButtonText: lockedString(UIStringsNotTranslate.learnMore),
572
- });
573
-
574
- if (result) {
575
- this.#aiPatchingFreCompletedSetting.set(true);
576
- }
577
- return result;
578
- }
579
-
580
- #selectDefaultProject(): void {
581
- const project = this.#automaticFileSystem ?
582
- this.#workspace.projectForFileSystemRoot(this.#automaticFileSystem.root) :
583
- this.#workspace.project(this.#projectIdSetting.get());
584
- if (project) {
585
- this.#project = project;
586
- } else {
587
- this.#project = undefined;
588
- this.#projectIdSetting.set('');
589
- }
590
- this.requestUpdate();
591
- }
592
-
593
- #onProjectAdded(event: Common.EventTarget.EventTargetEvent<Workspace.Workspace.Project>): void {
594
- const addedProject = event.data;
595
- if (this.#applyToDisconnectedAutomaticWorkspace && this.#automaticFileSystem &&
596
- addedProject === this.#workspace.projectForFileSystemRoot(this.#automaticFileSystem.root)) {
597
- this.#applyToDisconnectedAutomaticWorkspace = false;
598
- this.#project = addedProject;
599
- void this.#applyPatchAndUpdateUI();
600
- } else if (this.#project === undefined) {
601
- this.#selectDefaultProject();
602
- }
603
- }
604
-
605
- #onProjectRemoved(): void {
606
- if (this.#project && !this.#workspace.project(this.#project.id())) {
607
- this.#projectIdSetting.set('');
608
- this.#project = undefined;
609
- this.requestUpdate();
610
- }
611
- }
612
-
613
- #showSelectWorkspaceDialog(options: {applyPatch: boolean} = {applyPatch: false}): void {
614
- const onProjectSelected = (project: Workspace.Workspace.Project): void => {
615
- this.#project = project;
616
- this.#projectIdSetting.set(project.id());
617
- if (options.applyPatch) {
618
- void this.#applyPatchAndUpdateUI();
619
- } else {
620
- this.requestUpdate();
621
- void this.updateComplete.then(() => {
622
- this.contentElement?.querySelector('.apply-to-workspace-container devtools-button')
623
- ?.shadowRoot?.querySelector('button')
624
- ?.focus();
625
- });
626
- }
627
- };
628
-
629
- SelectWorkspaceDialog.show(onProjectSelected, this.#project);
630
- }
631
-
632
- async #onApplyToWorkspace(): Promise<void> {
633
- if (!isAiAssistancePatchingEnabled()) {
634
- return;
635
- }
636
-
637
- // Show the FRE dialog if needed and only continue when
638
- // the user accepted the disclaimer.
639
- const freDisclaimerCompleted = await this.#showFreDisclaimerIfNeeded();
640
- if (!freDisclaimerCompleted) {
641
- return;
642
- }
643
-
644
- if (this.#project) {
645
- await this.#applyPatchAndUpdateUI();
646
- } else if (this.#automaticFileSystem) {
647
- this.#applyToDisconnectedAutomaticWorkspace = true;
648
- await Persistence.AutomaticFileSystemManager.AutomaticFileSystemManager.instance().connectAutomaticFileSystem(
649
- /* addIfMissing= */ true);
650
- } else {
651
- this.#showSelectWorkspaceDialog({applyPatch: true});
652
- }
653
- }
654
-
655
- /**
656
- * The modified files excluding inspector stylesheets
657
- */
658
- get #modifiedFiles(): Workspace.UISourceCode.UISourceCode[] {
659
- return this.#workspaceDiff.modifiedUISourceCodes().filter(modifiedUISourceCode => {
660
- return !modifiedUISourceCode.url().startsWith('inspector://');
661
- });
662
- }
663
-
664
- async #applyPatchAndUpdateUI(): Promise<void> {
665
- const changeSummary = this.changeSummary;
666
- if (!changeSummary) {
667
- throw new Error('Change summary does not exist');
668
- }
669
-
670
- this.#patchSuggestionState = PatchSuggestionState.LOADING;
671
- this.#rpcId = null;
672
- this.requestUpdate();
673
- const {response, processedFiles} = await this.#applyPatch(changeSummary);
674
- if (response && 'rpcId' in response && response.rpcId) {
675
- this.#rpcId = response.rpcId;
676
- }
677
-
678
- // Determines if applying the patch resulted in any actual file changes in the workspace.
679
- // This is crucial because the agent might return an answer (e.g., an explanation)
680
- // without making any code modifications (i.e., no `writeFile` calls).
681
- // If no files were modified, we avoid transitioning to a success state,
682
- // which would otherwise lead to an empty and potentially confusing diff view.
683
- //
684
- // Note: The `hasChanges` check below is based on `modifiedUISourceCodes()`, which reflects
685
- // *all* current modifications in the workspace. It does not differentiate between
686
- // changes made by this specific AI patch operation versus pre-existing changes
687
- // made by the user. Consequently, if the AI patch itself makes no changes but the
688
- // user already had other modified files, the widget will still transition to the
689
- // success state (displaying all current workspace modifications).
690
- const hasChanges = this.#modifiedFiles.length > 0;
691
- if (response?.type === AiAssistanceModel.AiAgent.ResponseType.ANSWER && hasChanges) {
692
- this.#patchSuggestionState = PatchSuggestionState.SUCCESS;
693
- } else if (
694
- response?.type === AiAssistanceModel.AiAgent.ResponseType.ERROR &&
695
- response.error === AiAssistanceModel.AiAgent.ErrorType.ABORT) {
696
- // If this is an abort error, we're returning back to the initial state.
697
- this.#patchSuggestionState = PatchSuggestionState.INITIAL;
698
- } else {
699
- this.#patchSuggestionState = PatchSuggestionState.ERROR;
700
- }
701
- this.#patchSources = `Filenames in ${this.#project?.displayName()}.
702
- Files:
703
- ${processedFiles.map(filename => `* ${filename}`).join('\n')}`;
704
- this.requestUpdate();
705
-
706
- if (this.#patchSuggestionState === PatchSuggestionState.SUCCESS) {
707
- void this.updateComplete.then(() => {
708
- this.#viewOutput.summaryRef?.value?.focus();
709
- });
710
- }
711
- }
712
-
713
- #onDiscard(): void {
714
- for (const modifiedUISourceCode of this.#modifiedFiles) {
715
- modifiedUISourceCode.resetWorkingCopy();
716
- }
717
-
718
- this.#patchSuggestionState = PatchSuggestionState.INITIAL;
719
- this.#patchSources = undefined;
720
- void this.changeManager?.popStashedChanges();
721
- this.#submitRating(Host.AidaClient.Rating.NEGATIVE);
722
- this.requestUpdate();
723
- void this.updateComplete.then(() => {
724
- this.#viewOutput.changeRef?.value?.focus();
725
- });
726
- }
727
-
728
- #onSaveAll(): void {
729
- for (const modifiedUISourceCode of this.#modifiedFiles) {
730
- modifiedUISourceCode.commitWorkingCopy();
731
- }
732
- void this.changeManager?.stashChanges().then(() => {
733
- this.changeManager?.dropStashedChanges();
734
- });
735
-
736
- this.#savedToDisk = true;
737
- this.#submitRating(Host.AidaClient.Rating.POSITIVE);
738
- this.requestUpdate();
739
- }
740
-
741
- #submitRating(rating: Host.AidaClient.Rating): void {
742
- if (!this.#rpcId) {
743
- return;
744
- }
745
-
746
- void this.#aidaClient.registerClientEvent({
747
- corresponding_aida_rpc_global_id: this.#rpcId,
748
- disable_user_content_logging: true,
749
- do_conversation_client_event: {
750
- user_feedback: {
751
- sentiment: rating,
752
- },
753
- },
754
- });
755
- }
756
-
757
- async #applyPatch(changeSummary: string): Promise<{
758
- response: AiAssistanceModel.AiAgent.ResponseData | undefined,
759
- processedFiles: string[],
760
- }> {
761
- if (!this.#project) {
762
- throw new Error('Project does not exist');
763
- }
764
- this.#applyPatchAbortController = new AbortController();
765
- const agent = new AiAssistanceModel.PatchAgent.PatchAgent({
766
- aidaClient: this.#aidaClient,
767
- serverSideLoggingEnabled: false,
768
- project: this.#project,
769
- });
770
- const {responses, processedFiles} =
771
- await agent.applyChanges(changeSummary, {signal: this.#applyPatchAbortController.signal});
772
- return {
773
- response: responses.at(-1),
774
- processedFiles,
775
- };
776
- }
777
- }
778
-
779
- export function isAiAssistancePatchingEnabled(): boolean {
780
- return Boolean(Root.Runtime.hostConfig.devToolsFreestyler?.patching);
781
- }
782
-
783
- interface ExpectedChange {
784
- path: string;
785
- matches: string[];
786
- doesNotMatch?: string[];
787
- }
788
-
789
- // @ts-expect-error temporary global function for local testing.
790
- window.aiAssistanceTestPatchPrompt =
791
- async (projectName: string, changeSummary: string, expectedChanges: ExpectedChange[]) => {
792
- if (!isAiAssistancePatchingEnabled()) {
793
- return;
794
- }
795
- const workspaceDiff = WorkspaceDiff.WorkspaceDiff.workspaceDiff();
796
- const workspace = Workspace.Workspace.WorkspaceImpl.instance();
797
- const project = workspace.projectsForType(Workspace.Workspace.projectTypes.FileSystem)
798
- .filter(
799
- project => project instanceof Persistence.FileSystemWorkspaceBinding.FileSystem &&
800
- project.fileSystem().type() ===
801
- Persistence.PlatformFileSystem.PlatformFileSystemType.WORKSPACE_PROJECT)
802
- .find(project => project.displayName() === projectName);
803
-
804
- if (!project) {
805
- throw new Error('project not found');
806
- }
807
- const aidaClient = new Host.AidaClient.AidaClient();
808
- const agent = new AiAssistanceModel.PatchAgent.PatchAgent({
809
- aidaClient,
810
- serverSideLoggingEnabled: false,
811
- project,
812
- });
813
- try {
814
- const assertionFailures = [];
815
- const {processedFiles, responses} = await agent.applyChanges(changeSummary);
816
- if (responses.at(-1)?.type === AiAssistanceModel.AiAgent.ResponseType.ERROR) {
817
- return {
818
- error: 'failed to patch',
819
- debugInfo: {
820
- responses,
821
- processedFiles,
822
- },
823
- };
824
- }
825
- for (const file of processedFiles) {
826
- const change = expectedChanges.find(change => change.path === file);
827
- if (!change) {
828
- assertionFailures.push(`Patched ${file} that was not expected`);
829
- break;
830
- }
831
- const agentProject = agent.agentProject;
832
- const content = await agentProject.readFile(file);
833
- if (!content) {
834
- throw new Error(`${file} has no content`);
835
- }
836
- for (const m of change.matches) {
837
- if (!content.match(new RegExp(m, 'gm'))) {
838
- assertionFailures.push({
839
- message: `Did not match ${m} in ${file}`,
840
- file,
841
- content,
842
- });
843
- }
844
- }
845
- for (const m of change.doesNotMatch || []) {
846
- if (content.match(new RegExp(m, 'gm'))) {
847
- assertionFailures.push({
848
- message: `Unexpectedly matched ${m} in ${file}`,
849
- file,
850
- content,
851
- });
852
- }
853
- }
854
- }
855
- return {
856
- assertionFailures,
857
- debugInfo: {
858
- responses,
859
- processedFiles,
860
- },
861
- };
862
- } finally {
863
- workspaceDiff.modifiedUISourceCodes().forEach(modifiedUISourceCode => {
864
- modifiedUISourceCode.resetWorkingCopy();
865
- });
866
- }
867
- };