From 55be6ec8409c6e0c2e9533058ab0409ee8226f29 Mon Sep 17 00:00:00 2001 From: "Tommy D. Rossi" Date: Mon, 16 Feb 2026 20:03:36 +0100 Subject: [PATCH] fix: sanitize Buffer and long string output in CLI/MCP logging Buffer instances (from screenshots, PDFs, responses) were dumping hundreds of chars of hex bytes via util.inspect. Long strings nested in objects (base64, HTML) also wasted context window space. - Add Buffer.prototype[util.inspect.custom] in all entry points (cli, mcp, cdp-relay) so Buffers display as '' instead of hex dumps - Add maxStringLength: 1000 to all util.inspect calls so strings inside inspected objects get capped (top-level strings are untouched, the existing 10k char overall truncation handles those) --- playwriter/src/cdp-relay.ts | 7 +++++++ playwriter/src/cli.ts | 6 ++++++ playwriter/src/create-logger.ts | 2 +- playwriter/src/executor.ts | 4 ++-- playwriter/src/mcp.ts | 8 ++++++++ 5 files changed, 24 insertions(+), 3 deletions(-) diff --git a/playwriter/src/cdp-relay.ts b/playwriter/src/cdp-relay.ts index e308a60..1391497 100644 --- a/playwriter/src/cdp-relay.ts +++ b/playwriter/src/cdp-relay.ts @@ -17,6 +17,13 @@ import type { IsRecordingParams, } from './protocol.js' import pc from 'picocolors' +import util from 'node:util' + +// Prevent Buffers from dumping hex bytes in util.inspect output. +Buffer.prototype[util.inspect.custom] = function () { + return `` +} + import { EventEmitter } from 'node:events' import { VERSION, EXTENSION_IDS } from './utils.js' import { createCdpLogger, type CdpLogEntry, type CdpLogger } from './cdp-log.js' diff --git a/playwriter/src/cli.ts b/playwriter/src/cli.ts index e345406..ce2e52b 100644 --- a/playwriter/src/cli.ts +++ b/playwriter/src/cli.ts @@ -2,8 +2,14 @@ import fs from 'node:fs' import path from 'node:path' +import util from 'node:util' import { fileURLToPath } from 'node:url' import { cac } from '@xmorse/cac' + +// Prevent Buffers from dumping hex bytes in util.inspect output. +Buffer.prototype[util.inspect.custom] = function () { + return `` +} import { killPortProcess } from './kill-port.js' import { VERSION, LOG_FILE_PATH, LOG_CDP_FILE_PATH, parseRelayHost } from './utils.js' import { ensureRelayServer, RELAY_PORT, waitForExtension, getExtensionOutdatedWarning, getExtensionStatus } from './relay-client.js' diff --git a/playwriter/src/create-logger.ts b/playwriter/src/create-logger.ts index 387d1f5..675be18 100644 --- a/playwriter/src/create-logger.ts +++ b/playwriter/src/create-logger.ts @@ -22,7 +22,7 @@ export function createFileLogger({ logFilePath }: { logFilePath?: string } = {}) const log = (...args: unknown[]): Promise => { const message = args.map(arg => - typeof arg === 'string' ? arg : util.inspect(arg, { depth: null, colors: false }) + typeof arg === 'string' ? arg : util.inspect(arg, { depth: null, colors: false, maxStringLength: 1000 }) ).join(' ') queue = queue.then(() => fs.promises.appendFile(resolvedLogFilePath, stripAnsi(message) + '\n')) return queue diff --git a/playwriter/src/executor.ts b/playwriter/src/executor.ts index be8e39a..0cc8907 100644 --- a/playwriter/src/executor.ts +++ b/playwriter/src/executor.ts @@ -514,7 +514,7 @@ export class PlaywrightExecutor { const formattedArgs = args .map((arg) => { if (typeof arg === 'string') return arg - return util.inspect(arg, { depth: 4, colors: false, maxArrayLength: 100, breakLength: 80 }) + return util.inspect(arg, { depth: 4, colors: false, maxArrayLength: 100, maxStringLength: 1000, breakLength: 80 }) }) .join(' ') text += `[${method}] ${formattedArgs}\n` @@ -853,7 +853,7 @@ export class PlaywrightExecutor { const formatted = typeof resolvedResult === 'string' ? resolvedResult - : util.inspect(resolvedResult, { depth: 4, colors: false, maxArrayLength: 100, breakLength: 80 }) + : util.inspect(resolvedResult, { depth: 4, colors: false, maxArrayLength: 100, maxStringLength: 1000, breakLength: 80 }) if (formatted.trim()) { responseText += `[return value] ${formatted}\n` } diff --git a/playwriter/src/mcp.ts b/playwriter/src/mcp.ts index 7a50d89..55b520f 100644 --- a/playwriter/src/mcp.ts +++ b/playwriter/src/mcp.ts @@ -3,8 +3,16 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js' import { z } from 'zod' import fs from 'node:fs' import path from 'node:path' +import util from 'node:util' import { fileURLToPath } from 'node:url' import { createRequire } from 'node:module' + +// Prevent Buffers from dumping hex bytes in util.inspect output. +// Without this, returning a screenshot Buffer would log ~400+ chars of useless hex. +Buffer.prototype[util.inspect.custom] = function () { + return `` +} + import dedent from 'string-dedent' import { LOG_FILE_PATH, VERSION, parseRelayHost } from './utils.js' import { ensureRelayServer, RELAY_PORT } from './relay-client.js'