import { spawn } from 'node:child_process'; export declare const DEFAULT_PORT = 8931; export declare const MAX_PORT = 8949; /** The lowest TCP port the `--port` flag accepts. */ export declare const MIN_PORT = 1024; /** The highest TCP port the `--port` flag accepts. */ export declare const MAX_TCP_PORT = 65535; export declare const BROWSERS: readonly ["chromium", "firefox", "webkit"]; export type Browser = (typeof BROWSERS)[number]; export interface PlaywrightSession { terminalId: string; port: number; browser: Browser; userDataDir: string; startedAt: string; pid?: number; } export declare const PLAYWRIGHT_SESSIONS_DIR = "playwright-sessions"; export declare function playwrightSessionsDir(projectRoot: string): string; export declare function sessionFilePath(projectRoot: string, terminalId: string): string; /** * The per-terminal default `--user-data-dir` under the runtime tree. Guarded here, * beside the join, for the same reason `sessionFilePath` above is: rule D keys the * guard to the FILE, and the caller (`peaks playwright start`) reaches this only * through `readSession` — so a guard that leaned on that call order would be the * file-scoped hole the rule exists to keep visible. */ export declare function defaultUserDataDir(projectRoot: string, terminalId: string): string; /** * Derive a stable terminal id from the process environment. Prefers * the platform's own terminal-session id (macOS Terminal, Windows * Terminal) and falls back to a hash of (ppid, tty). */ export declare function deriveTerminalId(env?: NodeJS.ProcessEnv, ppid?: number): string; /** * Walk port range starting at `start` and return the first port * that is NOT bound. Defaults: 8931 → 8949. If the range is exhausted, * returns null. */ export declare function findFreePort(start?: number, max?: number, probe?: (port: number) => Promise): Promise; export declare function listSessions(projectRoot: string): PlaywrightSession[]; export declare function readSession(projectRoot: string, terminalId: string): PlaywrightSession | null; export declare function writeSession(projectRoot: string, session: PlaywrightSession): void; export declare function removeSession(projectRoot: string, terminalId: string): boolean; /** * Spawn the playwright MCP via npx. We do NOT bundle the binary; * we just orchestrate the lifecycle. Returns the child PID so the * session file can record it. */ export declare function spawnPlaywrightMcp(port: number, browser: Browser, userDataDir: string, projectRoot: string): { pid: number | undefined; child: ReturnType; }; /** * Resolve and validate a caller-supplied `--user-data-dir`. The dir must * live under `projectRoot` so a malicious `--user-data-dir /etc/foo` * cannot coerce the playwright-mcp browser into writing state to an * * Resolves `..` segments before checking, so a path like * `/../escape` is correctly normalized and rejected. * * Throws `Error('INVALID_USER_DATA_DIR: ...')` on validation failure; * the action handler catches and emits the JSON envelope. */ export declare function resolveUserDataDir(raw: string, projectRoot: string): string;