chrome-devtools-frontend 1.0.1602543 → 1.0.1603822
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.
- package/.agents/skills/version-control/SKILL.md +17 -2
- package/front_end/core/sdk/OverlayModel.ts +13 -13
- package/front_end/core/sdk/OverlayPersistentHighlighter.ts +13 -10
- package/front_end/core/sdk/RuntimeModel.ts +5 -5
- package/front_end/core/sdk/ServiceWorkerManager.ts +4 -2
- package/front_end/core/sdk/TargetManager.ts +5 -0
- package/front_end/core/sdk/WebMCPModel.ts +6 -0
- package/front_end/generated/InspectorBackendCommands.ts +3 -0
- package/front_end/generated/protocol-mapping.d.ts +8 -0
- package/front_end/generated/protocol-proxy-api.d.ts +10 -0
- package/front_end/generated/protocol.ts +57 -0
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +16 -5
- package/front_end/models/ai_assistance/data_formatters/LighthouseFormatter.snapshot.txt +60 -9
- package/front_end/models/ai_assistance/data_formatters/LighthouseFormatter.ts +71 -15
- package/front_end/models/javascript_metadata/NativeFunctions.js +6 -2
- package/front_end/models/lighthouse/LighthouseReporterTypes.ts +10 -8
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +4 -3
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +83 -19
- package/front_end/panels/ai_assistance/components/WalkthroughView.ts +30 -10
- package/front_end/panels/ai_assistance/components/chatMessage.css +33 -7
- package/front_end/panels/ai_assistance/components/walkthroughView.css +35 -5
- package/front_end/panels/common/ThrottlingUtils.ts +46 -0
- package/front_end/panels/common/common.ts +1 -0
- package/front_end/panels/elements/ComputedStyleWidget.ts +11 -1
- package/front_end/panels/elements/StandaloneStylesContainer.ts +0 -3
- package/front_end/panels/elements/StylePropertiesSection.ts +0 -49
- package/front_end/panels/elements/StylesContainer.ts +0 -1
- package/front_end/panels/elements/StylesSidebarPane.ts +32 -7
- package/front_end/panels/mobile_throttling/NetworkThrottlingSelector.ts +14 -0
- package/front_end/panels/profiler/ProfileView.ts +0 -9
- package/front_end/panels/settings/keybindsSettingsTab.css +25 -31
- package/front_end/panels/timeline/ThirdPartyTreeView.ts +8 -0
- package/front_end/panels/timeline/TimelinePanel.ts +14 -2
- package/front_end/panels/timeline/components/FieldSettingsDialog.ts +5 -9
- package/front_end/panels/timeline/components/LiveMetricsView.ts +1 -2
- package/front_end/panels/timeline/components/OriginMap.ts +176 -159
- package/front_end/panels/timeline/components/originMap.css +4 -51
- package/front_end/panels/timeline/thirdPartyTreeView.css +6 -0
- package/front_end/panels/timeline/timeline-meta.ts +11 -0
- package/front_end/panels/timeline/utils/Helpers.ts +5 -25
- package/front_end/third_party/acorn/README.chromium +1 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/components/{list → lists}/List.ts +1 -1
- package/front_end/ui/components/{list → lists}/list.css +0 -1
- package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +3 -3
- package/package.json +1 -1
- /package/front_end/ui/components/{list → lists}/lists.ts +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: devtools-version-control
|
|
3
|
-
description: Use when managing branches, creating CLs, or handling stacked changes in the DevTools Gerrit-based workflow.
|
|
3
|
+
description: Use when managing branches, creating and uploading CLs, or handling stacked changes in the DevTools Gerrit-based workflow.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# DevTools Version Control
|
|
@@ -27,7 +27,6 @@ To update your CL after feedback or more work:
|
|
|
27
27
|
1. Make more changes.
|
|
28
28
|
2. Stage them: `git add <files>`.
|
|
29
29
|
3. Amend the commit: `git commit --amend`.
|
|
30
|
-
4. Upload: `git cl upload`.
|
|
31
30
|
|
|
32
31
|
### Stacked CLs
|
|
33
32
|
If CL B depends on CL A:
|
|
@@ -54,6 +53,22 @@ To update all your branches with the latest changes from `main` and their respec
|
|
|
54
53
|
git rebase-update
|
|
55
54
|
```
|
|
56
55
|
|
|
56
|
+
### Initial upload
|
|
57
|
+
When a CL is ready, upload it with:
|
|
58
|
+
```bash
|
|
59
|
+
git cl upload -d --commit-description="<description>"
|
|
60
|
+
```
|
|
61
|
+
* Use the same writing style as the current committer
|
|
62
|
+
* Keep line length below 72
|
|
63
|
+
* Add a "Bug: <issue number>" or "Bug: None" trailer on a separate line.
|
|
64
|
+
* Amend formatter/linter changes and fix linter issues.
|
|
65
|
+
|
|
66
|
+
### Subsequent upload
|
|
67
|
+
To upload an updated CL:
|
|
68
|
+
```bash
|
|
69
|
+
git cl upload -d -t "<one sentence patch set description>"
|
|
70
|
+
```
|
|
71
|
+
|
|
57
72
|
## Quick Reference
|
|
58
73
|
|
|
59
74
|
| Action | Command |
|
|
@@ -97,10 +97,10 @@ export class OverlayModel extends SDKModel<EventTypes> implements ProtocolProxyA
|
|
|
97
97
|
target.registerOverlayDispatcher(this);
|
|
98
98
|
this.overlayAgent = target.overlayAgent();
|
|
99
99
|
|
|
100
|
+
const settings = this.target().targetManager().settings;
|
|
100
101
|
this.#debuggerModel = target.model(DebuggerModel);
|
|
101
102
|
if (this.#debuggerModel) {
|
|
102
|
-
|
|
103
|
-
.moduleSetting('disable-paused-state-overlay')
|
|
103
|
+
settings.moduleSetting('disable-paused-state-overlay')
|
|
104
104
|
.addChangeListener(this.updatePausedInDebuggerMessage, this);
|
|
105
105
|
this.#debuggerModel.addEventListener(
|
|
106
106
|
DebuggerModelEvents.DebuggerPaused, this.updatePausedInDebuggerMessage, this);
|
|
@@ -114,21 +114,19 @@ export class OverlayModel extends SDKModel<EventTypes> implements ProtocolProxyA
|
|
|
114
114
|
this.#defaultHighlighter = new DefaultHighlighter(this);
|
|
115
115
|
this.#highlighter = this.#defaultHighlighter;
|
|
116
116
|
|
|
117
|
-
this.#showPaintRectsSetting =
|
|
118
|
-
this.#showLayoutShiftRegionsSetting =
|
|
119
|
-
|
|
120
|
-
this.#
|
|
121
|
-
this.#
|
|
122
|
-
this.#
|
|
123
|
-
this.#showScrollBottleneckRectsSetting =
|
|
124
|
-
Common.Settings.Settings.instance().moduleSetting<boolean>('show-scroll-bottleneck-rects');
|
|
117
|
+
this.#showPaintRectsSetting = settings.moduleSetting<boolean>('show-paint-rects');
|
|
118
|
+
this.#showLayoutShiftRegionsSetting = settings.moduleSetting<boolean>('show-layout-shift-regions');
|
|
119
|
+
this.#showAdHighlightsSetting = settings.moduleSetting<boolean>('show-ad-highlights');
|
|
120
|
+
this.#showDebugBordersSetting = settings.moduleSetting<boolean>('show-debug-borders');
|
|
121
|
+
this.#showFPSCounterSetting = settings.moduleSetting<boolean>('show-fps-counter');
|
|
122
|
+
this.#showScrollBottleneckRectsSetting = settings.moduleSetting<boolean>('show-scroll-bottleneck-rects');
|
|
125
123
|
|
|
126
124
|
if (!target.suspended()) {
|
|
127
125
|
void this.overlayAgent.invoke_enable();
|
|
128
126
|
void this.wireAgentToSettings();
|
|
129
127
|
}
|
|
130
128
|
|
|
131
|
-
this.#persistentHighlighter = new OverlayPersistentHighlighter(this, {
|
|
129
|
+
this.#persistentHighlighter = new OverlayPersistentHighlighter(this, settings, {
|
|
132
130
|
onGridOverlayStateChanged: ({nodeId, enabled}) => {
|
|
133
131
|
this.#domModel.nodeForId(nodeId)?.dispatchEventToListeners(DOMNodeEvents.GRID_OVERLAY_STATE_CHANGED, {enabled});
|
|
134
132
|
this.dispatchEventToListeners(Events.PERSISTENT_GRID_OVERLAY_STATE_CHANGED, {nodeId, enabled});
|
|
@@ -291,8 +289,9 @@ export class OverlayModel extends SDKModel<EventTypes> implements ProtocolProxyA
|
|
|
291
289
|
if (this.target().suspended()) {
|
|
292
290
|
return;
|
|
293
291
|
}
|
|
292
|
+
const settings = this.target().targetManager().settings;
|
|
294
293
|
const message = this.#debuggerModel && this.#debuggerModel.isPaused() &&
|
|
295
|
-
!
|
|
294
|
+
!settings.moduleSetting('disable-paused-state-overlay').get() ?
|
|
296
295
|
i18nString(UIStrings.pausedInDebugger) :
|
|
297
296
|
undefined;
|
|
298
297
|
void this.overlayAgent.invoke_setPausedInDebuggerMessage({message});
|
|
@@ -524,7 +523,8 @@ export class OverlayModel extends SDKModel<EventTypes> implements ProtocolProxyA
|
|
|
524
523
|
|
|
525
524
|
private buildHighlightConfig(mode: string|undefined = 'all', showDetailedToolip: boolean|undefined = false):
|
|
526
525
|
Protocol.Overlay.HighlightConfig {
|
|
527
|
-
const
|
|
526
|
+
const settings = this.target().targetManager().settings;
|
|
527
|
+
const showRulers = settings.moduleSetting('show-metrics-rulers').get();
|
|
528
528
|
const highlightConfig: Protocol.Overlay.HighlightConfig = {
|
|
529
529
|
showInfo: mode === 'all' || mode === 'container-outline',
|
|
530
530
|
showRulers,
|
|
@@ -33,9 +33,7 @@ export interface PersistentHighlighterCallbacks {
|
|
|
33
33
|
export class OverlayPersistentHighlighter {
|
|
34
34
|
readonly #model: OverlayModel;
|
|
35
35
|
readonly #colors = new Map<Protocol.DOM.NodeId, Common.Color.Color>();
|
|
36
|
-
readonly #persistentHighlightSetting
|
|
37
|
-
Common.Settings.Settings.instance().createLocalSetting<PersistentHighlightSettingItem[]>(
|
|
38
|
-
'persistent-highlight-setting', []);
|
|
36
|
+
readonly #persistentHighlightSetting: Common.Settings.Setting<PersistentHighlightSettingItem[]>;
|
|
39
37
|
#gridHighlights = new Map<Protocol.DOM.NodeId, Protocol.Overlay.GridHighlightConfig>();
|
|
40
38
|
#scrollSnapHighlights = new Map<Protocol.DOM.NodeId, Protocol.Overlay.ScrollSnapContainerHighlightConfig>();
|
|
41
39
|
#flexHighlights = new Map<Protocol.DOM.NodeId, Protocol.Overlay.FlexContainerHighlightConfig>();
|
|
@@ -47,18 +45,23 @@ export class OverlayPersistentHighlighter {
|
|
|
47
45
|
/**
|
|
48
46
|
* @see `front_end/core/sdk/sdk-meta.ts`
|
|
49
47
|
*/
|
|
50
|
-
readonly #showGridLineLabelsSetting
|
|
51
|
-
|
|
52
|
-
readonly #
|
|
53
|
-
readonly #
|
|
54
|
-
readonly #showGridTrackSizesSetting =
|
|
55
|
-
Common.Settings.Settings.instance().moduleSetting<boolean>('show-grid-track-sizes');
|
|
48
|
+
readonly #showGridLineLabelsSetting: Common.Settings.Setting<string>;
|
|
49
|
+
readonly #extendGridLinesSetting: Common.Settings.Setting<boolean>;
|
|
50
|
+
readonly #showGridAreasSetting: Common.Settings.Setting<boolean>;
|
|
51
|
+
readonly #showGridTrackSizesSetting: Common.Settings.Setting<boolean>;
|
|
56
52
|
|
|
57
53
|
readonly #callbacks: PersistentHighlighterCallbacks;
|
|
58
|
-
constructor(model: OverlayModel, callbacks: PersistentHighlighterCallbacks) {
|
|
54
|
+
constructor(model: OverlayModel, settings: Common.Settings.Settings, callbacks: PersistentHighlighterCallbacks) {
|
|
59
55
|
this.#model = model;
|
|
60
56
|
this.#callbacks = callbacks;
|
|
61
57
|
|
|
58
|
+
this.#persistentHighlightSetting =
|
|
59
|
+
settings.createLocalSetting<PersistentHighlightSettingItem[]>('persistent-highlight-setting', []);
|
|
60
|
+
this.#showGridLineLabelsSetting = settings.moduleSetting<string>('show-grid-line-labels');
|
|
61
|
+
this.#extendGridLinesSetting = settings.moduleSetting<boolean>('extend-grid-lines');
|
|
62
|
+
this.#showGridAreasSetting = settings.moduleSetting<boolean>('show-grid-areas');
|
|
63
|
+
this.#showGridTrackSizesSetting = settings.moduleSetting<boolean>('show-grid-track-sizes');
|
|
64
|
+
|
|
62
65
|
this.#showGridLineLabelsSetting.addChangeListener(this.onSettingChange, this);
|
|
63
66
|
this.#extendGridLinesSetting.addChangeListener(this.onSettingChange, this);
|
|
64
67
|
this.#showGridAreasSetting.addChangeListener(this.onSettingChange, this);
|
|
@@ -32,13 +32,12 @@ export class RuntimeModel extends SDKModel<EventTypes> {
|
|
|
32
32
|
this.target().registerRuntimeDispatcher(new RuntimeDispatcher(this));
|
|
33
33
|
void this.agent.invoke_enable();
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
const settings = this.target().targetManager().context.get(Common.Settings.Settings);
|
|
36
|
+
if (settings.moduleSetting('custom-formatters').get()) {
|
|
36
37
|
void this.agent.invoke_setCustomObjectFormatterEnabled({enabled: true});
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
.moduleSetting('custom-formatters')
|
|
41
|
-
.addChangeListener(this.customFormattersStateChanged.bind(this));
|
|
40
|
+
settings.moduleSetting('custom-formatters').addChangeListener(this.customFormattersStateChanged.bind(this));
|
|
42
41
|
}
|
|
43
42
|
|
|
44
43
|
static isSideEffectFailure(response: Protocol.Runtime.EvaluateResponse|EvaluationResult): boolean {
|
|
@@ -301,7 +300,8 @@ export class RuntimeModel extends SDKModel<EventTypes> {
|
|
|
301
300
|
return;
|
|
302
301
|
}
|
|
303
302
|
|
|
304
|
-
const indent =
|
|
303
|
+
const indent =
|
|
304
|
+
this.target().targetManager().context.get(Common.Settings.Settings).moduleSetting('text-editor-indent').get();
|
|
305
305
|
void object
|
|
306
306
|
.callFunctionJSON(toStringForClipboard, [{
|
|
307
307
|
value: {
|
|
@@ -77,8 +77,10 @@ export class ServiceWorkerManager extends SDKModel<EventTypes> {
|
|
|
77
77
|
target.registerServiceWorkerDispatcher(new ServiceWorkerDispatcher(this));
|
|
78
78
|
this.#agent = target.serviceWorkerAgent();
|
|
79
79
|
void this.enable();
|
|
80
|
-
this.#forceUpdateSetting =
|
|
81
|
-
|
|
80
|
+
this.#forceUpdateSetting = this.target()
|
|
81
|
+
.targetManager()
|
|
82
|
+
.context.get(Common.Settings.Settings)
|
|
83
|
+
.createSetting('service-worker-update-on-reload', false);
|
|
82
84
|
if (this.#forceUpdateSetting.get()) {
|
|
83
85
|
this.forceUpdateSettingChanged();
|
|
84
86
|
}
|
|
@@ -26,6 +26,11 @@ export class TargetManager extends Common.ObjectWrapper.ObjectWrapper<EventTypes
|
|
|
26
26
|
readonly context: Root.DevToolsContext.DevToolsContext;
|
|
27
27
|
#targets: Set<Target>;
|
|
28
28
|
readonly #observers: Set<Observer>;
|
|
29
|
+
|
|
30
|
+
get settings(): Common.Settings.Settings {
|
|
31
|
+
return this.context.get(Common.Settings.Settings);
|
|
32
|
+
}
|
|
33
|
+
|
|
29
34
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
30
35
|
#modelListeners: Platform.MapUtilities.Multimap<string|symbol|number, {
|
|
31
36
|
modelClass: SDKModelConstructor,
|
|
@@ -93,6 +93,12 @@ class WebMCPDispatcher implements ProtocolProxyApi.WebMCPDispatcher {
|
|
|
93
93
|
toolsRemoved(params: Protocol.WebMCP.ToolsRemovedEvent): void {
|
|
94
94
|
this.#model.onToolsRemoved(params.tools);
|
|
95
95
|
}
|
|
96
|
+
|
|
97
|
+
toolInvoked(): void {
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
toolResponded(): void {
|
|
101
|
+
}
|
|
96
102
|
}
|
|
97
103
|
|
|
98
104
|
SDKModel.register(WebMCPModel, {capabilities: Capability.WEB_MCP, autostart: true});
|
|
@@ -1517,8 +1517,11 @@ inspectorBackend.registerType("WebAuthn.VirtualAuthenticatorOptions", [{"name":
|
|
|
1517
1517
|
inspectorBackend.registerType("WebAuthn.Credential", [{"name": "credentialId", "type": "string", "optional": false, "description": "", "typeRef": null}, {"name": "isResidentCredential", "type": "boolean", "optional": false, "description": "", "typeRef": null}, {"name": "rpId", "type": "string", "optional": true, "description": "Relying Party ID the credential is scoped to. Must be set when adding a credential.", "typeRef": null}, {"name": "privateKey", "type": "string", "optional": false, "description": "The ECDSA P-256 private key in PKCS#8 format.", "typeRef": null}, {"name": "userHandle", "type": "string", "optional": true, "description": "An opaque byte sequence with a maximum size of 64 bytes mapping the credential to a specific user.", "typeRef": null}, {"name": "signCount", "type": "number", "optional": false, "description": "Signature counter. This is incremented by one for each successful assertion. See https://w3c.github.io/webauthn/#signature-counter", "typeRef": null}, {"name": "largeBlob", "type": "string", "optional": true, "description": "The large blob associated with the credential. See https://w3c.github.io/webauthn/#sctn-large-blob-extension", "typeRef": null}, {"name": "backupEligibility", "type": "boolean", "optional": true, "description": "Assertions returned by this credential will have the backup eligibility (BE) flag set to this value. Defaults to the authenticator's defaultBackupEligibility value.", "typeRef": null}, {"name": "backupState", "type": "boolean", "optional": true, "description": "Assertions returned by this credential will have the backup state (BS) flag set to this value. Defaults to the authenticator's defaultBackupState value.", "typeRef": null}, {"name": "userName", "type": "string", "optional": true, "description": "The credential's user.name property. Equivalent to empty if not set. https://w3c.github.io/webauthn/#dom-publickeycredentialentity-name", "typeRef": null}, {"name": "userDisplayName", "type": "string", "optional": true, "description": "The credential's user.displayName property. Equivalent to empty if not set. https://w3c.github.io/webauthn/#dom-publickeycredentialuserentity-displayname", "typeRef": null}]);
|
|
1518
1518
|
|
|
1519
1519
|
// WebMCP.
|
|
1520
|
+
inspectorBackend.registerEnum("WebMCP.InvocationStatus", {Success: "Success", Canceled: "Canceled", Error: "Error"});
|
|
1520
1521
|
inspectorBackend.registerEvent("WebMCP.toolsAdded", ["tools"]);
|
|
1521
1522
|
inspectorBackend.registerEvent("WebMCP.toolsRemoved", ["tools"]);
|
|
1523
|
+
inspectorBackend.registerEvent("WebMCP.toolInvoked", ["toolName", "frameId", "invocationId", "input"]);
|
|
1524
|
+
inspectorBackend.registerEvent("WebMCP.toolResponded", ["invocationId", "status", "output", "errorText", "exception"]);
|
|
1522
1525
|
inspectorBackend.registerCommand("WebMCP.enable", [], [], "Enables the WebMCP domain, allowing events to be sent. Enabling the domain will trigger a toolsAdded event for all currently registered tools.");
|
|
1523
1526
|
inspectorBackend.registerType("WebMCP.Annotation", [{"name": "readOnly", "type": "boolean", "optional": true, "description": "A hint indicating that the tool does not modify any state.", "typeRef": null}, {"name": "autosubmit", "type": "boolean", "optional": true, "description": "If the declarative tool was declared with the autosubmit attribute.", "typeRef": null}]);
|
|
1524
1527
|
inspectorBackend.registerType("WebMCP.Tool", [{"name": "name", "type": "string", "optional": false, "description": "Tool name.", "typeRef": null}, {"name": "description", "type": "string", "optional": false, "description": "Tool description.", "typeRef": null}, {"name": "inputSchema", "type": "object", "optional": true, "description": "Schema for the tool's input parameters.", "typeRef": null}, {"name": "annotations", "type": "object", "optional": true, "description": "Optional annotations for the tool.", "typeRef": "WebMCP.Annotation"}, {"name": "frameId", "type": "string", "optional": false, "description": "Frame identifier associated with the tool registration.", "typeRef": "Page.FrameId"}, {"name": "backendNodeId", "type": "number", "optional": true, "description": "Optional node ID for declarative tools.", "typeRef": "DOM.BackendNodeId"}, {"name": "stackTrace", "type": "object", "optional": true, "description": "The stack trace at the time of the registration.", "typeRef": "Runtime.StackTrace"}]);
|
|
@@ -938,6 +938,14 @@ export namespace ProtocolMapping {
|
|
|
938
938
|
* Event fired when tools are removed.
|
|
939
939
|
*/
|
|
940
940
|
'WebMCP.toolsRemoved': [Protocol.WebMCP.ToolsRemovedEvent];
|
|
941
|
+
/**
|
|
942
|
+
* Event fired when a tool invocation starts.
|
|
943
|
+
*/
|
|
944
|
+
'WebMCP.toolInvoked': [Protocol.WebMCP.ToolInvokedEvent];
|
|
945
|
+
/**
|
|
946
|
+
* Event fired when a tool invocation completes or fails.
|
|
947
|
+
*/
|
|
948
|
+
'WebMCP.toolResponded': [Protocol.WebMCP.ToolRespondedEvent];
|
|
941
949
|
/**
|
|
942
950
|
* Fired when breakpoint is resolved to an actual script and location.
|
|
943
951
|
* Deprecated in favor of `resolvedBreakpoints` in the `scriptParsed` event.
|
|
@@ -4872,6 +4872,16 @@ declare namespace ProtocolProxyApi {
|
|
|
4872
4872
|
*/
|
|
4873
4873
|
toolsRemoved(params: Protocol.WebMCP.ToolsRemovedEvent): void;
|
|
4874
4874
|
|
|
4875
|
+
/**
|
|
4876
|
+
* Event fired when a tool invocation starts.
|
|
4877
|
+
*/
|
|
4878
|
+
toolInvoked(params: Protocol.WebMCP.ToolInvokedEvent): void;
|
|
4879
|
+
|
|
4880
|
+
/**
|
|
4881
|
+
* Event fired when a tool invocation completes or fails.
|
|
4882
|
+
*/
|
|
4883
|
+
toolResponded(params: Protocol.WebMCP.ToolRespondedEvent): void;
|
|
4884
|
+
|
|
4875
4885
|
}
|
|
4876
4886
|
|
|
4877
4887
|
export interface DebuggerApi {
|
|
@@ -20602,6 +20602,15 @@ export namespace WebMCP {
|
|
|
20602
20602
|
autosubmit?: boolean;
|
|
20603
20603
|
}
|
|
20604
20604
|
|
|
20605
|
+
/**
|
|
20606
|
+
* Represents the status of a tool invocation.
|
|
20607
|
+
*/
|
|
20608
|
+
export const enum InvocationStatus {
|
|
20609
|
+
Success = 'Success',
|
|
20610
|
+
Canceled = 'Canceled',
|
|
20611
|
+
Error = 'Error',
|
|
20612
|
+
}
|
|
20613
|
+
|
|
20605
20614
|
/**
|
|
20606
20615
|
* Definition of a tool that can be invoked.
|
|
20607
20616
|
*/
|
|
@@ -20655,6 +20664,54 @@ export namespace WebMCP {
|
|
|
20655
20664
|
*/
|
|
20656
20665
|
tools: Tool[];
|
|
20657
20666
|
}
|
|
20667
|
+
|
|
20668
|
+
/**
|
|
20669
|
+
* Event fired when a tool invocation starts.
|
|
20670
|
+
*/
|
|
20671
|
+
export interface ToolInvokedEvent {
|
|
20672
|
+
/**
|
|
20673
|
+
* Name of the tool to invoke.
|
|
20674
|
+
*/
|
|
20675
|
+
toolName: string;
|
|
20676
|
+
/**
|
|
20677
|
+
* Frame id
|
|
20678
|
+
*/
|
|
20679
|
+
frameId: Page.FrameId;
|
|
20680
|
+
/**
|
|
20681
|
+
* Invocation identifier.
|
|
20682
|
+
*/
|
|
20683
|
+
invocationId: string;
|
|
20684
|
+
/**
|
|
20685
|
+
* The input parameters used for the invocation.
|
|
20686
|
+
*/
|
|
20687
|
+
input: string;
|
|
20688
|
+
}
|
|
20689
|
+
|
|
20690
|
+
/**
|
|
20691
|
+
* Event fired when a tool invocation completes or fails.
|
|
20692
|
+
*/
|
|
20693
|
+
export interface ToolRespondedEvent {
|
|
20694
|
+
/**
|
|
20695
|
+
* Invocation identifier.
|
|
20696
|
+
*/
|
|
20697
|
+
invocationId: string;
|
|
20698
|
+
/**
|
|
20699
|
+
* Status of the invocation.
|
|
20700
|
+
*/
|
|
20701
|
+
status: InvocationStatus;
|
|
20702
|
+
/**
|
|
20703
|
+
* Output or error delivered as delivered to the agent. Missing if `status` is anything other than Success.
|
|
20704
|
+
*/
|
|
20705
|
+
output?: any;
|
|
20706
|
+
/**
|
|
20707
|
+
* Error text for protocol users.
|
|
20708
|
+
*/
|
|
20709
|
+
errorText?: string;
|
|
20710
|
+
/**
|
|
20711
|
+
* The exception object, if the javascript tool threw an error>
|
|
20712
|
+
*/
|
|
20713
|
+
exception?: Runtime.RemoteObject;
|
|
20714
|
+
}
|
|
20658
20715
|
}
|
|
20659
20716
|
|
|
20660
20717
|
/**
|
|
@@ -82,9 +82,9 @@ Your primary goal is to provide actionable advice to web developers about their
|
|
|
82
82
|
|
|
83
83
|
You will be provided a summary of a trace: some performance metrics; the most critical network requests; a bottom-up call graph summary; and a brief overview of available insights. Each insight has information about potential performance issues with the page.
|
|
84
84
|
|
|
85
|
-
Don't mention anything about an insight without first getting more data about it by calling \`getInsightDetails\`.
|
|
85
|
+
Don't mention anything about an insight or the actual LCP element without first getting more data about it by calling \`getInsightDetails\`.
|
|
86
86
|
|
|
87
|
-
You have
|
|
87
|
+
You have functions available to learn more about the trace. Use these to confirm hypotheses, or to further explore the trace when diagnosing performance issues.
|
|
88
88
|
|
|
89
89
|
${annotationsEnabled ? greenDevAdditionalAnnotationsFunction : ''}
|
|
90
90
|
|
|
@@ -106,14 +106,15 @@ Note: if the user asks a specific question about the trace (such as "What is my
|
|
|
106
106
|
### Step 1: Determine a performance problem to investigate
|
|
107
107
|
|
|
108
108
|
- With help from the user, determine what performance problem to focus on.
|
|
109
|
-
- If the user is not specific about what problem to investigate, help them by doing a
|
|
109
|
+
- If the user is not specific about what problem to investigate, help them by doing a investigation yourself. Present to the user options with 1-sentence summaries. Mention what performance metrics each option impacts. Call as many functions and confirm the data thoroughly: never present an option without being certain it is a real performance issue. Don't suggest solutions yet.
|
|
110
110
|
- Rank the options from most impactful to least impactful, and present them to the user in that order.
|
|
111
|
-
- Don't present more than
|
|
111
|
+
- Don't present more than 2 options.
|
|
112
112
|
- Once a performance problem has been identified for investigation, move on to step 2.
|
|
113
113
|
|
|
114
114
|
### Step 2: Suggest solutions
|
|
115
115
|
|
|
116
|
-
- Suggest
|
|
116
|
+
- Suggest solutions to remedy the identified performance problem. Be as specific as possible, using data from the trace via the provided functions to back up everything you say. You should prefer specific solutions, but absent any specific solution you may suggest general solutions (such as from an insight's documentation links).
|
|
117
|
+
- If you are unsure, be honest and present information that can be helpful for further investigation.
|
|
117
118
|
- A good first step to discover solutions is to consider the insights, but you should also validate all potential advice by analyzing the trace until you are confident about the root cause of a performance issue.
|
|
118
119
|
|
|
119
120
|
## Guidelines
|
|
@@ -145,6 +146,16 @@ Adhere to the following critical requirements:
|
|
|
145
146
|
- Do not mention that you are an AI, or refer to yourself in the third person. You are simulating a performance expert.
|
|
146
147
|
- If asked about sensitive topics (religion, race, politics, sexuality, gender, etc.), respond with: "My expertise is limited to website performance analysis. I cannot provide information on that topic.".
|
|
147
148
|
- Do not provide answers on non-web-development topics, such as legal, financial, medical, or personal advice.
|
|
149
|
+
- Use the precision of Strunk & White, the brevity of Hemingway, and the simple clarity of Vonnegut. Don't add repeated information, and keep the whole answer short.
|
|
150
|
+
|
|
151
|
+
## Response Structure
|
|
152
|
+
|
|
153
|
+
- If available, point out the root cause of the problem. It may be a bullet point list.
|
|
154
|
+
- Example: "**Root Cause**: The page is slow because of [reason]."
|
|
155
|
+
- if applicable, list actionable solution suggestion(s) in order of impact:
|
|
156
|
+
- Example: "**Suggestions**:
|
|
157
|
+
- [Suggestion 1]
|
|
158
|
+
- [Suggestion 2]
|
|
148
159
|
`;
|
|
149
160
|
};
|
|
150
161
|
|
|
@@ -39,9 +39,18 @@ The following audits in this category have a score below 90 and may need attenti
|
|
|
39
39
|
- **Table Audit**: 50
|
|
40
40
|
* Audit with a table
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
- Item:
|
|
43
|
+
* **URL**: https://example.com/script.js
|
|
44
|
+
* **Wasted Bytes**: 1 kB
|
|
45
|
+
* **Node**: div.main
|
|
46
|
+
* **Node path**: 1,HTML,1,BODY,5,DIV
|
|
47
|
+
* **Location**: https://example.com/script.js:10:5
|
|
48
|
+
- Item:
|
|
49
|
+
* **URL**: https://example.com/style.css
|
|
50
|
+
* **Wasted Bytes**: 512 B
|
|
51
|
+
* **Node**: body > p
|
|
52
|
+
* **Node path**: 1,HTML,1,BODY,10,P
|
|
53
|
+
* **Location**: https://example.com/style.css
|
|
45
54
|
=== end content
|
|
46
55
|
|
|
47
56
|
Title: LighthouseFormatter formats opportunity details
|
|
@@ -53,8 +62,9 @@ The following audits in this category have a score below 90 and may need attenti
|
|
|
53
62
|
* Audit with an opportunity
|
|
54
63
|
|
|
55
64
|
Potential savings: 500ms, Potential savings: 2048 bytes
|
|
56
|
-
|
|
57
|
-
|
|
65
|
+
- Item:
|
|
66
|
+
* **URL**: https://example.com/large-script.js
|
|
67
|
+
* **Wasted Bytes**: 2 kB
|
|
58
68
|
=== end content
|
|
59
69
|
|
|
60
70
|
Title: LighthouseFormatter formats table details with summary
|
|
@@ -67,8 +77,8 @@ The following audits in this category have a score below 90 and may need attenti
|
|
|
67
77
|
|
|
68
78
|
Wasted time: 100ms
|
|
69
79
|
Wasted bytes: 512
|
|
70
|
-
|
|
71
|
-
|
|
80
|
+
- Item:
|
|
81
|
+
* **Text**: Some detail
|
|
72
82
|
=== end content
|
|
73
83
|
|
|
74
84
|
Title: LighthouseFormatter formats landmark-one-main audit with node explanation
|
|
@@ -79,6 +89,47 @@ The following audits in this category have a score below 90 and may need attenti
|
|
|
79
89
|
- **Document does not have a main landmark.**: 0
|
|
80
90
|
* One main landmark helps screen reader users navigate a web page. [Learn more about landmarks](https://dequeuniversity.com/rules/axe/4.11/landmark-one-main).
|
|
81
91
|
|
|
82
|
-
|
|
83
|
-
|
|
92
|
+
- Item:
|
|
93
|
+
* **Failing Elements**: html
|
|
94
|
+
* **Failing Elements path**: 1,HTML
|
|
95
|
+
* **Failing Elements explanation**: Fix all of the following: Document does not have a main landmark
|
|
96
|
+
=== end content
|
|
97
|
+
|
|
98
|
+
Title: LighthouseFormatter formats table details with subItems
|
|
99
|
+
Content:
|
|
100
|
+
# Audits for Performance
|
|
101
|
+
|
|
102
|
+
The following audits in this category have a score below 90 and may need attention:
|
|
103
|
+
- **SubItems Audit**: 50
|
|
104
|
+
* Audit with subItems
|
|
105
|
+
|
|
106
|
+
- Item:
|
|
107
|
+
* **URL**: https://example.com/script.js
|
|
108
|
+
* Failed to load sourcemap
|
|
109
|
+
* Another error
|
|
110
|
+
* **Map URL**: https://example.com/script.js.map
|
|
111
|
+
=== end content
|
|
112
|
+
|
|
113
|
+
Title: LighthouseFormatter formats image-delivery-insight audit from realistic data
|
|
114
|
+
Content:
|
|
115
|
+
# Audits for Performance
|
|
116
|
+
|
|
117
|
+
The following audits in this category have a score below 90 and may need attention:
|
|
118
|
+
- **Improve image delivery**: 50 (Est savings of 35 KiB)
|
|
119
|
+
* Reducing the download time of images can improve the perceived load time of the page and LCP. [Learn more about optimizing image size](https://developer.chrome.com/docs/performance/insights/image-delivery)
|
|
120
|
+
|
|
121
|
+
- Item:
|
|
122
|
+
* **node**: div.devsite-landing-row-item-media > figure.devsite-landing-row-item-image > picture > img
|
|
123
|
+
* **node path**: 1,HTML,1,BODY,2,SECTION,6,SECTION,0,MAIN,1,DEVSITE-CONTENT,0,ARTICLE,4,DIV,0,SECTION,0,DIV,0,DIV,0,DIV,0,DIV,0,FIGURE,0,PICTURE,0,IMG
|
|
124
|
+
* **URL**: https://web.dev/static/images/home-blue_856.png
|
|
125
|
+
* This image file is larger than it needs to be (856x505) for its displayed dimensions (568x335). Use responsive images to reduce the image download size.
|
|
126
|
+
* **Resource Size**: 33.3 kB
|
|
127
|
+
* **Est Savings**: 18.6 kB
|
|
128
|
+
- Item:
|
|
129
|
+
* **node**: figure.devsite-landing-row-item-image > a > picture > img
|
|
130
|
+
* **node path**: 1,HTML,1,BODY,2,SECTION,6,SECTION,0,MAIN,1,DEVSITE-CONTENT,0,ARTICLE,4,DIV,1,SECTION,0,DIV,0,DIV,3,DIV,0,DIV,0,FIGURE,0,A,0,PICTURE,0,IMG
|
|
131
|
+
* **URL**: https://web.dev/static/identity/image/hero-identity_480.png
|
|
132
|
+
* This image file is larger than it needs to be (1296x881) for its displayed dimensions (632x430). Use responsive images to reduce the image download size.
|
|
133
|
+
* **Resource Size**: 22.2 kB
|
|
134
|
+
* **Est Savings**: 16.9 kB
|
|
84
135
|
=== end content
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
import type * as LHModel from '../../lighthouse/lighthouse.js';
|
|
6
6
|
|
|
7
|
+
import {bytes, millis} from './UnitFormatters.js';
|
|
8
|
+
|
|
7
9
|
/**
|
|
8
10
|
* A formatter that takes a raw Lighthouse report JSON and creates a markdown
|
|
9
11
|
* summary for an AI Agent.
|
|
@@ -120,37 +122,74 @@ export class LighthouseFormatter {
|
|
|
120
122
|
}
|
|
121
123
|
}
|
|
122
124
|
|
|
123
|
-
#formatTable(headings: LHModel.ReporterTypes.TableHeadingJSON[], items:
|
|
125
|
+
#formatTable(headings: LHModel.ReporterTypes.TableHeadingJSON[], items: LHModel.ReporterTypes.TableItem[]): string {
|
|
124
126
|
const lines: string[] = [];
|
|
125
|
-
|
|
127
|
+
|
|
126
128
|
for (const item of items) {
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
+
const itemLines: string[] = [];
|
|
130
|
+
for (const heading of headings) {
|
|
131
|
+
const value = item[heading.key] as LHModel.ReporterTypes.TableItemValue;
|
|
132
|
+
const formattedValues = this.#formatTableValues(value, heading.valueType);
|
|
133
|
+
for (const {labelSuffix, value: v} of formattedValues) {
|
|
134
|
+
const baseLabel = heading.label || heading.key;
|
|
135
|
+
const label = labelSuffix ? `${baseLabel} ${labelSuffix}` : baseLabel;
|
|
136
|
+
itemLines.push(` * **${label}**: ${v}`);
|
|
137
|
+
}
|
|
138
|
+
const subItems = item.subItems;
|
|
139
|
+
// subItems can technically be a string (TableItemValue), but we
|
|
140
|
+
// only care about it here if it's a SubItemsJSON (type:
|
|
141
|
+
// 'subitems'), which represents a nested table of values.
|
|
142
|
+
if (subItems && typeof subItems === 'object' && 'type' in subItems && subItems.type === 'subitems' &&
|
|
143
|
+
heading.subItemsHeading) {
|
|
144
|
+
for (const subItem of subItems.items) {
|
|
145
|
+
const subValue = subItem[heading.subItemsHeading.key] as LHModel.ReporterTypes.TableItemValue;
|
|
146
|
+
// Skip sub-item values that are identical to the main item's value
|
|
147
|
+
// for the same heading to avoid redundant output (e.g. if both
|
|
148
|
+
// show the same "Est Savings" value).
|
|
149
|
+
if (subValue === value) {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
const formattedSubValues = this.#formatTableValues(subValue, heading.subItemsHeading.valueType);
|
|
153
|
+
for (const {value: v} of formattedSubValues) {
|
|
154
|
+
itemLines.push(` * ${v}`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (itemLines.length > 0) {
|
|
160
|
+
lines.push(`- Item:`);
|
|
161
|
+
lines.push(...itemLines);
|
|
162
|
+
}
|
|
129
163
|
}
|
|
130
164
|
return lines.join('\n');
|
|
131
165
|
}
|
|
132
166
|
|
|
133
|
-
#
|
|
167
|
+
#formatTableValues(value: LHModel.ReporterTypes.TableItemValue|undefined, valueType?: string): Array<{
|
|
168
|
+
value: string,
|
|
169
|
+
labelSuffix?: string,
|
|
170
|
+
}> {
|
|
134
171
|
if (value === undefined || value === null) {
|
|
135
|
-
return
|
|
172
|
+
return [];
|
|
136
173
|
}
|
|
137
174
|
if (typeof value === 'string' || typeof value === 'number') {
|
|
138
|
-
return
|
|
175
|
+
return [{value: this.#formatValue(value, valueType)}];
|
|
139
176
|
}
|
|
140
177
|
if (typeof value === 'object' && 'type' in value) {
|
|
141
178
|
switch (value.type) {
|
|
142
179
|
case 'node': {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
180
|
+
const results = [];
|
|
181
|
+
const label = value.nodeLabel || value.selector || value.snippet || '(node)';
|
|
182
|
+
results.push({value: label});
|
|
183
|
+
if (value.selector && value.selector !== label) {
|
|
184
|
+
results.push({labelSuffix: 'selector', value: value.selector});
|
|
146
185
|
}
|
|
147
186
|
if (value.path) {
|
|
148
|
-
|
|
187
|
+
results.push({labelSuffix: 'path', value: value.path});
|
|
149
188
|
}
|
|
150
189
|
if (value.explanation) {
|
|
151
|
-
|
|
190
|
+
results.push({labelSuffix: 'explanation', value: value.explanation.replace(/\n/g, ' ')});
|
|
152
191
|
}
|
|
153
|
-
return
|
|
192
|
+
return results;
|
|
154
193
|
}
|
|
155
194
|
case 'source-location': {
|
|
156
195
|
const parts = [];
|
|
@@ -163,10 +202,27 @@ export class LighthouseFormatter {
|
|
|
163
202
|
if (value.column) {
|
|
164
203
|
parts.push(String(value.column));
|
|
165
204
|
}
|
|
166
|
-
return parts.join(':');
|
|
205
|
+
return [{value: parts.join(':')}];
|
|
167
206
|
}
|
|
168
207
|
}
|
|
169
208
|
}
|
|
170
|
-
return
|
|
209
|
+
return [];
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
#formatValue(value: string|number, valueType?: string): string {
|
|
213
|
+
if (typeof value === 'string') {
|
|
214
|
+
return value;
|
|
215
|
+
}
|
|
216
|
+
switch (valueType) {
|
|
217
|
+
case 'bytes': {
|
|
218
|
+
return bytes(value);
|
|
219
|
+
}
|
|
220
|
+
case 'timespanMs':
|
|
221
|
+
case 'ms': {
|
|
222
|
+
return millis(value);
|
|
223
|
+
}
|
|
224
|
+
default:
|
|
225
|
+
return String(value);
|
|
226
|
+
}
|
|
171
227
|
}
|
|
172
228
|
}
|