import type { BrowserBackend, McpContentBlock, SessionMcpCaller } from "./browser_session.js"; /** * The guest-image contract for the browser tier — the values the runner-images rootfs sets so this * backend can launch Chromium + Playwright MCP without any network fetch (the run's egress is proxied, * so a runtime `npx` download would fail). All but `chromePath` have safe defaults. */ export interface GuestBrowserConfig { /** Absolute path to the Chromium/Chrome binary the image ships (BOARDWALK_BROWSER_CHROME_PATH). */ chromePath: string; /** X display Chromium renders on (headful, so the desktop tier can mirror it). DISPLAY, default ":0". */ display: string; /** How to launch the PRE-INSTALLED Playwright MCP. The per-session flags (--port/--cdp-endpoint/ * --config) are appended. Default runs the pinned package via npx with fetching disabled. */ mcpCommand: string; mcpBaseArgs: readonly string[]; /** Milliseconds to wait for Chromium's CDP endpoint / the MCP server to answer before failing. */ readyTimeoutMs: number; /** Ambient X screen size (BOARDWALK_SCREEN_WIDTH/HEIGHT — the same envs screen capture reads). * A session's requested viewport is clamped to this: the Xvfb screen is fixed at snapshot time, * and a window past its edge would render outside the recording. */ screenWidth: number; screenHeight: number; } /** True when the runner image declares the browser stack present (BOARDWALK_BROWSER_TIER=1). */ export declare function browserTierEnabled(env: NodeJS.ProcessEnv): boolean; /** Read the guest browser config from env, or null when the tier is disabled / no Chrome path is set. */ export declare function loadGuestBrowserConfig(env: NodeJS.ProcessEnv): GuestBrowserConfig | null; /** * Chromium window flags for a session: the requested viewport clamped to the ambient screen, or the * full screen when none is requested (the SDK documents "defaults to the ambient desktop * resolution"). Pinned to 0,0 so the window sits inside the recorded frame. */ export declare function chromiumWindowArgs(viewport: { width: number; height: number; } | undefined, screen: { width: number; height: number; }): string[]; /** Bind an ephemeral port, read it, release it — then hand it to the child. A tiny TOCTOU window, but * each run owns its VM/container so nothing else competes for the loopback port. */ export declare function freePort(): Promise; /** Poll an HTTP URL until it answers (any status < 500 counts as "up" — Playwright MCP's localhost * guard returns 403 to a bare GET, which still proves the server is listening). */ export declare function waitForHttp(url: string, timeoutMs: number): Promise; /** * Build the production BrowserBackend. Each `launch` allocates two loopback ports, spawns a * program-owned Chromium (CDP endpoint, headful on the guest display, isolated profile) and a * per-session Playwright MCP HTTP server attached to it, waits for both to answer, and returns the * handle the manager wraps. On any failure it tears down everything it started (no leaked processes / * temp profiles). */ export declare function makeGuestBrowserBackend(cfg: GuestBrowserConfig): BrowserBackend; /** * Env for the browser-tier child processes — two macOS-only repairs of the run's redirected env, * both measured against a real Mac: * - HOME: the run's HOME is the WORKSPACE (the process-mode isolation default) and Chrome HANGS * mid-`createBrowserWithInfo` under a synthetic home — it needs the real `~/Library` (30s * timeout vs ~65ms). Restored from the user database, never `$HOME` (that IS the redirected one). * The browser PROFILE stays isolated via `--user-data-dir`, so only the OS home is restored — and * `npx` regains its normal cache, so Playwright MCP starts warm instead of re-downloading per run. * - TMPDIR: the run's tmp dir sits deep under `work/runs//tmp`, and Playwright's own control * socket path then exceeds macOS's 104-byte sockaddr limit (`listen EINVAL`, with a visibly * truncated name). `/tmp` keeps it short; these children are platform infrastructure, not author * code, so they need no workspace-scoped tmp. * Linux keeps the inherited env: the hosted guest is verified on it (and its TMPDIR is already /tmp). */ export declare function browserChildEnv(display: string, platform?: NodeJS.Platform, osHome?: () => string): NodeJS.ProcessEnv; /** Adapt one MCP tool-result content block (the SDK's loose shape) to the subset browser_session.ts reads. */ export declare function toContentBlock(block: unknown): McpContentBlock; /** * The program's MCP client factory: open a StreamableHTTP client to a session's Playwright MCP server * (the trusted PROGRAM's channel, distinct from the engine's separate connection the AGENT uses). Wraps * the SDK Client behind the manager's `SessionMcpCaller` seam. `mcpUrl` must be the `localhost` form. */ export declare function connectSessionMcp(mcpUrl: string): Promise;