chrome-devtools-frontend 1.0.1636056 → 1.0.1638082

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 (85) hide show
  1. package/front_end/core/common/Color.ts +0 -4
  2. package/front_end/core/root/Runtime.ts +2 -2
  3. package/front_end/core/sdk/SourceMap.ts +8 -3
  4. package/front_end/generated/ARIAProperties.js +17 -0
  5. package/front_end/generated/InspectorBackendCommands.ts +7 -5
  6. package/front_end/generated/SupportedCSSProperties.js +1 -0
  7. package/front_end/generated/protocol.ts +40 -2
  8. package/front_end/models/ai_assistance/AiConversation.ts +0 -8
  9. package/front_end/models/ai_assistance/AiHistoryStorage.ts +0 -1
  10. package/front_end/models/ai_assistance/AiUtils.ts +9 -0
  11. package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +10 -3
  12. package/front_end/models/ai_assistance/agents/AiAgent.ts +24 -7
  13. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +6 -0
  14. package/front_end/models/ai_assistance/agents/GreenDevAgent.ts +0 -2
  15. package/front_end/models/ai_assistance/agents/NetworkAgent.snapshot.txt +19 -0
  16. package/front_end/models/ai_assistance/agents/NetworkAgent.ts +6 -0
  17. package/front_end/models/ai_assistance/ai_assistance.ts +0 -2
  18. package/front_end/models/bindings/CompilerScriptMapping.ts +12 -4
  19. package/front_end/models/breakpoints/BreakpointManager.ts +54 -2
  20. package/front_end/models/greendev/Prototypes.ts +0 -7
  21. package/front_end/models/issues_manager/EmailVerificationRequestIssue.ts +293 -0
  22. package/front_end/models/issues_manager/IssuesManager.ts +5 -0
  23. package/front_end/models/issues_manager/descriptions/emailVerificationRequestDnsFetchFailed.md +1 -0
  24. package/front_end/models/issues_manager/descriptions/emailVerificationRequestDnsInvalidRecord.md +1 -0
  25. package/front_end/models/issues_manager/descriptions/emailVerificationRequestInvalidEmail.md +1 -0
  26. package/front_end/models/issues_manager/descriptions/emailVerificationRequestKeyBindingSigningFailed.md +1 -0
  27. package/front_end/models/issues_manager/descriptions/emailVerificationRequestRpOriginIsOpaque.md +1 -0
  28. package/front_end/models/issues_manager/descriptions/emailVerificationRequestTokenHttpNotFound.md +1 -0
  29. package/front_end/models/issues_manager/descriptions/emailVerificationRequestTokenInvalidContentType.md +1 -0
  30. package/front_end/models/issues_manager/descriptions/emailVerificationRequestTokenInvalidResponse.md +1 -0
  31. package/front_end/models/issues_manager/descriptions/emailVerificationRequestTokenInvalidSdJwt.md +1 -0
  32. package/front_end/models/issues_manager/descriptions/emailVerificationRequestTokenMalformedSdJwt.md +1 -0
  33. package/front_end/models/issues_manager/descriptions/emailVerificationRequestTokenNoResponse.md +1 -0
  34. package/front_end/models/issues_manager/descriptions/emailVerificationRequestUserLoggedOut.md +1 -0
  35. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownAccountsEndpointCrossOrigin.md +1 -0
  36. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownHttpNotFound.md +1 -0
  37. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownInvalidContentType.md +1 -0
  38. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownInvalidResponse.md +1 -0
  39. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownIssuanceEndpointCrossOrigin.md +1 -0
  40. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownListEmpty.md +1 -0
  41. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownMissingAccountsEndpoint.md +1 -0
  42. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownMissingIssuanceEndpoint.md +1 -0
  43. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownNoResponse.md +1 -0
  44. package/front_end/models/issues_manager/descriptions/emailVerificationRequestWellKnownUnsupportedSigningAlgorithm.md +1 -0
  45. package/front_end/models/issues_manager/issues_manager.ts +2 -0
  46. package/front_end/models/javascript_metadata/NativeFunctions.js +1739 -1734
  47. package/front_end/models/stack_trace/DetailedErrorStackParser.ts +9 -1
  48. package/front_end/models/trace/lantern/core/NetworkAnalyzer.ts +21 -25
  49. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +11 -75
  50. package/front_end/panels/ai_assistance/components/AccessibilityAgentMarkdownRenderer.ts +10 -3
  51. package/front_end/panels/ai_assistance/components/ChatMessage.ts +36 -2
  52. package/front_end/panels/application/preloading/components/UsedPreloadingView.ts +4 -4
  53. package/front_end/panels/console/ConsoleViewMessage.ts +0 -90
  54. package/front_end/panels/elements/StylePropertiesSection.ts +6 -2
  55. package/front_end/panels/elements/StylesSidebarPane.ts +9 -0
  56. package/front_end/panels/elements/elements-meta.ts +14 -0
  57. package/front_end/panels/network/RequestHeadersView.ts +55 -19
  58. package/front_end/panels/recorder/components/ReplaySection.ts +28 -16
  59. package/front_end/panels/recorder/converters/LighthouseConverter.snapshot.txt +47 -0
  60. package/front_end/panels/recorder/converters/PuppeteerConverter.snapshot.txt +49 -0
  61. package/front_end/panels/recorder/converters/PuppeteerReplayConverter.snapshot.txt +33 -0
  62. package/front_end/panels/settings/SettingsScreen.ts +1 -2
  63. package/front_end/panels/sources/BreakpointsView.ts +23 -42
  64. package/front_end/panels/sources/DebuggerPlugin.ts +12 -5
  65. package/front_end/third_party/chromium/README.chromium +1 -1
  66. package/front_end/third_party/lighthouse/lighthouse-dt-bundle.js +2 -2
  67. package/front_end/third_party/puppeteer-replay/README.chromium +2 -2
  68. package/front_end/third_party/puppeteer-replay/package/lib/cli.js +84 -80
  69. package/front_end/third_party/puppeteer-replay/package/lib/cli.js.map +1 -1
  70. package/front_end/third_party/puppeteer-replay/package/lib/extension-test.js +79 -83
  71. package/front_end/third_party/puppeteer-replay/package/lib/extension-test.js.map +1 -1
  72. package/front_end/third_party/puppeteer-replay/package/lib/main.d.ts +43 -171
  73. package/front_end/third_party/puppeteer-replay/package/lib/main.js +51 -206
  74. package/front_end/third_party/puppeteer-replay/package/lib/main.js.map +1 -1
  75. package/front_end/third_party/puppeteer-replay/package/package.json +37 -67
  76. package/front_end/ui/visual_logging/KnownContextValues.ts +2 -0
  77. package/mcp/mcp.ts +1 -6
  78. package/package.json +8 -8
  79. package/front_end/models/ai_assistance/agents/BreakpointDebuggerAgent.ts +0 -1015
  80. package/front_end/models/ai_assistance/agents/BreakpointDebuggerAgentOverlay.ts +0 -87
  81. package/front_end/third_party/puppeteer-replay/package/lib/cjs/main.cjs +0 -2099
  82. package/front_end/third_party/puppeteer-replay/package/lib/cjs/main.cjs.map +0 -1
  83. package/front_end/third_party/puppeteer-replay/package/lib/cjs/main.d.cts +0 -686
  84. package/front_end/third_party/puppeteer-replay/package/lib/cjs/main.d.ts +0 -35
  85. package/mcp/HostBindings.ts +0 -319
@@ -180,7 +180,7 @@ export function parseMessage(stack: string): string {
180
180
  */
181
181
  export function augmentRawFramesWithScriptIds(
182
182
  rawFrames: RawFrame[], protocolStackTrace: Protocol.Runtime.StackTrace): void {
183
- for (const rawFrame of rawFrames) {
183
+ function augmentFrame(rawFrame: RawFrame): void {
184
184
  const isWasm = rawFrame.parsedFrameInfo?.isWasm;
185
185
  const protocolFrame = protocolStackTrace.callFrames.find(frame => {
186
186
  if (isWasm) {
@@ -196,5 +196,13 @@ export function augmentRawFramesWithScriptIds(
196
196
  // @ts-expect-error scriptId is a readonly property.
197
197
  rawFrame.scriptId = protocolFrame.scriptId;
198
198
  }
199
+
200
+ if (rawFrame.parsedFrameInfo?.evalOrigin) {
201
+ augmentFrame(rawFrame.parsedFrameInfo.evalOrigin);
202
+ }
203
+ }
204
+
205
+ for (const rawFrame of rawFrames) {
206
+ augmentFrame(rawFrame);
199
207
  }
200
208
  }
@@ -4,8 +4,6 @@
4
4
 
5
5
  import type * as Lantern from '../types/types.js';
6
6
 
7
- import {LanternError} from './LanternError.js';
8
-
9
7
  class UrlUtils {
10
8
  /**
11
9
  * There is fancy URL rewriting logic for the chrome://settings page that we need to work around.
@@ -100,6 +98,12 @@ class NetworkAnalyzer {
100
98
  const grouped = new Map();
101
99
  records.forEach(item => {
102
100
  const key = item.parsedURL.securityOrigin;
101
+
102
+ // We never care about requests for extensions.
103
+ if (key.startsWith('chrome-extension:')) {
104
+ return;
105
+ }
106
+
103
107
  const group = grouped.get(key) || [];
104
108
  group.push(item);
105
109
  grouped.set(key, group);
@@ -458,30 +462,25 @@ class NetworkAnalyzer {
458
462
  }
459
463
  }
460
464
 
461
- if (!estimatesByOrigin.size) {
462
- throw new LanternError('No timing information available');
463
- }
464
465
  return NetworkAnalyzer.summarize(estimatesByOrigin);
465
466
  }
466
467
 
468
+ static estimateMinimumRTTByOrigin(records: Lantern.NetworkRequest[], options?: RTTEstimateOptions):
469
+ Map<string, number> {
470
+ const rttByOrigin = new Map<string, number>();
471
+ for (const [origin, summary] of NetworkAnalyzer.estimateRTTByOrigin(records, options).entries()) {
472
+ rttByOrigin.set(origin, summary.min);
473
+ }
474
+ return rttByOrigin;
475
+ }
476
+
467
477
  /**
468
- * Estimates the server response time of each origin. RTT times can be passed in or will be
469
- * estimated automatically if not provided.
478
+ * Estimates the server response time of each origin. RTT times must be passed in.
470
479
  */
471
- static estimateServerResponseTimeByOrigin(records: Lantern.NetworkRequest[], options?: RTTEstimateOptions&{
472
- rttByOrigin?: Map<string, number>,
480
+ static estimateServerResponseTimeByOrigin(records: Lantern.NetworkRequest[], options: {
481
+ rttByOrigin: Map<string, number>,
473
482
  }): Map<string, Summary> {
474
- let rttByOrigin = options?.rttByOrigin;
475
- if (!rttByOrigin) {
476
- rttByOrigin = new Map();
477
-
478
- const rttSummaryByOrigin = NetworkAnalyzer.estimateRTTByOrigin(records, options);
479
- for (const [origin, summary] of rttSummaryByOrigin.entries()) {
480
- rttByOrigin.set(origin, summary.min);
481
- }
482
- }
483
-
484
- const estimatesByOrigin = NetworkAnalyzer.estimateResponseTimeByOrigin(records, rttByOrigin);
483
+ const estimatesByOrigin = NetworkAnalyzer.estimateResponseTimeByOrigin(records, options.rttByOrigin);
485
484
  return NetworkAnalyzer.summarize(estimatesByOrigin);
486
485
  }
487
486
 
@@ -546,14 +545,11 @@ class NetworkAnalyzer {
546
545
  static computeRTTAndServerResponseTime(records: Lantern.NetworkRequest[]):
547
546
  {rtt: number, additionalRttByOrigin: Map<string, number>, serverResponseTimeByOrigin: Map<string, number>} {
548
547
  // First pass compute the estimated observed RTT to each origin's servers.
549
- const rttByOrigin = new Map<string, number>();
550
- for (const [origin, summary] of NetworkAnalyzer.estimateRTTByOrigin(records).entries()) {
551
- rttByOrigin.set(origin, summary.min);
552
- }
548
+ const rttByOrigin = NetworkAnalyzer.estimateMinimumRTTByOrigin(records);
553
549
 
554
550
  // We'll use the minimum RTT as the assumed connection latency since we care about how much addt'l
555
551
  // latency each origin introduces as Lantern will be simulating with its own connection latency.
556
- const minimumRtt = Math.min(...Array.from(rttByOrigin.values()));
552
+ const minimumRtt = rttByOrigin.size ? Math.min(...Array.from(rttByOrigin.values())) : 0;
557
553
  // We'll use the observed RTT information to help estimate the server response time
558
554
  const responseTimeSummaries = NetworkAnalyzer.estimateServerResponseTimeByOrigin(records, {
559
555
  rttByOrigin,
@@ -332,13 +332,6 @@ async function getEmptyStateSuggestions(conversation?: AiAssistanceModel.AiConve
332
332
  {title: 'What performance issues exist with my page?', jslogContext: 'performance-default'},
333
333
  ];
334
334
  }
335
- case AiAssistanceModel.AiHistoryStorage.ConversationType.BREAKPOINT: {
336
- return [
337
- {title: 'Why did the code pause here?'},
338
- {title: 'What function does this breakpoint belong to?'},
339
- {title: 'Why is this error thrown?'},
340
- ];
341
- }
342
335
 
343
336
  case AiAssistanceModel.AiHistoryStorage.ConversationType.NONE: {
344
337
  return [
@@ -383,9 +376,8 @@ function getMarkdownRenderer(conversation?: AiAssistanceModel.AiConversation.AiC
383
376
  return new StylingAgentMarkdownRenderer(mainFrameId);
384
377
  } else if (conversation?.type === AiAssistanceModel.AiHistoryStorage.ConversationType.ACCESSIBILITY) {
385
378
  const domModel = SDK.TargetManager.TargetManager.instance().primaryPageTarget()?.model(SDK.DOMModel.DOMModel);
386
- const resourceTreeModel = domModel?.target().model(SDK.ResourceTreeModel.ResourceTreeModel);
387
- const mainFrameId = resourceTreeModel?.mainFrame?.id;
388
- return new AccessibilityAgentMarkdownRenderer(mainFrameId);
379
+ const mainDocumentURL = domModel?.existingDocument()?.documentURL;
380
+ return new AccessibilityAgentMarkdownRenderer(mainDocumentURL);
389
381
  }
390
382
 
391
383
  return new MarkdownRendererWithCodeBlock();
@@ -526,8 +518,7 @@ function defaultView(input: ViewInput, output: PanelViewOutput, target: HTMLElem
526
518
  }
527
519
  }
528
520
 
529
- if (Root.Runtime.hostConfig.devToolsAiAssistanceV2?.enabled ||
530
- Greendev.Prototypes.instance().isEnabled('breakpointDebuggerAgent')) {
521
+ if (Root.Runtime.hostConfig.devToolsAiAssistanceV2?.enabled) {
531
522
 
532
523
  const shouldShowWalkthrough = input.state === ViewState.CHAT_VIEW && input.props.walkthrough.isExpanded;
533
524
  /**
@@ -590,14 +581,6 @@ function createFileContext(file: Workspace.UISourceCode.UISourceCode|null): AiAs
590
581
  return new AiAssistanceModel.FileAgent.FileContext(file);
591
582
  }
592
583
 
593
- function createBreakpointContext(uiLocation: Workspace.UISourceCode.UILocation|null):
594
- AiAssistanceModel.BreakpointDebuggerAgent.BreakpointContext|null {
595
- if (!uiLocation) {
596
- return null;
597
- }
598
- return new AiAssistanceModel.BreakpointDebuggerAgent.BreakpointContext(uiLocation);
599
- }
600
-
601
584
  function createAccessibilityContext(report: LighthousePanel.LighthousePanel.ActiveLighthouseReport|null):
602
585
  AiAssistanceModel.AccessibilityAgent.AccessibilityContext|null {
603
586
  if (!report) {
@@ -684,7 +667,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
684
667
  #selectedElement: AiAssistanceModel.StylingAgent.NodeContext|null = null;
685
668
  #selectedPerformanceTrace: AiAssistanceModel.PerformanceAgent.PerformanceTraceContext|null = null;
686
669
  #selectedRequest: AiAssistanceModel.NetworkAgent.RequestContext|null = null;
687
- #selectedBreakpoint: AiAssistanceModel.BreakpointDebuggerAgent.BreakpointContext|null = null;
670
+
688
671
  #selectedAccessibility: AiAssistanceModel.AccessibilityAgent.AccessibilityContext|null = null;
689
672
  #selectedStorage: AiAssistanceModel.StorageAgent.StorageContext|null = null;
690
673
 
@@ -1017,10 +1000,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1017
1000
  targetConversationType = AiAssistanceModel.AiHistoryStorage.ConversationType.STYLING;
1018
1001
  } else if (isNetworkPanelVisible && hostConfig.devToolsAiAssistanceNetworkAgent?.enabled) {
1019
1002
  targetConversationType = AiAssistanceModel.AiHistoryStorage.ConversationType.NETWORK;
1020
- } else if (
1021
- isSourcesPanelVisible &&
1022
- this.#conversation?.type === AiAssistanceModel.AiHistoryStorage.ConversationType.BREAKPOINT) {
1023
- targetConversationType = AiAssistanceModel.AiHistoryStorage.ConversationType.BREAKPOINT;
1003
+
1024
1004
  } else if (isSourcesPanelVisible && hostConfig.devToolsAiAssistanceFileAgent?.enabled) {
1025
1005
  targetConversationType = AiAssistanceModel.AiHistoryStorage.ConversationType.FILE;
1026
1006
  } else if (isPerformancePanelVisible && hostConfig.devToolsAiAssistancePerformanceAgent?.enabled) {
@@ -1127,30 +1107,6 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1127
1107
  this.requestUpdate();
1128
1108
  }
1129
1109
 
1130
- async handleBreakpointConversation(uiLocation: Workspace.UISourceCode.UILocation, errorMsg?: string): Promise<void> {
1131
- const context = new AiAssistanceModel.BreakpointDebuggerAgent.BreakpointContext(uiLocation);
1132
- this.#selectedBreakpoint = context;
1133
- const conversation = new AiAssistanceModel.AiConversation.AiConversation({
1134
- type: AiAssistanceModel.AiHistoryStorage.ConversationType.BREAKPOINT,
1135
- data: [],
1136
- isReadOnly: false,
1137
- aidaClient: this.#aidaClient,
1138
- changeManager: this.#changeManager,
1139
- isExternal: false,
1140
- performanceRecordAndReload: this.#handlePerformanceRecordAndReload.bind(this),
1141
- onInspectElement: this.#handleInspectElement.bind(this),
1142
- networkTimeCalculator: NetworkPanel.NetworkPanel.NetworkPanel.instance().networkLogView.timeCalculator(),
1143
- lighthouseRecording: this.#handleLighthouseRun.bind(this),
1144
- });
1145
- this.#updateConversationState(conversation);
1146
- this.#conversation?.setContext(context);
1147
- this.requestUpdate();
1148
- await UI.ViewManager.ViewManager.instance().showView(AiAssistancePanel.panelName);
1149
- const prompt = errorMsg ? `debug the error "${errorMsg}" using breakpoint debugging agent` :
1150
- 'debug the error using breakpoint debugging agent';
1151
- await this.#startConversation(prompt);
1152
- }
1153
-
1154
1110
  override wasShown(): void {
1155
1111
  super.wasShown();
1156
1112
  this.#viewOutput.chatView?.restoreScrollPosition();
@@ -1163,8 +1119,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1163
1119
  this.#selectedPerformanceTrace =
1164
1120
  createPerformanceTraceContext(UI.Context.Context.instance().flavor(AiAssistanceModel.AIContext.AgentFocus));
1165
1121
  this.#selectedFile = createFileContext(UI.Context.Context.instance().flavor(Workspace.UISourceCode.UISourceCode));
1166
- this.#selectedBreakpoint =
1167
- createBreakpointContext(UI.Context.Context.instance().flavor(Workspace.UISourceCode.UILocation));
1122
+
1168
1123
  this.#selectedAccessibility = createAccessibilityContext(
1169
1124
  UI.Context.Context.instance().flavor(LighthousePanel.LighthousePanel.ActiveLighthouseReport));
1170
1125
  this.#selectedStorage =
@@ -1186,8 +1141,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1186
1141
 
1187
1142
  UI.Context.Context.instance().addFlavorChangeListener(
1188
1143
  Workspace.UISourceCode.UISourceCode, this.#handleUISourceCodeFlavorChange);
1189
- UI.Context.Context.instance().addFlavorChangeListener(
1190
- Workspace.UISourceCode.UILocation, this.#handleBreakpointFlavorChange);
1144
+
1191
1145
  UI.Context.Context.instance().addFlavorChangeListener(
1192
1146
  LighthousePanel.LighthousePanel.ActiveLighthouseReport, this.#handleLighthouseReportFlavorChange);
1193
1147
 
@@ -1328,17 +1282,6 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1328
1282
  this.#updateConversationState(this.#conversation);
1329
1283
  };
1330
1284
 
1331
- #handleBreakpointFlavorChange =
1332
- (ev: Common.EventTarget.EventTargetEvent<Workspace.UISourceCode.UILocation>): void => {
1333
- const newBreakpoint = ev.data;
1334
-
1335
- if (!newBreakpoint || this.#selectedBreakpoint?.getItem() === newBreakpoint) {
1336
- return;
1337
- }
1338
- this.#selectedBreakpoint = new AiAssistanceModel.BreakpointDebuggerAgent.BreakpointContext(newBreakpoint);
1339
- this.#updateConversationState(this.#conversation);
1340
- };
1341
-
1342
1285
  #handleLighthouseReportFlavorChange =
1343
1286
  (ev: Common.EventTarget.EventTargetEvent<LighthousePanel.LighthousePanel.ActiveLighthouseReport>): void => {
1344
1287
  const newReport = ev.data;
@@ -1447,8 +1390,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1447
1390
 
1448
1391
  return lockedString(UIStringsNotTranslate.inputPlaceholderForPerformanceWithNoRecording);
1449
1392
  }
1450
- case AiAssistanceModel.AiHistoryStorage.ConversationType.BREAKPOINT:
1451
- return lockedString(UIStringsNotTranslate.inputPlaceholderForNoContext);
1393
+
1452
1394
  case AiAssistanceModel.AiHistoryStorage.ConversationType.ACCESSIBILITY:
1453
1395
  return this.#conversation.selectedContext ?
1454
1396
  lockedString(UIStringsNotTranslate.inputPlaceholderForAccessibility) :
@@ -1510,8 +1452,6 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1510
1452
  }
1511
1453
  return lockedString(UIStringsNotTranslate.inputDisclaimerForAccessibilityEnterpriseNoLogging);
1512
1454
 
1513
- case AiAssistanceModel.AiHistoryStorage.ConversationType.BREAKPOINT:
1514
-
1515
1455
  case AiAssistanceModel.AiHistoryStorage.ConversationType.STORAGE:
1516
1456
  case AiAssistanceModel.AiHistoryStorage.ConversationType.NONE:
1517
1457
  if (loggingEnabled) {
@@ -1763,8 +1703,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1763
1703
  return this.#selectedRequest;
1764
1704
  case AiAssistanceModel.AiHistoryStorage.ConversationType.PERFORMANCE:
1765
1705
  return this.#selectedPerformanceTrace;
1766
- case AiAssistanceModel.AiHistoryStorage.ConversationType.BREAKPOINT:
1767
- return this.#selectedBreakpoint;
1706
+
1768
1707
  case AiAssistanceModel.AiHistoryStorage.ConversationType.ACCESSIBILITY:
1769
1708
  return this.#selectedAccessibility;
1770
1709
  case AiAssistanceModel.AiHistoryStorage.ConversationType.STORAGE:
@@ -1786,8 +1725,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1786
1725
  this.#selectedRequest = data;
1787
1726
  } else if (data instanceof AiAssistanceModel.PerformanceAgent.PerformanceTraceContext) {
1788
1727
  this.#selectedPerformanceTrace = data;
1789
- } else if (data instanceof AiAssistanceModel.BreakpointDebuggerAgent.BreakpointContext) {
1790
- this.#selectedBreakpoint = data;
1728
+
1791
1729
  } else if (data instanceof AiAssistanceModel.AccessibilityAgent.AccessibilityContext) {
1792
1730
  this.#selectedAccessibility = data;
1793
1731
  } else if (data instanceof AiAssistanceModel.StorageAgent.StorageContext) {
@@ -1946,9 +1884,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1946
1884
  // This ensures that when a user asks a new question, the sidebar updates
1947
1885
  // immediately to show the "loading" state of the new walkthrough.
1948
1886
  const isSidebarWalkthroughOpen = this.#walkthrough.isExpanded && !this.#walkthrough.isInlined;
1949
- if (isSidebarWalkthroughOpen ||
1950
- (Greendev.Prototypes.instance().isEnabled('breakpointDebuggerAgent') &&
1951
- this.#conversation?.type === AiAssistanceModel.AiHistoryStorage.ConversationType.BREAKPOINT)) {
1887
+ if (isSidebarWalkthroughOpen) {
1952
1888
  this.#openWalkthrough(systemMessage);
1953
1889
  }
1954
1890
  break;
@@ -2,8 +2,10 @@
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
4
 
5
+ import type * as Platform from '../../../core/platform/platform.js';
5
6
  import * as SDK from '../../../core/sdk/sdk.js';
6
7
  import type * as Protocol from '../../../generated/protocol.js';
8
+ import * as AiAssistanceModel from '../../../models/ai_assistance/ai_assistance.js';
7
9
  import type * as Marked from '../../../third_party/marked/marked.js';
8
10
  import * as Lit from '../../../ui/lit/lit.js';
9
11
  import * as PanelsCommon from '../../common/common.js';
@@ -27,11 +29,16 @@ type ParsedLink = {
27
29
 
28
30
  export class AccessibilityAgentMarkdownRenderer extends MarkdownRendererWithCodeBlock {
29
31
  constructor(
30
- private mainFrameId = '',
32
+ private mainDocumentURL: Platform.DevToolsPath.UrlString = '' as Platform.DevToolsPath.UrlString,
31
33
  ) {
32
34
  super();
33
35
  }
34
36
 
37
+ #isSameOrigin(node: SDK.DOMModel.DOMNode): boolean {
38
+ const nodeDocumentURL = node.ownerDocument?.documentURL ?? '' as Platform.DevToolsPath.UrlString;
39
+ return AiAssistanceModel.AiUtils.isSameOrigin(this.mainDocumentURL, nodeDocumentURL);
40
+ }
41
+
35
42
  override templateForToken(token: Marked.Marked.MarkedToken): Lit.LitTemplate|null {
36
43
  if (token.type === 'link' && token.href.startsWith('#')) {
37
44
  const parsed = this.#parseLink(token.href);
@@ -98,7 +105,7 @@ export class AccessibilityAgentMarkdownRenderer extends MarkdownRendererWithCode
98
105
  return;
99
106
  }
100
107
 
101
- if (node.frameId() !== this.mainFrameId) {
108
+ if (!this.#isSameOrigin(node)) {
102
109
  return;
103
110
  }
104
111
 
@@ -123,7 +130,7 @@ export class AccessibilityAgentMarkdownRenderer extends MarkdownRendererWithCode
123
130
  if (!node) {
124
131
  return;
125
132
  }
126
- if (node.frameId() !== this.mainFrameId) {
133
+ if (!this.#isSameOrigin(node)) {
127
134
  return;
128
135
  }
129
136
  const linkedNode = PanelsCommon.DOMLinkifier.Linkifier.instance().linkify(node, {textContent: label});
@@ -14,8 +14,9 @@ import * as SDK from '../../../core/sdk/sdk.js';
14
14
  import type * as Protocol from '../../../generated/protocol.js';
15
15
  import type {
16
16
  AiWidget, BottomUpTreeAiWidget, ComputedStyleAiWidget, CoreVitalsAiWidget, DomTreeAiWidget, LighthouseReportAiWidget,
17
- PerfInsightAiWidget, PerformanceTraceAiWidget, SourceFileAiWidget, StylePropertiesAiWidget,
18
- TimelineEventSummaryAiWidget, TimelineRangeSummaryAiWidget} from '../../../models/ai_assistance/agents/AiAgent.js';
17
+ NetworkRequestGeneralHeadersAiWidget, PerfInsightAiWidget, PerformanceTraceAiWidget, SourceFileAiWidget,
18
+ StylePropertiesAiWidget, TimelineEventSummaryAiWidget,
19
+ TimelineRangeSummaryAiWidget} from '../../../models/ai_assistance/agents/AiAgent.js';
19
20
  import * as AiAssistanceModel from '../../../models/ai_assistance/ai_assistance.js';
20
21
  import * as ComputedStyle from '../../../models/computed_style/computed_style.js';
21
22
  import * as Trace from '../../../models/trace/trace.js';
@@ -32,6 +33,8 @@ import * as Lit from '../../../ui/lit/lit.js';
32
33
  import * as VisualLogging from '../../../ui/visual_logging/visual_logging.js';
33
34
  import * as Elements from '../../elements/elements.js';
34
35
  import * as Lighthouse from '../../lighthouse/lighthouse.js';
36
+ import * as NetworkForward from '../../network/forward/forward.js';
37
+ import * as Network from '../../network/network.js';
35
38
  import * as TimelineComponents from '../../timeline/components/components.js';
36
39
  import type {BaseInsightComponent} from '../../timeline/components/insights/BaseInsightComponent.js';
37
40
  import * as TimelineInsights from '../../timeline/components/insights/insights.js';
@@ -384,6 +387,14 @@ const UIStringsNotTranslate = {
384
387
  * @description Title for the viewport optimization widget.
385
388
  */
386
389
  viewport: 'Viewport optimization',
390
+ /**
391
+ * @description Accessible label for the reveal button in the network request general headers widget.
392
+ */
393
+ revealNetworkRequest: 'Reveal network request',
394
+ /**
395
+ * @description Title for the network request general headers widget.
396
+ */
397
+ networkRequest: 'Network request',
387
398
  /**
388
399
  * @description Accessible label for the reveal button in the modern HTTP usage widget.
389
400
  */
@@ -1464,6 +1475,8 @@ export function getWidgetSignature(widget: AiWidget): string {
1464
1475
  return `${widget.name}:${widget.data.report.fetchTime}`;
1465
1476
  case 'TIMELINE_EVENT_SUMMARY':
1466
1477
  return `${widget.name}:${widget.data.event.ts}:${widget.data.event.name}`;
1478
+ case 'NETWORK_REQUEST_GENERAL_HEADERS':
1479
+ return `${widget.name}:${widget.data.request.requestId()}`;
1467
1480
  default:
1468
1481
  Platform.assertNever(widget, 'Unknown AiWidget name');
1469
1482
  }
@@ -1556,6 +1569,9 @@ async function renderWidgets(
1556
1569
  case 'TIMELINE_EVENT_SUMMARY':
1557
1570
  response = await makeTimelineEventSummaryWidget(widgetData);
1558
1571
  break;
1572
+ case 'NETWORK_REQUEST_GENERAL_HEADERS':
1573
+ response = await makeNetworkRequestGeneralHeadersWidget(widgetData);
1574
+ break;
1559
1575
  default:
1560
1576
  Platform.assertNever(widgetData, 'Unknown AiWidget name');
1561
1577
  }
@@ -2131,3 +2147,21 @@ async function makeTimelineEventSummaryWidget(widgetData: TimelineEventSummaryAi
2131
2147
  jslogContext: 'timeline-event-summary-widget',
2132
2148
  };
2133
2149
  }
2150
+
2151
+ async function makeNetworkRequestGeneralHeadersWidget(widgetData: NetworkRequestGeneralHeadersAiWidget):
2152
+ Promise<WidgetMakerResponse|null> {
2153
+ const renderedWidget = html`<devtools-widget class="network-request-general-headers-widget" ${widget(() => {
2154
+ return Network.RequestHeadersView.RequestHeadersView.createGeneralHeadersView(widgetData.data.request);
2155
+ })}></devtools-widget>`;
2156
+
2157
+ return {
2158
+ renderedWidget,
2159
+ revealable: NetworkForward.UIRequestLocation.UIRequestLocation.tab(
2160
+ widgetData.data.request,
2161
+ NetworkForward.UIRequestLocation.UIRequestTabs.HEADERS_COMPONENT,
2162
+ ),
2163
+ accessibleRevealLabel: lockedString(UIStringsNotTranslate.revealNetworkRequest),
2164
+ title: lockedString(UIStringsNotTranslate.networkRequest),
2165
+ jslogContext: 'network-request-general-headers-widget',
2166
+ };
2167
+ }
@@ -475,14 +475,14 @@ export class UsedPreloadingView extends UI.Widget.VBox {
475
475
  if (prerenderLike?.status === SDK.PreloadingModel.PreloadingStatus.FAILURE &&
476
476
  prefetch?.status === SDK.PreloadingModel.PreloadingStatus.SUCCESS) {
477
477
  kind = UsedKind.DOWNGRADED_PRERENDER_TO_PREFETCH_AND_USED;
478
- } else if (prefetch?.status === SDK.PreloadingModel.PreloadingStatus.SUCCESS) {
479
- kind = UsedKind.PREFETCH_USED;
480
478
  } else if (prerenderLike?.status === SDK.PreloadingModel.PreloadingStatus.SUCCESS) {
481
479
  kind = UsedKind.PRERENDER_USED;
482
- } else if (prefetch?.status === SDK.PreloadingModel.PreloadingStatus.FAILURE) {
483
- kind = UsedKind.PREFETCH_FAILED;
480
+ } else if (prefetch?.status === SDK.PreloadingModel.PreloadingStatus.SUCCESS) {
481
+ kind = UsedKind.PREFETCH_USED;
484
482
  } else if (prerenderLike?.status === SDK.PreloadingModel.PreloadingStatus.FAILURE) {
485
483
  kind = UsedKind.PRERENDER_FAILED;
484
+ } else if (prefetch?.status === SDK.PreloadingModel.PreloadingStatus.FAILURE) {
485
+ kind = UsedKind.PREFETCH_FAILED;
486
486
  } else {
487
487
  kind = UsedKind.NO_PRELOADS;
488
488
  }
@@ -43,8 +43,6 @@ import * as SDK from '../../core/sdk/sdk.js';
43
43
  import * as Protocol from '../../generated/protocol.js';
44
44
  import * as AiAssistanceModel from '../../models/ai_assistance/ai_assistance.js';
45
45
  import * as Bindings from '../../models/bindings/bindings.js';
46
- import * as Breakpoints from '../../models/breakpoints/breakpoints.js';
47
- import * as Greendev from '../../models/greendev/greendev.js';
48
46
  import type * as IssuesManager from '../../models/issues_manager/issues_manager.js';
49
47
  import * as Logs from '../../models/logs/logs.js';
50
48
  import * as StackTrace from '../../models/stack_trace/stack_trace.js';
@@ -63,7 +61,6 @@ import * as Components from '../../ui/legacy/components/utils/utils.js';
63
61
  import * as UI from '../../ui/legacy/legacy.js';
64
62
  import {type LitTemplate, nothing, render} from '../../ui/lit/lit.js';
65
63
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
66
- import * as AiAssistancePanel from '../ai_assistance/ai_assistance.js';
67
64
 
68
65
  import {format, updateStyle} from './ConsoleFormat.js';
69
66
  import {ConsoleInsightTeaser} from './ConsoleInsightTeaser.js';
@@ -1508,11 +1505,6 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
1508
1505
  this.consoleRowWrapper.append(this.#createHoverButton());
1509
1506
  }
1510
1507
 
1511
- const breakpointAgentEnabled = Greendev.Prototypes.instance().isEnabled('breakpointDebuggerAgent');
1512
- if (breakpointAgentEnabled && this.message.level === Protocol.Log.LogEntryLevel.Error) {
1513
- this.consoleRowWrapper.append(this.#createBreakpointButton());
1514
- }
1515
-
1516
1508
  if (this.repeatCountInternal > 1) {
1517
1509
  this.showRepeatCountElement();
1518
1510
  }
@@ -1606,88 +1598,6 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
1606
1598
  return button;
1607
1599
  }
1608
1600
 
1609
- #createBreakpointButton(): HTMLButtonElement {
1610
- const button = document.createElement('button');
1611
-
1612
- const icon = new Icon();
1613
- icon.name = 'bug';
1614
- icon.style.color = 'var(--devtools-icon-color)';
1615
- icon.classList.add('medium');
1616
- button.append(icon);
1617
-
1618
- const label = document.createElement('div');
1619
- label.classList.add('button-label');
1620
- const text = document.createElement('div');
1621
- // We use a data attribute and a CSS pseudo-element for the button label
1622
- // to prevent the text from being picked up by the console's custom
1623
- // copy-to-clipboard traversal, which only collects actual text nodes.
1624
- text.setAttribute('data-text', 'Debug with breakpoint AI');
1625
- label.append(text);
1626
- button.append(label);
1627
- button.classList.add('hover-button');
1628
- // Offset the button to the left of the existing one (24px width + 6px right + gap)
1629
- if (this.shouldShowInsights()) {
1630
- button.style.right = '36px';
1631
- }
1632
- button.ariaLabel = 'Debug with breakpoint AI';
1633
- button.tabIndex = 0;
1634
-
1635
- button.onclick = async (event: Event) => {
1636
- event.stopPropagation();
1637
- const runtimeModel = this.message.runtimeModel();
1638
- if (!runtimeModel) {
1639
- return;
1640
- }
1641
- const debuggerModel = runtimeModel.debuggerModel();
1642
- const debuggerWorkspaceBinding = Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance();
1643
- let uiLocation: Workspace.UISourceCode.UILocation|null = null;
1644
-
1645
- // 1. Try stack trace latest called line
1646
- if (this.message.stackTrace?.callFrames.length) {
1647
- const callFrame = this.message.stackTrace.callFrames[0];
1648
- if (callFrame.scriptId) {
1649
- const script = debuggerModel.scriptForId(callFrame.scriptId);
1650
- if (script) {
1651
- const rawLocation = new SDK.DebuggerModel.Location(
1652
- debuggerModel, callFrame.scriptId, callFrame.lineNumber, callFrame.columnNumber);
1653
- uiLocation = await debuggerWorkspaceBinding.rawLocationToUILocation(rawLocation);
1654
- }
1655
- }
1656
- }
1657
-
1658
- // 2. Try scriptId on message
1659
- if (!uiLocation && this.message.scriptId) {
1660
- const script = debuggerModel.scriptForId(this.message.scriptId);
1661
- if (script) {
1662
- const rawLocation = new SDK.DebuggerModel.Location(
1663
- debuggerModel, this.message.scriptId, this.message.line, this.message.column);
1664
- uiLocation = await debuggerWorkspaceBinding.rawLocationToUILocation(rawLocation);
1665
- }
1666
- }
1667
-
1668
- // 3. Try URL
1669
- if (!uiLocation && this.message.url) {
1670
- const uiSourceCode = Workspace.Workspace.WorkspaceImpl.instance().uiSourceCodeForURL(this.message.url);
1671
- if (uiSourceCode) {
1672
- uiLocation = uiSourceCode.uiLocation(this.message.line, this.message.column);
1673
- }
1674
- }
1675
-
1676
- if (uiLocation) {
1677
- await Common.Revealer.reveal(uiLocation);
1678
- const breakpointManager = Breakpoints.BreakpointManager.BreakpointManager.instance();
1679
- await breakpointManager.setBreakpoint(
1680
- uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber,
1681
- Breakpoints.BreakpointManager.EMPTY_BREAKPOINT_CONDITION, /* enabled */ true,
1682
- /* isLogpoint */ false, Breakpoints.BreakpointManager.BreakpointOrigin.OTHER);
1683
- const aiPanel = await AiAssistancePanel.AiAssistancePanel.instance();
1684
- void aiPanel.handleBreakpointConversation(uiLocation, this.text);
1685
- }
1686
- };
1687
-
1688
- return button;
1689
- }
1690
-
1691
1601
  private shouldRenderAsWarning(): boolean {
1692
1602
  return (this.message.level === Protocol.Log.LogEntryLevel.Verbose ||
1693
1603
  this.message.level === Protocol.Log.LogEntryLevel.Info) &&
@@ -343,7 +343,7 @@ export class StylePropertiesSection {
343
343
  this.#isCollapsed = false;
344
344
  this.markSelectorMatches();
345
345
  this.onpopulate();
346
- this.#updateCollapsedState();
346
+ this.updateCollapsedState();
347
347
  }
348
348
 
349
349
  setComputedStyles(computedStyles: Map<string, string>|null): void {
@@ -1317,6 +1317,10 @@ export class StylePropertiesSection {
1317
1317
  * since the user intentionally toggled them off and they should remain visible.
1318
1318
  */
1319
1319
  #shouldCollapse(): boolean {
1320
+ if (!Common.Settings.Settings.instance().moduleSetting('collapse-non-contributing-css-rules').get()) {
1321
+ return false;
1322
+ }
1323
+
1320
1324
  const style = this.styleInternal;
1321
1325
  const properties = style.leadingProperties();
1322
1326
 
@@ -1343,7 +1347,7 @@ export class StylePropertiesSection {
1343
1347
  return allOverloaded;
1344
1348
  }
1345
1349
 
1346
- #updateCollapsedState(): void {
1350
+ updateCollapsedState(): void {
1347
1351
  const shouldCollapse = this.#shouldCollapse();
1348
1352
  // Mark as collapsible so the toggle icon is always shown for
1349
1353
  // sections that can be collapsed, even after manual expansion.
@@ -236,6 +236,9 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
236
236
  this.setMinimumSize(96, 26);
237
237
  this.registerRequiredCSS(stylesSidebarPaneStyles);
238
238
  Common.Settings.Settings.instance().moduleSetting('text-editor-indent').addChangeListener(this.requestUpdate, this);
239
+ Common.Settings.Settings.instance()
240
+ .moduleSetting('collapse-non-contributing-css-rules')
241
+ .addChangeListener(this.updateCollapsedSectionsSetting, this);
239
242
  this.toolbarPaneElement = this.createStylesSidebarToolbar();
240
243
  this.noMatchesElement = this.contentElement.createChild('div', 'gray-info-message hidden');
241
244
  this.noMatchesElement.textContent = i18nString(UIStrings.noMatchingSelectorOrStyle);
@@ -363,6 +366,12 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
363
366
  this.requestUpdate();
364
367
  }
365
368
 
369
+ private updateCollapsedSectionsSetting(): void {
370
+ for (const section of this.allSections()) {
371
+ section.updateCollapsedState();
372
+ }
373
+ }
374
+
366
375
  private sectionsContainerKeyDown(event: Event): void {
367
376
  const activeElement = UI.DOMUtilities.deepActiveElement(this.sectionsContainer.contentElement.ownerDocument);
368
377
  if (!activeElement) {
@@ -156,6 +156,10 @@ const UIStrings = {
156
156
  * @description Title of a setting under the Elements category.
157
157
  */
158
158
  cssAnimationsOnlyWhenAnimationsTabOpen: 'Show animation styles only when the Animations tab is open',
159
+ /**
160
+ * @description Whether CSS rules that do not apply active styles in the Styles pane are collapsed by default.
161
+ */
162
+ collapseNonContributingCSSRules: 'Collapse non-contributing CSS rules',
159
163
  } as const;
160
164
  const str_ = i18n.i18n.registerUIStrings('panels/elements/elements-meta.ts', UIStrings);
161
165
  const i18nLazyString = i18n.i18n.getLazilyComputedLocalizedString.bind(undefined, str_);
@@ -558,6 +562,16 @@ Common.Settings.registerSettingExtension({
558
562
  defaultValue: true,
559
563
  });
560
564
 
565
+ Common.Settings.registerSettingExtension({
566
+ category: Common.Settings.SettingCategory.ELEMENTS,
567
+ storageType: Common.Settings.SettingStorageType.SYNCED,
568
+ order: 7,
569
+ title: i18nLazyString(UIStrings.collapseNonContributingCSSRules),
570
+ settingName: 'collapse-non-contributing-css-rules',
571
+ settingType: Common.Settings.SettingType.BOOLEAN,
572
+ defaultValue: false,
573
+ });
574
+
561
575
  Common.Settings.registerSettingExtension({
562
576
  settingName: 'show-event-listeners-for-ancestors',
563
577
  settingType: Common.Settings.SettingType.BOOLEAN,