lighthouse 13.0.3 → 13.2.0
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/CONTRIBUTING.md +1 -1
- package/cli/bin.js +5 -0
- package/cli/test/smokehouse/__snapshots__/report-assert-test.js.snap +10 -10
- package/cli/test/smokehouse/config/exclusions.js +44 -0
- package/cli/test/smokehouse/frontends/smokehouse-bin.js +5 -4
- package/cli/test/smokehouse/lighthouse-runners/devtools-mcp.d.ts +14 -0
- package/cli/test/smokehouse/lighthouse-runners/devtools-mcp.js +141 -0
- package/core/audits/accessibility/autocomplete-valid.d.ts +10 -0
- package/core/audits/accessibility/autocomplete-valid.js +44 -0
- package/core/audits/accessibility/presentation-role-conflict.d.ts +10 -0
- package/core/audits/accessibility/presentation-role-conflict.js +46 -0
- package/core/audits/accessibility/svg-img-alt.d.ts +10 -0
- package/core/audits/accessibility/svg-img-alt.js +44 -0
- package/core/audits/agentic/agent-accessibility-tree.d.ts +19 -0
- package/core/audits/agentic/agent-accessibility-tree.js +115 -0
- package/core/audits/agentic/llms-txt.d.ts +20 -0
- package/core/audits/agentic/llms-txt.js +111 -0
- package/core/audits/baseline.d.ts +25 -0
- package/core/audits/baseline.js +190 -0
- package/core/audits/insights/insight-audit.d.ts +2 -2
- package/core/audits/insights/insight-audit.js +16 -6
- package/core/audits/layout-shifts.js +1 -1
- package/core/audits/server-response-time.js +3 -3
- package/core/audits/webmcp-form-coverage.d.ts +16 -0
- package/core/audits/webmcp-form-coverage.js +90 -0
- package/core/audits/webmcp-registered-tools.d.ts +21 -0
- package/core/audits/webmcp-registered-tools.js +149 -0
- package/core/audits/webmcp-schema-validity.d.ts +22 -0
- package/core/audits/webmcp-schema-validity.js +141 -0
- package/core/computed/document-urls.js +4 -2
- package/core/computed/main-resource.js +5 -3
- package/core/computed/metrics/lantern-metric.js +4 -4
- package/core/computed/metrics/lcp-breakdown.js +1 -1
- package/core/computed/metrics/time-to-first-byte.js +1 -1
- package/core/computed/navigation-insights.js +2 -1
- package/core/computed/network-analysis.js +3 -1
- package/core/config/agentic-browsing-config.d.ts +12 -0
- package/core/config/agentic-browsing-config.js +73 -0
- package/core/config/default-config.js +8 -0
- package/core/gather/driver/wait-for-condition.js +11 -1
- package/core/gather/gatherers/accessibility.js +5 -1
- package/core/gather/gatherers/agentic/llms-txt.d.ts +10 -0
- package/core/gather/gatherers/agentic/llms-txt.js +28 -0
- package/core/gather/gatherers/inputs.js +2 -0
- package/core/gather/gatherers/meta-elements.js +1 -1
- package/core/gather/gatherers/trace-elements.js +1 -1
- package/core/gather/gatherers/trace.js +3 -0
- package/core/gather/gatherers/webmcp-schema.d.ts +25 -0
- package/core/gather/gatherers/webmcp-schema.js +105 -0
- package/core/gather/gatherers/webmcp.d.ts +58 -0
- package/core/gather/gatherers/webmcp.js +159 -0
- package/core/index.d.ts +1 -0
- package/core/index.js +1 -0
- package/core/lib/baseline/web-features-metadata.json +3 -0
- package/core/lib/cdt/generated/SourceMap.js +2 -2
- package/core/lib/deprecations-strings.d.ts +169 -89
- package/core/lib/deprecations-strings.js +119 -24
- package/core/lib/navigation-error.js +5 -2
- package/core/lib/network-recorder.js +2 -1
- package/core/lib/page-functions.d.ts +3 -3
- package/core/lib/page-functions.js +11 -4
- package/core/lib/tracehouse/trace-processor.d.ts +5 -4
- package/core/lib/tracehouse/trace-processor.js +85 -19
- package/core/runner.js +3 -0
- package/core/scoring.d.ts +25 -0
- package/dist/report/bundle.esm.js +31 -3
- package/dist/report/flow.js +32 -4
- package/dist/report/standalone.js +32 -4
- package/flow-report/src/summary/category.tsx +1 -1
- package/package.json +12 -11
- package/report/assets/styles.css +28 -0
- package/report/renderer/category-renderer.js +1 -1
- package/report/renderer/components.js +1 -1
- package/report/renderer/details-renderer.d.ts +5 -0
- package/report/renderer/details-renderer.js +16 -0
- package/report/renderer/report-utils.d.ts +2 -1
- package/report/renderer/report-utils.js +7 -2
- package/report/types/report-renderer.d.ts +1 -1
- package/report/types/report-result.d.ts +1 -1
- package/shared/localization/locales/ar-XB.json +72 -36
- package/shared/localization/locales/ar.json +72 -36
- package/shared/localization/locales/bg.json +72 -36
- package/shared/localization/locales/ca.json +72 -36
- package/shared/localization/locales/cs.json +72 -36
- package/shared/localization/locales/da.json +74 -38
- package/shared/localization/locales/de.json +72 -36
- package/shared/localization/locales/el.json +73 -37
- package/shared/localization/locales/en-GB.json +74 -38
- package/shared/localization/locales/en-US.json +257 -17
- package/shared/localization/locales/en-XL.json +257 -17
- package/shared/localization/locales/es-419.json +72 -36
- package/shared/localization/locales/es.json +73 -37
- package/shared/localization/locales/fi.json +72 -36
- package/shared/localization/locales/fil.json +74 -38
- package/shared/localization/locales/fr.json +162 -126
- package/shared/localization/locales/he.json +74 -38
- package/shared/localization/locales/hi.json +73 -37
- package/shared/localization/locales/hr.json +72 -36
- package/shared/localization/locales/hu.json +73 -37
- package/shared/localization/locales/id.json +74 -38
- package/shared/localization/locales/it.json +72 -36
- package/shared/localization/locales/ja.json +72 -36
- package/shared/localization/locales/ko.json +72 -36
- package/shared/localization/locales/lt.json +72 -36
- package/shared/localization/locales/lv.json +72 -36
- package/shared/localization/locales/nl.json +73 -37
- package/shared/localization/locales/no.json +72 -36
- package/shared/localization/locales/pl.json +72 -36
- package/shared/localization/locales/pt-PT.json +72 -36
- package/shared/localization/locales/pt.json +74 -38
- package/shared/localization/locales/ro.json +72 -36
- package/shared/localization/locales/ru.json +72 -36
- package/shared/localization/locales/sk.json +72 -36
- package/shared/localization/locales/sl.json +72 -36
- package/shared/localization/locales/sr-Latn.json +73 -37
- package/shared/localization/locales/sr.json +73 -37
- package/shared/localization/locales/sv.json +75 -39
- package/shared/localization/locales/ta.json +73 -37
- package/shared/localization/locales/te.json +72 -36
- package/shared/localization/locales/th.json +73 -37
- package/shared/localization/locales/tr.json +72 -36
- package/shared/localization/locales/uk.json +72 -36
- package/shared/localization/locales/vi.json +74 -38
- package/shared/localization/locales/zh-HK.json +72 -36
- package/shared/localization/locales/zh-TW.json +74 -38
- package/shared/localization/locales/zh.json +75 -39
- package/tsconfig.json +2 -0
- package/types/artifacts.d.ts +66 -30
- package/types/audit.d.ts +1 -1
- package/types/config.d.ts +2 -1
- package/types/gatherer.d.ts +1 -1
- package/types/lhr/audit-details.d.ts +10 -4
- package/types/lhr/flow-result.d.ts +1 -1
- package/types/lhr/lhr.d.ts +12 -1
- package/types/lhr/treemap.d.ts +1 -1
- package/types/protocol.d.ts +1 -1
- package/types/puppeteer.d.ts +1 -1
- package/types/user-flow.d.ts +1 -1
- package/types/utility-types.d.ts +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// auto-generated by build/build-cdt-strings.js
|
|
2
2
|
/* eslint-disable */
|
|
3
|
-
// Copyright
|
|
3
|
+
// Copyright 2026 The Chromium Authors
|
|
4
4
|
// Use of this source code is governed by a BSD-style license that can be
|
|
5
5
|
// found in the LICENSE file.
|
|
6
6
|
|
|
@@ -8,6 +8,10 @@
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
export const UIStrings = {
|
|
11
|
+
/**
|
|
12
|
+
* @description This warning occurs when the website uses Attribution Reporting.
|
|
13
|
+
*/
|
|
14
|
+
AttributionReporting: "Attribution Reporting is deprecated and will be removed. See https://goo.gle/ps-status for details.",
|
|
11
15
|
/**
|
|
12
16
|
* @description We show this warning when 1) an 'authorization' header is attached to the request by scripts, 2) there is no 'authorization' in the 'access-control-allow-headers' header in the response, and 3) there is a wildcard symbol ('*') in the 'access-control-allow-header' header in the response. This is allowed now, but we're planning to reject such responses and require responses to have an 'access-control-allow-headers' containing 'authorization'.
|
|
13
17
|
*/
|
|
@@ -28,10 +32,6 @@ export const UIStrings = {
|
|
|
28
32
|
* @description This warning occurs when the website attempts to invoke the deprecated `chrome.loadTimes().wasAlternateProtocolAvailable` API.
|
|
29
33
|
*/
|
|
30
34
|
ChromeLoadTimesWasAlternateProtocolAvailable: "`chrome.loadTimes()` is deprecated, instead use standardized API: `nextHopProtocol` in Navigation Timing 2.",
|
|
31
|
-
/**
|
|
32
|
-
* @description This warning occurs when the browser attempts to store a cookie containing a banned character. Rather than the cookie string being truncated at the banned character, the entire cookie will be rejected now.
|
|
33
|
-
*/
|
|
34
|
-
CookieWithTruncatingChar: "Cookies containing a `(0|r|n)` character will be rejected instead of truncated.",
|
|
35
35
|
/**
|
|
36
36
|
* @description This warning occurs when a frame accesses another frame's data after having set `document.domain` without having set the `Origin-Agent-Cluster` http header. This is a companion warning to `documentDomainSettingWithoutOriginAgentClusterHeader`, where that warning occurs when `document.domain` is set, and this warning occurs when an access has been made, based on that previous `document.domain` setting.
|
|
37
37
|
*/
|
|
@@ -56,6 +56,22 @@ export const UIStrings = {
|
|
|
56
56
|
* @description Warning displayed to developers when a data: URL is assigned to SVGUseElement to let them know that the support is deprecated.
|
|
57
57
|
*/
|
|
58
58
|
DataUrlInSvgUse: "Support for data: URLs in SVGUseElement is deprecated and it will be removed in the future.",
|
|
59
|
+
/**
|
|
60
|
+
* @description Warning displayed to developers when document.createEvent() is called with 'KeyboardEvents', which is a non-standard event interface that will be removed.
|
|
61
|
+
*/
|
|
62
|
+
DocumentCreateEventKeyboardEvents: "document.createEvent('KeyboardEvents') is deprecated and will be removed. Use `new KeyboardEvent()` instead.",
|
|
63
|
+
/**
|
|
64
|
+
* @description Warning displayed to developers when document.createEvent() is called with 'TransitionEvent', which is a non-standard event interface that will be removed.
|
|
65
|
+
*/
|
|
66
|
+
DocumentCreateEventTransitionEvent: "document.createEvent('TransitionEvent') is deprecated and will be removed. Use `new TransitionEvent()` instead.",
|
|
67
|
+
/**
|
|
68
|
+
* @description Translation is not needed, this will never be exposed in production code.
|
|
69
|
+
*/
|
|
70
|
+
ExampleBrowserProcessDeprecation: "This is an example for showing the code required for a browser process reported deprecation.",
|
|
71
|
+
/**
|
|
72
|
+
* @description A deprecation warning shown in the DevTools Issues tab. It's shown when one of the Protected Audience APIs like `navigator.joinAdInterestGroup`, `navigator.getInterestGroupAdAuctionData` or `navigator.runAdAuction` are called.
|
|
73
|
+
*/
|
|
74
|
+
Fledge: "The Protected Audience API is deprecated and will be removed in a future release.",
|
|
59
75
|
/**
|
|
60
76
|
* @description Warning displayed to developers when the Geolocation API is used from an insecure origin (one that isn't localhost or doesn't use HTTPS) to notify them that this use is no longer supported.
|
|
61
77
|
*/
|
|
@@ -89,17 +105,37 @@ export const UIStrings = {
|
|
|
89
105
|
*/
|
|
90
106
|
IntlV8BreakIterator: "`Intl.v8BreakIterator` is deprecated. Please use `Intl.Segmenter` instead.",
|
|
91
107
|
/**
|
|
92
|
-
* @description
|
|
108
|
+
* @description Warning for using deprecated 'inputQuota' attribute.
|
|
93
109
|
*/
|
|
94
|
-
|
|
110
|
+
LanguageModel_InputQuota: "LanguageModel.inputQuota is deprecated. Please use LanguageModel.contextWindow instead. This alias is only available in extensions.",
|
|
95
111
|
/**
|
|
96
|
-
* @description
|
|
112
|
+
* @description Warning for using deprecated 'inputUsage' attribute.
|
|
97
113
|
*/
|
|
98
|
-
|
|
114
|
+
LanguageModel_InputUsage: "LanguageModel.inputUsage is deprecated. Please use LanguageModel.contextUsage instead. This alias is only available in extensions.",
|
|
99
115
|
/**
|
|
100
|
-
* @description
|
|
116
|
+
* @description Warning for using deprecated 'measureInputUsage' method.
|
|
101
117
|
*/
|
|
102
|
-
|
|
118
|
+
LanguageModel_MeasureInputUsage: "LanguageModel.measureInputUsage() is deprecated. Please use LanguageModel.measureContextUsage() instead. This alias is only available in extensions.",
|
|
119
|
+
/**
|
|
120
|
+
* @description Warning for using deprecated 'onquotaoverflow' event handler.
|
|
121
|
+
*/
|
|
122
|
+
LanguageModel_OnQuotaOverflow: "LanguageModel.onquotaoverflow is deprecated. Please use LanguageModel.oncontextoverflow instead. The LanguageModel.onquotaoverflow alias is only available in extensions.",
|
|
123
|
+
/**
|
|
124
|
+
* @description Warning message for web developers when they call the deprecated LanguageModel.params() method.
|
|
125
|
+
*/
|
|
126
|
+
LanguageModelParams: "LanguageModel.params() is deprecated and now only available in extension contexts. The topK and temperature related fields within its result are also deprecated.",
|
|
127
|
+
/**
|
|
128
|
+
* @description Warning message for web developers when they use the deprecated 'temperature' option in LanguageModel.create() or access the .temperature attribute.
|
|
129
|
+
*/
|
|
130
|
+
LanguageModelTemperature: "The 'temperature' parameter/attribute for LanguageModel is deprecated. It is only functional within extensions and may be removed in the future.",
|
|
131
|
+
/**
|
|
132
|
+
* @description Warning message for web developers when they use the deprecated 'topK' option in LanguageModel.create() or access the .topK attribute.
|
|
133
|
+
*/
|
|
134
|
+
LanguageModelTopK: "The 'topK' parameter/attribute for LanguageModel is deprecated. It is only functional within extensions and may be removed in the future.",
|
|
135
|
+
/**
|
|
136
|
+
* @description This warning occurs when a stylesheet loaded from a local file directive does not end in the file type `.css`.
|
|
137
|
+
*/
|
|
138
|
+
LocalCSSFileExtensionRejected: "CSS cannot be loaded from `file:` URLs unless they end in a `.css` file extension.",
|
|
103
139
|
/**
|
|
104
140
|
* @description This warning occurs when the browser requests Web MIDI access as sysex (system exclusive messages) can be allowed via prompt even if the browser did not specifically request it.
|
|
105
141
|
*/
|
|
@@ -176,14 +212,14 @@ export const UIStrings = {
|
|
|
176
212
|
* @description Standard message when one web API is deprecated in favor of another.
|
|
177
213
|
*/
|
|
178
214
|
PrefixedVideoSupportsFullscreen: "HTMLVideoElement.webkitSupportsFullscreen is deprecated. Please use Document.fullscreenEnabled instead.",
|
|
179
|
-
/**
|
|
180
|
-
* @description Warning displayed to developers that the API `chrome.privacy.websites.privacySandboxEnabled` is being deprecated in favour of three new more granular APIs: topicsEnabled, FledgeEnabled and adMeasurementEnabled. The `privacySandboxEnabled` API allowed extensions to control the homologous Chrome Setting. The existing Chrome Setting for Privacy Sandbox is also going away in favor of more granular settings that are matched by the new extensions APIs- topicsEnabled, FledgeEnabled and adMeasurementEnabled.
|
|
181
|
-
*/
|
|
182
|
-
PrivacySandboxExtensionsAPI: "We're deprecating the API `chrome.privacy.websites.privacySandboxEnabled`, though it will remain active for backward compatibility until release M113. Instead, please use `chrome.privacy.websites.topicsEnabled`, `chrome.privacy.websites.fledgeEnabled` and `chrome.privacy.websites.adMeasurementEnabled`. See https://developer.chrome.com/docs/extensions/reference/privacy/#property-websites-privacySandboxEnabled.",
|
|
183
215
|
/**
|
|
184
216
|
* @description Standard message when one web API is deprecated in favor of another.
|
|
185
217
|
*/
|
|
186
218
|
RangeExpand: "Range.expand() is deprecated. Please use Selection.modify() instead.",
|
|
219
|
+
/**
|
|
220
|
+
* @description A deprecation warning shown in the DevTools Issues tab. It's shown when the Storage Access API is automatically granted by Related Website Sets. The placeholder will always be the string `Related Website Sets`.
|
|
221
|
+
*/
|
|
222
|
+
RelatedWebsiteSets: "`Related Website Sets` is deprecated and will be removed. See https://privacysandbox.com/news/update-on-plans-for-privacy-sandbox-technologies/ for more details.",
|
|
187
223
|
/**
|
|
188
224
|
* @description This warning occurs when a subresource loaded by a page has a URL with an authority portion. These are disallowed.
|
|
189
225
|
*/
|
|
@@ -208,10 +244,22 @@ export const UIStrings = {
|
|
|
208
244
|
* @description A deprecation warning shown in the DevTools Issues tab. The placeholder is always the noun 'SharedArrayBuffer' which refers to a JavaScript construct.
|
|
209
245
|
*/
|
|
210
246
|
SharedArrayBufferConstructedWithoutIsolation: "`SharedArrayBuffer` will require cross-origin isolation. See https://developer.chrome.com/blog/enabling-shared-array-buffer/ for more details.",
|
|
247
|
+
/**
|
|
248
|
+
* @description A deprecation warning shown in the DevTools Issues tab. It's shown when one of the Shared Storage APIs like `sharedStorage.set()`, `sharedStorage.worklet.addModule()`, `sharedStorage.selectURL()`, etc., along with `<img sharedstoragewritable>`, `<iframe sharedstoragewritable>`, or `fetch(url, {sharedStorageWritable: true})` are used.
|
|
249
|
+
*/
|
|
250
|
+
SharedStorage: "The Shared Storage API is deprecated and will be removed in a future release.",
|
|
251
|
+
/**
|
|
252
|
+
* @description A deprecation warning shown in the DevTools Issues tab. It's shown when the `document.requestStorageAccessFor` API is called. The placeholder will always be the string `document.requestStorageAccessFor`.
|
|
253
|
+
*/
|
|
254
|
+
StorageAccessAPI_requestStorageAccessFor_Method: "`document.requestStorageAccessFor` is deprecated and will be removed. See https://privacysandbox.com/news/update-on-plans-for-privacy-sandbox-technologies/ for more details.",
|
|
211
255
|
/**
|
|
212
256
|
* @description A deprecation warning shown in the DevTools Issues tab. It's shown when the speech synthesis API is called before the page receives a user activation.
|
|
213
257
|
*/
|
|
214
258
|
TextToSpeech_DisallowedByAutoplay: "`speechSynthesis.speak()` without user activation is deprecated and will be removed.",
|
|
259
|
+
/**
|
|
260
|
+
* @description A deprecation warning shown in the DevTools Issues tab. It's shown when one of the Topics APIs like `document.browsingTopics()`, `<img browsingtopics>`, `<iframe browsingtopics>`, or `fetch(url, {browsingTopics: true})` are used.
|
|
261
|
+
*/
|
|
262
|
+
Topics: "The Topics API is deprecated and will be removed in a future release.",
|
|
215
263
|
/**
|
|
216
264
|
* @description A deprecation warning shown in the DevTools Issues tab. It's shown when a listener for the `unload` event is added.
|
|
217
265
|
*/
|
|
@@ -220,6 +268,10 @@ export const UIStrings = {
|
|
|
220
268
|
* @description A deprecation warning shown in the DevTools Issues tab. The placeholder is always the noun 'SharedArrayBuffer' which refers to a JavaScript construct. 'Extensions' refers to Chrome extensions. The warning is shown when Chrome Extensions attempt to use 'SharedArrayBuffer's under insecure circumstances.
|
|
221
269
|
*/
|
|
222
270
|
V8SharedArrayBufferConstructedInExtensionWithoutIsolation: "Extensions should opt into cross-origin isolation to continue using `SharedArrayBuffer`. See https://developer.chrome.com/docs/extensions/mv3/cross-origin-isolation/.",
|
|
271
|
+
/**
|
|
272
|
+
* @description This warning occurs when the deprecated `BluetoothRemoteGATTCharacteristic.writeValue()` method is used. Developers should use `writeValueWithResponse()` or `writeValueWithoutResponse()` instead.
|
|
273
|
+
*/
|
|
274
|
+
WebBluetoothRemoteCharacteristicWriteValue: "`BluetoothRemoteGATTCharacteristic.writeValue()` is deprecated. Use `writeValueWithResponse()` or `writeValueWithoutResponse()` instead.",
|
|
223
275
|
/**
|
|
224
276
|
* @description Warning displayed to developers that they are using `XMLHttpRequest` API in a way that they expect an unsupported character encoding `UTF-16` could be used in the server reply.
|
|
225
277
|
*/
|
|
@@ -228,6 +280,10 @@ export const UIStrings = {
|
|
|
228
280
|
* @description Warning displayed to developers. It is shown when the `XMLHttpRequest` API is used in a way that it slows down the page load of the next page. The `main thread` refers to an operating systems thread used to run most of the processing of HTML documents, so please use a consistent wording.
|
|
229
281
|
*/
|
|
230
282
|
XMLHttpRequestSynchronousInNonWorkerOutsideBeforeUnload: "Synchronous `XMLHttpRequest` on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.",
|
|
283
|
+
/**
|
|
284
|
+
* @description Warning displayed to developers that they are using either the XSLTProcessor API, or XSLT processing instructions, both of which have been deprecated and are scheduled to be removed.
|
|
285
|
+
*/
|
|
286
|
+
XSLT: "XSLTProcessor and XSLT Processing Instructions have been deprecated by all browsers. These features will be removed from this browser soon.",
|
|
231
287
|
};
|
|
232
288
|
|
|
233
289
|
|
|
@@ -235,6 +291,9 @@ export const UIStrings = {
|
|
|
235
291
|
|
|
236
292
|
|
|
237
293
|
export const DEPRECATIONS_METADATA = {
|
|
294
|
+
"AttributionReporting": {
|
|
295
|
+
"chromeStatusFeature": 6320639375966208
|
|
296
|
+
},
|
|
238
297
|
"AuthorizationCoveredByWildcard": {
|
|
239
298
|
"milestone": 97
|
|
240
299
|
},
|
|
@@ -256,9 +315,6 @@ export const DEPRECATIONS_METADATA = {
|
|
|
256
315
|
"ChromeLoadTimesWasAlternateProtocolAvailable": {
|
|
257
316
|
"chromeStatusFeature": 5637885046816768
|
|
258
317
|
},
|
|
259
|
-
"CookieWithTruncatingChar": {
|
|
260
|
-
"milestone": 103
|
|
261
|
-
},
|
|
262
318
|
"CrossOriginAccessBasedOnDocumentDomain": {
|
|
263
319
|
"milestone": 115
|
|
264
320
|
},
|
|
@@ -266,6 +322,14 @@ export const DEPRECATIONS_METADATA = {
|
|
|
266
322
|
"chromeStatusFeature": 5128825141198848,
|
|
267
323
|
"milestone": 119
|
|
268
324
|
},
|
|
325
|
+
"DocumentCreateEventKeyboardEvents": {
|
|
326
|
+
"chromeStatusFeature": 5095987863486464,
|
|
327
|
+
"milestone": 151
|
|
328
|
+
},
|
|
329
|
+
"DocumentCreateEventTransitionEvent": {
|
|
330
|
+
"chromeStatusFeature": 5095987863486464,
|
|
331
|
+
"milestone": 151
|
|
332
|
+
},
|
|
269
333
|
"IdentityInCanMakePaymentEvent": {
|
|
270
334
|
"chromeStatusFeature": 5190978431352832
|
|
271
335
|
},
|
|
@@ -273,14 +337,29 @@ export const DEPRECATIONS_METADATA = {
|
|
|
273
337
|
"chromeStatusFeature": 5436853517811712,
|
|
274
338
|
"milestone": 92
|
|
275
339
|
},
|
|
276
|
-
"
|
|
277
|
-
"
|
|
340
|
+
"LanguageModelParams": {
|
|
341
|
+
"chromeStatusFeature": 5134603979063296
|
|
342
|
+
},
|
|
343
|
+
"LanguageModelTemperature": {
|
|
344
|
+
"chromeStatusFeature": 5134603979063296
|
|
345
|
+
},
|
|
346
|
+
"LanguageModelTopK": {
|
|
347
|
+
"chromeStatusFeature": 5134603979063296
|
|
348
|
+
},
|
|
349
|
+
"LanguageModel_InputQuota": {
|
|
350
|
+
"chromeStatusFeature": 5134603979063296
|
|
351
|
+
},
|
|
352
|
+
"LanguageModel_InputUsage": {
|
|
353
|
+
"chromeStatusFeature": 5134603979063296
|
|
354
|
+
},
|
|
355
|
+
"LanguageModel_MeasureInputUsage": {
|
|
356
|
+
"chromeStatusFeature": 5134603979063296
|
|
278
357
|
},
|
|
279
|
-
"
|
|
280
|
-
"chromeStatusFeature":
|
|
358
|
+
"LanguageModel_OnQuotaOverflow": {
|
|
359
|
+
"chromeStatusFeature": 5134603979063296
|
|
281
360
|
},
|
|
282
|
-
"
|
|
283
|
-
"
|
|
361
|
+
"LocalCSSFileExtensionRejected": {
|
|
362
|
+
"milestone": 64
|
|
284
363
|
},
|
|
285
364
|
"NoSysexWebMIDIWithoutPermission": {
|
|
286
365
|
"chromeStatusFeature": 5138066234671104,
|
|
@@ -322,6 +401,9 @@ export const DEPRECATIONS_METADATA = {
|
|
|
322
401
|
"chromeStatusFeature": 4631626228695040,
|
|
323
402
|
"milestone": 117
|
|
324
403
|
},
|
|
404
|
+
"RelatedWebsiteSets": {
|
|
405
|
+
"chromeStatusFeature": 5194473869017088
|
|
406
|
+
},
|
|
325
407
|
"RequestedSubresourceWithEmbeddedCredentials": {
|
|
326
408
|
"chromeStatusFeature": 5669008342777856
|
|
327
409
|
},
|
|
@@ -332,6 +414,12 @@ export const DEPRECATIONS_METADATA = {
|
|
|
332
414
|
"SharedArrayBufferConstructedWithoutIsolation": {
|
|
333
415
|
"milestone": 106
|
|
334
416
|
},
|
|
417
|
+
"SharedStorage": {
|
|
418
|
+
"chromeStatusFeature": 5076349064708096
|
|
419
|
+
},
|
|
420
|
+
"StorageAccessAPI_requestStorageAccessFor_Method": {
|
|
421
|
+
"chromeStatusFeature": 5162221567082496
|
|
422
|
+
},
|
|
335
423
|
"TextToSpeech_DisallowedByAutoplay": {
|
|
336
424
|
"chromeStatusFeature": 5687444770914304,
|
|
337
425
|
"milestone": 71
|
|
@@ -342,7 +430,14 @@ export const DEPRECATIONS_METADATA = {
|
|
|
342
430
|
"V8SharedArrayBufferConstructedInExtensionWithoutIsolation": {
|
|
343
431
|
"milestone": 96
|
|
344
432
|
},
|
|
433
|
+
"WebBluetoothRemoteCharacteristicWriteValue": {
|
|
434
|
+
"chromeStatusFeature": 5088568590598144
|
|
435
|
+
},
|
|
345
436
|
"XHRJSONEncodingDetection": {
|
|
346
437
|
"milestone": 93
|
|
438
|
+
},
|
|
439
|
+
"XSLT": {
|
|
440
|
+
"chromeStatusFeature": 4709671889534976,
|
|
441
|
+
"milestone": 143
|
|
347
442
|
}
|
|
348
443
|
};
|
|
@@ -130,8 +130,11 @@ function getNonHtmlError(finalRecord) {
|
|
|
130
130
|
*/
|
|
131
131
|
function getPageLoadError(navigationError, context) {
|
|
132
132
|
const {url, networkRecords} = context;
|
|
133
|
-
|
|
134
|
-
|
|
133
|
+
const mainRecordLantern = Lantern.Core.NetworkAnalyzer.findResourceForUrl(
|
|
134
|
+
networkRecords,
|
|
135
|
+
url
|
|
136
|
+
);
|
|
137
|
+
let mainRecord = mainRecordLantern;
|
|
135
138
|
|
|
136
139
|
// If the url doesn't give us a network request, it's possible we landed on a chrome-error:// page
|
|
137
140
|
// In this case, just get the first document request.
|
|
@@ -253,7 +253,8 @@ class NetworkRecorder extends RequestEventEmitter {
|
|
|
253
253
|
return record.redirectSource;
|
|
254
254
|
}
|
|
255
255
|
|
|
256
|
-
const
|
|
256
|
+
const lanternReq = NetworkRequest.asLanternNetworkRequest(record);
|
|
257
|
+
const initiatorURL = Lantern.Graph.PageDependencyGraph.getNetworkInitiators(lanternReq)[0];
|
|
257
258
|
let candidates = recordsByURL.get(initiatorURL) || [];
|
|
258
259
|
// The (valid) initiator must come before the initiated request.
|
|
259
260
|
candidates = candidates.filter(c => {
|
|
@@ -88,10 +88,10 @@ declare namespace getOuterHTMLSnippet {
|
|
|
88
88
|
*/
|
|
89
89
|
declare function computeBenchmarkIndex(): number;
|
|
90
90
|
/**
|
|
91
|
-
* @param {
|
|
92
|
-
* @return {LH.Artifacts.NodeDetails}
|
|
91
|
+
* @param {Node|ShadowRoot} node
|
|
92
|
+
* @return {LH.Artifacts.NodeDetails | null}
|
|
93
93
|
*/
|
|
94
|
-
declare function getNodeDetails(
|
|
94
|
+
declare function getNodeDetails(node: Node | ShadowRoot): LH.Artifacts.NodeDetails | null;
|
|
95
95
|
declare namespace getNodeDetails {
|
|
96
96
|
function toString(): string;
|
|
97
97
|
}
|
|
@@ -450,16 +450,23 @@ function wrapRequestIdleCallback(cpuSlowdownMultiplier) {
|
|
|
450
450
|
}
|
|
451
451
|
|
|
452
452
|
/**
|
|
453
|
-
* @param {
|
|
454
|
-
* @return {LH.Artifacts.NodeDetails}
|
|
453
|
+
* @param {Node|ShadowRoot} node
|
|
454
|
+
* @return {LH.Artifacts.NodeDetails | null}
|
|
455
455
|
*/
|
|
456
|
-
function getNodeDetails(
|
|
456
|
+
function getNodeDetails(node) {
|
|
457
457
|
// This bookkeeping is for the FullPageScreenshot gatherer.
|
|
458
458
|
if (!window.__lighthouseNodesDontTouchOrAllVarianceGoesAway) {
|
|
459
459
|
window.__lighthouseNodesDontTouchOrAllVarianceGoesAway = new Map();
|
|
460
460
|
}
|
|
461
461
|
|
|
462
|
-
|
|
462
|
+
let elem = node.nodeType === Node.ELEMENT_NODE ? node : node.parentElement;
|
|
463
|
+
if (!elem && node instanceof ShadowRoot) {
|
|
464
|
+
elem = node.host;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
if (!elem) return null;
|
|
468
|
+
|
|
469
|
+
const element = /** @type {Element} */ (elem);
|
|
463
470
|
const selector = getNodeSelector(element);
|
|
464
471
|
|
|
465
472
|
// Create an id that will be unique across all execution contexts.
|
|
@@ -196,9 +196,10 @@ export class TraceProcessor {
|
|
|
196
196
|
*
|
|
197
197
|
* @param {LH.TraceEvent[]} events
|
|
198
198
|
* @param {LH.TraceEvent} timeOriginEvent
|
|
199
|
+
* @param {string|undefined} mainFrameId
|
|
199
200
|
* @return {{lcp: LCPEvent | undefined, invalidated: boolean}}
|
|
200
201
|
*/
|
|
201
|
-
static computeValidLCPAllFrames(events: LH.TraceEvent[], timeOriginEvent: LH.TraceEvent): {
|
|
202
|
+
static computeValidLCPAllFrames(events: LH.TraceEvent[], timeOriginEvent: LH.TraceEvent, mainFrameId: string | undefined): {
|
|
202
203
|
lcp: LCPEvent | undefined;
|
|
203
204
|
invalidated: boolean;
|
|
204
205
|
};
|
|
@@ -217,7 +218,7 @@ export class TraceProcessor {
|
|
|
217
218
|
* @param {LH.Trace} trace
|
|
218
219
|
* @param {{timeOriginDeterminationMethod?: TimeOriginDeterminationMethod}} [options]
|
|
219
220
|
* @return {LH.Artifacts.ProcessedTrace}
|
|
220
|
-
|
|
221
|
+
*/
|
|
221
222
|
static processTrace(trace: LH.Trace, options?: {
|
|
222
223
|
timeOriginDeterminationMethod?: TimeOriginDeterminationMethod;
|
|
223
224
|
}): LH.Artifacts.ProcessedTrace;
|
|
@@ -226,7 +227,7 @@ export class TraceProcessor {
|
|
|
226
227
|
* origin in addition to the standard microsecond monotonic timestamps.
|
|
227
228
|
* @param {LH.Artifacts.ProcessedTrace} processedTrace
|
|
228
229
|
* @return {LH.Artifacts.ProcessedNavigation}
|
|
229
|
-
|
|
230
|
+
*/
|
|
230
231
|
static processNavigation(processedTrace: LH.Artifacts.ProcessedTrace): LH.Artifacts.ProcessedNavigation;
|
|
231
232
|
/**
|
|
232
233
|
* Computes the last observable timestamp in a set of trace events.
|
|
@@ -272,7 +273,7 @@ export class TraceProcessor {
|
|
|
272
273
|
* in addition to the standard microsecond monotonic timestamps.
|
|
273
274
|
* @param {Array<LH.TraceEvent>} frameEvents
|
|
274
275
|
* @param {{timeOriginEvt: LH.TraceEvent}} options
|
|
275
|
-
|
|
276
|
+
*/
|
|
276
277
|
static computeNavigationTimingsForFrame(frameEvents: Array<LH.TraceEvent>, options: {
|
|
277
278
|
timeOriginEvt: LH.TraceEvent;
|
|
278
279
|
}): {
|
|
@@ -349,7 +349,7 @@ class TraceProcessor {
|
|
|
349
349
|
|
|
350
350
|
const ret = this.getMainThreadTopLevelEventDurations(events, startTime, endTime);
|
|
351
351
|
return this._riskPercentiles(ret.durations, totalTime, percentiles,
|
|
352
|
-
|
|
352
|
+
ret.clippedLength);
|
|
353
353
|
}
|
|
354
354
|
|
|
355
355
|
/**
|
|
@@ -479,9 +479,9 @@ class TraceProcessor {
|
|
|
479
479
|
const firstResourceSendEvt = events.find(e => e.name === 'ResourceSendRequest');
|
|
480
480
|
// We know that these properties exist if we found the events, but TSC doesn't.
|
|
481
481
|
if (navStartEvt?.args?.data &&
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
482
|
+
firstResourceSendEvt &&
|
|
483
|
+
firstResourceSendEvt.pid === navStartEvt.pid &&
|
|
484
|
+
firstResourceSendEvt.tid === navStartEvt.tid) {
|
|
485
485
|
const frameId = navStartEvt.args.frame;
|
|
486
486
|
if (frameId) {
|
|
487
487
|
return {
|
|
@@ -552,9 +552,9 @@ class TraceProcessor {
|
|
|
552
552
|
*/
|
|
553
553
|
static isScheduleableTask(evt) {
|
|
554
554
|
return evt.name === SCHEDULABLE_TASK_TITLE_LH ||
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
555
|
+
evt.name === SCHEDULABLE_TASK_TITLE_ALT1 ||
|
|
556
|
+
evt.name === SCHEDULABLE_TASK_TITLE_ALT2 ||
|
|
557
|
+
evt.name === SCHEDULABLE_TASK_TITLE_ALT3;
|
|
558
558
|
}
|
|
559
559
|
|
|
560
560
|
/**
|
|
@@ -563,7 +563,7 @@ class TraceProcessor {
|
|
|
563
563
|
*/
|
|
564
564
|
static isLCPEvent(evt) {
|
|
565
565
|
if (evt.name !== 'largestContentfulPaint::Invalidate' &&
|
|
566
|
-
|
|
566
|
+
evt.name !== 'largestContentfulPaint::Candidate') return false;
|
|
567
567
|
return Boolean(evt.args?.frame);
|
|
568
568
|
}
|
|
569
569
|
|
|
@@ -602,9 +602,10 @@ class TraceProcessor {
|
|
|
602
602
|
*
|
|
603
603
|
* @param {LH.TraceEvent[]} events
|
|
604
604
|
* @param {LH.TraceEvent} timeOriginEvent
|
|
605
|
+
* @param {string|undefined} mainFrameId
|
|
605
606
|
* @return {{lcp: LCPEvent | undefined, invalidated: boolean}}
|
|
606
607
|
*/
|
|
607
|
-
static computeValidLCPAllFrames(events, timeOriginEvent) {
|
|
608
|
+
static computeValidLCPAllFrames(events, timeOriginEvent, mainFrameId) {
|
|
608
609
|
const lcpEvents = events.filter(this.isLCPEvent).reverse();
|
|
609
610
|
|
|
610
611
|
/** @type {Map<string, LCPEvent>} */
|
|
@@ -628,6 +629,53 @@ class TraceProcessor {
|
|
|
628
629
|
}
|
|
629
630
|
}
|
|
630
631
|
|
|
632
|
+
// If no standard LCP candidate is found, try the UKM AllFramesEvents.
|
|
633
|
+
if (!maxLcpAcrossFrames) {
|
|
634
|
+
const ukmEvents = events.filter(
|
|
635
|
+
(e) =>
|
|
636
|
+
e.name.includes('LargestContentfulPaint') && e.name.includes('UKM')
|
|
637
|
+
);
|
|
638
|
+
|
|
639
|
+
// In the rare cases this whole fallback is necessary, the
|
|
640
|
+
// NavStartToLargestContentfulPaint::Candidate::AllFrames::UKM events are missing too.
|
|
641
|
+
// As a result, the only useful signal left is the AllFrames invalidates.
|
|
642
|
+
// Not ideal since they are 1 paint behind, but.. better than the dreaded
|
|
643
|
+
// NO_LCP error
|
|
644
|
+
const targetEventName =
|
|
645
|
+
'NavStartToLargestContentfulPaint::Invalidate::AllFrames::UKM';
|
|
646
|
+
const ukmInvalidates = ukmEvents.filter((e) => e.name === targetEventName);
|
|
647
|
+
|
|
648
|
+
if (ukmInvalidates.length > 0) {
|
|
649
|
+
ukmInvalidates.sort((a, b) => a.ts - b.ts);
|
|
650
|
+
const lastInvalidate = ukmInvalidates[ukmInvalidates.length - 1];
|
|
651
|
+
|
|
652
|
+
log.warn(
|
|
653
|
+
'TraceProcessor',
|
|
654
|
+
'LCP candidate missing, falling back to UKM Invalidate event.'
|
|
655
|
+
);
|
|
656
|
+
|
|
657
|
+
// Construct a mock LCP candidate event
|
|
658
|
+
maxLcpAcrossFrames = /** @type {LCPCandidateEvent} */ (
|
|
659
|
+
/** @type {unknown} */ ({
|
|
660
|
+
name: 'largestContentfulPaint::Candidate',
|
|
661
|
+
cat: 'loading',
|
|
662
|
+
ph: lastInvalidate.ph,
|
|
663
|
+
ts: lastInvalidate.ts,
|
|
664
|
+
pid: lastInvalidate.pid,
|
|
665
|
+
tid: lastInvalidate.tid,
|
|
666
|
+
args: {
|
|
667
|
+
frame: mainFrameId || 'main_frame', // Mocked frame ID
|
|
668
|
+
data: {
|
|
669
|
+
size: 1, // Don't know the actuall size so we assign it 1
|
|
670
|
+
isMainFrame: true,
|
|
671
|
+
isOutermostMainFrame: true,
|
|
672
|
+
},
|
|
673
|
+
},
|
|
674
|
+
})
|
|
675
|
+
);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
|
|
631
679
|
return {
|
|
632
680
|
lcp: maxLcpAcrossFrames,
|
|
633
681
|
// LCP events were found, but final LCP event of every frame was an invalidate event.
|
|
@@ -669,7 +717,7 @@ class TraceProcessor {
|
|
|
669
717
|
* @param {LH.Trace} trace
|
|
670
718
|
* @param {{timeOriginDeterminationMethod?: TimeOriginDeterminationMethod}} [options]
|
|
671
719
|
* @return {LH.Artifacts.ProcessedTrace}
|
|
672
|
-
|
|
720
|
+
*/
|
|
673
721
|
static processTrace(trace, options) {
|
|
674
722
|
const {timeOriginDeterminationMethod = 'auto'} = options || {};
|
|
675
723
|
|
|
@@ -677,9 +725,9 @@ class TraceProcessor {
|
|
|
677
725
|
// *must* be stable to keep events correctly nested.
|
|
678
726
|
const keyEvents = this.filteredTraceSort(trace.traceEvents, e => {
|
|
679
727
|
return e.cat.includes('blink.user_timing') ||
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
728
|
+
e.cat.includes('loading') ||
|
|
729
|
+
e.cat.includes('devtools.timeline') ||
|
|
730
|
+
e.cat === '__metadata';
|
|
683
731
|
});
|
|
684
732
|
|
|
685
733
|
// Find the inspected frame
|
|
@@ -699,7 +747,7 @@ class TraceProcessor {
|
|
|
699
747
|
// Begin collection of frame tree information with TracingStartedInBrowser,
|
|
700
748
|
// which should be present even without navigations.
|
|
701
749
|
const tracingStartedFrames = keyEvents
|
|
702
|
-
|
|
750
|
+
.find(e => e.name === 'TracingStartedInBrowser')?.args?.data?.frames;
|
|
703
751
|
if (tracingStartedFrames) {
|
|
704
752
|
for (const frame of tracingStartedFrames) {
|
|
705
753
|
framesById.set(frame.frame, {
|
|
@@ -738,12 +786,18 @@ class TraceProcessor {
|
|
|
738
786
|
// Filter to just events matching the main frame ID, just to make sure.
|
|
739
787
|
/** @param {LH.TraceEvent} e */
|
|
740
788
|
function associatedToMainFrame(e) {
|
|
789
|
+
if (e.name === 'NavStartToLargestContentfulPaint::Invalidate::AllFrames::UKM') {
|
|
790
|
+
return true;
|
|
791
|
+
}
|
|
741
792
|
const frameId = TraceProcessor.getFrameId(e);
|
|
742
793
|
return frameId === mainFrameInfo.frameId;
|
|
743
794
|
}
|
|
744
795
|
|
|
745
796
|
/** @param {LH.TraceEvent} e */
|
|
746
797
|
function associatedToAllFrames(e) {
|
|
798
|
+
if (e.name.includes('LargestContentfulPaint') && e.name.includes('UKM')) {
|
|
799
|
+
return true;
|
|
800
|
+
}
|
|
747
801
|
const frameId = TraceProcessor.getFrameId(e);
|
|
748
802
|
return frameId ? inspectedTreeFrameIds.includes(frameId) : false;
|
|
749
803
|
}
|
|
@@ -805,9 +859,16 @@ class TraceProcessor {
|
|
|
805
859
|
* origin in addition to the standard microsecond monotonic timestamps.
|
|
806
860
|
* @param {LH.Artifacts.ProcessedTrace} processedTrace
|
|
807
861
|
* @return {LH.Artifacts.ProcessedNavigation}
|
|
808
|
-
|
|
862
|
+
*/
|
|
809
863
|
static processNavigation(processedTrace) {
|
|
810
|
-
const {
|
|
864
|
+
const {
|
|
865
|
+
frameEvents,
|
|
866
|
+
frameTreeEvents,
|
|
867
|
+
timeOriginEvt,
|
|
868
|
+
timings,
|
|
869
|
+
timestamps,
|
|
870
|
+
mainFrameInfo,
|
|
871
|
+
} = processedTrace;
|
|
811
872
|
|
|
812
873
|
// Compute the key frame timings for the main frame.
|
|
813
874
|
const frameTimings = this.computeNavigationTimingsForFrame(frameEvents, {timeOriginEvt});
|
|
@@ -822,7 +883,11 @@ class TraceProcessor {
|
|
|
822
883
|
}
|
|
823
884
|
|
|
824
885
|
// Compute LCP for all frames.
|
|
825
|
-
const lcpAllFramesEvt = this.computeValidLCPAllFrames(
|
|
886
|
+
const lcpAllFramesEvt = this.computeValidLCPAllFrames(
|
|
887
|
+
frameTreeEvents,
|
|
888
|
+
timeOriginEvt,
|
|
889
|
+
mainFrameInfo.frameId
|
|
890
|
+
).lcp;
|
|
826
891
|
|
|
827
892
|
/** @param {number} ts */
|
|
828
893
|
const getTiming = ts => (ts - timeOriginEvt.ts) / 1000;
|
|
@@ -950,7 +1015,7 @@ class TraceProcessor {
|
|
|
950
1015
|
* in addition to the standard microsecond monotonic timestamps.
|
|
951
1016
|
* @param {Array<LH.TraceEvent>} frameEvents
|
|
952
1017
|
* @param {{timeOriginEvt: LH.TraceEvent}} options
|
|
953
|
-
|
|
1018
|
+
*/
|
|
954
1019
|
static computeNavigationTimingsForFrame(frameEvents, options) {
|
|
955
1020
|
const {timeOriginEvt} = options;
|
|
956
1021
|
|
|
@@ -967,7 +1032,8 @@ class TraceProcessor {
|
|
|
967
1032
|
}
|
|
968
1033
|
|
|
969
1034
|
// This function accepts events spanning multiple frames, but this usage will only provide events from the main frame.
|
|
970
|
-
const
|
|
1035
|
+
const frameId = frameEvents.map(e => TraceProcessor.getFrameId(e)).find(Boolean);
|
|
1036
|
+
const lcpResult = this.computeValidLCPAllFrames(frameEvents, timeOriginEvt, frameId);
|
|
971
1037
|
|
|
972
1038
|
const load = frameEvents.find(e => e.name === 'loadEventEnd' && e.ts > timeOriginEvt.ts);
|
|
973
1039
|
const domContentLoaded = frameEvents.find(
|
package/core/runner.js
CHANGED
|
@@ -498,6 +498,7 @@ vs: ${JSON.stringify(normalizedAuditSettings[k], null, 2)}`);
|
|
|
498
498
|
.map(f => `byte-efficiency/${f}`),
|
|
499
499
|
...fs.readdirSync(path.join(moduleDir, './audits/manual')).map(f => `manual/${f}`),
|
|
500
500
|
...fs.readdirSync(path.join(moduleDir, './audits/insights')).map(f => `insights/${f}`),
|
|
501
|
+
...fs.readdirSync(path.join(moduleDir, './audits/agentic')).map(f => `agentic/${f}`),
|
|
501
502
|
];
|
|
502
503
|
return fileList.filter(f => {
|
|
503
504
|
return /\.js$/.test(f) && !ignoredFiles.includes(f);
|
|
@@ -514,6 +515,8 @@ vs: ${JSON.stringify(normalizedAuditSettings[k], null, 2)}`);
|
|
|
514
515
|
...fs.readdirSync(path.join(moduleDir, './gather/gatherers/seo')).map(f => `seo/${f}`),
|
|
515
516
|
...fs.readdirSync(path.join(moduleDir, './gather/gatherers/dobetterweb'))
|
|
516
517
|
.map(f => `dobetterweb/${f}`),
|
|
518
|
+
...fs.readdirSync(path.join(moduleDir, './gather/gatherers/agentic'))
|
|
519
|
+
.map(f => `agentic/${f}`),
|
|
517
520
|
];
|
|
518
521
|
return fileList.filter(f => /\.js$/.test(f) && f !== 'gatherer.js').sort();
|
|
519
522
|
}
|