chrome-devtools-frontend 1.0.1592362 → 1.0.1593518

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 (109) hide show
  1. package/front_end/Images/src/tab-move.svg +1 -0
  2. package/front_end/application_tokens.css +4 -4
  3. package/front_end/core/protocol_client/InspectorBackend.ts +0 -4
  4. package/front_end/core/sdk/EmulationModel.ts +1 -41
  5. package/front_end/generated/InspectorBackendCommands.ts +2 -1
  6. package/front_end/generated/SupportedCSSProperties.js +2 -2
  7. package/front_end/generated/protocol-mapping.d.ts +7 -0
  8. package/front_end/generated/protocol-proxy-api.d.ts +5 -0
  9. package/front_end/generated/protocol.ts +59 -0
  10. package/front_end/models/ai_assistance/agents/AiAgent.ts +24 -1
  11. package/front_end/models/ai_assistance/agents/BreakpointDebuggerAgent.ts +26 -86
  12. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +14 -4
  13. package/front_end/models/ai_assistance/agents/StylingAgent.ts +16 -2
  14. package/front_end/models/emulation/DeviceModeModel.ts +0 -47
  15. package/front_end/models/javascript_metadata/NativeFunctions.js +6 -6
  16. package/front_end/panels/accessibility/AXBreadcrumbsPane.ts +5 -3
  17. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +29 -6
  18. package/front_end/panels/ai_assistance/README.md +61 -0
  19. package/front_end/panels/ai_assistance/components/ChatMessage.ts +141 -27
  20. package/front_end/panels/ai_assistance/components/ChatView.ts +5 -1
  21. package/front_end/panels/ai_assistance/components/WalkthroughView.ts +19 -7
  22. package/front_end/panels/ai_assistance/components/chatMessage.css +30 -0
  23. package/front_end/panels/ai_assistance/components/walkthroughView.css +12 -7
  24. package/front_end/panels/animation/AnimationGroupPreviewUI.ts +1 -1
  25. package/front_end/panels/application/ServiceWorkerUpdateCycleView.ts +1 -0
  26. package/front_end/panels/application/components/BackForwardCacheView.ts +4 -2
  27. package/front_end/panels/autofill/AutofillView.ts +1 -1
  28. package/front_end/panels/browser_debugger/DOMBreakpointsSidebarPane.ts +161 -154
  29. package/front_end/panels/browser_debugger/XHRBreakpointsSidebarPane.ts +1 -0
  30. package/front_end/panels/browser_debugger/domBreakpointsSidebarPane.css +58 -36
  31. package/front_end/panels/console/ConsoleViewMessage.ts +1 -0
  32. package/front_end/panels/console/consoleView.css +7 -2
  33. package/front_end/panels/elements/ComputedStyleWidget.ts +5 -1
  34. package/front_end/panels/elements/ElementsTreeElement.ts +1 -0
  35. package/front_end/panels/elements/LayoutPane.ts +8 -7
  36. package/front_end/panels/elements/StandaloneStylesContainer.ts +254 -0
  37. package/front_end/panels/elements/components/ComputedStyleTrace.ts +4 -0
  38. package/front_end/panels/elements/components/ElementsBreadcrumbs.ts +1 -1
  39. package/front_end/panels/elements/components/StylePropertyEditor.ts +2 -1
  40. package/front_end/panels/elements/components/computedStyleProperty.css +1 -1
  41. package/front_end/panels/elements/elements.ts +2 -0
  42. package/front_end/panels/emulation/DeviceModeToolbar.ts +0 -25
  43. package/front_end/panels/lighthouse/LighthouseReportRenderer.ts +1 -1
  44. package/front_end/panels/linear_memory_inspector/components/LinearMemoryValueInterpreter.ts +1 -1
  45. package/front_end/panels/linear_memory_inspector/components/ValueInterpreterDisplay.ts +1 -1
  46. package/front_end/panels/media/PlayerListView.ts +1 -1
  47. package/front_end/panels/network/NetworkLogViewColumns.ts +2 -1
  48. package/front_end/panels/network/components/RequestHeaderSection.ts +1 -1
  49. package/front_end/panels/protocol_monitor/JSONEditor.ts +1 -1
  50. package/front_end/panels/recorder/components/RecordingListView.ts +1 -1
  51. package/front_end/panels/recorder/components/StepEditor.ts +3 -3
  52. package/front_end/panels/settings/KeybindsSettingsTab.ts +2 -1
  53. package/front_end/panels/sources/components/HeadersView.ts +2 -2
  54. package/front_end/panels/timeline/components/BreadcrumbsUI.ts +1 -1
  55. package/front_end/panels/timeline/components/SidebarAnnotationsTab.ts +1 -1
  56. package/front_end/third_party/chromium/README.chromium +1 -1
  57. package/front_end/third_party/puppeteer/README.chromium +2 -2
  58. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Navigation.d.ts.map +1 -1
  59. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Navigation.js +1 -0
  60. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Navigation.js.map +1 -1
  61. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserContext.js +1 -1
  62. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserContext.js.map +1 -1
  63. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js +1 -1
  64. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js.map +1 -1
  65. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
  66. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/ChromeLauncher.d.ts.map +1 -1
  67. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/ChromeLauncher.js +1 -0
  68. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/ChromeLauncher.js.map +1 -1
  69. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +3 -3
  70. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +3 -3
  71. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js.map +1 -1
  72. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
  73. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
  74. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
  75. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +6 -6
  76. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/Navigation.d.ts.map +1 -1
  77. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/Navigation.js +1 -0
  78. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/Navigation.js.map +1 -1
  79. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserContext.js +1 -1
  80. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserContext.js.map +1 -1
  81. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js +1 -1
  82. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js.map +1 -1
  83. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/ChromeLauncher.d.ts.map +1 -1
  84. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/ChromeLauncher.js +1 -0
  85. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/ChromeLauncher.js.map +1 -1
  86. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +3 -3
  87. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +3 -3
  88. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js.map +1 -1
  89. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
  90. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
  91. package/front_end/third_party/puppeteer/package/package.json +4 -4
  92. package/front_end/third_party/puppeteer/package/src/bidi/core/Navigation.ts +1 -0
  93. package/front_end/third_party/puppeteer/package/src/cdp/BrowserContext.ts +1 -1
  94. package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +1 -1
  95. package/front_end/third_party/puppeteer/package/src/node/ChromeLauncher.ts +1 -0
  96. package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
  97. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  98. package/front_end/ui/components/suggestion_input/SuggestionInput.ts +7 -12
  99. package/front_end/ui/components/tree_outline/TreeOutline.ts +6 -2
  100. package/front_end/ui/components/tree_outline/treeOutline.css +5 -0
  101. package/front_end/ui/legacy/ListControl.ts +5 -3
  102. package/front_end/ui/legacy/ListWidget.ts +1 -1
  103. package/front_end/ui/legacy/SoftContextMenu.ts +2 -1
  104. package/front_end/ui/legacy/Treeoutline.ts +1 -0
  105. package/front_end/ui/legacy/components/data_grid/DataGrid.ts +4 -2
  106. package/front_end/ui/legacy/components/quick_open/FilteredListWidget.ts +1 -1
  107. package/front_end/ui/legacy/components/utils/JSPresentationUtils.ts +31 -0
  108. package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
  109. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 -960 960 960" width="20px" fill="#000000"><path d="M216-144q-29.7 0-50.85-21.5Q144-187 144-216v-120h72v120h528v-456H216v144h-72v-216q0-29 21.15-50.5T216-816h528q29.7 0 50.85 21.5Q816-773 816-744v528q0 29-21.15 50.5T744-144H216Zm240-120-51-51 81-81H144v-72h342l-81-81 51-51 168 168-168 168Z"/></svg>
@@ -180,8 +180,8 @@
180
180
  /**
181
181
  * Colors for Coverage visualization.
182
182
  */
183
- --app-color-coverage-used: var(--ref-palette-neutral80);
184
- --app-color-coverage-unused: var(--sys-color-error-bright);
183
+ --app-color-coverage-used: var(--sys-color-green-bright);
184
+ --app-color-coverage-unused: var(--ref-palette-neutral80);
185
185
  --app-color-toolbar-background: var(--sys-color-surface4);
186
186
 
187
187
  /**
@@ -372,8 +372,8 @@
372
372
  /**
373
373
  * Colors for Coverage visualization.
374
374
  */
375
- --app-color-coverage-used: var(--ref-palette-neutral40);
376
- --app-color-coverage-unused: var(--sys-color-error-bright);
375
+ --app-color-coverage-used: var(--sys-color-green-bright);
376
+ --app-color-coverage-unused: var(--ref-palette-neutral40);
377
377
  --app-color-toolbar-background: var(--sys-color-base);
378
378
 
379
379
  /**
@@ -559,10 +559,6 @@ export class TargetBase {
559
559
  this.registerDispatcher('DOMStorage', dispatcher);
560
560
  }
561
561
 
562
- registerEmulationDispatcher(dispatcher: ProtocolProxyApi.EmulationDispatcher): void {
563
- this.registerDispatcher('Emulation', dispatcher);
564
- }
565
-
566
562
  registerFetchDispatcher(dispatcher: ProtocolProxyApi.FetchDispatcher): void {
567
563
  this.registerDispatcher('Fetch', dispatcher);
568
564
  }
@@ -18,7 +18,7 @@ export const enum DataSaverOverride {
18
18
  DISABLED = 'disabled',
19
19
  }
20
20
 
21
- export class EmulationModel extends SDKModel<EmulationModelEventTypes> implements ProtocolProxyApi.EmulationDispatcher {
21
+ export class EmulationModel extends SDKModel<void> {
22
22
  readonly #emulationAgent: ProtocolProxyApi.EmulationApi;
23
23
  readonly #deviceOrientationAgent: ProtocolProxyApi.DeviceOrientationApi;
24
24
  #cssModel: CSSModel|null;
@@ -33,15 +33,11 @@ export class EmulationModel extends SDKModel<EmulationModelEventTypes> implement
33
33
  enabled: boolean,
34
34
  configuration: Protocol.Emulation.SetEmitTouchEventsForMouseRequestConfiguration,
35
35
  };
36
- #screenOrientationLocked: boolean;
37
- #lockedOrientation: Protocol.Emulation.ScreenOrientation|null;
38
36
 
39
37
  constructor(target: Target) {
40
38
  super(target);
41
39
  this.#emulationAgent = target.emulationAgent();
42
40
  this.#deviceOrientationAgent = target.deviceOrientationAgent();
43
- this.#screenOrientationLocked = false;
44
- this.#lockedOrientation = null;
45
41
  this.#cssModel = target.model(CSSModel);
46
42
  this.#overlayModel = target.model(OverlayModel);
47
43
  if (this.#overlayModel) {
@@ -229,7 +225,6 @@ export class EmulationModel extends SDKModel<EmulationModelEventTypes> implement
229
225
  enabled: false,
230
226
  configuration: Protocol.Emulation.SetEmitTouchEventsForMouseRequestConfiguration.Mobile,
231
227
  };
232
- target.registerEmulationDispatcher(this);
233
228
  }
234
229
 
235
230
  setTouchEmulationAllowed(touchEmulationAllowed: boolean): void {
@@ -483,41 +478,6 @@ export class EmulationModel extends SDKModel<EmulationModelEventTypes> implement
483
478
  ];
484
479
  return await this.emulateCSSMedia(type, features);
485
480
  }
486
-
487
- // ProtocolProxyApi.EmulationDispatcher implementation
488
-
489
- virtualTimeBudgetExpired(): void {
490
- // No-op for now; not used by the frontend.
491
- }
492
-
493
- screenOrientationLockChanged(event: Protocol.Emulation.ScreenOrientationLockChangedEvent): void {
494
- this.#screenOrientationLocked = event.locked;
495
- this.#lockedOrientation = event.orientation ?? null;
496
- this.dispatchEventToListeners(
497
- EmulationModelEvents.SCREEN_ORIENTATION_LOCK_CHANGED,
498
- {locked: event.locked, orientation: event.orientation ?? null});
499
- }
500
-
501
- isScreenOrientationLocked(): boolean {
502
- return this.#screenOrientationLocked;
503
- }
504
-
505
- lockedOrientation(): Protocol.Emulation.ScreenOrientation|null {
506
- return this.#lockedOrientation;
507
- }
508
- }
509
-
510
- export const enum EmulationModelEvents {
511
- SCREEN_ORIENTATION_LOCK_CHANGED = 'ScreenOrientationLockChanged',
512
- }
513
-
514
- export interface ScreenOrientationLockChangedEvent {
515
- locked: boolean;
516
- orientation: Protocol.Emulation.ScreenOrientation|null;
517
- }
518
-
519
- export interface EmulationModelEventTypes {
520
- [EmulationModelEvents.SCREEN_ORIENTATION_LOCK_CHANGED]: ScreenOrientationLockChangedEvent;
521
481
  }
522
482
 
523
483
  export class Location {
@@ -519,7 +519,7 @@ inspectorBackend.registerCommand("Emulation.setCPUThrottlingRate", [{"name": "ra
519
519
  inspectorBackend.registerCommand("Emulation.setDefaultBackgroundColorOverride", [{"name": "color", "type": "object", "optional": true, "description": "RGBA of the default background color. If not specified, any existing override will be cleared.", "typeRef": "DOM.RGBA"}], [], "Sets or clears an override of the default background color of the frame. This override is used if the content does not specify one.");
520
520
  inspectorBackend.registerCommand("Emulation.setSafeAreaInsetsOverride", [{"name": "insets", "type": "object", "optional": false, "description": "", "typeRef": "Emulation.SafeAreaInsets"}], [], "Overrides the values for env(safe-area-inset-*) and env(safe-area-max-inset-*). Unset values will cause the respective variables to be undefined, even if previously overridden.");
521
521
  inspectorBackend.registerEnum("Emulation.SetDeviceMetricsOverrideRequestScrollbarType", {Overlay: "overlay", Default: "default"});
522
- inspectorBackend.registerCommand("Emulation.setDeviceMetricsOverride", [{"name": "width", "type": "number", "optional": false, "description": "Overriding width value in pixels (minimum 0, maximum 10000000). 0 disables the override.", "typeRef": null}, {"name": "height", "type": "number", "optional": false, "description": "Overriding height value in pixels (minimum 0, maximum 10000000). 0 disables the override.", "typeRef": null}, {"name": "deviceScaleFactor", "type": "number", "optional": false, "description": "Overriding device scale factor value. 0 disables the override.", "typeRef": null}, {"name": "mobile", "type": "boolean", "optional": false, "description": "Whether to emulate mobile device. This includes viewport meta tag, overlay scrollbars, text autosizing and more.", "typeRef": null}, {"name": "scale", "type": "number", "optional": true, "description": "Scale to apply to resulting view image.", "typeRef": null}, {"name": "screenWidth", "type": "number", "optional": true, "description": "Overriding screen width value in pixels (minimum 0, maximum 10000000).", "typeRef": null}, {"name": "screenHeight", "type": "number", "optional": true, "description": "Overriding screen height value in pixels (minimum 0, maximum 10000000).", "typeRef": null}, {"name": "positionX", "type": "number", "optional": true, "description": "Overriding view X position on screen in pixels (minimum 0, maximum 10000000).", "typeRef": null}, {"name": "positionY", "type": "number", "optional": true, "description": "Overriding view Y position on screen in pixels (minimum 0, maximum 10000000).", "typeRef": null}, {"name": "dontSetVisibleSize", "type": "boolean", "optional": true, "description": "Do not set visible view size, rely upon explicit setVisibleSize call.", "typeRef": null}, {"name": "screenOrientation", "type": "object", "optional": true, "description": "Screen orientation override.", "typeRef": "Emulation.ScreenOrientation"}, {"name": "viewport", "type": "object", "optional": true, "description": "If set, the visible area of the page will be overridden to this viewport. This viewport change is not observed by the page, e.g. viewport-relative elements do not change positions.", "typeRef": "Page.Viewport"}, {"name": "displayFeature", "type": "object", "optional": true, "description": "If set, the display feature of a multi-segment screen. If not set, multi-segment support is turned-off. Deprecated, use Emulation.setDisplayFeaturesOverride.", "typeRef": "Emulation.DisplayFeature"}, {"name": "devicePosture", "type": "object", "optional": true, "description": "If set, the posture of a foldable device. If not set the posture is set to continuous. Deprecated, use Emulation.setDevicePostureOverride.", "typeRef": "Emulation.DevicePosture"}, {"name": "scrollbarType", "type": "string", "optional": true, "description": "Scrollbar type. Default: `default`.", "typeRef": "Emulation.SetDeviceMetricsOverrideRequestScrollbarType"}], [], "Overrides the values of device screen dimensions (window.screen.width, window.screen.height, window.innerWidth, window.innerHeight, and \"device-width\"/\"device-height\"-related CSS media query results).");
522
+ inspectorBackend.registerCommand("Emulation.setDeviceMetricsOverride", [{"name": "width", "type": "number", "optional": false, "description": "Overriding width value in pixels (minimum 0, maximum 10000000). 0 disables the override.", "typeRef": null}, {"name": "height", "type": "number", "optional": false, "description": "Overriding height value in pixels (minimum 0, maximum 10000000). 0 disables the override.", "typeRef": null}, {"name": "deviceScaleFactor", "type": "number", "optional": false, "description": "Overriding device scale factor value. 0 disables the override.", "typeRef": null}, {"name": "mobile", "type": "boolean", "optional": false, "description": "Whether to emulate mobile device. This includes viewport meta tag, overlay scrollbars, text autosizing and more.", "typeRef": null}, {"name": "scale", "type": "number", "optional": true, "description": "Scale to apply to resulting view image.", "typeRef": null}, {"name": "screenWidth", "type": "number", "optional": true, "description": "Overriding screen width value in pixels (minimum 0, maximum 10000000).", "typeRef": null}, {"name": "screenHeight", "type": "number", "optional": true, "description": "Overriding screen height value in pixels (minimum 0, maximum 10000000).", "typeRef": null}, {"name": "positionX", "type": "number", "optional": true, "description": "Overriding view X position on screen in pixels (minimum 0, maximum 10000000).", "typeRef": null}, {"name": "positionY", "type": "number", "optional": true, "description": "Overriding view Y position on screen in pixels (minimum 0, maximum 10000000).", "typeRef": null}, {"name": "dontSetVisibleSize", "type": "boolean", "optional": true, "description": "Do not set visible view size, rely upon explicit setVisibleSize call.", "typeRef": null}, {"name": "screenOrientation", "type": "object", "optional": true, "description": "Screen orientation override.", "typeRef": "Emulation.ScreenOrientation"}, {"name": "viewport", "type": "object", "optional": true, "description": "If set, the visible area of the page will be overridden to this viewport. This viewport change is not observed by the page, e.g. viewport-relative elements do not change positions.", "typeRef": "Page.Viewport"}, {"name": "displayFeature", "type": "object", "optional": true, "description": "If set, the display feature of a multi-segment screen. If not set, multi-segment support is turned-off. Deprecated, use Emulation.setDisplayFeaturesOverride.", "typeRef": "Emulation.DisplayFeature"}, {"name": "devicePosture", "type": "object", "optional": true, "description": "If set, the posture of a foldable device. If not set the posture is set to continuous. Deprecated, use Emulation.setDevicePostureOverride.", "typeRef": "Emulation.DevicePosture"}, {"name": "scrollbarType", "type": "string", "optional": true, "description": "Scrollbar type. Default: `default`.", "typeRef": "Emulation.SetDeviceMetricsOverrideRequestScrollbarType"}, {"name": "screenOrientationLockEmulation", "type": "boolean", "optional": true, "description": "If set to true, enables screen orientation lock emulation, which intercepts screen.orientation.lock() calls from the page and reports orientation changes via screenOrientationLockChanged events. This is useful for emulating mobile device orientation lock behavior in responsive design mode.", "typeRef": null}], [], "Overrides the values of device screen dimensions (window.screen.width, window.screen.height, window.innerWidth, window.innerHeight, and \"device-width\"/\"device-height\"-related CSS media query results).");
523
523
  inspectorBackend.registerCommand("Emulation.setDevicePostureOverride", [{"name": "posture", "type": "object", "optional": false, "description": "", "typeRef": "Emulation.DevicePosture"}], [], "Start reporting the given posture value to the Device Posture API. This override can also be set in setDeviceMetricsOverride().");
524
524
  inspectorBackend.registerCommand("Emulation.clearDevicePostureOverride", [], [], "Clears a device posture override set with either setDeviceMetricsOverride() or setDevicePostureOverride() and starts using posture information from the platform again. Does nothing if no override is set.");
525
525
  inspectorBackend.registerCommand("Emulation.setDisplayFeaturesOverride", [{"name": "features", "type": "array", "optional": false, "description": "", "typeRef": "Emulation.DisplayFeature"}], [], "Start using the given display features to pupulate the Viewport Segments API. This override can also be set in setDeviceMetricsOverride().");
@@ -557,6 +557,7 @@ inspectorBackend.registerCommand("Emulation.setAutomationOverride", [{"name": "e
557
557
  inspectorBackend.registerCommand("Emulation.setSmallViewportHeightDifferenceOverride", [{"name": "difference", "type": "number", "optional": false, "description": "This will cause an element of size 100svh to be `difference` pixels smaller than an element of size 100lvh.", "typeRef": null}], [], "Allows overriding the difference between the small and large viewport sizes, which determine the value of the `svh` and `lvh` unit, respectively. Only supported for top-level frames.");
558
558
  inspectorBackend.registerCommand("Emulation.getScreenInfos", [], ["screenInfos"], "Returns device's screen configuration. In headful mode, the physical screens configuration is returned, whereas in headless mode, a virtual headless screen configuration is provided instead.");
559
559
  inspectorBackend.registerCommand("Emulation.addScreen", [{"name": "left", "type": "number", "optional": false, "description": "Offset of the left edge of the screen in pixels.", "typeRef": null}, {"name": "top", "type": "number", "optional": false, "description": "Offset of the top edge of the screen in pixels.", "typeRef": null}, {"name": "width", "type": "number", "optional": false, "description": "The width of the screen in pixels.", "typeRef": null}, {"name": "height", "type": "number", "optional": false, "description": "The height of the screen in pixels.", "typeRef": null}, {"name": "workAreaInsets", "type": "object", "optional": true, "description": "Specifies the screen's work area. Default is entire screen.", "typeRef": "Emulation.WorkAreaInsets"}, {"name": "devicePixelRatio", "type": "number", "optional": true, "description": "Specifies the screen's device pixel ratio. Default is 1.", "typeRef": null}, {"name": "rotation", "type": "number", "optional": true, "description": "Specifies the screen's rotation angle. Available values are 0, 90, 180 and 270. Default is 0.", "typeRef": null}, {"name": "colorDepth", "type": "number", "optional": true, "description": "Specifies the screen's color depth in bits. Default is 24.", "typeRef": null}, {"name": "label", "type": "string", "optional": true, "description": "Specifies the descriptive label for the screen. Default is none.", "typeRef": null}, {"name": "isInternal", "type": "boolean", "optional": true, "description": "Indicates whether the screen is internal to the device or external, attached to the device. Default is false.", "typeRef": null}], ["screenInfo"], "Add a new screen to the device. Only supported in headless mode.");
560
+ inspectorBackend.registerCommand("Emulation.updateScreen", [{"name": "screenId", "type": "string", "optional": false, "description": "Target screen identifier.", "typeRef": "Emulation.ScreenId"}, {"name": "left", "type": "number", "optional": true, "description": "Offset of the left edge of the screen in pixels.", "typeRef": null}, {"name": "top", "type": "number", "optional": true, "description": "Offset of the top edge of the screen in pixels.", "typeRef": null}, {"name": "width", "type": "number", "optional": true, "description": "The width of the screen in pixels.", "typeRef": null}, {"name": "height", "type": "number", "optional": true, "description": "The height of the screen in pixels.", "typeRef": null}, {"name": "workAreaInsets", "type": "object", "optional": true, "description": "Specifies the screen's work area.", "typeRef": "Emulation.WorkAreaInsets"}, {"name": "devicePixelRatio", "type": "number", "optional": true, "description": "Specifies the screen's device pixel ratio.", "typeRef": null}, {"name": "rotation", "type": "number", "optional": true, "description": "Specifies the screen's rotation angle. Available values are 0, 90, 180 and 270.", "typeRef": null}, {"name": "colorDepth", "type": "number", "optional": true, "description": "Specifies the screen's color depth in bits.", "typeRef": null}, {"name": "label", "type": "string", "optional": true, "description": "Specifies the descriptive label for the screen.", "typeRef": null}, {"name": "isInternal", "type": "boolean", "optional": true, "description": "Indicates whether the screen is internal to the device or external, attached to the device. Default is false.", "typeRef": null}], ["screenInfo"], "Updates specified screen parameters. Only supported in headless mode.");
560
561
  inspectorBackend.registerCommand("Emulation.removeScreen", [{"name": "screenId", "type": "string", "optional": false, "description": "", "typeRef": "Emulation.ScreenId"}], [], "Remove screen from the device. Only supported in headless mode.");
561
562
  inspectorBackend.registerCommand("Emulation.setPrimaryScreen", [{"name": "screenId", "type": "string", "optional": false, "description": "", "typeRef": "Emulation.ScreenId"}], [], "Set primary screen. Only supported in headless mode. Note that this changes the coordinate system origin to the top-left of the new primary screen, updating the bounds and work areas of all existing screens accordingly.");
562
563
  inspectorBackend.registerType("Emulation.SafeAreaInsets", [{"name": "top", "type": "number", "optional": true, "description": "Overrides safe-area-inset-top.", "typeRef": null}, {"name": "topMax", "type": "number", "optional": true, "description": "Overrides safe-area-max-inset-top.", "typeRef": null}, {"name": "left", "type": "number", "optional": true, "description": "Overrides safe-area-inset-left.", "typeRef": null}, {"name": "leftMax", "type": "number", "optional": true, "description": "Overrides safe-area-max-inset-left.", "typeRef": null}, {"name": "bottom", "type": "number", "optional": true, "description": "Overrides safe-area-inset-bottom.", "typeRef": null}, {"name": "bottomMax", "type": "number", "optional": true, "description": "Overrides safe-area-max-inset-bottom.", "typeRef": null}, {"name": "right", "type": "number", "optional": true, "description": "Overrides safe-area-inset-right.", "typeRef": null}, {"name": "rightMax", "type": "number", "optional": true, "description": "Overrides safe-area-max-inset-right.", "typeRef": null}]);
@@ -4891,7 +4891,7 @@ export const generatedProperties = [
4891
4891
  "inherited": false,
4892
4892
  "keywords": [
4893
4893
  "none",
4894
- "auto"
4894
+ "all"
4895
4895
  ],
4896
4896
  "name": "view-transition-scope"
4897
4897
  },
@@ -7267,7 +7267,7 @@ export const generatedPropertyValues = {
7267
7267
  "view-transition-scope": {
7268
7268
  "values": [
7269
7269
  "none",
7270
- "auto"
7270
+ "all"
7271
7271
  ]
7272
7272
  },
7273
7273
  "visibility": {
@@ -2781,6 +2781,13 @@ export namespace ProtocolMapping {
2781
2781
  paramsType: [Protocol.Emulation.AddScreenRequest];
2782
2782
  returnType: Protocol.Emulation.AddScreenResponse;
2783
2783
  };
2784
+ /**
2785
+ * Updates specified screen parameters. Only supported in headless mode.
2786
+ */
2787
+ 'Emulation.updateScreen': {
2788
+ paramsType: [Protocol.Emulation.UpdateScreenRequest];
2789
+ returnType: Protocol.Emulation.UpdateScreenResponse;
2790
+ };
2784
2791
  /**
2785
2792
  * Remove screen from the device. Only supported in headless mode.
2786
2793
  */
@@ -1847,6 +1847,11 @@ declare namespace ProtocolProxyApi {
1847
1847
  */
1848
1848
  invoke_addScreen(params: Protocol.Emulation.AddScreenRequest): Promise<Protocol.Emulation.AddScreenResponse>;
1849
1849
 
1850
+ /**
1851
+ * Updates specified screen parameters. Only supported in headless mode.
1852
+ */
1853
+ invoke_updateScreen(params: Protocol.Emulation.UpdateScreenRequest): Promise<Protocol.Emulation.UpdateScreenResponse>;
1854
+
1850
1855
  /**
1851
1856
  * Remove screen from the device. Only supported in headless mode.
1852
1857
  */
@@ -7205,6 +7205,14 @@ export namespace Emulation {
7205
7205
  * Scrollbar type. Default: `default`.
7206
7206
  */
7207
7207
  scrollbarType?: SetDeviceMetricsOverrideRequestScrollbarType;
7208
+ /**
7209
+ * If set to true, enables screen orientation lock emulation, which
7210
+ * intercepts screen.orientation.lock() calls from the page and reports
7211
+ * orientation changes via screenOrientationLockChanged events. This is
7212
+ * useful for emulating mobile device orientation lock behavior in
7213
+ * responsive design mode.
7214
+ */
7215
+ screenOrientationLockEmulation?: boolean;
7208
7216
  }
7209
7217
 
7210
7218
  export interface SetDevicePostureOverrideRequest {
@@ -7547,6 +7555,57 @@ export namespace Emulation {
7547
7555
  screenInfo: ScreenInfo;
7548
7556
  }
7549
7557
 
7558
+ export interface UpdateScreenRequest {
7559
+ /**
7560
+ * Target screen identifier.
7561
+ */
7562
+ screenId: ScreenId;
7563
+ /**
7564
+ * Offset of the left edge of the screen in pixels.
7565
+ */
7566
+ left?: integer;
7567
+ /**
7568
+ * Offset of the top edge of the screen in pixels.
7569
+ */
7570
+ top?: integer;
7571
+ /**
7572
+ * The width of the screen in pixels.
7573
+ */
7574
+ width?: integer;
7575
+ /**
7576
+ * The height of the screen in pixels.
7577
+ */
7578
+ height?: integer;
7579
+ /**
7580
+ * Specifies the screen's work area.
7581
+ */
7582
+ workAreaInsets?: WorkAreaInsets;
7583
+ /**
7584
+ * Specifies the screen's device pixel ratio.
7585
+ */
7586
+ devicePixelRatio?: number;
7587
+ /**
7588
+ * Specifies the screen's rotation angle. Available values are 0, 90, 180 and 270.
7589
+ */
7590
+ rotation?: integer;
7591
+ /**
7592
+ * Specifies the screen's color depth in bits.
7593
+ */
7594
+ colorDepth?: integer;
7595
+ /**
7596
+ * Specifies the descriptive label for the screen.
7597
+ */
7598
+ label?: string;
7599
+ /**
7600
+ * Indicates whether the screen is internal to the device or external, attached to the device. Default is false.
7601
+ */
7602
+ isInternal?: boolean;
7603
+ }
7604
+
7605
+ export interface UpdateScreenResponse extends ProtocolResponseWithError {
7606
+ screenInfo: ScreenInfo;
7607
+ }
7608
+
7550
7609
  export interface RemoveScreenRequest {
7551
7610
  screenId: ScreenId;
7552
7611
  }
@@ -5,6 +5,7 @@
5
5
  import * as Host from '../../../core/host/host.js';
6
6
  import * as Root from '../../../core/root/root.js';
7
7
  import type * as SDK from '../../../core/sdk/sdk.js';
8
+ import type * as Protocol from '../../../generated/protocol.js';
8
9
  import * as Greendev from '../../greendev/greendev.js';
9
10
  import {debugLog, isStructuredLogEnabled} from '../debug.js';
10
11
 
@@ -84,6 +85,7 @@ export interface ThoughtResponse {
84
85
 
85
86
  export interface SideEffectResponse {
86
87
  type: ResponseType.SIDE_EFFECT;
88
+ description: string|null;
87
89
  code?: string;
88
90
  confirm: (confirm: boolean) => void;
89
91
  }
@@ -105,6 +107,7 @@ export interface ActionResponse {
105
107
  code?: string;
106
108
  output?: string;
107
109
  canceled: boolean;
110
+ widgets?: AiWidget[];
108
111
  }
109
112
 
110
113
  export interface QueryingResponse {
@@ -215,10 +218,29 @@ export abstract class ConversationContext<T> {
215
218
  }
216
219
  }
217
220
 
221
+ export interface ComputedStyleAiWidget {
222
+ name: 'COMPUTED_STYLES';
223
+ data: {
224
+ computedStyles: Map<string, string>,
225
+ backendNodeId: Protocol.DOM.BackendNodeId,
226
+ matchedCascade: SDK.CSSMatchedStyles.CSSMatchedStyles,
227
+ // The subset of CSS properties that the AI looked up.
228
+ properties: string[],
229
+ };
230
+ }
231
+ // This type will grow as we add more widgets.
232
+ export type AiWidget = ComputedStyleAiWidget;
233
+
218
234
  export type FunctionCallHandlerResult<Result> = {
219
235
  requiresApproval: true,
236
+ /**
237
+ * Provides extra description of what the required
238
+ * approval is requesting.
239
+ */
240
+ description: string|null,
220
241
  }|{
221
242
  result: Result,
243
+ widgets?: AiWidget[],
222
244
  }|{
223
245
  context: ConversationContext<unknown>,
224
246
  description: string,
@@ -259,7 +281,6 @@ export interface FunctionDeclaration<Args extends Record<string, unknown>, Retur
259
281
  /**
260
282
  * Function implementation that the LLM will try to execute,
261
283
  */
262
-
263
284
  handler(args: Args, options?: FunctionHandlerOptions): Promise<FunctionCallHandlerResult<ReturnType>>;
264
285
  }
265
286
 
@@ -738,6 +759,7 @@ export abstract class AiAgent<T> {
738
759
  yield {
739
760
  type: ResponseType.SIDE_EFFECT,
740
761
  confirm: sideEffectConfirmationPromiseWithResolvers.resolve,
762
+ description: result.description,
741
763
  };
742
764
 
743
765
  const approvedRun = await sideEffectConfirmationPromiseWithResolvers.promise;
@@ -764,6 +786,7 @@ export abstract class AiAgent<T> {
764
786
  type: ResponseType.ACTION,
765
787
  code,
766
788
  output: typeof result.result === 'string' ? result.result : JSON.stringify(result.result),
789
+ widgets: result.widgets,
767
790
  canceled: false,
768
791
  };
769
792
  }
@@ -4,6 +4,7 @@
4
4
 
5
5
  import type * as Common from '../../../core/common/common.js';
6
6
  import * as Host from '../../../core/host/host.js';
7
+ import * as i18n from '../../../core/i18n/i18n.js';
7
8
  import type * as Platform from '../../../core/platform/platform.js';
8
9
  import * as SDK from '../../../core/sdk/sdk.js';
9
10
  import * as Bindings from '../../bindings/bindings.js';
@@ -31,6 +32,8 @@ import {
31
32
  removeOverlay,
32
33
  } from './BreakpointDebuggerAgentOverlay.js';
33
34
 
35
+ const lockedString = i18n.i18n.lockedString;
36
+
34
37
  // This is a temporary agent for a GreenDev prototype.
35
38
  // The preamble is not on the server and you should not build on top of this.
36
39
  const preamble = `You are an expert Root Cause Analysis (RCA) specialist.
@@ -52,17 +55,18 @@ You have two modes of operation that you can switch between and control:
52
55
  6. **Step**: Use 'stepInto' to investigate function calls on the current line. Use 'stepOut' to return to the caller. Use 'stepOver' to move to the next line.
53
56
  7. **Trace Back**: If the current function isn't the root cause, use 'getCallStack' to find the caller, and repeat the analysis there.
54
57
  8. **Root Cause**: Explain exactly how the runtime state contradicts the expected logic and point to the specific line of code that is the root cause.
55
- 9. **Test Fix**: Use the 'testFixInConsole' tool to run a JavaScript snippet in the current execution context to test your fix before making permanent changes. This will overwrite the problematic function or state. Follow the instructions to get the user's approval.
56
- 10. **Verify**: IMMEDIATELY AFTER 'testFixInConsole' succeeds, you MUST call 'waitForUserActionToTriggerBreakpoint' (to pause and inspect) or 'resume' (if no inspection is needed), AND ask the user to trigger the buggy action again to verify the fix.
57
- 11. **Patch**: Once the fix is successfully verified by the user, you MUST use the 'suggestFix' tool to apply the patch to the source code file. Provide the URL, the exact original code to change, and the new code. Finish the execution then.
58
+ 9. **Apply Fix**: Use the 'testFixInConsole' tool to overwrite the problematic code in the current session.
59
+ 10. **Verify**: The fix is applied but NOT verified. You MUST run the code again to verify the fix worked.
60
+ 11. **Finish**: If the fix worked, you may output the solution and finish the execution.
58
61
 
59
62
  **Rules**:
60
- - **NEVER FINISH** execution until you have found the root cause or answer.
63
+ - **NEVER FINISH** execution until you have found the root cause and verified the fix.
61
64
  - **ACTION OVER TALK**: If you need the user to trigger a breakpoint, do NOT just ask them in text. You **MUST** call 'waitForUserActionToTriggerBreakpoint'. This tool will block and wait for the user to act.
62
65
  - **STATIC MODE**: If you are in STATIC MODE and need to see variables: 1. 'setBreakpoint', 2. 'waitForUserActionToTriggerBreakpoint'. **DO NOT STOP** to ask the user. Investigate code and set breakpoints to find the root cause.
63
66
  - **ALREADY PAUSED?**: If 'setBreakpoint' warns you that you are already paused, **DO NOT** call 'waitForUserActionToTriggerBreakpoint'. Start inspecting immediately. You can set more breakpoints while paused, but to call 'waitForUserActionToTriggerBreakpoint' again you MUST be in static state.
64
67
  - **USE TOOLS EXCESSIVELY**: checking one thing is often not enough. Check everything you can thinks of.
65
68
  - **CHECK LOCATION**: If you are not sure where you are, call 'getExecutionLocation' after 'waitForUserActionToTriggerBreakpoint' or any step command to confirm where you are.
69
+ - **INITIAL CONTEXT**: The breakpoint provided in the context is ALREADY SET. Do NOT set it again. Start by setting additional breakpoints if needed, or, if no additional breakpoints within the code you see make sense, call 'waitForUserActionToTriggerBreakpoint'.
66
70
 
67
71
  **Execution Control when you are currently on a breakpoint**:
68
72
  - **stepInto**: ESSENTIAL for entering function calls on the current line. Use this heavily when you suspect the issue is inside a called function.
@@ -121,8 +125,10 @@ export class BreakpointDebuggerAgent extends AiAgent<Workspace.UISourceCode.UILo
121
125
  required: ['url', 'lineNumber'],
122
126
  },
123
127
  displayInfoFromArgs: (args: {url: string, lineNumber: number}) => {
128
+ const uiSourceCode = Workspace.Workspace.WorkspaceImpl.instance().uiSourceCodeForURL(
129
+ args.url as Platform.DevToolsPath.UrlString);
124
130
  return {
125
- title: `Reading function source for ${args.url}:${args.lineNumber}`,
131
+ title: `Reading function source for ${uiSourceCode?.displayName()}:${args.lineNumber}`,
126
132
  };
127
133
  },
128
134
  handler: async (args: {url: string, lineNumber: number}) => {
@@ -155,8 +161,10 @@ export class BreakpointDebuggerAgent extends AiAgent<Workspace.UISourceCode.UILo
155
161
  required: ['url', 'lineNumber', 'direction'],
156
162
  },
157
163
  displayInfoFromArgs: (args: {url: string, lineNumber: number, direction: 'before'|'after'}) => {
164
+ const uiSourceCode = Workspace.Workspace.WorkspaceImpl.instance().uiSourceCodeForURL(
165
+ args.url as Platform.DevToolsPath.UrlString);
158
166
  return {
159
- title: `Reading code ${args.direction} ${args.url}:${args.lineNumber}`,
167
+ title: `Reading code ${args.direction} ${uiSourceCode?.displayName()}:${args.lineNumber}`,
160
168
  };
161
169
  },
162
170
  handler: async (args: {url: string, lineNumber: number, direction: 'before'|'after'}) => {
@@ -240,8 +248,10 @@ export class BreakpointDebuggerAgent extends AiAgent<Workspace.UISourceCode.UILo
240
248
  required: ['url', 'lineNumber'],
241
249
  },
242
250
  displayInfoFromArgs: (args: {url: string, lineNumber: number}) => {
251
+ const uiSourceCode = Workspace.Workspace.WorkspaceImpl.instance().uiSourceCodeForURL(
252
+ args.url as Platform.DevToolsPath.UrlString);
243
253
  return {
244
- title: `Setting breakpoint at ${args.url}:${args.lineNumber}`,
254
+ title: `Setting breakpoint at ${uiSourceCode?.displayName() ?? args.url}:${args.lineNumber}`,
245
255
  };
246
256
  },
247
257
  handler: async (args: {url: string, lineNumber: number}) => {
@@ -269,8 +279,10 @@ export class BreakpointDebuggerAgent extends AiAgent<Workspace.UISourceCode.UILo
269
279
  required: ['url', 'lineNumber'],
270
280
  },
271
281
  displayInfoFromArgs: (args: {url: string, lineNumber: number}) => {
282
+ const uiSourceCode = Workspace.Workspace.WorkspaceImpl.instance().uiSourceCodeForURL(
283
+ args.url as Platform.DevToolsPath.UrlString);
272
284
  return {
273
- title: `Removing breakpoint at ${args.url}:${args.lineNumber}`,
285
+ title: `Removing breakpoint at ${uiSourceCode?.displayName() ?? args.url}:${args.lineNumber}`,
274
286
  };
275
287
  },
276
288
  handler: async (args: {url: string, lineNumber: number}) => {
@@ -429,7 +441,7 @@ export class BreakpointDebuggerAgent extends AiAgent<Workspace.UISourceCode.UILo
429
441
 
430
442
  this.declareFunction('testFixInConsole', {
431
443
  description:
432
- 'Tests a JavaScript code snippet in the current execution context to overwrite the problematic code or state. Use this to verify the fix works before patching the source file.',
444
+ 'Tests a JavaScript code snippet in the current execution context to overwrite the problematic code or state. After running this, verify the fix worked.',
433
445
  parameters: {
434
446
  type: Host.AidaClient.ParametersTypes.OBJECT,
435
447
  description: 'Provide the code to evaluate to test the fix',
@@ -458,7 +470,10 @@ export class BreakpointDebuggerAgent extends AiAgent<Workspace.UISourceCode.UILo
458
470
  return {error: 'Fix rejected by the user.'};
459
471
  }
460
472
  if (!options?.approved) {
461
- return {requiresApproval: true};
473
+ return {
474
+ requiresApproval: true,
475
+ description: lockedString('This code may modify page content. Continue?'),
476
+ };
462
477
  }
463
478
 
464
479
  const targetManager = SDK.TargetManager.TargetManager.instance();
@@ -498,86 +513,11 @@ export class BreakpointDebuggerAgent extends AiAgent<Workspace.UISourceCode.UILo
498
513
  return {
499
514
  result: {
500
515
  status:
501
- 'Code evaluated successfully. You MUST now call waitForUserActionToTriggerBreakpoint or resume, and ask the user to trigger the action again to verify the fix.'
516
+ 'Code evaluated successfully. Fix applied. PROCEED TO VERIFICATION: Call "resume" and ask the user to "run the code again" to verify.'
502
517
  }
503
518
  };
504
519
  },
505
520
  });
506
-
507
- this.declareFunction('suggestFix', {
508
- description:
509
- 'Suggests a JavaScript code snippet to fix the root cause of the issue and applies it to the source code file if the user approves. Call this function AFTER you have verified the fix works using testFixInConsole.',
510
- parameters: {
511
- type: Host.AidaClient.ParametersTypes.OBJECT,
512
- description: 'Provide the fix to the user',
513
- properties: {
514
- url: {
515
- type: Host.AidaClient.ParametersTypes.STRING,
516
- description: 'The URL of the file to fix.',
517
- },
518
- originalCode: {
519
- type: Host.AidaClient.ParametersTypes.STRING,
520
- description:
521
- 'The exact original code to replace. Must match the file content exactly, including whitespace.',
522
- },
523
- suggestion: {
524
- type: Host.AidaClient.ParametersTypes.STRING,
525
- description: 'The new JavaScript code to replace the original code with.',
526
- },
527
- explanation: {
528
- type: Host.AidaClient.ParametersTypes.STRING,
529
- description: 'Explanation for why this code fixes the issue.',
530
- },
531
- },
532
- required: ['url', 'originalCode', 'suggestion', 'explanation'],
533
- },
534
- displayInfoFromArgs: (args: {suggestion: string, explanation: string}) => {
535
- return {
536
- title: 'Suggesting a fix',
537
- thought: args.explanation,
538
- action: args.suggestion,
539
- };
540
- },
541
- handler: async (
542
- args: {url: string, originalCode: string, suggestion: string, explanation: string},
543
- options?: FunctionHandlerOptions) => {
544
- debugLog('suggestFix requested', args);
545
- if (options?.approved === false) {
546
- return {error: 'Fix rejected by the user.'};
547
- }
548
- if (!options?.approved) {
549
- return {requiresApproval: true};
550
- }
551
-
552
- const uiSourceCode = Workspace.Workspace.WorkspaceImpl.instance().uiSourceCodeForURL(
553
- args.url as Platform.DevToolsPath.UrlString);
554
- if (!uiSourceCode) {
555
- return {error: `File not found: ${args.url}`};
556
- }
557
-
558
- const contentData = await uiSourceCode.requestContentData();
559
- if ('error' in contentData || !contentData.isTextContent) {
560
- return {error: `Could not read content for file: ${args.url}`};
561
- }
562
-
563
- let currentContent = uiSourceCode.workingCopy();
564
- if (!uiSourceCode.isDirty()) {
565
- currentContent = contentData.text;
566
- }
567
-
568
- if (!currentContent.includes(args.originalCode)) {
569
- return {
570
- error: 'originalCode not found in the file. Ensure the originalCode is an exact match including whitespace.'
571
- };
572
- }
573
-
574
- const newContent = currentContent.replace(args.originalCode, args.suggestion);
575
- uiSourceCode.setWorkingCopy(newContent);
576
- uiSourceCode.commitWorkingCopy();
577
-
578
- return {result: {status: 'Fix applied to the source file successfully.'}};
579
- },
580
- });
581
521
  }
582
522
 
583
523
  async #getFunctionSource(args: {url: string, lineNumber: number}):
@@ -123,6 +123,7 @@ export class ContextSelectionAgent extends AiAgent<never> {
123
123
  url: request.url(),
124
124
  statusCode: request.statusCode,
125
125
  duration: i18n.TimeUtilities.secondsToString(request.duration),
126
+ transferSize: i18n.ByteUtilities.formatBytesToKb(request.transferSize),
126
127
  });
127
128
  }
128
129
 
@@ -290,14 +291,23 @@ export class ContextSelectionAgent extends AiAgent<never> {
290
291
  },
291
292
  displayInfoFromArgs: () => {
292
293
  return {
293
- title: lockedString('Please select an element on the page'),
294
- action: 'selectElement()',
294
+ title: lockedString('Select an element on the page or in the Elements panel'),
295
295
  };
296
296
  },
297
- handler: async () => {
297
+ handler: async (_params, options) => {
298
298
  if (!this.#onInspectElement) {
299
- return {error: 'The inspect element action is not available.'};
299
+ return {
300
+ error: 'The inspect element action is not available.',
301
+ };
302
+ }
303
+
304
+ if (!options?.approved) {
305
+ return {
306
+ requiresApproval: true,
307
+ description: null,
308
+ };
300
309
  }
310
+
301
311
  const node = await this.#onInspectElement();
302
312
  if (node) {
303
313
  return {
@@ -18,6 +18,7 @@ import {FREESTYLER_WORLD_NAME} from '../injected.js';
18
18
  import {
19
19
  type AgentOptions as BaseAgentOptions,
20
20
  AiAgent,
21
+ type ComputedStyleAiWidget,
21
22
  type ContextResponse,
22
23
  ConversationContext,
23
24
  type ConversationSuggestions,
@@ -325,7 +326,7 @@ export class StylingAgent extends AiAgent<SDK.DOMModel.DOMNode> {
325
326
  };
326
327
  },
327
328
  handler: async params => {
328
- return await this.getStyles(params.elements, params.styleProperties);
329
+ return await this.#getStyles(params.elements, params.styleProperties);
329
330
  },
330
331
  });
331
332
 
@@ -606,7 +607,9 @@ const data = {
606
607
  return this.context?.getItem() ?? null;
607
608
  }
608
609
 
609
- async getStyles(elements: number[], properties: string[]): Promise<FunctionCallHandlerResult<unknown>> {
610
+ async #getStyles(elements: number[], properties: string[]): Promise<FunctionCallHandlerResult<unknown>> {
611
+ const widgets: ComputedStyleAiWidget[] = [];
612
+
610
613
  const result:
611
614
  Record<string, {computed: Record<string, string|undefined>, authored: Record<string, string|undefined>}> = {};
612
615
  for (const uid of elements) {
@@ -630,6 +633,15 @@ const data = {
630
633
  if (!matchedStyles) {
631
634
  return {error: 'Error: Could not get authored styles.'};
632
635
  }
636
+ widgets.push({
637
+ name: 'COMPUTED_STYLES',
638
+ data: {
639
+ computedStyles: styles,
640
+ backendNodeId: node.backendNodeId(),
641
+ matchedCascade: matchedStyles,
642
+ properties,
643
+ }
644
+ });
633
645
  for (const prop of properties) {
634
646
  result[uid].computed[prop] = styles.get(prop);
635
647
  }
@@ -647,6 +659,7 @@ const data = {
647
659
  }
648
660
  return {
649
661
  result: JSON.stringify(result, null, 2),
662
+ widgets,
650
663
  };
651
664
  }
652
665
 
@@ -701,6 +714,7 @@ const data = {
701
714
 
702
715
  return {
703
716
  requiresApproval: true,
717
+ description: lockedString('This code may modify page content. Continue?'),
704
718
  };
705
719
  }
706
720
  if (result.canceled) {