chrome-devtools-frontend 1.0.1605390 → 1.0.1606789

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 (60) hide show
  1. package/front_end/core/host/UserMetrics.ts +0 -1
  2. package/front_end/core/platform/api/HostRuntime.ts +9 -6
  3. package/front_end/core/platform/browser/HostRuntime.ts +2 -2
  4. package/front_end/core/platform/node/HostRuntime.ts +7 -7
  5. package/front_end/core/protocol_client/InspectorBackend.ts +4 -0
  6. package/front_end/core/root/ExperimentNames.ts +0 -1
  7. package/front_end/core/sdk/CrashReportContextModel.ts +28 -0
  8. package/front_end/core/sdk/sdk.ts +2 -2
  9. package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshotWorkerDispatcher.ts +3 -3
  10. package/front_end/entrypoints/heap_snapshot_worker/heap_snapshot_worker-entrypoint.ts +5 -4
  11. package/front_end/entrypoints/main/MainImpl.ts +0 -101
  12. package/front_end/models/ai_assistance/ChangeManager.ts +6 -6
  13. package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +112 -5
  14. package/front_end/models/ai_assistance/agents/AiAgent.ts +0 -24
  15. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.snapshot.txt +2 -2
  16. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +6 -3
  17. package/front_end/models/ai_assistance/agents/ExecuteJavascript.ts +13 -1
  18. package/front_end/models/ai_assistance/agents/FileAgent.ts +15 -1
  19. package/front_end/models/ai_assistance/agents/NetworkAgent.ts +15 -1
  20. package/front_end/models/ai_assistance/agents/StylingAgent.ts +24 -15
  21. package/front_end/models/ai_assistance/ai_assistance.ts +0 -2
  22. package/front_end/models/javascript_metadata/NativeFunctions.js +1 -5
  23. package/front_end/models/web_mcp/WebMCPModel.ts +187 -0
  24. package/front_end/models/web_mcp/web_mcp.ts +9 -0
  25. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +8 -1
  26. package/front_end/panels/ai_assistance/ai_assistance.ts +1 -0
  27. package/front_end/panels/ai_assistance/components/AccessibilityAgentMarkdownRenderer.ts +88 -0
  28. package/front_end/panels/ai_assistance/components/ChatMessage.ts +19 -3
  29. package/front_end/panels/ai_assistance/components/ChatView.ts +11 -4
  30. package/front_end/panels/ai_assistance/components/ExportForAgentsDialog.ts +12 -3
  31. package/front_end/panels/ai_assistance/components/chatMessage.css +10 -0
  32. package/front_end/panels/ai_assistance/components/chatView.css +0 -2
  33. package/front_end/panels/ai_assistance/components/exportForAgentsDialog.css +13 -0
  34. package/front_end/panels/application/WebMCPView.ts +126 -30
  35. package/front_end/panels/application/webMCPView.css +28 -2
  36. package/front_end/panels/elements/ElementsTreeElement.ts +1 -1
  37. package/front_end/panels/elements/StylePropertiesSection.ts +0 -4
  38. package/front_end/panels/elements/elements.ts +3 -0
  39. package/front_end/panels/elements/stylePropertiesTreeOutline.css +7 -0
  40. package/front_end/panels/lighthouse/LighthousePanel.ts +7 -1
  41. package/front_end/panels/lighthouse/LighthouseProtocolService.ts +25 -2
  42. package/front_end/panels/profiler/HeapSnapshotProxy.ts +2 -6
  43. package/front_end/panels/profiler/HeapSnapshotView.ts +7 -16
  44. package/front_end/panels/profiler/ProfileHeader.ts +1 -4
  45. package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +27 -22
  46. package/front_end/panels/timeline/TimelinePanel.ts +0 -153
  47. package/front_end/panels/timeline/TimelineTreeView.ts +11 -1
  48. package/front_end/panels/timeline/TimelineUIUtils.ts +2 -1
  49. package/front_end/third_party/chromium/README.chromium +1 -1
  50. package/front_end/ui/components/markdown_view/CodeBlock.ts +47 -1
  51. package/front_end/ui/components/markdown_view/codeBlock.css +8 -0
  52. package/front_end/ui/legacy/TabbedPane.ts +123 -3
  53. package/front_end/ui/legacy/Widget.ts +67 -28
  54. package/front_end/ui/legacy/components/source_frame/JSONView.ts +1 -1
  55. package/front_end/ui/legacy/components/utils/jsUtils.css +2 -0
  56. package/front_end/ui/legacy/infobar.css +1 -0
  57. package/front_end/ui/visual_logging/KnownContextValues.ts +0 -1
  58. package/package.json +1 -1
  59. package/front_end/core/sdk/WebMCPModel.ts +0 -159
  60. package/front_end/models/ai_assistance/ConversationHandler.ts +0 -325
@@ -53,8 +53,8 @@ function assert(condition: unknown, message: string): void {
53
53
  }
54
54
  }
55
55
 
56
- type WidgetConstructor<WidgetT extends Widget> = new (element: WidgetElement<WidgetT>) => WidgetT;
57
- type WidgetProducer<WidgetT extends Widget> = (element: WidgetElement<WidgetT>) => WidgetT;
56
+ type WidgetConstructor<WidgetT extends Widget> = new (element: HTMLElement) => WidgetT;
57
+ type WidgetProducer<WidgetT extends Widget> = (element: HTMLElement) => WidgetT;
58
58
  type WidgetFactory<WidgetT extends Widget> = WidgetConstructor<WidgetT>|WidgetProducer<WidgetT>;
59
59
  type InferWidgetTFromFactory<F> = F extends WidgetFactory<infer WidgetT>? WidgetT : never;
60
60
 
@@ -154,10 +154,13 @@ function runNextUpdate(): void {
154
154
  }
155
155
 
156
156
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
157
- const widgetConfigs = new WeakMap<WidgetElement<any>, WidgetConfig<any>>();
157
+ const widgetConfigs = new WeakMap<HTMLElement, WidgetConfig<any>>();
158
158
 
159
159
  export function registerWidgetConfig<WidgetT extends Widget>(
160
- element: WidgetElement<WidgetT>, config: WidgetConfig<WidgetT>): void {
160
+ element: HTMLElement, config: WidgetConfig<WidgetT>): void {
161
+ if (!widgetConfigs.has(element)) {
162
+ setUpLifecycleTracking(element);
163
+ }
161
164
  widgetConfigs.set(element, config);
162
165
  }
163
166
 
@@ -169,10 +172,10 @@ function instantiateWidget<WidgetT extends Widget>(element: HTMLElement, widgetC
169
172
  let newWidget: WidgetT;
170
173
  if (Widget.isPrototypeOf(widgetConfig.widgetClass)) {
171
174
  const ctor = widgetConfig.widgetClass as WidgetConstructor<WidgetT>;
172
- newWidget = new ctor(element as WidgetElement<WidgetT>);
175
+ newWidget = new ctor(element);
173
176
  } else {
174
177
  const factory = widgetConfig.widgetClass as WidgetProducer<WidgetT>;
175
- newWidget = factory(element as WidgetElement<WidgetT>);
178
+ newWidget = factory(element);
176
179
  }
177
180
 
178
181
  if (widgetConfig.widgetParams) {
@@ -182,24 +185,66 @@ function instantiateWidget<WidgetT extends Widget>(element: HTMLElement, widgetC
182
185
  return newWidget;
183
186
  }
184
187
 
188
+ function setUpLifecycleTracking<WidgetT extends Widget>(element: HTMLElement): void {
189
+ let tracker: WidgetElement<WidgetT>;
190
+ if (element instanceof WidgetElement) {
191
+ tracker = element as WidgetElement<WidgetT>;
192
+ } else {
193
+ tracker = document.createElement('devtools-widget') as WidgetElement<WidgetT>;
194
+ tracker.style.display = 'none';
195
+ element.appendChild(tracker);
196
+ }
197
+
198
+ tracker.onDisconnect = () => {
199
+ const widget = Widget.get(element);
200
+ if (widget) {
201
+ widget.setHideOnDetach();
202
+ widget.detach();
203
+ }
204
+ };
205
+ tracker.onConnect = () => {
206
+ let widget = Widget.get(element) as WidgetT;
207
+ if (!widget) {
208
+ const config = widgetConfigs.get(element);
209
+ if (!config) {
210
+ throw new Error('No widgetConfig defined');
211
+ }
212
+ widget = instantiateWidget(element, config);
213
+ }
214
+ const parent = element.parentElementOrShadowHost() as HTMLElement | null;
215
+ if (!parent) {
216
+ widget.markAsRoot();
217
+ }
218
+ widget.show(parent as HTMLElement, undefined, /* suppressOrphanWidgetError= */ true);
219
+ };
220
+ }
221
+
185
222
  export class WidgetElement<WidgetT extends Widget> extends HTMLElement {
223
+ onDisconnect?: () => void;
224
+ onConnect?: () => void;
225
+ #disconnectTimeout?: ReturnType<typeof setTimeout>;
226
+
186
227
  getWidget(): WidgetT|undefined {
187
228
  return Widget.get(this) as WidgetT | undefined;
188
229
  }
189
230
 
190
231
  connectedCallback(): void {
191
- const widget = Widget.getOrCreateWidget(this);
192
- if (!widget.element.parentElement) {
193
- widget.markAsRoot();
232
+ if (this.#disconnectTimeout) {
233
+ clearTimeout(this.#disconnectTimeout);
234
+ this.#disconnectTimeout = undefined;
235
+ }
236
+ if (this.onConnect) {
237
+ this.onConnect();
238
+ return;
194
239
  }
195
- widget.show(this.parentElement as HTMLElement, undefined, /* suppressOrphanWidgetError= */ true);
196
240
  }
197
241
 
198
242
  disconnectedCallback(): void {
199
- const widget = Widget.get(this);
200
- if (widget) {
201
- widget.setHideOnDetach();
202
- widget.detach();
243
+ if (this.onDisconnect) {
244
+ this.#disconnectTimeout = setTimeout(() => {
245
+ this.onDisconnect?.();
246
+ }, 0);
247
+ return;
203
248
  }
204
249
  }
205
250
 
@@ -224,7 +269,7 @@ export class WidgetElement<WidgetT extends Widget> extends HTMLElement {
224
269
  override removeChild<T extends Node>(child: T): T {
225
270
  const childWidget = Widget.get(child);
226
271
  if (childWidget) {
227
- childWidget.detach();
272
+ childWidget.detach(/* overrideHideOnDetach= */ true);
228
273
  return child;
229
274
  }
230
275
  return super.removeChild(child);
@@ -234,7 +279,7 @@ export class WidgetElement<WidgetT extends Widget> extends HTMLElement {
234
279
  for (const child of this.children) {
235
280
  const childWidget = Widget.get(child);
236
281
  if (childWidget) {
237
- childWidget.detach();
282
+ childWidget.detach(/* overrideHideOnDetach= */ true);
238
283
  }
239
284
  }
240
285
  super.removeChildren();
@@ -243,10 +288,9 @@ export class WidgetElement<WidgetT extends Widget> extends HTMLElement {
243
288
  override cloneNode(deep: boolean): Node {
244
289
  const clone = cloneCustomElement(this, deep) as WidgetElement<WidgetT>;
245
290
  const config = widgetConfigs.get(this);
246
- if (!config?.widgetClass) {
247
- throw new Error('No widgetClass defined');
291
+ if (config) {
292
+ registerWidgetConfig(clone, config);
248
293
  }
249
- widgetConfigs.set(clone, config);
250
294
  return clone;
251
295
  }
252
296
 
@@ -273,10 +317,8 @@ export class WidgetDirective extends Lit.Directive.Directive {
273
317
 
274
318
  override update(part: Lit.Directive.Part, [widgetClass, widgetParams]: Parameters<this['render']>): unknown {
275
319
  if (this.#partType === Lit.Directive.PartType.ELEMENT) {
276
- const element = (part as Lit.Directive.ElementPart).element;
277
- if (!(element instanceof WidgetElement)) {
278
- throw new Error('Widget directive must be used on a devtools-widget element.');
279
- }
320
+ const element = (part as Lit.Directive.ElementPart).element as HTMLElement;
321
+
280
322
  const config = widgetConfig(widgetClass, widgetParams);
281
323
  const oldConfig = widgetConfigs.get(element);
282
324
  const widget = Widget.get(element);
@@ -294,7 +336,7 @@ export class WidgetDirective extends Lit.Directive.Directive {
294
336
  widget.requestUpdate();
295
337
  }
296
338
  }
297
- widgetConfigs.set(element, config);
339
+ registerWidgetConfig(element, config);
298
340
  return Lit.nothing;
299
341
  }
300
342
  return this.render(widgetClass, widgetParams);
@@ -498,11 +540,8 @@ export class Widget {
498
540
  let config = widgetConfigs.get(element as WidgetElement<Widget>);
499
541
  if (!config) {
500
542
  config = widgetConfig(element => new Widget(element));
501
- if (element instanceof WidgetElement) {
502
- widgetConfigs.set(element, config);
503
- }
504
543
  }
505
- return instantiateWidget(element, config);
544
+ return instantiateWidget(element as WidgetElement<Widget>, config);
506
545
  }
507
546
 
508
547
  markAsRoot(): void {
@@ -300,7 +300,7 @@ export class SearchableJsonView extends UI.SearchableView.SearchableView {
300
300
  jsonView.element.tabIndex = 0;
301
301
  }
302
302
 
303
- set jsonObject(obj: Object) {
303
+ set jsonObject(obj: Object|null|undefined) {
304
304
  const jsonView = new JSONView(new ParsedJSON(obj, '', ''));
305
305
  this.#jsonView.detach();
306
306
  this.#jsonView = jsonView;
@@ -13,6 +13,8 @@
13
13
  --display-ignored-row: none;
14
14
  --display-toggle-link: var(--override-display-stack-preview-toggle-link, none);
15
15
 
16
+ user-select: text;
17
+
16
18
  & > tfoot > tr {
17
19
  font-style: italic;
18
20
  display: var(--display-toggle-link);
@@ -125,6 +125,7 @@
125
125
 
126
126
  .infobar-info-actions {
127
127
  display: flex;
128
+ flex-wrap: wrap;
128
129
  gap: var(--sys-size-5);
129
130
  }
130
131
 
@@ -3623,7 +3623,6 @@ export const knownContextValues = new Set([
3623
3623
  'show-minimal-safe-area-for-maskable-icons',
3624
3624
  'show-more',
3625
3625
  'show-network-requests',
3626
- 'show-option-to-expose-internals-in-heap-snapshot',
3627
3626
  'show-overrides',
3628
3627
  'show-paint-rects',
3629
3628
  'show-paint-rects-true',
package/package.json CHANGED
@@ -105,5 +105,5 @@
105
105
  "flat-cache": "6.1.12"
106
106
  }
107
107
  },
108
- "version": "1.0.1605390"
108
+ "version": "1.0.1606789"
109
109
  }
@@ -1,159 +0,0 @@
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
-
5
- import type * as ProtocolProxyApi from '../../generated/protocol-proxy-api.js';
6
- import type * as Protocol from '../../generated/protocol.js';
7
- import type * as Common from '../common/common.js';
8
-
9
- import {Events as RuntimeModelEvents, type ExecutionContext, RuntimeModel} from './RuntimeModel.js';
10
- import {SDKModel} from './SDKModel.js';
11
- import {Capability, type Target} from './Target.js';
12
-
13
- export const enum Events {
14
- TOOLS_ADDED = 'ToolsAdded',
15
- TOOLS_REMOVED = 'ToolsRemoved',
16
- TOOL_INVOKED = 'ToolInvoked',
17
- TOOL_RESPONDED = 'ToolResponded',
18
- }
19
-
20
- export interface Call {
21
- invocationId: string;
22
- input: string;
23
- tool: Protocol.WebMCP.Tool;
24
- result?: {
25
- status: Protocol.WebMCP.InvocationStatus,
26
- output?: unknown,
27
- errorText?: string,
28
- exception?: Protocol.Runtime.RemoteObject,
29
- };
30
- }
31
-
32
- export interface EventTypes {
33
- [Events.TOOLS_ADDED]: ReadonlyArray<Readonly<Protocol.WebMCP.Tool>>;
34
- [Events.TOOLS_REMOVED]: ReadonlyArray<Readonly<Protocol.WebMCP.Tool>>;
35
- [Events.TOOL_INVOKED]: Call;
36
- [Events.TOOL_RESPONDED]: Call;
37
- }
38
-
39
- export class WebMCPModel extends SDKModel<EventTypes> {
40
- readonly #tools = new Map<Protocol.Page.FrameId, Map<string, Protocol.WebMCP.Tool>>();
41
- readonly #calls = new Map<string, Call>();
42
- readonly agent: ProtocolProxyApi.WebMCPApi;
43
- #enabled = false;
44
-
45
- constructor(target: Target) {
46
- super(target);
47
- this.agent = target.webMCPAgent();
48
- target.registerWebMCPDispatcher(new WebMCPDispatcher(this));
49
-
50
- const runtimeModel = target.model(RuntimeModel);
51
- if (runtimeModel) {
52
- runtimeModel.addEventListener(
53
- RuntimeModelEvents.ExecutionContextDestroyed, this.#executionContextDestroyed, this);
54
- }
55
-
56
- void this.enable();
57
- }
58
-
59
- get tools(): IteratorObject<Protocol.WebMCP.Tool> {
60
- return this.#tools.values().flatMap(toolMap => toolMap.values());
61
- }
62
-
63
- get toolCalls(): Call[] {
64
- return [...this.#calls.values()];
65
- }
66
-
67
- clearCalls(): void {
68
- this.#calls.clear();
69
- }
70
-
71
- async enable(): Promise<void> {
72
- if (this.#enabled) {
73
- return;
74
- }
75
- await this.agent.invoke_enable();
76
- this.#enabled = true;
77
- }
78
-
79
- #executionContextDestroyed(event: Common.EventTarget.EventTargetEvent<ExecutionContext>): void {
80
- const executionContext = event.data;
81
- if (executionContext.isDefault && executionContext.frameId) {
82
- const frameTools = this.#tools.get(executionContext.frameId);
83
- if (frameTools) {
84
- const toolsToRemove = [...frameTools.values()];
85
- this.#tools.delete(executionContext.frameId);
86
- this.dispatchEventToListeners(Events.TOOLS_REMOVED, toolsToRemove);
87
- }
88
- }
89
- }
90
-
91
- onToolsRemoved(tools: Protocol.WebMCP.Tool[]): void {
92
- const deletedTools = tools.filter(tool => this.#tools.get(tool.frameId)?.delete(tool.name));
93
- this.dispatchEventToListeners(Events.TOOLS_REMOVED, deletedTools);
94
- }
95
-
96
- onToolsAdded(tools: Protocol.WebMCP.Tool[]): void {
97
- for (const tool of tools) {
98
- const frameTools = this.#tools.get(tool.frameId) ?? new Map();
99
- if (!this.#tools.has(tool.frameId)) {
100
- this.#tools.set(tool.frameId, frameTools);
101
- }
102
- frameTools.set(tool.name, tool);
103
- }
104
- this.dispatchEventToListeners(Events.TOOLS_ADDED, tools);
105
- }
106
-
107
- toolInvoked(params: Protocol.WebMCP.ToolInvokedEvent): void {
108
- const tool = this.#tools.get(params.frameId)?.get(params.toolName);
109
- if (!tool) {
110
- return;
111
- }
112
- const call: Call = {
113
- invocationId: params.invocationId,
114
- input: params.input,
115
- tool,
116
- };
117
- this.#calls.set(params.invocationId, call);
118
- this.dispatchEventToListeners(Events.TOOL_INVOKED, call);
119
- }
120
-
121
- toolResponded(params: Protocol.WebMCP.ToolRespondedEvent): void {
122
- const call = this.#calls.get(params.invocationId);
123
- if (!call) {
124
- return;
125
- }
126
- call.result = {
127
- status: params.status,
128
- output: params.output,
129
- errorText: params.errorText,
130
- exception: params.exception,
131
- };
132
- this.dispatchEventToListeners(Events.TOOL_RESPONDED, call);
133
- }
134
- }
135
-
136
- class WebMCPDispatcher implements ProtocolProxyApi.WebMCPDispatcher {
137
- readonly #model: WebMCPModel;
138
- constructor(model: WebMCPModel) {
139
- this.#model = model;
140
- }
141
-
142
- toolsAdded(params: Protocol.WebMCP.ToolsAddedEvent): void {
143
- this.#model.onToolsAdded(params.tools);
144
- }
145
-
146
- toolsRemoved(params: Protocol.WebMCP.ToolsRemovedEvent): void {
147
- this.#model.onToolsRemoved(params.tools);
148
- }
149
-
150
- toolInvoked(params: Protocol.WebMCP.ToolInvokedEvent): void {
151
- this.#model.toolInvoked(params);
152
- }
153
-
154
- toolResponded(params: Protocol.WebMCP.ToolRespondedEvent): void {
155
- this.#model.toolResponded(params);
156
- }
157
- }
158
-
159
- SDKModel.register(WebMCPModel, {capabilities: Capability.WEB_MCP, autostart: true});