chrome-devtools-frontend 1.0.1611390 → 1.0.1613465

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 (53) hide show
  1. package/front_end/Images/src/flowsheet.svg +1 -0
  2. package/front_end/core/common/Color.ts +3 -2
  3. package/front_end/core/host/AidaClientTypes.ts +5 -0
  4. package/front_end/core/host/AidaGcaTranslation.ts +1 -0
  5. package/front_end/core/platform/StringUtilities.ts +5 -0
  6. package/front_end/core/sdk/NetworkManager.ts +7 -0
  7. package/front_end/core/sdk/ResourceTreeModel.ts +2 -1
  8. package/front_end/core/sdk/Target.ts +1 -3
  9. package/front_end/generated/InspectorBackendCommands.ts +3 -3
  10. package/front_end/generated/SupportedCSSProperties.js +4 -0
  11. package/front_end/generated/protocol.ts +12 -10
  12. package/front_end/models/greendev/Prototypes.ts +7 -4
  13. package/front_end/models/har/HARFormat.ts +30 -0
  14. package/front_end/models/har/Importer.ts +12 -1
  15. package/front_end/models/har/Log.ts +28 -0
  16. package/front_end/models/web_mcp/WebMCPModel.ts +73 -18
  17. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +64 -25
  18. package/front_end/panels/ai_assistance/PatchWidget.ts +7 -23
  19. package/front_end/panels/ai_assistance/SelectWorkspaceDialog.ts +3 -3
  20. package/front_end/panels/ai_assistance/ai_assistance-meta.ts +7 -0
  21. package/front_end/panels/ai_assistance/ai_assistance.ts +1 -0
  22. package/front_end/panels/ai_assistance/components/ChatMessage.ts +21 -11
  23. package/front_end/panels/ai_assistance/components/ChatView.ts +4 -0
  24. package/front_end/panels/ai_assistance/components/ExportForAgentsDialog.ts +20 -10
  25. package/front_end/panels/ai_assistance/components/OptInChangeDialog.ts +179 -0
  26. package/front_end/panels/ai_assistance/components/WalkthroughView.ts +6 -2
  27. package/front_end/panels/ai_assistance/components/exportForAgentsDialog.css +1 -1
  28. package/front_end/panels/ai_assistance/components/optInChangeDialog.css +95 -0
  29. package/front_end/panels/ai_assistance/components/walkthroughView.css +19 -18
  30. package/front_end/panels/application/CookieItemsView.ts +3 -2
  31. package/front_end/panels/application/WebMCPView.ts +97 -6
  32. package/front_end/panels/application/webMCPView.css +7 -1
  33. package/front_end/panels/changes/ChangesView.ts +0 -12
  34. package/front_end/panels/common/common.ts +0 -1
  35. package/front_end/panels/console/ConsolePrompt.ts +2 -2
  36. package/front_end/panels/elements/StylePropertyTreeElement.ts +2 -1
  37. package/front_end/panels/elements/StylesSidebarPane.ts +3 -1
  38. package/front_end/panels/elements/elements-meta.ts +14 -0
  39. package/front_end/panels/network/NetworkLogView.ts +58 -28
  40. package/front_end/panels/recorder/RecorderController.ts +4 -4
  41. package/front_end/panels/settings/AISettingsTab.ts +39 -3
  42. package/front_end/panels/settings/SettingsScreen.ts +2 -2
  43. package/front_end/panels/sources/BreakpointEditDialog.ts +6 -0
  44. package/front_end/third_party/chromium/README.chromium +1 -1
  45. package/front_end/ui/components/markdown_view/CodeBlock.ts +6 -0
  46. package/front_end/ui/legacy/SplitWidget.ts +9 -6
  47. package/front_end/ui/legacy/components/settings_ui/SettingsUI.ts +3 -3
  48. package/front_end/ui/legacy/components/source_frame/FontView.ts +101 -88
  49. package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +4 -4
  50. package/front_end/ui/visual_logging/KnownContextValues.ts +10 -0
  51. package/mcp/mcp.ts +1 -1
  52. package/package.json +1 -1
  53. package/front_end/panels/common/CopyChangesToPrompt.ts +0 -233
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 -960 960 960" width="20px" fill="currentColor"><path d="M168-456v192-432V-456Zm383.79 312q15.21 0 25.71-10.29t10.5-25.5q0-15.21-10.29-25.71t-25.5-10.5q-15.21 0-25.71 10.29t-10.5 25.5q0 15.21 10.29 25.71t25.5 10.5Zm240-360q15.21 0 25.71-10.29t10.5-25.5q0-15.21-10.29-25.71t-25.5-10.5q-15.21 0-25.71 10.29t-10.5 25.5q0 15.21 10.29 25.71t25.5 10.5ZM240-528h204v-72H240v72Zm0 168h204v-72H240v72Zm-72 168q-29.7 0-50.85-21.16Q96-234.32 96-264.04v-432.24Q96-726 117.15-747T168-768h624q29.7 0 50.85 21.15Q864-725.7 864-696H168v432h204v72H168Zm307.5 88.52Q444-134.96 444-179.92 444-215 464-243t52-39v-102h240v-54q-32-11-52-38.92t-20-63.05q0-45.03 31.5-76.53T792-648q45 0 76.5 31.48t31.5 76.44Q900-505 880-477t-52 39v126H588v30q32 11 52 38.92t20 63.05q0 45.03-31.5 76.53T552-72q-45 0-76.5-31.48Z"/></svg>
@@ -684,6 +684,7 @@ export interface Color {
684
684
 
685
685
  const EPSILON = 0.01;
686
686
  const WIDE_RANGE_EPSILON = 1; // For comparisons on channels with a wider range than [0,1]
687
+ const STRICT_EPSILON = 1e-4;
687
688
  function equals(a: number[], b: number[], accuracy?: number): boolean;
688
689
  function equals(a: number|null, b: number|null, accuracy?: number): boolean;
689
690
  function equals(a: number|null|number[], b: number|null|number[], accuracy = EPSILON): boolean {
@@ -994,7 +995,7 @@ export class LCH implements Color {
994
995
  // See "powerless" component definitions in
995
996
  // https://www.w3.org/TR/css-color-4/#specifying-lab-lch
996
997
  isHuePowerless(): boolean {
997
- return equals(this.c, 0);
998
+ return equals(this.c, 0, STRICT_EPSILON);
998
999
  }
999
1000
  static fromSpec(spec: ColorParameterSpec, text: string): LCH|null {
1000
1001
  const L = parsePercentage(spec[0], [0, 100]) ?? parseNumber(spec[0]);
@@ -1592,7 +1593,7 @@ export class HSL implements Color {
1592
1593
  this.l = clamp(l, {min: 0, max: 1});
1593
1594
  s = equals(this.l, 0) || equals(this.l, 1) ? 0 : s;
1594
1595
  this.s = clamp(s, {min: 0, max: 1});
1595
- h = equals(this.s, 0) ? 0 : h;
1596
+ h = equals(this.s, 0, STRICT_EPSILON) ? 0 : h;
1596
1597
  this.h = normalizeHue(h * 360) / 360;
1597
1598
  this.alpha = clamp(alpha ?? null, {min: 0, max: 1});
1598
1599
  this.#authoredText = authoredText;
@@ -384,10 +384,15 @@ export interface FactualityMetadata {
384
384
  facts: FactualityFact[];
385
385
  }
386
386
 
387
+ export interface InferenceOptionMetadata {
388
+ modelId: string;
389
+ }
390
+
387
391
  export interface ResponseMetadata {
388
392
  rpcGlobalId?: RpcGlobalId;
389
393
  attributionMetadata?: AttributionMetadata;
390
394
  factualityMetadata?: FactualityMetadata;
395
+ inferenceOptionMetadata?: InferenceOptionMetadata;
391
396
  }
392
397
 
393
398
  export interface DoConversationResponse {
@@ -454,6 +454,7 @@ export function gcaChunkResponseToAidaChunkResponse(response: GCA.GenerateConten
454
454
  const parts = candidate?.content?.parts || [];
455
455
  const metadata: AIDA.ResponseMetadata = {
456
456
  rpcGlobalId: response.responseId,
457
+ inferenceOptionMetadata: {modelId: response.modelVersion}
457
458
  };
458
459
 
459
460
  if (candidate?.citationMetadata?.citations) {
@@ -276,6 +276,7 @@ export const removeURLFragment = (inputStr: string): string => {
276
276
  };
277
277
 
278
278
  const SPECIAL_REGEX_CHARACTERS = '^[]{}()\\.^$*+?|-,';
279
+ const SPECIAL_URL_PATTERN_CHARACTERS = '?+*(){}\\:';
279
280
 
280
281
  export const regexSpecialCharacters = function(): string {
281
282
  return SPECIAL_REGEX_CHARACTERS;
@@ -450,6 +451,10 @@ export const escapeForRegExp = (str: string): string => {
450
451
  return escapeCharacters(str, SPECIAL_REGEX_CHARACTERS);
451
452
  };
452
453
 
454
+ export const escapeForURLPattern = (text: string): string => {
455
+ return escapeCharacters(text, SPECIAL_URL_PATTERN_CHARACTERS);
456
+ };
457
+
453
458
  export const naturalOrderComparator = (a: string, b: string): number => {
454
459
  const chunk = /^\d+|^\D+/;
455
460
  let chunkA, chunkB, numA, numB;
@@ -32,6 +32,10 @@ const UIStrings = {
32
32
  * @description Explanation why no content is shown for WebSocket connection.
33
33
  */
34
34
  noContentForWebSocket: 'Content for WebSockets is currently not supported',
35
+ /**
36
+ * @description Explanation why no content is shown for Server-Sent Events (SSE).
37
+ */
38
+ noContentForSSE: 'Content for Server-Sent Events (SSE) is currently not supported',
35
39
  /**
36
40
  * @description Explanation why no content is shown for redirect response.
37
41
  */
@@ -215,6 +219,9 @@ export class NetworkManager extends SDKModel<EventTypes> {
215
219
  return {error: i18nString(UIStrings.noContentForWebSocket)};
216
220
  }
217
221
  if (!request.finished) {
222
+ if (Boolean(request.eventSourceMessages()?.length)) {
223
+ return {error: i18nString(UIStrings.noContentForSSE)};
224
+ }
218
225
  await request.once(NetworkRequestEvents.FINISHED_LOADING);
219
226
  }
220
227
  if (request.isRedirect()) {
@@ -858,7 +858,8 @@ export class ResourceTreeFrame {
858
858
  * https://chromium.googlesource.com/chromium/src/+/HEAD/docs/frame_trees.md
859
859
  */
860
860
  isPrimaryFrame(): boolean {
861
- return !this.#sameTargetParentFrame && this.#model.target() === TargetManager.instance().primaryPageTarget();
861
+ return !this.#sameTargetParentFrame &&
862
+ this.#model.target() === this.#model.target().targetManager().primaryPageTarget();
862
863
  }
863
864
 
864
865
  removeChildFrame(frame: ResourceTreeFrame, isSwap: boolean): void {
@@ -70,9 +70,7 @@ export class Target extends ProtocolClient.InspectorBackend.TargetBase {
70
70
  this.#capabilitiesMask = Capability.JS | Capability.LOG | Capability.NETWORK | Capability.TARGET |
71
71
  Capability.INSPECTOR | Capability.IO | Capability.EVENT_BREAKPOINTS;
72
72
  if (parentTarget?.type() !== Type.FRAME) {
73
- // TODO(crbug.com/406991275): This should also grant the `STORAGE` capability, but first the
74
- // crashers in https://crbug.com/466134219 have to be resolved.
75
- this.#capabilitiesMask |= Capability.BROWSER;
73
+ this.#capabilitiesMask |= Capability.BROWSER | Capability.STORAGE;
76
74
  }
77
75
  break;
78
76
  case Type.SHARED_WORKER:
@@ -867,7 +867,7 @@ inspectorBackend.registerCommand("Network.continueInterceptedRequest", [{"name":
867
867
  inspectorBackend.registerCommand("Network.deleteCookies", [{"name": "name", "type": "string", "optional": false, "description": "Name of the cookies to remove.", "typeRef": null}, {"name": "url", "type": "string", "optional": true, "description": "If specified, deletes all the cookies with the given name where domain and path match provided URL.", "typeRef": null}, {"name": "domain", "type": "string", "optional": true, "description": "If specified, deletes only cookies with the exact domain.", "typeRef": null}, {"name": "path", "type": "string", "optional": true, "description": "If specified, deletes only cookies with the exact path.", "typeRef": null}, {"name": "partitionKey", "type": "object", "optional": true, "description": "If specified, deletes only cookies with the the given name and partitionKey where all partition key attributes match the cookie partition key attribute.", "typeRef": "Network.CookiePartitionKey"}], [], "Deletes browser cookies with matching name and url or domain/path/partitionKey pair.");
868
868
  inspectorBackend.registerCommand("Network.disable", [], [], "Disables network tracking, prevents network events from being sent to the client.");
869
869
  inspectorBackend.registerCommand("Network.emulateNetworkConditions", [{"name": "offline", "type": "boolean", "optional": false, "description": "True to emulate internet disconnection.", "typeRef": null}, {"name": "latency", "type": "number", "optional": false, "description": "Minimum latency from request sent to response headers received (ms).", "typeRef": null}, {"name": "downloadThroughput", "type": "number", "optional": false, "description": "Maximal aggregated download throughput (bytes/sec). -1 disables download throttling.", "typeRef": null}, {"name": "uploadThroughput", "type": "number", "optional": false, "description": "Maximal aggregated upload throughput (bytes/sec). -1 disables upload throttling.", "typeRef": null}, {"name": "connectionType", "type": "string", "optional": true, "description": "Connection type if known.", "typeRef": "Network.ConnectionType"}, {"name": "packetLoss", "type": "number", "optional": true, "description": "WebRTC packet loss (percent, 0-100). 0 disables packet loss emulation, 100 drops all the packets.", "typeRef": null}, {"name": "packetQueueLength", "type": "number", "optional": true, "description": "WebRTC packet queue length (packet). 0 removes any queue length limitations.", "typeRef": null}, {"name": "packetReordering", "type": "boolean", "optional": true, "description": "WebRTC packetReordering feature.", "typeRef": null}], [], "Activates emulation of network conditions. This command is deprecated in favor of the emulateNetworkConditionsByRule and overrideNetworkState commands, which can be used together to the same effect.");
870
- inspectorBackend.registerCommand("Network.emulateNetworkConditionsByRule", [{"name": "offline", "type": "boolean", "optional": false, "description": "True to emulate internet disconnection.", "typeRef": null}, {"name": "matchedNetworkConditions", "type": "array", "optional": false, "description": "Configure conditions for matching requests. If multiple entries match a request, the first entry wins. Global conditions can be configured by leaving the urlPattern for the conditions empty. These global conditions are also applied for throttling of p2p connections.", "typeRef": "Network.NetworkConditions"}], ["ruleIds"], "Activates emulation of network conditions for individual requests using URL match patterns. Unlike the deprecated Network.emulateNetworkConditions this method does not affect `navigator` state. Use Network.overrideNetworkState to explicitly modify `navigator` behavior.");
870
+ inspectorBackend.registerCommand("Network.emulateNetworkConditionsByRule", [{"name": "offline", "type": "boolean", "optional": true, "description": "True to emulate internet disconnection. Deprecated, use the offline property in matchedNetworkConditions or emulateOfflineServiceWorker instead.", "typeRef": null}, {"name": "emulateOfflineServiceWorker", "type": "boolean", "optional": true, "description": "True to emulate offline service worker.", "typeRef": null}, {"name": "matchedNetworkConditions", "type": "array", "optional": false, "description": "Configure conditions for matching requests. If multiple entries match a request, the first entry wins. Global conditions can be configured by leaving the urlPattern for the conditions empty. These global conditions are also applied for throttling of p2p connections.", "typeRef": "Network.NetworkConditions"}], ["ruleIds"], "Activates emulation of network conditions for individual requests using URL match patterns. Unlike the deprecated Network.emulateNetworkConditions this method does not affect `navigator` state. Use Network.overrideNetworkState to explicitly modify `navigator` behavior.");
871
871
  inspectorBackend.registerCommand("Network.overrideNetworkState", [{"name": "offline", "type": "boolean", "optional": false, "description": "True to emulate internet disconnection.", "typeRef": null}, {"name": "latency", "type": "number", "optional": false, "description": "Minimum latency from request sent to response headers received (ms).", "typeRef": null}, {"name": "downloadThroughput", "type": "number", "optional": false, "description": "Maximal aggregated download throughput (bytes/sec). -1 disables download throttling.", "typeRef": null}, {"name": "uploadThroughput", "type": "number", "optional": false, "description": "Maximal aggregated upload throughput (bytes/sec). -1 disables upload throttling.", "typeRef": null}, {"name": "connectionType", "type": "string", "optional": true, "description": "Connection type if known.", "typeRef": "Network.ConnectionType"}], [], "Override the state of navigator.onLine and navigator.connection.");
872
872
  inspectorBackend.registerCommand("Network.enable", [{"name": "maxTotalBufferSize", "type": "number", "optional": true, "description": "Buffer size in bytes to use when preserving network payloads (XHRs, etc). This is the maximum number of bytes that will be collected by this DevTools session.", "typeRef": null}, {"name": "maxResourceBufferSize", "type": "number", "optional": true, "description": "Per-resource buffer size in bytes to use when preserving network payloads (XHRs, etc).", "typeRef": null}, {"name": "maxPostDataSize", "type": "number", "optional": true, "description": "Longest post body size (in bytes) that would be included in requestWillBeSent notification", "typeRef": null}, {"name": "reportDirectSocketTraffic", "type": "boolean", "optional": true, "description": "Whether DirectSocket chunk send/receive events should be reported.", "typeRef": null}, {"name": "enableDurableMessages", "type": "boolean", "optional": true, "description": "Enable storing response bodies outside of renderer, so that these survive a cross-process navigation. Requires maxTotalBufferSize to be set. Currently defaults to false. This field is being deprecated in favor of the dedicated configureDurableMessages command, due to the possibility of deadlocks when awaiting Network.enable before issuing Runtime.runIfWaitingForDebugger.", "typeRef": null}], [], "Enables network tracking, network events will now be delivered to the client.");
873
873
  inspectorBackend.registerCommand("Network.configureDurableMessages", [{"name": "maxTotalBufferSize", "type": "number", "optional": true, "description": "Buffer size in bytes to use when preserving network payloads (XHRs, etc).", "typeRef": null}, {"name": "maxResourceBufferSize", "type": "number", "optional": true, "description": "Per-resource buffer size in bytes to use when preserving network payloads (XHRs, etc).", "typeRef": null}], [], "Configures storing response bodies outside of renderer, so that these survive a cross-process navigation. If maxTotalBufferSize is not set, durable messages are disabled.");
@@ -895,7 +895,7 @@ inspectorBackend.registerCommand("Network.enableReportingApi", [{"name": "enable
895
895
  inspectorBackend.registerCommand("Network.enableDeviceBoundSessions", [{"name": "enable", "type": "boolean", "optional": false, "description": "Whether to enable or disable events.", "typeRef": null}], [], "Sets up tracking device bound sessions and fetching of initial set of sessions.");
896
896
  inspectorBackend.registerCommand("Network.fetchSchemefulSite", [{"name": "origin", "type": "string", "optional": false, "description": "The URL origin.", "typeRef": null}], ["schemefulSite"], "Fetches the schemeful site for a specific origin.");
897
897
  inspectorBackend.registerCommand("Network.loadNetworkResource", [{"name": "frameId", "type": "string", "optional": true, "description": "Frame id to get the resource for. Mandatory for frame targets, and should be omitted for worker targets.", "typeRef": "Page.FrameId"}, {"name": "url", "type": "string", "optional": false, "description": "URL of the resource to get content for.", "typeRef": null}, {"name": "options", "type": "object", "optional": false, "description": "Options for the request.", "typeRef": "Network.LoadNetworkResourceOptions"}], ["resource"], "Fetches the resource and returns the content.");
898
- inspectorBackend.registerCommand("Network.setCookieControls", [{"name": "enableThirdPartyCookieRestriction", "type": "boolean", "optional": false, "description": "Whether 3pc restriction is enabled.", "typeRef": null}, {"name": "disableThirdPartyCookieMetadata", "type": "boolean", "optional": false, "description": "Whether 3pc grace period exception should be enabled; false by default.", "typeRef": null}, {"name": "disableThirdPartyCookieHeuristics", "type": "boolean", "optional": false, "description": "Whether 3pc heuristics exceptions should be enabled; false by default.", "typeRef": null}], [], "Sets Controls for third-party cookie access Page reload is required before the new cookie behavior will be observed");
898
+ inspectorBackend.registerCommand("Network.setCookieControls", [{"name": "enableThirdPartyCookieRestriction", "type": "boolean", "optional": false, "description": "Whether 3pc restriction is enabled.", "typeRef": null}], [], "Sets Controls for third-party cookie access Page reload is required before the new cookie behavior will be observed");
899
899
  inspectorBackend.registerType("Network.ResourceTiming", [{"name": "requestTime", "type": "number", "optional": false, "description": "Timing's requestTime is a baseline in seconds, while the other numbers are ticks in milliseconds relatively to this requestTime.", "typeRef": null}, {"name": "proxyStart", "type": "number", "optional": false, "description": "Started resolving proxy.", "typeRef": null}, {"name": "proxyEnd", "type": "number", "optional": false, "description": "Finished resolving proxy.", "typeRef": null}, {"name": "dnsStart", "type": "number", "optional": false, "description": "Started DNS address resolve.", "typeRef": null}, {"name": "dnsEnd", "type": "number", "optional": false, "description": "Finished DNS address resolve.", "typeRef": null}, {"name": "connectStart", "type": "number", "optional": false, "description": "Started connecting to the remote host.", "typeRef": null}, {"name": "connectEnd", "type": "number", "optional": false, "description": "Connected to the remote host.", "typeRef": null}, {"name": "sslStart", "type": "number", "optional": false, "description": "Started SSL handshake.", "typeRef": null}, {"name": "sslEnd", "type": "number", "optional": false, "description": "Finished SSL handshake.", "typeRef": null}, {"name": "workerStart", "type": "number", "optional": false, "description": "Started running ServiceWorker.", "typeRef": null}, {"name": "workerReady", "type": "number", "optional": false, "description": "Finished Starting ServiceWorker.", "typeRef": null}, {"name": "workerFetchStart", "type": "number", "optional": false, "description": "Started fetch event.", "typeRef": null}, {"name": "workerRespondWithSettled", "type": "number", "optional": false, "description": "Settled fetch event respondWith promise.", "typeRef": null}, {"name": "workerRouterEvaluationStart", "type": "number", "optional": true, "description": "Started ServiceWorker static routing source evaluation.", "typeRef": null}, {"name": "workerCacheLookupStart", "type": "number", "optional": true, "description": "Started cache lookup when the source was evaluated to `cache`.", "typeRef": null}, {"name": "sendStart", "type": "number", "optional": false, "description": "Started sending request.", "typeRef": null}, {"name": "sendEnd", "type": "number", "optional": false, "description": "Finished sending request.", "typeRef": null}, {"name": "pushStart", "type": "number", "optional": false, "description": "Time the server started pushing request.", "typeRef": null}, {"name": "pushEnd", "type": "number", "optional": false, "description": "Time the server finished pushing request.", "typeRef": null}, {"name": "receiveHeadersStart", "type": "number", "optional": false, "description": "Started receiving response headers.", "typeRef": null}, {"name": "receiveHeadersEnd", "type": "number", "optional": false, "description": "Finished receiving response headers.", "typeRef": null}]);
900
900
  inspectorBackend.registerType("Network.PostDataEntry", [{"name": "bytes", "type": "string", "optional": true, "description": "", "typeRef": null}]);
901
901
  inspectorBackend.registerType("Network.Request", [{"name": "url", "type": "string", "optional": false, "description": "Request URL (without fragment).", "typeRef": null}, {"name": "urlFragment", "type": "string", "optional": true, "description": "Fragment of the requested URL starting with hash, if present.", "typeRef": null}, {"name": "method", "type": "string", "optional": false, "description": "HTTP request method.", "typeRef": null}, {"name": "headers", "type": "object", "optional": false, "description": "HTTP request headers.", "typeRef": "Network.Headers"}, {"name": "postData", "type": "string", "optional": true, "description": "HTTP POST request data. Use postDataEntries instead.", "typeRef": null}, {"name": "hasPostData", "type": "boolean", "optional": true, "description": "True when the request has POST data. Note that postData might still be omitted when this flag is true when the data is too long.", "typeRef": null}, {"name": "postDataEntries", "type": "array", "optional": true, "description": "Request body elements (post data broken into individual entries).", "typeRef": "Network.PostDataEntry"}, {"name": "mixedContentType", "type": "string", "optional": true, "description": "The mixed content type of the request.", "typeRef": "Security.MixedContentType"}, {"name": "initialPriority", "type": "string", "optional": false, "description": "Priority of the resource request at the time request is sent.", "typeRef": "Network.ResourcePriority"}, {"name": "referrerPolicy", "type": "string", "optional": false, "description": "The referrer policy of the request, as defined in https://www.w3.org/TR/referrer-policy/", "typeRef": null}, {"name": "isLinkPreload", "type": "boolean", "optional": true, "description": "Whether is loaded via link preload.", "typeRef": null}, {"name": "trustTokenParams", "type": "object", "optional": true, "description": "Set for requests when the TrustToken API is used. Contains the parameters passed by the developer (e.g. via \\\"fetch\\\") as understood by the backend.", "typeRef": "Network.TrustTokenParams"}, {"name": "isSameSite", "type": "boolean", "optional": true, "description": "True if this resource request is considered to be the 'same site' as the request corresponding to the main frame.", "typeRef": null}, {"name": "isAdRelated", "type": "boolean", "optional": true, "description": "True when the resource request is ad-related.", "typeRef": null}]);
@@ -923,7 +923,7 @@ inspectorBackend.registerType("Network.SignedExchangeSignature", [{"name": "labe
923
923
  inspectorBackend.registerType("Network.SignedExchangeHeader", [{"name": "requestUrl", "type": "string", "optional": false, "description": "Signed exchange request URL.", "typeRef": null}, {"name": "responseCode", "type": "number", "optional": false, "description": "Signed exchange response code.", "typeRef": null}, {"name": "responseHeaders", "type": "object", "optional": false, "description": "Signed exchange response headers.", "typeRef": "Network.Headers"}, {"name": "signatures", "type": "array", "optional": false, "description": "Signed exchange response signature.", "typeRef": "Network.SignedExchangeSignature"}, {"name": "headerIntegrity", "type": "string", "optional": false, "description": "Signed exchange header integrity hash in the form of `sha256-<base64-hash-value>`.", "typeRef": null}]);
924
924
  inspectorBackend.registerType("Network.SignedExchangeError", [{"name": "message", "type": "string", "optional": false, "description": "Error message.", "typeRef": null}, {"name": "signatureIndex", "type": "number", "optional": true, "description": "The index of the signature which caused the error.", "typeRef": null}, {"name": "errorField", "type": "string", "optional": true, "description": "The field which caused the error.", "typeRef": "Network.SignedExchangeErrorField"}]);
925
925
  inspectorBackend.registerType("Network.SignedExchangeInfo", [{"name": "outerResponse", "type": "object", "optional": false, "description": "The outer response of signed HTTP exchange which was received from network.", "typeRef": "Network.Response"}, {"name": "hasExtraInfo", "type": "boolean", "optional": false, "description": "Whether network response for the signed exchange was accompanied by extra headers.", "typeRef": null}, {"name": "header", "type": "object", "optional": true, "description": "Information about the signed exchange header.", "typeRef": "Network.SignedExchangeHeader"}, {"name": "securityDetails", "type": "object", "optional": true, "description": "Security details for the signed exchange header.", "typeRef": "Network.SecurityDetails"}, {"name": "errors", "type": "array", "optional": true, "description": "Errors occurred while handling the signed exchange.", "typeRef": "Network.SignedExchangeError"}]);
926
- inspectorBackend.registerType("Network.NetworkConditions", [{"name": "urlPattern", "type": "string", "optional": false, "description": "Only matching requests will be affected by these conditions. Patterns use the URLPattern constructor string syntax (https://urlpattern.spec.whatwg.org/) and must be absolute. If the pattern is empty, all requests are matched (including p2p connections).", "typeRef": null}, {"name": "latency", "type": "number", "optional": false, "description": "Minimum latency from request sent to response headers received (ms).", "typeRef": null}, {"name": "downloadThroughput", "type": "number", "optional": false, "description": "Maximal aggregated download throughput (bytes/sec). -1 disables download throttling.", "typeRef": null}, {"name": "uploadThroughput", "type": "number", "optional": false, "description": "Maximal aggregated upload throughput (bytes/sec). -1 disables upload throttling.", "typeRef": null}, {"name": "connectionType", "type": "string", "optional": true, "description": "Connection type if known.", "typeRef": "Network.ConnectionType"}, {"name": "packetLoss", "type": "number", "optional": true, "description": "WebRTC packet loss (percent, 0-100). 0 disables packet loss emulation, 100 drops all the packets.", "typeRef": null}, {"name": "packetQueueLength", "type": "number", "optional": true, "description": "WebRTC packet queue length (packet). 0 removes any queue length limitations.", "typeRef": null}, {"name": "packetReordering", "type": "boolean", "optional": true, "description": "WebRTC packetReordering feature.", "typeRef": null}]);
926
+ inspectorBackend.registerType("Network.NetworkConditions", [{"name": "urlPattern", "type": "string", "optional": false, "description": "Only matching requests will be affected by these conditions. Patterns use the URLPattern constructor string syntax (https://urlpattern.spec.whatwg.org/) and must be absolute. If the pattern is empty, all requests are matched (including p2p connections).", "typeRef": null}, {"name": "latency", "type": "number", "optional": false, "description": "Minimum latency from request sent to response headers received (ms).", "typeRef": null}, {"name": "downloadThroughput", "type": "number", "optional": false, "description": "Maximal aggregated download throughput (bytes/sec). -1 disables download throttling.", "typeRef": null}, {"name": "uploadThroughput", "type": "number", "optional": false, "description": "Maximal aggregated upload throughput (bytes/sec). -1 disables upload throttling.", "typeRef": null}, {"name": "connectionType", "type": "string", "optional": true, "description": "Connection type if known.", "typeRef": "Network.ConnectionType"}, {"name": "packetLoss", "type": "number", "optional": true, "description": "WebRTC packet loss (percent, 0-100). 0 disables packet loss emulation, 100 drops all the packets.", "typeRef": null}, {"name": "packetQueueLength", "type": "number", "optional": true, "description": "WebRTC packet queue length (packet). 0 removes any queue length limitations.", "typeRef": null}, {"name": "packetReordering", "type": "boolean", "optional": true, "description": "WebRTC packetReordering feature.", "typeRef": null}, {"name": "offline", "type": "boolean", "optional": true, "description": "True to emulate internet disconnection.", "typeRef": null}]);
927
927
  inspectorBackend.registerType("Network.BlockPattern", [{"name": "urlPattern", "type": "string", "optional": false, "description": "URL pattern to match. Patterns use the URLPattern constructor string syntax (https://urlpattern.spec.whatwg.org/) and must be absolute. Example: `*://*:*/*.css`.", "typeRef": null}, {"name": "block", "type": "boolean", "optional": false, "description": "Whether or not to block the pattern. If false, a matching request will not be blocked even if it matches a later `BlockPattern`.", "typeRef": null}]);
928
928
  inspectorBackend.registerType("Network.DirectTCPSocketOptions", [{"name": "noDelay", "type": "boolean", "optional": false, "description": "TCP_NODELAY option", "typeRef": null}, {"name": "keepAliveDelay", "type": "number", "optional": true, "description": "Expected to be unsigned integer.", "typeRef": null}, {"name": "sendBufferSize", "type": "number", "optional": true, "description": "Expected to be unsigned integer.", "typeRef": null}, {"name": "receiveBufferSize", "type": "number", "optional": true, "description": "Expected to be unsigned integer.", "typeRef": null}, {"name": "dnsQueryType", "type": "string", "optional": true, "description": "", "typeRef": "Network.DirectSocketDnsQueryType"}]);
929
929
  inspectorBackend.registerType("Network.DirectUDPSocketOptions", [{"name": "remoteAddr", "type": "string", "optional": true, "description": "", "typeRef": null}, {"name": "remotePort", "type": "number", "optional": true, "description": "Unsigned int 16.", "typeRef": null}, {"name": "localAddr", "type": "string", "optional": true, "description": "", "typeRef": null}, {"name": "localPort", "type": "number", "optional": true, "description": "Unsigned int 16.", "typeRef": null}, {"name": "dnsQueryType", "type": "string", "optional": true, "description": "", "typeRef": "Network.DirectSocketDnsQueryType"}, {"name": "sendBufferSize", "type": "number", "optional": true, "description": "Expected to be unsigned integer.", "typeRef": null}, {"name": "receiveBufferSize", "type": "number", "optional": true, "description": "Expected to be unsigned integer.", "typeRef": null}, {"name": "multicastLoopback", "type": "boolean", "optional": true, "description": "", "typeRef": null}, {"name": "multicastTimeToLive", "type": "number", "optional": true, "description": "Unsigned int 8.", "typeRef": null}, {"name": "multicastAllowAddressSharing", "type": "boolean", "optional": true, "description": "", "typeRef": null}]);
@@ -3493,6 +3493,7 @@ export const generatedProperties = [
3493
3493
  {
3494
3494
  "keywords": [
3495
3495
  "auto",
3496
+ "chain",
3496
3497
  "contain",
3497
3498
  "none"
3498
3499
  ],
@@ -3501,6 +3502,7 @@ export const generatedProperties = [
3501
3502
  {
3502
3503
  "keywords": [
3503
3504
  "auto",
3505
+ "chain",
3504
3506
  "contain",
3505
3507
  "none"
3506
3508
  ],
@@ -6635,6 +6637,7 @@ export const generatedPropertyValues = {
6635
6637
  "overscroll-behavior-x": {
6636
6638
  "values": [
6637
6639
  "auto",
6640
+ "chain",
6638
6641
  "contain",
6639
6642
  "none"
6640
6643
  ]
@@ -6642,6 +6645,7 @@ export const generatedPropertyValues = {
6642
6645
  "overscroll-behavior-y": {
6643
6646
  "values": [
6644
6647
  "auto",
6648
+ "chain",
6645
6649
  "contain",
6646
6650
  "none"
6647
6651
  ]
@@ -11376,6 +11376,10 @@ export namespace Network {
11376
11376
  * WebRTC packetReordering feature.
11377
11377
  */
11378
11378
  packetReordering?: boolean;
11379
+ /**
11380
+ * True to emulate internet disconnection.
11381
+ */
11382
+ offline?: boolean;
11379
11383
  }
11380
11384
 
11381
11385
  export interface BlockPattern {
@@ -12154,9 +12158,15 @@ export namespace Network {
12154
12158
 
12155
12159
  export interface EmulateNetworkConditionsByRuleRequest {
12156
12160
  /**
12157
- * True to emulate internet disconnection.
12161
+ * True to emulate internet disconnection. Deprecated, use the offline property in matchedNetworkConditions
12162
+ * or emulateOfflineServiceWorker instead.
12163
+ * @deprecated
12158
12164
  */
12159
- offline: boolean;
12165
+ offline?: boolean;
12166
+ /**
12167
+ * True to emulate offline service worker.
12168
+ */
12169
+ emulateOfflineServiceWorker?: boolean;
12160
12170
  /**
12161
12171
  * Configure conditions for matching requests. If multiple entries match a request, the first entry wins. Global
12162
12172
  * conditions can be configured by leaving the urlPattern for the conditions empty. These global conditions are
@@ -12584,14 +12594,6 @@ export namespace Network {
12584
12594
  * Whether 3pc restriction is enabled.
12585
12595
  */
12586
12596
  enableThirdPartyCookieRestriction: boolean;
12587
- /**
12588
- * Whether 3pc grace period exception should be enabled; false by default.
12589
- */
12590
- disableThirdPartyCookieMetadata: boolean;
12591
- /**
12592
- * Whether 3pc heuristics exceptions should be enabled; false by default.
12593
- */
12594
- disableThirdPartyCookieHeuristics: boolean;
12595
12597
  }
12596
12598
 
12597
12599
  /**
@@ -9,7 +9,7 @@ let instance: Prototypes|null = null;
9
9
 
10
10
  export interface GreenDevSettings {
11
11
  aiAnnotations: Common.Settings.Setting<boolean>;
12
- copyToGemini: Common.Settings.Setting<boolean>;
12
+ beyondStyling: Common.Settings.Setting<boolean>;
13
13
  breakpointDebuggerAgent: Common.Settings.Setting<boolean>;
14
14
  emulationCapabilities: Common.Settings.Setting<boolean>;
15
15
  }
@@ -42,8 +42,11 @@ export class Prototypes {
42
42
  false,
43
43
  Common.Settings.SettingStorageType.LOCAL,
44
44
  );
45
- const copyToGemini =
46
- settings.createSetting('greendev-copy-to-gemini-enabled', false, Common.Settings.SettingStorageType.LOCAL);
45
+ const beyondStyling = settings.createSetting(
46
+ 'greendev-beyond-styling-enabled',
47
+ false,
48
+ Common.Settings.SettingStorageType.LOCAL,
49
+ );
47
50
  const breakpointDebuggerAgent = settings.createSetting(
48
51
  'greendev-breakpoint-debugger-agent-enabled',
49
52
  false,
@@ -55,6 +58,6 @@ export class Prototypes {
55
58
  Common.Settings.SettingStorageType.LOCAL,
56
59
  );
57
60
 
58
- return {aiAnnotations, copyToGemini, breakpointDebuggerAgent, emulationCapabilities};
61
+ return {aiAnnotations, beyondStyling, breakpointDebuggerAgent, emulationCapabilities};
59
62
  }
60
63
  }
@@ -171,6 +171,7 @@ export class HAREntry extends HARBase {
171
171
  this.custom.set('initiator', this.importInitiator(data['_initiator']));
172
172
  this.custom.set('priority', HARBase.optionalString(data['_priority']));
173
173
  this.custom.set('resourceType', HARBase.optionalString(data['_resourceType']));
174
+ this.custom.set('eventSourceMessages', this.#importEventSourceMessages(data['_eventSourceMessages']));
174
175
  this.custom.set('webSocketMessages', this.importWebSocketMessages(data['_webSocketMessages']));
175
176
  }
176
177
 
@@ -196,6 +197,21 @@ export class HAREntry extends HARBase {
196
197
  }
197
198
  return outputMessages;
198
199
  }
200
+
201
+ #importEventSourceMessages(inputMessages: any): HAREventSourceMessage[]|undefined {
202
+ if (!Array.isArray(inputMessages)) {
203
+ return;
204
+ }
205
+
206
+ const outputMessages = [];
207
+ for (const message of inputMessages) {
208
+ if (typeof message !== 'object') {
209
+ return;
210
+ }
211
+ outputMessages.push(new HAREventSourceMessage(message));
212
+ }
213
+ return outputMessages;
214
+ }
199
215
  }
200
216
 
201
217
  class HARRequest extends HARBase {
@@ -480,3 +496,17 @@ class HARWebSocketMessage extends HARBase {
480
496
  this.type = HARBase.optionalString(data['type']);
481
497
  }
482
498
  }
499
+
500
+ class HAREventSourceMessage extends HARBase {
501
+ time: number|undefined;
502
+ eventName: string|undefined;
503
+ eventId: string|undefined;
504
+ data: string|undefined;
505
+ constructor(data: any) {
506
+ super(data);
507
+ this.time = HARBase.optionalNumber(data['time']);
508
+ this.eventName = HARBase.optionalString(data['eventName']);
509
+ this.eventId = HARBase.optionalString(data['eventId']);
510
+ this.data = HARBase.optionalString(data['data']);
511
+ }
512
+ }
@@ -137,7 +137,18 @@ export class Importer {
137
137
  async () =>
138
138
  new TextUtils.ContentData.ContentData(contentText ?? '', isBase64, mimeType ?? '', charset ?? undefined));
139
139
 
140
- if (request.mimeType === Platform.MimeType.MimeType.EVENTSTREAM && contentText) {
140
+ const importedEventSourceMessages = entry.customAsArray('eventSourceMessages');
141
+
142
+ if (importedEventSourceMessages) {
143
+ for (const message of importedEventSourceMessages) {
144
+ if (message.time === undefined || message.eventName === undefined || message.eventId === undefined) {
145
+ continue;
146
+ }
147
+ // message.data may be undefined, if saved in a sanitized context
148
+
149
+ request.addEventSourceMessage(message.time, message.eventName, message.eventId, message.data);
150
+ }
151
+ } else if (request.mimeType === Platform.MimeType.MimeType.EVENTSTREAM && contentText) {
141
152
  const issueTime = entry.startedDateTime.getTime() / 1000;
142
153
  const onEvent = (eventName: string, data: string, eventId: string): void => {
143
154
  request.addEventSourceMessage(issueTime, eventName, eventId, data);
@@ -176,6 +176,26 @@ export class Entry {
176
176
  delete entry._webSocketMessages;
177
177
  }
178
178
 
179
+ const eventSourceMessages = harEntry.request.eventSourceMessages();
180
+ if (eventSourceMessages?.length) {
181
+ const messages = [];
182
+ for (const message of eventSourceMessages) {
183
+ const messageDTO: EventSourceMessageDTO = {
184
+ time: message.time,
185
+ eventName: message.eventName,
186
+ eventId: message.eventId,
187
+ };
188
+ if (!options.sanitize) {
189
+ // Omit the data when sanitizing, as it could contain sensitive information.
190
+ messageDTO.data = message.data;
191
+ }
192
+ messages.push(messageDTO);
193
+ }
194
+ entry._eventSourceMessages = messages;
195
+ } else {
196
+ delete entry._eventSourceMessages;
197
+ }
198
+
179
199
  return entry;
180
200
  }
181
201
 
@@ -490,6 +510,7 @@ export interface EntryDTO {
490
510
  _priority: Protocol.Network.ResourcePriority|null;
491
511
  _resourceType: string;
492
512
  _webSocketMessages?: Object[];
513
+ _eventSourceMessages?: EventSourceMessageDTO[];
493
514
  cache: Object;
494
515
  connection?: string;
495
516
  pageref?: string;
@@ -540,3 +561,10 @@ export interface LogDTO {
540
561
  pages: Page[];
541
562
  entries: EntryDTO[];
542
563
  }
564
+
565
+ export interface EventSourceMessageDTO {
566
+ time: number;
567
+ eventName: string;
568
+ eventId: string;
569
+ data?: string;
570
+ }
@@ -7,7 +7,7 @@ import * as SDK from '../../core/sdk/sdk.js';
7
7
  import type * as ProtocolProxyApi from '../../generated/protocol-proxy-api.js';
8
8
  import type * as Protocol from '../../generated/protocol.js';
9
9
  import * as Bindings from '../bindings/bindings.js';
10
- import type * as StackTrace from '../stack_trace/stack_trace.js';
10
+ import * as StackTrace from '../stack_trace/stack_trace.js';
11
11
 
12
12
  export const enum Events {
13
13
  TOOLS_ADDED = 'ToolsAdded',
@@ -16,16 +16,78 @@ export const enum Events {
16
16
  TOOL_RESPONDED = 'ToolResponded',
17
17
  }
18
18
 
19
+ export interface ExceptionDetails {
20
+ readonly error: SDK.RemoteObject.RemoteObject;
21
+ readonly description: string;
22
+ readonly frames: StackTrace.ErrorStackParser.ParsedErrorFrame[];
23
+ readonly cause?: ExceptionDetails;
24
+ }
25
+
26
+ export class Result {
27
+ readonly status: Protocol.WebMCP.InvocationStatus;
28
+ readonly output?: unknown;
29
+ readonly errorText?: string;
30
+ // TODO(crbug.com/494516094) Clean this up if the target disappears?
31
+ readonly #exception?: SDK.RemoteObject.RemoteObject;
32
+ #exceptionDetails?: Promise<ExceptionDetails|undefined>;
33
+
34
+ constructor(
35
+ status: Protocol.WebMCP.InvocationStatus, output: unknown|undefined, errorText: string|undefined,
36
+ exception: SDK.RemoteObject.RemoteObject|undefined) {
37
+ this.status = status;
38
+ this.errorText = errorText;
39
+ this.#exception = exception;
40
+ this.output = output;
41
+ }
42
+
43
+ get exceptionDetails(): Promise<ExceptionDetails|undefined>|undefined {
44
+ if (!this.#exceptionDetails) {
45
+ this.#exceptionDetails = this.#resolveExceptionDetails(this.#exception);
46
+ }
47
+ return this.#exceptionDetails;
48
+ }
49
+
50
+ async #resolveExceptionDetails(errorObj: SDK.RemoteObject.RemoteObject|undefined):
51
+ Promise<ExceptionDetails|undefined> {
52
+ if (!errorObj) {
53
+ return undefined;
54
+ }
55
+ const error = SDK.RemoteObject.RemoteError.objectAsError(errorObj);
56
+ const [details, cause] = await Promise.all([error.exceptionDetails(), error.cause()]);
57
+ const description = error.errorStack;
58
+
59
+ const frames =
60
+ StackTrace.ErrorStackParser.parseSourcePositionsFromErrorStack(errorObj.runtimeModel(), error.errorStack) || [];
61
+ if (details?.stackTrace) {
62
+ StackTrace.ErrorStackParser.augmentErrorStackWithScriptIds(frames, details.stackTrace);
63
+ }
64
+
65
+ if (cause?.subtype === 'error') {
66
+ return {error: errorObj, description, frames, cause: await this.#resolveExceptionDetails(cause)};
67
+ }
68
+
69
+ if (cause?.type === 'string') {
70
+ return {
71
+ error: errorObj,
72
+ description,
73
+ frames,
74
+ cause: {
75
+ error: cause,
76
+ description: cause.value as string,
77
+ frames: [],
78
+ }
79
+ };
80
+ }
81
+
82
+ return {error: errorObj, description, frames};
83
+ }
84
+ }
85
+
19
86
  export interface Call {
20
87
  invocationId: string;
21
88
  tool: Tool;
22
89
  input: string;
23
- result?: {
24
- status: Protocol.WebMCP.InvocationStatus,
25
- output?: unknown,
26
- errorText?: string,
27
- exception?: Protocol.Runtime.RemoteObject,
28
- };
90
+ result?: Result;
29
91
  }
30
92
 
31
93
  export class Tool {
@@ -160,11 +222,7 @@ export class WebMCPModel extends SDK.SDKModel.SDKModel<EventTypes> implements Pr
160
222
  if (!tool) {
161
223
  return;
162
224
  }
163
- const call: Call = {
164
- invocationId: params.invocationId,
165
- input: params.input,
166
- tool,
167
- };
225
+ const call: Call = {tool, input: params.input, invocationId: params.invocationId};
168
226
  this.#calls.set(params.invocationId, call);
169
227
  this.dispatchEventToListeners(Events.TOOL_INVOKED, call);
170
228
  }
@@ -174,12 +232,9 @@ export class WebMCPModel extends SDK.SDKModel.SDKModel<EventTypes> implements Pr
174
232
  if (!call) {
175
233
  return;
176
234
  }
177
- call.result = {
178
- status: params.status,
179
- output: params.output,
180
- errorText: params.errorText,
181
- exception: params.exception,
182
- };
235
+ const exception =
236
+ params.exception && this.target().model(SDK.RuntimeModel.RuntimeModel)?.createRemoteObject(params.exception);
237
+ call.result = new Result(params.status, params.output, params.errorText, exception);
183
238
  this.dispatchEventToListeners(Events.TOOL_RESPONDED, call);
184
239
  }
185
240
  }