chrome-devtools-frontend 1.0.1597624 → 1.0.1599001

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 (140) hide show
  1. package/.agents/README.md +13 -0
  2. package/{agents/prompts/creating-a-model.md → .agents/skills/creating-a-model/SKILL.md} +7 -1
  3. package/{agents/prompts/devtools-imports.md → .agents/skills/devtools-imports/SKILL.md} +10 -5
  4. package/{agents/prompts/merging-devtools-module.md → .agents/skills/merging-devtools-module/SKILL.md} +5 -0
  5. package/{agents/prompts/ui-widgets.md → .agents/skills/ui-widgets/SKILL.md} +5 -0
  6. package/{agents/prompts/verification.md → .agents/skills/verification/SKILL.md} +5 -0
  7. package/docs/ui_engineering.md +6 -6
  8. package/front_end/core/host/AidaClient.ts +2 -0
  9. package/front_end/core/host/GcaTypes.ts +518 -0
  10. package/front_end/core/host/UserMetrics.ts +0 -1
  11. package/front_end/core/host/host.ts +2 -0
  12. package/front_end/core/root/ExperimentNames.ts +0 -1
  13. package/front_end/entrypoints/main/MainImpl.ts +0 -2
  14. package/front_end/generated/InspectorBackendCommands.ts +1 -1
  15. package/front_end/generated/protocol.ts +2 -1
  16. package/front_end/models/ai_assistance/AiConversation.ts +28 -15
  17. package/front_end/models/ai_assistance/AiHistoryStorage.snapshot.txt +1 -1
  18. package/front_end/models/ai_assistance/AiHistoryStorage.ts +1 -0
  19. package/front_end/models/ai_assistance/ConversationHandler.ts +8 -2
  20. package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +3 -18
  21. package/front_end/models/ai_assistance/agents/AiAgent.ts +39 -5
  22. package/front_end/models/ai_assistance/agents/BreakpointDebuggerAgent.ts +0 -1
  23. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +1 -0
  24. package/front_end/models/ai_assistance/agents/ConversationSummaryAgent.ts +108 -0
  25. package/front_end/models/ai_assistance/agents/FileAgent.ts +0 -15
  26. package/front_end/models/ai_assistance/agents/NetworkAgent.ts +0 -5
  27. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +76 -13
  28. package/front_end/models/ai_assistance/agents/PerformanceAnnotationsAgent.ts +0 -10
  29. package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +0 -6
  30. package/front_end/models/ai_assistance/agents/StylingAgent.ts +0 -5
  31. package/front_end/models/ai_assistance/ai_assistance.ts +2 -0
  32. package/front_end/models/emulation/DeviceModeModel.ts +5 -1
  33. package/front_end/models/emulation/EmulatedDevices.ts +3 -2
  34. package/front_end/models/issues_manager/SharedDictionaryIssue.ts +15 -5
  35. package/front_end/models/issues_manager/descriptions/sharedDictionaryUseErrorNoCorpCrossOriginNoCorsRequest.md +3 -0
  36. package/front_end/models/issues_manager/descriptions/sharedDictionaryWriteErrorNoCorpCossOriginNoCorsRequest.md +3 -0
  37. package/front_end/models/javascript_metadata/NativeFunctions.js +8 -0
  38. package/front_end/models/lighthouse/RunTypes.ts +41 -0
  39. package/front_end/models/lighthouse/lighthouse.ts +2 -0
  40. package/front_end/models/trace/ModelImpl.ts +4 -0
  41. package/front_end/models/trace/helpers/SamplesIntegrator.ts +1 -8
  42. package/front_end/models/trace/types/Configuration.ts +0 -5
  43. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +90 -14
  44. package/front_end/panels/ai_assistance/PatchWidget.ts +1 -1
  45. package/front_end/panels/ai_assistance/components/ChatInput.ts +2 -0
  46. package/front_end/panels/ai_assistance/components/ChatMessage.ts +153 -42
  47. package/front_end/panels/ai_assistance/components/ChatView.ts +1 -1
  48. package/front_end/panels/ai_assistance/components/chatMessage.css +61 -0
  49. package/front_end/panels/application/AppManifestView.ts +2 -2
  50. package/front_end/panels/application/CookieItemsView.ts +9 -15
  51. package/front_end/panels/application/DeviceBoundSessionsView.ts +3 -5
  52. package/front_end/panels/application/FrameDetailsView.ts +2 -2
  53. package/front_end/panels/application/ReportingApiView.ts +2 -2
  54. package/front_end/panels/application/preloading/PreloadingView.ts +20 -7
  55. package/front_end/panels/application/preloading/components/PreloadingDetailsReportView.ts +6 -3
  56. package/front_end/panels/application/preloading/components/PreloadingString.ts +15 -2
  57. package/front_end/panels/application/preloading/helper/PreloadingForward.ts +31 -2
  58. package/front_end/panels/changes/ChangesView.ts +7 -11
  59. package/front_end/panels/coverage/CoverageView.ts +4 -4
  60. package/front_end/panels/css_overview/CSSOverviewCompletedView.ts +3 -3
  61. package/front_end/panels/elements/ElementsTreeOutline.ts +34 -8
  62. package/front_end/panels/elements/StylePropertiesSection.ts +129 -1
  63. package/front_end/panels/elements/StylePropertyHighlighter.ts +3 -0
  64. package/front_end/panels/elements/stylesSidebarPane.css +34 -0
  65. package/front_end/panels/issues/AffectedSelectivePermissionsInterventionView.ts +3 -5
  66. package/front_end/panels/layer_viewer/LayerDetailsView.ts +2 -1
  67. package/front_end/panels/lighthouse/LighthouseController.ts +148 -162
  68. package/front_end/panels/lighthouse/LighthousePanel.ts +2 -7
  69. package/front_end/panels/lighthouse/LighthouseStartView.ts +7 -6
  70. package/front_end/panels/lighthouse/LighthouseStatusView.ts +3 -3
  71. package/front_end/panels/linear_memory_inspector/components/LinearMemoryInspector.ts +7 -3
  72. package/front_end/panels/network/RequestConditionsDrawer.ts +4 -4
  73. package/front_end/panels/network/RequestCookiesView.ts +2 -2
  74. package/front_end/panels/network/RequestHeadersView.ts +4 -4
  75. package/front_end/panels/network/RequestResponseView.ts +2 -2
  76. package/front_end/panels/performance_monitor/PerformanceMonitor.ts +2 -2
  77. package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +3 -3
  78. package/front_end/panels/recorder/components/StepView.ts +2 -1
  79. package/front_end/panels/search/SearchView.ts +2 -2
  80. package/front_end/panels/sensors/SensorsView.ts +32 -22
  81. package/front_end/panels/settings/emulation/DevicesSettingsTab.ts +18 -4
  82. package/front_end/panels/timeline/StatusDialog.ts +159 -83
  83. package/front_end/panels/timeline/TimelineController.ts +0 -4
  84. package/front_end/panels/timeline/TimelineDetailsView.ts +8 -6
  85. package/front_end/panels/timeline/TimelinePanel.ts +29 -2
  86. package/front_end/panels/timeline/components/LiveMetricsView.ts +2 -2
  87. package/front_end/panels/timeline/components/Sidebar.ts +1 -1
  88. package/front_end/panels/timeline/components/SidebarInsightsTab.ts +1 -1
  89. package/front_end/panels/timeline/components/SidebarSingleInsightSet.ts +62 -34
  90. package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +53 -28
  91. package/front_end/panels/timeline/components/insights/CharacterSet.ts +2 -6
  92. package/front_end/panels/timeline/components/insights/EventRef.ts +2 -2
  93. package/front_end/panels/timeline/components/insights/baseInsightComponent.css +7 -0
  94. package/front_end/panels/timeline/components/insights/insights.ts +0 -2
  95. package/front_end/panels/timeline/timeline-meta.ts +11 -0
  96. package/front_end/panels/webauthn/WebauthnPane.ts +2 -2
  97. package/front_end/third_party/chromium/README.chromium +1 -1
  98. package/front_end/third_party/puppeteer/README.chromium +2 -2
  99. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Realm.js +1 -1
  100. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Realm.js.map +1 -1
  101. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/util.d.ts +4 -0
  102. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/util.d.ts.map +1 -1
  103. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/util.js +13 -0
  104. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/util.js.map +1 -1
  105. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
  106. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +3 -3
  107. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +3 -3
  108. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js.map +1 -1
  109. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
  110. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
  111. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
  112. package/front_end/third_party/puppeteer/package/lib/cjs/third_party/mitt/mitt.js +2 -2
  113. package/front_end/third_party/puppeteer/package/lib/cjs/third_party/parsel-js/parsel-js.js +1 -1
  114. package/front_end/third_party/puppeteer/package/lib/cjs/third_party/rxjs/rxjs.js +446 -446
  115. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +166 -167
  116. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Realm.js +2 -2
  117. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Realm.js.map +1 -1
  118. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/util.d.ts +4 -0
  119. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/util.d.ts.map +1 -1
  120. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/util.js +12 -0
  121. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/util.js.map +1 -1
  122. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +3 -3
  123. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +3 -3
  124. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js.map +1 -1
  125. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
  126. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
  127. package/front_end/third_party/puppeteer/package/lib/esm/third_party/mitt/mitt.js +1 -1
  128. package/front_end/third_party/puppeteer/package/lib/esm/third_party/parsel-js/parsel-js.js +1 -1
  129. package/front_end/third_party/puppeteer/package/lib/esm/third_party/rxjs/rxjs.js +97 -97
  130. package/front_end/third_party/puppeteer/package/package.json +1 -1
  131. package/front_end/third_party/puppeteer/package/src/bidi/Realm.ts +2 -2
  132. package/front_end/third_party/puppeteer/package/src/bidi/util.ts +17 -0
  133. package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
  134. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  135. package/front_end/ui/legacy/Widget.ts +47 -9
  136. package/front_end/ui/visual_logging/KnownContextValues.ts +1 -1
  137. package/package.json +1 -1
  138. package/agents/prompts/README.md +0 -18
  139. package/front_end/models/issues_manager/descriptions/sharedDictionaryUseErrorCrossOriginNoCorsRequest.md +0 -1
  140. package/front_end/panels/timeline/components/insights/InsightRenderer.ts +0 -93
@@ -8,9 +8,12 @@ import * as i18n from '../../../core/i18n/i18n.js';
8
8
  import * as Platform from '../../../core/platform/platform.js';
9
9
  import * as Root from '../../../core/root/root.js';
10
10
  import * as SDK from '../../../core/sdk/sdk.js';
11
+ import type * as Protocol from '../../../generated/protocol.js';
11
12
  import * as Tracing from '../../../services/tracing/tracing.js';
12
13
  import * as Annotations from '../../annotations/annotations.js';
14
+ import * as Logs from '../../logs/logs.js';
13
15
  import * as SourceMapScopes from '../../source_map_scopes/source_map_scopes.js';
16
+ import * as TextUtils from '../../text_utils/text_utils.js';
14
17
  import * as Trace from '../../trace/trace.js';
15
18
  import {
16
19
  PerformanceInsightFormatter,
@@ -34,10 +37,6 @@ import {
34
37
  } from './AiAgent.js';
35
38
 
36
39
  const UIStringsNotTranslated = {
37
- /**
38
- *@description Shown when the agent is investigating a trace
39
- */
40
- analyzingTrace: 'Analyzing trace',
41
40
  /**
42
41
  * @description Shown when the agent is investigating network activity
43
42
  */
@@ -317,7 +316,6 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
317
316
  #formatter: PerformanceTraceFormatter|null = null;
318
317
  #lastEventForEnhancedQuery: Trace.Types.Events.Event|undefined;
319
318
  #lastInsightForEnhancedQuery: Trace.Insights.Types.InsightModel|undefined;
320
- #hasShownAnalyzeTraceContext = false;
321
319
 
322
320
  /**
323
321
  * Cache of all function calls made by the agent. This allows us to include (as a
@@ -378,10 +376,6 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
378
376
  return;
379
377
  }
380
378
 
381
- if (this.#hasShownAnalyzeTraceContext) {
382
- return;
383
- }
384
-
385
379
  const widgets: AiWidget[] = [];
386
380
  const primaryInsightSet = context.getItem().primaryInsightSet;
387
381
  if (primaryInsightSet) {
@@ -396,7 +390,6 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
396
390
 
397
391
  yield {
398
392
  type: ResponseType.CONTEXT,
399
- title: lockedString(UIStringsNotTranslated.analyzingTrace),
400
393
  details: [
401
394
  {
402
395
  title: 'Trace',
@@ -405,8 +398,6 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
405
398
  ],
406
399
  widgets,
407
400
  };
408
-
409
- this.#hasShownAnalyzeTraceContext = true;
410
401
  }
411
402
 
412
403
  #callTreeContextSet = new WeakSet();
@@ -700,6 +691,7 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
700
691
  #declareFunctions(context: PerformanceTraceContext): void {
701
692
  const focus = context.getItem();
702
693
  const {parsedTrace} = focus;
694
+ const processedNodeIds = new Set<Protocol.DOM.BackendNodeId>();
703
695
 
704
696
  this.declareFunction<{insightSetId: string, insightName: string}, {details: string}>('getInsightDetails', {
705
697
  description:
@@ -749,9 +741,60 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
749
741
 
750
742
  const details = new PerformanceInsightFormatter(focus, insight).formatInsight();
751
743
 
744
+ const widgets: AiWidget[] = [];
745
+ if (Trace.Insights.Models.LCPDiscovery.isLCPDiscoveryInsight(insight) ||
746
+ Trace.Insights.Models.LCPBreakdown.isLCPBreakdownInsight(insight)) {
747
+ const lcpMetric = Trace.Insights.Common.getLCP(insightSet);
748
+ const lcpEvent = lcpMetric?.event;
749
+ if (lcpEvent && Trace.Types.Events.isAnyLargestContentfulPaintCandidate(lcpEvent)) {
750
+ const nodeId = lcpEvent.args.data?.nodeId;
751
+ // We want to show only one DOM tree widget per walkthrough per node.
752
+ // We do want to show the widget for the same node again, if it's within a new walkthrough.
753
+ if (nodeId && !processedNodeIds.has(nodeId)) {
754
+ const target = SDK.TargetManager.TargetManager.instance().primaryPageTarget();
755
+ const domModel = target?.model(SDK.DOMModel.DOMModel);
756
+ if (domModel) {
757
+ const nodeMap = await domModel.pushNodesByBackendIdsToFrontend(new Set([nodeId]));
758
+ const node = nodeMap?.get(nodeId);
759
+ if (node) {
760
+ const snapshot = await node.takeSnapshot();
761
+ let networkRequest;
762
+ const lcpSyntheticRequest = insight.lcpRequest;
763
+ if (lcpSyntheticRequest) {
764
+ networkRequest = {
765
+ url: lcpSyntheticRequest.args.data.url,
766
+ size: lcpSyntheticRequest.args.data.decodedBodyLength ??
767
+ lcpSyntheticRequest.args.data.encodedDataLength ?? 0,
768
+ resourceType: lcpSyntheticRequest.args.data.resourceType,
769
+ mimeType: lcpSyntheticRequest.args.data.mimeType ?? '',
770
+ imageUrl: await this.#getNetworkRequestImageData(lcpSyntheticRequest),
771
+ };
772
+ }
773
+ widgets.push({
774
+ name: 'DOM_TREE',
775
+ data: {
776
+ root: snapshot,
777
+ networkRequest,
778
+ },
779
+ });
780
+ processedNodeIds.add(nodeId);
781
+ }
782
+ }
783
+ }
784
+ }
785
+ if (params.insightName === 'LCPBreakdown') {
786
+ widgets.push({
787
+ name: 'LCP_BREAKDOWN',
788
+ data: {
789
+ lcpData: insight as Trace.Insights.Models.LCPBreakdown.LCPBreakdownInsightModel,
790
+ },
791
+ });
792
+ }
793
+ }
794
+
752
795
  const key = `getInsightDetails('${params.insightSetId}', '${params.insightName}')`;
753
796
  this.#cacheFunctionResult(focus, key, details);
754
- return {result: {details}};
797
+ return {result: {details}, widgets};
755
798
  },
756
799
  });
757
800
 
@@ -1229,4 +1272,24 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
1229
1272
  Annotations.AnnotationRepository.instance().addNetworkRequestAnnotation(annotationMessage, requestId);
1230
1273
  return {result: {success: true}};
1231
1274
  }
1275
+
1276
+ async #getNetworkRequestImageData(lcpRequest: Trace.Types.Events.SyntheticNetworkRequest): Promise<string|undefined> {
1277
+ const target = SDK.TargetManager.TargetManager.instance().primaryPageTarget();
1278
+ const networkManager = target?.model(SDK.NetworkManager.NetworkManager);
1279
+ if (!target || !networkManager) {
1280
+ return undefined;
1281
+ }
1282
+
1283
+ const networkLog = Logs.NetworkLog.NetworkLog.instance();
1284
+ const requestId = lcpRequest.args.data.requestId;
1285
+ const sdkRequest = networkLog.requestByManagerAndId(networkManager, requestId);
1286
+
1287
+ if (sdkRequest?.contentType().isImage()) {
1288
+ const contentData = await sdkRequest.requestContentData();
1289
+ if (!TextUtils.ContentData.ContentData.isError(contentData)) {
1290
+ return contentData.asDataUrl() ?? undefined;
1291
+ }
1292
+ }
1293
+ return undefined;
1294
+ }
1232
1295
  }
@@ -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 i18n from '../../../core/i18n/i18n.js';
7
6
  import * as Root from '../../../core/root/root.js';
8
7
  import type {AICallTree} from '../performance/AICallTree.js';
9
8
  import type {AgentFocus} from '../performance/AIContext.js';
@@ -11,14 +10,6 @@ import type {AgentFocus} from '../performance/AIContext.js';
11
10
  import {AiAgent, type ContextResponse, type ConversationContext, type RequestOptions, ResponseType} from './AiAgent.js';
12
11
  import {PerformanceTraceContext} from './PerformanceAgent.js';
13
12
 
14
- const UIStringsNotTranslated = {
15
- analyzingCallTree: 'Analyzing call tree',
16
- /**
17
- * @description Shown when the agent is investigating network activity
18
- */
19
- } as const;
20
- const lockedString = i18n.i18n.lockedString;
21
-
22
13
  /**
23
14
  * Preamble clocks in at ~970 tokens.
24
15
  * The prose is around 4.5 chars per token.
@@ -124,7 +115,6 @@ export class PerformanceAnnotationsAgent extends AiAgent<AgentFocus> {
124
115
 
125
116
  yield {
126
117
  type: ResponseType.CONTEXT,
127
- title: lockedString(UIStringsNotTranslated.analyzingCallTree),
128
118
  details: [
129
119
  {
130
120
  title: 'Selected call tree',
@@ -216,7 +216,6 @@ Content:
216
216
  [
217
217
  {
218
218
  "type": "context",
219
- "title": "Analyzing the prompt",
220
219
  "details": [
221
220
  {
222
221
  "title": "Data used",
@@ -296,7 +295,6 @@ Content:
296
295
  [
297
296
  {
298
297
  "type": "context",
299
- "title": "Analyzing the prompt",
300
298
  "details": [
301
299
  {
302
300
  "title": "Data used",
@@ -321,7 +319,6 @@ Content:
321
319
  [
322
320
  {
323
321
  "type": "context",
324
- "title": "Analyzing the prompt",
325
322
  "details": [
326
323
  {
327
324
  "title": "Data used",
@@ -349,7 +346,6 @@ Content:
349
346
  [
350
347
  {
351
348
  "type": "context",
352
- "title": "Analyzing the prompt",
353
349
  "details": [
354
350
  {
355
351
  "title": "Data used",
@@ -374,7 +370,6 @@ Content:
374
370
  [
375
371
  {
376
372
  "type": "context",
377
- "title": "Analyzing the prompt",
378
373
  "details": [
379
374
  {
380
375
  "title": "Data used",
@@ -397,7 +392,6 @@ Content:
397
392
  [
398
393
  {
399
394
  "type": "context",
400
- "title": "Analyzing the prompt",
401
395
  "details": [
402
396
  {
403
397
  "title": "Data used",
@@ -37,10 +37,6 @@ import {
37
37
  * Strings that don't need to be translated at this time.
38
38
  */
39
39
  const UIStringsNotTranslate = {
40
- /**
41
- * @description Title for context details for Freestyler.
42
- */
43
- analyzingThePrompt: 'Analyzing the prompt',
44
40
  /**
45
41
  * @description Heading text for context details of Freestyler agent.
46
42
  */
@@ -1045,7 +1041,6 @@ const data = {
1045
1041
  }
1046
1042
  yield {
1047
1043
  type: ResponseType.CONTEXT,
1048
- title: lockedString(UIStringsNotTranslate.analyzingThePrompt),
1049
1044
  details: [{
1050
1045
  title: lockedString(UIStringsNotTranslate.dataUsed),
1051
1046
  text: await StylingAgent.describeElement(selectedElement.getItem()),
@@ -7,6 +7,7 @@ import * as AccessibilityAgent from './agents/AccessibilityAgent.js';
7
7
  import * as AiAgent from './agents/AiAgent.js';
8
8
  import * as BreakpointDebuggerAgent from './agents/BreakpointDebuggerAgent.js';
9
9
  import * as ContextSelectionAgent from './agents/ContextSelectionAgent.js';
10
+ import * as ConversationSummaryAgent from './agents/ConversationSummaryAgent.js';
10
11
  import * as FileAgent from './agents/FileAgent.js';
11
12
  import * as NetworkAgent from './agents/NetworkAgent.js';
12
13
  import * as PatchAgent from './agents/PatchAgent.js';
@@ -47,6 +48,7 @@ export {
47
48
  ChangeManager,
48
49
  ContextSelectionAgent,
49
50
  ConversationHandler,
51
+ ConversationSummaryAgent,
50
52
  Debug,
51
53
  EvaluateAction,
52
54
  ExtensionScope,
@@ -680,7 +680,11 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
680
680
  }
681
681
 
682
682
  private applyUserAgent(userAgent: string, userAgentMetadata: Protocol.Emulation.UserAgentMetadata|null): void {
683
- SDK.NetworkManager.MultitargetNetworkManager.instance().setUserAgentOverride(userAgent, userAgentMetadata);
683
+ // When the user agent string is empty (e.g. custom desktop device without
684
+ // a UA override), metadata must also be cleared. The backend rejects
685
+ // setUserAgentOverride calls that provide metadata without a UA string.
686
+ SDK.NetworkManager.MultitargetNetworkManager.instance().setUserAgentOverride(
687
+ userAgent, userAgent ? userAgentMetadata : null);
684
688
  }
685
689
 
686
690
  private applyDeviceMetrics(
@@ -201,7 +201,8 @@ export class EmulatedDevice {
201
201
  const rawUserAgent = (parseValue(json, 'user-agent', 'string') as string);
202
202
  result.userAgent = SDK.NetworkManager.MultitargetNetworkManager.patchUserAgentWithChromeVersion(rawUserAgent);
203
203
 
204
- result.userAgentMetadata = parseValue(json, 'user-agent-metadata', 'object', null);
204
+ const userAgentMetadata = parseValue(json, 'user-agent-metadata', 'object', null);
205
+ result.userAgentMetadata = result.userAgent ? userAgentMetadata : null;
205
206
 
206
207
  const capabilities = parseValue(json, 'capabilities', 'object', []);
207
208
  if (!Array.isArray(capabilities)) {
@@ -366,7 +367,7 @@ export class EmulatedDevice {
366
367
  json['foldable-screen'] = this.isFoldableScreen;
367
368
  json['show'] = this.#show;
368
369
 
369
- if (this.userAgentMetadata) {
370
+ if (this.userAgent && this.userAgentMetadata) {
370
371
  json['user-agent-metadata'] = this.userAgentMetadata;
371
372
  }
372
373
 
@@ -23,7 +23,7 @@ const str_ = i18n.i18n.registerUIStrings('models/issues_manager/SharedDictionary
23
23
  const i18nLazyString = i18n.i18n.getLazilyComputedLocalizedString.bind(undefined, str_);
24
24
 
25
25
  export const enum IssueCode {
26
- USE_ERROR_CROSS_ORIGIN_NO_CORS_REQUEST = 'SharedDictionaryIssue::UseErrorCrossOriginNoCorsRequest',
26
+ USE_ERROR_NO_CORP_CROSS_ORIGIN_NO_CORS_REQUEST = 'SharedDictionaryIssue::UseErrorNoCorpCrossOriginNoCorsRequest',
27
27
  USE_ERROR_DICTIONARY_LOAD_FAILURE = 'SharedDictionaryIssue::UseErrorDictionaryLoadFailure',
28
28
  USE_ERROR_MATCHING_DICTIONARY_NOT_USED = 'SharedDictionaryIssue::UseErrorMatchingDictionaryNotUsed',
29
29
  USE_ERROR_UNEXPECTED_CONTENT_DICTIONARY_HEADER = 'SharedDictionaryIssue::UseErrorUnexpectedContentDictionaryHeader',
@@ -36,6 +36,7 @@ export const enum IssueCode {
36
36
  WRITE_ERROR_INVALID_STRUCTURED_HEADER = 'SharedDictionaryIssue::WriteErrorInvalidStructuredHeader',
37
37
  WRITE_ERROR_INVALID_TTL_FIELD = 'SharedDictionaryIssue::WriteErrorInvalidTTLField',
38
38
  WRITE_ERROR_NAVIGATION_REQUEST = 'SharedDictionaryIssue::WriteErrorNavigationRequest',
39
+ WRITE_ERROR_NO_CORP_COSS_ORIGIN_NO_CORS_REQUEST = 'SharedDictionaryIssue::WriteErrorNoCorpCossOriginNoCorsRequest',
39
40
  WRITE_ERROR_NO_MATCH_FIELD = 'SharedDictionaryIssue::WriteErrorNoMatchField',
40
41
  WRITE_ERROR_NON_INTEGER_TTL_FIELD = 'SharedDictionaryIssue::WriteErrorNonIntegerTTLField',
41
42
  WRITE_ERROR_NON_LIST_MATCH_DEST_FIELD = 'SharedDictionaryIssue::WriteErrorNonListMatchDestField',
@@ -53,8 +54,8 @@ export const enum IssueCode {
53
54
 
54
55
  function getIssueCode(details: Protocol.Audits.SharedDictionaryIssueDetails): IssueCode {
55
56
  switch (details.sharedDictionaryError) {
56
- case Protocol.Audits.SharedDictionaryError.UseErrorCrossOriginNoCorsRequest:
57
- return IssueCode.USE_ERROR_CROSS_ORIGIN_NO_CORS_REQUEST;
57
+ case Protocol.Audits.SharedDictionaryError.UseErrorNoCorpCrossOriginNoCorsRequest:
58
+ return IssueCode.USE_ERROR_NO_CORP_CROSS_ORIGIN_NO_CORS_REQUEST;
58
59
  case Protocol.Audits.SharedDictionaryError.UseErrorDictionaryLoadFailure:
59
60
  return IssueCode.USE_ERROR_DICTIONARY_LOAD_FAILURE;
60
61
  case Protocol.Audits.SharedDictionaryError.UseErrorMatchingDictionaryNotUsed:
@@ -79,6 +80,8 @@ function getIssueCode(details: Protocol.Audits.SharedDictionaryIssueDetails): Is
79
80
  return IssueCode.WRITE_ERROR_INVALID_TTL_FIELD;
80
81
  case Protocol.Audits.SharedDictionaryError.WriteErrorNavigationRequest:
81
82
  return IssueCode.WRITE_ERROR_NAVIGATION_REQUEST;
83
+ case Protocol.Audits.SharedDictionaryError.WriteErrorNoCorpCossOriginNoCorsRequest:
84
+ return IssueCode.WRITE_ERROR_NO_CORP_COSS_ORIGIN_NO_CORS_REQUEST;
82
85
  case Protocol.Audits.SharedDictionaryError.WriteErrorNoMatchField:
83
86
  return IssueCode.WRITE_ERROR_NO_MATCH_FIELD;
84
87
  case Protocol.Audits.SharedDictionaryError.WriteErrorNonIntegerTTLField:
@@ -168,9 +171,9 @@ const specLinks = [{
168
171
  const issueDescriptions = new Map<Protocol.Audits.SharedDictionaryError, LazyMarkdownIssueDescription>([
169
172
 
170
173
  [
171
- Protocol.Audits.SharedDictionaryError.UseErrorCrossOriginNoCorsRequest,
174
+ Protocol.Audits.SharedDictionaryError.UseErrorNoCorpCrossOriginNoCorsRequest,
172
175
  {
173
- file: 'sharedDictionaryUseErrorCrossOriginNoCorsRequest.md',
176
+ file: 'sharedDictionaryUseErrorNoCorpCrossOriginNoCorsRequest.md',
174
177
  links: specLinks,
175
178
  },
176
179
  ],
@@ -258,6 +261,13 @@ const issueDescriptions = new Map<Protocol.Audits.SharedDictionaryError, LazyMar
258
261
  links: specLinks,
259
262
  },
260
263
  ],
264
+ [
265
+ Protocol.Audits.SharedDictionaryError.WriteErrorNoCorpCossOriginNoCorsRequest,
266
+ {
267
+ file: 'sharedDictionaryWriteErrorNoCorpCossOriginNoCorsRequest.md',
268
+ links: specLinks,
269
+ },
270
+ ],
261
271
  [
262
272
  Protocol.Audits.SharedDictionaryError.WriteErrorNoMatchField,
263
273
  {
@@ -0,0 +1,3 @@
1
+ # Dictionary compression cannot be used for cross-origin no-cors requests without a Cross-Origin-Resource-Policy response header
2
+
3
+ To use dictionary compression for a cross-origin no-cors request, the response must have a `Cross-Origin-Resource-Policy: cross-origin` header. Without it, the response can not be decoded and will fail.
@@ -0,0 +1,3 @@
1
+ # A cross-origin no-cors response cannot be stored as a shared dictionary for future requests without a Cross-Origin-Resource-Policy response header
2
+
3
+ To store a response from a cross-origin no-cors request as a shared dictionary for future requests, the response must have a `Cross-Origin-Resource-Policy: cross-origin` header. Without it, the response will not be stored as a dictionary.
@@ -8785,6 +8785,14 @@ export const NativeFunctions = [
8785
8785
  name: "SpeechSynthesisUtterance",
8786
8786
  signatures: [["?text"]]
8787
8787
  },
8788
+ {
8789
+ name: "addWords",
8790
+ signatures: [["words"]]
8791
+ },
8792
+ {
8793
+ name: "removeWords",
8794
+ signatures: [["words"]]
8795
+ },
8788
8796
  {
8789
8797
  name: "requestStorageAccessFor",
8790
8798
  signatures: [["requestedOrigin"]]
@@ -0,0 +1,41 @@
1
+ // Copyright 2026 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+ import type * as Common from '../../core/common/common.js';
5
+ import type * as Host from '../../core/host/host.js';
6
+ import type * as Platform from '../../core/platform/platform.js';
7
+
8
+ export type CategoryId = 'performance'|'accessibility'|'best-practices'|'seo';
9
+
10
+ export interface Preset {
11
+ setting: Common.Settings.Setting<boolean>;
12
+ configID: CategoryId;
13
+ title: () => Common.UIString.LocalizedString;
14
+ description: () => Common.UIString.LocalizedString;
15
+ supportedModes: string[];
16
+ userMetric: Host.UserMetrics.LighthouseCategoryUsed;
17
+ }
18
+ export interface RuntimeSetting {
19
+ setting: Common.Settings.Setting<string|boolean>;
20
+ description: () => Common.UIString.LocalizedString;
21
+ setFlags: (flags: Flags, value: string|boolean) => void;
22
+ options?: Array<{
23
+ label: () => Common.UIString.LocalizedString,
24
+ value: string,
25
+ tooltip?: () => Common.UIString.LocalizedString,
26
+ }>;
27
+ title?: () => Common.UIString.LocalizedString;
28
+ learnMore?: Platform.DevToolsPath.UrlString;
29
+ }
30
+
31
+ export interface Flags {
32
+ additionalTraceCategories?: string;
33
+ disableStorageReset?: boolean;
34
+ throttlingMethod?: string;
35
+ formFactor?: string|boolean;
36
+ mode?: string|boolean;
37
+ }
38
+
39
+ export interface RunOverrides {
40
+ categoryIds: CategoryId[];
41
+ }
@@ -3,7 +3,9 @@
3
3
  // found in the LICENSE file.
4
4
 
5
5
  import * as ReporterTypes from './LighthouseReporterTypes.js';
6
+ import * as RunTypes from './RunTypes.js';
6
7
 
7
8
  export {
8
9
  ReporterTypes,
10
+ RunTypes,
9
11
  };
@@ -173,6 +173,10 @@ export class Model extends EventTarget {
173
173
  this.#recordingsAvailable.splice(recordingIndex, 1);
174
174
  }
175
175
 
176
+ indexForTrace(trace: ParsedTrace): number {
177
+ return this.#traces.indexOf(trace);
178
+ }
179
+
176
180
  getRecordingsAvailable(): string[] {
177
181
  return this.#recordingsAvailable;
178
182
  }
@@ -477,20 +477,13 @@ export class SamplesIntegrator {
477
477
  if (showAllEvents) {
478
478
  return;
479
479
  }
480
- let previousNativeFrameName: string|null = null;
481
480
  let j = 0;
482
481
  for (let i = 0; i < stack.length; ++i) {
483
482
  const frame = stack[i].callFrame;
484
483
  const nativeRuntimeFrame = SamplesIntegrator.isNativeRuntimeFrame(frame);
485
- if (nativeRuntimeFrame &&
486
- !SamplesIntegrator.showNativeName(frame.functionName, engineConfig.includeRuntimeCallStats)) {
484
+ if (nativeRuntimeFrame) {
487
485
  continue;
488
486
  }
489
- const nativeFrameName = nativeRuntimeFrame ? SamplesIntegrator.nativeGroup(frame.functionName) : null;
490
- if (previousNativeFrameName && previousNativeFrameName === nativeFrameName) {
491
- continue;
492
- }
493
- previousNativeFrameName = nativeFrameName;
494
487
  stack[j++] = stack[i];
495
488
  }
496
489
  stack.length = j;
@@ -11,10 +11,6 @@ import type * as File from './File.js';
11
11
  import type {Milli} from './Timing.js';
12
12
 
13
13
  export interface Configuration {
14
- /**
15
- * Include V8 RCS functions in the JS stacks
16
- */
17
- includeRuntimeCallStats: boolean;
18
14
  /**
19
15
  * Show all events: disable the default filtering which hides and excludes some events.
20
16
  */
@@ -49,7 +45,6 @@ export interface Configuration {
49
45
  }
50
46
 
51
47
  export const defaults = (): Configuration => ({
52
- includeRuntimeCallStats: false,
53
48
  showAllEvents: false,
54
49
  debugMode: false,
55
50
  maxInvalidationEventsPerEvent: 20,