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
|
@@ -61,6 +61,9 @@ class Trace extends BaseGatherer {
|
|
|
61
61
|
'disabled-by-default-devtools.v8-source-rundown-sources',
|
|
62
62
|
'disabled-by-default-devtools.v8-source-rundown',
|
|
63
63
|
|
|
64
|
+
// Required for Baseline Audit to detect feature usage.
|
|
65
|
+
'blink.webdx_feature_usage',
|
|
66
|
+
|
|
64
67
|
// Not used by Lighthouse (yet) but included for users that want JS samples when looking at
|
|
65
68
|
// a trace collected by Lighthouse (e.g. "View Trace" workflow in DevTools)
|
|
66
69
|
// TODO: Re-enable after investigating b/325659693
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export default WebMcpSchemaIssues;
|
|
2
|
+
declare class WebMcpSchemaIssues extends BaseGatherer {
|
|
3
|
+
/** @type {LH.Artifacts.WebMcpSchemaIssue[]} */
|
|
4
|
+
_issues: LH.Artifacts.WebMcpSchemaIssue[];
|
|
5
|
+
_onIssueAdded: (event: Record<string, any>) => void;
|
|
6
|
+
/**
|
|
7
|
+
* @param {Record<string, any>} event
|
|
8
|
+
*/
|
|
9
|
+
onIssueAdded(event: Record<string, any>): void;
|
|
10
|
+
/**
|
|
11
|
+
* @param {LH.Gatherer.Context} passContext
|
|
12
|
+
*/
|
|
13
|
+
startInstrumentation(passContext: LH.Gatherer.Context): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* @param {LH.Gatherer.Context} passContext
|
|
16
|
+
*/
|
|
17
|
+
stopInstrumentation(passContext: LH.Gatherer.Context): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* @param {LH.Gatherer.Context} context
|
|
20
|
+
* @return {Promise<LH.Artifacts.WebMcpSchemaIssue[]>}
|
|
21
|
+
*/
|
|
22
|
+
getArtifact(context: LH.Gatherer.Context): Promise<LH.Artifacts.WebMcpSchemaIssue[]>;
|
|
23
|
+
}
|
|
24
|
+
import BaseGatherer from '../base-gatherer.js';
|
|
25
|
+
//# sourceMappingURL=webmcp-schema.d.ts.map
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import BaseGatherer from '../base-gatherer.js';
|
|
8
|
+
import {resolveNodeIdToObjectId} from '../driver/dom.js';
|
|
9
|
+
import {pageFunctions} from '../../lib/page-functions.js';
|
|
10
|
+
import {ExecutionContext} from '../driver/execution-context.js';
|
|
11
|
+
|
|
12
|
+
class WebMcpSchemaIssues extends BaseGatherer {
|
|
13
|
+
/** @type {LH.Gatherer.GathererMeta} */
|
|
14
|
+
meta = {
|
|
15
|
+
supportedModes: ['navigation', 'snapshot'],
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
constructor() {
|
|
19
|
+
super();
|
|
20
|
+
/** @type {LH.Artifacts.WebMcpSchemaIssue[]} */
|
|
21
|
+
this._issues = [];
|
|
22
|
+
this._onIssueAdded = this.onIssueAdded.bind(this);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @param {Record<string, any>} event
|
|
27
|
+
*/
|
|
28
|
+
onIssueAdded(event) {
|
|
29
|
+
const issue = event.issue;
|
|
30
|
+
if (!issue || issue.code !== 'GenericIssue') return;
|
|
31
|
+
|
|
32
|
+
const details = issue.details?.genericIssueDetails;
|
|
33
|
+
if (!details) return;
|
|
34
|
+
|
|
35
|
+
const errorType = details.errorType;
|
|
36
|
+
if (errorType && (
|
|
37
|
+
errorType === 'FormModelContextMissingToolName' ||
|
|
38
|
+
errorType === 'FormModelContextMissingToolDescription' ||
|
|
39
|
+
errorType === 'FormModelContextRequiredParameterMissingName' ||
|
|
40
|
+
errorType === 'FormModelContextParameterMissingTitleAndDescription' ||
|
|
41
|
+
errorType === 'FormModelContextParameterMissingName'
|
|
42
|
+
)) {
|
|
43
|
+
this._issues.push(details);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @param {LH.Gatherer.Context} passContext
|
|
49
|
+
*/
|
|
50
|
+
async startInstrumentation(passContext) {
|
|
51
|
+
const session = passContext.driver.defaultSession;
|
|
52
|
+
session.on('Audits.issueAdded', this._onIssueAdded);
|
|
53
|
+
await session.sendCommand('Audits.enable');
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @param {LH.Gatherer.Context} passContext
|
|
58
|
+
*/
|
|
59
|
+
async stopInstrumentation(passContext) {
|
|
60
|
+
const session = passContext.driver.defaultSession;
|
|
61
|
+
session.off('Audits.issueAdded', this._onIssueAdded);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @param {LH.Gatherer.Context} context
|
|
66
|
+
* @return {Promise<LH.Artifacts.WebMcpSchemaIssue[]>}
|
|
67
|
+
*/
|
|
68
|
+
async getArtifact(context) {
|
|
69
|
+
const session = context.driver.defaultSession;
|
|
70
|
+
|
|
71
|
+
const deps = ExecutionContext.serializeDeps([
|
|
72
|
+
pageFunctions.getNodeDetails,
|
|
73
|
+
]);
|
|
74
|
+
|
|
75
|
+
const promises = this._issues.map(async (issue) => {
|
|
76
|
+
const processedIssue = {...issue};
|
|
77
|
+
if (issue.violatingNodeId) {
|
|
78
|
+
try {
|
|
79
|
+
const objectId = await resolveNodeIdToObjectId(session, issue.violatingNodeId);
|
|
80
|
+
if (objectId) {
|
|
81
|
+
const response = await session.sendCommand('Runtime.callFunctionOn', {
|
|
82
|
+
objectId,
|
|
83
|
+
functionDeclaration: `function () {
|
|
84
|
+
${deps}
|
|
85
|
+
return getNodeDetails(this);
|
|
86
|
+
}`,
|
|
87
|
+
returnByValue: true,
|
|
88
|
+
awaitPromise: true,
|
|
89
|
+
});
|
|
90
|
+
if (response && response.result && response.result.value) {
|
|
91
|
+
processedIssue.nodeDetails = response.result.value;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
} catch (err) {
|
|
95
|
+
// Ignore error
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return processedIssue;
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
return Promise.all(promises);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export default WebMcpSchemaIssues;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export default WebMCP;
|
|
2
|
+
export type WebMCPTool = {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
inputSchema: Record<string, any>;
|
|
6
|
+
frameId: string;
|
|
7
|
+
backendNodeId?: number | undefined;
|
|
8
|
+
stackTrace?: any;
|
|
9
|
+
nodeDetails?: import("../../index.js").Artifacts.NodeDetails | undefined;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* @typedef {Object} WebMCPTool
|
|
13
|
+
* @property {string} name
|
|
14
|
+
* @property {string} description
|
|
15
|
+
* @property {Record<string, any>} inputSchema
|
|
16
|
+
* @property {string} frameId
|
|
17
|
+
* @property {number} [backendNodeId]
|
|
18
|
+
* @property {any} [stackTrace]
|
|
19
|
+
* @property {LH.Artifacts.NodeDetails} [nodeDetails]
|
|
20
|
+
*/
|
|
21
|
+
declare class WebMCP extends BaseGatherer {
|
|
22
|
+
/** @type {WebMCPTool[]} */
|
|
23
|
+
_tools: WebMCPTool[];
|
|
24
|
+
_isSupported: boolean;
|
|
25
|
+
_onToolsAdded: (event: {
|
|
26
|
+
tools: WebMCPTool[];
|
|
27
|
+
}) => void;
|
|
28
|
+
_onToolsRemoved: (event: {
|
|
29
|
+
tools: WebMCPTool[];
|
|
30
|
+
}) => void;
|
|
31
|
+
/**
|
|
32
|
+
* @param {{tools: WebMCPTool[]}} event
|
|
33
|
+
*/
|
|
34
|
+
onToolsAdded(event: {
|
|
35
|
+
tools: WebMCPTool[];
|
|
36
|
+
}): void;
|
|
37
|
+
/**
|
|
38
|
+
* @param {{tools: WebMCPTool[]}} event
|
|
39
|
+
*/
|
|
40
|
+
onToolsRemoved(event: {
|
|
41
|
+
tools: WebMCPTool[];
|
|
42
|
+
}): void;
|
|
43
|
+
/**
|
|
44
|
+
* @param {LH.Gatherer.Context} passContext
|
|
45
|
+
*/
|
|
46
|
+
startInstrumentation(passContext: LH.Gatherer.Context): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* @param {LH.Gatherer.Context} passContext
|
|
49
|
+
*/
|
|
50
|
+
stopInstrumentation(passContext: LH.Gatherer.Context): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* @param {LH.Gatherer.Context} context
|
|
53
|
+
* @return {Promise<LH.Artifacts['WebMCP']>}
|
|
54
|
+
*/
|
|
55
|
+
getArtifact(context: LH.Gatherer.Context): Promise<LH.Artifacts["WebMCP"]>;
|
|
56
|
+
}
|
|
57
|
+
import BaseGatherer from '../base-gatherer.js';
|
|
58
|
+
//# sourceMappingURL=webmcp.d.ts.map
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @fileoverview Capture WebMCP data
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import BaseGatherer from '../base-gatherer.js';
|
|
12
|
+
import {resolveNodeIdToObjectId} from '../driver/dom.js';
|
|
13
|
+
import {pageFunctions} from '../../lib/page-functions.js';
|
|
14
|
+
import {ExecutionContext} from '../driver/execution-context.js';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @typedef {Object} WebMCPTool
|
|
18
|
+
* @property {string} name
|
|
19
|
+
* @property {string} description
|
|
20
|
+
* @property {Record<string, any>} inputSchema
|
|
21
|
+
* @property {string} frameId
|
|
22
|
+
* @property {number} [backendNodeId]
|
|
23
|
+
* @property {any} [stackTrace]
|
|
24
|
+
* @property {LH.Artifacts.NodeDetails} [nodeDetails]
|
|
25
|
+
*/
|
|
26
|
+
class WebMCP extends BaseGatherer {
|
|
27
|
+
/** @type {LH.Gatherer.GathererMeta} */
|
|
28
|
+
meta = {
|
|
29
|
+
supportedModes: ['navigation', 'snapshot'],
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
constructor() {
|
|
33
|
+
super();
|
|
34
|
+
/** @type {WebMCPTool[]} */
|
|
35
|
+
this._tools = [];
|
|
36
|
+
this._isSupported = true;
|
|
37
|
+
this._onToolsAdded = this.onToolsAdded.bind(this);
|
|
38
|
+
this._onToolsRemoved = this.onToolsRemoved.bind(this);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @param {{tools: WebMCPTool[]}} event
|
|
43
|
+
*/
|
|
44
|
+
// TODO: Handle WebMCP tools per frame.
|
|
45
|
+
onToolsAdded(event) {
|
|
46
|
+
// Note that as of M148, there is a bug in WebMCP CDP.
|
|
47
|
+
// While WebMCP is enabled, any newly registered tool will
|
|
48
|
+
// have an empty schema.
|
|
49
|
+
if (event.tools) {
|
|
50
|
+
this._tools.push(...event.tools);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @param {{tools: WebMCPTool[]}} event
|
|
56
|
+
*/
|
|
57
|
+
onToolsRemoved(event) {
|
|
58
|
+
if (event.tools) {
|
|
59
|
+
const removedNames = new Set(event.tools.map(t => t.name));
|
|
60
|
+
this._tools = this._tools.filter(t => !removedNames.has(t.name));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @param {LH.Gatherer.Context} passContext
|
|
66
|
+
*/
|
|
67
|
+
async startInstrumentation(passContext) {
|
|
68
|
+
const session = passContext.driver.defaultSession;
|
|
69
|
+
|
|
70
|
+
// @ts-expect-error - WebMCP domain might not be in types yet.
|
|
71
|
+
session.on('WebMCP.toolsAdded', this._onToolsAdded);
|
|
72
|
+
// @ts-expect-error
|
|
73
|
+
session.on('WebMCP.toolsRemoved', this._onToolsRemoved);
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
await session.sendCommand('WebMCP.enable');
|
|
77
|
+
} catch (err) {
|
|
78
|
+
if (err.message.includes('\'WebMCP.enable\' wasn\'t found')) {
|
|
79
|
+
this._isSupported = false;
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
throw err;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @param {LH.Gatherer.Context} passContext
|
|
88
|
+
*/
|
|
89
|
+
async stopInstrumentation(passContext) {
|
|
90
|
+
const session = passContext.driver.defaultSession;
|
|
91
|
+
// @ts-expect-error
|
|
92
|
+
session.off('WebMCP.toolsAdded', this._onToolsAdded);
|
|
93
|
+
// @ts-expect-error
|
|
94
|
+
session.off('WebMCP.toolsRemoved', this._onToolsRemoved);
|
|
95
|
+
try {
|
|
96
|
+
await session.sendCommand('WebMCP.disable');
|
|
97
|
+
} catch (err) {
|
|
98
|
+
// Ignore errors
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* @param {LH.Gatherer.Context} context
|
|
104
|
+
* @return {Promise<LH.Artifacts['WebMCP']>}
|
|
105
|
+
*/
|
|
106
|
+
async getArtifact(context) {
|
|
107
|
+
const isSupported = await context.driver.executionContext.evaluate(
|
|
108
|
+
// @ts-expect-error - modelContext is not in types
|
|
109
|
+
() => typeof navigator.modelContext !== 'undefined',
|
|
110
|
+
{args: [], useIsolation: true}
|
|
111
|
+
);
|
|
112
|
+
if (!isSupported || !this._isSupported) {
|
|
113
|
+
return {isSupported: false, tools: []};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const session = context.driver.defaultSession;
|
|
117
|
+
|
|
118
|
+
// Remove duplicates based on name, keeping the latest occurrence.
|
|
119
|
+
const toolMap = new Map();
|
|
120
|
+
for (const tool of this._tools) {
|
|
121
|
+
toolMap.set(tool.name, tool);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const resolvedTools = [];
|
|
125
|
+
for (const tool of toolMap.values()) {
|
|
126
|
+
if (tool.backendNodeId) {
|
|
127
|
+
try {
|
|
128
|
+
const objectId = await resolveNodeIdToObjectId(session, tool.backendNodeId);
|
|
129
|
+
if (objectId) {
|
|
130
|
+
const deps = ExecutionContext.serializeDeps([
|
|
131
|
+
pageFunctions.getNodeDetails,
|
|
132
|
+
]);
|
|
133
|
+
const response = await session.sendCommand('Runtime.callFunctionOn', {
|
|
134
|
+
objectId,
|
|
135
|
+
functionDeclaration: `function () {
|
|
136
|
+
${deps}
|
|
137
|
+
return getNodeDetails(this);
|
|
138
|
+
}`,
|
|
139
|
+
returnByValue: true,
|
|
140
|
+
awaitPromise: true,
|
|
141
|
+
});
|
|
142
|
+
if (response && response.result && response.result.value) {
|
|
143
|
+
tool.nodeDetails = response.result.value;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
} catch (err) {
|
|
147
|
+
// Ignore error
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
resolvedTools.push(tool);
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
isSupported: true,
|
|
154
|
+
tools: resolvedTools,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export default WebMCP;
|
package/core/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export { default as Gatherer } from "./gather/base-gatherer.js";
|
|
|
4
4
|
export { NetworkRecords } from "./computed/network-records.js";
|
|
5
5
|
export { default as defaultConfig } from "./config/default-config.js";
|
|
6
6
|
export { default as desktopConfig } from "./config/desktop-config.js";
|
|
7
|
+
export { default as agenticBrowsingConfig } from "./config/agentic-browsing-config.js";
|
|
7
8
|
export * from "../types/lh.js";
|
|
8
9
|
/**
|
|
9
10
|
* Run Lighthouse.
|
package/core/index.js
CHANGED
|
@@ -121,6 +121,7 @@ export {default as Gatherer} from './gather/base-gatherer.js';
|
|
|
121
121
|
export {NetworkRecords} from './computed/network-records.js';
|
|
122
122
|
export {default as defaultConfig} from './config/default-config.js';
|
|
123
123
|
export {default as desktopConfig} from './config/desktop-config.js';
|
|
124
|
+
export {default as agenticBrowsingConfig} from './config/agentic-browsing-config.js';
|
|
124
125
|
export * from '../types/lh.js';
|
|
125
126
|
export {
|
|
126
127
|
startFlow,
|
|
@@ -381,7 +381,7 @@ class SourceMap {
|
|
|
381
381
|
let nameIndex = 0;
|
|
382
382
|
const names = map.names ?? [];
|
|
383
383
|
const tokenIter = new TokenIterator(map.mappings);
|
|
384
|
-
let sourceURL = this.#sourceInfos[sourceIndex]
|
|
384
|
+
let sourceURL = this.#sourceInfos[sourceIndex]?.sourceURL;
|
|
385
385
|
while (true) {
|
|
386
386
|
if (tokenIter.peek() === ',') {
|
|
387
387
|
tokenIter.next();
|
|
@@ -404,7 +404,7 @@ class SourceMap {
|
|
|
404
404
|
const sourceIndexDelta = tokenIter.nextVLQ();
|
|
405
405
|
if (sourceIndexDelta) {
|
|
406
406
|
sourceIndex += sourceIndexDelta;
|
|
407
|
-
sourceURL = this.#sourceInfos[sourceIndex]
|
|
407
|
+
sourceURL = this.#sourceInfos[sourceIndex]?.sourceURL;
|
|
408
408
|
}
|
|
409
409
|
sourceLineNumber += tokenIter.nextVLQ();
|
|
410
410
|
sourceColumnNumber += tokenIter.nextVLQ();
|