chrome-devtools-frontend 1.0.1578729 → 1.0.1579812

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 (72) hide show
  1. package/docs/cookbook/devtools_on_devtools.md +2 -2
  2. package/docs/feature-specs/elements-gutter-decorators.md +40 -0
  3. package/docs/feature-specs/elements-tree-selection-and-hover.md +31 -0
  4. package/docs/feature-specs/images/elements-gutter-decorators-multiple.png +0 -0
  5. package/docs/get_the_code.md +3 -3
  6. package/front_end/generated/ARIAProperties.js +0 -6
  7. package/front_end/generated/InspectorBackendCommands.ts +1 -1
  8. package/front_end/generated/protocol.ts +1 -0
  9. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.snapshot.txt +30 -0
  10. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +79 -0
  11. package/front_end/models/javascript_metadata/NativeFunctions.js +4 -0
  12. package/front_end/panels/accessibility/AXBreadcrumbsPane.ts +5 -3
  13. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +18 -4
  14. package/front_end/panels/ai_assistance/components/ChatInput.ts +38 -18
  15. package/front_end/panels/ai_assistance/components/ChatMessage.ts +7 -4
  16. package/front_end/panels/ai_assistance/components/ChatView.ts +2 -0
  17. package/front_end/panels/ai_assistance/components/chatInput.css +10 -3
  18. package/front_end/panels/animation/AnimationGroupPreviewUI.ts +1 -1
  19. package/front_end/panels/application/DeviceBoundSessionsView.ts +51 -76
  20. package/front_end/panels/application/ServiceWorkerUpdateCycleView.ts +1 -0
  21. package/front_end/panels/application/components/BackForwardCacheView.ts +4 -2
  22. package/front_end/panels/autofill/AutofillView.ts +1 -1
  23. package/front_end/panels/browser_debugger/XHRBreakpointsSidebarPane.ts +1 -0
  24. package/front_end/panels/common/AiCodeGenerationTeaser.ts +2 -2
  25. package/front_end/panels/common/AiCodeGenerationUpgradeDialog.ts +4 -4
  26. package/front_end/panels/console/ConsoleViewMessage.ts +1 -0
  27. package/front_end/panels/elements/AdoptedStyleSheetTreeElement.ts +78 -0
  28. package/front_end/panels/elements/ElementsTreeElement.ts +93 -121
  29. package/front_end/panels/elements/ElementsTreeOutline.ts +1 -0
  30. package/front_end/panels/elements/LayoutPane.ts +8 -7
  31. package/front_end/panels/elements/components/ElementsBreadcrumbs.ts +1 -1
  32. package/front_end/panels/elements/components/StylePropertyEditor.ts +2 -1
  33. package/front_end/panels/elements/elements.ts +3 -0
  34. package/front_end/panels/elements/elementsTreeOutline.css +16 -5
  35. package/front_end/panels/lighthouse/LighthouseReportRenderer.ts +1 -1
  36. package/front_end/panels/lighthouse/LighthouseStartView.ts +1 -1
  37. package/front_end/panels/lighthouse/lighthouseStartView.css +6 -0
  38. package/front_end/panels/linear_memory_inspector/components/LinearMemoryValueInterpreter.ts +1 -1
  39. package/front_end/panels/linear_memory_inspector/components/ValueInterpreterDisplay.ts +1 -1
  40. package/front_end/panels/media/PlayerListView.ts +1 -1
  41. package/front_end/panels/network/NetworkLogView.ts +2 -5
  42. package/front_end/panels/network/NetworkLogViewColumns.ts +2 -1
  43. package/front_end/panels/network/components/RequestHeaderSection.ts +1 -1
  44. package/front_end/panels/protocol_monitor/JSONEditor.ts +1 -1
  45. package/front_end/panels/recorder/components/RecordingListView.ts +1 -1
  46. package/front_end/panels/recorder/components/StepEditor.ts +3 -3
  47. package/front_end/panels/settings/EditFileSystemView.ts +8 -8
  48. package/front_end/panels/settings/KeybindsSettingsTab.ts +2 -1
  49. package/front_end/panels/settings/SettingsScreen.ts +4 -4
  50. package/front_end/panels/sources/components/HeadersView.ts +2 -2
  51. package/front_end/panels/timeline/components/BreadcrumbsUI.ts +1 -1
  52. package/front_end/panels/timeline/components/SidebarAnnotationsTab.ts +1 -1
  53. package/front_end/panels/timeline/overlays/OverlaysImpl.ts +47 -26
  54. package/front_end/panels/timeline/overlays/components/TimespanBreakdownOverlay.ts +121 -39
  55. package/front_end/panels/timeline/overlays/components/timespanBreakdownOverlay.css +106 -101
  56. package/front_end/third_party/chromium/README.chromium +1 -1
  57. package/front_end/ui/components/suggestion_input/SuggestionInput.ts +7 -12
  58. package/front_end/ui/components/tree_outline/TreeOutline.ts +1 -1
  59. package/front_end/ui/legacy/InplaceEditor.ts +1 -1
  60. package/front_end/ui/legacy/ListControl.ts +2 -1
  61. package/front_end/ui/legacy/ListWidget.ts +1 -1
  62. package/front_end/ui/legacy/SoftContextMenu.ts +2 -1
  63. package/front_end/ui/legacy/Treeoutline.ts +1 -0
  64. package/front_end/ui/legacy/components/data_grid/DataGrid.ts +4 -2
  65. package/front_end/ui/legacy/components/data_grid/SortableDataGrid.ts +59 -9
  66. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +28 -15
  67. package/front_end/ui/legacy/components/quick_open/CommandMenu.ts +2 -2
  68. package/front_end/ui/legacy/components/quick_open/FilteredListWidget.ts +1 -1
  69. package/front_end/ui/legacy/components/settings_ui/SettingsUI.ts +3 -3
  70. package/front_end/ui/legacy/components/source_frame/JSONView.ts +2 -3
  71. package/front_end/ui/visual_logging/Debugging.ts +1 -1
  72. package/package.json +1 -1
@@ -44,7 +44,7 @@ set up your Chrome or Chromium instance for earlier versions of M-136 and M-135.
44
44
  Then in your `devtools-frontend` checkout, use
45
45
 
46
46
  ```bash
47
- ./third_party/chrome/chrome-linux/chrome \
47
+ ./third_party/chrome/chrome-linux/chrome-linux64/chrome \
48
48
  --disable-infobars \
49
49
  --custom-devtools-frontend=file://$(realpath out/Default/gen/front_end)
50
50
  ```
@@ -52,7 +52,7 @@ Then in your `devtools-frontend` checkout, use
52
52
  on Linux or
53
53
 
54
54
  ```bash
55
- ./third_party/chrome/chrome-mac/Google\ Chrome\ for\ Testing.app/Contents/MacOS/Google\ Chrome\ for\ Testing \
55
+ ./third_party/chrome/chrome-mac-{arm64|x64}/chrome-mac-{arm64|x64}/Google\ Chrome\ for\ Testing.app/Contents/MacOS/Google\ Chrome\ for\ Testing \
56
56
  --disable-infobars \
57
57
  --disable-features=MediaRouter \
58
58
  --custom-devtools-frontend=file://$(realpath out/Default/gen/front_end) \
@@ -0,0 +1,40 @@
1
+ # Requirements Specification: Elements Panel Gutter & Decoration Logic
2
+
3
+ ## 1. Overview
4
+ The gutter area in the Elements panel DOM tree serves as a visual indicator for state markers (decorations) associated with DOM nodes. These decorations provide users with "at-a-glance" information about the node or its subtree, such as active breakpoints or framework-specific annotations.
5
+
6
+ ## 2. Functional Requirements
7
+
8
+ ### 2.1 Decoration Visibility
9
+ * **Target Nodes**: Decorations must only appear on **Element** nodes (e.g., `<div>`, `<body>`). They must not appear on text nodes or closing tags.
10
+ * **Visual Indicators**: Active states must be represented by colored markers (dots) within the gutter to the left of the element's tag.
11
+ * **Multiple States**: If a node has multiple active states (e.g., multiple types of breakpoints), the gutter must display markers for all of them.
12
+ * **Layout**: Markers must be arranged horizontally.
13
+ * **Spacing**: Markers must be tightly packed, with each subsequent marker offset by exactly `3px` to the right of the previous one (creating a stacked or dense visual line).
14
+ ![Multiple Markers Example](images/elements-gutter-decorators-multiple.png)
15
+
16
+ ### 2.2 Parent/Child Aggregation Logic
17
+ The visibility of decorations depends on the expansion state of the node to ensure users don't miss information hidden inside collapsed regions.
18
+
19
+ * **Collapsed State (Summary View)**:
20
+ * The gutter must display markers for the node's **own** decorations.
21
+ * The gutter must **also** display markers for any **descendant** nodes that have decorations. This acts as a summary, alerting the user that a reflected state exists somewhere inside the collapsed subtree.
22
+ * **Expanded State (Direct View)**:
23
+ * The gutter must **only** display markers for the node's **own** decorations.
24
+ * Markers for descendant nodes must be hidden from the parent's gutter, as they will be directly visible on the child nodes themselves.
25
+ * **Style**: Descendant markers visible in the collapsed state must be rendered with `50%` opacity to visually distinguish them from the node's own decorations.
26
+
27
+ ### 2.3 Tooltip Behavior
28
+ Hovering over the decoration markers in the gutter must display a consolidated tooltip containing:
29
+ * **Own Decorations**: A list of titles for all decorations active on the current node.
30
+ * **Descendant Decorations** (Collapsed State Only): A separate list of titles for decorations found within the subtree, clearly labeled to distinguish them from the parent's own states (e.g., under a "Children:" header).
31
+
32
+ ### 2.4 Layout & Positioning
33
+ * **Indentation Tracking**: The decoration container must dynamically adjust its position to match the indentation level of the tree element. It should always appear to the left of the opening tag, regardless of how deep the node is in the DOM hierarchy.
34
+ * **Gutter Alignment**: The markers must align consistent with the "gutter" column effectively creating a vertical channel for status indicators down the left side of the tree.
35
+
36
+ ### 2.5 User Interaction
37
+ * **Menu Access**: Clicking on the gutter area (often visualized with a "..." icon or actionable space) must trigger the context menu for that node, allowing access to actions related to the decorations (e.g., removing a breakpoint).
38
+
39
+ ### 2.6 Performance
40
+ * **Throttled Updates**: Changes to decorations must be batched or throttled. Visually updating the markers should not occur synchronously with every minor internal state change to prevent UI flickering during rapid DOM updates.
@@ -0,0 +1,31 @@
1
+ # Requirements Specification: Elements Panel Tree Selection and Hover
2
+
3
+ ## 1. Overview
4
+ The Elements panel DOM tree visualizes the structure of the inspected page. As users navigate this tree—either by clicking or hovering—the panel provides visual feedback to indicate the currently active node and offers contextual actions like a console hint and an AI assistance button.
5
+
6
+ ## 2. Functional Requirements
7
+
8
+ ### 2.1 Selection State
9
+ * **Visual Indicator**: When a tree node is selected, its entire row must be highlighted visually. This is achieved by rendering a background spanning the full width of the tree, visually anchoring the node.
10
+ * **Full Row Coverage**: The selection highlight must extend to the left edge of the panel, accounting for the dynamic indentation of the DOM tree structure.
11
+ * **Behavior on Deselection**: When a node loses selection focus, the visual highlight must be removed immediately.
12
+
13
+ ### 2.2 Console Hint (`== $0`)
14
+ * **Visibility**: The `$0` hint must only appear on the currently selected tree node.
15
+ * **Placement**: It must be positioned to the right of the closing tag or the node's text content.
16
+ * **Tooltip**: Hovering over the hint must display a tooltip explaining its purpose: `Use $0 in the console to refer to this element.`
17
+ * **Accessibility**: The hint itself should be marked hidden from screen readers (`aria-hidden="true"`) to prevent redundancy, as the selection state inherently implies `$0` context to power users.
18
+
19
+ ### 2.3 Floating AI Assistance Button
20
+ * **Eligibility**: The AI button must only appear for valid `Element` nodes (e.g., `<button>`, `<div>`). It must not appear on text nodes, comments, but does appear for closing tags.
21
+ * **Visibility Conditions**:
22
+ * The button must be visible when the node is actively hovered by the user's cursor.
23
+ * The button must also be visible when the node currently holds the selection state (even if not hovered).
24
+ * **Action**: Clicking the button must:
25
+ * Select the node (if it wasn't already selected).
26
+ * Open the AI assistance panel with the context of the selected node.
27
+ * Not propagate the click event to the underlying row (which might otherwise cause tree expansion/collapse).
28
+ * **Visual Design**: It should render as a floating button using the standard DevTools AI icon, with the tooltip matching the registered AI action title.
29
+
30
+ ## 3. Implementation Details (Declarative UI)
31
+ The selection background, `$0` hint, and AI floating button are integrated into the primary Lit-html render cycle (`DEFAULT_VIEW`) for the tree element. This replaces previous imperative DOM creation strategies, routing all visibility and styling updates through a unified state object passed to the view.
@@ -250,19 +250,19 @@ This works with Chromium 79 or later.
250
250
  To run on **Mac**:
251
251
 
252
252
  ```bash
253
- <path-to-devtools-frontend>./third_party/chrome/chrome-mac/Google\ Chrome\ for\ Testing.app/Contents/MacOS/Google\ Chrome\ for\ Testing --disable-infobars --disable-features=MediaRouter --custom-devtools-frontend=file://$(realpath out/Default/gen/front_end) --use-mock-keychain
253
+ <path-to-devtools-frontend>./third_party/chrome/chrome-mac-{arm64|x64}/chrome-mac-{arm64|x64}/Google\ Chrome\ for\ Testing.app/Contents/MacOS/Google\ Chrome\ for\ Testing --disable-infobars --disable-features=MediaRouter --custom-devtools-frontend=file://$(realpath out/Default/gen/front_end) --use-mock-keychain
254
254
  ```
255
255
 
256
256
  To run on **Linux**:
257
257
 
258
258
  ```bash
259
- <path-to-devtools-frontend>./third_party/chrome/chrome-linux/chrome --disable-infobars --custom-devtools-frontend=file://$(realpath out/Default/gen/front_end)
259
+ <path-to-devtools-frontend>./third_party/chrome/chrome-linux/chrome-linux64/chrome --disable-infobars --custom-devtools-frontend=file://$(realpath out/Default/gen/front_end)
260
260
  ```
261
261
 
262
262
  To run on **Windows**:
263
263
 
264
264
  ```bash
265
- <path-to-devtools-frontend>\third_party\chrome\chrome-win\chrome.exe --disable-infobars --custom-devtools-frontend="<path-to-devtools-frontend>\out\Default\gen\front_end"
265
+ <path-to-devtools-frontend>\third_party\chrome\chrome-win\chrome-win64\chrome.exe --disable-infobars --custom-devtools-frontend="<path-to-devtools-frontend>\out\Default\gen\front_end"
266
266
  ```
267
267
 
268
268
  Note that `$(realpath out/Default/gen/front_end)` expands to the absolute path to build artifacts for DevTools frontend.
@@ -1314,9 +1314,6 @@ export const config = {
1314
1314
  ]
1315
1315
  },
1316
1316
  {
1317
- "implicitValues": {
1318
- "aria-live": "off"
1319
- },
1320
1317
  "name": "marquee",
1321
1318
  "nameFrom": [
1322
1319
  "author"
@@ -1975,9 +1972,6 @@ export const config = {
1975
1972
  ]
1976
1973
  },
1977
1974
  {
1978
- "implicitValues": {
1979
- "aria-live": "off"
1980
- },
1981
1975
  "name": "timer",
1982
1976
  "nameFrom": [
1983
1977
  "author"
@@ -1018,7 +1018,7 @@ inspectorBackend.registerEnum("Page.ClientNavigationReason", {AnchorClick: "anch
1018
1018
  inspectorBackend.registerEnum("Page.ClientNavigationDisposition", {CurrentTab: "currentTab", NewTab: "newTab", NewWindow: "newWindow", Download: "download"});
1019
1019
  inspectorBackend.registerEnum("Page.ReferrerPolicy", {NoReferrer: "noReferrer", NoReferrerWhenDowngrade: "noReferrerWhenDowngrade", Origin: "origin", OriginWhenCrossOrigin: "originWhenCrossOrigin", SameOrigin: "sameOrigin", StrictOrigin: "strictOrigin", StrictOriginWhenCrossOrigin: "strictOriginWhenCrossOrigin", UnsafeUrl: "unsafeUrl"});
1020
1020
  inspectorBackend.registerEnum("Page.NavigationType", {Navigation: "Navigation", BackForwardCacheRestore: "BackForwardCacheRestore"});
1021
- inspectorBackend.registerEnum("Page.BackForwardCacheNotRestoredReason", {NotPrimaryMainFrame: "NotPrimaryMainFrame", BackForwardCacheDisabled: "BackForwardCacheDisabled", RelatedActiveContentsExist: "RelatedActiveContentsExist", HTTPStatusNotOK: "HTTPStatusNotOK", SchemeNotHTTPOrHTTPS: "SchemeNotHTTPOrHTTPS", Loading: "Loading", WasGrantedMediaAccess: "WasGrantedMediaAccess", DisableForRenderFrameHostCalled: "DisableForRenderFrameHostCalled", DomainNotAllowed: "DomainNotAllowed", HTTPMethodNotGET: "HTTPMethodNotGET", SubframeIsNavigating: "SubframeIsNavigating", Timeout: "Timeout", CacheLimit: "CacheLimit", JavaScriptExecution: "JavaScriptExecution", RendererProcessKilled: "RendererProcessKilled", RendererProcessCrashed: "RendererProcessCrashed", SchedulerTrackedFeatureUsed: "SchedulerTrackedFeatureUsed", ConflictingBrowsingInstance: "ConflictingBrowsingInstance", CacheFlushed: "CacheFlushed", ServiceWorkerVersionActivation: "ServiceWorkerVersionActivation", SessionRestored: "SessionRestored", ServiceWorkerPostMessage: "ServiceWorkerPostMessage", EnteredBackForwardCacheBeforeServiceWorkerHostAdded: "EnteredBackForwardCacheBeforeServiceWorkerHostAdded", RenderFrameHostReused_SameSite: "RenderFrameHostReused_SameSite", RenderFrameHostReused_CrossSite: "RenderFrameHostReused_CrossSite", ServiceWorkerClaim: "ServiceWorkerClaim", IgnoreEventAndEvict: "IgnoreEventAndEvict", HaveInnerContents: "HaveInnerContents", TimeoutPuttingInCache: "TimeoutPuttingInCache", BackForwardCacheDisabledByLowMemory: "BackForwardCacheDisabledByLowMemory", BackForwardCacheDisabledByCommandLine: "BackForwardCacheDisabledByCommandLine", NetworkRequestDatAPIpeDrainedAsBytesConsumer: "NetworkRequestDatapipeDrainedAsBytesConsumer", NetworkRequestRedirected: "NetworkRequestRedirected", NetworkRequestTimeout: "NetworkRequestTimeout", NetworkExceedsBufferLimit: "NetworkExceedsBufferLimit", NavigationCancelledWhileRestoring: "NavigationCancelledWhileRestoring", NotMostRecentNavigationEntry: "NotMostRecentNavigationEntry", BackForwardCacheDisabledForPrerender: "BackForwardCacheDisabledForPrerender", UserAgentOverrideDiffers: "UserAgentOverrideDiffers", ForegroundCacheLimit: "ForegroundCacheLimit", BrowsingInstanceNotSwapped: "BrowsingInstanceNotSwapped", BackForwardCacheDisabledForDelegate: "BackForwardCacheDisabledForDelegate", UnloadHandlerExistsInMainFrame: "UnloadHandlerExistsInMainFrame", UnloadHandlerExistsInSubFrame: "UnloadHandlerExistsInSubFrame", ServiceWorkerUnregistration: "ServiceWorkerUnregistration", CacheControlNoStore: "CacheControlNoStore", CacheControlNoStoreCookieModified: "CacheControlNoStoreCookieModified", CacheControlNoStoreHTTPOnlyCookieModified: "CacheControlNoStoreHTTPOnlyCookieModified", NoResponseHead: "NoResponseHead", Unknown: "Unknown", ActivationNavigationsDisallowedForBug1234857: "ActivationNavigationsDisallowedForBug1234857", ErrorDocument: "ErrorDocument", FencedFramesEmbedder: "FencedFramesEmbedder", CookieDisabled: "CookieDisabled", HTTPAuthRequired: "HTTPAuthRequired", CookieFlushed: "CookieFlushed", BroadcastChannelOnMessage: "BroadcastChannelOnMessage", WebViewSettingsChanged: "WebViewSettingsChanged", WebViewJavaScriptObjectChanged: "WebViewJavaScriptObjectChanged", WebViewMessageListenerInjected: "WebViewMessageListenerInjected", WebViewSafeBrowsingAllowlistChanged: "WebViewSafeBrowsingAllowlistChanged", WebViewDocumentStartJavascriptChanged: "WebViewDocumentStartJavascriptChanged", WebSocket: "WebSocket", WebTransport: "WebTransport", WebRTC: "WebRTC", MainResourceHasCacheControlNoStore: "MainResourceHasCacheControlNoStore", MainResourceHasCacheControlNoCache: "MainResourceHasCacheControlNoCache", SubresourceHasCacheControlNoStore: "SubresourceHasCacheControlNoStore", SubresourceHasCacheControlNoCache: "SubresourceHasCacheControlNoCache", ContainsPlugins: "ContainsPlugins", DocumentLoaded: "DocumentLoaded", OutstandingNetworkRequestOthers: "OutstandingNetworkRequestOthers", RequestedMIDIPermission: "RequestedMIDIPermission", RequestedAudioCapturePermission: "RequestedAudioCapturePermission", RequestedVideoCapturePermission: "RequestedVideoCapturePermission", RequestedBackForwardCacheBlockedSensors: "RequestedBackForwardCacheBlockedSensors", RequestedBackgroundWorkPermission: "RequestedBackgroundWorkPermission", BroadcastChannel: "BroadcastChannel", WebXR: "WebXR", SharedWorker: "SharedWorker", SharedWorkerMessage: "SharedWorkerMessage", SharedWorkerWithNoActiveClient: "SharedWorkerWithNoActiveClient", WebLocks: "WebLocks", WebHID: "WebHID", WebBluetooth: "WebBluetooth", WebShare: "WebShare", RequestedStorageAccessGrant: "RequestedStorageAccessGrant", WebNfc: "WebNfc", OutstandingNetworkRequestFetch: "OutstandingNetworkRequestFetch", OutstandingNetworkRequestXHR: "OutstandingNetworkRequestXHR", AppBanner: "AppBanner", Printing: "Printing", WebDatabase: "WebDatabase", PictureInPicture: "PictureInPicture", SpeechRecognizer: "SpeechRecognizer", IdleManager: "IdleManager", PaymentManager: "PaymentManager", SpeechSynthesis: "SpeechSynthesis", KeyboardLock: "KeyboardLock", WebOTPService: "WebOTPService", OutstandingNetworkRequestDirectSocket: "OutstandingNetworkRequestDirectSocket", InjectedJavascript: "InjectedJavascript", InjectedStyleSheet: "InjectedStyleSheet", KeepaliveRequest: "KeepaliveRequest", IndexedDBEvent: "IndexedDBEvent", Dummy: "Dummy", JsNetworkRequestReceivedCacheControlNoStoreResource: "JsNetworkRequestReceivedCacheControlNoStoreResource", WebRTCUsedWithCCNS: "WebRTCUsedWithCCNS", WebTransportUsedWithCCNS: "WebTransportUsedWithCCNS", WebSocketUsedWithCCNS: "WebSocketUsedWithCCNS", SmartCard: "SmartCard", LiveMediaStreamTrack: "LiveMediaStreamTrack", UnloadHandler: "UnloadHandler", ParserAborted: "ParserAborted", ContentSecurityHandler: "ContentSecurityHandler", ContentWebAuthenticationAPI: "ContentWebAuthenticationAPI", ContentFileChooser: "ContentFileChooser", ContentSerial: "ContentSerial", ContentFileSystemAccess: "ContentFileSystemAccess", ContentMediaDevicesDispatcherHost: "ContentMediaDevicesDispatcherHost", ContentWebBluetooth: "ContentWebBluetooth", ContentWebUSB: "ContentWebUSB", ContentMediaSessionService: "ContentMediaSessionService", ContentScreenReader: "ContentScreenReader", ContentDiscarded: "ContentDiscarded", EmbedderPopupBlockerTabHelper: "EmbedderPopupBlockerTabHelper", EmbedderSafeBrowsingTriggeredPopupBlocker: "EmbedderSafeBrowsingTriggeredPopupBlocker", EmbedderSafeBrowsingThreatDetails: "EmbedderSafeBrowsingThreatDetails", EmbedderAppBannerManager: "EmbedderAppBannerManager", EmbedderDomDistillerViewerSource: "EmbedderDomDistillerViewerSource", EmbedderDomDistillerSelfDeletingRequestDelegate: "EmbedderDomDistillerSelfDeletingRequestDelegate", EmbedderOomInterventionTabHelper: "EmbedderOomInterventionTabHelper", EmbedderOfflinePage: "EmbedderOfflinePage", EmbedderChromePasswordManagerClientBindCredentialManager: "EmbedderChromePasswordManagerClientBindCredentialManager", EmbedderPermissionRequestManager: "EmbedderPermissionRequestManager", EmbedderModalDialog: "EmbedderModalDialog", EmbedderExtensions: "EmbedderExtensions", EmbedderExtensionMessaging: "EmbedderExtensionMessaging", EmbedderExtensionMessagingForOpenPort: "EmbedderExtensionMessagingForOpenPort", EmbedderExtensionSentMessageToCachedFrame: "EmbedderExtensionSentMessageToCachedFrame", RequestedByWebViewClient: "RequestedByWebViewClient", PostMessageByWebViewClient: "PostMessageByWebViewClient", CacheControlNoStoreDeviceBoundSessionTerminated: "CacheControlNoStoreDeviceBoundSessionTerminated", CacheLimitPrunedOnModerateMemoryPressure: "CacheLimitPrunedOnModerateMemoryPressure", CacheLimitPrunedOnCriticalMemoryPressure: "CacheLimitPrunedOnCriticalMemoryPressure"});
1021
+ inspectorBackend.registerEnum("Page.BackForwardCacheNotRestoredReason", {NotPrimaryMainFrame: "NotPrimaryMainFrame", BackForwardCacheDisabled: "BackForwardCacheDisabled", RelatedActiveContentsExist: "RelatedActiveContentsExist", HTTPStatusNotOK: "HTTPStatusNotOK", SchemeNotHTTPOrHTTPS: "SchemeNotHTTPOrHTTPS", Loading: "Loading", WasGrantedMediaAccess: "WasGrantedMediaAccess", DisableForRenderFrameHostCalled: "DisableForRenderFrameHostCalled", DomainNotAllowed: "DomainNotAllowed", HTTPMethodNotGET: "HTTPMethodNotGET", SubframeIsNavigating: "SubframeIsNavigating", Timeout: "Timeout", CacheLimit: "CacheLimit", JavaScriptExecution: "JavaScriptExecution", RendererProcessKilled: "RendererProcessKilled", RendererProcessCrashed: "RendererProcessCrashed", SchedulerTrackedFeatureUsed: "SchedulerTrackedFeatureUsed", ConflictingBrowsingInstance: "ConflictingBrowsingInstance", CacheFlushed: "CacheFlushed", ServiceWorkerVersionActivation: "ServiceWorkerVersionActivation", SessionRestored: "SessionRestored", ServiceWorkerPostMessage: "ServiceWorkerPostMessage", EnteredBackForwardCacheBeforeServiceWorkerHostAdded: "EnteredBackForwardCacheBeforeServiceWorkerHostAdded", RenderFrameHostReused_SameSite: "RenderFrameHostReused_SameSite", RenderFrameHostReused_CrossSite: "RenderFrameHostReused_CrossSite", ServiceWorkerClaim: "ServiceWorkerClaim", IgnoreEventAndEvict: "IgnoreEventAndEvict", HaveInnerContents: "HaveInnerContents", TimeoutPuttingInCache: "TimeoutPuttingInCache", BackForwardCacheDisabledByLowMemory: "BackForwardCacheDisabledByLowMemory", BackForwardCacheDisabledByCommandLine: "BackForwardCacheDisabledByCommandLine", NetworkRequestDatAPIpeDrainedAsBytesConsumer: "NetworkRequestDatapipeDrainedAsBytesConsumer", NetworkRequestRedirected: "NetworkRequestRedirected", NetworkRequestTimeout: "NetworkRequestTimeout", NetworkExceedsBufferLimit: "NetworkExceedsBufferLimit", NavigationCancelledWhileRestoring: "NavigationCancelledWhileRestoring", NotMostRecentNavigationEntry: "NotMostRecentNavigationEntry", BackForwardCacheDisabledForPrerender: "BackForwardCacheDisabledForPrerender", UserAgentOverrideDiffers: "UserAgentOverrideDiffers", ForegroundCacheLimit: "ForegroundCacheLimit", BrowsingInstanceNotSwapped: "BrowsingInstanceNotSwapped", BackForwardCacheDisabledForDelegate: "BackForwardCacheDisabledForDelegate", UnloadHandlerExistsInMainFrame: "UnloadHandlerExistsInMainFrame", UnloadHandlerExistsInSubFrame: "UnloadHandlerExistsInSubFrame", ServiceWorkerUnregistration: "ServiceWorkerUnregistration", CacheControlNoStore: "CacheControlNoStore", CacheControlNoStoreCookieModified: "CacheControlNoStoreCookieModified", CacheControlNoStoreHTTPOnlyCookieModified: "CacheControlNoStoreHTTPOnlyCookieModified", NoResponseHead: "NoResponseHead", Unknown: "Unknown", ActivationNavigationsDisallowedForBug1234857: "ActivationNavigationsDisallowedForBug1234857", ErrorDocument: "ErrorDocument", FencedFramesEmbedder: "FencedFramesEmbedder", CookieDisabled: "CookieDisabled", HTTPAuthRequired: "HTTPAuthRequired", CookieFlushed: "CookieFlushed", BroadcastChannelOnMessage: "BroadcastChannelOnMessage", WebViewSettingsChanged: "WebViewSettingsChanged", WebViewJavaScriptObjectChanged: "WebViewJavaScriptObjectChanged", WebViewMessageListenerInjected: "WebViewMessageListenerInjected", WebViewSafeBrowsingAllowlistChanged: "WebViewSafeBrowsingAllowlistChanged", WebViewDocumentStartJavascriptChanged: "WebViewDocumentStartJavascriptChanged", WebSocket: "WebSocket", WebTransport: "WebTransport", WebRTC: "WebRTC", MainResourceHasCacheControlNoStore: "MainResourceHasCacheControlNoStore", MainResourceHasCacheControlNoCache: "MainResourceHasCacheControlNoCache", SubresourceHasCacheControlNoStore: "SubresourceHasCacheControlNoStore", SubresourceHasCacheControlNoCache: "SubresourceHasCacheControlNoCache", ContainsPlugins: "ContainsPlugins", DocumentLoaded: "DocumentLoaded", OutstandingNetworkRequestOthers: "OutstandingNetworkRequestOthers", RequestedMIDIPermission: "RequestedMIDIPermission", RequestedAudioCapturePermission: "RequestedAudioCapturePermission", RequestedVideoCapturePermission: "RequestedVideoCapturePermission", RequestedBackForwardCacheBlockedSensors: "RequestedBackForwardCacheBlockedSensors", RequestedBackgroundWorkPermission: "RequestedBackgroundWorkPermission", BroadcastChannel: "BroadcastChannel", WebXR: "WebXR", SharedWorker: "SharedWorker", SharedWorkerMessage: "SharedWorkerMessage", SharedWorkerWithNoActiveClient: "SharedWorkerWithNoActiveClient", WebLocks: "WebLocks", WebLocksContention: "WebLocksContention", WebHID: "WebHID", WebBluetooth: "WebBluetooth", WebShare: "WebShare", RequestedStorageAccessGrant: "RequestedStorageAccessGrant", WebNfc: "WebNfc", OutstandingNetworkRequestFetch: "OutstandingNetworkRequestFetch", OutstandingNetworkRequestXHR: "OutstandingNetworkRequestXHR", AppBanner: "AppBanner", Printing: "Printing", WebDatabase: "WebDatabase", PictureInPicture: "PictureInPicture", SpeechRecognizer: "SpeechRecognizer", IdleManager: "IdleManager", PaymentManager: "PaymentManager", SpeechSynthesis: "SpeechSynthesis", KeyboardLock: "KeyboardLock", WebOTPService: "WebOTPService", OutstandingNetworkRequestDirectSocket: "OutstandingNetworkRequestDirectSocket", InjectedJavascript: "InjectedJavascript", InjectedStyleSheet: "InjectedStyleSheet", KeepaliveRequest: "KeepaliveRequest", IndexedDBEvent: "IndexedDBEvent", Dummy: "Dummy", JsNetworkRequestReceivedCacheControlNoStoreResource: "JsNetworkRequestReceivedCacheControlNoStoreResource", WebRTCUsedWithCCNS: "WebRTCUsedWithCCNS", WebTransportUsedWithCCNS: "WebTransportUsedWithCCNS", WebSocketUsedWithCCNS: "WebSocketUsedWithCCNS", SmartCard: "SmartCard", LiveMediaStreamTrack: "LiveMediaStreamTrack", UnloadHandler: "UnloadHandler", ParserAborted: "ParserAborted", ContentSecurityHandler: "ContentSecurityHandler", ContentWebAuthenticationAPI: "ContentWebAuthenticationAPI", ContentFileChooser: "ContentFileChooser", ContentSerial: "ContentSerial", ContentFileSystemAccess: "ContentFileSystemAccess", ContentMediaDevicesDispatcherHost: "ContentMediaDevicesDispatcherHost", ContentWebBluetooth: "ContentWebBluetooth", ContentWebUSB: "ContentWebUSB", ContentMediaSessionService: "ContentMediaSessionService", ContentScreenReader: "ContentScreenReader", ContentDiscarded: "ContentDiscarded", EmbedderPopupBlockerTabHelper: "EmbedderPopupBlockerTabHelper", EmbedderSafeBrowsingTriggeredPopupBlocker: "EmbedderSafeBrowsingTriggeredPopupBlocker", EmbedderSafeBrowsingThreatDetails: "EmbedderSafeBrowsingThreatDetails", EmbedderAppBannerManager: "EmbedderAppBannerManager", EmbedderDomDistillerViewerSource: "EmbedderDomDistillerViewerSource", EmbedderDomDistillerSelfDeletingRequestDelegate: "EmbedderDomDistillerSelfDeletingRequestDelegate", EmbedderOomInterventionTabHelper: "EmbedderOomInterventionTabHelper", EmbedderOfflinePage: "EmbedderOfflinePage", EmbedderChromePasswordManagerClientBindCredentialManager: "EmbedderChromePasswordManagerClientBindCredentialManager", EmbedderPermissionRequestManager: "EmbedderPermissionRequestManager", EmbedderModalDialog: "EmbedderModalDialog", EmbedderExtensions: "EmbedderExtensions", EmbedderExtensionMessaging: "EmbedderExtensionMessaging", EmbedderExtensionMessagingForOpenPort: "EmbedderExtensionMessagingForOpenPort", EmbedderExtensionSentMessageToCachedFrame: "EmbedderExtensionSentMessageToCachedFrame", RequestedByWebViewClient: "RequestedByWebViewClient", PostMessageByWebViewClient: "PostMessageByWebViewClient", CacheControlNoStoreDeviceBoundSessionTerminated: "CacheControlNoStoreDeviceBoundSessionTerminated", CacheLimitPrunedOnModerateMemoryPressure: "CacheLimitPrunedOnModerateMemoryPressure", CacheLimitPrunedOnCriticalMemoryPressure: "CacheLimitPrunedOnCriticalMemoryPressure"});
1022
1022
  inspectorBackend.registerEnum("Page.BackForwardCacheNotRestoredReasonType", {SupportPending: "SupportPending", PageSupportNeeded: "PageSupportNeeded", Circumstantial: "Circumstantial"});
1023
1023
  inspectorBackend.registerEvent("Page.domContentEventFired", ["timestamp"]);
1024
1024
  inspectorBackend.registerEnum("Page.FileChooserOpenedEventMode", {SelectSingle: "selectSingle", SelectMultiple: "selectMultiple"});
@@ -14981,6 +14981,7 @@ export namespace Page {
14981
14981
  SharedWorkerMessage = 'SharedWorkerMessage',
14982
14982
  SharedWorkerWithNoActiveClient = 'SharedWorkerWithNoActiveClient',
14983
14983
  WebLocks = 'WebLocks',
14984
+ WebLocksContention = 'WebLocksContention',
14984
14985
  WebHID = 'WebHID',
14985
14986
  WebBluetooth = 'WebBluetooth',
14986
14987
  WebShare = 'WebShare',
@@ -58,6 +58,36 @@ Content:
58
58
  }
59
59
  }
60
60
  }
61
+ },
62
+ {
63
+ "name": "listSourceFiles",
64
+ "description": "Returns a list of all files in the project.",
65
+ "parameters": {
66
+ "type": 6,
67
+ "description": "",
68
+ "nullable": true,
69
+ "required": [],
70
+ "properties": {}
71
+ }
72
+ },
73
+ {
74
+ "name": "selectSourceFile",
75
+ "description": "Returns a list of all files in the project.",
76
+ "parameters": {
77
+ "type": 6,
78
+ "description": "",
79
+ "nullable": true,
80
+ "required": [
81
+ "name"
82
+ ],
83
+ "properties": {
84
+ "name": {
85
+ "type": 1,
86
+ "description": "The name of the file",
87
+ "nullable": false
88
+ }
89
+ }
90
+ }
61
91
  }
62
92
  ],
63
93
  "options": {},
@@ -7,6 +7,7 @@ import * as i18n from '../../../core/i18n/i18n.js';
7
7
  import * as Platform from '../../../core/platform/platform.js';
8
8
  import * as Root from '../../../core/root/root.js';
9
9
  import * as Logs from '../../logs/logs.js';
10
+ import * as Workspace from '../../workspace/workspace.js';
10
11
 
11
12
  import {
12
13
  type AgentOptions,
@@ -132,8 +133,86 @@ export class ContextSelectionAgent extends AiAgent<never> {
132
133
  };
133
134
  },
134
135
  });
136
+
137
+ this.declareFunction<Record<string, never>>('listSourceFiles', {
138
+ description: `Returns a list of all files in the project.`,
139
+ parameters: {
140
+ type: Host.AidaClient.ParametersTypes.OBJECT,
141
+ description: '',
142
+ nullable: true,
143
+ required: [],
144
+ properties: {},
145
+ },
146
+ displayInfoFromArgs: () => {
147
+ return {title: lockedString('Listing source requests…')};
148
+ },
149
+ handler: async () => {
150
+ const files = [];
151
+ for (const file of this.#getUISourceCodes()) {
152
+ files.push(file.fullDisplayName());
153
+ }
154
+
155
+ return {
156
+ result: files,
157
+ };
158
+ },
159
+ });
160
+
161
+ this.declareFunction<{name: string}>('selectSourceFile', {
162
+ description: `Returns a list of all files in the project.`,
163
+ parameters: {
164
+ type: Host.AidaClient.ParametersTypes.OBJECT,
165
+ description: '',
166
+ nullable: true,
167
+ required: ['name'],
168
+ properties: {
169
+ name: {
170
+ type: Host.AidaClient.ParametersTypes.STRING,
171
+ description: 'The name of the file',
172
+ nullable: false,
173
+ },
174
+ },
175
+ },
176
+ displayInfoFromArgs: args => {
177
+ return {title: lockedString('Getting source file'), action: `selectSourceFile(${args.name})`};
178
+ },
179
+ handler: async params => {
180
+ for (const file of this.#getUISourceCodes()) {
181
+ if (file.fullDisplayName() === params.name) {
182
+ return {
183
+ context: file,
184
+ };
185
+ }
186
+ }
187
+
188
+ return {error: 'Unable to find file.'};
189
+ },
190
+ });
135
191
  }
136
192
 
193
+ #getUISourceCodes = (): Iterable<Workspace.UISourceCode.UISourceCode> => {
194
+ const workspace = Workspace.Workspace.WorkspaceImpl.instance();
195
+ const projects = workspace.projects().filter(project => {
196
+ switch (project.type()) {
197
+ case Workspace.Workspace.projectTypes.Network:
198
+ case Workspace.Workspace.projectTypes.FileSystem:
199
+ case Workspace.Workspace.projectTypes.ConnectableFileSystem:
200
+ return true;
201
+
202
+ default:
203
+ return false;
204
+ }
205
+ });
206
+ const uiSourceCodes = [];
207
+ for (const project of projects) {
208
+ for (const uiSourceCode of project.uiSourceCodes()) {
209
+ uiSourceCodes.push(uiSourceCode);
210
+ }
211
+ }
212
+
213
+ return uiSourceCodes;
214
+ };
215
+
137
216
  async * handleContextDetails(): AsyncGenerator<ContextResponse, void, void> {
138
217
  }
139
218
 
@@ -6821,6 +6821,10 @@ export const NativeFunctions = [
6821
6821
  name: "UIEvent",
6822
6822
  signatures: [["type","?eventInitDict"]]
6823
6823
  },
6824
+ {
6825
+ name: "WebMCPEvent",
6826
+ signatures: [["type","?eventInitDict"]]
6827
+ },
6824
6828
  {
6825
6829
  name: "WheelEvent",
6826
6830
  signatures: [["type","?eventInitDict"]]
@@ -452,9 +452,11 @@ export class AXBreadcrumb {
452
452
 
453
453
  this.#element = document.createElement('div');
454
454
  this.#element.classList.add('ax-breadcrumb');
455
- this.#element.setAttribute(
456
- 'jslog',
457
- `${VisualLogging.treeItem().track({click: true, keydown: 'ArrowUp|ArrowDown|ArrowLeft|ArrowRight|Enter'})}`);
455
+ this.#element.setAttribute('jslog', `${VisualLogging.treeItem().track({
456
+ click: true,
457
+ resize: true,
458
+ keydown: 'ArrowUp|ArrowDown|ArrowLeft|ArrowRight|Enter'
459
+ })}`);
458
460
  elementsToAXBreadcrumb.set(this.#element, this);
459
461
 
460
462
  this.#nodeElement = document.createElement('div');
@@ -164,6 +164,10 @@ const UIStringsNotTranslate = {
164
164
  *@description Placeholder text for the chat UI input.
165
165
  */
166
166
  inputPlaceholderForNoContext: 'Ask AI Assistance',
167
+ /**
168
+ * @description Placeholder text for the chat UI input with branding Gemini (do not translate)
169
+ */
170
+ inputPlaceholderForNoContextBranded: 'Ask Gemini',
167
171
  /**
168
172
  * @description Disclaimer text right after the chat input.
169
173
  */
@@ -591,6 +595,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
591
595
  onContextClick: this.#handleContextClick.bind(this),
592
596
  onNewConversation: this.#handleNewChatRequest.bind(this),
593
597
  onCopyResponseClick: this.#onCopyResponseClick.bind(this),
598
+ onContextRemoved: isAiAssistanceContextSelectionAgentEnabled() ? this.#handleContextRemoved.bind(this) : null,
594
599
  }
595
600
  };
596
601
  }
@@ -1011,6 +1016,9 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1011
1016
  return lockedString(UIStringsNotTranslate.inputPlaceholderForPerformanceWithNoRecording);
1012
1017
  }
1013
1018
  case AiAssistanceModel.AiHistoryStorage.ConversationType.NONE:
1019
+ if (AiAssistanceModel.AiUtils.isGeminiBranding()) {
1020
+ return lockedString(UIStringsNotTranslate.inputPlaceholderForNoContextBranded);
1021
+ }
1014
1022
  return lockedString(UIStringsNotTranslate.inputPlaceholderForNoContext);
1015
1023
  }
1016
1024
  }
@@ -1098,6 +1106,11 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1098
1106
  // Node picker is using linkifier.
1099
1107
  }
1100
1108
 
1109
+ #handleContextRemoved(): void {
1110
+ this.#conversation?.setContext(null);
1111
+ this.requestUpdate();
1112
+ }
1113
+
1101
1114
  #canExecuteQuery(): boolean {
1102
1115
  const isBrandedBuild = Boolean(Root.Runtime.hostConfig.aidaAvailability?.enabled);
1103
1116
  const isBlockedByAge = Boolean(Root.Runtime.hostConfig.aidaAvailability?.blockedByAge);
@@ -1292,22 +1305,23 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1292
1305
  if (data instanceof Workspace.UISourceCode.UISourceCode) {
1293
1306
  const context = new AiAssistanceModel.FileAgent.FileContext(data);
1294
1307
  this.#selectedFile = context;
1295
-
1308
+ this.#conversation?.setContext(context);
1296
1309
  } else if (data instanceof SDK.DOMModel.DOMNode) {
1297
1310
  const context = new AiAssistanceModel.StylingAgent.NodeContext(data);
1298
1311
  this.#selectedElement = context;
1299
-
1312
+ this.#conversation?.setContext(context);
1300
1313
  } else if (data instanceof SDK.NetworkRequest.NetworkRequest) {
1301
1314
  const calculator = NetworkPanel.NetworkPanel.NetworkPanel.instance().networkLogView.timeCalculator();
1302
-
1303
1315
  const context = new AiAssistanceModel.NetworkAgent.RequestContext(data, calculator);
1304
1316
  this.#selectedRequest = context;
1317
+ this.#conversation?.setContext(context);
1305
1318
  } else if (data instanceof AiAssistanceModel.AIContext.AgentFocus) {
1306
1319
  const context = new AiAssistanceModel.PerformanceAgent.PerformanceTraceContext(data);
1307
1320
  this.#selectedPerformanceTrace = context;
1321
+ this.#conversation?.setContext(context);
1308
1322
  }
1309
1323
 
1310
- this.#updateConversationState(this.#conversation);
1324
+ this.requestUpdate();
1311
1325
  };
1312
1326
 
1313
1327
  async #startConversation(
@@ -39,6 +39,10 @@ const UIStrings = {
39
39
  * @description The footer disclaimer that links to more information about the AI feature.
40
40
  */
41
41
  learnAbout: 'Learn about AI in DevTools',
42
+ /**
43
+ * @description Label added to the button that remove the currently selected context in AI Assistance panel.
44
+ */
45
+ removeContext: 'Remove selected context',
42
46
  } as const;
43
47
 
44
48
  /*
@@ -137,23 +141,27 @@ export interface ViewInput {
137
141
  onImagePaste: (event: ClipboardEvent) => void;
138
142
  onImageDragOver: (event: DragEvent) => void;
139
143
  onImageDrop: (event: DragEvent) => void;
144
+ onContextRemoved: (() => void)|null;
140
145
  }
141
146
 
142
147
  export type ViewOutput = undefined;
143
148
 
144
- export const DEFAULT_VIEW = (input: ViewInput, output: ViewOutput, target: HTMLElement): void => {
145
- const chatInputContainerCls = Lit.Directives.classMap({
146
- 'chat-input-container': true,
147
- 'single-line-layout': !input.selectedContext,
148
- disabled: input.isTextInputDisabled,
149
- });
150
-
151
- const renderRelevantDataDisclaimer = (tooltipId: string): Lit.LitTemplate => {
152
- const classes = Lit.Directives.classMap({
153
- 'chat-input-disclaimer': true,
154
- 'hide-divider': !input.isLoading && input.blockedByCrossOrigin,
155
- });
156
- // clang-format off
149
+ export const
150
+ DEFAULT_VIEW =
151
+ (input: ViewInput, output: ViewOutput, target: HTMLElement):
152
+ void => {
153
+ const chatInputContainerCls = Lit.Directives.classMap({
154
+ 'chat-input-container': true,
155
+ 'single-line-layout': !input.selectedContext,
156
+ disabled: input.isTextInputDisabled,
157
+ });
158
+
159
+ const renderRelevantDataDisclaimer = (tooltipId: string): Lit.LitTemplate => {
160
+ const classes = Lit.Directives.classMap({
161
+ 'chat-input-disclaimer': true,
162
+ 'hide-divider': !input.isLoading && input.blockedByCrossOrigin,
163
+ });
164
+ // clang-format off
157
165
  return html`
158
166
  <div class=${classes}>
159
167
  <button
@@ -185,10 +193,10 @@ export const DEFAULT_VIEW = (input: ViewInput, output: ViewOutput, target: HTMLE
185
193
  </div></devtools-tooltip>
186
194
  </div>
187
195
  `;
188
- // clang-format on
189
- };
196
+ // clang-format on
197
+ };
190
198
 
191
- // clang-format off
199
+ // clang-format off
192
200
  Lit.render(html`
193
201
  <style>${Input.textInputStyles}</style>
194
202
  <style>${chatInputStyles}</style>
@@ -363,6 +371,16 @@ export const DEFAULT_VIEW = (input: ViewInput, output: ViewOutput, target: HTMLE
363
371
  :
364
372
  input.selectedContext.getTitle()}
365
373
  </span>
374
+ ${input.onContextRemoved ? html`
375
+ <devtools-button
376
+ title=${i18nString(UIStrings.removeContext)}
377
+ aria-label=${i18nString(UIStrings.removeContext)}
378
+ class="remove-context"
379
+ .iconName=${'cross'}
380
+ .size=${Buttons.Button.Size.MICRO}
381
+ .jslogContext=${'context-removed'}
382
+ .variant=${Buttons.Button.Variant.ICON}
383
+ @click=${input.onContextRemoved}></devtools-button>` : Lit.nothing}
366
384
  </div>
367
385
  </div>`
368
386
  : Lit.nothing}
@@ -462,8 +480,8 @@ export const DEFAULT_VIEW = (input: ViewInput, output: ViewOutput, target: HTMLE
462
480
  ${renderRelevantDataDisclaimer(RELEVANT_DATA_LINK_FOOTER_ID)}
463
481
  </footer>
464
482
  `, target);
465
- // clang-format on
466
- };
483
+ // clang-format on
484
+ };
467
485
 
468
486
  /**
469
487
  * ChatInput is a presenter for the input area in the AI Assistance panel.
@@ -503,6 +521,7 @@ export class ChatInput extends UI.Widget.Widget implements SDK.TargetManager.Obs
503
521
  onInspectElementClick = (): void => {};
504
522
  onCancelClick = (): void => {};
505
523
  onNewConversation = (): void => {};
524
+ onContextRemoved: (() => void)|null = null;
506
525
 
507
526
  async #handleTakeScreenshot(): Promise<void> {
508
527
  const mainTarget = SDK.TargetManager.TargetManager.instance().primaryPageTarget();
@@ -685,6 +704,7 @@ export class ChatInput extends UI.Widget.Widget implements SDK.TargetManager.Obs
685
704
  onImageUpload: this.onImageUpload,
686
705
  onImageDragOver: this.#handleImageDragOver,
687
706
  onImageDrop: this.#handleImageDrop,
707
+ onContextRemoved: this.onContextRemoved,
688
708
  },
689
709
  undefined, this.contentElement);
690
710
  }
@@ -323,6 +323,7 @@ export const DEFAULT_VIEW = (input: ChatMessageViewInput, output: ViewOutput, ta
323
323
  }
324
324
  return renderStep({
325
325
  step: part.step,
326
+ isLoading: input.isLoading,
326
327
  markdownRenderer: input.markdownRenderer,
327
328
  isLast: isLastPart,
328
329
  });
@@ -450,11 +451,12 @@ function renderStepDetails({
450
451
  // clang-format on
451
452
  }
452
453
 
453
- function renderStepBadge({step, isLast}: {
454
+ function renderStepBadge({step, isLoading, isLast}: {
454
455
  step: Step,
456
+ isLoading: boolean,
455
457
  isLast: boolean,
456
458
  }): Lit.LitTemplate {
457
- if (step.isLoading && isLast && !step.sideEffect) {
459
+ if (isLoading && isLast && !step.sideEffect) {
458
460
  return html`<devtools-spinner></devtools-spinner>`;
459
461
  }
460
462
 
@@ -478,8 +480,9 @@ function renderStepBadge({step, isLast}: {
478
480
  ></devtools-icon>`;
479
481
  }
480
482
 
481
- function renderStep({step, markdownRenderer, isLast}: {
483
+ function renderStep({step, isLoading, markdownRenderer, isLast}: {
482
484
  step: Step,
485
+ isLoading: boolean,
483
486
  markdownRenderer: MarkdownLitRenderer,
484
487
  isLast: boolean,
485
488
  }): Lit.LitTemplate {
@@ -496,7 +499,7 @@ function renderStep({step, markdownRenderer, isLast}: {
496
499
  .open=${Boolean(step.sideEffect)}>
497
500
  <summary>
498
501
  <div class="summary">
499
- ${renderStepBadge({ step, isLast })}
502
+ ${renderStepBadge({ step, isLoading, isLast })}
500
503
  ${renderTitle(step)}
501
504
  <devtools-icon
502
505
  class="arrow"
@@ -56,6 +56,7 @@ export interface Props {
56
56
  onContextClick: () => void;
57
57
  onNewConversation: () => void;
58
58
  onCopyResponseClick: (message: ModelChatMessage) => void;
59
+ onContextRemoved: (() => void)|null;
59
60
  changeManager: AiAssistanceModel.ChangeManager.ChangeManager;
60
61
  inspectElementToggled: boolean;
61
62
  messages: Message[];
@@ -175,6 +176,7 @@ const DEFAULT_VIEW: View = (input, output, target) => {
175
176
  onTextSubmit: input.onTextSubmit,
176
177
  onCancelClick: input.onCancelClick,
177
178
  onNewConversation: input.onNewConversation,
179
+ onContextRemoved: input.onContextRemoved,
178
180
  })} ${ref(element => { output.input = element as UI.Widget.WidgetElement<ChatInput>; } )}></devtools-widget>
179
181
  </main>
180
182
  </div>
@@ -22,7 +22,6 @@
22
22
  max-width: var(--sys-size-36);
23
23
  background-color: var(--sys-color-cdt-base-container);
24
24
  width: 100%;
25
-
26
25
  }
27
26
 
28
27
  .chat-readonly-container {
@@ -221,6 +220,8 @@
221
220
 
222
221
  .resource-link,
223
222
  .resource-task {
223
+ display: flex;
224
+ align-items: center;
224
225
  cursor: pointer;
225
226
  padding: var(--sys-size-2) var(--sys-size-3);
226
227
  font: var(--sys-typescale-body5-regular);
@@ -239,6 +240,12 @@
239
240
  & .title {
240
241
  vertical-align: middle;
241
242
  font: var(--sys-typescale-body5-regular);
243
+ overflow: hidden;
244
+ text-overflow: ellipsis;
245
+ }
246
+
247
+ & .remove-context {
248
+ vertical-align: middle;
242
249
  }
243
250
 
244
251
  &.has-picker-behavior {
@@ -253,8 +260,8 @@
253
260
  devtools-file-source-icon {
254
261
  display: inline-flex;
255
262
  vertical-align: middle;
256
- width: var(--sys-size-7);
257
- height: var(--sys-size-7);
263
+ min-width: var(--sys-size-7);
264
+ min-height: var(--sys-size-7);
258
265
  }
259
266
 
260
267
  /*
@@ -98,7 +98,7 @@ const DEFAULT_VIEW: View = (input, output, target) => {
98
98
  render(html`
99
99
  <div class="animation-group-preview-ui">
100
100
  <button
101
- jslog=${VisualLogging.item(`animations.buffer-preview${input.isScrollDrivenAnimationGroup ? '-sda' : ''}`).track({click: true})}
101
+ jslog=${VisualLogging.item(`animations.buffer-preview${input.isScrollDrivenAnimationGroup ? '-sda' : ''}`).track({click: true, resize: true})}
102
102
  class=${classes}
103
103
  role="option"
104
104
  aria-label=${input.label}