@guanzhu.me/pw-cli 0.0.18 → 0.0.20
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/package.json +1 -1
- package/src/browser-manager.js +35 -3
package/package.json
CHANGED
package/src/browser-manager.js
CHANGED
|
@@ -9,7 +9,27 @@ const crypto = require('crypto');
|
|
|
9
9
|
const { execSync } = require('child_process');
|
|
10
10
|
const { readState, writeState, clearState, getProfileDir } = require('./state');
|
|
11
11
|
const { probeCDP, findFreePort, sleep, fetchActivePageUrl } = require('./utils');
|
|
12
|
-
|
|
12
|
+
|
|
13
|
+
function loadPlaywrightUtilsBundle() {
|
|
14
|
+
const candidates = [
|
|
15
|
+
'../node_modules/@playwright/cli/node_modules/playwright-core/lib/utilsBundleImpl',
|
|
16
|
+
'../node_modules/@playwright/cli/node_modules/playwright-core/lib/utilsBundleImpl/index.js',
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
for (const candidate of candidates) {
|
|
20
|
+
try {
|
|
21
|
+
return require(candidate);
|
|
22
|
+
} catch (error) {
|
|
23
|
+
if (error.code !== 'MODULE_NOT_FOUND') {
|
|
24
|
+
throw error;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
throw new Error('Unable to load playwright-core utilsBundleImpl from @playwright/cli. Reinstall @playwright/cli or playwright.');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const { ws, wsServer } = loadPlaywrightUtilsBundle();
|
|
13
33
|
|
|
14
34
|
const DAEMON_SCRIPT = path.join(__dirname, 'launch-daemon.js');
|
|
15
35
|
|
|
@@ -242,13 +262,14 @@ class ExtensionConnection {
|
|
|
242
262
|
}
|
|
243
263
|
|
|
244
264
|
class CDPRelayServer {
|
|
245
|
-
constructor(server, browserChannel, userDataDir, executablePath) {
|
|
265
|
+
constructor(server, browserChannel, userDataDir, executablePath, extensionToken) {
|
|
246
266
|
this._playwrightConnection = null;
|
|
247
267
|
this._extensionConnection = null;
|
|
248
268
|
this._nextSessionId = 1;
|
|
249
269
|
this._browserChannel = browserChannel;
|
|
250
270
|
this._userDataDir = userDataDir;
|
|
251
271
|
this._executablePath = executablePath;
|
|
272
|
+
this._extensionToken = extensionToken || null;
|
|
252
273
|
const uuid = crypto.randomUUID();
|
|
253
274
|
const address = server.address();
|
|
254
275
|
this._wsHost = `ws://127.0.0.1:${address.port}`;
|
|
@@ -294,6 +315,9 @@ class CDPRelayServer {
|
|
|
294
315
|
url.searchParams.set('mcpRelayUrl', relayUrl);
|
|
295
316
|
url.searchParams.set('client', JSON.stringify({ name: clientName }));
|
|
296
317
|
url.searchParams.set('protocolVersion', '1');
|
|
318
|
+
if (this._extensionToken) {
|
|
319
|
+
url.searchParams.set('token', this._extensionToken);
|
|
320
|
+
}
|
|
297
321
|
|
|
298
322
|
const executablePath = this._executablePath || resolveExtensionExecutablePath(this._browserChannel);
|
|
299
323
|
const args = [];
|
|
@@ -318,6 +342,13 @@ class CDPRelayServer {
|
|
|
318
342
|
return;
|
|
319
343
|
}
|
|
320
344
|
if (url.pathname === this._extensionPath) {
|
|
345
|
+
if (this._extensionToken) {
|
|
346
|
+
const token = url.searchParams.get('token');
|
|
347
|
+
if (token !== this._extensionToken) {
|
|
348
|
+
socket.close(4003, 'Invalid token');
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
321
352
|
this._handleExtensionConnection(socket);
|
|
322
353
|
return;
|
|
323
354
|
}
|
|
@@ -459,7 +490,8 @@ async function startExtensionRelay(extension) {
|
|
|
459
490
|
server.once('error', reject);
|
|
460
491
|
server.listen(0, '127.0.0.1', resolve);
|
|
461
492
|
});
|
|
462
|
-
const
|
|
493
|
+
const extensionToken = process.env.PLAYWRIGHT_MCP_EXTENSION_TOKEN || null;
|
|
494
|
+
const relay = new CDPRelayServer(server, browser, null, null, extensionToken);
|
|
463
495
|
await relay.ensureExtensionConnectionForMCPContext('pw-cli');
|
|
464
496
|
return { relay, server };
|
|
465
497
|
}
|