Add unified mcpLog for relay server and stderr logging
This commit is contained in:
+22
-12
@@ -189,6 +189,15 @@ async function sendLogToRelayServer(level: string, ...args: any[]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log to both console.error (for early startup) and relay server log file.
|
||||||
|
* Fire-and-forget to avoid blocking.
|
||||||
|
*/
|
||||||
|
function mcpLog(...args: any[]) {
|
||||||
|
console.error(...args)
|
||||||
|
sendLogToRelayServer('log', ...args)
|
||||||
|
}
|
||||||
|
|
||||||
async function getServerVersion(port: number): Promise<string | null> {
|
async function getServerVersion(port: number): Promise<string | null> {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`http://127.0.0.1:${port}/version`, {
|
const response = await fetch(`http://127.0.0.1:${port}/version`, {
|
||||||
@@ -246,10 +255,10 @@ async function ensureRelayServer(): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (serverVersion !== null) {
|
if (serverVersion !== null) {
|
||||||
console.error(`CDP relay server version mismatch (server: ${serverVersion}, mcp: ${VERSION}), restarting...`)
|
mcpLog(`CDP relay server version mismatch (server: ${serverVersion}, mcp: ${VERSION}), restarting...`)
|
||||||
await killRelayServer(RELAY_PORT)
|
await killRelayServer(RELAY_PORT)
|
||||||
} else {
|
} else {
|
||||||
console.error('CDP relay server not running, starting it...')
|
mcpLog('CDP relay server not running, starting it...')
|
||||||
}
|
}
|
||||||
|
|
||||||
const scriptPath = require.resolve('../dist/start-relay-server.js')
|
const scriptPath = require.resolve('../dist/start-relay-server.js')
|
||||||
@@ -265,7 +274,7 @@ async function ensureRelayServer(): Promise<void> {
|
|||||||
await sleep(500)
|
await sleep(500)
|
||||||
const newVersion = await getServerVersion(RELAY_PORT)
|
const newVersion = await getServerVersion(RELAY_PORT)
|
||||||
if (newVersion === VERSION) {
|
if (newVersion === VERSION) {
|
||||||
console.error('CDP relay server started successfully, waiting for extension to connect...')
|
mcpLog('CDP relay server started successfully, waiting for extension to connect...')
|
||||||
await sleep(1000)
|
await sleep(1000)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -370,7 +379,7 @@ function setupPageConsoleListener(page: Page) {
|
|||||||
pageLogs.shift()
|
pageLogs.shift()
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('[MCP] Failed to get console message text:', e)
|
mcpLog('[MCP] Failed to get console message text:', e)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -402,7 +411,7 @@ async function resetConnection(): Promise<{ browser: Browser; page: Page; contex
|
|||||||
try {
|
try {
|
||||||
await state.browser.close()
|
await state.browser.close()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Error closing browser:', e)
|
mcpLog('Error closing browser:', e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -547,7 +556,7 @@ server.tool(
|
|||||||
const page = await getCurrentPage(timeout)
|
const page = await getCurrentPage(timeout)
|
||||||
const context = state.context || page.context()
|
const context = state.context || page.context()
|
||||||
|
|
||||||
console.error('Executing code:', code)
|
mcpLog('Executing code:', code)
|
||||||
|
|
||||||
const customConsole = {
|
const customConsole = {
|
||||||
log: (...args: any[]) => {
|
log: (...args: any[]) => {
|
||||||
@@ -813,15 +822,16 @@ server.tool(
|
|||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
const errorStack = error.stack || error.message
|
const errorStack = error.stack || error.message
|
||||||
|
const isTimeoutError = error instanceof CodeExecutionTimeoutError || error.name === 'TimeoutError'
|
||||||
|
|
||||||
|
// Always log to stderr, but only send non-timeout errors to relay server
|
||||||
console.error('Error in execute tool:', errorStack)
|
console.error('Error in execute tool:', errorStack)
|
||||||
|
if (!isTimeoutError) {
|
||||||
|
sendLogToRelayServer('error', 'Error in execute tool:', errorStack)
|
||||||
|
}
|
||||||
|
|
||||||
const logsText = formatConsoleLogs(consoleLogs, 'Console output (before error)')
|
const logsText = formatConsoleLogs(consoleLogs, 'Console output (before error)')
|
||||||
|
|
||||||
const isTimeoutError = error instanceof CodeExecutionTimeoutError || error.name === 'TimeoutError'
|
|
||||||
if (!isTimeoutError) {
|
|
||||||
sendLogToRelayServer('error', '[MCP] Error:', errorStack)
|
|
||||||
}
|
|
||||||
|
|
||||||
const resetHint = isTimeoutError
|
const resetHint = isTimeoutError
|
||||||
? ''
|
? ''
|
||||||
: '\n\n[HINT: If this is an internal Playwright error, page/browser closed, or connection issue, call the `reset` tool to reconnect. Do NOT reset for other non-connection non-internal errors.]'
|
: '\n\n[HINT: If this is an internal Playwright error, page/browser closed, or connection issue, call the `reset` tool to reconnect. Do NOT reset for other non-connection non-internal errors.]'
|
||||||
@@ -908,7 +918,7 @@ export async function startMcp(options: { host?: string; token?: string } = {})
|
|||||||
if (!remote) {
|
if (!remote) {
|
||||||
await ensureRelayServer()
|
await ensureRelayServer()
|
||||||
} else {
|
} else {
|
||||||
console.error(`Using remote CDP relay server: ${remote.host}:${remote.port}`)
|
mcpLog(`Using remote CDP relay server: ${remote.host}:${remote.port}`)
|
||||||
await checkRemoteServer(remote)
|
await checkRemoteServer(remote)
|
||||||
}
|
}
|
||||||
const transport = new StdioServerTransport()
|
const transport = new StdioServerTransport()
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
## Types
|
## Types
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import type { CDPSession } from './cdp-session.js';
|
import type { ICDPSession } from './cdp-session.js';
|
||||||
export interface BreakpointInfo {
|
export interface BreakpointInfo {
|
||||||
id: string;
|
id: string;
|
||||||
file: string;
|
file: string;
|
||||||
@@ -57,7 +57,8 @@ export declare class Debugger {
|
|||||||
* Creates a new Debugger instance.
|
* Creates a new Debugger instance.
|
||||||
*
|
*
|
||||||
* @param options - Configuration options
|
* @param options - Configuration options
|
||||||
* @param options.cdp - A CDPSession instance for sending CDP commands
|
* @param options.cdp - A CDPSession instance for sending CDP commands (works with both
|
||||||
|
* our CDPSession and Playwright's CDPSession)
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```ts
|
* ```ts
|
||||||
@@ -66,7 +67,7 @@ export declare class Debugger {
|
|||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
constructor({ cdp }: {
|
constructor({ cdp }: {
|
||||||
cdp: CDPSession;
|
cdp: ICDPSession;
|
||||||
});
|
});
|
||||||
private setupEventListeners;
|
private setupEventListeners;
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ The Editor class provides a Claude Code-like interface for viewing and editing w
|
|||||||
## Types
|
## Types
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import type { CDPSession } from './cdp-session.js';
|
import type { ICDPSession } from './cdp-session.js';
|
||||||
export interface ReadResult {
|
export interface ReadResult {
|
||||||
content: string;
|
content: string;
|
||||||
totalLines: number;
|
totalLines: number;
|
||||||
@@ -55,7 +55,7 @@ export declare class Editor {
|
|||||||
private stylesheets;
|
private stylesheets;
|
||||||
private sourceCache;
|
private sourceCache;
|
||||||
constructor({ cdp }: {
|
constructor({ cdp }: {
|
||||||
cdp: CDPSession;
|
cdp: ICDPSession;
|
||||||
});
|
});
|
||||||
private setupEventListeners;
|
private setupEventListeners;
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ The getStylesForLocator function inspects CSS styles applied to an element, simi
|
|||||||
## Types
|
## Types
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import type { CDPSession } from './cdp-session.js';
|
import type { ICDPSession } from './cdp-session.js';
|
||||||
import type { Locator } from 'playwright-core';
|
import type { Locator } from 'playwright-core';
|
||||||
export interface StyleSource {
|
export interface StyleSource {
|
||||||
url: string;
|
url: string;
|
||||||
@@ -25,9 +25,9 @@ export interface StylesResult {
|
|||||||
inlineStyle: StyleDeclarations | null;
|
inlineStyle: StyleDeclarations | null;
|
||||||
rules: StyleRule[];
|
rules: StyleRule[];
|
||||||
}
|
}
|
||||||
export declare function getStylesForLocator({ locator, cdp, includeUserAgentStyles, }: {
|
export declare function getStylesForLocator({ locator, cdp: cdpSession, includeUserAgentStyles, }: {
|
||||||
locator: Locator;
|
locator: Locator;
|
||||||
cdp: CDPSession;
|
cdp: ICDPSession;
|
||||||
includeUserAgentStyles?: boolean;
|
includeUserAgentStyles?: boolean;
|
||||||
}): Promise<StylesResult>;
|
}): Promise<StylesResult>;
|
||||||
export declare function formatStylesAsText(styles: StylesResult): string;
|
export declare function formatStylesAsText(styles: StylesResult): string;
|
||||||
|
|||||||
Reference in New Issue
Block a user