chrome-devtools-frontend 1.0.1661063 → 1.0.1662965

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 (131) hide show
  1. package/.agents/skills/devtools-unicode-escaping/SKILL.md +64 -0
  2. package/.agents/skills/evaluate-ai-css-completion/SKILL.md +19 -9
  3. package/.agents/skills/evaluate-ai-css-completion/scripts/evaluate.js +44 -16
  4. package/.agents/skills/migrate-chromium-test/SKILL.md +32 -2
  5. package/.agents/skills/ui-eng-vision-local-lit-renderer/SKILL.md +7 -1
  6. package/docs/ui_engineering.md +75 -42
  7. package/front_end/core/common/SettingRegistration.ts +0 -10
  8. package/front_end/core/common/Settings.ts +69 -3
  9. package/front_end/core/platform/ArrayUtilities.ts +10 -0
  10. package/front_end/core/platform/StringUtilities.ts +38 -6
  11. package/front_end/core/sdk/ServiceWorkerCacheModel.ts +0 -10
  12. package/front_end/core/sdk/StorageBucketsModel.ts +0 -10
  13. package/front_end/core/sdk/sdk-meta.ts +0 -1
  14. package/front_end/entrypoints/inspector_main/OutermostTargetSelector.ts +0 -13
  15. package/front_end/entrypoints/inspector_main/RenderingOptions.ts +8 -3
  16. package/front_end/entrypoints/inspector_main/inspector_main-meta.ts +3 -3
  17. package/front_end/entrypoints/main/MainImpl.ts +7 -2
  18. package/front_end/foundation/README.md +86 -0
  19. package/front_end/foundation/Universe.ts +16 -0
  20. package/front_end/generated/InspectorBackendCommands.ts +6 -19
  21. package/front_end/generated/protocol-mapping.d.ts +0 -53
  22. package/front_end/generated/protocol-proxy-api.d.ts +0 -46
  23. package/front_end/generated/protocol.ts +20 -186
  24. package/front_end/models/ai_assistance/AiAgent2.ts +3 -3
  25. package/front_end/models/ai_assistance/AiConversation.ts +21 -10
  26. package/front_end/models/ai_assistance/AiHistoryStorage.ts +21 -10
  27. package/front_end/models/ai_assistance/ChangeManager.ts +2 -2
  28. package/front_end/models/ai_assistance/ExtensionScope.ts +6 -2
  29. package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +1 -1
  30. package/front_end/models/ai_assistance/agents/AiAgent.ts +8 -1
  31. package/front_end/models/ai_assistance/agents/StylingAgent.ts +1 -1
  32. package/front_end/models/badges/UserBadges.ts +31 -17
  33. package/front_end/models/bindings/CompilerScriptMapping.ts +5 -4
  34. package/front_end/models/bindings/ContentProviderBasedProject.ts +2 -3
  35. package/front_end/models/bindings/DebuggerLanguagePlugins.ts +4 -3
  36. package/front_end/models/bindings/DefaultScriptMapping.ts +3 -3
  37. package/front_end/models/bindings/NetworkProject.ts +22 -1
  38. package/front_end/models/bindings/ResourceMapping.ts +4 -3
  39. package/front_end/models/bindings/ResourceScriptMapping.ts +2 -1
  40. package/front_end/models/bindings/SASSSourceMapping.ts +4 -3
  41. package/front_end/models/bindings/StylesSourceMapping.ts +3 -3
  42. package/front_end/models/emulation/DeviceModeModel.ts +67 -5
  43. package/front_end/models/extensions/RecorderExtensionEndpoint.ts +7 -5
  44. package/front_end/models/extensions/RecorderPluginManager.ts +10 -6
  45. package/front_end/models/har/Log.snapshot.txt +193 -0
  46. package/front_end/models/har/Log.ts +3 -2
  47. package/front_end/models/heap_snapshot/HeapSnapshotProxy.ts +14 -5
  48. package/front_end/models/issues_manager/CheckFormsIssuesTrigger.ts +8 -9
  49. package/front_end/models/issues_manager/RelatedIssue.ts +10 -8
  50. package/front_end/models/javascript_metadata/NativeFunctions.js +1 -1
  51. package/front_end/models/logs/RequestResolver.ts +2 -2
  52. package/front_end/models/persistence/AutomaticFileSystemWorkspaceBinding.ts +0 -5
  53. package/front_end/models/source_map_scopes/FunctionCodeResolver.ts +8 -6
  54. package/front_end/models/source_map_scopes/NamesResolver.ts +36 -30
  55. package/front_end/models/stack_trace/StackTrace.ts +17 -0
  56. package/front_end/models/trace/handlers/FramesHandler.ts +4 -7
  57. package/front_end/models/trace/handlers/ModelHandlers.ts +0 -1
  58. package/front_end/models/trace/handlers/RendererHandler.ts +2 -15
  59. package/front_end/models/trace/handlers/Threads.ts +4 -11
  60. package/front_end/models/trace/insights/DOMSize.ts +1 -1
  61. package/front_end/models/workspace/WorkspaceImpl.ts +1 -10
  62. package/front_end/panels/application/ApplicationPanelSidebar.ts +0 -44
  63. package/front_end/panels/application/CookieItemsView.ts +1 -1
  64. package/front_end/panels/application/FrameDetailsView.ts +1 -1
  65. package/front_end/panels/application/IndexedDBModel.ts +0 -10
  66. package/front_end/panels/application/IndexedDBViews.ts +240 -164
  67. package/front_end/panels/application/ServiceWorkersView.ts +494 -411
  68. package/front_end/panels/application/SharedStorageModel.ts +0 -10
  69. package/front_end/panels/application/application.ts +0 -6
  70. package/front_end/panels/application/components/AdsView.ts +23 -0
  71. package/front_end/panels/application/components/SharedStorageAccessGrid.ts +1 -1
  72. package/front_end/panels/application/components/adsView.css +21 -1
  73. package/front_end/panels/application/components/components.ts +0 -2
  74. package/front_end/panels/application/indexedDBViews.css +1 -1
  75. package/front_end/panels/application/preloading/components/PreloadingDetailsReportView.ts +1 -1
  76. package/front_end/panels/application/serviceWorkersView.css +40 -4
  77. package/front_end/panels/browser_debugger/XHRBreakpointsSidebarPane.ts +147 -123
  78. package/front_end/panels/common/ExtensionServer.ts +3 -3
  79. package/front_end/panels/console/ConsoleView.ts +1 -1
  80. package/front_end/panels/emulation/DeviceModeView.ts +139 -70
  81. package/front_end/panels/issues/AffectedResourcesView.ts +1 -1
  82. package/front_end/panels/lighthouse/LighthouseProtocolService.ts +53 -12
  83. package/front_end/panels/network/NetworkDataGridNode.ts +43 -1
  84. package/front_end/panels/network/RequestInitiatorView.ts +24 -2
  85. package/front_end/panels/network/RequestPayloadView.ts +77 -39
  86. package/front_end/panels/network/components/ResponseHeaderSection.ts +5 -3
  87. package/front_end/panels/network/networkLogView.css +5 -0
  88. package/front_end/panels/network/requestInitiatorViewTree.css +5 -0
  89. package/front_end/panels/profiler/HeapProfileView.ts +198 -79
  90. package/front_end/panels/profiler/HeapSnapshotView.ts +2 -2
  91. package/front_end/panels/recorder/README.md +1 -2
  92. package/front_end/panels/recorder/RecorderPanel.ts +1749 -17
  93. package/front_end/panels/recorder/recorder.ts +0 -2
  94. package/front_end/panels/settings/AISettingsTab.ts +13 -0
  95. package/front_end/panels/sources/SourcesNavigator.ts +3 -2
  96. package/front_end/panels/sources/SourcesView.ts +0 -17
  97. package/front_end/panels/sources/UISourceCodeFrame.ts +42 -0
  98. package/front_end/panels/sources/sources.ts +0 -2
  99. package/front_end/panels/timeline/CompatibilityTracksAppender.ts +0 -17
  100. package/front_end/panels/timeline/ThreadAppender.ts +0 -106
  101. package/front_end/third_party/chromium/README.chromium +1 -1
  102. package/front_end/ui/components/report_view/ReportView.ts +11 -5
  103. package/front_end/ui/components/report_view/report.css +4 -1
  104. package/front_end/ui/components/spinners/Spinner.ts +29 -32
  105. package/front_end/ui/components/spinners/spinner.css +32 -84
  106. package/front_end/ui/legacy/TextPrompt.ts +49 -1
  107. package/front_end/ui/legacy/Treeoutline.ts +14 -6
  108. package/front_end/ui/legacy/UIUtils.ts +36 -11
  109. package/front_end/ui/legacy/Widget.ts +17 -10
  110. package/front_end/ui/legacy/components/cookie_table/CookiesTable.ts +2 -2
  111. package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +36 -7
  112. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +63 -68
  113. package/front_end/ui/legacy/components/object_ui/RemoteObjectPreviewFormatter.ts +1 -1
  114. package/front_end/ui/legacy/components/object_ui/objectValue.css +2 -1
  115. package/front_end/ui/legacy/inspectorCommon.css +4 -4
  116. package/front_end/ui/legacy/textPrompt.css +10 -0
  117. package/front_end/ui/lit/lit.ts +1 -0
  118. package/front_end/ui/lit/render.ts +44 -10
  119. package/front_end/ui/lit/strip-whitespace.ts +23 -2
  120. package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
  121. package/package.json +1 -1
  122. package/front_end/models/trace/handlers/AuctionWorkletsHandler.ts +0 -183
  123. package/front_end/panels/application/InterestGroupStorageModel.ts +0 -81
  124. package/front_end/panels/application/InterestGroupStorageView.ts +0 -151
  125. package/front_end/panels/application/InterestGroupTreeElement.ts +0 -65
  126. package/front_end/panels/application/components/InterestGroupAccessGrid.ts +0 -135
  127. package/front_end/panels/application/components/interestGroupAccessGrid.css +0 -27
  128. package/front_end/panels/application/interestGroupStorageView.css +0 -9
  129. package/front_end/panels/recorder/RecorderController.ts +0 -1595
  130. package/front_end/panels/sources/InplaceFormatterEditorAction.ts +0 -149
  131. /package/front_end/panels/recorder/{recorderController.css → recorderPanel.css} +0 -0
@@ -943,7 +943,6 @@ export namespace Audits {
943
943
  }
944
944
 
945
945
  export const enum MixedContentResourceType {
946
- AttributionSrc = 'AttributionSrc',
947
946
  Audio = 'Audio',
948
947
  Beacon = 'Beacon',
949
948
  CSPReport = 'CSPReport',
@@ -1120,30 +1119,6 @@ export namespace Audits {
1120
1119
  clientSecurityState?: Network.ClientSecurityState;
1121
1120
  }
1122
1121
 
1123
- export const enum AttributionReportingIssueType {
1124
- PermissionPolicyDisabled = 'PermissionPolicyDisabled',
1125
- UntrustworthyReportingOrigin = 'UntrustworthyReportingOrigin',
1126
- InsecureContext = 'InsecureContext',
1127
- InvalidHeader = 'InvalidHeader',
1128
- InvalidRegisterTriggerHeader = 'InvalidRegisterTriggerHeader',
1129
- SourceAndTriggerHeaders = 'SourceAndTriggerHeaders',
1130
- SourceIgnored = 'SourceIgnored',
1131
- TriggerIgnored = 'TriggerIgnored',
1132
- OsSourceIgnored = 'OsSourceIgnored',
1133
- OsTriggerIgnored = 'OsTriggerIgnored',
1134
- InvalidRegisterOsSourceHeader = 'InvalidRegisterOsSourceHeader',
1135
- InvalidRegisterOsTriggerHeader = 'InvalidRegisterOsTriggerHeader',
1136
- WebAndOsHeaders = 'WebAndOsHeaders',
1137
- NoWebOrOsSupport = 'NoWebOrOsSupport',
1138
- NavigationRegistrationWithoutTransientUserActivation = 'NavigationRegistrationWithoutTransientUserActivation',
1139
- InvalidInfoHeader = 'InvalidInfoHeader',
1140
- NoRegisterSourceHeader = 'NoRegisterSourceHeader',
1141
- NoRegisterTriggerHeader = 'NoRegisterTriggerHeader',
1142
- NoRegisterOsSourceHeader = 'NoRegisterOsSourceHeader',
1143
- NoRegisterOsTriggerHeader = 'NoRegisterOsTriggerHeader',
1144
- NavigationRegistrationUniqueScopeAlreadySet = 'NavigationRegistrationUniqueScopeAlreadySet',
1145
- }
1146
-
1147
1122
  export const enum SharedDictionaryError {
1148
1123
  UseErrorCrossOriginNoCorsRequest = 'UseErrorCrossOriginNoCorsRequest',
1149
1124
  UseErrorDictionaryLoadFailure = 'UseErrorDictionaryLoadFailure',
@@ -1217,17 +1192,6 @@ export namespace Audits {
1217
1192
  InvalidUrlPattern = 'InvalidUrlPattern',
1218
1193
  }
1219
1194
 
1220
- /**
1221
- * Details for issues around "Attribution Reporting API" usage.
1222
- * Explainer: https://github.com/WICG/attribution-reporting-api
1223
- */
1224
- export interface AttributionReportingIssueDetails {
1225
- violationType: AttributionReportingIssueType;
1226
- request?: AffectedRequest;
1227
- violatingNodeId?: DOM.BackendNodeId;
1228
- invalidParameter?: string;
1229
- }
1230
-
1231
1195
  /**
1232
1196
  * Details for issues about documents in Quirks Mode
1233
1197
  * or Limited Quirks Mode that affects page layouting.
@@ -1707,6 +1671,24 @@ export namespace Audits {
1707
1671
  stackTrace?: Runtime.StackTrace;
1708
1672
  }
1709
1673
 
1674
+ /**
1675
+ * Details for issues about lazy-loaded images without explicit dimensions.
1676
+ */
1677
+ export interface LazyLoadImageIssueDetails {
1678
+ /**
1679
+ * DOM node of the problematic HTMLImageElement.
1680
+ */
1681
+ nodeId: DOM.BackendNodeId;
1682
+ /**
1683
+ * URL or src attribute of the image.
1684
+ */
1685
+ url: string;
1686
+ /**
1687
+ * Frame containing the image.
1688
+ */
1689
+ frameId: Page.FrameId;
1690
+ }
1691
+
1710
1692
  /**
1711
1693
  * A unique identifier for the type of issue. Each type may use one of the
1712
1694
  * optional fields in InspectorIssueDetails to convey more specific
@@ -1720,7 +1702,6 @@ export namespace Audits {
1720
1702
  ContentSecurityPolicyIssue = 'ContentSecurityPolicyIssue',
1721
1703
  SharedArrayBufferIssue = 'SharedArrayBufferIssue',
1722
1704
  CorsIssue = 'CorsIssue',
1723
- AttributionReportingIssue = 'AttributionReportingIssue',
1724
1705
  QuirksModeIssue = 'QuirksModeIssue',
1725
1706
  PartitioningBlobURLIssue = 'PartitioningBlobURLIssue',
1726
1707
  NavigatorUserAgentIssue = 'NavigatorUserAgentIssue',
@@ -1743,6 +1724,7 @@ export namespace Audits {
1743
1724
  PerformanceIssue = 'PerformanceIssue',
1744
1725
  SelectivePermissionsInterventionIssue = 'SelectivePermissionsInterventionIssue',
1745
1726
  EmailVerificationRequestIssue = 'EmailVerificationRequestIssue',
1727
+ LazyLoadImageIssue = 'LazyLoadImageIssue',
1746
1728
  }
1747
1729
 
1748
1730
  /**
@@ -1758,7 +1740,6 @@ export namespace Audits {
1758
1740
  contentSecurityPolicyIssueDetails?: ContentSecurityPolicyIssueDetails;
1759
1741
  sharedArrayBufferIssueDetails?: SharedArrayBufferIssueDetails;
1760
1742
  corsIssueDetails?: CorsIssueDetails;
1761
- attributionReportingIssueDetails?: AttributionReportingIssueDetails;
1762
1743
  quirksModeIssueDetails?: QuirksModeIssueDetails;
1763
1744
  partitioningBlobURLIssueDetails?: PartitioningBlobURLIssueDetails;
1764
1745
  /**
@@ -1784,6 +1765,7 @@ export namespace Audits {
1784
1765
  performanceIssueDetails?: PerformanceIssueDetails;
1785
1766
  selectivePermissionsInterventionIssueDetails?: SelectivePermissionsInterventionIssueDetails;
1786
1767
  emailVerificationRequestIssueDetails?: EmailVerificationRequestIssueDetails;
1768
+ lazyLoadImageIssueDetails?: LazyLoadImageIssueDetails;
1787
1769
  }
1788
1770
 
1789
1771
  /**
@@ -2524,11 +2506,6 @@ export namespace Browser {
2524
2506
  buckets: Bucket[];
2525
2507
  }
2526
2508
 
2527
- export const enum PrivacySandboxAPI {
2528
- BiddingAndAuctionServices = 'BiddingAndAuctionServices',
2529
- TrustedKeyValue = 'TrustedKeyValue',
2530
- }
2531
-
2532
2509
  export interface SetPermissionRequest {
2533
2510
  /**
2534
2511
  * Descriptor of permission to override.
@@ -2760,17 +2737,6 @@ export namespace Browser {
2760
2737
  url: string;
2761
2738
  }
2762
2739
 
2763
- export interface AddPrivacySandboxCoordinatorKeyConfigRequest {
2764
- api: PrivacySandboxAPI;
2765
- coordinatorOrigin: string;
2766
- keyConfig: string;
2767
- /**
2768
- * BrowserContext to perform the action in. When omitted, default browser
2769
- * context is used.
2770
- */
2771
- browserContextId?: BrowserContextID;
2772
- }
2773
-
2774
2740
  /**
2775
2741
  * Fired when page is about to start a download.
2776
2742
  */
@@ -14719,7 +14685,6 @@ export namespace Page {
14719
14685
  AllScreensCapture = 'all-screens-capture',
14720
14686
  AmbientLightSensor = 'ambient-light-sensor',
14721
14687
  AriaNotify = 'aria-notify',
14722
- AttributionReporting = 'attribution-reporting',
14723
14688
  Autofill = 'autofill',
14724
14689
  Autoplay = 'autoplay',
14725
14690
  Bluetooth = 'bluetooth',
@@ -18335,54 +18300,12 @@ export namespace Storage {
18335
18300
  count: number;
18336
18301
  }
18337
18302
 
18338
- /**
18339
- * Protected audience interest group auction identifier.
18340
- */
18341
- export type InterestGroupAuctionId = OpaqueIdentifier<string, 'Protocol.Storage.InterestGroupAuctionId'>;
18342
-
18343
- /**
18344
- * Enum of interest group access types.
18345
- */
18346
- export const enum InterestGroupAccessType {
18347
- Join = 'join',
18348
- Leave = 'leave',
18349
- Update = 'update',
18350
- Loaded = 'loaded',
18351
- Bid = 'bid',
18352
- Win = 'win',
18353
- AdditionalBid = 'additionalBid',
18354
- AdditionalBidWin = 'additionalBidWin',
18355
- TopLevelBid = 'topLevelBid',
18356
- TopLevelAdditionalBid = 'topLevelAdditionalBid',
18357
- Clear = 'clear',
18358
- }
18359
-
18360
- /**
18361
- * Enum of auction events.
18362
- */
18363
- export const enum InterestGroupAuctionEventType {
18364
- Started = 'started',
18365
- ConfigResolved = 'configResolved',
18366
- }
18367
-
18368
- /**
18369
- * Enum of network fetches auctions can do.
18370
- */
18371
- export const enum InterestGroupAuctionFetchType {
18372
- BidderJs = 'bidderJs',
18373
- BidderWasm = 'bidderWasm',
18374
- SellerJs = 'sellerJs',
18375
- BidderTrustedSignals = 'bidderTrustedSignals',
18376
- SellerTrustedSignals = 'sellerTrustedSignals',
18377
- }
18378
-
18379
18303
  /**
18380
18304
  * Enum of shared storage access scopes.
18381
18305
  */
18382
18306
  export const enum SharedStorageAccessScope {
18383
18307
  Window = 'window',
18384
18308
  SharedStorageWorklet = 'sharedStorageWorklet',
18385
- ProtectedAudienceWorklet = 'protectedAudienceWorklet',
18386
18309
  Header = 'header',
18387
18310
  }
18388
18311
 
@@ -18815,29 +18738,6 @@ export namespace Storage {
18815
18738
  didDeleteTokens: boolean;
18816
18739
  }
18817
18740
 
18818
- export interface GetInterestGroupDetailsRequest {
18819
- ownerOrigin: string;
18820
- name: string;
18821
- }
18822
-
18823
- export interface GetInterestGroupDetailsResponse extends ProtocolResponseWithError {
18824
- /**
18825
- * This largely corresponds to:
18826
- * https://wicg.github.io/turtledove/#dictdef-generatebidinterestgroup
18827
- * but has absolute expirationTime instead of relative lifetimeMs and
18828
- * also adds joiningOrigin.
18829
- */
18830
- details: any;
18831
- }
18832
-
18833
- export interface SetInterestGroupTrackingRequest {
18834
- enable: boolean;
18835
- }
18836
-
18837
- export interface SetInterestGroupAuctionTrackingRequest {
18838
- enable: boolean;
18839
- }
18840
-
18841
18741
  export interface GetSharedStorageMetadataRequest {
18842
18742
  ownerOrigin: string;
18843
18743
  }
@@ -18899,12 +18799,6 @@ export namespace Storage {
18899
18799
  sets: RelatedWebsiteSet[];
18900
18800
  }
18901
18801
 
18902
- export interface SetProtectedAudienceKAnonymityRequest {
18903
- owner: string;
18904
- name: string;
18905
- hashes: binary[];
18906
- }
18907
-
18908
18802
  /**
18909
18803
  * A cache's contents have been modified.
18910
18804
  */
@@ -18989,66 +18883,6 @@ export namespace Storage {
18989
18883
  bucketId: string;
18990
18884
  }
18991
18885
 
18992
- /**
18993
- * One of the interest groups was accessed. Note that these events are global
18994
- * to all targets sharing an interest group store.
18995
- */
18996
- export interface InterestGroupAccessedEvent {
18997
- accessTime: Network.TimeSinceEpoch;
18998
- type: InterestGroupAccessType;
18999
- ownerOrigin: string;
19000
- name: string;
19001
- /**
19002
- * For topLevelBid/topLevelAdditionalBid, and when appropriate,
19003
- * win and additionalBidWin
19004
- */
19005
- componentSellerOrigin?: string;
19006
- /**
19007
- * For bid or somethingBid event, if done locally and not on a server.
19008
- */
19009
- bid?: number;
19010
- bidCurrency?: string;
19011
- /**
19012
- * For non-global events --- links to interestGroupAuctionEvent
19013
- */
19014
- uniqueAuctionId?: InterestGroupAuctionId;
19015
- }
19016
-
19017
- /**
19018
- * An auction involving interest groups is taking place. These events are
19019
- * target-specific.
19020
- */
19021
- export interface InterestGroupAuctionEventOccurredEvent {
19022
- eventTime: Network.TimeSinceEpoch;
19023
- type: InterestGroupAuctionEventType;
19024
- uniqueAuctionId: InterestGroupAuctionId;
19025
- /**
19026
- * Set for child auctions.
19027
- */
19028
- parentAuctionId?: InterestGroupAuctionId;
19029
- /**
19030
- * Set for started and configResolved
19031
- */
19032
- auctionConfig?: any;
19033
- }
19034
-
19035
- /**
19036
- * Specifies which auctions a particular network fetch may be related to, and
19037
- * in what role. Note that it is not ordered with respect to
19038
- * Network.requestWillBeSent (but will happen before loadingFinished
19039
- * loadingFailed).
19040
- */
19041
- export interface InterestGroupAuctionNetworkRequestCreatedEvent {
19042
- type: InterestGroupAuctionFetchType;
19043
- requestId: Network.RequestId;
19044
- /**
19045
- * This is the set of the auctions using the worklet that issued this
19046
- * request. In the case of trusted signals, it's possible that only some of
19047
- * them actually care about the keys being queried.
19048
- */
19049
- auctions: InterestGroupAuctionId[];
19050
- }
19051
-
19052
18886
  /**
19053
18887
  * Shared storage was accessed by the associated page.
19054
18888
  * The following parameters are included in all events.
@@ -3,7 +3,6 @@
3
3
  // found in the LICENSE file.
4
4
 
5
5
  import * as Host from '../../core/host/host.js';
6
- import * as SDK from '../../core/sdk/sdk.js';
7
6
  import type * as LHModel from '../lighthouse/lighthouse.js';
8
7
 
9
8
  import {
@@ -68,7 +67,7 @@ export class AiAgent2 extends AiAgent<unknown> {
68
67
  readonly clientFeature = Host.AidaClient.ClientFeature.CHROME_DEVTOOLS_V2_AGENT;
69
68
  readonly userTier = 'TESTERS';
70
69
 
71
- #changes = new ChangeManager();
70
+ #changes: ChangeManager;
72
71
  #execJs: typeof executeJsCode;
73
72
  readonly #allowedOrigin?: () => AllowedOriginResult;
74
73
  readonly #lighthouseRecording?:
@@ -83,6 +82,7 @@ export class AiAgent2 extends AiAgent<unknown> {
83
82
 
84
83
  constructor(opts: AiAgent2Options) {
85
84
  super(opts);
85
+ this.#changes = new ChangeManager(opts.targetManager);
86
86
  this.#lighthouseRecording = opts.lighthouseRecording;
87
87
  this.#execJs = opts.execJs ?? executeJsCode;
88
88
  this.#allowedOrigin = opts.allowedOrigin;
@@ -231,7 +231,7 @@ User query: ${enhancedQuery}`;
231
231
  createExtensionScope: this.#createExtensionScope.bind(this),
232
232
  execJs: this.#execJs,
233
233
  getExecutionContextNode: () => this.context instanceof DOMNodeContext ? this.context.getItem() : null,
234
- getTarget: () => SDK.TargetManager.TargetManager.instance().primaryPageTarget(),
234
+ getTarget: () => this.targetManager.primaryPageTarget(),
235
235
  getEstablishedOrigin: () => this.#getConversationOrigin(),
236
236
  lighthouseRecording: this.#lighthouseRecording,
237
237
  };
@@ -72,6 +72,8 @@ export interface AiConversationOptions {
72
72
  onInspectElement?: () => Promise<SDK.DOMModel.DOMNode|null>;
73
73
  networkTimeCalculator?: NetworkTimeCalculator.NetworkTransferTimeCalculator;
74
74
  lighthouseRecording?: (overrides?: LHModel.RunTypes.RunOverrides) => Promise<LHModel.ReporterTypes.ReportJSON|null>;
75
+ aiHistoryStorage?: AiHistoryStorage;
76
+ targetManager?: SDK.TargetManager.TargetManager;
75
77
  }
76
78
 
77
79
  export class AiConversation {
@@ -110,6 +112,8 @@ export class AiConversation {
110
112
  #lighthouseRecording?: (overrides?: LHModel.RunTypes.RunOverrides) => Promise<LHModel.ReporterTypes.ReportJSON|null>;
111
113
  #onInspectElement?: () => Promise<SDK.DOMModel.DOMNode|null>;
112
114
  #networkTimeCalculator?: NetworkTimeCalculator.NetworkTransferTimeCalculator;
115
+ readonly #aiHistoryStorage: AiHistoryStorage;
116
+ readonly #targetManager: SDK.TargetManager.TargetManager;
113
117
 
114
118
  constructor(options: AiConversationOptions) {
115
119
  const {
@@ -123,6 +127,8 @@ export class AiConversation {
123
127
  onInspectElement,
124
128
  networkTimeCalculator,
125
129
  lighthouseRecording,
130
+ aiHistoryStorage = AiHistoryStorage.instance(),
131
+ targetManager = SDK.TargetManager.TargetManager.instance(),
126
132
  } = options;
127
133
  this.#changeManager = changeManager;
128
134
  this.#aidaClient = aidaClient;
@@ -130,6 +136,8 @@ export class AiConversation {
130
136
  this.#onInspectElement = onInspectElement;
131
137
  this.#networkTimeCalculator = networkTimeCalculator;
132
138
  this.#lighthouseRecording = lighthouseRecording;
139
+ this.#aiHistoryStorage = aiHistoryStorage;
140
+ this.#targetManager = targetManager;
133
141
 
134
142
  this.id = id;
135
143
  this.#isReadOnly = isReadOnly;
@@ -208,7 +216,7 @@ export class AiConversation {
208
216
  }
209
217
 
210
218
  #reconstructHistory(historyWithoutImages: ResponseData[]): ResponseData[] {
211
- const imageHistory = AiHistoryStorage.instance().getImageHistory();
219
+ const imageHistory = this.#aiHistoryStorage.getImageHistory();
212
220
  if (imageHistory && imageHistory.length > 0) {
213
221
  const history: ResponseData[] = [];
214
222
  for (const data of historyWithoutImages) {
@@ -286,12 +294,12 @@ export class AiConversation {
286
294
 
287
295
  async addHistoryItem(item: ResponseData): Promise<void> {
288
296
  this.history.push(item);
289
- await AiHistoryStorage.instance().upsertHistoryEntry(this.serialize());
297
+ await this.#aiHistoryStorage.upsertHistoryEntry(this.serialize());
290
298
  if (item.type === ResponseType.USER_QUERY) {
291
- void AiHistoryStorage.instance().addRecentPrompt(item.query);
299
+ void this.#aiHistoryStorage.addRecentPrompt(item.query);
292
300
  if (item.imageId && item.imageInput && 'inlineData' in item.imageInput) {
293
301
  const inlineData = item.imageInput.inlineData;
294
- await AiHistoryStorage.instance().upsertImage({
302
+ await this.#aiHistoryStorage.upsertImage({
295
303
  id: item.imageId,
296
304
  data: inlineData.data,
297
305
  mimeType: inlineData.mimeType,
@@ -361,6 +369,7 @@ export class AiConversation {
361
369
  lighthouseRecording: this.#lighthouseRecording,
362
370
  allowedOrigin: this.allowedOrigin,
363
371
  history,
372
+ targetManager: this.#targetManager,
364
373
  };
365
374
 
366
375
  this.#agent = Root.Runtime.hostConfig.devToolsAiV2Architecture?.enabled ? new AiAgent2(options) :
@@ -397,18 +406,18 @@ export class AiConversation {
397
406
  } = {},
398
407
  ): AsyncGenerator<ResponseData, void, void> {
399
408
  this.#navigationOccurredDuringRun = false;
400
- const originAtRunStart = getPrimaryPageOrigin();
409
+ const originAtRunStart = getPrimaryPageOrigin(this.#targetManager);
401
410
  const listener = (): void => {
402
411
  // If an unexpected navigation to a different origin occurred
403
412
  // during processing the user's request, we don't want to allow
404
413
  // the agent to run any function calls and retrieve data from the new origin.
405
414
  // Performance agent and accessibility agent navigate to 'about://' or 'chrome://terms'
406
- const newOrigin = getPrimaryPageOrigin();
415
+ const newOrigin = getPrimaryPageOrigin(this.#targetManager);
407
416
  if (originAtRunStart !== newOrigin && newOrigin && !ALLOWED_PAGE_NAVIGATIONS.includes(newOrigin)) {
408
417
  this.#navigationOccurredDuringRun = true;
409
418
  }
410
419
  };
411
- const targetManager = SDK.TargetManager.TargetManager.instance();
420
+ const targetManager = this.#targetManager;
412
421
  targetManager.addModelListener(SDK.ResourceTreeModel.ResourceTreeModel,
413
422
  SDK.ResourceTreeModel.Events.PrimaryPageChanged, listener, this);
414
423
 
@@ -524,7 +533,7 @@ export class AiConversation {
524
533
  if (this.#origin) {
525
534
  return {origin: this.#origin};
526
535
  }
527
- this.#origin = getPrimaryPageOrigin();
536
+ this.#origin = getPrimaryPageOrigin(this.#targetManager);
528
537
 
529
538
  return {origin: this.#origin};
530
539
  };
@@ -538,8 +547,10 @@ function isAiAssistanceContextSelectionAgentEnabled(): boolean {
538
547
  return Boolean(Root.Runtime.hostConfig.devToolsAiAssistanceContextSelectionAgent?.enabled);
539
548
  }
540
549
 
541
- function getPrimaryPageOrigin(): Platform.DevToolsPath.UrlString|undefined {
542
- const target = SDK.TargetManager.TargetManager.instance().primaryPageTarget();
550
+ function getPrimaryPageOrigin(
551
+ targetManager: SDK.TargetManager.TargetManager,
552
+ ): Platform.DevToolsPath.UrlString|undefined {
553
+ const target = targetManager.primaryPageTarget();
543
554
  const inspectedURL = target?.inspectedURL();
544
555
  return inspectedURL ? new Common.ParsedURL.ParsedURL(inspectedURL).securityOrigin() : undefined;
545
556
  }
@@ -4,6 +4,7 @@
4
4
  // found in the LICENSE file.
5
5
 
6
6
  import * as Common from '../../core/common/common.js';
7
+ import * as Root from '../../core/root/root.js';
7
8
 
8
9
  import {ResponseType, type SerializedResponseData} from './agents/AiAgent.js';
9
10
 
@@ -33,8 +34,6 @@ export interface SerializedImage {
33
34
  data: string;
34
35
  }
35
36
 
36
- let instance: AiHistoryStorage|null = null;
37
-
38
37
  const DEFAULT_MAX_STORAGE_SIZE = 50 * 1024 * 1024;
39
38
  export const MAX_RECENT_PROMPTS_COUNT = 20;
40
39
  export const MAX_CONVERSATIONS_COUNT = 50;
@@ -55,14 +54,17 @@ export class AiHistoryStorage extends Common.ObjectWrapper.ObjectWrapper<EventTy
55
54
  #mutex = new Common.Mutex.Mutex();
56
55
  #maxStorageSize: number;
57
56
 
58
- constructor(maxStorageSize = DEFAULT_MAX_STORAGE_SIZE) {
57
+ constructor(
58
+ settings: Common.Settings.Settings = Common.Settings.Settings.instance(),
59
+ maxStorageSize = DEFAULT_MAX_STORAGE_SIZE,
60
+ ) {
59
61
  super();
60
- this.#historySetting = Common.Settings.Settings.instance().createSetting('ai-assistance-history-entries', []);
61
- this.#imageHistorySettings = Common.Settings.Settings.instance().createSetting(
62
+ this.#historySetting = settings.createSetting('ai-assistance-history-entries', []);
63
+ this.#imageHistorySettings = settings.createSetting(
62
64
  'ai-assistance-history-images',
63
65
  [],
64
66
  );
65
- this.#recentPromptsSetting = Common.Settings.Settings.instance().createSetting('ai-assistance-recent-prompts', []);
67
+ this.#recentPromptsSetting = settings.createSetting('ai-assistance-recent-prompts', []);
66
68
  this.#maxStorageSize = maxStorageSize;
67
69
  }
68
70
 
@@ -225,12 +227,21 @@ export class AiHistoryStorage extends Common.ObjectWrapper.ObjectWrapper<EventTy
225
227
  opts: {
226
228
  forceNew: boolean,
227
229
  maxStorageSize?: number,
230
+ settings?: Common.Settings.Settings,
228
231
  } = {forceNew: false, maxStorageSize: DEFAULT_MAX_STORAGE_SIZE},
229
232
  ): AiHistoryStorage {
230
- const {forceNew, maxStorageSize} = opts;
231
- if (!instance || forceNew) {
232
- instance = new AiHistoryStorage(maxStorageSize);
233
+ const {forceNew, maxStorageSize, settings} = opts;
234
+ if (!Root.DevToolsContext.globalInstance().has(AiHistoryStorage) || forceNew) {
235
+ Root.DevToolsContext.globalInstance().set(AiHistoryStorage,
236
+ new AiHistoryStorage(
237
+ settings ?? Common.Settings.Settings.instance(),
238
+ maxStorageSize,
239
+ ));
233
240
  }
234
- return instance;
241
+ return Root.DevToolsContext.globalInstance().get(AiHistoryStorage);
242
+ }
243
+
244
+ static removeInstance(): void {
245
+ Root.DevToolsContext.globalInstance().delete(AiHistoryStorage);
235
246
  }
236
247
  }
@@ -36,8 +36,8 @@ export class ChangeManager {
36
36
  readonly #stylesheetChanges = new Map<Protocol.DOM.StyleSheetId, Change[]>();
37
37
  readonly #backupStylesheetChanges = new Map<Protocol.DOM.StyleSheetId, Change[]>();
38
38
 
39
- constructor() {
40
- SDK.TargetManager.TargetManager.instance().addModelListener(
39
+ constructor(targetManager: SDK.TargetManager.TargetManager = SDK.TargetManager.TargetManager.instance()) {
40
+ targetManager.addModelListener(
41
41
  SDK.ResourceTreeModel.ResourceTreeModel,
42
42
  SDK.ResourceTreeModel.Events.PrimaryPageChanged,
43
43
  this.clear,
@@ -237,7 +237,11 @@ export class ExtensionScope {
237
237
  return node.localName() || node.nodeName().toLowerCase();
238
238
  }
239
239
 
240
- static getSourceLocation(styleRule: SDK.CSSRule.CSSStyleRule): string|undefined {
240
+ static getSourceLocation(
241
+ styleRule: SDK.CSSRule.CSSStyleRule,
242
+ cssWorkspaceBinding: Bindings.CSSWorkspaceBinding.CSSWorkspaceBinding =
243
+ Bindings.CSSWorkspaceBinding.CSSWorkspaceBinding.instance(),
244
+ ): string|undefined {
241
245
  const styleSheetHeader = styleRule.header;
242
246
  if (!styleSheetHeader) {
243
247
  return;
@@ -250,7 +254,7 @@ export class ExtensionScope {
250
254
  const lineNumber = styleSheetHeader.lineNumberInSource(range.startLine);
251
255
  const columnNumber = styleSheetHeader.columnNumberInSource(range.startLine, range.startColumn);
252
256
  const location = new SDK.CSSModel.CSSLocation(styleSheetHeader, lineNumber, columnNumber);
253
- const uiLocation = Bindings.CSSWorkspaceBinding.CSSWorkspaceBinding.instance().rawLocationToUILocation(location);
257
+ const uiLocation = cssWorkspaceBinding.rawLocationToUILocation(location);
254
258
  return uiLocation?.linkText(/* skipTrim= */ true, /* showColumnNumber= */ true);
255
259
  }
256
260
 
@@ -97,7 +97,7 @@ export class AccessibilityAgent extends AiAgent<LHModel.ReporterTypes.ReportJSON
97
97
  constructor(opts: ExecuteJsAgentOptions) {
98
98
  super(opts);
99
99
  this.#lighthouseRecording = opts.lighthouseRecording;
100
- this.#changes = opts.changeManager || new ChangeManager();
100
+ this.#changes = opts.changeManager || new ChangeManager(opts.targetManager);
101
101
  this.#execJs = opts.execJs ?? executeJsCode;
102
102
  this.#createExtensionScope = opts.createExtensionScope ?? ((changes: ChangeManager) => {
103
103
  return new ExtensionScope(changes, this.sessionId, this.#getDocumentBodyNode());
@@ -6,7 +6,7 @@ import * as Host from '../../../core/host/host.js';
6
6
  import type {UrlString} from '../../../core/platform/DevToolsPath.js';
7
7
  import type * as Platform from '../../../core/platform/platform.js';
8
8
  import * as Root from '../../../core/root/root.js';
9
- import type * as SDK from '../../../core/sdk/sdk.js';
9
+ import * as SDK from '../../../core/sdk/sdk.js';
10
10
  import type * as Protocol from '../../../generated/protocol.js';
11
11
  import type * as LHModel from '../../lighthouse/lighthouse.js';
12
12
  import type * as TextUtils from '../../text_utils/text_utils.js';
@@ -166,6 +166,7 @@ export interface AgentOptions {
166
166
  history?: Host.AidaClient.Content[];
167
167
  allowedOrigin?: () => AllowedOriginResult;
168
168
  lighthouseRecording?: (overrides?: LHModel.RunTypes.RunOverrides) => Promise<LHModel.ReporterTypes.ReportJSON|null>;
169
+ targetManager?: SDK.TargetManager.TargetManager;
169
170
  }
170
171
 
171
172
  export interface ParsedAnswer {
@@ -485,6 +486,7 @@ export abstract class AiAgent<T> {
485
486
  readonly confirmSideEffect: typeof Promise.withResolvers;
486
487
  readonly #functionDeclarations = new Map<string, FunctionDeclaration<Record<string, unknown>, unknown>>();
487
488
  readonly #allowedOrigin?: () => AllowedOriginResult;
489
+ readonly #targetManager: SDK.TargetManager.TargetManager;
488
490
 
489
491
  /**
490
492
  * Used in the debug mode and evals.
@@ -518,6 +520,7 @@ export abstract class AiAgent<T> {
518
520
  this.confirmSideEffect = opts.confirmSideEffectForTest ?? (() => Promise.withResolvers());
519
521
  this.#history = opts.history ?? [];
520
522
  this.#allowedOrigin = opts.allowedOrigin;
523
+ this.#targetManager = opts.targetManager ?? SDK.TargetManager.TargetManager.instance();
521
524
  }
522
525
 
523
526
  async enhanceQuery(query: string, selected: ConversationContext<T>|null,
@@ -534,6 +537,10 @@ export abstract class AiAgent<T> {
534
537
  return [...this.#history];
535
538
  }
536
539
 
540
+ get targetManager(): SDK.TargetManager.TargetManager {
541
+ return this.#targetManager;
542
+ }
543
+
537
544
  /**
538
545
  * Add a fact which will be sent for any subsequent requests.
539
546
  * Returns the new list of all facts.
@@ -133,7 +133,7 @@ export class StylingAgent extends AiAgent<SDK.DOMModel.DOMNode> {
133
133
  constructor(opts: ExecuteJsAgentOptions) {
134
134
  super(opts);
135
135
 
136
- this.#changes = opts.changeManager || new ChangeManager();
136
+ this.#changes = opts.changeManager || new ChangeManager(opts.targetManager);
137
137
  this.#execJs = opts.execJs ?? executeJsCode;
138
138
  this.#createExtensionScope = opts.createExtensionScope ?? ((changes: ChangeManager) => {
139
139
  return new ExtensionScope(changes, this.sessionId, this.context?.getItem() ?? null);