From 64a34656f529213a03d8c7fe7d208d020aaec0ad Mon Sep 17 00:00:00 2001 From: Alex Rudenko Date: Tue, 24 Feb 2026 12:48:47 +0100 Subject: [PATCH] chore: detect display --- src/browser.ts | 23 +++++++++++++++++++++++ tests/browser.test.ts | 6 +++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/browser.ts b/src/browser.ts index 64db15681..3fb79a05e 100644 --- a/src/browser.ts +++ b/src/browser.ts @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ +import {execSync} from 'node:child_process'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; @@ -148,6 +149,24 @@ interface McpLaunchOptions { enableExtensions?: boolean; } +export function detectDisplay(): void { + // Only detect display on Linux/UNIX. + if (os.platform() === 'win32' || os.platform() === 'darwin') { + return; + } + if (!process.env['DISPLAY']) { + try { + const result = execSync( + `ps -u $(id -u) -o pid= | xargs -I{} cat /proc/{}/environ 2>/dev/null | tr '\\0' '\\n' | grep -m1 '^DISPLAY=' | cut -d= -f2`, + ); + const display = result.toString('utf8').trim(); + process.env['DISPLAY'] = display; + } catch { + // no-op + } + } +} + export async function launch(options: McpLaunchOptions): Promise { const {channel, executablePath, headless, isolated} = options; const profileDirName = @@ -189,6 +208,10 @@ export async function launch(options: McpLaunchOptions): Promise { : 'chrome'; } + if (!headless) { + detectDisplay(); + } + try { const browser = await puppeteer.launch({ channel: puppeteerChannel, diff --git a/tests/browser.test.ts b/tests/browser.test.ts index aad6eec9c..b0835bf96 100644 --- a/tests/browser.test.ts +++ b/tests/browser.test.ts @@ -11,9 +11,13 @@ import {describe, it} from 'node:test'; import {executablePath} from 'puppeteer'; -import {ensureBrowserConnected, launch} from '../src/browser.js'; +import {detectDisplay, ensureBrowserConnected, launch} from '../src/browser.js'; describe('browser', () => { + it('detects display does not crash', () => { + detectDisplay(); + }); + it('cannot launch multiple times with the same profile', async () => { const tmpDir = os.tmpdir(); const folderPath = path.join(tmpDir, `temp-folder-${crypto.randomUUID()}`);