mcp-accessibility-scanner 2.0.8 → 2.0.10
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 +48 -1
- package/lib/browserContextFactory.js +68 -0
- package/lib/browserContextFactory.js.map +1 -1
- package/lib/browserServerBackend.js +1 -1
- package/lib/browserServerBackend.js.map +1 -1
- package/lib/config.js +15 -0
- package/lib/config.js.map +1 -1
- package/lib/mcp/http.js +129 -34
- package/lib/mcp/http.js.map +1 -1
- package/lib/mcp/mdb.js +5 -5
- package/lib/mcp/mdb.js.map +1 -1
- package/lib/mcp/proxyBackend.js +18 -4
- package/lib/mcp/proxyBackend.js.map +1 -1
- package/lib/mcp/server.js +8 -4
- 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 +150 -54
- package/lib/program.js.map +1 -1
- package/lib/response.js +34 -1
- package/lib/response.js.map +1 -1
- package/lib/tools/auditKeyboard.js +47 -0
- package/lib/tools/auditKeyboard.js.map +1 -1
- package/lib/tools/auditSite.js +39 -0
- package/lib/tools/auditSite.js.map +1 -1
- package/lib/tools/scanPageMatrix.js +29 -0
- package/lib/tools/scanPageMatrix.js.map +1 -1
- package/lib/vscode/host.js +21 -7
- package/lib/vscode/host.js.map +1 -1
- package/package.json +3 -2
package/lib/mcp/proxyBackend.js
CHANGED
|
@@ -17,19 +17,22 @@ import debug from 'debug';
|
|
|
17
17
|
import { z } from 'zod';
|
|
18
18
|
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
19
19
|
import { ListRootsRequestSchema, PingRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
20
|
+
import { notifyToolListChanged } from './toolListChanged.js';
|
|
20
21
|
const errorsDebug = debug('pw:mcp:errors');
|
|
21
22
|
export class ProxyBackend {
|
|
22
23
|
_mcpProviders;
|
|
23
24
|
_currentClient;
|
|
24
25
|
_contextSwitchTool;
|
|
25
26
|
_roots = [];
|
|
27
|
+
_backendContext;
|
|
26
28
|
constructor(mcpProviders) {
|
|
27
29
|
this._mcpProviders = mcpProviders;
|
|
28
30
|
this._contextSwitchTool = this._defineContextSwitchTool();
|
|
29
31
|
}
|
|
30
|
-
async initialize(
|
|
32
|
+
async initialize(context, clientVersion, roots) {
|
|
33
|
+
this._backendContext = context;
|
|
31
34
|
this._roots = roots;
|
|
32
|
-
await this._setCurrentClient(this._mcpProviders[0]);
|
|
35
|
+
await this._setCurrentClient(this._mcpProviders[0], false);
|
|
33
36
|
}
|
|
34
37
|
async listTools() {
|
|
35
38
|
const response = await this._currentClient.listTools();
|
|
@@ -62,7 +65,7 @@ export class ProxyBackend {
|
|
|
62
65
|
const factory = this._mcpProviders.find(factory => factory.name === params.name);
|
|
63
66
|
if (!factory)
|
|
64
67
|
throw new Error('Unknown connection method: ' + params.name);
|
|
65
|
-
await this._setCurrentClient(factory);
|
|
68
|
+
await this._setCurrentClient(factory, true);
|
|
66
69
|
return {
|
|
67
70
|
content: [{ type: 'text', text: '### Result\nSuccessfully changed connection method.\n' }],
|
|
68
71
|
};
|
|
@@ -105,7 +108,8 @@ export class ProxyBackend {
|
|
|
105
108
|
},
|
|
106
109
|
};
|
|
107
110
|
}
|
|
108
|
-
async _setCurrentClient(factory) {
|
|
111
|
+
async _setCurrentClient(factory, notifyOnChange) {
|
|
112
|
+
const previousTools = notifyOnChange ? await this._getExposedTools(this._currentClient).catch(() => undefined) : undefined;
|
|
109
113
|
await this._currentClient?.close();
|
|
110
114
|
this._currentClient = undefined;
|
|
111
115
|
const client = new Client({ name: 'Playwright MCP Proxy', version: '0.0.0' });
|
|
@@ -119,6 +123,16 @@ export class ProxyBackend {
|
|
|
119
123
|
const transport = await factory.connect();
|
|
120
124
|
await client.connect(transport);
|
|
121
125
|
this._currentClient = client;
|
|
126
|
+
await notifyToolListChanged(this._backendContext, previousTools, await this._getExposedTools(client));
|
|
127
|
+
}
|
|
128
|
+
async _getExposedTools(client) {
|
|
129
|
+
if (!client)
|
|
130
|
+
return [];
|
|
131
|
+
const { tools } = await client.listTools();
|
|
132
|
+
const toolDescriptors = [...tools];
|
|
133
|
+
if (this._mcpProviders.length > 1)
|
|
134
|
+
toolDescriptors.push(this._contextSwitchTool);
|
|
135
|
+
return toolDescriptors;
|
|
122
136
|
}
|
|
123
137
|
}
|
|
124
138
|
//# sourceMappingURL=proxyBackend.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxyBackend.js","sourceRoot":"","sources":["../../src/mcp/proxyBackend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"proxyBackend.js","sourceRoot":"","sources":["../../src/mcp/proxyBackend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAC/F,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAY7D,MAAM,WAAW,GAAG,KAAK,CAAC,eAAe,CAAC,CAAC;AAE3C,MAAM,OAAO,YAAY;IACf,aAAa,CAAgB;IAC7B,cAAc,CAAqB;IACnC,kBAAkB,CAAO;IACzB,MAAM,GAAW,EAAE,CAAC;IACpB,eAAe,CAAmC;IAE1D,YAAY,YAA2B;QACrC,IAAI,CAAC,aAAa,GAAG,YAAY,CAAC;QAClC,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,wBAAwB,EAAE,CAAC;IAC5D,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,OAA6B,EAAE,aAA4B,EAAE,KAAa;QACzF,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC;QAC/B,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAC7D,CAAC;IAED,KAAK,CAAC,SAAS;QACb,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,cAAe,CAAC,SAAS,EAAE,CAAC;QACxD,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC;YACjC,OAAO,QAAQ,CAAC,KAAK,CAAC;QACxB,OAAO;YACL,GAAG,QAAQ,CAAC,KAAK;YACjB,IAAI,CAAC,kBAAkB;SACxB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,IAAY,EAAE,IAA4C,EAAE,cAAuC;QAChH,IAAI,IAAI,KAAK,IAAI,CAAC,kBAAkB,CAAC,IAAI;YACvC,OAAO,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,aAAa,GAAG,cAAc,EAAE,KAAK,EAAE,aAAa,CAAC;QAC3D,OAAO,MAAM,IAAI,CAAC,cAAe,CAAC,QAAQ,CAAC;YACzC,IAAI;YACJ,SAAS,EAAE,IAAI;YACf,KAAK,EAAE,cAAc,EAAE,KAAK;SAC7B,EAAE,SAAS,EAAE,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;YACtD,UAAU,EAAE,MAAM,CAAC,EAAE;gBACnB,KAAK,IAAI,CAAC,4BAA4B,CAAC,cAAc,EAAE,aAAa,EAAE,MAAM,CAAC,CAAC;YAChF,CAAC;SACF,CAAmB,CAAC;IACvB,CAAC;IAED,YAAY;QACV,KAAK,IAAI,CAAC,cAAc,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACvD,CAAC;IAEO,KAAK,CAAC,sBAAsB,CAAC,MAAW;QAC9C,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC;YACjF,IAAI,CAAC,OAAO;gBACV,MAAM,IAAI,KAAK,CAAC,6BAA6B,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;YAE/D,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAC5C,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,uDAAuD,EAAE,CAAC;aAC3F,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,sBAAsB,KAAK,IAAI,EAAE,CAAC;gBAClE,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,4BAA4B,CACxC,cAAkD,EAClD,aAA8B,EAC9B,MAA8D;QAE9D,IAAI,CAAC;YACH,MAAM,cAAc,EAAE,gBAAgB,CAAC;gBACrC,MAAM,EAAE,wBAAwB;gBAChC,MAAM,EAAE;oBACN,aAAa;oBACb,GAAG,MAAM;iBACV;aACF,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,WAAW,CAAC,wDAAwD,EAAE,KAAK,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC;IAEO,wBAAwB;QAC9B,OAAO;YACL,IAAI,EAAE,iBAAiB;YACvB,WAAW,EAAE;gBACX,0DAA0D;gBAC1D,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,IAAI,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC;aACpF,CAAC,IAAI,CAAC,IAAI,CAAC;YACZ,WAAW,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC;gBACnC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAA0B,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,6CAA6C,CAAC;aACnL,CAAC,CAAwB;YAC1B,WAAW,EAAE;gBACX,KAAK,EAAE,8BAA8B;gBACrC,YAAY,EAAE,IAAI;gBAClB,aAAa,EAAE,KAAK;aACrB;SACF,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,OAAoB,EAAE,cAAuB;QAC3E,MAAM,aAAa,GAAG,cAAc,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC3H,MAAM,IAAI,CAAC,cAAc,EAAE,KAAK,EAAE,CAAC;QACnC,IAAI,CAAC,cAAc,GAAG,SAAS,CAAC;QAEhC,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,IAAI,EAAE,sBAAsB,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAC9E,MAAM,CAAC,oBAAoB,CAAC;YAC1B,KAAK,EAAE;gBACL,WAAW,EAAE,IAAI;aAClB;SACF,CAAC,CAAC;QACH,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACjF,MAAM,CAAC,iBAAiB,CAAC,iBAAiB,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAExD,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QAC1C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAChC,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC;QAC7B,MAAM,qBAAqB,CAAC,IAAI,CAAC,eAAe,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;IACxG,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,MAA0B;QACvD,IAAI,CAAC,MAAM;YACT,OAAO,EAAE,CAAC;QAEZ,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,EAAE,CAAC;QAC3C,MAAM,eAAe,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;QACnC,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC;YAC/B,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAChD,OAAO,eAAe,CAAC;IACzB,CAAC;CACF"}
|
package/lib/mcp/server.js
CHANGED
|
@@ -34,7 +34,9 @@ export function createServer(name, version, backend, runHeartbeat) {
|
|
|
34
34
|
const initializedPromise = new Promise(resolve => initializedPromiseResolve = resolve);
|
|
35
35
|
const server = new Server({ name, version }, {
|
|
36
36
|
capabilities: {
|
|
37
|
-
tools: {
|
|
37
|
+
tools: {
|
|
38
|
+
listChanged: true,
|
|
39
|
+
},
|
|
38
40
|
}
|
|
39
41
|
});
|
|
40
42
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
@@ -70,14 +72,17 @@ export function createServer(name, version, backend, runHeartbeat) {
|
|
|
70
72
|
clientRoots = roots;
|
|
71
73
|
}
|
|
72
74
|
const clientVersion = server.getClientVersion() ?? { name: 'unknown', version: 'unknown' };
|
|
73
|
-
|
|
75
|
+
const context = {
|
|
76
|
+
notifyToolListChanged: () => server.sendToolListChanged(),
|
|
77
|
+
};
|
|
78
|
+
await backend.initialize?.(context, clientVersion, clientRoots);
|
|
74
79
|
initializedPromiseResolve();
|
|
75
80
|
}
|
|
76
81
|
catch (e) {
|
|
77
82
|
errorsDebug(e);
|
|
78
83
|
}
|
|
79
84
|
});
|
|
80
|
-
addServerListener(server, 'close', () => backend.serverClosed?.(
|
|
85
|
+
addServerListener(server, 'close', () => backend.serverClosed?.());
|
|
81
86
|
return server;
|
|
82
87
|
}
|
|
83
88
|
const startHeartbeat = (server) => {
|
|
@@ -116,7 +121,6 @@ export async function start(serverBackendFactory, options) {
|
|
|
116
121
|
`Listening on ${url}`,
|
|
117
122
|
'Put this in your client config:',
|
|
118
123
|
JSON.stringify(mcpConfig, undefined, 2),
|
|
119
|
-
'For legacy SSE transport support, you can use the /sse endpoint instead.',
|
|
120
124
|
].join('\n');
|
|
121
125
|
// eslint-disable-next-line no-console
|
|
122
126
|
console.error(message);
|
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;AAEjF,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACvF,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAO7D,MAAM,WAAW,GAAG,KAAK,CAAC,eAAe,CAAC,CAAC;AAC3C,MAAM,WAAW,GAAG,KAAK,CAAC,eAAe,CAAC,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,69 @@ 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-launch-command <command>', 'launch a desktop app command and connect to its CDP endpoint.')
|
|
54
|
+
.option('--cdp-launch-args <args>', 'comma-separated arguments passed to the CDP launch command.', commaSeparatedList)
|
|
55
|
+
.option('--cdp-launch-cwd <path>', 'working directory for the CDP launch command.')
|
|
56
|
+
.option('--cdp-launch-port <port>', 'port to use for the launched app CDP endpoint.', parseInt)
|
|
57
|
+
.option('--cdp-launch-startup-timeout <ms>', 'maximum time in milliseconds to wait for a launched app CDP endpoint.', parseInt)
|
|
58
|
+
.option('--cdp-endpoint <endpoint>', 'CDP endpoint to connect to.')
|
|
59
|
+
.option('--config <path>', 'path to the configuration file.')
|
|
60
|
+
.option('--device <device>', 'device to emulate, for example: "iPhone 15"')
|
|
61
|
+
.option('--executable-path <path>', 'path to the browser executable.')
|
|
62
|
+
.option('--extension', 'Connect to a running browser instance (Edge/Chrome only). Requires the "Playwright MCP Bridge" browser extension to be installed.')
|
|
63
|
+
.option('--headless', 'run browser in headless mode, headed by default')
|
|
64
|
+
.option('--host <host>', 'host to bind server to. Default is localhost. Use 0.0.0.0 to bind to all interfaces.')
|
|
65
|
+
.option('--ignore-https-errors', 'ignore https errors')
|
|
66
|
+
.option('--isolated', 'keep the browser profile in memory, do not save it to disk.')
|
|
67
|
+
.option('--image-responses <mode>', 'whether to send image responses to the client. Can be "allow" or "omit", Defaults to "allow".')
|
|
68
|
+
.option('--no-sandbox', 'disable the sandbox for all process types that are normally sandboxed.')
|
|
69
|
+
.option('--output-dir <path>', 'path to the directory for output files.')
|
|
70
|
+
.option('--port <port>', 'port to listen on for MCP Streamable HTTP transport.')
|
|
71
|
+
.option('--proxy-bypass <bypass>', 'comma-separated domains to bypass proxy, for example ".com,chromium.org,.domain.com"')
|
|
72
|
+
.option('--proxy-server <proxy>', 'specify proxy server, for example "http://myproxy:3128" or "socks5://myproxy:8080"')
|
|
73
|
+
.option('--save-session', 'Whether to save the Playwright MCP session into the output directory.')
|
|
74
|
+
.option('--save-trace', 'Whether to save the Playwright Trace of the session into the output directory.')
|
|
75
|
+
.option('--storage-state <path>', 'path to the storage state file for isolated sessions.')
|
|
76
|
+
.option('--user-agent <ua string>', 'specify user agent string')
|
|
77
|
+
.option('--user-data-dir <path>', 'path to the user data directory. If not specified, a temporary directory will be created.')
|
|
78
|
+
.option('--viewport-size <size>', 'specify browser viewport size in pixels, for example "1280, 720"')
|
|
79
|
+
.option('--navigation-timeout <ms>', 'maximum time in milliseconds for page navigation. Defaults to 60000ms (60 seconds).', parseInt)
|
|
80
|
+
.option('--default-timeout <ms>', 'default timeout for all Playwright operations (clicks, fills, etc). Defaults to 5000ms (5 seconds).', parseInt)
|
|
81
|
+
.addOption(new Option('--connect-tool', 'Allow to switch between different browser connection methods.').hideHelp())
|
|
82
|
+
.addOption(new Option('--vscode', 'VS Code tools.').hideHelp());
|
|
83
|
+
return program;
|
|
84
|
+
}
|
|
85
|
+
configureBaseProgram()
|
|
86
|
+
.action(async (options) => {
|
|
87
|
+
setupExitWatchdog();
|
|
88
|
+
const { config, browserContextFactory, extensionContextFactory } = await resolveProgramContext(options);
|
|
70
89
|
if (options.extension) {
|
|
71
90
|
const serverBackendFactory = {
|
|
72
91
|
name: 'Playwright w/ extension',
|
|
@@ -103,27 +122,104 @@ program
|
|
|
103
122
|
await mcpServer.start(factory, config.server);
|
|
104
123
|
return;
|
|
105
124
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
125
|
+
await startMCPServer(config, browserContextFactory);
|
|
126
|
+
});
|
|
127
|
+
program
|
|
128
|
+
.command('list-tools')
|
|
129
|
+
.description('List available MCP tools')
|
|
130
|
+
.action(async () => {
|
|
131
|
+
const parentOptions = program.opts();
|
|
132
|
+
const { config } = await resolveProgramContext(parentOptions);
|
|
133
|
+
const tools = filteredTools(config);
|
|
134
|
+
for (const tool of tools) {
|
|
135
|
+
// eslint-disable-next-line no-console
|
|
136
|
+
console.log(`${tool.schema.name} ${tool.schema.description}`);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
program
|
|
140
|
+
.command('interactive')
|
|
141
|
+
.description('Start an interactive REPL for manual tool execution')
|
|
142
|
+
.action(async () => {
|
|
143
|
+
const parentOptions = program.opts();
|
|
144
|
+
const { config, browserContextFactory, extensionContextFactory } = await resolveProgramContext(parentOptions);
|
|
145
|
+
const backend = new BrowserServerBackend(config, parentOptions.extension ? extensionContextFactory : browserContextFactory);
|
|
146
|
+
const handleExit = setupExitWatchdog();
|
|
147
|
+
await backend.initialize({ notifyToolListChanged: async () => { } }, { name: 'interactive-cli', version: packageJSON.version }, []);
|
|
148
|
+
const rl = readline.createInterface({
|
|
149
|
+
input: process.stdin,
|
|
150
|
+
output: process.stdout,
|
|
151
|
+
});
|
|
152
|
+
// eslint-disable-next-line no-console
|
|
153
|
+
console.log('Interactive mode. Type "<tool-name> <json>" to call a tool. Ctrl+D to exit.');
|
|
154
|
+
const prompt = () => rl.prompt();
|
|
155
|
+
rl.setPrompt('> ');
|
|
156
|
+
prompt();
|
|
157
|
+
rl.on('line', async (line) => {
|
|
158
|
+
const trimmed = line.trim();
|
|
159
|
+
if (!trimmed) {
|
|
160
|
+
prompt();
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
const spaceIndex = trimmed.indexOf(' ');
|
|
164
|
+
const toolName = spaceIndex === -1 ? trimmed : trimmed.substring(0, spaceIndex);
|
|
165
|
+
const jsonStr = spaceIndex === -1 ? '{}' : trimmed.substring(spaceIndex + 1).trim();
|
|
166
|
+
let args;
|
|
167
|
+
try {
|
|
168
|
+
args = JSON.parse(jsonStr);
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
// eslint-disable-next-line no-console
|
|
172
|
+
console.error(`Invalid JSON: ${jsonStr}`);
|
|
173
|
+
prompt();
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
try {
|
|
177
|
+
const result = await backend.callTool(toolName, args);
|
|
178
|
+
if (result.content) {
|
|
179
|
+
for (const item of result.content) {
|
|
180
|
+
if (item.type === 'text')
|
|
181
|
+
// eslint-disable-next-line no-console
|
|
182
|
+
console.log(item.text);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
// eslint-disable-next-line no-console
|
|
188
|
+
console.error(`Error: ${String(error)}`);
|
|
189
|
+
}
|
|
190
|
+
prompt();
|
|
191
|
+
});
|
|
192
|
+
rl.on('close', () => {
|
|
193
|
+
void handleExit();
|
|
194
|
+
});
|
|
113
195
|
});
|
|
114
|
-
function setupExitWatchdog() {
|
|
196
|
+
function setupExitWatchdog(cleanup = () => Context.disposeAll()) {
|
|
115
197
|
let isExiting = false;
|
|
116
198
|
const handleExit = async () => {
|
|
117
199
|
if (isExiting)
|
|
118
200
|
return;
|
|
119
201
|
isExiting = true;
|
|
120
202
|
setTimeout(() => process.exit(0), 15000);
|
|
121
|
-
|
|
122
|
-
|
|
203
|
+
try {
|
|
204
|
+
await cleanup();
|
|
205
|
+
}
|
|
206
|
+
catch (error) {
|
|
207
|
+
logUnhandledError(error);
|
|
208
|
+
}
|
|
209
|
+
finally {
|
|
210
|
+
process.exit(0);
|
|
211
|
+
}
|
|
123
212
|
};
|
|
124
|
-
process.stdin.on('close',
|
|
125
|
-
|
|
126
|
-
|
|
213
|
+
process.stdin.on('close', () => {
|
|
214
|
+
void handleExit();
|
|
215
|
+
});
|
|
216
|
+
process.on('SIGINT', () => {
|
|
217
|
+
void handleExit();
|
|
218
|
+
});
|
|
219
|
+
process.on('SIGTERM', () => {
|
|
220
|
+
void handleExit();
|
|
221
|
+
});
|
|
222
|
+
return handleExit;
|
|
127
223
|
}
|
|
128
224
|
void program.parseAsync(process.argv);
|
|
129
225
|
//# 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,6 +13,8 @@
|
|
|
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';
|
|
16
18
|
import debug from 'debug';
|
|
17
19
|
import { renderModalStates } from './tab.js';
|
|
18
20
|
const errorsDebug = debug('pw:mcp:errors');
|
|
@@ -20,11 +22,13 @@ export class Response {
|
|
|
20
22
|
_result = [];
|
|
21
23
|
_code = [];
|
|
22
24
|
_images = [];
|
|
25
|
+
_resourceLinks = [];
|
|
23
26
|
_context;
|
|
24
27
|
_includeSnapshot = false;
|
|
25
28
|
_includeTabs = false;
|
|
26
29
|
_tabSnapshot;
|
|
27
30
|
_requestContext;
|
|
31
|
+
_structuredContent;
|
|
28
32
|
toolName;
|
|
29
33
|
toolArgs;
|
|
30
34
|
_isError;
|
|
@@ -59,6 +63,29 @@ export class Response {
|
|
|
59
63
|
images() {
|
|
60
64
|
return this._images;
|
|
61
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
|
+
}
|
|
62
89
|
setIncludeSnapshot() {
|
|
63
90
|
this._includeSnapshot = true;
|
|
64
91
|
}
|
|
@@ -127,12 +154,18 @@ ${this._code.join('\n')}
|
|
|
127
154
|
const content = [
|
|
128
155
|
{ type: 'text', text: response.join('\n') },
|
|
129
156
|
];
|
|
157
|
+
for (const link of this._resourceLinks)
|
|
158
|
+
content.push(link);
|
|
130
159
|
// Image attachments.
|
|
131
160
|
if (this._context.config.imageResponses !== 'omit') {
|
|
132
161
|
for (const image of this._images)
|
|
133
162
|
content.push({ type: 'image', data: image.data.toString('base64'), mimeType: image.contentType });
|
|
134
163
|
}
|
|
135
|
-
return {
|
|
164
|
+
return {
|
|
165
|
+
content,
|
|
166
|
+
structuredContent: this._structuredContent,
|
|
167
|
+
isError: this._isError,
|
|
168
|
+
};
|
|
136
169
|
}
|
|
137
170
|
}
|
|
138
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,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAa7C,MAAM,WAAW,GAAG,KAAK,CAAC,eAAe,CAAC,CAAC;AAE3C,MAAM,OAAO,QAAQ;IACX,OAAO,GAAa,EAAE,CAAC;IACvB,KAAK,GAAa,EAAE,CAAC;IACrB,OAAO,GAA4C,EAAE,CAAC;IACtD,QAAQ,CAAU;IAClB,gBAAgB,GAAG,KAAK,CAAC;IACzB,YAAY,GAAG,KAAK,CAAC;IACrB,YAAY,CAA0B;IACtC,eAAe,CAAqC;
|
|
1
|
+
{"version":3,"file":"response.js","sourceRoot":"","sources":["../src/response.ts"],"names":[],"mappings":"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"}
|
|
@@ -287,6 +287,53 @@ const auditKeyboard = defineTabTool({
|
|
|
287
287
|
const reportFileName = sanitizeForFilePath(params.reportFile ?? `audit-keyboard-${safeIsoTimestampForFileName()}.json`);
|
|
288
288
|
const reportPath = await tab.context.outputFile(reportFileName);
|
|
289
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
|
+
});
|
|
290
337
|
const focusVisibilityPreview = result.focusVisibilityIssues.slice(0, 10).map(stop => (`- Step ${stop.step} (${stop.key}): ${stop.role ?? 'unknown-role'} ${stop.name ?? ''}`.trim()));
|
|
291
338
|
const focusJumpPreview = result.focusJumpIssues.slice(0, 10).map(stop => (`- Step ${stop.step}: deltaY=${stop.scrollDeltaY}, inViewport=${stop.inViewport}`));
|
|
292
339
|
const skipLinkResult = result.skipLink.found
|