mcp-accessibility-scanner 2.0.7 → 2.0.9
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/README.md +81 -1
- package/lib/browserServerBackend.js +3 -3
- package/lib/browserServerBackend.js.map +1 -1
- package/lib/mcp/http.js +129 -34
- package/lib/mcp/http.js.map +1 -1
- package/lib/mcp/mdb.js +9 -8
- package/lib/mcp/mdb.js.map +1 -1
- package/lib/mcp/proxyBackend.js +39 -5
- package/lib/mcp/proxyBackend.js.map +1 -1
- package/lib/mcp/server.js +10 -6
- package/lib/mcp/server.js.map +1 -1
- package/lib/mcp/toolListChanged.js +53 -0
- package/lib/mcp/toolListChanged.js.map +1 -0
- package/lib/program.js +145 -54
- package/lib/program.js.map +1 -1
- package/lib/response.js +58 -2
- package/lib/response.js.map +1 -1
- package/lib/tools/auditKeyboard.js +58 -5
- package/lib/tools/auditKeyboard.js.map +1 -1
- package/lib/tools/auditSite.js +56 -0
- package/lib/tools/auditSite.js.map +1 -1
- package/lib/tools/scanPageMatrix.js +34 -0
- package/lib/tools/scanPageMatrix.js.map +1 -1
- package/lib/vscode/host.js +25 -10
- package/lib/vscode/host.js.map +1 -1
- package/package.json +4 -2
package/lib/mcp/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AACnG,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import debug from 'debug';
|
|
17
|
+
const errorsDebug = debug('pw:mcp:errors');
|
|
18
|
+
export function haveToolNamesChanged(previousTools, nextTools) {
|
|
19
|
+
if (!previousTools)
|
|
20
|
+
return true;
|
|
21
|
+
if (previousTools.length !== nextTools.length)
|
|
22
|
+
return true;
|
|
23
|
+
for (let index = 0; index < nextTools.length; index++) {
|
|
24
|
+
if (stableSerializeTool(previousTools[index]) !== stableSerializeTool(nextTools[index]))
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
function stableSerializeTool(tool) {
|
|
30
|
+
return JSON.stringify(canonicalize(tool));
|
|
31
|
+
}
|
|
32
|
+
function canonicalize(value) {
|
|
33
|
+
if (Array.isArray(value))
|
|
34
|
+
return value.map(item => canonicalize(item));
|
|
35
|
+
if (value && typeof value === 'object') {
|
|
36
|
+
return Object.fromEntries(Object.entries(value)
|
|
37
|
+
.filter(([, entryValue]) => entryValue !== undefined)
|
|
38
|
+
.sort(([leftKey], [rightKey]) => leftKey.localeCompare(rightKey))
|
|
39
|
+
.map(([key, entryValue]) => [key, canonicalize(entryValue)]));
|
|
40
|
+
}
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
export async function notifyToolListChanged(context, previousTools, nextTools) {
|
|
44
|
+
if (!context || !haveToolNamesChanged(previousTools, nextTools))
|
|
45
|
+
return;
|
|
46
|
+
try {
|
|
47
|
+
await context.notifyToolListChanged();
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
errorsDebug('Failed to send tool list changed notification: %o', error);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=toolListChanged.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolListChanged.js","sourceRoot":"","sources":["../../src/mcp/toolListChanged.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,WAAW,GAAG,KAAK,CAAC,eAAe,CAAC,CAAC;AAI3C,MAAM,UAAU,oBAAoB,CAAC,aAA2C,EAAE,SAA2B;IAC3G,IAAI,CAAC,aAAa;QAChB,OAAO,IAAI,CAAC;IAEd,IAAI,aAAa,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM;QAC3C,OAAO,IAAI,CAAC;IAEd,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QACtD,IAAI,mBAAmB,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,KAAK,mBAAmB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YACrF,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAoB;IAC/C,OAAO,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,YAAY,CAAC,KAAc;IAClC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACtB,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;IAC/C,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,OAAO,MAAM,CAAC,WAAW,CACrB,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;aAChB,MAAM,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,UAAU,KAAK,SAAS,CAAC;aACpD,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;aAChE,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,CACnE,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,OAAyC,EAAE,aAA2C,EAAE,SAA2B;IAC7J,IAAI,CAAC,OAAO,IAAI,CAAC,oBAAoB,CAAC,aAAa,EAAE,SAAS,CAAC;QAC7D,OAAO;IAET,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,qBAAqB,EAAE,CAAC;IACxC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,WAAW,CAAC,mDAAmD,EAAE,KAAK,CAAC,CAAC;IAC1E,CAAC;AACH,CAAC"}
|
package/lib/program.js
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
+
import readline from 'node:readline';
|
|
16
17
|
import { program, Option } from 'commander';
|
|
17
18
|
import * as mcpServer from './mcp/server.js';
|
|
18
19
|
import { commaSeparatedList, resolveCLIConfig, semicolonSeparatedList } from './config.js';
|
|
@@ -22,51 +23,64 @@ import { contextFactory } from './browserContextFactory.js';
|
|
|
22
23
|
import { ProxyBackend } from './mcp/proxyBackend.js';
|
|
23
24
|
import { BrowserServerBackend } from './browserServerBackend.js';
|
|
24
25
|
import { ExtensionContextFactory } from './extension/extensionContextFactory.js';
|
|
26
|
+
import { filteredTools } from './tools.js';
|
|
27
|
+
import { logUnhandledError } from './utils/log.js';
|
|
25
28
|
import { runVSCodeTools } from './vscode/host.js';
|
|
26
|
-
|
|
27
|
-
.version('Version ' + packageJSON.version)
|
|
28
|
-
.name(packageJSON.name)
|
|
29
|
-
.option('--allowed-origins <origins>', 'semicolon-separated list of origins to allow the browser to request. Default is to allow all.', semicolonSeparatedList)
|
|
30
|
-
.option('--blocked-origins <origins>', 'semicolon-separated list of origins to block the browser from requesting. Blocklist is evaluated before allowlist. If used without the allowlist, requests not matching the blocklist are still allowed.', semicolonSeparatedList)
|
|
31
|
-
.option('--block-service-workers', 'block service workers')
|
|
32
|
-
.option('--browser <browser>', 'browser or chrome channel to use, possible values: chrome, firefox, webkit, msedge.')
|
|
33
|
-
.option('--caps <caps>', 'comma-separated list of additional capabilities to enable, possible values: vision, pdf.', commaSeparatedList)
|
|
34
|
-
.option('--cdp-endpoint <endpoint>', 'CDP endpoint to connect to.')
|
|
35
|
-
.option('--config <path>', 'path to the configuration file.')
|
|
36
|
-
.option('--device <device>', 'device to emulate, for example: "iPhone 15"')
|
|
37
|
-
.option('--executable-path <path>', 'path to the browser executable.')
|
|
38
|
-
.option('--extension', 'Connect to a running browser instance (Edge/Chrome only). Requires the "Playwright MCP Bridge" browser extension to be installed.')
|
|
39
|
-
.option('--headless', 'run browser in headless mode, headed by default')
|
|
40
|
-
.option('--host <host>', 'host to bind server to. Default is localhost. Use 0.0.0.0 to bind to all interfaces.')
|
|
41
|
-
.option('--ignore-https-errors', 'ignore https errors')
|
|
42
|
-
.option('--isolated', 'keep the browser profile in memory, do not save it to disk.')
|
|
43
|
-
.option('--image-responses <mode>', 'whether to send image responses to the client. Can be "allow" or "omit", Defaults to "allow".')
|
|
44
|
-
.option('--no-sandbox', 'disable the sandbox for all process types that are normally sandboxed.')
|
|
45
|
-
.option('--output-dir <path>', 'path to the directory for output files.')
|
|
46
|
-
.option('--port <port>', 'port to listen on for SSE transport.')
|
|
47
|
-
.option('--proxy-bypass <bypass>', 'comma-separated domains to bypass proxy, for example ".com,chromium.org,.domain.com"')
|
|
48
|
-
.option('--proxy-server <proxy>', 'specify proxy server, for example "http://myproxy:3128" or "socks5://myproxy:8080"')
|
|
49
|
-
.option('--save-session', 'Whether to save the Playwright MCP session into the output directory.')
|
|
50
|
-
.option('--save-trace', 'Whether to save the Playwright Trace of the session into the output directory.')
|
|
51
|
-
.option('--storage-state <path>', 'path to the storage state file for isolated sessions.')
|
|
52
|
-
.option('--user-agent <ua string>', 'specify user agent string')
|
|
53
|
-
.option('--user-data-dir <path>', 'path to the user data directory. If not specified, a temporary directory will be created.')
|
|
54
|
-
.option('--viewport-size <size>', 'specify browser viewport size in pixels, for example "1280, 720"')
|
|
55
|
-
.option('--navigation-timeout <ms>', 'maximum time in milliseconds for page navigation. Defaults to 60000ms (60 seconds).', parseInt)
|
|
56
|
-
.option('--default-timeout <ms>', 'default timeout for all Playwright operations (clicks, fills, etc). Defaults to 5000ms (5 seconds).', parseInt)
|
|
57
|
-
.addOption(new Option('--connect-tool', 'Allow to switch between different browser connection methods.').hideHelp())
|
|
58
|
-
.addOption(new Option('--vscode', 'VS Code tools.').hideHelp())
|
|
59
|
-
.addOption(new Option('--vision', 'Legacy option, use --caps=vision instead').hideHelp())
|
|
60
|
-
.action(async (options) => {
|
|
61
|
-
setupExitWatchdog();
|
|
62
|
-
if (options.vision) {
|
|
63
|
-
// eslint-disable-next-line no-console
|
|
64
|
-
console.error('The --vision option is deprecated, use --caps=vision instead');
|
|
65
|
-
options.caps = 'vision';
|
|
66
|
-
}
|
|
29
|
+
async function resolveProgramContext(options) {
|
|
67
30
|
const config = await resolveCLIConfig(options);
|
|
68
31
|
const browserContextFactory = contextFactory(config);
|
|
69
32
|
const extensionContextFactory = new ExtensionContextFactory(config.browser.launchOptions.channel || 'chrome', config.browser.userDataDir, config.browser.launchOptions.executablePath);
|
|
33
|
+
return { config, browserContextFactory, extensionContextFactory };
|
|
34
|
+
}
|
|
35
|
+
async function startMCPServer(config, browserContextFactory) {
|
|
36
|
+
const factory = {
|
|
37
|
+
name: 'Playwright',
|
|
38
|
+
nameInConfig: 'playwright',
|
|
39
|
+
version: packageJSON.version,
|
|
40
|
+
create: () => new BrowserServerBackend(config, browserContextFactory)
|
|
41
|
+
};
|
|
42
|
+
await mcpServer.start(factory, config.server);
|
|
43
|
+
}
|
|
44
|
+
function configureBaseProgram() {
|
|
45
|
+
program
|
|
46
|
+
.version('Version ' + packageJSON.version)
|
|
47
|
+
.name(packageJSON.name)
|
|
48
|
+
.option('--allowed-origins <origins>', 'semicolon-separated list of origins to allow the browser to request. Default is to allow all.', semicolonSeparatedList)
|
|
49
|
+
.option('--blocked-origins <origins>', 'semicolon-separated list of origins to block the browser from requesting. Blocklist is evaluated before allowlist. If used without the allowlist, requests not matching the blocklist are still allowed.', semicolonSeparatedList)
|
|
50
|
+
.option('--block-service-workers', 'block service workers')
|
|
51
|
+
.option('--browser <browser>', 'browser or chrome channel to use, possible values: chrome, firefox, webkit, msedge.')
|
|
52
|
+
.option('--caps <caps>', 'comma-separated list of additional capabilities to enable, possible values: vision, pdf.', commaSeparatedList)
|
|
53
|
+
.option('--cdp-endpoint <endpoint>', 'CDP endpoint to connect to.')
|
|
54
|
+
.option('--config <path>', 'path to the configuration file.')
|
|
55
|
+
.option('--device <device>', 'device to emulate, for example: "iPhone 15"')
|
|
56
|
+
.option('--executable-path <path>', 'path to the browser executable.')
|
|
57
|
+
.option('--extension', 'Connect to a running browser instance (Edge/Chrome only). Requires the "Playwright MCP Bridge" browser extension to be installed.')
|
|
58
|
+
.option('--headless', 'run browser in headless mode, headed by default')
|
|
59
|
+
.option('--host <host>', 'host to bind server to. Default is localhost. Use 0.0.0.0 to bind to all interfaces.')
|
|
60
|
+
.option('--ignore-https-errors', 'ignore https errors')
|
|
61
|
+
.option('--isolated', 'keep the browser profile in memory, do not save it to disk.')
|
|
62
|
+
.option('--image-responses <mode>', 'whether to send image responses to the client. Can be "allow" or "omit", Defaults to "allow".')
|
|
63
|
+
.option('--no-sandbox', 'disable the sandbox for all process types that are normally sandboxed.')
|
|
64
|
+
.option('--output-dir <path>', 'path to the directory for output files.')
|
|
65
|
+
.option('--port <port>', 'port to listen on for MCP Streamable HTTP transport.')
|
|
66
|
+
.option('--proxy-bypass <bypass>', 'comma-separated domains to bypass proxy, for example ".com,chromium.org,.domain.com"')
|
|
67
|
+
.option('--proxy-server <proxy>', 'specify proxy server, for example "http://myproxy:3128" or "socks5://myproxy:8080"')
|
|
68
|
+
.option('--save-session', 'Whether to save the Playwright MCP session into the output directory.')
|
|
69
|
+
.option('--save-trace', 'Whether to save the Playwright Trace of the session into the output directory.')
|
|
70
|
+
.option('--storage-state <path>', 'path to the storage state file for isolated sessions.')
|
|
71
|
+
.option('--user-agent <ua string>', 'specify user agent string')
|
|
72
|
+
.option('--user-data-dir <path>', 'path to the user data directory. If not specified, a temporary directory will be created.')
|
|
73
|
+
.option('--viewport-size <size>', 'specify browser viewport size in pixels, for example "1280, 720"')
|
|
74
|
+
.option('--navigation-timeout <ms>', 'maximum time in milliseconds for page navigation. Defaults to 60000ms (60 seconds).', parseInt)
|
|
75
|
+
.option('--default-timeout <ms>', 'default timeout for all Playwright operations (clicks, fills, etc). Defaults to 5000ms (5 seconds).', parseInt)
|
|
76
|
+
.addOption(new Option('--connect-tool', 'Allow to switch between different browser connection methods.').hideHelp())
|
|
77
|
+
.addOption(new Option('--vscode', 'VS Code tools.').hideHelp());
|
|
78
|
+
return program;
|
|
79
|
+
}
|
|
80
|
+
configureBaseProgram()
|
|
81
|
+
.action(async (options) => {
|
|
82
|
+
setupExitWatchdog();
|
|
83
|
+
const { config, browserContextFactory, extensionContextFactory } = await resolveProgramContext(options);
|
|
70
84
|
if (options.extension) {
|
|
71
85
|
const serverBackendFactory = {
|
|
72
86
|
name: 'Playwright w/ extension',
|
|
@@ -103,27 +117,104 @@ program
|
|
|
103
117
|
await mcpServer.start(factory, config.server);
|
|
104
118
|
return;
|
|
105
119
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
120
|
+
await startMCPServer(config, browserContextFactory);
|
|
121
|
+
});
|
|
122
|
+
program
|
|
123
|
+
.command('list-tools')
|
|
124
|
+
.description('List available MCP tools')
|
|
125
|
+
.action(async () => {
|
|
126
|
+
const parentOptions = program.opts();
|
|
127
|
+
const { config } = await resolveProgramContext(parentOptions);
|
|
128
|
+
const tools = filteredTools(config);
|
|
129
|
+
for (const tool of tools) {
|
|
130
|
+
// eslint-disable-next-line no-console
|
|
131
|
+
console.log(`${tool.schema.name} ${tool.schema.description}`);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
program
|
|
135
|
+
.command('interactive')
|
|
136
|
+
.description('Start an interactive REPL for manual tool execution')
|
|
137
|
+
.action(async () => {
|
|
138
|
+
const parentOptions = program.opts();
|
|
139
|
+
const { config, browserContextFactory, extensionContextFactory } = await resolveProgramContext(parentOptions);
|
|
140
|
+
const backend = new BrowserServerBackend(config, parentOptions.extension ? extensionContextFactory : browserContextFactory);
|
|
141
|
+
const handleExit = setupExitWatchdog();
|
|
142
|
+
await backend.initialize({ notifyToolListChanged: async () => { } }, { name: 'interactive-cli', version: packageJSON.version }, []);
|
|
143
|
+
const rl = readline.createInterface({
|
|
144
|
+
input: process.stdin,
|
|
145
|
+
output: process.stdout,
|
|
146
|
+
});
|
|
147
|
+
// eslint-disable-next-line no-console
|
|
148
|
+
console.log('Interactive mode. Type "<tool-name> <json>" to call a tool. Ctrl+D to exit.');
|
|
149
|
+
const prompt = () => rl.prompt();
|
|
150
|
+
rl.setPrompt('> ');
|
|
151
|
+
prompt();
|
|
152
|
+
rl.on('line', async (line) => {
|
|
153
|
+
const trimmed = line.trim();
|
|
154
|
+
if (!trimmed) {
|
|
155
|
+
prompt();
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const spaceIndex = trimmed.indexOf(' ');
|
|
159
|
+
const toolName = spaceIndex === -1 ? trimmed : trimmed.substring(0, spaceIndex);
|
|
160
|
+
const jsonStr = spaceIndex === -1 ? '{}' : trimmed.substring(spaceIndex + 1).trim();
|
|
161
|
+
let args;
|
|
162
|
+
try {
|
|
163
|
+
args = JSON.parse(jsonStr);
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
// eslint-disable-next-line no-console
|
|
167
|
+
console.error(`Invalid JSON: ${jsonStr}`);
|
|
168
|
+
prompt();
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
try {
|
|
172
|
+
const result = await backend.callTool(toolName, args);
|
|
173
|
+
if (result.content) {
|
|
174
|
+
for (const item of result.content) {
|
|
175
|
+
if (item.type === 'text')
|
|
176
|
+
// eslint-disable-next-line no-console
|
|
177
|
+
console.log(item.text);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
// eslint-disable-next-line no-console
|
|
183
|
+
console.error(`Error: ${String(error)}`);
|
|
184
|
+
}
|
|
185
|
+
prompt();
|
|
186
|
+
});
|
|
187
|
+
rl.on('close', () => {
|
|
188
|
+
void handleExit();
|
|
189
|
+
});
|
|
113
190
|
});
|
|
114
|
-
function setupExitWatchdog() {
|
|
191
|
+
function setupExitWatchdog(cleanup = () => Context.disposeAll()) {
|
|
115
192
|
let isExiting = false;
|
|
116
193
|
const handleExit = async () => {
|
|
117
194
|
if (isExiting)
|
|
118
195
|
return;
|
|
119
196
|
isExiting = true;
|
|
120
197
|
setTimeout(() => process.exit(0), 15000);
|
|
121
|
-
|
|
122
|
-
|
|
198
|
+
try {
|
|
199
|
+
await cleanup();
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
logUnhandledError(error);
|
|
203
|
+
}
|
|
204
|
+
finally {
|
|
205
|
+
process.exit(0);
|
|
206
|
+
}
|
|
123
207
|
};
|
|
124
|
-
process.stdin.on('close',
|
|
125
|
-
|
|
126
|
-
|
|
208
|
+
process.stdin.on('close', () => {
|
|
209
|
+
void handleExit();
|
|
210
|
+
});
|
|
211
|
+
process.on('SIGINT', () => {
|
|
212
|
+
void handleExit();
|
|
213
|
+
});
|
|
214
|
+
process.on('SIGTERM', () => {
|
|
215
|
+
void handleExit();
|
|
216
|
+
});
|
|
217
|
+
return handleExit;
|
|
127
218
|
}
|
|
128
219
|
void program.parseAsync(process.argv);
|
|
129
220
|
//# sourceMappingURL=program.js.map
|
package/lib/program.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"program.js","sourceRoot":"","sources":["../src/program.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC3F,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;
|
|
1
|
+
{"version":3,"file":"program.js","sourceRoot":"","sources":["../src/program.ts"],"names":[],"mappings":"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"}
|
package/lib/response.js
CHANGED
|
@@ -13,22 +13,30 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
+
import { basename } from 'path';
|
|
17
|
+
import { pathToFileURL } from 'url';
|
|
18
|
+
import debug from 'debug';
|
|
16
19
|
import { renderModalStates } from './tab.js';
|
|
20
|
+
const errorsDebug = debug('pw:mcp:errors');
|
|
17
21
|
export class Response {
|
|
18
22
|
_result = [];
|
|
19
23
|
_code = [];
|
|
20
24
|
_images = [];
|
|
25
|
+
_resourceLinks = [];
|
|
21
26
|
_context;
|
|
22
27
|
_includeSnapshot = false;
|
|
23
28
|
_includeTabs = false;
|
|
24
29
|
_tabSnapshot;
|
|
30
|
+
_requestContext;
|
|
31
|
+
_structuredContent;
|
|
25
32
|
toolName;
|
|
26
33
|
toolArgs;
|
|
27
34
|
_isError;
|
|
28
|
-
constructor(context, toolName, toolArgs) {
|
|
35
|
+
constructor(context, toolName, toolArgs, requestContext) {
|
|
29
36
|
this._context = context;
|
|
30
37
|
this.toolName = toolName;
|
|
31
38
|
this.toolArgs = toolArgs;
|
|
39
|
+
this._requestContext = requestContext;
|
|
32
40
|
}
|
|
33
41
|
addResult(result) {
|
|
34
42
|
this._result.push(result);
|
|
@@ -55,12 +63,54 @@ export class Response {
|
|
|
55
63
|
images() {
|
|
56
64
|
return this._images;
|
|
57
65
|
}
|
|
66
|
+
addResourceLink(link) {
|
|
67
|
+
this._resourceLinks.push(link);
|
|
68
|
+
return link;
|
|
69
|
+
}
|
|
70
|
+
addFileResourceLink(filePath, options) {
|
|
71
|
+
return this.addResourceLink({
|
|
72
|
+
type: 'resource_link',
|
|
73
|
+
uri: pathToFileURL(filePath).toString(),
|
|
74
|
+
name: options?.name ?? basename(filePath),
|
|
75
|
+
title: options?.title,
|
|
76
|
+
description: options?.description,
|
|
77
|
+
mimeType: options?.mimeType,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
resourceLinks() {
|
|
81
|
+
return this._resourceLinks;
|
|
82
|
+
}
|
|
83
|
+
setStructuredContent(content) {
|
|
84
|
+
this._structuredContent = content;
|
|
85
|
+
}
|
|
86
|
+
structuredContent() {
|
|
87
|
+
return this._structuredContent;
|
|
88
|
+
}
|
|
58
89
|
setIncludeSnapshot() {
|
|
59
90
|
this._includeSnapshot = true;
|
|
60
91
|
}
|
|
61
92
|
setIncludeTabs() {
|
|
62
93
|
this._includeTabs = true;
|
|
63
94
|
}
|
|
95
|
+
async reportProgress(update) {
|
|
96
|
+
const progressToken = this._requestContext?._meta?.progressToken;
|
|
97
|
+
if (progressToken === undefined)
|
|
98
|
+
return;
|
|
99
|
+
try {
|
|
100
|
+
await this._requestContext?.sendNotification({
|
|
101
|
+
method: 'notifications/progress',
|
|
102
|
+
params: {
|
|
103
|
+
progressToken,
|
|
104
|
+
progress: update.progress,
|
|
105
|
+
total: update.total,
|
|
106
|
+
message: update.message,
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
errorsDebug('Failed to send progress notification for token %o with update %o: %o', progressToken, update, error);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
64
114
|
async finish() {
|
|
65
115
|
// All the async snapshotting post-action is happening here.
|
|
66
116
|
// Everything below should race against modal states.
|
|
@@ -104,12 +154,18 @@ ${this._code.join('\n')}
|
|
|
104
154
|
const content = [
|
|
105
155
|
{ type: 'text', text: response.join('\n') },
|
|
106
156
|
];
|
|
157
|
+
for (const link of this._resourceLinks)
|
|
158
|
+
content.push(link);
|
|
107
159
|
// Image attachments.
|
|
108
160
|
if (this._context.config.imageResponses !== 'omit') {
|
|
109
161
|
for (const image of this._images)
|
|
110
162
|
content.push({ type: 'image', data: image.data.toString('base64'), mimeType: image.contentType });
|
|
111
163
|
}
|
|
112
|
-
return {
|
|
164
|
+
return {
|
|
165
|
+
content,
|
|
166
|
+
structuredContent: this._structuredContent,
|
|
167
|
+
isError: this._isError,
|
|
168
|
+
};
|
|
113
169
|
}
|
|
114
170
|
}
|
|
115
171
|
function renderTabSnapshot(tabSnapshot) {
|
package/lib/response.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"response.js","sourceRoot":"","sources":["../src/response.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"response.js","sourceRoot":"","sources":["../src/response.ts"],"names":[],"mappings":"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"}
|
|
@@ -112,8 +112,8 @@ export async function runKeyboardFocusAudit(options, callbacks) {
|
|
|
112
112
|
skipLinkActivated = true;
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
|
+
let shouldStopOnCycle = false;
|
|
115
116
|
if (options.checkFocusTrap) {
|
|
116
|
-
let shouldStopOnCycle = false;
|
|
117
117
|
const recentStops = stops.slice(Math.max(0, stops.length - options.cycleWindow + 1));
|
|
118
118
|
const foundRepeat = recentStops.some(previous => previous.fingerprint === stop.fingerprint);
|
|
119
119
|
const touchedDocumentRoot = recentStops.some(previous => previous.tagName === 'HTML' || previous.tagName === 'BODY') || stop.tagName === 'HTML' || stop.tagName === 'BODY';
|
|
@@ -126,12 +126,11 @@ export async function runKeyboardFocusAudit(options, callbacks) {
|
|
|
126
126
|
if (options.stopOnCycle)
|
|
127
127
|
shouldStopOnCycle = true;
|
|
128
128
|
}
|
|
129
|
-
stops.push(stop);
|
|
130
|
-
if (shouldStopOnCycle)
|
|
131
|
-
break;
|
|
132
|
-
continue;
|
|
133
129
|
}
|
|
134
130
|
stops.push(stop);
|
|
131
|
+
await callbacks.onStep?.(stop);
|
|
132
|
+
if (shouldStopOnCycle)
|
|
133
|
+
break;
|
|
135
134
|
}
|
|
136
135
|
return {
|
|
137
136
|
stops,
|
|
@@ -263,6 +262,13 @@ const auditKeyboard = defineTabTool({
|
|
|
263
262
|
});
|
|
264
263
|
},
|
|
265
264
|
getActiveElementInfo,
|
|
265
|
+
onStep: async (stop) => {
|
|
266
|
+
await response.reportProgress({
|
|
267
|
+
progress: stop.step,
|
|
268
|
+
total: params.maxTabs,
|
|
269
|
+
message: `Processed keyboard step ${stop.step}/${params.maxTabs}: ${stop.key}`,
|
|
270
|
+
});
|
|
271
|
+
},
|
|
266
272
|
getCurrentUrl: async () => tab.page.url(),
|
|
267
273
|
goBack: async () => {
|
|
268
274
|
await tab.page.goBack({ waitUntil: 'domcontentloaded' });
|
|
@@ -281,6 +287,53 @@ const auditKeyboard = defineTabTool({
|
|
|
281
287
|
const reportFileName = sanitizeForFilePath(params.reportFile ?? `audit-keyboard-${safeIsoTimestampForFileName()}.json`);
|
|
282
288
|
const reportPath = await tab.context.outputFile(reportFileName);
|
|
283
289
|
await fs.promises.writeFile(reportPath, JSON.stringify(report, null, 2), 'utf-8');
|
|
290
|
+
const reportResourceLink = response.addFileResourceLink(reportPath, {
|
|
291
|
+
name: 'audit-keyboard-report',
|
|
292
|
+
title: 'Audit keyboard JSON report',
|
|
293
|
+
description: 'JSON report for keyboard navigation, focus, and skip-link findings.',
|
|
294
|
+
mimeType: 'application/json',
|
|
295
|
+
});
|
|
296
|
+
const screenshotResources = result.screenshots.map((screenshotPath, index) => {
|
|
297
|
+
const link = response.addFileResourceLink(screenshotPath, {
|
|
298
|
+
name: `audit-keyboard-screenshot-${index + 1}`,
|
|
299
|
+
title: `Audit keyboard issue screenshot ${index + 1}`,
|
|
300
|
+
description: `Screenshot captured for keyboard audit issue ${index + 1}.`,
|
|
301
|
+
mimeType: 'image/png',
|
|
302
|
+
});
|
|
303
|
+
return {
|
|
304
|
+
path: screenshotPath,
|
|
305
|
+
uri: link.uri,
|
|
306
|
+
name: link.name,
|
|
307
|
+
title: link.title ?? null,
|
|
308
|
+
mimeType: link.mimeType ?? null,
|
|
309
|
+
};
|
|
310
|
+
});
|
|
311
|
+
response.setStructuredContent({
|
|
312
|
+
kind: 'audit_keyboard',
|
|
313
|
+
report: {
|
|
314
|
+
path: reportPath,
|
|
315
|
+
uri: reportResourceLink.uri,
|
|
316
|
+
name: reportResourceLink.name,
|
|
317
|
+
title: reportResourceLink.title ?? null,
|
|
318
|
+
mimeType: reportResourceLink.mimeType ?? null,
|
|
319
|
+
},
|
|
320
|
+
page: {
|
|
321
|
+
url: tab.page.url(),
|
|
322
|
+
},
|
|
323
|
+
summary: {
|
|
324
|
+
uniqueFocusStops: result.uniqueFingerprints,
|
|
325
|
+
skipLinkFound: result.skipLink.found,
|
|
326
|
+
skipLinkStep: result.skipLink.step,
|
|
327
|
+
skipLinkActivated: result.skipLink.activated,
|
|
328
|
+
focusVisibilityIssueCount: result.focusVisibilityIssues.length,
|
|
329
|
+
focusJumpIssueCount: result.focusJumpIssues.length,
|
|
330
|
+
focusTrapDetected: result.focusTrap.detected,
|
|
331
|
+
focusTrapStep: result.focusTrap.step,
|
|
332
|
+
screenshotCount: result.screenshots.length,
|
|
333
|
+
},
|
|
334
|
+
screenshots: screenshotResources,
|
|
335
|
+
reportUri: reportResourceLink.uri,
|
|
336
|
+
});
|
|
284
337
|
const focusVisibilityPreview = result.focusVisibilityIssues.slice(0, 10).map(stop => (`- Step ${stop.step} (${stop.key}): ${stop.role ?? 'unknown-role'} ${stop.name ?? ''}`.trim()));
|
|
285
338
|
const focusJumpPreview = result.focusJumpIssues.slice(0, 10).map(stop => (`- Step ${stop.step}: deltaY=${stop.scrollDeltaY}, inViewport=${stop.inViewport}`));
|
|
286
339
|
const skipLinkResult = result.skipLink.found
|