@@ -26,11 +26,11 @@ import { WebSocket, WebSocketServer } from 'ws';
2626import type websocket from 'ws' ;
2727import http from 'node:http' ;
2828import debug from 'debug' ;
29- import { promisify } from 'node:util' ;
30- import { exec } from 'node:child_process' ;
3129import { httpAddressToString , startHttpServer } from '../transport.js' ;
3230import { BrowserContextFactory } from '../browserContextFactory.js' ;
3331import { Browser , chromium , type BrowserContext } from 'playwright' ;
32+ import { spawnAsync } from './spawnAsync.js' ;
33+ import { findChromeExecutable } from './browserRegistry.js' ;
3434
3535const debugLogger = debug ( 'pw:mcp:relay' ) ;
3636
@@ -88,10 +88,13 @@ export class CDPRelayServer {
8888 }
8989
9090 async ensureExtensionConnectionForMCPContext ( clientInfo : { name : string , version : string } ) {
91+ debugLogger ( 'Ensuring extension connection for MCP context' ) ;
9192 if ( this . _extensionConnection )
9293 return ;
9394 await this . _connectBrowser ( clientInfo ) ;
95+ debugLogger ( 'Waiting for incoming extension connection' ) ;
9496 await this . _extensionConnectionPromise ;
97+ debugLogger ( 'Extension connection established' ) ;
9598 }
9699
97100 private async _connectBrowser ( clientInfo : { name : string , version : string } ) {
@@ -101,12 +104,10 @@ export class CDPRelayServer {
101104 url . searchParams . set ( 'mcpRelayUrl' , mcpRelayEndpoint ) ;
102105 url . searchParams . set ( 'client' , JSON . stringify ( clientInfo ) ) ;
103106 const href = url . toString ( ) ;
104- const command = `'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome' '${ href } '` ;
105- try {
106- await promisify ( exec ) ( command ) ;
107- } catch ( err ) {
107+ const chromeExecutablePath = findChromeExecutable ( ) ;
108+ void spawnAsync ( chromeExecutablePath , [ href ] , { detached : true , shell : false } ) . catch ( err => {
108109 debugLogger ( 'Failed to run command:' , err ) ;
109- }
110+ } ) ;
110111 }
111112
112113 stop ( ) : void {
@@ -332,7 +333,7 @@ class ExtensionConnection {
332333
333334 async send ( method : string , params ?: any , sessionId ?: string ) : Promise < any > {
334335 if ( this . _ws . readyState !== WebSocket . OPEN )
335- throw new Error ( ' WebSocket closed' ) ;
336+ throw new Error ( `Unexpected WebSocket state: ${ this . _ws . readyState } ` ) ;
336337 const id = ++ this . _lastId ;
337338 this . _ws . send ( JSON . stringify ( { id, method, params, sessionId } ) ) ;
338339 return new Promise ( ( resolve , reject ) => {
0 commit comments