@kritchoff/agent-browser 1.0.6 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +6 -8
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +6 -8
- package/dist/cli.js.map +1 -1
- package/dist/daemon.cjs +1 -1
- package/dist/daemon.cjs.map +1 -1
- package/dist/daemon.js +1 -1
- package/dist/daemon.js.map +1 -1
- package/dist/index.cjs +6 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -2
- package/dist/index.d.ts +1 -2
- package/dist/index.js +6 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/daemon.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/daemon.ts","../src/browser.ts","../src/snapshot.ts","../src/taxtree.ts","../src/ios-manager.ts","../src/protocol.ts","../src/actions.ts","../src/ios-actions.ts","../src/stream-server.ts"],"sourcesContent":["import * as net from 'net';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { BrowserManager } from './browser.js';\nimport { IOSManager } from './ios-manager.js';\nimport { parseCommand, serializeResponse, errorResponse } from './protocol.js';\nimport { executeCommand } from './actions.js';\nimport { executeIOSCommand } from './ios-actions.js';\nimport { StreamServer } from './stream-server.js';\n\n// Manager type - either desktop browser or iOS\ntype Manager = BrowserManager | IOSManager;\n\n// Platform detection\nconst isWindows = process.platform === 'win32';\n\n// Session support - each session gets its own socket/pid\nlet currentSession = process.env.AGENT_BROWSER_SESSION || 'default';\n\n// Stream server for browser preview\nlet streamServer: StreamServer | null = null;\n\n// Default stream port (can be overridden with AGENT_BROWSER_STREAM_PORT)\nconst DEFAULT_STREAM_PORT = 9223;\n\n/**\n * Set the current session\n */\nexport function setSession(session: string): void {\n currentSession = session;\n}\n\n/**\n * Get the current session\n */\nexport function getSession(): string {\n return currentSession;\n}\n\n/**\n * Get port number for TCP mode (Windows)\n * Uses a hash of the session name to get a consistent port\n */\nfunction getPortForSession(session: string): number {\n let hash = 0;\n for (let i = 0; i < session.length; i++) {\n hash = (hash << 5) - hash + session.charCodeAt(i);\n hash |= 0;\n }\n // Port range 49152-65535 (dynamic/private ports)\n return 49152 + (Math.abs(hash) % 16383);\n}\n\n/**\n * Get the base directory for socket/pid files.\n * Priority: AGENT_BROWSER_SOCKET_DIR > XDG_RUNTIME_DIR > ~/.agent-browser > tmpdir\n */\nexport function getAppDir(): string {\n // 1. XDG_RUNTIME_DIR (Linux standard)\n if (process.env.XDG_RUNTIME_DIR) {\n return path.join(process.env.XDG_RUNTIME_DIR, 'agent-browser');\n }\n\n // 2. Home directory fallback (like Docker Desktop's ~/.docker/run/)\n const homeDir = os.homedir();\n if (homeDir) {\n return path.join(homeDir, '.agent-browser');\n }\n\n // 3. Last resort: temp dir\n return path.join(os.tmpdir(), 'agent-browser');\n}\n\nexport function getSocketDir(): string {\n // Allow explicit override for socket directory\n if (process.env.AGENT_BROWSER_SOCKET_DIR) {\n return process.env.AGENT_BROWSER_SOCKET_DIR;\n }\n return getAppDir();\n}\n\n/**\n * Get the socket path for the current session (Unix) or port (Windows)\n */\nexport function getSocketPath(session?: string): string {\n const sess = session ?? currentSession;\n if (isWindows) {\n return String(getPortForSession(sess));\n }\n return path.join(getSocketDir(), `${sess}.sock`);\n}\n\n/**\n * Get the port file path for Windows (stores the port number)\n */\nexport function getPortFile(session?: string): string {\n const sess = session ?? currentSession;\n return path.join(getSocketDir(), `${sess}.port`);\n}\n\n/**\n * Get the PID file path for the current session\n */\nexport function getPidFile(session?: string): string {\n const sess = session ?? currentSession;\n return path.join(getSocketDir(), `${sess}.pid`);\n}\n\n/**\n * Check if daemon is running for the current session\n */\nexport function isDaemonRunning(session?: string): boolean {\n const pidFile = getPidFile(session);\n if (!fs.existsSync(pidFile)) return false;\n\n try {\n const pid = parseInt(fs.readFileSync(pidFile, 'utf8').trim(), 10);\n // Check if process exists (works on both Unix and Windows)\n process.kill(pid, 0);\n return true;\n } catch {\n // Process doesn't exist, clean up stale files\n cleanupSocket(session);\n return false;\n }\n}\n\n/**\n * Get connection info for the current session\n * Returns { type: 'unix', path: string } or { type: 'tcp', port: number }\n */\nexport function getConnectionInfo(\n session?: string\n): { type: 'unix'; path: string } | { type: 'tcp'; port: number } {\n const sess = session ?? currentSession;\n if (isWindows) {\n return { type: 'tcp', port: getPortForSession(sess) };\n }\n return { type: 'unix', path: path.join(getSocketDir(), `${sess}.sock`) };\n}\n\n/**\n * Clean up socket and PID file for the current session\n */\nexport function cleanupSocket(session?: string): void {\n const pidFile = getPidFile(session);\n const streamPortFile = getStreamPortFile(session);\n try {\n if (fs.existsSync(pidFile)) fs.unlinkSync(pidFile);\n if (fs.existsSync(streamPortFile)) fs.unlinkSync(streamPortFile);\n if (isWindows) {\n const portFile = getPortFile(session);\n if (fs.existsSync(portFile)) fs.unlinkSync(portFile);\n } else {\n const socketPath = getSocketPath(session);\n if (fs.existsSync(socketPath)) fs.unlinkSync(socketPath);\n }\n } catch {\n // Ignore cleanup errors\n }\n}\n\n/**\n * Get the stream port file path\n */\nexport function getStreamPortFile(session?: string): string {\n const sess = session ?? currentSession;\n return path.join(getSocketDir(), `${sess}.stream`);\n}\n\n/**\n * Start the daemon server\n * @param options.streamPort Port for WebSocket stream server (0 to disable)\n * @param options.provider Provider type ('ios' for iOS Simulator, undefined for desktop)\n */\nexport async function startDaemon(options?: {\n streamPort?: number;\n provider?: string;\n}): Promise<void> {\n // Ensure socket directory exists\n const socketDir = getSocketDir();\n if (!fs.existsSync(socketDir)) {\n fs.mkdirSync(socketDir, { recursive: true });\n }\n\n // Clean up any stale socket\n cleanupSocket();\n\n // Determine provider from options or environment\n const provider = options?.provider ?? process.env.AGENT_BROWSER_PROVIDER;\n const isIOS = provider === 'ios';\n\n // Create appropriate manager\n const manager: Manager = isIOS ? new IOSManager() : new BrowserManager();\n let shuttingDown = false;\n\n // Start stream server if port is specified (or use default if env var is set)\n // Note: Stream server only works with BrowserManager (desktop), not iOS\n const streamPort =\n options?.streamPort ??\n (process.env.AGENT_BROWSER_STREAM_PORT\n ? parseInt(process.env.AGENT_BROWSER_STREAM_PORT, 10)\n : 0);\n\n if (streamPort > 0 && !isIOS && manager instanceof BrowserManager) {\n streamServer = new StreamServer(manager, streamPort);\n await streamServer.start();\n\n // Write stream port to file for clients to discover\n const streamPortFile = getStreamPortFile();\n fs.writeFileSync(streamPortFile, streamPort.toString());\n }\n\n const server = net.createServer((socket) => {\n let buffer = '';\n let httpChecked = false;\n\n socket.on('data', async (data) => {\n buffer += data.toString();\n\n // Security: Detect and reject HTTP requests to prevent cross-origin attacks.\n // Browsers using fetch() must send HTTP headers (e.g., \"POST / HTTP/1.1\"),\n // while legitimate clients send raw JSON starting with \"{\".\n if (!httpChecked) {\n httpChecked = true;\n const trimmed = buffer.trimStart();\n if (/^(GET|POST|PUT|DELETE|HEAD|OPTIONS|PATCH|CONNECT|TRACE)\\s/i.test(trimmed)) {\n socket.destroy();\n return;\n }\n }\n\n // Process complete lines\n while (buffer.includes('\\n')) {\n const newlineIdx = buffer.indexOf('\\n');\n const line = buffer.substring(0, newlineIdx);\n buffer = buffer.substring(newlineIdx + 1);\n\n if (!line.trim()) continue;\n\n try {\n const parseResult = parseCommand(line);\n\n if (!parseResult.success) {\n const resp = errorResponse(parseResult.id ?? 'unknown', parseResult.error);\n socket.write(serializeResponse(resp) + '\\n');\n continue;\n }\n\n // Handle device_list specially - it works without a session and always uses IOSManager\n if (parseResult.command.action === 'device_list') {\n const iosManager = new IOSManager();\n try {\n const devices = await iosManager.listAllDevices();\n const response = {\n id: parseResult.command.id,\n success: true as const,\n data: { devices },\n };\n socket.write(serializeResponse(response) + '\\n');\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n socket.write(\n serializeResponse(errorResponse(parseResult.command.id, message)) + '\\n'\n );\n }\n continue;\n }\n\n // Auto-launch if not already launched and this isn't a launch/close command\n if (\n !manager.isLaunched() &&\n parseResult.command.action !== 'launch' &&\n parseResult.command.action !== 'close'\n ) {\n if (isIOS && manager instanceof IOSManager) {\n // Auto-launch iOS Safari\n // Check for device in command first (for reused daemons), then fall back to env vars\n const cmd = parseResult.command as { iosDevice?: string };\n const iosDevice = cmd.iosDevice || process.env.AGENT_BROWSER_IOS_DEVICE;\n await manager.launch({\n device: iosDevice,\n udid: process.env.AGENT_BROWSER_IOS_UDID,\n });\n } else if (manager instanceof BrowserManager) {\n // Auto-launch desktop browser\n const extensions = process.env.AGENT_BROWSER_EXTENSIONS\n ? process.env.AGENT_BROWSER_EXTENSIONS.split(',')\n .map((p) => p.trim())\n .filter(Boolean)\n : undefined;\n\n // Parse args from env (comma or newline separated)\n const argsEnv = process.env.AGENT_BROWSER_ARGS;\n const args = argsEnv\n ? argsEnv\n .split(/[,\\n]/)\n .map((a) => a.trim())\n .filter((a) => a.length > 0)\n : undefined;\n\n // Parse proxy from env\n const proxyServer = process.env.AGENT_BROWSER_PROXY;\n const proxyBypass = process.env.AGENT_BROWSER_PROXY_BYPASS;\n const proxy = proxyServer\n ? {\n server: proxyServer,\n ...(proxyBypass && { bypass: proxyBypass }),\n }\n : undefined;\n\n const ignoreHTTPSErrors = process.env.AGENT_BROWSER_IGNORE_HTTPS_ERRORS === '1';\n const allowFileAccess = process.env.AGENT_BROWSER_ALLOW_FILE_ACCESS === '1';\n await manager.launch({\n id: 'auto',\n action: 'launch' as const,\n headless: process.env.AGENT_BROWSER_HEADED !== '1',\n executablePath: process.env.AGENT_BROWSER_EXECUTABLE_PATH,\n extensions: extensions,\n profile: process.env.AGENT_BROWSER_PROFILE,\n storageState: process.env.AGENT_BROWSER_STATE,\n args,\n userAgent: process.env.AGENT_BROWSER_USER_AGENT,\n proxy,\n ignoreHTTPSErrors: ignoreHTTPSErrors,\n allowFileAccess: allowFileAccess,\n cdpUrl: process.env.AGENT_BROWSER_CDP_URL,\n });\n }\n }\n\n // Handle close command specially - shuts down daemon\n if (parseResult.command.action === 'close') {\n const response =\n isIOS && manager instanceof IOSManager\n ? await executeIOSCommand(parseResult.command, manager)\n : await executeCommand(parseResult.command, manager as BrowserManager);\n socket.write(serializeResponse(response) + '\\n');\n\n if (!shuttingDown) {\n shuttingDown = true;\n setTimeout(() => {\n server.close();\n cleanupSocket();\n process.exit(0);\n }, 100);\n }\n return;\n }\n\n // Execute command with appropriate handler\n const response =\n isIOS && manager instanceof IOSManager\n ? await executeIOSCommand(parseResult.command, manager)\n : await executeCommand(parseResult.command, manager as BrowserManager);\n socket.write(serializeResponse(response) + '\\n');\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n socket.write(serializeResponse(errorResponse('error', message)) + '\\n');\n }\n }\n });\n\n socket.on('error', () => {\n // Client disconnected, ignore\n });\n });\n\n const pidFile = getPidFile();\n\n // Write PID file before listening\n fs.writeFileSync(pidFile, process.pid.toString());\n\n // Check for explicit TCP port override (e.g. for Docker)\n const tcpPortEnv = process.env.AGENT_BROWSER_TCP_PORT;\n\n if (tcpPortEnv) {\n const port = parseInt(tcpPortEnv, 10);\n server.listen(port, '0.0.0.0', () => {\n console.log(`Daemon listening on TCP 0.0.0.0:${port}`);\n });\n } else if (isWindows) {\n // Windows: use TCP socket on localhost\n const port = getPortForSession(currentSession);\n const portFile = getPortFile();\n fs.writeFileSync(portFile, port.toString());\n server.listen(port, '127.0.0.1', () => {\n // Daemon is ready on TCP port\n });\n } else {\n // Unix: use Unix domain socket\n const socketPath = getSocketPath();\n server.listen(socketPath, () => {\n // Daemon is ready\n });\n }\n\n server.on('error', (err) => {\n console.error('Server error:', err);\n cleanupSocket();\n process.exit(1);\n });\n\n // Handle shutdown signals\n const shutdown = async () => {\n if (shuttingDown) return;\n shuttingDown = true;\n\n // Stop stream server if running\n if (streamServer) {\n await streamServer.stop();\n streamServer = null;\n // Clean up stream port file\n const streamPortFile = getStreamPortFile();\n try {\n if (fs.existsSync(streamPortFile)) fs.unlinkSync(streamPortFile);\n } catch {\n // Ignore cleanup errors\n }\n }\n\n await manager.close();\n server.close();\n cleanupSocket();\n process.exit(0);\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n process.on('SIGHUP', shutdown);\n\n // Handle unexpected errors - always cleanup\n process.on('uncaughtException', (err) => {\n console.error('Uncaught exception:', err);\n cleanupSocket();\n process.exit(1);\n });\n\n process.on('unhandledRejection', (reason) => {\n console.error('Unhandled rejection:', reason);\n cleanupSocket();\n process.exit(1);\n });\n\n // Cleanup on normal exit\n process.on('exit', () => {\n cleanupSocket();\n });\n\n // Keep process alive\n process.stdin.resume();\n}\n\n// Run daemon if this is the entry point\nif (process.argv[1]?.endsWith('daemon.js') || process.env.AGENT_BROWSER_DAEMON === '1') {\n startDaemon().catch((err) => {\n console.error('Daemon error:', err);\n cleanupSocket();\n process.exit(1);\n });\n}\n","import {\n chromium,\n firefox,\n webkit,\n devices,\n type Browser,\n type BrowserContext,\n type Page,\n type Frame,\n type Dialog,\n type Request,\n type Route,\n type Locator,\n type CDPSession,\n type Video,\n} from 'playwright-core';\nimport path from 'node:path';\nimport os from 'node:os';\nimport { existsSync, mkdirSync, rmSync } from 'node:fs';\nimport type { LaunchCommand } from './types.js';\nimport { type RefMap, type EnhancedSnapshot, parseRef } from './snapshot.js';\nimport { getDualModeSnapshot } from './taxtree.js';\n\n// Screencast frame data from CDP\nexport interface ScreencastFrame {\n data: string; // base64 encoded image\n metadata: {\n offsetTop: number;\n pageScaleFactor: number;\n deviceWidth: number;\n deviceHeight: number;\n scrollOffsetX: number;\n scrollOffsetY: number;\n timestamp?: number;\n };\n sessionId: number;\n}\n\n// Screencast options\nexport interface ScreencastOptions {\n format?: 'jpeg' | 'png';\n quality?: number; // 0-100, only for jpeg\n maxWidth?: number;\n maxHeight?: number;\n everyNthFrame?: number;\n}\n\ninterface TrackedRequest {\n url: string;\n method: string;\n headers: Record<string, string>;\n timestamp: number;\n resourceType: string;\n}\n\ninterface ConsoleMessage {\n type: string;\n text: string;\n timestamp: number;\n}\n\ninterface PageError {\n message: string;\n timestamp: number;\n}\n\n/**\n * Manages the Playwright browser lifecycle with multiple tabs/windows\n */\nexport class BrowserManager {\n private browser: Browser | null = null;\n private cdpEndpoint: string | null = null; // stores port number or full URL\n private isPersistentContext: boolean = false;\n private browserbaseSessionId: string | null = null;\n private browserbaseApiKey: string | null = null;\n private browserUseSessionId: string | null = null;\n private browserUseApiKey: string | null = null;\n private kernelSessionId: string | null = null;\n private kernelApiKey: string | null = null;\n private contexts: BrowserContext[] = [];\n private pages: Page[] = [];\n private activePageIndex: number = 0;\n private activeFrame: Frame | null = null;\n private dialogHandler: ((dialog: Dialog) => Promise<void>) | null = null;\n private trackedRequests: TrackedRequest[] = [];\n private routes: Map<string, (route: Route) => Promise<void>> = new Map();\n private consoleMessages: ConsoleMessage[] = [];\n private pageErrors: PageError[] = [];\n private isRecordingHar: boolean = false;\n private refMap: RefMap = {};\n private lastSnapshot: string = '';\n private scopedHeaderRoutes: Map<string, (route: Route) => Promise<void>> = new Map();\n\n // CDP session for screencast and input injection\n private cdpSession: CDPSession | null = null;\n private screencastActive: boolean = false;\n private screencastSessionId: number = 0;\n private frameCallback: ((frame: ScreencastFrame) => void) | null = null;\n private screencastFrameHandler: ((params: any) => void) | null = null;\n\n // Video recording (Playwright native)\n private recordingContext: BrowserContext | null = null;\n private recordingPage: Page | null = null;\n private recordingOutputPath: string = '';\n private recordingTempDir: string = '';\n\n /**\n * Check if browser is launched\n */\n isLaunched(): boolean {\n return this.browser !== null || this.isPersistentContext;\n }\n\n /**\n * Get enhanced snapshot with refs and cache the ref map\n */\n async getSnapshot(options?: {\n interactive?: boolean;\n cursor?: boolean;\n maxDepth?: number;\n compact?: boolean;\n selector?: string;\n }): Promise<EnhancedSnapshot> {\n const page = this.getPage();\n // Use DualMode AXTree (WootzApp) instead of Playwright's ariaSnapshot\n const snapshot = await getDualModeSnapshot(page, options);\n this.refMap = snapshot.refs;\n this.lastSnapshot = snapshot.tree;\n return snapshot;\n }\n\n /**\n * Get the cached ref map from last snapshot\n */\n getRefMap(): RefMap {\n return this.refMap;\n }\n\n /**\n * Get a locator from a ref (e.g., \"e1\", \"@e1\", \"ref=e1\")\n * Returns null if ref doesn't exist or is invalid\n */\n getLocatorFromRef(refArg: string): Locator | null {\n const ref = parseRef(refArg);\n if (!ref) return null;\n\n const refData = this.refMap[ref];\n if (!refData) return null;\n\n const page = this.getPage();\n\n // Check if this is a cursor-interactive element (uses CSS selector, not ARIA role)\n // These have pseudo-roles 'clickable' or 'focusable' and a CSS selector\n if (refData.role === 'clickable' || refData.role === 'focusable') {\n // The selector is a CSS selector, use it directly\n return page.locator(refData.selector);\n }\n\n // Build locator with exact: true to avoid substring matches\n let locator: Locator;\n if (refData.name) {\n locator = page.getByRole(refData.role as any, { name: refData.name, exact: true });\n } else {\n locator = page.getByRole(refData.role as any);\n }\n\n // If an nth index is stored (for disambiguation), use it\n if (refData.nth !== undefined) {\n locator = locator.nth(refData.nth);\n }\n\n return locator;\n }\n\n /**\n * Check if a selector looks like a ref\n */\n isRef(selector: string): boolean {\n return parseRef(selector) !== null;\n }\n\n /**\n * Get raw ref data (including bounds/nodeId)\n */\n getRefData(refArg: string): RefMap[string] | null {\n const ref = parseRef(refArg);\n if (!ref) return null;\n return this.refMap[ref] || null;\n }\n\n /**\n * Get locator - supports both refs and regular selectors\n */\n getLocator(selectorOrRef: string): Locator {\n // Check if it's a ref first\n const locator = this.getLocatorFromRef(selectorOrRef);\n if (locator) return locator;\n\n // Otherwise treat as regular selector\n const page = this.getPage();\n return page.locator(selectorOrRef);\n }\n\n /**\n * Get the current active page, throws if not launched\n */\n getPage(): Page {\n if (this.pages.length === 0) {\n throw new Error('Browser not launched. Call launch first.');\n }\n return this.pages[this.activePageIndex];\n }\n\n /**\n * Get the current frame (or page's main frame if no frame is selected)\n */\n getFrame(): Frame {\n if (this.activeFrame) {\n return this.activeFrame;\n }\n return this.getPage().mainFrame();\n }\n\n /**\n * Switch to a frame by selector, name, or URL\n */\n async switchToFrame(options: { selector?: string; name?: string; url?: string }): Promise<void> {\n const page = this.getPage();\n\n if (options.selector) {\n const frameElement = await page.$(options.selector);\n if (!frameElement) {\n throw new Error(`Frame not found: ${options.selector}`);\n }\n const frame = await frameElement.contentFrame();\n if (!frame) {\n throw new Error(`Element is not a frame: ${options.selector}`);\n }\n this.activeFrame = frame;\n } else if (options.name) {\n const frame = page.frame({ name: options.name });\n if (!frame) {\n throw new Error(`Frame not found with name: ${options.name}`);\n }\n this.activeFrame = frame;\n } else if (options.url) {\n const frame = page.frame({ url: options.url });\n if (!frame) {\n throw new Error(`Frame not found with URL: ${options.url}`);\n }\n this.activeFrame = frame;\n }\n }\n\n /**\n * Switch back to main frame\n */\n switchToMainFrame(): void {\n this.activeFrame = null;\n }\n\n /**\n * Set up dialog handler\n */\n setDialogHandler(response: 'accept' | 'dismiss', promptText?: string): void {\n const page = this.getPage();\n\n // Remove existing handler if any\n if (this.dialogHandler) {\n page.removeListener('dialog', this.dialogHandler);\n }\n\n this.dialogHandler = async (dialog: Dialog) => {\n if (response === 'accept') {\n await dialog.accept(promptText);\n } else {\n await dialog.dismiss();\n }\n };\n\n page.on('dialog', this.dialogHandler);\n }\n\n /**\n * Clear dialog handler\n */\n clearDialogHandler(): void {\n if (this.dialogHandler) {\n const page = this.getPage();\n page.removeListener('dialog', this.dialogHandler);\n this.dialogHandler = null;\n }\n }\n\n /**\n * Start tracking requests\n */\n startRequestTracking(): void {\n const page = this.getPage();\n page.on('request', (request: Request) => {\n this.trackedRequests.push({\n url: request.url(),\n method: request.method(),\n headers: request.headers(),\n timestamp: Date.now(),\n resourceType: request.resourceType(),\n });\n });\n }\n\n /**\n * Get tracked requests\n */\n getRequests(filter?: string): TrackedRequest[] {\n if (filter) {\n return this.trackedRequests.filter((r) => r.url.includes(filter));\n }\n return this.trackedRequests;\n }\n\n /**\n * Clear tracked requests\n */\n clearRequests(): void {\n this.trackedRequests = [];\n }\n\n /**\n * Add a route to intercept requests\n */\n async addRoute(\n url: string,\n options: {\n response?: {\n status?: number;\n body?: string;\n contentType?: string;\n headers?: Record<string, string>;\n };\n abort?: boolean;\n }\n ): Promise<void> {\n const page = this.getPage();\n\n const handler = async (route: Route) => {\n if (options.abort) {\n await route.abort();\n } else if (options.response) {\n await route.fulfill({\n status: options.response.status ?? 200,\n body: options.response.body ?? '',\n contentType: options.response.contentType ?? 'text/plain',\n headers: options.response.headers,\n });\n } else {\n await route.continue();\n }\n };\n\n this.routes.set(url, handler);\n await page.route(url, handler);\n }\n\n /**\n * Remove a route\n */\n async removeRoute(url?: string): Promise<void> {\n const page = this.getPage();\n\n if (url) {\n const handler = this.routes.get(url);\n if (handler) {\n await page.unroute(url, handler);\n this.routes.delete(url);\n }\n } else {\n // Remove all routes\n for (const [routeUrl, handler] of this.routes) {\n await page.unroute(routeUrl, handler);\n }\n this.routes.clear();\n }\n }\n\n /**\n * Set geolocation\n */\n async setGeolocation(latitude: number, longitude: number, accuracy?: number): Promise<void> {\n const context = this.contexts[0];\n if (context) {\n await context.setGeolocation({ latitude, longitude, accuracy });\n }\n }\n\n /**\n * Set permissions\n */\n async setPermissions(permissions: string[], grant: boolean): Promise<void> {\n const context = this.contexts[0];\n if (context) {\n if (grant) {\n await context.grantPermissions(permissions);\n } else {\n await context.clearPermissions();\n }\n }\n }\n\n /**\n * Set viewport\n */\n async setViewport(width: number, height: number): Promise<void> {\n const page = this.getPage();\n await page.setViewportSize({ width, height });\n }\n\n /**\n * Set device scale factor (devicePixelRatio) via CDP\n * This sets window.devicePixelRatio which affects how the page renders and responds to media queries\n *\n * Note: When using CDP to set deviceScaleFactor, screenshots will be at logical pixel dimensions\n * (viewport size), not physical pixel dimensions (viewport × scale). This is a Playwright limitation\n * when using CDP emulation on existing contexts. For true HiDPI screenshots with physical pixels,\n * deviceScaleFactor must be set at context creation time.\n *\n * Must be called after setViewport to work correctly\n */\n async setDeviceScaleFactor(\n deviceScaleFactor: number,\n width: number,\n height: number,\n mobile: boolean = false\n ): Promise<void> {\n const cdp = await this.getCDPSession();\n await cdp.send('Emulation.setDeviceMetricsOverride', {\n width,\n height,\n deviceScaleFactor,\n mobile,\n });\n }\n\n /**\n * Clear device metrics override to restore default devicePixelRatio\n */\n async clearDeviceMetricsOverride(): Promise<void> {\n const cdp = await this.getCDPSession();\n await cdp.send('Emulation.clearDeviceMetricsOverride');\n }\n\n /**\n * Get device descriptor\n */\n getDevice(deviceName: string): (typeof devices)[keyof typeof devices] | undefined {\n return devices[deviceName as keyof typeof devices];\n }\n\n /**\n * List available devices\n */\n listDevices(): string[] {\n return Object.keys(devices);\n }\n\n /**\n * Start console message tracking\n */\n startConsoleTracking(): void {\n const page = this.getPage();\n page.on('console', (msg) => {\n this.consoleMessages.push({\n type: msg.type(),\n text: msg.text(),\n timestamp: Date.now(),\n });\n });\n }\n\n /**\n * Get console messages\n */\n getConsoleMessages(): ConsoleMessage[] {\n return this.consoleMessages;\n }\n\n /**\n * Clear console messages\n */\n clearConsoleMessages(): void {\n this.consoleMessages = [];\n }\n\n /**\n * Start error tracking\n */\n startErrorTracking(): void {\n const page = this.getPage();\n page.on('pageerror', (error) => {\n this.pageErrors.push({\n message: error.message,\n timestamp: Date.now(),\n });\n });\n }\n\n /**\n * Get page errors\n */\n getPageErrors(): PageError[] {\n return this.pageErrors;\n }\n\n /**\n * Clear page errors\n */\n clearPageErrors(): void {\n this.pageErrors = [];\n }\n\n /**\n * Start HAR recording\n */\n async startHarRecording(): Promise<void> {\n // HAR is started at context level, flag for tracking\n this.isRecordingHar = true;\n }\n\n /**\n * Check if HAR recording\n */\n isHarRecording(): boolean {\n return this.isRecordingHar;\n }\n\n /**\n * Set offline mode\n */\n async setOffline(offline: boolean): Promise<void> {\n const context = this.contexts[0];\n if (context) {\n await context.setOffline(offline);\n }\n }\n\n /**\n * Set extra HTTP headers (global - all requests)\n */\n async setExtraHeaders(headers: Record<string, string>): Promise<void> {\n const context = this.contexts[0];\n if (context) {\n await context.setExtraHTTPHeaders(headers);\n }\n }\n\n /**\n * Set scoped HTTP headers (only for requests matching the origin)\n * Uses route interception to add headers only to matching requests\n */\n async setScopedHeaders(origin: string, headers: Record<string, string>): Promise<void> {\n const page = this.getPage();\n\n // Build URL pattern from origin (e.g., \"api.example.com\" -> \"**://api.example.com/**\")\n // Handle both full URLs and just hostnames\n let urlPattern: string;\n try {\n const url = new URL(origin.startsWith('http') ? origin : `https://${origin}`);\n // Match any protocol, the host, and any path\n urlPattern = `**://${url.host}/**`;\n } catch {\n // If parsing fails, treat as hostname pattern\n urlPattern = `**://${origin}/**`;\n }\n\n // Remove existing route for this origin if any\n const existingHandler = this.scopedHeaderRoutes.get(urlPattern);\n if (existingHandler) {\n await page.unroute(urlPattern, existingHandler);\n }\n\n // Create handler that adds headers to matching requests\n const handler = async (route: Route) => {\n const requestHeaders = route.request().headers();\n await route.continue({\n headers: {\n ...requestHeaders,\n ...headers,\n },\n });\n };\n\n // Store and register the route\n this.scopedHeaderRoutes.set(urlPattern, handler);\n await page.route(urlPattern, handler);\n }\n\n /**\n * Clear scoped headers for an origin (or all if no origin specified)\n */\n async clearScopedHeaders(origin?: string): Promise<void> {\n const page = this.getPage();\n\n if (origin) {\n let urlPattern: string;\n try {\n const url = new URL(origin.startsWith('http') ? origin : `https://${origin}`);\n urlPattern = `**://${url.host}/**`;\n } catch {\n urlPattern = `**://${origin}/**`;\n }\n\n const handler = this.scopedHeaderRoutes.get(urlPattern);\n if (handler) {\n await page.unroute(urlPattern, handler);\n this.scopedHeaderRoutes.delete(urlPattern);\n }\n } else {\n // Clear all scoped header routes\n for (const [pattern, handler] of this.scopedHeaderRoutes) {\n await page.unroute(pattern, handler);\n }\n this.scopedHeaderRoutes.clear();\n }\n }\n\n /**\n * Start tracing\n */\n async startTracing(options: { screenshots?: boolean; snapshots?: boolean }): Promise<void> {\n const context = this.contexts[0];\n if (context) {\n await context.tracing.start({\n screenshots: options.screenshots ?? true,\n snapshots: options.snapshots ?? true,\n });\n }\n }\n\n /**\n * Stop tracing and save\n */\n async stopTracing(path: string): Promise<void> {\n const context = this.contexts[0];\n if (context) {\n await context.tracing.stop({ path });\n }\n }\n\n /**\n * Save storage state (cookies, localStorage, etc.)\n */\n async saveStorageState(path: string): Promise<void> {\n const context = this.contexts[0];\n if (context) {\n await context.storageState({ path });\n }\n }\n\n /**\n * Get all pages\n */\n getPages(): Page[] {\n return this.pages;\n }\n\n /**\n * Get current page index\n */\n getActiveIndex(): number {\n return this.activePageIndex;\n }\n\n /**\n * Get the current browser instance\n */\n getBrowser(): Browser | null {\n return this.browser;\n }\n\n /**\n * Check if an existing CDP connection is still alive\n * by verifying we can access browser contexts and that at least one has pages\n */\n private isCdpConnectionAlive(): boolean {\n if (!this.browser) return false;\n try {\n const contexts = this.browser.contexts();\n if (contexts.length === 0) return false;\n return contexts.some((context) => context.pages().length > 0);\n } catch {\n return false;\n }\n }\n\n /**\n * Check if CDP connection needs to be re-established\n */\n private needsCdpReconnect(cdpEndpoint: string): boolean {\n if (!this.browser?.isConnected()) return true;\n if (this.cdpEndpoint !== cdpEndpoint) return true;\n if (!this.isCdpConnectionAlive()) return true;\n return false;\n }\n\n /**\n * Close a Browserbase session via API\n */\n private async closeBrowserbaseSession(sessionId: string, apiKey: string): Promise<void> {\n await fetch(`https://api.browserbase.com/v1/sessions/${sessionId}`, {\n method: 'DELETE',\n headers: {\n 'X-BB-API-Key': apiKey,\n },\n });\n }\n\n /**\n * Close a Browser Use session via API\n */\n private async closeBrowserUseSession(sessionId: string, apiKey: string): Promise<void> {\n const response = await fetch(`https://api.browser-use.com/api/v2/browsers/${sessionId}`, {\n method: 'PATCH',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Browser-Use-API-Key': apiKey,\n },\n body: JSON.stringify({ action: 'stop' }),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to close Browser Use session: ${response.statusText}`);\n }\n }\n\n /**\n * Close a Kernel session via API\n */\n private async closeKernelSession(sessionId: string, apiKey: string): Promise<void> {\n const response = await fetch(`https://api.onkernel.com/browsers/${sessionId}`, {\n method: 'DELETE',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to close Kernel session: ${response.statusText}`);\n }\n }\n\n /**\n * Connect to Browserbase remote browser via CDP.\n * Requires BROWSERBASE_API_KEY and BROWSERBASE_PROJECT_ID environment variables.\n */\n private async connectToBrowserbase(): Promise<void> {\n const browserbaseApiKey = process.env.BROWSERBASE_API_KEY;\n const browserbaseProjectId = process.env.BROWSERBASE_PROJECT_ID;\n\n if (!browserbaseApiKey || !browserbaseProjectId) {\n throw new Error(\n 'BROWSERBASE_API_KEY and BROWSERBASE_PROJECT_ID are required when using browserbase as a provider'\n );\n }\n\n const response = await fetch('https://api.browserbase.com/v1/sessions', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-BB-API-Key': browserbaseApiKey,\n },\n body: JSON.stringify({\n projectId: browserbaseProjectId,\n }),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to create Browserbase session: ${response.statusText}`);\n }\n\n const session = (await response.json()) as { id: string; connectUrl: string };\n\n const browser = await chromium.connectOverCDP(session.connectUrl).catch(() => {\n throw new Error('Failed to connect to Browserbase session via CDP');\n });\n\n try {\n const contexts = browser.contexts();\n if (contexts.length === 0) {\n throw new Error('No browser context found in Browserbase session');\n }\n\n const context = contexts[0];\n const pages = context.pages();\n const page = pages[0] ?? (await context.newPage());\n\n this.browserbaseSessionId = session.id;\n this.browserbaseApiKey = browserbaseApiKey;\n this.browser = browser;\n context.setDefaultTimeout(10000);\n this.contexts.push(context);\n this.setupContextTracking(context);\n this.pages.push(page);\n this.activePageIndex = 0;\n this.setupPageTracking(page);\n } catch (error) {\n await this.closeBrowserbaseSession(session.id, browserbaseApiKey).catch((sessionError) => {\n console.error('Failed to close Browserbase session during cleanup:', sessionError);\n });\n throw error;\n }\n }\n\n /**\n * Find or create a Kernel profile by name.\n * Returns the profile object if successful.\n */\n private async findOrCreateKernelProfile(\n profileName: string,\n apiKey: string\n ): Promise<{ name: string }> {\n // First, try to get the existing profile\n const getResponse = await fetch(\n `https://api.onkernel.com/profiles/${encodeURIComponent(profileName)}`,\n {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n },\n }\n );\n\n if (getResponse.ok) {\n // Profile exists, return it\n return { name: profileName };\n }\n\n if (getResponse.status !== 404) {\n throw new Error(`Failed to check Kernel profile: ${getResponse.statusText}`);\n }\n\n // Profile doesn't exist, create it\n const createResponse = await fetch('https://api.onkernel.com/profiles', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({ name: profileName }),\n });\n\n if (!createResponse.ok) {\n throw new Error(`Failed to create Kernel profile: ${createResponse.statusText}`);\n }\n\n return { name: profileName };\n }\n\n /**\n * Connect to Kernel remote browser via CDP.\n * Requires KERNEL_API_KEY environment variable.\n */\n private async connectToKernel(): Promise<void> {\n const kernelApiKey = process.env.KERNEL_API_KEY;\n if (!kernelApiKey) {\n throw new Error('KERNEL_API_KEY is required when using kernel as a provider');\n }\n\n // Find or create profile if KERNEL_PROFILE_NAME is set\n const profileName = process.env.KERNEL_PROFILE_NAME;\n let profileConfig: { profile: { name: string; save_changes: boolean } } | undefined;\n\n if (profileName) {\n await this.findOrCreateKernelProfile(profileName, kernelApiKey);\n profileConfig = {\n profile: {\n name: profileName,\n save_changes: true, // Save cookies/state back to the profile when session ends\n },\n };\n }\n\n const response = await fetch('https://api.onkernel.com/browsers', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${kernelApiKey}`,\n },\n body: JSON.stringify({\n // Kernel browsers are headful by default with stealth mode available\n // The user can configure these via environment variables if needed\n headless: process.env.KERNEL_HEADLESS?.toLowerCase() === 'true',\n stealth: process.env.KERNEL_STEALTH?.toLowerCase() !== 'false', // Default to stealth mode\n timeout_seconds: parseInt(process.env.KERNEL_TIMEOUT_SECONDS || '300', 10),\n // Load and save to a profile if specified\n ...profileConfig,\n }),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to create Kernel session: ${response.statusText}`);\n }\n\n let session: { session_id: string; cdp_ws_url: string };\n try {\n session = (await response.json()) as { session_id: string; cdp_ws_url: string };\n } catch (error) {\n throw new Error(\n `Failed to parse Kernel session response: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n\n if (!session.session_id || !session.cdp_ws_url) {\n throw new Error(\n `Invalid Kernel session response: missing ${!session.session_id ? 'session_id' : 'cdp_ws_url'}`\n );\n }\n\n const browser = await chromium.connectOverCDP(session.cdp_ws_url).catch(() => {\n throw new Error('Failed to connect to Kernel session via CDP');\n });\n\n try {\n const contexts = browser.contexts();\n let context: BrowserContext;\n let page: Page;\n\n // Kernel browsers launch with a default context and page\n if (contexts.length === 0) {\n context = await browser.newContext();\n page = await context.newPage();\n } else {\n context = contexts[0];\n const pages = context.pages();\n page = pages[0] ?? (await context.newPage());\n }\n\n this.kernelSessionId = session.session_id;\n this.kernelApiKey = kernelApiKey;\n this.browser = browser;\n context.setDefaultTimeout(60000);\n this.contexts.push(context);\n this.pages.push(page);\n this.activePageIndex = 0;\n this.setupPageTracking(page);\n this.setupContextTracking(context);\n } catch (error) {\n await this.closeKernelSession(session.session_id, kernelApiKey).catch((sessionError) => {\n console.error('Failed to close Kernel session during cleanup:', sessionError);\n });\n throw error;\n }\n }\n\n /**\n * Connect to Browser Use remote browser via CDP.\n * Requires BROWSER_USE_API_KEY environment variable.\n */\n private async connectToBrowserUse(): Promise<void> {\n const browserUseApiKey = process.env.BROWSER_USE_API_KEY;\n if (!browserUseApiKey) {\n throw new Error('BROWSER_USE_API_KEY is required when using browseruse as a provider');\n }\n\n const response = await fetch('https://api.browser-use.com/api/v2/browsers', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Browser-Use-API-Key': browserUseApiKey,\n },\n body: JSON.stringify({}),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to create Browser Use session: ${response.statusText}`);\n }\n\n let session: { id: string; cdpUrl: string };\n try {\n session = (await response.json()) as { id: string; cdpUrl: string };\n } catch (error) {\n throw new Error(\n `Failed to parse Browser Use session response: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n\n if (!session.id || !session.cdpUrl) {\n throw new Error(\n `Invalid Browser Use session response: missing ${!session.id ? 'id' : 'cdpUrl'}`\n );\n }\n\n const browser = await chromium.connectOverCDP(session.cdpUrl).catch(() => {\n throw new Error('Failed to connect to Browser Use session via CDP');\n });\n\n try {\n const contexts = browser.contexts();\n let context: BrowserContext;\n let page: Page;\n\n if (contexts.length === 0) {\n context = await browser.newContext();\n page = await context.newPage();\n } else {\n context = contexts[0];\n const pages = context.pages();\n page = pages[0] ?? (await context.newPage());\n }\n\n this.browserUseSessionId = session.id;\n this.browserUseApiKey = browserUseApiKey;\n this.browser = browser;\n context.setDefaultTimeout(60000);\n this.contexts.push(context);\n this.pages.push(page);\n this.activePageIndex = 0;\n this.setupPageTracking(page);\n this.setupContextTracking(context);\n } catch (error) {\n await this.closeBrowserUseSession(session.id, browserUseApiKey).catch((sessionError) => {\n console.error('Failed to close Browser Use session during cleanup:', sessionError);\n });\n throw error;\n }\n }\n\n /**\n * Launch the browser with the specified options\n * If already launched, this is a no-op (browser stays open)\n */\n async launch(options: LaunchCommand): Promise<void> {\n // Determine CDP endpoint: prefer cdpUrl over cdpPort for flexibility\n const cdpEndpoint = options.cdpUrl ?? (options.cdpPort ? String(options.cdpPort) : undefined);\n const hasExtensions = !!options.extensions?.length;\n const hasProfile = !!options.profile;\n const hasStorageState = !!options.storageState;\n\n if (hasExtensions && cdpEndpoint) {\n throw new Error('Extensions cannot be used with CDP connection');\n }\n\n if (hasProfile && cdpEndpoint) {\n throw new Error('Profile cannot be used with CDP connection');\n }\n\n if (hasStorageState && hasProfile) {\n throw new Error(\n 'Storage state cannot be used with profile (profile is already persistent storage)'\n );\n }\n\n if (hasStorageState && hasExtensions) {\n throw new Error(\n 'Storage state cannot be used with extensions (extensions require persistent context)'\n );\n }\n\n if (this.isLaunched()) {\n const needsRelaunch =\n (!cdpEndpoint && this.cdpEndpoint !== null) ||\n (!!cdpEndpoint && this.needsCdpReconnect(cdpEndpoint));\n if (needsRelaunch) {\n await this.close();\n } else {\n return;\n }\n }\n\n if (cdpEndpoint) {\n await this.connectViaCDP(cdpEndpoint);\n return;\n }\n\n // Cloud browser providers require explicit opt-in via -p flag or AGENT_BROWSER_PROVIDER env var\n // -p flag takes precedence over env var\n const provider = options.provider ?? process.env.AGENT_BROWSER_PROVIDER;\n if (provider === 'browserbase') {\n await this.connectToBrowserbase();\n return;\n }\n if (provider === 'browseruse') {\n await this.connectToBrowserUse();\n return;\n }\n\n // Kernel: requires explicit opt-in via -p kernel flag or AGENT_BROWSER_PROVIDER=kernel\n if (provider === 'kernel') {\n await this.connectToKernel();\n return;\n }\n\n const browserType = options.browser ?? 'chromium';\n if (hasExtensions && browserType !== 'chromium') {\n throw new Error('Extensions are only supported in Chromium');\n }\n\n // allowFileAccess is only supported in Chromium\n if (options.allowFileAccess && browserType !== 'chromium') {\n throw new Error('allowFileAccess is only supported in Chromium');\n }\n\n const launcher =\n browserType === 'firefox' ? firefox : browserType === 'webkit' ? webkit : chromium;\n const viewport = options.viewport ?? { width: 1280, height: 720 };\n\n // Build base args array with file access flags if enabled\n // --allow-file-access-from-files: allows file:// URLs to read other file:// URLs via XHR/fetch\n // --allow-file-access: allows the browser to access local files in general\n const fileAccessArgs = options.allowFileAccess\n ? ['--allow-file-access-from-files', '--allow-file-access']\n : [];\n const baseArgs = options.args\n ? [...fileAccessArgs, ...options.args]\n : fileAccessArgs.length > 0\n ? fileAccessArgs\n : undefined;\n\n let context: BrowserContext;\n if (hasExtensions) {\n // Extensions require persistent context in a temp directory\n const extPaths = options.extensions!.join(',');\n const session = process.env.AGENT_BROWSER_SESSION || 'default';\n // Combine extension args with custom args and file access args\n const extArgs = [`--disable-extensions-except=${extPaths}`, `--load-extension=${extPaths}`];\n const allArgs = baseArgs ? [...extArgs, ...baseArgs] : extArgs;\n context = await launcher.launchPersistentContext(\n path.join(os.tmpdir(), `agent-browser-ext-${session}`),\n {\n headless: false,\n executablePath: options.executablePath,\n args: allArgs,\n viewport,\n extraHTTPHeaders: options.headers,\n userAgent: options.userAgent,\n ...(options.proxy && { proxy: options.proxy }),\n ignoreHTTPSErrors: options.ignoreHTTPSErrors ?? false,\n }\n );\n this.isPersistentContext = true;\n } else if (hasProfile) {\n // Profile uses persistent context for durable cookies/storage\n // Expand ~ to home directory since it won't be shell-expanded\n const profilePath = options.profile!.replace(/^~\\//, os.homedir() + '/');\n context = await launcher.launchPersistentContext(profilePath, {\n headless: options.headless ?? true,\n executablePath: options.executablePath,\n args: baseArgs,\n viewport,\n extraHTTPHeaders: options.headers,\n userAgent: options.userAgent,\n ...(options.proxy && { proxy: options.proxy }),\n ignoreHTTPSErrors: options.ignoreHTTPSErrors ?? false,\n });\n this.isPersistentContext = true;\n } else {\n // Regular ephemeral browser\n this.browser = await launcher.launch({\n headless: options.headless ?? true,\n executablePath: options.executablePath,\n args: baseArgs,\n });\n this.cdpEndpoint = null;\n context = await this.browser.newContext({\n viewport,\n extraHTTPHeaders: options.headers,\n userAgent: options.userAgent,\n ...(options.proxy && { proxy: options.proxy }),\n ignoreHTTPSErrors: options.ignoreHTTPSErrors ?? false,\n ...(options.storageState && { storageState: options.storageState }),\n });\n }\n\n context.setDefaultTimeout(60000);\n this.contexts.push(context);\n this.setupContextTracking(context);\n\n const page = context.pages()[0] ?? (await context.newPage());\n // Only add if not already tracked (setupContextTracking may have already added it via 'page' event)\n if (!this.pages.includes(page)) {\n this.pages.push(page);\n this.setupPageTracking(page);\n }\n this.activePageIndex = this.pages.length > 0 ? this.pages.length - 1 : 0;\n }\n\n /**\n * Connect to a running browser via CDP (Chrome DevTools Protocol)\n * @param cdpEndpoint Either a port number (as string) or a full WebSocket URL (ws:// or wss://)\n */\n private async connectViaCDP(cdpEndpoint: string | undefined): Promise<void> {\n if (!cdpEndpoint) {\n throw new Error('CDP endpoint is required for CDP connection');\n }\n\n // Determine the connection URL:\n // - If it starts with ws://, wss://, http://, or https://, use it directly\n // - If it's a numeric string (e.g., \"9222\"), treat as port for localhost\n // - Otherwise, treat it as a port number for localhost\n let cdpUrl: string;\n if (\n cdpEndpoint.startsWith('ws://') ||\n cdpEndpoint.startsWith('wss://') ||\n cdpEndpoint.startsWith('http://') ||\n cdpEndpoint.startsWith('https://')\n ) {\n cdpUrl = cdpEndpoint;\n } else if (/^\\d+$/.test(cdpEndpoint)) {\n // Numeric string - treat as port number (handles JSON serialization quirks)\n cdpUrl = `http://localhost:${cdpEndpoint}`;\n } else {\n // Unknown format - still try as port for backward compatibility\n cdpUrl = `http://localhost:${cdpEndpoint}`;\n }\n\n const browser = await chromium.connectOverCDP(cdpUrl).catch(() => {\n throw new Error(\n `Failed to connect via CDP to ${cdpUrl}. ` +\n (cdpUrl.includes('localhost')\n ? `Make sure the app is running with --remote-debugging-port=${cdpEndpoint}`\n : 'Make sure the remote browser is accessible and the URL is correct.')\n );\n });\n\n // Validate and set up state, cleaning up browser connection if anything fails\n try {\n const contexts = browser.contexts();\n if (contexts.length === 0) {\n throw new Error('No browser context found. Make sure the app has an open window.');\n }\n\n // Filter out pages with empty URLs, which can cause Playwright to hang\n const allPages = contexts.flatMap((context) => context.pages()).filter((page) => page.url());\n\n if (allPages.length === 0) {\n throw new Error('No page found. Make sure the app has loaded content.');\n }\n\n // All validation passed - commit state\n this.browser = browser;\n this.cdpEndpoint = cdpEndpoint;\n\n for (const context of contexts) {\n context.setDefaultTimeout(10000);\n this.contexts.push(context);\n this.setupContextTracking(context);\n }\n\n for (const page of allPages) {\n this.pages.push(page);\n this.setupPageTracking(page);\n }\n\n this.activePageIndex = 0;\n } catch (error) {\n // Clean up browser connection if validation or setup failed\n await browser.close().catch(() => {});\n throw error;\n }\n }\n\n /**\n * Set up console, error, and close tracking for a page\n */\n private setupPageTracking(page: Page): void {\n page.on('console', (msg) => {\n this.consoleMessages.push({\n type: msg.type(),\n text: msg.text(),\n timestamp: Date.now(),\n });\n });\n\n page.on('pageerror', (error) => {\n this.pageErrors.push({\n message: error.message,\n timestamp: Date.now(),\n });\n });\n\n page.on('close', () => {\n const index = this.pages.indexOf(page);\n if (index !== -1) {\n this.pages.splice(index, 1);\n if (this.activePageIndex >= this.pages.length) {\n this.activePageIndex = Math.max(0, this.pages.length - 1);\n }\n }\n });\n }\n\n /**\n * Set up tracking for new pages in a context (for CDP connections and popups/new tabs)\n * This handles pages created externally (e.g., via target=\"_blank\" links, window.open)\n */\n private setupContextTracking(context: BrowserContext): void {\n context.on('page', (page) => {\n // Only add if not already tracked (avoids duplicates when newTab() creates pages)\n if (!this.pages.includes(page)) {\n this.pages.push(page);\n this.setupPageTracking(page);\n }\n\n // Auto-switch to the newly opened tab so subsequent commands target it.\n // For tabs created via newTab()/newWindow(), this is redundant (they set activePageIndex after),\n // but for externally opened tabs (window.open, target=\"_blank\"), this ensures the active tab\n // stays in sync with the browser.\n const newIndex = this.pages.indexOf(page);\n if (newIndex !== -1 && newIndex !== this.activePageIndex) {\n this.activePageIndex = newIndex;\n // Invalidate CDP session since the active page changed\n this.invalidateCDPSession().catch(() => {});\n }\n });\n }\n\n /**\n * Create a new tab in the current context\n */\n async newTab(): Promise<{ index: number; total: number }> {\n if (!this.browser || this.contexts.length === 0) {\n throw new Error('Browser not launched');\n }\n\n // Invalidate CDP session since we're switching to a new page\n await this.invalidateCDPSession();\n\n const context = this.contexts[0]; // Use first context for tabs\n const page = await context.newPage();\n // Only add if not already tracked (setupContextTracking may have already added it via 'page' event)\n if (!this.pages.includes(page)) {\n this.pages.push(page);\n this.setupPageTracking(page);\n }\n this.activePageIndex = this.pages.length - 1;\n\n return { index: this.activePageIndex, total: this.pages.length };\n }\n\n /**\n * Create a new window (new context)\n */\n async newWindow(viewport?: {\n width: number;\n height: number;\n }): Promise<{ index: number; total: number }> {\n if (!this.browser) {\n throw new Error('Browser not launched');\n }\n\n const context = await this.browser.newContext({\n viewport: viewport ?? { width: 1280, height: 720 },\n });\n context.setDefaultTimeout(60000);\n this.contexts.push(context);\n this.setupContextTracking(context);\n\n const page = await context.newPage();\n // Only add if not already tracked (setupContextTracking may have already added it via 'page' event)\n if (!this.pages.includes(page)) {\n this.pages.push(page);\n this.setupPageTracking(page);\n }\n this.activePageIndex = this.pages.length - 1;\n\n return { index: this.activePageIndex, total: this.pages.length };\n }\n\n /**\n * Invalidate the current CDP session (must be called before switching pages)\n * This ensures screencast and input injection work correctly after tab switch\n */\n private async invalidateCDPSession(): Promise<void> {\n // Stop screencast if active (it's tied to the current page's CDP session)\n if (this.screencastActive) {\n await this.stopScreencast();\n }\n\n // Detach and clear the CDP session\n if (this.cdpSession) {\n await this.cdpSession.detach().catch(() => {});\n this.cdpSession = null;\n }\n }\n\n /**\n * Switch to a specific tab/page by index\n */\n async switchTo(index: number): Promise<{ index: number; url: string; title: string }> {\n if (index < 0 || index >= this.pages.length) {\n throw new Error(`Invalid tab index: ${index}. Available: 0-${this.pages.length - 1}`);\n }\n\n // Invalidate CDP session before switching (it's page-specific)\n if (index !== this.activePageIndex) {\n await this.invalidateCDPSession();\n }\n\n this.activePageIndex = index;\n const page = this.pages[index];\n\n return {\n index: this.activePageIndex,\n url: page.url(),\n title: '', // Title requires async, will be fetched separately\n };\n }\n\n /**\n * Close a specific tab/page\n */\n async closeTab(index?: number): Promise<{ closed: number; remaining: number }> {\n const targetIndex = index ?? this.activePageIndex;\n\n if (targetIndex < 0 || targetIndex >= this.pages.length) {\n throw new Error(`Invalid tab index: ${targetIndex}`);\n }\n\n if (this.pages.length === 1) {\n throw new Error('Cannot close the last tab. Use \"close\" to close the browser.');\n }\n\n // If closing the active tab, invalidate CDP session first\n if (targetIndex === this.activePageIndex) {\n await this.invalidateCDPSession();\n }\n\n const page = this.pages[targetIndex];\n await page.close();\n this.pages.splice(targetIndex, 1);\n\n // Adjust active index if needed\n if (this.activePageIndex >= this.pages.length) {\n this.activePageIndex = this.pages.length - 1;\n } else if (this.activePageIndex > targetIndex) {\n this.activePageIndex--;\n }\n\n return { closed: targetIndex, remaining: this.pages.length };\n }\n\n /**\n * List all tabs with their info\n */\n async listTabs(): Promise<Array<{ index: number; url: string; title: string; active: boolean }>> {\n const tabs = await Promise.all(\n this.pages.map(async (page, index) => ({\n index,\n url: page.url(),\n title: await page.title().catch(() => ''),\n active: index === this.activePageIndex,\n }))\n );\n return tabs;\n }\n\n /**\n * Get or create a CDP session for the current page\n * Only works with Chromium-based browsers\n */\n async getCDPSession(): Promise<CDPSession> {\n if (this.cdpSession) {\n return this.cdpSession;\n }\n\n const page = this.getPage();\n const context = page.context();\n\n // Create a new CDP session attached to the page\n this.cdpSession = await context.newCDPSession(page);\n return this.cdpSession;\n }\n\n /**\n * Check if screencast is currently active\n */\n isScreencasting(): boolean {\n return this.screencastActive;\n }\n\n /**\n * Start screencast - streams viewport frames via CDP\n * @param callback Function called for each frame\n * @param options Screencast options\n */\n async startScreencast(\n callback: (frame: ScreencastFrame) => void,\n options?: ScreencastOptions\n ): Promise<void> {\n if (this.screencastActive) {\n throw new Error('Screencast already active');\n }\n\n const cdp = await this.getCDPSession();\n this.frameCallback = callback;\n this.screencastActive = true;\n\n // Create and store the frame handler so we can remove it later\n this.screencastFrameHandler = async (params: any) => {\n const frame: ScreencastFrame = {\n data: params.data,\n metadata: params.metadata,\n sessionId: params.sessionId,\n };\n\n // Acknowledge the frame to receive the next one\n await cdp.send('Page.screencastFrameAck', { sessionId: params.sessionId });\n\n // Call the callback with the frame\n if (this.frameCallback) {\n this.frameCallback(frame);\n }\n };\n\n // Listen for screencast frames\n cdp.on('Page.screencastFrame', this.screencastFrameHandler);\n\n // Start the screencast\n await cdp.send('Page.startScreencast', {\n format: options?.format ?? 'jpeg',\n quality: options?.quality ?? 80,\n maxWidth: options?.maxWidth ?? 1280,\n maxHeight: options?.maxHeight ?? 720,\n everyNthFrame: options?.everyNthFrame ?? 1,\n });\n }\n\n /**\n * Stop screencast\n */\n async stopScreencast(): Promise<void> {\n if (!this.screencastActive) {\n return;\n }\n\n try {\n const cdp = await this.getCDPSession();\n await cdp.send('Page.stopScreencast');\n\n // Remove the event listener to prevent accumulation\n if (this.screencastFrameHandler) {\n cdp.off('Page.screencastFrame', this.screencastFrameHandler);\n }\n } catch {\n // Ignore errors when stopping\n }\n\n this.screencastActive = false;\n this.frameCallback = null;\n this.screencastFrameHandler = null;\n }\n\n /**\n * Inject a mouse event via CDP\n */\n async injectMouseEvent(params: {\n type: 'mousePressed' | 'mouseReleased' | 'mouseMoved' | 'mouseWheel';\n x: number;\n y: number;\n button?: 'left' | 'right' | 'middle' | 'none';\n clickCount?: number;\n deltaX?: number;\n deltaY?: number;\n modifiers?: number; // 1=Alt, 2=Ctrl, 4=Meta, 8=Shift\n }): Promise<void> {\n const cdp = await this.getCDPSession();\n\n const cdpButton =\n params.button === 'left'\n ? 'left'\n : params.button === 'right'\n ? 'right'\n : params.button === 'middle'\n ? 'middle'\n : 'none';\n\n await cdp.send('Input.dispatchMouseEvent', {\n type: params.type,\n x: params.x,\n y: params.y,\n button: cdpButton,\n clickCount: params.clickCount ?? 1,\n deltaX: params.deltaX ?? 0,\n deltaY: params.deltaY ?? 0,\n modifiers: params.modifiers ?? 0,\n });\n }\n\n /**\n * Inject a keyboard event via CDP\n */\n async injectKeyboardEvent(params: {\n type: 'keyDown' | 'keyUp' | 'char';\n key?: string;\n code?: string;\n text?: string;\n modifiers?: number; // 1=Alt, 2=Ctrl, 4=Meta, 8=Shift\n }): Promise<void> {\n const cdp = await this.getCDPSession();\n\n await cdp.send('Input.dispatchKeyEvent', {\n type: params.type,\n key: params.key,\n code: params.code,\n text: params.text,\n modifiers: params.modifiers ?? 0,\n });\n }\n\n /**\n * Inject touch event via CDP (for mobile emulation)\n */\n async injectTouchEvent(params: {\n type: 'touchStart' | 'touchEnd' | 'touchMove' | 'touchCancel';\n touchPoints: Array<{ x: number; y: number; id?: number }>;\n modifiers?: number;\n }): Promise<void> {\n const cdp = await this.getCDPSession();\n\n await cdp.send('Input.dispatchTouchEvent', {\n type: params.type,\n touchPoints: params.touchPoints.map((tp, i) => ({\n x: tp.x,\n y: tp.y,\n id: tp.id ?? i,\n })),\n modifiers: params.modifiers ?? 0,\n });\n }\n\n /**\n * Check if video recording is currently active\n */\n isRecording(): boolean {\n return this.recordingContext !== null;\n }\n\n /**\n * Start recording to a video file using Playwright's native video recording.\n * Creates a fresh browser context with video recording enabled.\n * Automatically captures current URL and transfers cookies/storage if no URL provided.\n *\n * @param outputPath - Path to the output video file (will be .webm)\n * @param url - Optional URL to navigate to (defaults to current page URL)\n */\n async startRecording(outputPath: string, url?: string): Promise<void> {\n if (this.recordingContext) {\n throw new Error(\n \"Recording already in progress. Run 'record stop' first, or use 'record restart' to stop and start a new recording.\"\n );\n }\n\n if (!this.browser) {\n throw new Error('Browser not launched. Call launch first.');\n }\n\n // Check if output file already exists\n if (existsSync(outputPath)) {\n throw new Error(`Output file already exists: ${outputPath}`);\n }\n\n // Validate output path is .webm (Playwright native format)\n if (!outputPath.endsWith('.webm')) {\n throw new Error(\n 'Playwright native recording only supports WebM format. Please use a .webm extension.'\n );\n }\n\n // Auto-capture current URL if none provided\n const currentPage = this.pages.length > 0 ? this.pages[this.activePageIndex] : null;\n const currentContext = this.contexts.length > 0 ? this.contexts[0] : null;\n if (!url && currentPage) {\n const currentUrl = currentPage.url();\n if (currentUrl && currentUrl !== 'about:blank') {\n url = currentUrl;\n }\n }\n\n // Capture state from current context (cookies + storage)\n let storageState:\n | {\n cookies: Array<{\n name: string;\n value: string;\n domain: string;\n path: string;\n expires: number;\n httpOnly: boolean;\n secure: boolean;\n sameSite: 'Strict' | 'Lax' | 'None';\n }>;\n origins: Array<{\n origin: string;\n localStorage: Array<{ name: string; value: string }>;\n }>;\n }\n | undefined;\n\n if (currentContext) {\n try {\n storageState = await currentContext.storageState();\n } catch {\n // Ignore errors - context might be closed or invalid\n }\n }\n\n // Create a temp directory for video recording\n const session = process.env.AGENT_BROWSER_SESSION || 'default';\n this.recordingTempDir = path.join(\n os.tmpdir(),\n `agent-browser-recording-${session}-${Date.now()}`\n );\n mkdirSync(this.recordingTempDir, { recursive: true });\n\n this.recordingOutputPath = outputPath;\n\n // Create a new context with video recording enabled and restored state\n const viewport = { width: 1280, height: 720 };\n this.recordingContext = await this.browser.newContext({\n viewport,\n recordVideo: {\n dir: this.recordingTempDir,\n size: viewport,\n },\n storageState,\n });\n this.recordingContext.setDefaultTimeout(10000);\n\n // Create a page in the recording context\n this.recordingPage = await this.recordingContext.newPage();\n\n // Add the recording context and page to our managed lists\n this.contexts.push(this.recordingContext);\n this.pages.push(this.recordingPage);\n this.activePageIndex = this.pages.length - 1;\n\n // Set up page tracking\n this.setupPageTracking(this.recordingPage);\n\n // Invalidate CDP session since we switched pages\n await this.invalidateCDPSession();\n\n // Navigate to URL if provided or captured\n if (url) {\n await this.recordingPage.goto(url, { waitUntil: 'load' });\n }\n }\n\n /**\n * Stop recording and save the video file\n * @returns Recording result with path\n */\n async stopRecording(): Promise<{ path: string; frames: number; error?: string }> {\n if (!this.recordingContext || !this.recordingPage) {\n return { path: '', frames: 0, error: 'No recording in progress' };\n }\n\n const outputPath = this.recordingOutputPath;\n\n try {\n // Get the video object before closing the page\n const video = this.recordingPage.video();\n\n // Remove recording page/context from our managed lists before closing\n const pageIndex = this.pages.indexOf(this.recordingPage);\n if (pageIndex !== -1) {\n this.pages.splice(pageIndex, 1);\n }\n const contextIndex = this.contexts.indexOf(this.recordingContext);\n if (contextIndex !== -1) {\n this.contexts.splice(contextIndex, 1);\n }\n\n // Close the page to finalize the video\n await this.recordingPage.close();\n\n // Save the video to the desired output path\n if (video) {\n await video.saveAs(outputPath);\n }\n\n // Clean up temp directory\n if (this.recordingTempDir) {\n rmSync(this.recordingTempDir, { recursive: true, force: true });\n }\n\n // Close the recording context\n await this.recordingContext.close();\n\n // Reset recording state\n this.recordingContext = null;\n this.recordingPage = null;\n this.recordingOutputPath = '';\n this.recordingTempDir = '';\n\n // Adjust active page index\n if (this.pages.length > 0) {\n this.activePageIndex = Math.min(this.activePageIndex, this.pages.length - 1);\n } else {\n this.activePageIndex = 0;\n }\n\n // Invalidate CDP session since we may have switched pages\n await this.invalidateCDPSession();\n\n return { path: outputPath, frames: 0 }; // Playwright doesn't expose frame count\n } catch (error) {\n // Clean up temp directory on error\n if (this.recordingTempDir) {\n rmSync(this.recordingTempDir, { recursive: true, force: true });\n }\n\n // Reset state on error\n this.recordingContext = null;\n this.recordingPage = null;\n this.recordingOutputPath = '';\n this.recordingTempDir = '';\n\n const message = error instanceof Error ? error.message : String(error);\n return { path: outputPath, frames: 0, error: message };\n }\n }\n\n /**\n * Restart recording - stops current recording (if any) and starts a new one.\n * Convenience method that combines stopRecording and startRecording.\n *\n * @param outputPath - Path to the output video file (must be .webm)\n * @param url - Optional URL to navigate to (defaults to current page URL)\n * @returns Result from stopping the previous recording (if any)\n */\n async restartRecording(\n outputPath: string,\n url?: string\n ): Promise<{ previousPath?: string; stopped: boolean }> {\n let previousPath: string | undefined;\n let stopped = false;\n\n // Stop current recording if active\n if (this.recordingContext) {\n const result = await this.stopRecording();\n previousPath = result.path;\n stopped = true;\n }\n\n // Start new recording\n await this.startRecording(outputPath, url);\n\n return { previousPath, stopped };\n }\n\n /**\n * Close the browser and clean up\n */\n async close(): Promise<void> {\n // Stop recording if active (saves video)\n if (this.recordingContext) {\n await this.stopRecording();\n }\n\n // Stop screencast if active\n if (this.screencastActive) {\n await this.stopScreencast();\n }\n\n // Clean up CDP session\n if (this.cdpSession) {\n await this.cdpSession.detach().catch(() => {});\n this.cdpSession = null;\n }\n\n if (this.browserbaseSessionId && this.browserbaseApiKey) {\n await this.closeBrowserbaseSession(this.browserbaseSessionId, this.browserbaseApiKey).catch(\n (error) => {\n console.error('Failed to close Browserbase session:', error);\n }\n );\n this.browser = null;\n } else if (this.browserUseSessionId && this.browserUseApiKey) {\n await this.closeBrowserUseSession(this.browserUseSessionId, this.browserUseApiKey).catch(\n (error) => {\n console.error('Failed to close Browser Use session:', error);\n }\n );\n this.browser = null;\n } else if (this.kernelSessionId && this.kernelApiKey) {\n await this.closeKernelSession(this.kernelSessionId, this.kernelApiKey).catch((error) => {\n console.error('Failed to close Kernel session:', error);\n });\n this.browser = null;\n } else if (this.cdpEndpoint !== null) {\n // CDP: only disconnect, don't close external app's pages\n if (this.browser) {\n await this.browser.close().catch(() => {});\n this.browser = null;\n }\n } else {\n // Regular browser: close everything\n for (const page of this.pages) {\n await page.close().catch(() => {});\n }\n for (const context of this.contexts) {\n await context.close().catch(() => {});\n }\n if (this.browser) {\n await this.browser.close().catch(() => {});\n this.browser = null;\n }\n }\n\n this.pages = [];\n this.contexts = [];\n this.cdpEndpoint = null;\n this.browserbaseSessionId = null;\n this.browserbaseApiKey = null;\n this.browserUseSessionId = null;\n this.browserUseApiKey = null;\n this.kernelSessionId = null;\n this.kernelApiKey = null;\n this.isPersistentContext = false;\n this.activePageIndex = 0;\n this.refMap = {};\n this.lastSnapshot = '';\n this.frameCallback = null;\n }\n}\n","/**\n * Enhanced snapshot with element refs for deterministic element selection.\n *\n * This module generates accessibility snapshots with embedded refs that can be\n * used to click/fill/interact with elements without re-querying the DOM.\n *\n * Example output:\n * - heading \"Example Domain\" [ref=e1] [level=1]\n * - paragraph: Some text content\n * - button \"Submit\" [ref=e2]\n * - textbox \"Email\" [ref=e3]\n *\n * Usage:\n * agent-browser snapshot # Full snapshot\n * agent-browser snapshot -i # Interactive elements only\n * agent-browser snapshot --depth 3 # Limit depth\n * agent-browser click @e2 # Click element by ref\n */\n\nimport type { Page, Locator } from 'playwright-core';\n\nexport interface RefMap {\n [ref: string]: {\n selector: string;\n role: string;\n name?: string;\n /** Index for disambiguation when multiple elements have same role+name */\n nth?: number;\n /** Coordinate-based bounds from DualMode tree */\n bounds?: { left: number; top: number; right: number; bottom: number };\n /** CDP Node ID */\n nodeId?: number;\n };\n}\n\nexport interface EnhancedSnapshot {\n tree: string;\n refs: RefMap;\n}\n\nexport interface SnapshotOptions {\n /** Only include interactive elements (buttons, links, inputs, etc.) */\n interactive?: boolean;\n /** Include cursor-interactive elements (cursor:pointer, onclick, tabindex) */\n cursor?: boolean;\n /** Maximum depth of tree to include (0 = root only) */\n maxDepth?: number;\n /** Remove structural elements without meaningful content */\n compact?: boolean;\n /** CSS selector to scope the snapshot */\n selector?: string;\n}\n\n// Counter for generating refs\nlet refCounter = 0;\n\n/**\n * Reset ref counter (call at start of each snapshot)\n */\nexport function resetRefs(): void {\n refCounter = 0;\n}\n\n/**\n * Generate next ref ID\n */\nfunction nextRef(): string {\n return `e${++refCounter}`;\n}\n\n/**\n * Roles that are interactive and should get refs\n */\nconst INTERACTIVE_ROLES = new Set([\n 'button',\n 'link',\n 'textbox',\n 'checkbox',\n 'radio',\n 'combobox',\n 'listbox',\n 'menuitem',\n 'menuitemcheckbox',\n 'menuitemradio',\n 'option',\n 'searchbox',\n 'slider',\n 'spinbutton',\n 'switch',\n 'tab',\n 'treeitem',\n]);\n\n/**\n * Roles that provide structure/context (get refs for text extraction)\n */\nconst CONTENT_ROLES = new Set([\n 'heading',\n 'cell',\n 'gridcell',\n 'columnheader',\n 'rowheader',\n 'listitem',\n 'article',\n 'region',\n 'main',\n 'navigation',\n]);\n\n/**\n * Roles that are purely structural (can be filtered in compact mode)\n */\nconst STRUCTURAL_ROLES = new Set([\n 'generic',\n 'group',\n 'list',\n 'table',\n 'row',\n 'rowgroup',\n 'grid',\n 'treegrid',\n 'menu',\n 'menubar',\n 'toolbar',\n 'tablist',\n 'tree',\n 'directory',\n 'document',\n 'application',\n 'presentation',\n 'none',\n]);\n\n/**\n * Build a selector string for storing in ref map\n */\nfunction buildSelector(role: string, name?: string): string {\n if (name) {\n const escapedName = name.replace(/\"/g, '\\\\\"');\n return `getByRole('${role}', { name: \"${escapedName}\", exact: true })`;\n }\n return `getByRole('${role}')`;\n}\n\n/**\n * Query the page for clickable elements that might not have proper ARIA roles.\n * This finds elements with cursor: pointer or onclick handlers.\n */\nasync function findCursorInteractiveElements(\n page: Page,\n selector?: string\n): Promise<\n Array<{\n selector: string;\n text: string;\n tagName: string;\n hasOnClick: boolean;\n hasCursorPointer: boolean;\n hasTabIndex: boolean;\n }>\n> {\n const rootSelector = selector || 'body';\n\n // Use a string function body to avoid TypeScript transpilation issues\n const scriptBody = `(rootSel) => {\n const results = [];\n\n // Elements that already have interactive ARIA roles - skip these\n const interactiveRoles = new Set([\n 'button', 'link', 'textbox', 'checkbox', 'radio', 'combobox', 'listbox',\n 'menuitem', 'menuitemcheckbox', 'menuitemradio', 'option', 'searchbox',\n 'slider', 'spinbutton', 'switch', 'tab', 'treeitem'\n ]);\n\n // Tags that are already interactive by default\n const interactiveTags = new Set([\n 'a', 'button', 'input', 'select', 'textarea', 'details', 'summary'\n ]);\n\n const root = document.querySelector(rootSel) || document.body;\n const allElements = root.querySelectorAll('*');\n\n // Build a unique selector for an element\n const buildSelector = (el) => {\n const testId = el.getAttribute('data-testid');\n if (testId) return '[data-testid=\"' + testId + '\"]';\n if (el.id) return '#' + CSS.escape(el.id);\n\n const path = [];\n let current = el;\n while (current && current !== document.body) {\n let sel = current.tagName.toLowerCase();\n const classes = Array.from(current.classList).filter(c => c.trim());\n if (classes.length > 0) sel += '.' + CSS.escape(classes[0]);\n\n const parent = current.parentElement;\n if (parent) {\n const siblings = Array.from(parent.children);\n const matching = siblings.filter(s => {\n if (s.tagName !== current.tagName) return false;\n if (classes.length > 0 && !s.classList.contains(classes[0])) return false;\n return true;\n });\n if (matching.length > 1) {\n const idx = matching.indexOf(current) + 1;\n sel += ':nth-of-type(' + idx + ')';\n }\n }\n path.unshift(sel);\n current = current.parentElement;\n if (path.length >= 3) break;\n }\n return path.join(' > ');\n };\n\n for (const el of allElements) {\n const tagName = el.tagName.toLowerCase();\n if (interactiveTags.has(tagName)) continue;\n\n const role = el.getAttribute('role');\n if (role && interactiveRoles.has(role.toLowerCase())) continue;\n\n const computedStyle = getComputedStyle(el);\n const hasCursorPointer = computedStyle.cursor === 'pointer';\n const hasOnClick = el.hasAttribute('onclick') || el.onclick !== null;\n const tabIndex = el.getAttribute('tabindex');\n const hasTabIndex = tabIndex !== null && tabIndex !== '-1';\n\n if (!hasCursorPointer && !hasOnClick && !hasTabIndex) continue;\n\n const text = (el.textContent || '').trim().slice(0, 100);\n if (!text) continue;\n\n const rect = el.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) continue;\n\n results.push({\n selector: buildSelector(el),\n text,\n tagName,\n hasOnClick,\n hasCursorPointer,\n hasTabIndex\n });\n }\n return results;\n }`;\n\n \n const fn = new Function('return ' + scriptBody)();\n return page.evaluate(fn, rootSelector);\n}\n\n/**\n * Get enhanced snapshot with refs and optional filtering\n */\nexport async function getEnhancedSnapshot(\n page: Page,\n options: SnapshotOptions = {}\n): Promise<EnhancedSnapshot> {\n resetRefs();\n const refs: RefMap = {};\n\n // Get ARIA snapshot from Playwright\n const locator = options.selector ? page.locator(options.selector) : page.locator(':root');\n const ariaTree = await locator.ariaSnapshot();\n\n if (!ariaTree) {\n return {\n tree: '(empty)',\n refs: {},\n };\n }\n\n // Parse and enhance the ARIA tree\n const enhancedTree = processAriaTree(ariaTree, refs, options);\n\n // When cursor flag is set, also find cursor-interactive elements\n // that may not have proper ARIA roles\n if (options.cursor) {\n const cursorElements = await findCursorInteractiveElements(page, options.selector);\n\n // Filter out elements whose text is already captured in the snapshot\n const existingTexts = new Set(Object.values(refs).map((r) => r.name?.toLowerCase()));\n\n const additionalLines: string[] = [];\n for (const el of cursorElements) {\n // Skip if text already captured (likely already in ARIA tree)\n if (existingTexts.has(el.text.toLowerCase())) continue;\n\n const ref = nextRef();\n const role = el.hasCursorPointer ? 'clickable' : el.hasOnClick ? 'clickable' : 'focusable';\n\n refs[ref] = {\n selector: el.selector,\n role: role,\n name: el.text,\n };\n\n // Build description of why it's interactive\n const hints: string[] = [];\n if (el.hasCursorPointer) hints.push('cursor:pointer');\n if (el.hasOnClick) hints.push('onclick');\n if (el.hasTabIndex) hints.push('tabindex');\n\n additionalLines.push(`- ${role} \"${el.text}\" [ref=${ref}] [${hints.join(', ')}]`);\n }\n\n if (additionalLines.length > 0) {\n const separator =\n enhancedTree === '(no interactive elements)' ? '' : '\\n# Cursor-interactive elements:\\n';\n const base = enhancedTree === '(no interactive elements)' ? '' : enhancedTree;\n return {\n tree: base + separator + additionalLines.join('\\n'),\n refs,\n };\n }\n }\n\n return { tree: enhancedTree, refs };\n}\n\n/**\n * Track role+name combinations to detect duplicates\n */\ninterface RoleNameTracker {\n counts: Map<string, number>;\n /** Maps role+name key to array of ref IDs that use it */\n refsByKey: Map<string, string[]>;\n getKey(role: string, name?: string): string;\n getNextIndex(role: string, name?: string): number;\n trackRef(role: string, name: string | undefined, ref: string): void;\n /** Get all role+name keys that have duplicates */\n getDuplicateKeys(): Set<string>;\n}\n\nfunction createRoleNameTracker(): RoleNameTracker {\n const counts = new Map<string, number>();\n const refsByKey = new Map<string, string[]>();\n return {\n counts,\n refsByKey,\n getKey(role: string, name?: string): string {\n return `${role}:${name ?? ''}`;\n },\n getNextIndex(role: string, name?: string): number {\n const key = this.getKey(role, name);\n const current = counts.get(key) ?? 0;\n counts.set(key, current + 1);\n return current;\n },\n trackRef(role: string, name: string | undefined, ref: string): void {\n const key = this.getKey(role, name);\n const refs = refsByKey.get(key) ?? [];\n refs.push(ref);\n refsByKey.set(key, refs);\n },\n getDuplicateKeys(): Set<string> {\n const duplicates = new Set<string>();\n for (const [key, refs] of refsByKey) {\n if (refs.length > 1) {\n duplicates.add(key);\n }\n }\n return duplicates;\n },\n };\n}\n\n/**\n * Process ARIA snapshot: add refs and apply filters\n */\nfunction processAriaTree(ariaTree: string, refs: RefMap, options: SnapshotOptions): string {\n const lines = ariaTree.split('\\n');\n const result: string[] = [];\n const tracker = createRoleNameTracker();\n\n // For interactive-only mode, we collect just interactive elements\n if (options.interactive) {\n for (const line of lines) {\n const match = line.match(/^(\\s*-\\s*)(\\w+)(?:\\s+\"([^\"]*)\")?(.*)$/);\n if (!match) continue;\n\n const [, , role, name, suffix] = match;\n const roleLower = role.toLowerCase();\n\n if (INTERACTIVE_ROLES.has(roleLower)) {\n const ref = nextRef();\n const nth = tracker.getNextIndex(roleLower, name);\n tracker.trackRef(roleLower, name, ref);\n refs[ref] = {\n selector: buildSelector(roleLower, name),\n role: roleLower,\n name,\n nth, // Always store nth, we'll use it for duplicates\n };\n\n let enhanced = `- ${role}`;\n if (name) enhanced += ` \"${name}\"`;\n enhanced += ` [ref=${ref}]`;\n // Only show nth in output if it's > 0 (for readability)\n if (nth > 0) enhanced += ` [nth=${nth}]`;\n if (suffix && suffix.includes('[')) enhanced += suffix;\n\n result.push(enhanced);\n }\n }\n\n // Post-process: remove nth from refs that don't have duplicates\n removeNthFromNonDuplicates(refs, tracker);\n\n return result.join('\\n') || '(no interactive elements)';\n }\n\n // Normal processing with depth/compact filters\n for (const line of lines) {\n const processed = processLine(line, refs, options, tracker);\n if (processed !== null) {\n result.push(processed);\n }\n }\n\n // Post-process: remove nth from refs that don't have duplicates\n removeNthFromNonDuplicates(refs, tracker);\n\n // If compact mode, remove empty structural elements\n if (options.compact) {\n return compactTree(result.join('\\n'));\n }\n\n return result.join('\\n');\n}\n\n/**\n * Remove nth from refs that ended up not having duplicates\n * This keeps single-element locators simple (no unnecessary .nth(0))\n */\nfunction removeNthFromNonDuplicates(refs: RefMap, tracker: RoleNameTracker): void {\n const duplicateKeys = tracker.getDuplicateKeys();\n\n for (const [ref, data] of Object.entries(refs)) {\n const key = tracker.getKey(data.role, data.name);\n if (!duplicateKeys.has(key)) {\n // Not a duplicate, remove nth to keep locator simple\n delete refs[ref].nth;\n }\n }\n}\n\n/**\n * Get indentation level (number of spaces / 2)\n */\nfunction getIndentLevel(line: string): number {\n const match = line.match(/^(\\s*)/);\n return match ? Math.floor(match[1].length / 2) : 0;\n}\n\n/**\n * Process a single line: add ref if needed, filter if requested\n */\nfunction processLine(\n line: string,\n refs: RefMap,\n options: SnapshotOptions,\n tracker: RoleNameTracker\n): string | null {\n const depth = getIndentLevel(line);\n\n // Check max depth\n if (options.maxDepth !== undefined && depth > options.maxDepth) {\n return null;\n }\n\n // Match lines like:\n // - button \"Submit\"\n // - heading \"Title\" [level=1]\n // - link \"Click me\":\n const match = line.match(/^(\\s*-\\s*)(\\w+)(?:\\s+\"([^\"]*)\")?(.*)$/);\n\n if (!match) {\n // Metadata lines (like /url:) or text content\n if (options.interactive) {\n // In interactive mode, only keep metadata under interactive elements\n return null;\n }\n return line;\n }\n\n const [, prefix, role, name, suffix] = match;\n const roleLower = role.toLowerCase();\n\n // Skip metadata lines (like /url:)\n if (role.startsWith('/')) {\n return line;\n }\n\n const isInteractive = INTERACTIVE_ROLES.has(roleLower);\n const isContent = CONTENT_ROLES.has(roleLower);\n const isStructural = STRUCTURAL_ROLES.has(roleLower);\n\n // In interactive-only mode, filter non-interactive elements\n if (options.interactive && !isInteractive) {\n return null;\n }\n\n // In compact mode, skip unnamed structural elements\n if (options.compact && isStructural && !name) {\n return null;\n }\n\n // Add ref for interactive or named content elements\n const shouldHaveRef = isInteractive || (isContent && name);\n\n if (shouldHaveRef) {\n const ref = nextRef();\n const nth = tracker.getNextIndex(roleLower, name);\n tracker.trackRef(roleLower, name, ref);\n\n refs[ref] = {\n selector: buildSelector(roleLower, name),\n role: roleLower,\n name,\n nth, // Always store nth, we'll clean up non-duplicates later\n };\n\n // Build enhanced line with ref\n let enhanced = `${prefix}${role}`;\n if (name) enhanced += ` \"${name}\"`;\n enhanced += ` [ref=${ref}]`;\n // Only show nth in output if it's > 0 (for readability)\n if (nth > 0) enhanced += ` [nth=${nth}]`;\n if (suffix) enhanced += suffix;\n\n return enhanced;\n }\n\n return line;\n}\n\n/**\n * Remove empty structural branches in compact mode\n */\nfunction compactTree(tree: string): string {\n const lines = tree.split('\\n');\n const result: string[] = [];\n\n // Simple pass: keep lines that have content or refs\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Always keep lines with refs\n if (line.includes('[ref=')) {\n result.push(line);\n continue;\n }\n\n // Keep lines with text content (after :)\n if (line.includes(':') && !line.endsWith(':')) {\n result.push(line);\n continue;\n }\n\n // Check if this structural element has children with refs\n const currentIndent = getIndentLevel(line);\n let hasRelevantChildren = false;\n\n for (let j = i + 1; j < lines.length; j++) {\n const childIndent = getIndentLevel(lines[j]);\n if (childIndent <= currentIndent) break;\n if (lines[j].includes('[ref=')) {\n hasRelevantChildren = true;\n break;\n }\n }\n\n if (hasRelevantChildren) {\n result.push(line);\n }\n }\n\n return result.join('\\n');\n}\n\n/**\n * Parse a ref from command argument (e.g., \"@e1\" -> \"e1\")\n */\nexport function parseRef(arg: string): string | null {\n if (arg.startsWith('@')) {\n return arg.slice(1);\n }\n if (arg.startsWith('ref=')) {\n return arg.slice(4);\n }\n if (/^e\\d+$/.test(arg)) {\n return arg;\n }\n return null;\n}\n\n/**\n * Get snapshot statistics\n */\nexport function getSnapshotStats(\n tree: string,\n refs: RefMap\n): {\n lines: number;\n chars: number;\n tokens: number;\n refs: number;\n interactive: number;\n} {\n const interactive = Object.values(refs).filter((r) => INTERACTIVE_ROLES.has(r.role)).length;\n\n return {\n lines: tree.split('\\n').length,\n chars: tree.length,\n tokens: Math.ceil(tree.length / 4),\n refs: Object.keys(refs).length,\n interactive,\n };\n}\n","import type { Page } from 'playwright-core';\nimport type { EnhancedSnapshot, RefMap } from './snapshot.js';\n\ninterface DualModeNode {\n core: {\n nodeId: number;\n backendNodeId: number;\n childrenIds?: number[];\n parentId?: number;\n className?: string;\n text?: string;\n contentDescription?: string;\n bounds: {\n left: number;\n top: number;\n right: number;\n bottom: number;\n };\n clickable: boolean;\n longClickable: boolean;\n scrollable: boolean;\n focusable: boolean;\n editable: boolean;\n checkable: boolean;\n enabled: boolean;\n focused: boolean;\n selected: boolean;\n checked: boolean;\n visible: boolean;\n };\n designMode?: {\n visual?: {\n backgroundColor?: string;\n foregroundColor?: string;\n opacity?: number;\n fontSize?: number;\n fontWeight?: number;\n };\n layout?: {\n zIndex?: number;\n isFixedPosition?: boolean;\n isSticky?: boolean;\n };\n spatial?: {\n distanceFromViewportTop?: number;\n isAboveFold?: boolean;\n visualProminenceScore?: number;\n };\n };\n xrayMode?: {\n semantics?: {\n role?: string;\n name?: string;\n description?: string;\n intentTags?: string[];\n importanceScore?: number;\n };\n interaction?: {\n enabled?: boolean;\n selected?: boolean;\n checked?: boolean;\n expanded?: boolean;\n focused?: boolean;\n availableActions?: string[];\n affordanceScore?: number;\n };\n };\n children?: DualModeNode[];\n}\n\ninterface AXNode {\n nodeId: string;\n role?: { value: string };\n name?: { value: string };\n childIds?: string[];\n parentId?: string;\n}\n\ntype HydratedAXNode = AXNode & { children: HydratedAXNode[] };\n\nexport async function getDualModeSnapshot(\n page: Page,\n options: { interactive?: boolean } = {}\n): Promise<EnhancedSnapshot> {\n const session = await page.context().newCDPSession(page);\n let nodes: any[] = [];\n let isDualMode = false;\n\n try {\n const result = (await session.send('Accessibility.getDualModeAXTree' as any)) as any;\n nodes = result.nodes;\n isDualMode = true;\n } catch (e) {\n try {\n const result = (await session.send('Accessibility.getFullAXTree')) as any;\n nodes = result.nodes;\n } catch (e2) {\n console.warn('Failed to fetch AXTree via CDP:', e2);\n return { tree: '(accessibility tree unavailable)', refs: {} };\n }\n } finally {\n await session.detach();\n }\n\n const refs: RefMap = {};\n let tree = '';\n\n resetRefs();\n\n if (isDualMode) {\n const rootNodes = buildTreeFromFlatNodes(nodes);\n tree = processDualModeTree(rootNodes, refs, options.interactive ?? false);\n } else {\n const rootNodes = buildStandardTree(nodes);\n tree = processStandardTree(rootNodes, refs, options.interactive ?? false);\n }\n\n return { tree, refs };\n}\n\nfunction buildTreeFromFlatNodes(nodes: DualModeNode[]): DualModeNode[] {\n const nodeMap = new Map<number, DualModeNode>();\n nodes.forEach((n) => nodeMap.set(n.core.nodeId, n));\n\n const roots: DualModeNode[] = [];\n\n nodes.forEach((node) => {\n if (node.core.childrenIds) {\n node.children = node.core.childrenIds\n .map((id) => nodeMap.get(id))\n .filter((n): n is DualModeNode => !!n);\n }\n\n const parentId = node.core.parentId;\n if (parentId === undefined || !nodeMap.has(parentId)) {\n roots.push(node);\n }\n });\n\n return roots;\n}\n\nfunction buildStandardTree(nodes: AXNode[]): HydratedAXNode[] {\n const nodeMap = new Map<string, HydratedAXNode>();\n // Initialize with empty children array\n nodes.forEach((n) => nodeMap.set(n.nodeId, { ...n, children: [] } as HydratedAXNode));\n\n const roots: HydratedAXNode[] = [];\n const childrenIdsSet = new Set<string>();\n\n nodes.forEach((node) => {\n if (node.childIds) {\n const parent = nodeMap.get(node.nodeId);\n if (parent) {\n node.childIds.forEach((childId) => {\n const child = nodeMap.get(childId);\n if (child) {\n parent.children.push(child);\n childrenIdsSet.add(childId);\n }\n });\n }\n }\n });\n\n nodes.forEach((node) => {\n if (!childrenIdsSet.has(node.nodeId)) {\n const root = nodeMap.get(node.nodeId);\n if (root) roots.push(root);\n }\n });\n\n return roots;\n}\n\nlet refCounter = 0;\nfunction resetRefs(): void {\n refCounter = 0;\n}\nfunction nextRef(): string {\n return `e${++refCounter}`;\n}\n\nconst INTERACTIVE_ROLES = new Set([\n 'button',\n 'link',\n 'textbox',\n 'checkbox',\n 'radio',\n 'combobox',\n 'listbox',\n 'menuitem',\n 'option',\n 'searchbox',\n 'slider',\n 'spinbutton',\n 'switch',\n 'tab',\n 'treeitem',\n]);\n\nfunction processDualModeTree(\n nodes: DualModeNode[],\n refs: RefMap,\n interactiveOnly: boolean = false,\n depth: number = 0\n): string {\n const lines: string[] = [];\n\n for (const node of nodes) {\n const core = node.core;\n if (!core.visible) continue;\n\n const semantics = node.xrayMode?.semantics || {};\n const interaction = node.xrayMode?.interaction || {};\n const design = node.designMode || {};\n\n const role = (semantics.role || core.className || 'unknown').toLowerCase();\n let name = semantics.name || core.text || core.contentDescription || '';\n name = name.replace(/\\s+/g, ' ').trim();\n\n // Smart Merge: Use child text if name is empty\n if (name === '' && node.children && node.children.length > 0) {\n const textChild = node.children.find((c) => c.core.className === '#text.StaticText');\n if (textChild) {\n name = (textChild.core.text || '').trim();\n }\n }\n\n const isInteractive =\n core.clickable ||\n INTERACTIVE_ROLES.has(role) ||\n semantics.intentTags?.includes('interactive');\n\n if (interactiveOnly && !isInteractive && (!node.children || node.children.length === 0)) {\n continue;\n }\n\n let line = `${' '.repeat(depth)}- ${role}`;\n if (name) line += ` \"${name.replace(/\"/g, '\\\\\"')}\"`;\n\n if (isInteractive || (name && !['unknown', 'generic', 'group'].includes(role))) {\n const ref = nextRef();\n line += ` [ref=${ref}]`;\n\n const safeNameDouble = name.replace(/\"/g, '\\\\\"');\n let selector = '';\n if (['button', 'link', 'textbox', 'checkbox', 'radio'].includes(role)) {\n if (name) selector = `getByRole('${role}', { name: \"${safeNameDouble}\" })`;\n else selector = `getByRole('${role}')`;\n } else if (name) {\n selector = `getByText(\"${safeNameDouble}\")`;\n } else {\n selector = `locator('.${core.className || role}')`;\n }\n\n refs[ref] = {\n selector,\n role,\n name,\n bounds: core.bounds,\n nodeId: core.nodeId,\n };\n }\n\n // --- FULL METADATA OUTPUT ---\n\n // 1. Core Info (filtered to interesting flags)\n const coreInfo: Record<string, boolean> = {};\n if (core.clickable) coreInfo.clickable = true;\n if (core.longClickable) coreInfo.longClickable = true;\n if (core.scrollable) coreInfo.scrollable = true;\n if (core.focusable) coreInfo.focusable = true;\n if (core.editable) coreInfo.editable = true;\n if (core.checkable) coreInfo.checkable = true;\n if (core.checked) coreInfo.checked = true;\n if (core.selected) coreInfo.selected = true;\n if (core.focused) coreInfo.focused = true;\n if (!core.enabled) coreInfo.disabled = true;\n\n // 2. Xray Info (semantics + interaction)\n const xrayInfo: any = {};\n if (semantics.importanceScore) xrayInfo.importance = semantics.importanceScore;\n if (semantics.intentTags?.length) xrayInfo.intent = semantics.intentTags;\n if (interaction.availableActions?.length) xrayInfo.actions = interaction.availableActions;\n if (interaction.affordanceScore) xrayInfo.affordance = interaction.affordanceScore;\n\n // 3. Design Info (visual + layout + spatial)\n // Only include if non-default/interesting\n const designInfo: any = {};\n if (design.visual) {\n if (design.visual.backgroundColor) designInfo.bg = design.visual.backgroundColor;\n if (design.visual.foregroundColor) designInfo.fg = design.visual.foregroundColor;\n if (design.visual.fontSize) designInfo.fontSize = design.visual.fontSize;\n if (design.visual.fontWeight && design.visual.fontWeight !== 400)\n designInfo.weight = design.visual.fontWeight;\n if (design.visual.opacity !== 1) designInfo.opacity = design.visual.opacity;\n }\n if (design.layout) {\n if (design.layout.zIndex !== 0) designInfo.zIndex = design.layout.zIndex;\n if (design.layout.isFixedPosition) designInfo.fixed = true;\n if (design.layout.isSticky) designInfo.sticky = true;\n }\n if (design.spatial) {\n if (!design.spatial.isAboveFold) designInfo.belowFold = true;\n if (design.spatial.visualProminenceScore)\n designInfo.prominence = design.spatial.visualProminenceScore;\n }\n\n // Append JSON objects to line, indented\n const indent = ' '.repeat(depth + 1);\n\n if (Object.keys(coreInfo).length > 0) {\n line += `\\n${indent}core: ${JSON.stringify(coreInfo)}`;\n }\n if (Object.keys(xrayInfo).length > 0) {\n line += `\\n${indent}xray: ${JSON.stringify(xrayInfo)}`;\n }\n if (Object.keys(designInfo).length > 0) {\n line += `\\n${indent}design: ${JSON.stringify(designInfo)}`;\n }\n\n lines.push(line);\n\n if (node.children) {\n const filteredChildren = node.children.filter((c) => c.core.className !== '#text.StaticText');\n if (filteredChildren.length > 0) {\n const childrenStr = processDualModeTree(filteredChildren, refs, interactiveOnly, depth + 1);\n if (childrenStr) lines.push(childrenStr);\n }\n }\n }\n\n return lines.join('\\n');\n}\n\nfunction processStandardTree(\n nodes: HydratedAXNode[],\n refs: RefMap,\n interactiveOnly: boolean,\n depth: number = 0\n): string {\n const lines: string[] = [];\n\n for (const node of nodes) {\n const role = (node.role?.value || 'unknown').toLowerCase();\n let name = node.name?.value || '';\n name = name.replace(/\\s+/g, ' ').trim();\n\n const isInteractive = INTERACTIVE_ROLES.has(role);\n\n let line = `${' '.repeat(depth)}- ${role}`;\n if (name) {\n line += ` \"${name.replace(/\"/g, '\\\\\"')}\"`;\n }\n\n if (isInteractive || (name && role !== 'unknown')) {\n const ref = nextRef();\n line += ` [ref=${ref}]`;\n\n const safeNameDouble = name.replace(/\"/g, '\\\\\"');\n let selector = '';\n if (isInteractive) {\n if (name) selector = `getByRole('${role}', { name: \"${safeNameDouble}\" })`;\n else selector = `getByRole('${role}')`;\n } else if (name) {\n selector = `getByText(\"${safeNameDouble}\")`;\n } else {\n selector = `locator('${role}')`;\n }\n\n refs[ref] = {\n selector: selector,\n role: role,\n name: name,\n };\n }\n\n lines.push(line);\n\n if (node.children && node.children.length > 0) {\n const childrenTree = processStandardTree(node.children, refs, interactiveOnly, depth + 1);\n if (childrenTree) lines.push(childrenTree);\n }\n }\n\n return lines.join('\\n');\n}\n","/**\n * iOS Simulator Manager - Manages iOS Simulator and Safari automation via Appium.\n *\n * This provides 1:1 command parity with BrowserManager for iOS Safari.\n */\n\n// Declare browser globals used in execute() callbacks - these run in browser context, not Node\ndeclare const document: any;\ndeclare const window: any;\n\nimport { Simctl } from 'node-simctl';\nimport { remote, type Browser as WDIOBrowser } from 'webdriverio';\nimport { spawn, type ChildProcess } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport path from 'node:path';\nimport 'node:os';\n\n// Ref map for element targeting (mirrors snapshot.ts)\nexport interface IOSRefMap {\n [ref: string]: {\n selector: string;\n role?: string;\n name?: string;\n xpath?: string;\n };\n}\n\nexport interface IOSEnhancedSnapshot {\n tree: string;\n refs: IOSRefMap;\n}\n\ninterface ConsoleMessage {\n type: string;\n text: string;\n timestamp: number;\n}\n\ninterface IOSDeviceInfo {\n name: string;\n udid: string;\n state: string;\n runtime: string;\n isAvailable: boolean;\n isRealDevice?: boolean;\n}\n\n/**\n * Manages iOS Simulator and Safari automation via Appium\n */\nexport class IOSManager {\n private simctl: Simctl;\n private browser: WDIOBrowser | null = null;\n private appiumProcess: ChildProcess | null = null;\n private deviceUdid: string | null = null;\n private deviceName: string | null = null;\n private consoleMessages: ConsoleMessage[] = [];\n private refMap: IOSRefMap = {};\n private lastSnapshot: string = '';\n private refCounter: number = 0;\n\n // Default Appium port\n private static readonly APPIUM_PORT = 4723;\n private static readonly APPIUM_HOST = '127.0.0.1';\n\n constructor() {\n this.simctl = new Simctl();\n }\n\n /**\n * Check if browser is launched\n */\n isLaunched(): boolean {\n return this.browser !== null;\n }\n\n /**\n * List connected real iOS devices\n */\n private async listRealDevices(): Promise<IOSDeviceInfo[]> {\n const devices: IOSDeviceInfo[] = [];\n\n try {\n // Use xcrun xctrace to list connected devices\n const { execSync } = await import('node:child_process');\n const output = execSync('xcrun xctrace list devices 2>/dev/null || true', {\n encoding: 'utf-8',\n timeout: 10000,\n });\n\n // Parse output - format is:\n // == Devices ==\n // Device Name (OS Version) (UDID)\n // Real devices show version as just \"26.2\", simulators as \"iOS 18.0\"\n const lines = output.split('\\n');\n let inDevicesSection = false;\n\n for (const line of lines) {\n if (line.includes('== Devices ==')) {\n inDevicesSection = true;\n continue;\n }\n // Stop at Simulators or Devices Offline section\n if (line.includes('== Simulators ==') || line.includes('== Devices Offline ==')) {\n break;\n }\n\n if (inDevicesSection && line.trim()) {\n // Match pattern: \"Device Name (version) (UDID)\"\n const match = line.match(/^(.+?)\\s+\\(([^)]+)\\)\\s+\\(([A-F0-9-]+)\\)$/i);\n if (match) {\n const [, name, version, udid] = match;\n const nameLower = name.toLowerCase();\n // Include iOS devices: either name contains iPhone/iPad, or version looks like iOS\n // (a simple version number like \"26.2\" or \"18.6\") and isn't a Mac\n const isIOS =\n nameLower.includes('iphone') ||\n nameLower.includes('ipad') ||\n version.includes('iOS') ||\n version.includes('iPadOS');\n const isMac =\n nameLower.includes('mac') ||\n nameLower.includes('macbook') ||\n nameLower.includes('imac');\n\n if (isIOS || (!isMac && /^\\d+\\.\\d+(\\.\\d+)?$/.test(version))) {\n devices.push({\n name: name.trim(),\n udid: udid,\n state: 'Connected',\n runtime: `iOS ${version}`,\n isAvailable: true,\n isRealDevice: true,\n });\n }\n }\n }\n }\n } catch {\n // Ignore errors - real device listing is optional\n }\n\n return devices;\n }\n\n /**\n * List available iOS simulators\n */\n async listDevices(): Promise<IOSDeviceInfo[]> {\n const devices: IOSDeviceInfo[] = [];\n\n try {\n const rawDevices = await this.simctl.getDevices();\n\n for (const [runtime, deviceList] of Object.entries(rawDevices)) {\n if (!Array.isArray(deviceList)) continue;\n\n for (const device of deviceList) {\n // Only include iPhone and iPad simulators\n if (device.name && (device.name.includes('iPhone') || device.name.includes('iPad'))) {\n devices.push({\n name: device.name,\n udid: device.udid,\n state: device.state,\n runtime: runtime,\n isAvailable: device.isAvailable ?? true,\n isRealDevice: false,\n });\n }\n }\n }\n } catch (error) {\n throw new Error(\n `Failed to list iOS simulators. Is Xcode installed? Error: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n\n return devices;\n }\n\n /**\n * List all devices (simulators + real devices)\n */\n async listAllDevices(): Promise<IOSDeviceInfo[]> {\n const [simulators, realDevices] = await Promise.all([\n this.listDevices(),\n this.listRealDevices(),\n ]);\n\n // Real devices first, then simulators\n return [...realDevices, ...simulators];\n }\n\n /**\n * Find the best default device (most recent iPhone)\n */\n private async findDefaultDevice(): Promise<IOSDeviceInfo | null> {\n const devices = await this.listDevices();\n\n // Filter to available iPhones, prefer Pro models, then by name (which typically indicates recency)\n const iphones = devices\n .filter((d) => d.isAvailable && d.name.includes('iPhone'))\n .sort((a, b) => {\n // Prefer Pro models\n const aIsPro = a.name.includes('Pro') ? 1 : 0;\n const bIsPro = b.name.includes('Pro') ? 1 : 0;\n if (aIsPro !== bIsPro) return bIsPro - aIsPro;\n\n // Then sort by name descending (iPhone 15 > iPhone 14)\n return b.name.localeCompare(a.name);\n });\n\n return iphones[0] ?? null;\n }\n\n /**\n * Find device by name or UDID (searches both simulators and real devices)\n */\n private async findDevice(nameOrUdid: string): Promise<IOSDeviceInfo | null> {\n const devices = await this.listAllDevices();\n\n // Try exact UDID match first\n const byUdid = devices.find((d) => d.udid === nameOrUdid);\n if (byUdid) return byUdid;\n\n // Try exact name match\n const byExactName = devices.find((d) => d.name === nameOrUdid);\n if (byExactName) return byExactName;\n\n // Try partial name match\n const byPartialName = devices.find((d) =>\n d.name.toLowerCase().includes(nameOrUdid.toLowerCase())\n );\n return byPartialName ?? null;\n }\n\n /**\n * Check if Appium is installed\n */\n private async checkAppiumInstalled(): Promise<boolean> {\n return new Promise((resolve) => {\n const proc = spawn('appium', ['--version'], { shell: true });\n proc.on('close', (code) => resolve(code === 0));\n proc.on('error', () => resolve(false));\n });\n }\n\n /**\n * Check if Appium server is already running\n */\n private async isAppiumRunning(): Promise<boolean> {\n try {\n const response = await fetch(\n `http://${IOSManager.APPIUM_HOST}:${IOSManager.APPIUM_PORT}/status`\n );\n return response.ok;\n } catch {\n return false;\n }\n }\n\n /**\n * Start Appium server if not already running\n */\n private async startAppiumServer(): Promise<void> {\n if (await this.isAppiumRunning()) {\n return; // Already running\n }\n\n if (!(await this.checkAppiumInstalled())) {\n throw new Error(\n 'Appium not installed. Run: npm install -g appium && appium driver install xcuitest'\n );\n }\n\n return new Promise((resolve, reject) => {\n this.appiumProcess = spawn(\n 'appium',\n ['--port', String(IOSManager.APPIUM_PORT), '--relaxed-security'],\n {\n shell: true,\n stdio: ['ignore', 'pipe', 'pipe'],\n }\n );\n\n let started = false;\n const timeout = setTimeout(() => {\n if (!started) {\n reject(new Error('Appium server failed to start within 30 seconds'));\n }\n }, 30000);\n\n this.appiumProcess.stdout?.on('data', (data: Buffer) => {\n const output = data.toString();\n if (output.includes('Appium REST http interface listener started')) {\n started = true;\n clearTimeout(timeout);\n resolve();\n }\n });\n\n this.appiumProcess.stderr?.on('data', (data: Buffer) => {\n const output = data.toString();\n // Appium logs to stderr for info messages too\n if (output.includes('Appium REST http interface listener started')) {\n started = true;\n clearTimeout(timeout);\n resolve();\n }\n });\n\n this.appiumProcess.on('error', (err) => {\n clearTimeout(timeout);\n reject(new Error(`Failed to start Appium: ${err.message}`));\n });\n\n this.appiumProcess.on('close', (code) => {\n if (!started) {\n clearTimeout(timeout);\n reject(new Error(`Appium exited with code ${code}`));\n }\n });\n });\n }\n\n /**\n * Boot the iOS simulator\n */\n private async bootSimulator(udid: string): Promise<void> {\n try {\n const devices = await this.simctl.getDevices();\n let currentState: string | undefined;\n\n // Find current device state\n for (const deviceList of Object.values(devices)) {\n if (!Array.isArray(deviceList)) continue;\n const device = (deviceList as any[]).find((d: any) => d.udid === udid);\n if (device) {\n currentState = device.state;\n break;\n }\n }\n\n if (currentState === 'Booted') {\n return; // Already booted\n }\n\n // node-simctl expects udid to be set on the instance\n this.simctl.udid = udid;\n await this.simctl.bootDevice();\n\n // Wait for device to be fully booted\n let attempts = 0;\n while (attempts < 60) {\n const updatedDevices = await this.simctl.getDevices();\n for (const deviceList of Object.values(updatedDevices)) {\n if (!Array.isArray(deviceList)) continue;\n const device = (deviceList as any[]).find((d: any) => d.udid === udid);\n if (device?.state === 'Booted') {\n return;\n }\n }\n await new Promise((r) => setTimeout(r, 1000));\n attempts++;\n }\n\n throw new Error('Simulator failed to boot within 60 seconds');\n } catch (error) {\n throw new Error(\n `Failed to boot simulator: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n /**\n * Launch iOS Safari via Appium\n */\n async launch(\n options: {\n device?: string;\n udid?: string;\n headless?: boolean;\n } = {}\n ): Promise<void> {\n if (this.isLaunched()) {\n return; // Already launched\n }\n\n // Find device\n let device: IOSDeviceInfo | null = null;\n\n if (options.udid) {\n device = await this.findDevice(options.udid);\n if (!device) {\n throw new Error(`Device with UDID ${options.udid} not found`);\n }\n } else if (options.device) {\n device = await this.findDevice(options.device);\n if (!device) {\n throw new Error(`Device \"${options.device}\" not found. Run: agent-browser device list`);\n }\n } else {\n // Check environment variable\n const envDevice = process.env.AGENT_BROWSER_IOS_DEVICE;\n const envUdid = process.env.AGENT_BROWSER_IOS_UDID;\n\n if (envUdid) {\n device = await this.findDevice(envUdid);\n if (!device) {\n throw new Error(`Device with UDID ${envUdid} not found. Run: agent-browser device list`);\n }\n } else if (envDevice) {\n device = await this.findDevice(envDevice);\n if (!device) {\n throw new Error(`Device \"${envDevice}\" not found. Run: agent-browser device list`);\n }\n } else {\n device = await this.findDefaultDevice();\n if (!device) {\n throw new Error(\n 'No iOS simulators available. Open Xcode and download simulator runtimes.'\n );\n }\n }\n }\n\n this.deviceUdid = device.udid;\n this.deviceName = device.name;\n\n // Start Appium server\n await this.startAppiumServer();\n\n // Boot simulator (skip for real devices - they're already running)\n if (!device.isRealDevice) {\n await this.bootSimulator(device.udid);\n }\n\n // Connect to Safari via Appium\n try {\n this.browser = await remote({\n hostname: IOSManager.APPIUM_HOST,\n port: IOSManager.APPIUM_PORT,\n path: '/',\n capabilities: {\n platformName: 'iOS',\n 'appium:automationName': 'XCUITest',\n 'appium:deviceName': device.name,\n 'appium:udid': device.udid,\n browserName: 'Safari',\n 'appium:noReset': true,\n 'appium:newCommandTimeout': 300,\n },\n connectionRetryTimeout: 120000,\n connectionRetryCount: 3,\n });\n } catch (error) {\n throw new Error(\n `Failed to connect to Safari: ${error instanceof Error ? error.message : String(error)}. ` +\n 'Make sure XCUITest driver is installed: appium driver install xcuitest'\n );\n }\n }\n\n /**\n * Navigate to URL\n */\n async navigate(url: string): Promise<{ url: string; title: string }> {\n if (!this.browser) {\n throw new Error('iOS browser not launched. Call launch first.');\n }\n\n await this.browser.url(url);\n\n // Wait for page to load\n await this.browser.waitUntil(\n async () => {\n const state = (await this.browser!.execute(\n 'return document.readyState'\n )) as unknown as string;\n return state === 'complete';\n },\n { timeout: 30000, interval: 500 }\n );\n\n const title = await this.browser.getTitle();\n const currentUrl = await this.browser.getUrl();\n\n return { url: currentUrl, title };\n }\n\n /**\n * Get current URL\n */\n async getUrl(): Promise<string> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n return this.browser.getUrl();\n }\n\n /**\n * Get page title\n */\n async getTitle(): Promise<string> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n return this.browser.getTitle();\n }\n\n /**\n * Click/tap an element\n */\n async click(selector: string): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const element = await this.getElement(selector);\n await element.click();\n }\n\n /**\n * Alias for click (semantic clarity for touch)\n */\n async tap(selector: string): Promise<void> {\n return this.click(selector);\n }\n\n /**\n * Type text into an element\n */\n async type(\n selector: string,\n text: string,\n options?: { delay?: number; clear?: boolean }\n ): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const element = await this.getElement(selector);\n\n if (options?.clear) {\n await element.clearValue();\n }\n\n // WebdriverIO doesn't have a delay option, so we simulate it\n if (options?.delay && options.delay > 0) {\n for (const char of text) {\n await element.addValue(char);\n await new Promise((r) => setTimeout(r, options.delay));\n }\n } else {\n await element.addValue(text);\n }\n }\n\n /**\n * Fill an element (clear first, then type)\n */\n async fill(selector: string, value: string): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const element = await this.getElement(selector);\n await element.clearValue();\n await element.setValue(value);\n }\n\n /**\n * Get element by selector or ref\n */\n private async getElement(selectorOrRef: string) {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n // Check if it's a ref\n const refData = this.getRefData(selectorOrRef);\n if (refData) {\n if (refData.xpath) {\n return this.browser.$(refData.xpath);\n }\n return this.browser.$(refData.selector);\n }\n\n // Regular CSS selector\n return this.browser.$(selectorOrRef);\n }\n\n /**\n * Get ref data from ref string\n */\n private getRefData(refArg: string): IOSRefMap[string] | null {\n let ref: string | null = null;\n\n if (refArg.startsWith('@')) {\n ref = refArg.slice(1);\n } else if (refArg.startsWith('ref=')) {\n ref = refArg.slice(4);\n } else if (/^e\\d+$/.test(refArg)) {\n ref = refArg;\n }\n\n if (ref && this.refMap[ref]) {\n return this.refMap[ref];\n }\n\n return null;\n }\n\n /**\n * Take a screenshot\n */\n async screenshot(options?: {\n path?: string;\n fullPage?: boolean;\n }): Promise<{ path?: string; base64?: string }> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const base64 = await this.browser.takeScreenshot();\n\n if (options?.path) {\n const { writeFileSync, mkdirSync } = await import('node:fs');\n const dir = path.dirname(options.path);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(options.path, base64, 'base64');\n return { path: options.path };\n }\n\n return { base64 };\n }\n\n /**\n * Get page snapshot with refs\n */\n async getSnapshot(options?: { interactive?: boolean }): Promise<IOSEnhancedSnapshot> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n this.refCounter = 0;\n this.refMap = {};\n\n // Get page structure via JavaScript execution\n // Note: The function runs in browser context, so we use 'any' for DOM types\n const snapshot = await this.browser.execute(function (interactiveOnly: boolean): any {\n const INTERACTIVE_ROLES = new Set([\n 'button',\n 'link',\n 'textbox',\n 'checkbox',\n 'radio',\n 'combobox',\n 'listbox',\n 'menuitem',\n 'option',\n 'searchbox',\n 'slider',\n 'spinbutton',\n 'switch',\n 'tab',\n 'treeitem',\n ]);\n\n const INTERACTIVE_TAGS = new Set([\n 'A',\n 'BUTTON',\n 'INPUT',\n 'SELECT',\n 'TEXTAREA',\n 'DETAILS',\n 'SUMMARY',\n ]);\n\n function getXPath(element: any): string {\n if (element.id) {\n return `//*[@id=\"${element.id}\"]`;\n }\n\n const parts: string[] = [];\n let current: any = element;\n\n while (current && current.nodeType === 1) {\n // Node.ELEMENT_NODE = 1\n let index = 1;\n let sibling: any = current.previousElementSibling;\n\n while (sibling) {\n if (sibling.nodeName === current.nodeName) {\n index++;\n }\n sibling = sibling.previousElementSibling;\n }\n\n const tagName = current.nodeName.toLowerCase();\n parts.unshift(`${tagName}[${index}]`);\n current = current.parentElement;\n }\n\n return '/' + parts.join('/');\n }\n\n function getAccessibleName(element: any): string {\n // aria-label takes precedence\n const ariaLabel = element.getAttribute('aria-label');\n if (ariaLabel) return ariaLabel;\n\n // For inputs, check placeholder and label\n const tagName = element.tagName;\n if (tagName === 'INPUT' || tagName === 'TEXTAREA') {\n const id = element.id;\n if (id) {\n const label = (document as any).querySelector(`label[for=\"${id}\"]`);\n if (label) return label.textContent?.trim() || '';\n }\n if (element.placeholder) return element.placeholder;\n }\n\n // For buttons and links, use text content\n if (tagName === 'BUTTON' || tagName === 'A') {\n return element.textContent?.trim() || '';\n }\n\n // aria-labelledby\n const labelledBy = element.getAttribute('aria-labelledby');\n if (labelledBy) {\n const labelElement = (document as any).getElementById(labelledBy);\n if (labelElement) return labelElement.textContent?.trim() || '';\n }\n\n return element.textContent?.trim().slice(0, 50) || '';\n }\n\n function getRole(element: any): string | null {\n // Explicit role\n const role = element.getAttribute('role');\n if (role) return role;\n\n // Implicit roles\n const tag = element.tagName;\n if (tag === 'A' && element.hasAttribute('href')) return 'link';\n if (tag === 'BUTTON') return 'button';\n if (tag === 'INPUT') {\n const type = element.type;\n if (type === 'checkbox') return 'checkbox';\n if (type === 'radio') return 'radio';\n if (type === 'text' || type === 'email' || type === 'password' || type === 'search')\n return 'textbox';\n if (type === 'submit' || type === 'button') return 'button';\n }\n if (tag === 'TEXTAREA') return 'textbox';\n if (tag === 'SELECT') return 'combobox';\n if (\n tag === 'H1' ||\n tag === 'H2' ||\n tag === 'H3' ||\n tag === 'H4' ||\n tag === 'H5' ||\n tag === 'H6'\n )\n return 'heading';\n if (tag === 'IMG') return 'img';\n if (tag === 'NAV') return 'navigation';\n if (tag === 'MAIN') return 'main';\n if (tag === 'HEADER') return 'banner';\n if (tag === 'FOOTER') return 'contentinfo';\n\n return null;\n }\n\n function traverse(element: any, depth: number): any {\n if (depth > 10) return null; // Limit depth\n\n const tag = element.tagName;\n const role = getRole(element);\n const name = getAccessibleName(element);\n const isInteractive =\n INTERACTIVE_TAGS.has(tag) || (role !== null && INTERACTIVE_ROLES.has(role));\n\n // Skip hidden elements\n const style = (window as any).getComputedStyle(element);\n if (style.display === 'none' || style.visibility === 'hidden') {\n return null;\n }\n\n const children: any[] = [];\n for (const child of element.children) {\n const childInfo = traverse(child, depth + 1);\n if (childInfo) {\n children.push(childInfo);\n }\n }\n\n // In interactive mode, skip non-interactive elements without interactive children\n if (interactiveOnly && !isInteractive && children.length === 0) {\n return null;\n }\n\n return {\n tag,\n role,\n name,\n text: element.textContent?.trim().slice(0, 100) || '',\n isInteractive,\n xpath: getXPath(element),\n children,\n };\n }\n\n const root = traverse((document as any).body, 0);\n return root;\n }, options?.interactive ?? false);\n\n // Build tree string and refs\n const lines: string[] = [];\n const buildTree = (node: any, indent: number) => {\n if (!node) return;\n\n const prefix = ' '.repeat(indent) + '- ';\n const role = node.role || node.tag.toLowerCase();\n const name = node.name;\n\n let line = `${prefix}${role}`;\n if (name) {\n line += ` \"${name}\"`;\n }\n\n // Add ref for interactive elements\n if (node.isInteractive) {\n const ref = `e${++this.refCounter}`;\n line += ` [ref=${ref}]`;\n\n this.refMap[ref] = {\n selector: node.xpath.startsWith('/') ? node.xpath : `#${node.xpath}`,\n role: node.role,\n name: node.name,\n xpath: node.xpath,\n };\n }\n\n lines.push(line);\n\n for (const child of node.children || []) {\n buildTree(child, indent + 1);\n }\n };\n\n if (snapshot) {\n buildTree(snapshot, 0);\n }\n\n const tree = lines.join('\\n') || '(empty)';\n this.lastSnapshot = tree;\n\n return { tree, refs: this.refMap };\n }\n\n /**\n * Get cached ref map\n */\n getRefMap(): IOSRefMap {\n return this.refMap;\n }\n\n /**\n * Scroll the page\n */\n async scroll(options?: {\n selector?: string;\n x?: number;\n y?: number;\n direction?: 'up' | 'down' | 'left' | 'right';\n amount?: number;\n }): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const amount = options?.amount ?? 300;\n\n if (options?.selector) {\n const element = await this.getElement(options.selector);\n await element.scrollIntoView();\n return;\n }\n\n // Use JavaScript scrolling\n let deltaX = options?.x ?? 0;\n let deltaY = options?.y ?? 0;\n\n if (options?.direction) {\n switch (options.direction) {\n case 'up':\n deltaY = -amount;\n break;\n case 'down':\n deltaY = amount;\n break;\n case 'left':\n deltaX = -amount;\n break;\n case 'right':\n deltaX = amount;\n break;\n }\n }\n\n await this.browser.execute(\n function (x: number, y: number) {\n (window as any).scrollBy(x, y);\n },\n deltaX,\n deltaY\n );\n }\n\n /**\n * Swipe gesture (iOS-specific)\n */\n async swipe(\n direction: 'up' | 'down' | 'left' | 'right',\n options?: { distance?: number }\n ): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const distance = options?.distance ?? 300;\n\n // Map direction to scroll (opposite direction)\n const scrollDirection = {\n up: 'down',\n down: 'up',\n left: 'right',\n right: 'left',\n }[direction] as 'up' | 'down' | 'left' | 'right';\n\n await this.scroll({ direction: scrollDirection, amount: distance });\n }\n\n /**\n * Execute JavaScript\n */\n async evaluate<T = unknown>(script: string, ...args: unknown[]): Promise<T> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n // Execute the script directly - WebdriverIO handles the context\n const result = await this.browser.execute(\n function (code: string, evalArgs: any[]) {\n // Create a function from the code and execute it\n const fn = new Function(...evalArgs.map((_: any, i: number) => `arg${i}`), code);\n return fn(...evalArgs);\n },\n script.includes('return') ? script : `return (${script})`,\n args\n );\n\n return result as T;\n }\n\n /**\n * Wait for element\n */\n async wait(options: {\n selector?: string;\n timeout?: number;\n state?: 'attached' | 'detached' | 'visible' | 'hidden';\n }): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const timeout = options.timeout ?? 30000;\n\n if (options.selector) {\n const element = await this.getElement(options.selector);\n\n switch (options.state) {\n case 'detached':\n await element.waitForExist({ timeout, reverse: true });\n break;\n case 'hidden':\n await element.waitForDisplayed({ timeout, reverse: true });\n break;\n case 'visible':\n await element.waitForDisplayed({ timeout });\n break;\n case 'attached':\n default:\n await element.waitForExist({ timeout });\n break;\n }\n } else {\n // Just wait for timeout\n await new Promise((r) => setTimeout(r, timeout));\n }\n }\n\n /**\n * Press a key\n */\n async press(key: string): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n // Map common key names\n const keyMap: Record<string, string> = {\n Enter: '\\uE007',\n Tab: '\\uE004',\n Escape: '\\uE00C',\n Backspace: '\\uE003',\n Delete: '\\uE017',\n ArrowUp: '\\uE013',\n ArrowDown: '\\uE015',\n ArrowLeft: '\\uE012',\n ArrowRight: '\\uE014',\n };\n\n const mappedKey = keyMap[key] ?? key;\n await this.browser.keys(mappedKey);\n }\n\n /**\n * Hover over element (limited on touch - just scrolls into view)\n */\n async hover(selector: string): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const element = await this.getElement(selector);\n await element.scrollIntoView();\n }\n\n /**\n * Get page content (HTML)\n */\n async getContent(selector?: string): Promise<string> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n if (selector) {\n const element = await this.getElement(selector);\n return element.getHTML();\n }\n\n return this.browser.getPageSource();\n }\n\n /**\n * Get text content of element\n */\n async getText(selector: string): Promise<string> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const element = await this.getElement(selector);\n return element.getText();\n }\n\n /**\n * Get attribute value\n */\n async getAttribute(selector: string, attribute: string): Promise<string | null> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const element = await this.getElement(selector);\n return element.getAttribute(attribute);\n }\n\n /**\n * Check if element is visible\n */\n async isVisible(selector: string): Promise<boolean> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n try {\n const element = await this.getElement(selector);\n return element.isDisplayed();\n } catch {\n return false;\n }\n }\n\n /**\n * Check if element is enabled\n */\n async isEnabled(selector: string): Promise<boolean> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const element = await this.getElement(selector);\n return element.isEnabled();\n }\n\n /**\n * Navigate back\n */\n async goBack(): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n await this.browser.back();\n }\n\n /**\n * Navigate forward\n */\n async goForward(): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n await this.browser.forward();\n }\n\n /**\n * Reload page\n */\n async reload(): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n await this.browser.refresh();\n }\n\n /**\n * Select option(s) from dropdown\n */\n async select(selector: string, values: string | string[]): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const element = await this.getElement(selector);\n const valueArray = Array.isArray(values) ? values : [values];\n\n for (const value of valueArray) {\n await element.selectByAttribute('value', value);\n }\n }\n\n /**\n * Check a checkbox\n */\n async check(selector: string): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const element = await this.getElement(selector);\n const isChecked = await element.isSelected();\n if (!isChecked) {\n await element.click();\n }\n }\n\n /**\n * Uncheck a checkbox\n */\n async uncheck(selector: string): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const element = await this.getElement(selector);\n const isChecked = await element.isSelected();\n if (isChecked) {\n await element.click();\n }\n }\n\n /**\n * Focus an element\n */\n async focus(selector: string): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const element = await this.getElement(selector);\n await this.browser.execute(function (el: any) {\n el.focus();\n }, element as any);\n }\n\n /**\n * Clear input field\n */\n async clear(selector: string): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const element = await this.getElement(selector);\n await element.clearValue();\n }\n\n /**\n * Get element count\n */\n async count(selector: string): Promise<number> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const elements = await this.browser.$$(selector);\n return elements.length;\n }\n\n /**\n * Get bounding box\n */\n async getBoundingBox(\n selector: string\n ): Promise<{ x: number; y: number; width: number; height: number } | null> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n try {\n const element = await this.getElement(selector);\n const location = await element.getLocation();\n const size = await element.getSize();\n return {\n x: location.x,\n y: location.y,\n width: size.width,\n height: size.height,\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Get device info\n */\n getDeviceInfo(): { name: string; udid: string } | null {\n if (!this.deviceName || !this.deviceUdid) {\n return null;\n }\n return {\n name: this.deviceName,\n udid: this.deviceUdid,\n };\n }\n\n /**\n * Close browser and cleanup\n */\n async close(): Promise<void> {\n if (this.browser) {\n try {\n await this.browser.deleteSession();\n } catch {\n // Ignore cleanup errors\n }\n this.browser = null;\n }\n\n if (this.appiumProcess) {\n this.appiumProcess.kill();\n this.appiumProcess = null;\n }\n\n // Optionally shutdown simulator\n if (this.deviceUdid) {\n try {\n this.simctl.udid = this.deviceUdid;\n await this.simctl.shutdownDevice();\n } catch {\n // Ignore - simulator might already be shutdown\n }\n }\n\n this.deviceUdid = null;\n this.deviceName = null;\n this.refMap = {};\n this.lastSnapshot = '';\n this.refCounter = 0;\n }\n}\n","import { z } from 'zod';\nimport type { Command, Response } from './types.js';\n\n// Base schema for all commands\nconst baseCommandSchema = z.object({\n id: z.string(),\n action: z.string(),\n});\n\n// Individual action schemas\nconst launchSchema = baseCommandSchema.extend({\n action: z.literal('launch'),\n headless: z.boolean().optional(),\n viewport: z\n .object({\n width: z.number().positive(),\n height: z.number().positive(),\n })\n .optional(),\n browser: z.enum(['chromium', 'firefox', 'webkit']).optional(),\n cdpPort: z.number().positive().optional(),\n cdpUrl: z\n .string()\n .url()\n .refine(\n (url) =>\n url.startsWith('ws://') ||\n url.startsWith('wss://') ||\n url.startsWith('http://') ||\n url.startsWith('https://'),\n { message: 'CDP URL must start with ws://, wss://, http://, or https://' }\n )\n .optional(),\n executablePath: z.string().optional(),\n extensions: z.array(z.string()).optional(),\n headers: z.record(z.string()).optional(),\n proxy: z\n .object({\n server: z.string().min(1),\n bypass: z.string().optional(),\n username: z.string().optional(),\n password: z.string().optional(),\n })\n .optional(),\n args: z.array(z.string()).optional(),\n userAgent: z.string().optional(),\n provider: z.string().optional(),\n ignoreHTTPSErrors: z.boolean().optional(),\n profile: z.string().optional(),\n storageState: z.string().optional(),\n});\n\nconst navigateSchema = baseCommandSchema.extend({\n action: z.literal('navigate'),\n url: z.string().min(1),\n waitUntil: z.enum(['load', 'domcontentloaded', 'networkidle']).optional(),\n headers: z.record(z.string()).optional(),\n});\n\nconst clickSchema = baseCommandSchema.extend({\n action: z.literal('click'),\n selector: z.string().min(1),\n button: z.enum(['left', 'right', 'middle']).optional(),\n clickCount: z.number().positive().optional(),\n delay: z.number().nonnegative().optional(),\n});\n\nconst typeSchema = baseCommandSchema.extend({\n action: z.literal('type'),\n selector: z.string().min(1),\n text: z.string(),\n delay: z.number().nonnegative().optional(),\n clear: z.boolean().optional(),\n});\n\nconst fillSchema = baseCommandSchema.extend({\n action: z.literal('fill'),\n selector: z.string().min(1),\n value: z.string(),\n});\n\nconst checkSchema = baseCommandSchema.extend({\n action: z.literal('check'),\n selector: z.string().min(1),\n});\n\nconst uncheckSchema = baseCommandSchema.extend({\n action: z.literal('uncheck'),\n selector: z.string().min(1),\n});\n\nconst uploadSchema = baseCommandSchema.extend({\n action: z.literal('upload'),\n selector: z.string().min(1),\n files: z.union([z.string(), z.array(z.string())]),\n});\n\nconst dblclickSchema = baseCommandSchema.extend({\n action: z.literal('dblclick'),\n selector: z.string().min(1),\n});\n\nconst focusSchema = baseCommandSchema.extend({\n action: z.literal('focus'),\n selector: z.string().min(1),\n});\n\nconst dragSchema = baseCommandSchema.extend({\n action: z.literal('drag'),\n source: z.string().min(1),\n target: z.string().min(1),\n});\n\nconst frameSchema = baseCommandSchema.extend({\n action: z.literal('frame'),\n selector: z.string().min(1).optional(),\n name: z.string().optional(),\n url: z.string().optional(),\n});\n\nconst mainframeSchema = baseCommandSchema.extend({\n action: z.literal('mainframe'),\n});\n\nconst getByRoleSchema = baseCommandSchema.extend({\n action: z.literal('getbyrole'),\n role: z.string().min(1),\n name: z.string().optional(),\n exact: z.boolean().optional(),\n subaction: z.enum(['click', 'fill', 'check', 'hover']),\n value: z.string().optional(),\n});\n\nconst getByTextSchema = baseCommandSchema.extend({\n action: z.literal('getbytext'),\n text: z.string().min(1),\n exact: z.boolean().optional(),\n subaction: z.enum(['click', 'hover']),\n});\n\nconst getByLabelSchema = baseCommandSchema.extend({\n action: z.literal('getbylabel'),\n label: z.string().min(1),\n exact: z.boolean().optional(),\n subaction: z.enum(['click', 'fill', 'check']),\n value: z.string().optional(),\n});\n\nconst getByPlaceholderSchema = baseCommandSchema.extend({\n action: z.literal('getbyplaceholder'),\n placeholder: z.string().min(1),\n exact: z.boolean().optional(),\n subaction: z.enum(['click', 'fill']),\n value: z.string().optional(),\n});\n\nconst cookiesGetSchema = baseCommandSchema.extend({\n action: z.literal('cookies_get'),\n urls: z.array(z.string()).optional(),\n});\n\nconst cookiesSetSchema = baseCommandSchema.extend({\n action: z.literal('cookies_set'),\n cookies: z.array(\n z.object({\n name: z.string(),\n value: z.string(),\n url: z.string().optional(),\n domain: z.string().optional(),\n path: z.string().optional(),\n expires: z.number().optional(),\n httpOnly: z.boolean().optional(),\n secure: z.boolean().optional(),\n sameSite: z.enum(['Strict', 'Lax', 'None']).optional(),\n })\n ),\n});\n\nconst cookiesClearSchema = baseCommandSchema.extend({\n action: z.literal('cookies_clear'),\n});\n\nconst storageGetSchema = baseCommandSchema.extend({\n action: z.literal('storage_get'),\n key: z.string().optional(),\n type: z.enum(['local', 'session']),\n});\n\nconst storageSetSchema = baseCommandSchema.extend({\n action: z.literal('storage_set'),\n key: z.string().min(1),\n value: z.string(),\n type: z.enum(['local', 'session']),\n});\n\nconst storageClearSchema = baseCommandSchema.extend({\n action: z.literal('storage_clear'),\n type: z.enum(['local', 'session']),\n});\n\nconst dialogSchema = baseCommandSchema.extend({\n action: z.literal('dialog'),\n response: z.enum(['accept', 'dismiss']),\n promptText: z.string().optional(),\n});\n\nconst pdfSchema = baseCommandSchema.extend({\n action: z.literal('pdf'),\n path: z.string().min(1),\n format: z\n .enum(['Letter', 'Legal', 'Tabloid', 'Ledger', 'A0', 'A1', 'A2', 'A3', 'A4', 'A5', 'A6'])\n .optional(),\n});\n\nconst routeSchema = baseCommandSchema.extend({\n action: z.literal('route'),\n url: z.string().min(1),\n response: z\n .object({\n status: z.number().optional(),\n body: z.string().optional(),\n contentType: z.string().optional(),\n headers: z.record(z.string()).optional(),\n })\n .optional(),\n abort: z.boolean().optional(),\n});\n\nconst unrouteSchema = baseCommandSchema.extend({\n action: z.literal('unroute'),\n url: z.string().optional(),\n});\n\nconst requestsSchema = baseCommandSchema.extend({\n action: z.literal('requests'),\n filter: z.string().optional(),\n clear: z.boolean().optional(),\n});\n\nconst downloadSchema = baseCommandSchema.extend({\n action: z.literal('download'),\n selector: z.string().min(1),\n path: z.string().min(1),\n});\n\nconst geolocationSchema = baseCommandSchema.extend({\n action: z.literal('geolocation'),\n latitude: z.number(),\n longitude: z.number(),\n accuracy: z.number().optional(),\n});\n\nconst permissionsSchema = baseCommandSchema.extend({\n action: z.literal('permissions'),\n permissions: z.array(z.string()),\n grant: z.boolean(),\n});\n\nconst viewportSchema = baseCommandSchema.extend({\n action: z.literal('viewport'),\n width: z.number().positive(),\n height: z.number().positive(),\n});\n\nconst userAgentSchema = baseCommandSchema.extend({\n action: z.literal('useragent'),\n userAgent: z.string().min(1),\n});\n\nconst deviceSchema = baseCommandSchema.extend({\n action: z.literal('device'),\n device: z.string().min(1),\n});\n\nconst backSchema = baseCommandSchema.extend({\n action: z.literal('back'),\n});\n\nconst forwardSchema = baseCommandSchema.extend({\n action: z.literal('forward'),\n});\n\nconst reloadSchema = baseCommandSchema.extend({\n action: z.literal('reload'),\n});\n\nconst urlSchema = baseCommandSchema.extend({\n action: z.literal('url'),\n});\n\nconst titleSchema = baseCommandSchema.extend({\n action: z.literal('title'),\n});\n\nconst getAttributeSchema = baseCommandSchema.extend({\n action: z.literal('getattribute'),\n selector: z.string().min(1),\n attribute: z.string().min(1),\n});\n\nconst getTextSchema = baseCommandSchema.extend({\n action: z.literal('gettext'),\n selector: z.string().min(1),\n});\n\nconst isVisibleSchema = baseCommandSchema.extend({\n action: z.literal('isvisible'),\n selector: z.string().min(1),\n});\n\nconst isEnabledSchema = baseCommandSchema.extend({\n action: z.literal('isenabled'),\n selector: z.string().min(1),\n});\n\nconst isCheckedSchema = baseCommandSchema.extend({\n action: z.literal('ischecked'),\n selector: z.string().min(1),\n});\n\nconst countSchema = baseCommandSchema.extend({\n action: z.literal('count'),\n selector: z.string().min(1),\n});\n\nconst boundingBoxSchema = baseCommandSchema.extend({\n action: z.literal('boundingbox'),\n selector: z.string().min(1),\n});\n\nconst stylesSchema = baseCommandSchema.extend({\n action: z.literal('styles'),\n selector: z.string().min(1),\n});\n\nconst videoStartSchema = baseCommandSchema.extend({\n action: z.literal('video_start'),\n path: z.string().min(1),\n});\n\nconst videoStopSchema = baseCommandSchema.extend({\n action: z.literal('video_stop'),\n});\n\n// Recording schemas (Playwright native video recording)\nconst recordingStartSchema = baseCommandSchema.extend({\n action: z.literal('recording_start'),\n path: z.string().min(1),\n url: z.string().min(1).optional(),\n});\n\nconst recordingStopSchema = baseCommandSchema.extend({\n action: z.literal('recording_stop'),\n});\n\nconst recordingRestartSchema = baseCommandSchema.extend({\n action: z.literal('recording_restart'),\n path: z.string().min(1),\n url: z.string().min(1).optional(),\n});\n\nconst traceStartSchema = baseCommandSchema.extend({\n action: z.literal('trace_start'),\n screenshots: z.boolean().optional(),\n snapshots: z.boolean().optional(),\n});\n\nconst traceStopSchema = baseCommandSchema.extend({\n action: z.literal('trace_stop'),\n path: z.string().min(1),\n});\n\nconst harStartSchema = baseCommandSchema.extend({\n action: z.literal('har_start'),\n});\n\nconst harStopSchema = baseCommandSchema.extend({\n action: z.literal('har_stop'),\n path: z.string().min(1),\n});\n\nconst stateSaveSchema = baseCommandSchema.extend({\n action: z.literal('state_save'),\n path: z.string().min(1),\n});\n\nconst stateLoadSchema = baseCommandSchema.extend({\n action: z.literal('state_load'),\n path: z.string().min(1),\n});\n\nconst consoleSchema = baseCommandSchema.extend({\n action: z.literal('console'),\n clear: z.boolean().optional(),\n});\n\nconst errorsSchema = baseCommandSchema.extend({\n action: z.literal('errors'),\n clear: z.boolean().optional(),\n});\n\nconst keyboardSchema = baseCommandSchema.extend({\n action: z.literal('keyboard'),\n keys: z.string().min(1),\n});\n\nconst wheelSchema = baseCommandSchema.extend({\n action: z.literal('wheel'),\n deltaX: z.number().optional(),\n deltaY: z.number().optional(),\n selector: z.string().optional(),\n});\n\nconst tapSchema = baseCommandSchema.extend({\n action: z.literal('tap'),\n selector: z.string().min(1),\n});\n\nconst clipboardSchema = baseCommandSchema.extend({\n action: z.literal('clipboard'),\n operation: z.enum(['copy', 'paste', 'read']),\n text: z.string().optional(),\n});\n\nconst highlightSchema = baseCommandSchema.extend({\n action: z.literal('highlight'),\n selector: z.string().min(1),\n});\n\nconst clearSchema = baseCommandSchema.extend({\n action: z.literal('clear'),\n selector: z.string().min(1),\n});\n\nconst selectAllSchema = baseCommandSchema.extend({\n action: z.literal('selectall'),\n selector: z.string().min(1),\n});\n\nconst innerTextSchema = baseCommandSchema.extend({\n action: z.literal('innertext'),\n selector: z.string().min(1),\n});\n\nconst innerHtmlSchema = baseCommandSchema.extend({\n action: z.literal('innerhtml'),\n selector: z.string().min(1),\n});\n\nconst inputValueSchema = baseCommandSchema.extend({\n action: z.literal('inputvalue'),\n selector: z.string().min(1),\n});\n\nconst setValueSchema = baseCommandSchema.extend({\n action: z.literal('setvalue'),\n selector: z.string().min(1),\n value: z.string(),\n});\n\nconst dispatchSchema = baseCommandSchema.extend({\n action: z.literal('dispatch'),\n selector: z.string().min(1),\n event: z.string().min(1),\n eventInit: z.record(z.unknown()).optional(),\n});\n\nconst evalHandleSchema = baseCommandSchema.extend({\n action: z.literal('evalhandle'),\n script: z.string().min(1),\n});\n\nconst exposeSchema = baseCommandSchema.extend({\n action: z.literal('expose'),\n name: z.string().min(1),\n});\n\nconst addScriptSchema = baseCommandSchema.extend({\n action: z.literal('addscript'),\n content: z.string().optional(),\n url: z.string().optional(),\n});\n\nconst addStyleSchema = baseCommandSchema.extend({\n action: z.literal('addstyle'),\n content: z.string().optional(),\n url: z.string().optional(),\n});\n\nconst emulateMediaSchema = baseCommandSchema.extend({\n action: z.literal('emulatemedia'),\n media: z.enum(['screen', 'print']).nullable().optional(),\n colorScheme: z.enum(['light', 'dark', 'no-preference']).nullable().optional(),\n reducedMotion: z.enum(['reduce', 'no-preference']).nullable().optional(),\n forcedColors: z.enum(['active', 'none']).nullable().optional(),\n});\n\nconst offlineSchema = baseCommandSchema.extend({\n action: z.literal('offline'),\n offline: z.boolean(),\n});\n\nconst headersSchema = baseCommandSchema.extend({\n action: z.literal('headers'),\n headers: z.record(z.string()),\n});\n\nconst pauseSchema = baseCommandSchema.extend({\n action: z.literal('pause'),\n});\n\nconst getByAltTextSchema = baseCommandSchema.extend({\n action: z.literal('getbyalttext'),\n text: z.string().min(1),\n exact: z.boolean().optional(),\n subaction: z.enum(['click', 'hover']),\n});\n\nconst getByTitleSchema = baseCommandSchema.extend({\n action: z.literal('getbytitle'),\n text: z.string().min(1),\n exact: z.boolean().optional(),\n subaction: z.enum(['click', 'hover']),\n});\n\nconst getByTestIdSchema = baseCommandSchema.extend({\n action: z.literal('getbytestid'),\n testId: z.string().min(1),\n subaction: z.enum(['click', 'fill', 'check', 'hover']),\n value: z.string().optional(),\n});\n\nconst nthSchema = baseCommandSchema.extend({\n action: z.literal('nth'),\n selector: z.string().min(1),\n index: z.number(),\n subaction: z.enum(['click', 'fill', 'check', 'hover', 'text']),\n value: z.string().optional(),\n});\n\nconst waitForUrlSchema = baseCommandSchema.extend({\n action: z.literal('waitforurl'),\n url: z.string().min(1),\n timeout: z.number().positive().optional(),\n});\n\nconst waitForLoadStateSchema = baseCommandSchema.extend({\n action: z.literal('waitforloadstate'),\n state: z.enum(['load', 'domcontentloaded', 'networkidle']),\n timeout: z.number().positive().optional(),\n});\n\nconst setContentSchema = baseCommandSchema.extend({\n action: z.literal('setcontent'),\n html: z.string(),\n});\n\nconst timezoneSchema = baseCommandSchema.extend({\n action: z.literal('timezone'),\n timezone: z.string().min(1),\n});\n\nconst localeSchema = baseCommandSchema.extend({\n action: z.literal('locale'),\n locale: z.string().min(1),\n});\n\nconst credentialsSchema = baseCommandSchema.extend({\n action: z.literal('credentials'),\n username: z.string(),\n password: z.string(),\n});\n\nconst mouseMoveSchema = baseCommandSchema.extend({\n action: z.literal('mousemove'),\n x: z.number(),\n y: z.number(),\n});\n\nconst mouseDownSchema = baseCommandSchema.extend({\n action: z.literal('mousedown'),\n button: z.enum(['left', 'right', 'middle']).optional(),\n});\n\nconst mouseUpSchema = baseCommandSchema.extend({\n action: z.literal('mouseup'),\n button: z.enum(['left', 'right', 'middle']).optional(),\n});\n\nconst bringToFrontSchema = baseCommandSchema.extend({\n action: z.literal('bringtofront'),\n});\n\nconst waitForFunctionSchema = baseCommandSchema.extend({\n action: z.literal('waitforfunction'),\n expression: z.string().min(1),\n timeout: z.number().positive().optional(),\n});\n\nconst scrollIntoViewSchema = baseCommandSchema.extend({\n action: z.literal('scrollintoview'),\n selector: z.string().min(1),\n});\n\nconst addInitScriptSchema = baseCommandSchema.extend({\n action: z.literal('addinitscript'),\n script: z.string().min(1),\n});\n\nconst keyDownSchema = baseCommandSchema.extend({\n action: z.literal('keydown'),\n key: z.string().min(1),\n});\n\nconst keyUpSchema = baseCommandSchema.extend({\n action: z.literal('keyup'),\n key: z.string().min(1),\n});\n\nconst insertTextSchema = baseCommandSchema.extend({\n action: z.literal('inserttext'),\n text: z.string(),\n});\n\nconst multiSelectSchema = baseCommandSchema.extend({\n action: z.literal('multiselect'),\n selector: z.string().min(1),\n values: z.array(z.string()),\n});\n\nconst waitForDownloadSchema = baseCommandSchema.extend({\n action: z.literal('waitfordownload'),\n path: z.string().optional(),\n timeout: z.number().positive().optional(),\n});\n\nconst responseBodySchema = baseCommandSchema.extend({\n action: z.literal('responsebody'),\n url: z.string().min(1),\n timeout: z.number().positive().optional(),\n});\n\n// Screencast schemas for streaming browser viewport\nconst screencastStartSchema = baseCommandSchema.extend({\n action: z.literal('screencast_start'),\n format: z.enum(['jpeg', 'png']).optional(),\n quality: z.number().min(0).max(100).optional(),\n maxWidth: z.number().positive().optional(),\n maxHeight: z.number().positive().optional(),\n everyNthFrame: z.number().positive().optional(),\n});\n\nconst screencastStopSchema = baseCommandSchema.extend({\n action: z.literal('screencast_stop'),\n});\n\n// Input injection schemas for pair browsing\nconst inputMouseSchema = baseCommandSchema.extend({\n action: z.literal('input_mouse'),\n type: z.enum(['mousePressed', 'mouseReleased', 'mouseMoved', 'mouseWheel']),\n x: z.number(),\n y: z.number(),\n button: z.enum(['left', 'right', 'middle', 'none']).optional(),\n clickCount: z.number().positive().optional(),\n deltaX: z.number().optional(),\n deltaY: z.number().optional(),\n modifiers: z.number().optional(),\n});\n\nconst inputKeyboardSchema = baseCommandSchema.extend({\n action: z.literal('input_keyboard'),\n type: z.enum(['keyDown', 'keyUp', 'char']),\n key: z.string().optional(),\n code: z.string().optional(),\n text: z.string().optional(),\n modifiers: z.number().optional(),\n});\n\nconst inputTouchSchema = baseCommandSchema.extend({\n action: z.literal('input_touch'),\n type: z.enum(['touchStart', 'touchEnd', 'touchMove', 'touchCancel']),\n touchPoints: z.array(\n z.object({\n x: z.number(),\n y: z.number(),\n id: z.number().optional(),\n })\n ),\n modifiers: z.number().optional(),\n});\n\n// iOS-specific schemas\nconst swipeSchema = baseCommandSchema.extend({\n action: z.literal('swipe'),\n direction: z.enum(['up', 'down', 'left', 'right']),\n distance: z.number().positive().optional(),\n});\n\nconst deviceListSchema = baseCommandSchema.extend({\n action: z.literal('device_list'),\n});\n\nconst pressSchema = baseCommandSchema.extend({\n action: z.literal('press'),\n key: z.string().min(1),\n selector: z.string().min(1).optional(),\n});\n\nconst screenshotSchema = baseCommandSchema.extend({\n action: z.literal('screenshot'),\n path: z.string().nullable().optional(),\n fullPage: z.boolean().optional(),\n selector: z.string().min(1).nullish(),\n format: z.enum(['png', 'jpeg']).optional(),\n quality: z.number().min(0).max(100).optional(),\n});\n\nconst snapshotSchema = baseCommandSchema.extend({\n action: z.literal('snapshot'),\n interactive: z.boolean().optional(),\n maxDepth: z.number().nonnegative().optional(),\n compact: z.boolean().optional(),\n selector: z.string().optional(),\n});\n\nconst evaluateSchema = baseCommandSchema.extend({\n action: z.literal('evaluate'),\n script: z.string().min(1),\n args: z.array(z.unknown()).optional(),\n});\n\nconst waitSchema = baseCommandSchema.extend({\n action: z.literal('wait'),\n selector: z.string().min(1).optional(),\n timeout: z.number().positive().optional(),\n state: z.enum(['attached', 'detached', 'visible', 'hidden']).optional(),\n});\n\nconst scrollSchema = baseCommandSchema.extend({\n action: z.literal('scroll'),\n selector: z.string().min(1).optional(),\n x: z.number().optional(),\n y: z.number().optional(),\n direction: z.enum(['up', 'down', 'left', 'right']).optional(),\n amount: z.number().positive().optional(),\n});\n\nconst selectSchema = baseCommandSchema.extend({\n action: z.literal('select'),\n selector: z.string().min(1),\n values: z.union([z.string(), z.array(z.string())]),\n});\n\nconst hoverSchema = baseCommandSchema.extend({\n action: z.literal('hover'),\n selector: z.string().min(1),\n});\n\nconst contentSchema = baseCommandSchema.extend({\n action: z.literal('content'),\n selector: z.string().min(1).optional(),\n});\n\nconst closeSchema = baseCommandSchema.extend({\n action: z.literal('close'),\n});\n\n// Tab/Window schemas\nconst tabNewSchema = baseCommandSchema.extend({\n action: z.literal('tab_new'),\n url: z.string().min(1).optional(),\n});\n\nconst tabListSchema = baseCommandSchema.extend({\n action: z.literal('tab_list'),\n});\n\nconst tabSwitchSchema = baseCommandSchema.extend({\n action: z.literal('tab_switch'),\n index: z.number().nonnegative(),\n});\n\nconst tabCloseSchema = baseCommandSchema.extend({\n action: z.literal('tab_close'),\n index: z.number().nonnegative().optional(),\n});\n\nconst windowNewSchema = baseCommandSchema.extend({\n action: z.literal('window_new'),\n viewport: z\n .object({\n width: z.number().positive(),\n height: z.number().positive(),\n })\n .optional(),\n});\n\n// Union schema for all commands\nconst commandSchema = z.discriminatedUnion('action', [\n launchSchema,\n navigateSchema,\n clickSchema,\n typeSchema,\n fillSchema,\n checkSchema,\n uncheckSchema,\n uploadSchema,\n dblclickSchema,\n focusSchema,\n dragSchema,\n frameSchema,\n mainframeSchema,\n getByRoleSchema,\n getByTextSchema,\n getByLabelSchema,\n getByPlaceholderSchema,\n pressSchema,\n screenshotSchema,\n snapshotSchema,\n evaluateSchema,\n waitSchema,\n scrollSchema,\n selectSchema,\n hoverSchema,\n contentSchema,\n closeSchema,\n tabNewSchema,\n tabListSchema,\n tabSwitchSchema,\n tabCloseSchema,\n windowNewSchema,\n cookiesGetSchema,\n cookiesSetSchema,\n cookiesClearSchema,\n storageGetSchema,\n storageSetSchema,\n storageClearSchema,\n dialogSchema,\n pdfSchema,\n routeSchema,\n unrouteSchema,\n requestsSchema,\n downloadSchema,\n geolocationSchema,\n permissionsSchema,\n viewportSchema,\n userAgentSchema,\n deviceSchema,\n backSchema,\n forwardSchema,\n reloadSchema,\n urlSchema,\n titleSchema,\n getAttributeSchema,\n getTextSchema,\n isVisibleSchema,\n isEnabledSchema,\n isCheckedSchema,\n countSchema,\n boundingBoxSchema,\n stylesSchema,\n videoStartSchema,\n videoStopSchema,\n recordingStartSchema,\n recordingStopSchema,\n recordingRestartSchema,\n traceStartSchema,\n traceStopSchema,\n harStartSchema,\n harStopSchema,\n stateSaveSchema,\n stateLoadSchema,\n consoleSchema,\n errorsSchema,\n keyboardSchema,\n wheelSchema,\n tapSchema,\n clipboardSchema,\n highlightSchema,\n clearSchema,\n selectAllSchema,\n innerTextSchema,\n innerHtmlSchema,\n inputValueSchema,\n setValueSchema,\n dispatchSchema,\n evalHandleSchema,\n exposeSchema,\n addScriptSchema,\n addStyleSchema,\n emulateMediaSchema,\n offlineSchema,\n headersSchema,\n pauseSchema,\n getByAltTextSchema,\n getByTitleSchema,\n getByTestIdSchema,\n nthSchema,\n waitForUrlSchema,\n waitForLoadStateSchema,\n setContentSchema,\n timezoneSchema,\n localeSchema,\n credentialsSchema,\n mouseMoveSchema,\n mouseDownSchema,\n mouseUpSchema,\n bringToFrontSchema,\n waitForFunctionSchema,\n scrollIntoViewSchema,\n addInitScriptSchema,\n keyDownSchema,\n keyUpSchema,\n insertTextSchema,\n multiSelectSchema,\n waitForDownloadSchema,\n responseBodySchema,\n screencastStartSchema,\n screencastStopSchema,\n inputMouseSchema,\n inputKeyboardSchema,\n inputTouchSchema,\n swipeSchema,\n deviceListSchema,\n]);\n\n// Parse result type\nexport type ParseResult =\n | { success: true; command: Command }\n | { success: false; error: string; id?: string };\n\n/**\n * Parse a JSON string into a validated command\n */\nexport function parseCommand(input: string): ParseResult {\n // First, try to parse JSON\n let json: unknown;\n try {\n json = JSON.parse(input);\n } catch {\n return { success: false, error: 'Invalid JSON' };\n }\n\n // Extract id for error responses if possible\n const id =\n typeof json === 'object' && json !== null && 'id' in json\n ? String((json as { id: unknown }).id)\n : undefined;\n\n // Validate against schema\n const result = commandSchema.safeParse(json);\n\n if (!result.success) {\n const errors = result.error.errors.map((e) => `${e.path.join('.')}: ${e.message}`).join(', ');\n return { success: false, error: `Validation error: ${errors}`, id };\n }\n\n return { success: true, command: result.data as Command };\n}\n\n/**\n * Create a success response\n */\nexport function successResponse<T>(id: string, data: T): Response<T> {\n return { id, success: true, data };\n}\n\n/**\n * Create an error response\n */\nexport function errorResponse(id: string, error: string): Response {\n return { id, success: false, error };\n}\n\n/**\n * Serialize a response to JSON string\n */\nexport function serializeResponse(response: Response): string {\n return JSON.stringify(response);\n}\n","import type { Page, Frame } from 'playwright-core';\nimport { mkdirSync } from 'node:fs';\nimport path from 'node:path';\nimport type { BrowserManager, ScreencastFrame } from './browser.js';\nimport { getAppDir } from './daemon.js';\nimport type {\n Command,\n Response,\n NavigateCommand,\n ClickCommand,\n TypeCommand,\n FillCommand,\n CheckCommand,\n UncheckCommand,\n UploadCommand,\n DoubleClickCommand,\n FocusCommand,\n DragCommand,\n FrameCommand,\n GetByRoleCommand,\n GetByTextCommand,\n GetByLabelCommand,\n GetByPlaceholderCommand,\n PressCommand,\n ScreenshotCommand,\n EvaluateCommand,\n WaitCommand,\n ScrollCommand,\n SelectCommand,\n HoverCommand,\n ContentCommand,\n TabNewCommand,\n TabSwitchCommand,\n TabCloseCommand,\n WindowNewCommand,\n CookiesSetCommand,\n StorageGetCommand,\n StorageSetCommand,\n StorageClearCommand,\n DialogCommand,\n PdfCommand,\n RouteCommand,\n RequestsCommand,\n DownloadCommand,\n GeolocationCommand,\n PermissionsCommand,\n ViewportCommand,\n DeviceCommand,\n GetAttributeCommand,\n GetTextCommand,\n IsVisibleCommand,\n IsEnabledCommand,\n IsCheckedCommand,\n CountCommand,\n BoundingBoxCommand,\n StylesCommand,\n TraceStartCommand,\n TraceStopCommand,\n HarStopCommand,\n StorageStateSaveCommand,\n ConsoleCommand,\n ErrorsCommand,\n KeyboardCommand,\n WheelCommand,\n TapCommand,\n ClipboardCommand,\n HighlightCommand,\n ClearCommand,\n SelectAllCommand,\n InnerTextCommand,\n InnerHtmlCommand,\n InputValueCommand,\n SetValueCommand,\n DispatchEventCommand,\n AddScriptCommand,\n AddStyleCommand,\n EmulateMediaCommand,\n OfflineCommand,\n HeadersCommand,\n GetByAltTextCommand,\n GetByTitleCommand,\n GetByTestIdCommand,\n NthCommand,\n WaitForUrlCommand,\n WaitForLoadStateCommand,\n SetContentCommand,\n TimezoneCommand,\n LocaleCommand,\n HttpCredentialsCommand,\n MouseMoveCommand,\n MouseDownCommand,\n MouseUpCommand,\n WaitForFunctionCommand,\n ScrollIntoViewCommand,\n AddInitScriptCommand,\n KeyDownCommand,\n KeyUpCommand,\n InsertTextCommand,\n MultiSelectCommand,\n WaitForDownloadCommand,\n ResponseBodyCommand,\n ScreencastStartCommand,\n ScreencastStopCommand,\n InputMouseCommand,\n InputKeyboardCommand,\n InputTouchCommand,\n RecordingStartCommand,\n RecordingStopCommand,\n RecordingRestartCommand,\n NavigateData,\n ScreenshotData,\n EvaluateData,\n ContentData,\n TabListData,\n TabNewData,\n TabSwitchData,\n TabCloseData,\n ScreencastStartData,\n ScreencastStopData,\n RecordingStartData,\n RecordingStopData,\n RecordingRestartData,\n InputEventData,\n StylesData,\n} from './types.js';\nimport { successResponse, errorResponse } from './protocol.js';\n\n// Callback for screencast frames - will be set by the daemon when streaming is active\nlet screencastFrameCallback: ((frame: ScreencastFrame) => void) | null = null;\n\n/**\n * Set the callback for screencast frames\n * This is called by the daemon to set up frame streaming\n */\nexport function setScreencastFrameCallback(\n callback: ((frame: ScreencastFrame) => void) | null\n): void {\n screencastFrameCallback = callback;\n}\n\n// Snapshot response type\ninterface SnapshotData {\n snapshot: string;\n refs?: Record<string, { role: string; name?: string }>;\n}\n\n/**\n * Convert Playwright errors to AI-friendly messages\n * @internal Exported for testing\n */\nexport function toAIFriendlyError(error: unknown, selector: string): Error {\n const message = error instanceof Error ? error.message : String(error);\n\n // Handle strict mode violation (multiple elements match)\n if (message.includes('strict mode violation')) {\n // Extract count if available\n const countMatch = message.match(/resolved to (\\d+) elements/);\n const count = countMatch ? countMatch[1] : 'multiple';\n\n return new Error(\n `Selector \"${selector}\" matched ${count} elements. ` +\n `Run 'snapshot' to get updated refs, or use a more specific CSS selector.`\n );\n }\n\n // Handle element not interactable (must be checked BEFORE timeout case)\n // This includes cases where an overlay/modal blocks the element\n if (message.includes('intercepts pointer events')) {\n return new Error(\n `Element \"${selector}\" is blocked by another element (likely a modal or overlay). ` +\n `Try dismissing any modals/cookie banners first.`\n );\n }\n\n // Handle element not visible\n if (message.includes('not visible') && !message.includes('Timeout')) {\n return new Error(\n `Element \"${selector}\" is not visible. ` +\n `Try scrolling it into view or check if it's hidden.`\n );\n }\n\n // Handle general timeout (element exists but action couldn't complete)\n if (message.includes('Timeout') && message.includes('exceeded')) {\n return new Error(\n `Action on \"${selector}\" timed out. The element may be blocked, still loading, or not interactable. ` +\n `Run 'snapshot' to check the current page state.`\n );\n }\n\n // Handle element not found (timeout waiting for element)\n if (\n message.includes('waiting for') &&\n (message.includes('to be visible') || message.includes('Timeout'))\n ) {\n return new Error(\n `Element \"${selector}\" not found or not visible. ` +\n `Run 'snapshot' to see current page elements.`\n );\n }\n\n // Return original error for unknown cases\n return error instanceof Error ? error : new Error(message);\n}\n\n/**\n * Execute a command and return a response\n */\nexport async function executeCommand(command: Command, browser: BrowserManager): Promise<Response> {\n try {\n switch (command.action) {\n case 'launch':\n return await handleLaunch(command, browser);\n case 'navigate':\n return await handleNavigate(command, browser);\n case 'click':\n return await handleClick(command, browser);\n case 'type':\n return await handleType(command, browser);\n case 'fill':\n return await handleFill(command, browser);\n case 'check':\n return await handleCheck(command, browser);\n case 'uncheck':\n return await handleUncheck(command, browser);\n case 'upload':\n return await handleUpload(command, browser);\n case 'dblclick':\n return await handleDoubleClick(command, browser);\n case 'focus':\n return await handleFocus(command, browser);\n case 'drag':\n return await handleDrag(command, browser);\n case 'frame':\n return await handleFrame(command, browser);\n case 'mainframe':\n return await handleMainFrame(command, browser);\n case 'getbyrole':\n return await handleGetByRole(command, browser);\n case 'getbytext':\n return await handleGetByText(command, browser);\n case 'getbylabel':\n return await handleGetByLabel(command, browser);\n case 'getbyplaceholder':\n return await handleGetByPlaceholder(command, browser);\n case 'press':\n return await handlePress(command, browser);\n case 'screenshot':\n return await handleScreenshot(command, browser);\n case 'snapshot':\n return await handleSnapshot(command, browser);\n case 'evaluate':\n return await handleEvaluate(command, browser);\n case 'wait':\n return await handleWait(command, browser);\n case 'scroll':\n return await handleScroll(command, browser);\n case 'select':\n return await handleSelect(command, browser);\n case 'hover':\n return await handleHover(command, browser);\n case 'content':\n return await handleContent(command, browser);\n case 'close':\n return await handleClose(command, browser);\n case 'tab_new':\n return await handleTabNew(command, browser);\n case 'tab_list':\n return await handleTabList(command, browser);\n case 'tab_switch':\n return await handleTabSwitch(command, browser);\n case 'tab_close':\n return await handleTabClose(command, browser);\n case 'window_new':\n return await handleWindowNew(command, browser);\n case 'cookies_get':\n return await handleCookiesGet(command, browser);\n case 'cookies_set':\n return await handleCookiesSet(command, browser);\n case 'cookies_clear':\n return await handleCookiesClear(command, browser);\n case 'storage_get':\n return await handleStorageGet(command, browser);\n case 'storage_set':\n return await handleStorageSet(command, browser);\n case 'storage_clear':\n return await handleStorageClear(command, browser);\n case 'dialog':\n return await handleDialog(command, browser);\n case 'pdf':\n return await handlePdf(command, browser);\n case 'route':\n return await handleRoute(command, browser);\n case 'unroute':\n return await handleUnroute(command, browser);\n case 'requests':\n return await handleRequests(command, browser);\n case 'download':\n return await handleDownload(command, browser);\n case 'geolocation':\n return await handleGeolocation(command, browser);\n case 'permissions':\n return await handlePermissions(command, browser);\n case 'viewport':\n return await handleViewport(command, browser);\n case 'useragent':\n return await handleUserAgent(command, browser);\n case 'device':\n return await handleDevice(command, browser);\n case 'back':\n return await handleBack(command, browser);\n case 'forward':\n return await handleForward(command, browser);\n case 'reload':\n return await handleReload(command, browser);\n case 'url':\n return await handleUrl(command, browser);\n case 'title':\n return await handleTitle(command, browser);\n case 'getattribute':\n return await handleGetAttribute(command, browser);\n case 'gettext':\n return await handleGetText(command, browser);\n case 'isvisible':\n return await handleIsVisible(command, browser);\n case 'isenabled':\n return await handleIsEnabled(command, browser);\n case 'ischecked':\n return await handleIsChecked(command, browser);\n case 'count':\n return await handleCount(command, browser);\n case 'boundingbox':\n return await handleBoundingBox(command, browser);\n case 'styles':\n return await handleStyles(command, browser);\n case 'video_start':\n return await handleVideoStart(command, browser);\n case 'video_stop':\n return await handleVideoStop(command, browser);\n case 'trace_start':\n return await handleTraceStart(command, browser);\n case 'trace_stop':\n return await handleTraceStop(command, browser);\n case 'har_start':\n return await handleHarStart(command, browser);\n case 'har_stop':\n return await handleHarStop(command, browser);\n case 'state_save':\n return await handleStateSave(command, browser);\n case 'state_load':\n return await handleStateLoad(command, browser);\n case 'console':\n return await handleConsole(command, browser);\n case 'errors':\n return await handleErrors(command, browser);\n case 'keyboard':\n return await handleKeyboard(command, browser);\n case 'wheel':\n return await handleWheel(command, browser);\n case 'tap':\n return await handleTap(command, browser);\n case 'clipboard':\n return await handleClipboard(command, browser);\n case 'highlight':\n return await handleHighlight(command, browser);\n case 'clear':\n return await handleClear(command, browser);\n case 'selectall':\n return await handleSelectAll(command, browser);\n case 'innertext':\n return await handleInnerText(command, browser);\n case 'innerhtml':\n return await handleInnerHtml(command, browser);\n case 'inputvalue':\n return await handleInputValue(command, browser);\n case 'setvalue':\n return await handleSetValue(command, browser);\n case 'dispatch':\n return await handleDispatch(command, browser);\n case 'evalhandle':\n return await handleEvalHandle(command, browser);\n case 'expose':\n return await handleExpose(command, browser);\n case 'addscript':\n return await handleAddScript(command, browser);\n case 'addstyle':\n return await handleAddStyle(command, browser);\n case 'emulatemedia':\n return await handleEmulateMedia(command, browser);\n case 'offline':\n return await handleOffline(command, browser);\n case 'headers':\n return await handleHeaders(command, browser);\n case 'pause':\n return await handlePause(command, browser);\n case 'getbyalttext':\n return await handleGetByAltText(command, browser);\n case 'getbytitle':\n return await handleGetByTitle(command, browser);\n case 'getbytestid':\n return await handleGetByTestId(command, browser);\n case 'nth':\n return await handleNth(command, browser);\n case 'waitforurl':\n return await handleWaitForUrl(command, browser);\n case 'waitforloadstate':\n return await handleWaitForLoadState(command, browser);\n case 'setcontent':\n return await handleSetContent(command, browser);\n case 'timezone':\n return await handleTimezone(command, browser);\n case 'locale':\n return await handleLocale(command, browser);\n case 'credentials':\n return await handleCredentials(command, browser);\n case 'mousemove':\n return await handleMouseMove(command, browser);\n case 'mousedown':\n return await handleMouseDown(command, browser);\n case 'mouseup':\n return await handleMouseUp(command, browser);\n case 'bringtofront':\n return await handleBringToFront(command, browser);\n case 'waitforfunction':\n return await handleWaitForFunction(command, browser);\n case 'scrollintoview':\n return await handleScrollIntoView(command, browser);\n case 'addinitscript':\n return await handleAddInitScript(command, browser);\n case 'keydown':\n return await handleKeyDown(command, browser);\n case 'keyup':\n return await handleKeyUp(command, browser);\n case 'inserttext':\n return await handleInsertText(command, browser);\n case 'multiselect':\n return await handleMultiSelect(command, browser);\n case 'waitfordownload':\n return await handleWaitForDownload(command, browser);\n case 'responsebody':\n return await handleResponseBody(command, browser);\n case 'screencast_start':\n return await handleScreencastStart(command, browser);\n case 'screencast_stop':\n return await handleScreencastStop(command, browser);\n case 'input_mouse':\n return await handleInputMouse(command, browser);\n case 'input_keyboard':\n return await handleInputKeyboard(command, browser);\n case 'input_touch':\n return await handleInputTouch(command, browser);\n case 'recording_start':\n return await handleRecordingStart(command, browser);\n case 'recording_stop':\n return await handleRecordingStop(command, browser);\n case 'recording_restart':\n return await handleRecordingRestart(command, browser);\n default: {\n // TypeScript narrows to never here, but we handle it for safety\n const unknownCommand = command as { id: string; action: string };\n return errorResponse(unknownCommand.id, `Unknown action: ${unknownCommand.action}`);\n }\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return errorResponse(command.id, message);\n }\n}\n\nasync function handleLaunch(\n command: Command & { action: 'launch' },\n browser: BrowserManager\n): Promise<Response> {\n await browser.launch(command);\n return successResponse(command.id, { launched: true });\n}\n\nasync function handleNavigate(\n command: NavigateCommand,\n browser: BrowserManager\n): Promise<Response<NavigateData>> {\n const page = browser.getPage();\n\n // If headers are provided, set up scoped headers for this origin\n if (command.headers && Object.keys(command.headers).length > 0) {\n await browser.setScopedHeaders(command.url, command.headers);\n }\n\n await page.goto(command.url, {\n waitUntil: command.waitUntil ?? 'load',\n });\n\n return successResponse(command.id, {\n url: page.url(),\n title: await page.title(),\n });\n}\n\nasync function handleClick(command: ClickCommand, browser: BrowserManager): Promise<Response> {\n // 1. Check if this is a ref with coordinate bounds\n if (browser.isRef(command.selector)) {\n const refData = browser.getRefData(command.selector);\n if (refData && refData.bounds) {\n const b = refData.bounds;\n // Calculate center of the bounds\n const centerX = b.left + (b.right - b.left) / 2;\n const centerY = b.top + (b.bottom - b.top) / 2;\n\n // Inject raw mouse events via CDP\n await browser.injectMouseEvent({\n type: 'mousePressed',\n x: centerX,\n y: centerY,\n button: command.button || 'left',\n clickCount: command.clickCount || 1,\n });\n await browser.injectMouseEvent({\n type: 'mouseReleased',\n x: centerX,\n y: centerY,\n button: command.button || 'left',\n });\n\n return successResponse(command.id, { clicked: true, method: 'cdp_coordinates' });\n }\n }\n\n // 2. Fallback to standard Playwright locator click\n const locator = browser.getLocator(command.selector);\n\n try {\n await locator.click({\n button: command.button,\n clickCount: command.clickCount,\n delay: command.delay,\n });\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n\n return successResponse(command.id, { clicked: true, method: 'playwright_locator' });\n}\n\nasync function handleType(command: TypeCommand, browser: BrowserManager): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n\n try {\n if (command.clear) {\n await locator.fill('');\n }\n\n await locator.pressSequentially(command.text, {\n delay: command.delay,\n });\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n\n return successResponse(command.id, { typed: true });\n}\n\nasync function handlePress(command: PressCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n\n if (command.selector) {\n await page.press(command.selector, command.key);\n } else {\n await page.keyboard.press(command.key);\n }\n\n return successResponse(command.id, { pressed: true });\n}\n\nasync function handleScreenshot(\n command: ScreenshotCommand,\n browser: BrowserManager\n): Promise<Response<ScreenshotData>> {\n const page = browser.getPage();\n\n const options: Parameters<Page['screenshot']>[0] = {\n fullPage: command.fullPage,\n type: command.format ?? 'png',\n };\n\n if (command.format === 'jpeg' && command.quality !== undefined) {\n options.quality = command.quality;\n }\n\n let target: Page | ReturnType<Page['locator']> = page;\n if (command.selector) {\n target = browser.getLocator(command.selector);\n }\n\n try {\n let savePath = command.path;\n if (!savePath) {\n const ext = command.format === 'jpeg' ? 'jpg' : 'png';\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const random = Math.random().toString(36).substring(2, 8);\n const filename = `screenshot-${timestamp}-${random}.${ext}`;\n const screenshotDir = path.join(getAppDir(), 'tmp', 'screenshots');\n mkdirSync(screenshotDir, { recursive: true });\n savePath = path.join(screenshotDir, filename);\n }\n\n await target.screenshot({ ...options, path: savePath });\n return successResponse(command.id, { path: savePath });\n } catch (error) {\n if (command.selector) {\n throw toAIFriendlyError(error, command.selector);\n }\n throw error;\n }\n}\n\nasync function handleSnapshot(\n command: Command & {\n action: 'snapshot';\n interactive?: boolean;\n cursor?: boolean;\n maxDepth?: number;\n compact?: boolean;\n selector?: string;\n },\n browser: BrowserManager\n): Promise<Response<SnapshotData>> {\n // Use enhanced snapshot with refs and optional filtering\n const { tree, refs } = await browser.getSnapshot({\n interactive: command.interactive,\n cursor: command.cursor,\n maxDepth: command.maxDepth,\n compact: command.compact,\n selector: command.selector,\n });\n\n // Simplify refs for output (just role and name)\n const simpleRefs: Record<string, { role: string; name?: string }> = {};\n for (const [ref, data] of Object.entries(refs)) {\n simpleRefs[ref] = { role: data.role, name: data.name };\n }\n\n return successResponse(command.id, {\n snapshot: tree || 'Empty page',\n refs: Object.keys(simpleRefs).length > 0 ? simpleRefs : undefined,\n });\n}\n\nasync function handleEvaluate(\n command: EvaluateCommand,\n browser: BrowserManager\n): Promise<Response<EvaluateData>> {\n const page = browser.getPage();\n\n // Evaluate the script directly as a string expression\n const result = await page.evaluate(command.script);\n\n return successResponse(command.id, { result });\n}\n\nasync function handleWait(command: WaitCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n\n if (command.selector) {\n await page.waitForSelector(command.selector, {\n state: command.state ?? 'visible',\n timeout: command.timeout,\n });\n } else if (command.timeout) {\n await page.waitForTimeout(command.timeout);\n } else {\n // Default: wait for load state\n await page.waitForLoadState('load');\n }\n\n return successResponse(command.id, { waited: true });\n}\n\nasync function handleScroll(command: ScrollCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n\n if (command.selector) {\n const element = page.locator(command.selector);\n await element.scrollIntoViewIfNeeded();\n\n if (command.x !== undefined || command.y !== undefined) {\n await element.evaluate(\n (el, { x, y }) => {\n el.scrollBy(x ?? 0, y ?? 0);\n },\n { x: command.x, y: command.y }\n );\n }\n } else {\n // Scroll the page\n let deltaX = command.x ?? 0;\n let deltaY = command.y ?? 0;\n\n if (command.direction) {\n const amount = command.amount ?? 100;\n switch (command.direction) {\n case 'up':\n deltaY = -amount;\n break;\n case 'down':\n deltaY = amount;\n break;\n case 'left':\n deltaX = -amount;\n break;\n case 'right':\n deltaX = amount;\n break;\n }\n }\n\n await page.evaluate(`window.scrollBy(${deltaX}, ${deltaY})`);\n }\n\n return successResponse(command.id, { scrolled: true });\n}\n\nasync function handleSelect(command: SelectCommand, browser: BrowserManager): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n const values = Array.isArray(command.values) ? command.values : [command.values];\n\n try {\n await locator.selectOption(values);\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n\n return successResponse(command.id, { selected: values });\n}\n\nasync function handleHover(command: HoverCommand, browser: BrowserManager): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n try {\n await locator.hover();\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n\n return successResponse(command.id, { hovered: true });\n}\n\nasync function handleContent(\n command: ContentCommand,\n browser: BrowserManager\n): Promise<Response<ContentData>> {\n const page = browser.getPage();\n\n let html: string;\n if (command.selector) {\n html = await page.locator(command.selector).innerHTML();\n } else {\n html = await page.content();\n }\n\n return successResponse(command.id, { html });\n}\n\nasync function handleClose(\n command: Command & { action: 'close' },\n browser: BrowserManager\n): Promise<Response> {\n await browser.close();\n return successResponse(command.id, { closed: true });\n}\n\nasync function handleTabNew(\n command: TabNewCommand,\n browser: BrowserManager\n): Promise<Response<TabNewData>> {\n const result = await browser.newTab();\n\n // Navigate to URL if provided (same pattern as handleNavigate)\n if (command.url) {\n const page = browser.getPage();\n await page.goto(command.url, { waitUntil: 'domcontentloaded' });\n }\n\n return successResponse(command.id, result);\n}\n\nasync function handleTabList(\n command: Command & { action: 'tab_list' },\n browser: BrowserManager\n): Promise<Response<TabListData>> {\n const tabs = await browser.listTabs();\n return successResponse(command.id, {\n tabs,\n active: browser.getActiveIndex(),\n });\n}\n\nasync function handleTabSwitch(\n command: TabSwitchCommand,\n browser: BrowserManager\n): Promise<Response<TabSwitchData>> {\n const result = await browser.switchTo(command.index);\n const page = browser.getPage();\n return successResponse(command.id, {\n ...result,\n title: await page.title(),\n });\n}\n\nasync function handleTabClose(\n command: TabCloseCommand,\n browser: BrowserManager\n): Promise<Response<TabCloseData>> {\n const result = await browser.closeTab(command.index);\n return successResponse(command.id, result);\n}\n\nasync function handleWindowNew(\n command: WindowNewCommand,\n browser: BrowserManager\n): Promise<Response<TabNewData>> {\n const result = await browser.newWindow(command.viewport);\n return successResponse(command.id, result);\n}\n\n// New handlers for enhanced Playwright parity\n\nasync function handleFill(command: FillCommand, browser: BrowserManager): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n try {\n await locator.fill(command.value);\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n return successResponse(command.id, { filled: true });\n}\n\nasync function handleCheck(command: CheckCommand, browser: BrowserManager): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n try {\n await locator.check();\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n return successResponse(command.id, { checked: true });\n}\n\nasync function handleUncheck(command: UncheckCommand, browser: BrowserManager): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n try {\n await locator.uncheck();\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n return successResponse(command.id, { unchecked: true });\n}\n\nasync function handleUpload(command: UploadCommand, browser: BrowserManager): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n const files = Array.isArray(command.files) ? command.files : [command.files];\n try {\n await locator.setInputFiles(files);\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n return successResponse(command.id, { uploaded: files });\n}\n\nasync function handleDoubleClick(\n command: DoubleClickCommand,\n browser: BrowserManager\n): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n try {\n await locator.dblclick();\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n return successResponse(command.id, { clicked: true });\n}\n\nasync function handleFocus(command: FocusCommand, browser: BrowserManager): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n try {\n await locator.focus();\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n return successResponse(command.id, { focused: true });\n}\n\nasync function handleDrag(command: DragCommand, browser: BrowserManager): Promise<Response> {\n const frame = browser.getFrame();\n await frame.dragAndDrop(command.source, command.target);\n return successResponse(command.id, { dragged: true });\n}\n\nasync function handleFrame(command: FrameCommand, browser: BrowserManager): Promise<Response> {\n await browser.switchToFrame({\n selector: command.selector,\n name: command.name,\n url: command.url,\n });\n return successResponse(command.id, { switched: true });\n}\n\nasync function handleMainFrame(\n command: Command & { action: 'mainframe' },\n browser: BrowserManager\n): Promise<Response> {\n browser.switchToMainFrame();\n return successResponse(command.id, { switched: true });\n}\n\nasync function handleGetByRole(\n command: GetByRoleCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const locator = page.getByRole(command.role as any, { name: command.name, exact: command.exact });\n\n switch (command.subaction) {\n case 'click':\n await locator.click();\n return successResponse(command.id, { clicked: true });\n case 'fill':\n await locator.fill(command.value ?? '');\n return successResponse(command.id, { filled: true });\n case 'check':\n await locator.check();\n return successResponse(command.id, { checked: true });\n case 'hover':\n await locator.hover();\n return successResponse(command.id, { hovered: true });\n }\n}\n\nasync function handleGetByText(\n command: GetByTextCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const locator = page.getByText(command.text, { exact: command.exact });\n\n switch (command.subaction) {\n case 'click':\n await locator.click();\n return successResponse(command.id, { clicked: true });\n case 'hover':\n await locator.hover();\n return successResponse(command.id, { hovered: true });\n }\n}\n\nasync function handleGetByLabel(\n command: GetByLabelCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const locator = page.getByLabel(command.label, { exact: command.exact });\n\n switch (command.subaction) {\n case 'click':\n await locator.click();\n return successResponse(command.id, { clicked: true });\n case 'fill':\n await locator.fill(command.value ?? '');\n return successResponse(command.id, { filled: true });\n case 'check':\n await locator.check();\n return successResponse(command.id, { checked: true });\n }\n}\n\nasync function handleGetByPlaceholder(\n command: GetByPlaceholderCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const locator = page.getByPlaceholder(command.placeholder, { exact: command.exact });\n\n switch (command.subaction) {\n case 'click':\n await locator.click();\n return successResponse(command.id, { clicked: true });\n case 'fill':\n await locator.fill(command.value ?? '');\n return successResponse(command.id, { filled: true });\n }\n}\n\nasync function handleCookiesGet(\n command: Command & { action: 'cookies_get'; urls?: string[] },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const context = page.context();\n const cookies = await context.cookies(command.urls);\n return successResponse(command.id, { cookies });\n}\n\nasync function handleCookiesSet(\n command: CookiesSetCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const context = page.context();\n // Auto-fill URL for cookies that don't have domain/path/url set\n const pageUrl = page.url();\n const cookies = command.cookies.map((cookie) => {\n if (!cookie.url && !cookie.domain && !cookie.path) {\n return { ...cookie, url: pageUrl };\n }\n return cookie;\n });\n await context.addCookies(cookies);\n return successResponse(command.id, { set: true });\n}\n\nasync function handleCookiesClear(\n command: Command & { action: 'cookies_clear' },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const context = page.context();\n await context.clearCookies();\n return successResponse(command.id, { cleared: true });\n}\n\nasync function handleStorageGet(\n command: StorageGetCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const storageType = command.type === 'local' ? 'localStorage' : 'sessionStorage';\n\n if (command.key) {\n const value = await page.evaluate(`${storageType}.getItem(${JSON.stringify(command.key)})`);\n return successResponse(command.id, { key: command.key, value });\n } else {\n const data = await page.evaluate(`\n (() => {\n const storage = ${storageType};\n const result = {};\n for (let i = 0; i < storage.length; i++) {\n const key = storage.key(i);\n if (key) result[key] = storage.getItem(key);\n }\n return result;\n })()\n `);\n return successResponse(command.id, { data });\n }\n}\n\nasync function handleStorageSet(\n command: StorageSetCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const storageType = command.type === 'local' ? 'localStorage' : 'sessionStorage';\n\n await page.evaluate(\n `${storageType}.setItem(${JSON.stringify(command.key)}, ${JSON.stringify(command.value)})`\n );\n return successResponse(command.id, { set: true });\n}\n\nasync function handleStorageClear(\n command: StorageClearCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const storageType = command.type === 'local' ? 'localStorage' : 'sessionStorage';\n\n await page.evaluate(`${storageType}.clear()`);\n return successResponse(command.id, { cleared: true });\n}\n\nasync function handleDialog(command: DialogCommand, browser: BrowserManager): Promise<Response> {\n browser.setDialogHandler(command.response, command.promptText);\n return successResponse(command.id, { handler: 'set', response: command.response });\n}\n\nasync function handlePdf(command: PdfCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n await page.pdf({\n path: command.path,\n format: command.format ?? 'Letter',\n });\n return successResponse(command.id, { path: command.path });\n}\n\n// Network & Request handlers\n\nasync function handleRoute(command: RouteCommand, browser: BrowserManager): Promise<Response> {\n await browser.addRoute(command.url, {\n response: command.response,\n abort: command.abort,\n });\n return successResponse(command.id, { routed: command.url });\n}\n\nasync function handleUnroute(\n command: Command & { action: 'unroute'; url?: string },\n browser: BrowserManager\n): Promise<Response> {\n await browser.removeRoute(command.url);\n return successResponse(command.id, { unrouted: command.url ?? 'all' });\n}\n\nasync function handleRequests(\n command: RequestsCommand,\n browser: BrowserManager\n): Promise<Response> {\n if (command.clear) {\n browser.clearRequests();\n return successResponse(command.id, { cleared: true });\n }\n\n // Start tracking if not already\n browser.startRequestTracking();\n\n const requests = browser.getRequests(command.filter);\n return successResponse(command.id, { requests });\n}\n\nasync function handleDownload(\n command: DownloadCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const locator = browser.getLocator(command.selector);\n\n const [download] = await Promise.all([page.waitForEvent('download'), locator.click()]);\n\n await download.saveAs(command.path);\n return successResponse(command.id, {\n path: command.path,\n suggestedFilename: download.suggestedFilename(),\n });\n}\n\nasync function handleGeolocation(\n command: GeolocationCommand,\n browser: BrowserManager\n): Promise<Response> {\n await browser.setGeolocation(command.latitude, command.longitude, command.accuracy);\n return successResponse(command.id, {\n latitude: command.latitude,\n longitude: command.longitude,\n });\n}\n\nasync function handlePermissions(\n command: PermissionsCommand,\n browser: BrowserManager\n): Promise<Response> {\n await browser.setPermissions(command.permissions, command.grant);\n return successResponse(command.id, {\n permissions: command.permissions,\n granted: command.grant,\n });\n}\n\nasync function handleViewport(\n command: ViewportCommand,\n browser: BrowserManager\n): Promise<Response> {\n await browser.setViewport(command.width, command.height);\n return successResponse(command.id, {\n width: command.width,\n height: command.height,\n });\n}\n\nasync function handleUserAgent(\n command: Command & { action: 'useragent'; userAgent: string },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const context = page.context();\n // Note: Can't change user agent after context is created, but we can for new pages\n return successResponse(command.id, {\n note: 'User agent can only be set at launch time. Use device command instead.',\n });\n}\n\nasync function handleDevice(command: DeviceCommand, browser: BrowserManager): Promise<Response> {\n const device = browser.getDevice(command.device);\n if (!device) {\n const available = browser.listDevices().slice(0, 10).join(', ');\n throw new Error(`Unknown device: ${command.device}. Available: ${available}...`);\n }\n\n // Apply device viewport\n await browser.setViewport(device.viewport.width, device.viewport.height);\n\n // Apply or clear device scale factor\n if (device.deviceScaleFactor && device.deviceScaleFactor !== 1) {\n // Apply device scale factor for HiDPI/retina displays\n await browser.setDeviceScaleFactor(\n device.deviceScaleFactor,\n device.viewport.width,\n device.viewport.height,\n device.isMobile ?? false\n );\n } else {\n // Clear device scale factor override to restore default (1x)\n try {\n await browser.clearDeviceMetricsOverride();\n } catch {\n // Ignore error if override was never set\n }\n }\n\n return successResponse(command.id, {\n device: command.device,\n viewport: device.viewport,\n userAgent: device.userAgent,\n deviceScaleFactor: device.deviceScaleFactor,\n });\n}\n\nasync function handleBack(\n command: Command & { action: 'back' },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.goBack();\n return successResponse(command.id, { url: page.url() });\n}\n\nasync function handleForward(\n command: Command & { action: 'forward' },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.goForward();\n return successResponse(command.id, { url: page.url() });\n}\n\nasync function handleReload(\n command: Command & { action: 'reload' },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.reload();\n return successResponse(command.id, { url: page.url() });\n}\n\nasync function handleUrl(\n command: Command & { action: 'url' },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n return successResponse(command.id, { url: page.url() });\n}\n\nasync function handleTitle(\n command: Command & { action: 'title' },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const title = await page.title();\n return successResponse(command.id, { title });\n}\n\nasync function handleGetAttribute(\n command: GetAttributeCommand,\n browser: BrowserManager\n): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n const value = await locator.getAttribute(command.attribute);\n return successResponse(command.id, { attribute: command.attribute, value });\n}\n\nasync function handleGetText(command: GetTextCommand, browser: BrowserManager): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n const text = await locator.textContent();\n return successResponse(command.id, { text });\n}\n\nasync function handleIsVisible(\n command: IsVisibleCommand,\n browser: BrowserManager\n): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n const visible = await locator.isVisible();\n return successResponse(command.id, { visible });\n}\n\nasync function handleIsEnabled(\n command: IsEnabledCommand,\n browser: BrowserManager\n): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n const enabled = await locator.isEnabled();\n return successResponse(command.id, { enabled });\n}\n\nasync function handleIsChecked(\n command: IsCheckedCommand,\n browser: BrowserManager\n): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n const checked = await locator.isChecked();\n return successResponse(command.id, { checked });\n}\n\nasync function handleCount(command: CountCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n const count = await page.locator(command.selector).count();\n return successResponse(command.id, { count });\n}\n\nasync function handleBoundingBox(\n command: BoundingBoxCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const box = await page.locator(command.selector).boundingBox();\n return successResponse(command.id, { box });\n}\n\nasync function handleStyles(\n command: StylesCommand,\n browser: BrowserManager\n): Promise<Response<StylesData>> {\n const page = browser.getPage();\n\n // Shared extraction logic as a string to be eval'd in browser context\n const extractStyles = (el: Element) => {\n const s = getComputedStyle(el);\n const r = el.getBoundingClientRect();\n return {\n tag: el.tagName.toLowerCase(),\n text: (el as HTMLElement).innerText?.trim().slice(0, 80) || null,\n box: {\n x: Math.round(r.x),\n y: Math.round(r.y),\n width: Math.round(r.width),\n height: Math.round(r.height),\n },\n styles: {\n fontSize: s.fontSize,\n fontWeight: s.fontWeight,\n fontFamily: s.fontFamily.split(',')[0].trim().replace(/\"/g, ''),\n color: s.color,\n backgroundColor: s.backgroundColor,\n borderRadius: s.borderRadius,\n border: s.border !== 'none' && s.borderWidth !== '0px' ? s.border : null,\n boxShadow: s.boxShadow !== 'none' ? s.boxShadow : null,\n padding: s.padding,\n },\n };\n };\n\n // Check if it's a ref - single element\n if (browser.isRef(command.selector)) {\n const locator = browser.getLocator(command.selector);\n const element = (await locator.evaluate(extractStyles)) as StylesData['elements'][0];\n return successResponse(command.id, { elements: [element] });\n }\n\n // CSS selector - can match multiple elements\n const elements = (await page.$$eval(command.selector, (els) => {\n return els.map((el) => {\n const s = getComputedStyle(el);\n const r = el.getBoundingClientRect();\n return {\n tag: el.tagName.toLowerCase(),\n text: (el as HTMLElement).innerText?.trim().slice(0, 80) || null,\n box: {\n x: Math.round(r.x),\n y: Math.round(r.y),\n width: Math.round(r.width),\n height: Math.round(r.height),\n },\n styles: {\n fontSize: s.fontSize,\n fontWeight: s.fontWeight,\n fontFamily: s.fontFamily.split(',')[0].trim().replace(/\"/g, ''),\n color: s.color,\n backgroundColor: s.backgroundColor,\n borderRadius: s.borderRadius,\n border: s.border !== 'none' && s.borderWidth !== '0px' ? s.border : null,\n boxShadow: s.boxShadow !== 'none' ? s.boxShadow : null,\n padding: s.padding,\n },\n };\n });\n })) as StylesData['elements'];\n\n return successResponse(command.id, { elements });\n}\n\n// Advanced handlers\n\nasync function handleVideoStart(\n command: Command & { action: 'video_start'; path: string },\n browser: BrowserManager\n): Promise<Response> {\n // Video recording requires context-level setup at launch\n // For now, return a note about this limitation\n return successResponse(command.id, {\n note: 'Video recording must be enabled at browser launch. Use --video flag when starting.',\n path: command.path,\n });\n}\n\nasync function handleVideoStop(\n command: Command & { action: 'video_stop' },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const video = page.video();\n if (video) {\n const path = await video.path();\n return successResponse(command.id, { path });\n }\n return successResponse(command.id, { note: 'No video recording active' });\n}\n\nasync function handleTraceStart(\n command: TraceStartCommand,\n browser: BrowserManager\n): Promise<Response> {\n await browser.startTracing({\n screenshots: command.screenshots,\n snapshots: command.snapshots,\n });\n return successResponse(command.id, { started: true });\n}\n\nasync function handleTraceStop(\n command: TraceStopCommand,\n browser: BrowserManager\n): Promise<Response> {\n await browser.stopTracing(command.path);\n return successResponse(command.id, { path: command.path });\n}\n\nasync function handleHarStart(\n command: Command & { action: 'har_start' },\n browser: BrowserManager\n): Promise<Response> {\n await browser.startHarRecording();\n browser.startRequestTracking();\n return successResponse(command.id, { started: true });\n}\n\nasync function handleHarStop(command: HarStopCommand, browser: BrowserManager): Promise<Response> {\n // HAR recording is handled at context level\n // For now, we save tracked requests as a simplified HAR-like format\n const requests = browser.getRequests();\n return successResponse(command.id, {\n path: command.path,\n requestCount: requests.length,\n });\n}\n\nasync function handleStateSave(\n command: StorageStateSaveCommand,\n browser: BrowserManager\n): Promise<Response> {\n await browser.saveStorageState(command.path);\n return successResponse(command.id, { path: command.path });\n}\n\nasync function handleStateLoad(\n command: Command & { action: 'state_load'; path: string },\n browser: BrowserManager\n): Promise<Response> {\n // Storage state is loaded at context creation\n return successResponse(command.id, {\n note: 'Storage state must be loaded at browser launch. Use --state flag.',\n path: command.path,\n });\n}\n\nasync function handleConsole(command: ConsoleCommand, browser: BrowserManager): Promise<Response> {\n if (command.clear) {\n browser.clearConsoleMessages();\n return successResponse(command.id, { cleared: true });\n }\n\n const messages = browser.getConsoleMessages();\n return successResponse(command.id, { messages });\n}\n\nasync function handleErrors(command: ErrorsCommand, browser: BrowserManager): Promise<Response> {\n if (command.clear) {\n browser.clearPageErrors();\n return successResponse(command.id, { cleared: true });\n }\n\n const errors = browser.getPageErrors();\n return successResponse(command.id, { errors });\n}\n\nasync function handleKeyboard(\n command: KeyboardCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.keyboard.press(command.keys);\n return successResponse(command.id, { pressed: command.keys });\n}\n\nasync function handleWheel(command: WheelCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n\n if (command.selector) {\n const element = page.locator(command.selector);\n await element.hover();\n }\n\n await page.mouse.wheel(command.deltaX ?? 0, command.deltaY ?? 0);\n return successResponse(command.id, { scrolled: true });\n}\n\nasync function handleTap(command: TapCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n await page.tap(command.selector);\n return successResponse(command.id, { tapped: true });\n}\n\nasync function handleClipboard(\n command: ClipboardCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n\n switch (command.operation) {\n case 'copy':\n await page.keyboard.press('Control+c');\n return successResponse(command.id, { copied: true });\n case 'paste':\n await page.keyboard.press('Control+v');\n return successResponse(command.id, { pasted: true });\n case 'read':\n const text = await page.evaluate('navigator.clipboard.readText()');\n return successResponse(command.id, { text });\n default:\n return errorResponse(command.id, 'Unknown clipboard operation');\n }\n}\n\nasync function handleHighlight(\n command: HighlightCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.locator(command.selector).highlight();\n return successResponse(command.id, { highlighted: true });\n}\n\nasync function handleClear(command: ClearCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n await page.locator(command.selector).clear();\n return successResponse(command.id, { cleared: true });\n}\n\nasync function handleSelectAll(\n command: SelectAllCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.locator(command.selector).selectText();\n return successResponse(command.id, { selected: true });\n}\n\nasync function handleInnerText(\n command: InnerTextCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const text = await page.locator(command.selector).innerText();\n return successResponse(command.id, { text });\n}\n\nasync function handleInnerHtml(\n command: InnerHtmlCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const html = await page.locator(command.selector).innerHTML();\n return successResponse(command.id, { html });\n}\n\nasync function handleInputValue(\n command: InputValueCommand,\n browser: BrowserManager\n): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n const value = await locator.inputValue();\n return successResponse(command.id, { value });\n}\n\nasync function handleSetValue(\n command: SetValueCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.locator(command.selector).fill(command.value);\n return successResponse(command.id, { set: true });\n}\n\nasync function handleDispatch(\n command: DispatchEventCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.locator(command.selector).dispatchEvent(command.event, command.eventInit);\n return successResponse(command.id, { dispatched: command.event });\n}\n\nasync function handleEvalHandle(\n command: Command & { action: 'evalhandle'; script: string },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const handle = await page.evaluateHandle(command.script);\n const result = await handle.jsonValue().catch(() => 'Handle (non-serializable)');\n return successResponse(command.id, { result });\n}\n\nasync function handleExpose(\n command: Command & { action: 'expose'; name: string },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.exposeFunction(command.name, () => {\n // Exposed function - can be extended\n return `Function ${command.name} called`;\n });\n return successResponse(command.id, { exposed: command.name });\n}\n\nasync function handleAddScript(\n command: AddScriptCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n\n if (command.content) {\n await page.addScriptTag({ content: command.content });\n } else if (command.url) {\n await page.addScriptTag({ url: command.url });\n }\n\n return successResponse(command.id, { added: true });\n}\n\nasync function handleAddStyle(\n command: AddStyleCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n\n if (command.content) {\n await page.addStyleTag({ content: command.content });\n } else if (command.url) {\n await page.addStyleTag({ url: command.url });\n }\n\n return successResponse(command.id, { added: true });\n}\n\nasync function handleEmulateMedia(\n command: EmulateMediaCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.emulateMedia({\n media: command.media,\n colorScheme: command.colorScheme,\n reducedMotion: command.reducedMotion,\n forcedColors: command.forcedColors,\n });\n return successResponse(command.id, { emulated: true });\n}\n\nasync function handleOffline(command: OfflineCommand, browser: BrowserManager): Promise<Response> {\n await browser.setOffline(command.offline);\n return successResponse(command.id, { offline: command.offline });\n}\n\nasync function handleHeaders(command: HeadersCommand, browser: BrowserManager): Promise<Response> {\n await browser.setExtraHeaders(command.headers);\n return successResponse(command.id, { set: true });\n}\n\nasync function handlePause(\n command: Command & { action: 'pause' },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.pause();\n return successResponse(command.id, { paused: true });\n}\n\nasync function handleGetByAltText(\n command: GetByAltTextCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const locator = page.getByAltText(command.text, { exact: command.exact });\n\n switch (command.subaction) {\n case 'click':\n await locator.click();\n return successResponse(command.id, { clicked: true });\n case 'hover':\n await locator.hover();\n return successResponse(command.id, { hovered: true });\n }\n}\n\nasync function handleGetByTitle(\n command: GetByTitleCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const locator = page.getByTitle(command.text, { exact: command.exact });\n\n switch (command.subaction) {\n case 'click':\n await locator.click();\n return successResponse(command.id, { clicked: true });\n case 'hover':\n await locator.hover();\n return successResponse(command.id, { hovered: true });\n }\n}\n\nasync function handleGetByTestId(\n command: GetByTestIdCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const locator = page.getByTestId(command.testId);\n\n switch (command.subaction) {\n case 'click':\n await locator.click();\n return successResponse(command.id, { clicked: true });\n case 'fill':\n await locator.fill(command.value ?? '');\n return successResponse(command.id, { filled: true });\n case 'check':\n await locator.check();\n return successResponse(command.id, { checked: true });\n case 'hover':\n await locator.hover();\n return successResponse(command.id, { hovered: true });\n }\n}\n\nasync function handleNth(command: NthCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n const base = page.locator(command.selector);\n const locator = command.index === -1 ? base.last() : base.nth(command.index);\n\n switch (command.subaction) {\n case 'click':\n await locator.click();\n return successResponse(command.id, { clicked: true });\n case 'fill':\n await locator.fill(command.value ?? '');\n return successResponse(command.id, { filled: true });\n case 'check':\n await locator.check();\n return successResponse(command.id, { checked: true });\n case 'hover':\n await locator.hover();\n return successResponse(command.id, { hovered: true });\n case 'text':\n const text = await locator.textContent();\n return successResponse(command.id, { text });\n }\n}\n\nasync function handleWaitForUrl(\n command: WaitForUrlCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.waitForURL(command.url, { timeout: command.timeout });\n return successResponse(command.id, { url: page.url() });\n}\n\nasync function handleWaitForLoadState(\n command: WaitForLoadStateCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.waitForLoadState(command.state, { timeout: command.timeout });\n return successResponse(command.id, { state: command.state });\n}\n\nasync function handleSetContent(\n command: SetContentCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.setContent(command.html);\n return successResponse(command.id, { set: true });\n}\n\nasync function handleTimezone(\n command: TimezoneCommand,\n browser: BrowserManager\n): Promise<Response> {\n // Timezone must be set at context level before navigation\n // This is a limitation - it sets for the current context\n const page = browser.getPage();\n await page.context().setGeolocation({ latitude: 0, longitude: 0 }); // Trigger context awareness\n return successResponse(command.id, {\n note: 'Timezone must be set at browser launch. Use --timezone flag.',\n timezone: command.timezone,\n });\n}\n\nasync function handleLocale(command: LocaleCommand, browser: BrowserManager): Promise<Response> {\n // Locale must be set at context creation\n return successResponse(command.id, {\n note: 'Locale must be set at browser launch. Use --locale flag.',\n locale: command.locale,\n });\n}\n\nasync function handleCredentials(\n command: HttpCredentialsCommand,\n browser: BrowserManager\n): Promise<Response> {\n const context = browser.getPage().context();\n await context.setHTTPCredentials({\n username: command.username,\n password: command.password,\n });\n return successResponse(command.id, { set: true });\n}\n\nasync function handleMouseMove(\n command: MouseMoveCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.mouse.move(command.x, command.y);\n return successResponse(command.id, { moved: true, x: command.x, y: command.y });\n}\n\nasync function handleMouseDown(\n command: MouseDownCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.mouse.down({ button: command.button ?? 'left' });\n return successResponse(command.id, { down: true });\n}\n\nasync function handleMouseUp(command: MouseUpCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n await page.mouse.up({ button: command.button ?? 'left' });\n return successResponse(command.id, { up: true });\n}\n\nasync function handleBringToFront(\n command: Command & { action: 'bringtofront' },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.bringToFront();\n return successResponse(command.id, { focused: true });\n}\n\nasync function handleWaitForFunction(\n command: WaitForFunctionCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.waitForFunction(command.expression, { timeout: command.timeout });\n return successResponse(command.id, { waited: true });\n}\n\nasync function handleScrollIntoView(\n command: ScrollIntoViewCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.locator(command.selector).scrollIntoViewIfNeeded();\n return successResponse(command.id, { scrolled: true });\n}\n\nasync function handleAddInitScript(\n command: AddInitScriptCommand,\n browser: BrowserManager\n): Promise<Response> {\n const context = browser.getPage().context();\n await context.addInitScript(command.script);\n return successResponse(command.id, { added: true });\n}\n\nasync function handleKeyDown(command: KeyDownCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n await page.keyboard.down(command.key);\n return successResponse(command.id, { down: true, key: command.key });\n}\n\nasync function handleKeyUp(command: KeyUpCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n await page.keyboard.up(command.key);\n return successResponse(command.id, { up: true, key: command.key });\n}\n\nasync function handleInsertText(\n command: InsertTextCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.keyboard.insertText(command.text);\n return successResponse(command.id, { inserted: true });\n}\n\nasync function handleMultiSelect(\n command: MultiSelectCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const selected = await page.locator(command.selector).selectOption(command.values);\n return successResponse(command.id, { selected });\n}\n\nasync function handleWaitForDownload(\n command: WaitForDownloadCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const download = await page.waitForEvent('download', { timeout: command.timeout });\n\n let filePath: string;\n if (command.path) {\n filePath = command.path;\n await download.saveAs(filePath);\n } else {\n filePath = (await download.path()) || download.suggestedFilename();\n }\n\n return successResponse(command.id, {\n path: filePath,\n filename: download.suggestedFilename(),\n url: download.url(),\n });\n}\n\nasync function handleResponseBody(\n command: ResponseBodyCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const response = await page.waitForResponse((resp) => resp.url().includes(command.url), {\n timeout: command.timeout,\n });\n\n const body = await response.text();\n let parsed: unknown = body;\n\n try {\n parsed = JSON.parse(body);\n } catch {\n // Keep as string if not JSON\n }\n\n return successResponse(command.id, {\n url: response.url(),\n status: response.status(),\n body: parsed,\n });\n}\n\n// Screencast and input injection handlers\n\nasync function handleScreencastStart(\n command: ScreencastStartCommand,\n browser: BrowserManager\n): Promise<Response<ScreencastStartData>> {\n if (!screencastFrameCallback) {\n throw new Error('Screencast frame callback not set. Start the streaming server first.');\n }\n\n await browser.startScreencast(screencastFrameCallback, {\n format: command.format,\n quality: command.quality,\n maxWidth: command.maxWidth,\n maxHeight: command.maxHeight,\n everyNthFrame: command.everyNthFrame,\n });\n\n return successResponse(command.id, {\n started: true,\n format: command.format ?? 'jpeg',\n quality: command.quality ?? 80,\n });\n}\n\nasync function handleScreencastStop(\n command: ScreencastStopCommand,\n browser: BrowserManager\n): Promise<Response<ScreencastStopData>> {\n await browser.stopScreencast();\n return successResponse(command.id, { stopped: true });\n}\n\nasync function handleInputMouse(\n command: InputMouseCommand,\n browser: BrowserManager\n): Promise<Response<InputEventData>> {\n await browser.injectMouseEvent({\n type: command.type,\n x: command.x,\n y: command.y,\n button: command.button,\n clickCount: command.clickCount,\n deltaX: command.deltaX,\n deltaY: command.deltaY,\n modifiers: command.modifiers,\n });\n return successResponse(command.id, { injected: true });\n}\n\nasync function handleInputKeyboard(\n command: InputKeyboardCommand,\n browser: BrowserManager\n): Promise<Response<InputEventData>> {\n await browser.injectKeyboardEvent({\n type: command.type,\n key: command.key,\n code: command.code,\n text: command.text,\n modifiers: command.modifiers,\n });\n return successResponse(command.id, { injected: true });\n}\n\nasync function handleInputTouch(\n command: InputTouchCommand,\n browser: BrowserManager\n): Promise<Response<InputEventData>> {\n await browser.injectTouchEvent({\n type: command.type,\n touchPoints: command.touchPoints,\n modifiers: command.modifiers,\n });\n return successResponse(command.id, { injected: true });\n}\n\n// Recording handlers (Playwright native video recording)\n\nasync function handleRecordingStart(\n command: RecordingStartCommand,\n browser: BrowserManager\n): Promise<Response<RecordingStartData>> {\n await browser.startRecording(command.path, command.url);\n return successResponse(command.id, {\n started: true,\n path: command.path,\n });\n}\n\nasync function handleRecordingStop(\n command: RecordingStopCommand,\n browser: BrowserManager\n): Promise<Response<RecordingStopData>> {\n const result = await browser.stopRecording();\n return successResponse(command.id, result);\n}\n\nasync function handleRecordingRestart(\n command: RecordingRestartCommand,\n browser: BrowserManager\n): Promise<Response<RecordingRestartData>> {\n const result = await browser.restartRecording(command.path, command.url);\n return successResponse(command.id, {\n started: true,\n path: command.path,\n previousPath: result.previousPath,\n stopped: result.stopped,\n });\n}\n","/**\n * iOS command execution - mirrors actions.ts but for iOS Safari via Appium.\n * Provides 1:1 command parity where possible.\n */\n\nimport type { IOSManager } from './ios-manager.js';\nimport type { Command, Response } from './types.js';\n\nfunction successResponse<T>(id: string, data: T): Response<T> {\n return { id, success: true, data };\n}\n\nfunction errorResponse(id: string, error: string): Response {\n return { id, success: false, error };\n}\n\n/**\n * Execute a command on the iOS manager\n */\nexport async function executeIOSCommand(command: Command, manager: IOSManager): Promise<Response> {\n const { id, action } = command;\n\n try {\n switch (action) {\n case 'launch': {\n const cmd = command as any;\n await manager.launch({\n device: cmd.device,\n udid: cmd.udid,\n });\n const info = manager.getDeviceInfo();\n return successResponse(id, {\n launched: true,\n device: info?.name ?? 'iOS Simulator',\n udid: info?.udid,\n });\n }\n\n case 'navigate': {\n const cmd = command as any;\n const result = await manager.navigate(cmd.url);\n return successResponse(id, result);\n }\n\n case 'click': {\n const cmd = command as any;\n await manager.click(cmd.selector);\n return successResponse(id, { clicked: true });\n }\n\n case 'tap': {\n const cmd = command as any;\n await manager.tap(cmd.selector);\n return successResponse(id, { tapped: true });\n }\n\n case 'type': {\n const cmd = command as any;\n await manager.type(cmd.selector, cmd.text, {\n delay: cmd.delay,\n clear: cmd.clear,\n });\n return successResponse(id, { typed: true });\n }\n\n case 'fill': {\n const cmd = command as any;\n await manager.fill(cmd.selector, cmd.value);\n return successResponse(id, { filled: true });\n }\n\n case 'screenshot': {\n const cmd = command as any;\n const result = await manager.screenshot({\n path: cmd.path,\n fullPage: cmd.fullPage,\n });\n return successResponse(id, result);\n }\n\n case 'snapshot': {\n const cmd = command as any;\n const result = await manager.getSnapshot({\n interactive: cmd.interactive,\n });\n return successResponse(id, { snapshot: result.tree, refs: result.refs });\n }\n\n case 'scroll': {\n const cmd = command as any;\n await manager.scroll({\n selector: cmd.selector,\n x: cmd.x,\n y: cmd.y,\n direction: cmd.direction,\n amount: cmd.amount,\n });\n return successResponse(id, { scrolled: true });\n }\n\n case 'swipe': {\n const cmd = command as any;\n await manager.swipe(cmd.direction, { distance: cmd.distance });\n return successResponse(id, { swiped: true });\n }\n\n case 'evaluate': {\n const cmd = command as any;\n const result = await manager.evaluate(cmd.script, ...(cmd.args ?? []));\n return successResponse(id, { result });\n }\n\n case 'wait': {\n const cmd = command as any;\n await manager.wait({\n selector: cmd.selector,\n timeout: cmd.timeout,\n state: cmd.state,\n });\n return successResponse(id, { waited: true });\n }\n\n case 'press': {\n const cmd = command as any;\n await manager.press(cmd.key);\n return successResponse(id, { pressed: true });\n }\n\n case 'hover': {\n const cmd = command as any;\n await manager.hover(cmd.selector);\n return successResponse(id, { hovered: true });\n }\n\n case 'content': {\n const cmd = command as any;\n const html = await manager.getContent(cmd.selector);\n return successResponse(id, { html });\n }\n\n case 'gettext': {\n const cmd = command as any;\n const text = await manager.getText(cmd.selector);\n return successResponse(id, { text });\n }\n\n case 'getattribute': {\n const cmd = command as any;\n const value = await manager.getAttribute(cmd.selector, cmd.attribute);\n return successResponse(id, { value });\n }\n\n case 'isvisible': {\n const cmd = command as any;\n const visible = await manager.isVisible(cmd.selector);\n return successResponse(id, { visible });\n }\n\n case 'isenabled': {\n const cmd = command as any;\n const enabled = await manager.isEnabled(cmd.selector);\n return successResponse(id, { enabled });\n }\n\n case 'url': {\n const url = await manager.getUrl();\n return successResponse(id, { url });\n }\n\n case 'title': {\n const title = await manager.getTitle();\n return successResponse(id, { title });\n }\n\n case 'back': {\n await manager.goBack();\n return successResponse(id, { navigated: 'back' });\n }\n\n case 'forward': {\n await manager.goForward();\n return successResponse(id, { navigated: 'forward' });\n }\n\n case 'reload': {\n await manager.reload();\n return successResponse(id, { reloaded: true });\n }\n\n case 'select': {\n const cmd = command as any;\n await manager.select(cmd.selector, cmd.values);\n return successResponse(id, { selected: true });\n }\n\n case 'check': {\n const cmd = command as any;\n await manager.check(cmd.selector);\n return successResponse(id, { checked: true });\n }\n\n case 'uncheck': {\n const cmd = command as any;\n await manager.uncheck(cmd.selector);\n return successResponse(id, { unchecked: true });\n }\n\n case 'focus': {\n const cmd = command as any;\n await manager.focus(cmd.selector);\n return successResponse(id, { focused: true });\n }\n\n case 'clear': {\n const cmd = command as any;\n await manager.clear(cmd.selector);\n return successResponse(id, { cleared: true });\n }\n\n case 'count': {\n const cmd = command as any;\n const count = await manager.count(cmd.selector);\n return successResponse(id, { count });\n }\n\n case 'boundingbox': {\n const cmd = command as any;\n const box = await manager.getBoundingBox(cmd.selector);\n return successResponse(id, { box });\n }\n\n case 'close': {\n await manager.close();\n return successResponse(id, { closed: true });\n }\n\n // iOS-specific: device list\n case 'device_list': {\n const devices = await manager.listDevices();\n return successResponse(id, { devices });\n }\n\n // Commands that don't apply to iOS Safari\n case 'tab_new':\n case 'tab_list':\n case 'tab_switch':\n case 'tab_close':\n case 'window_new':\n return errorResponse(\n id,\n `Command '${action}' is not supported on iOS Safari. Mobile Safari does not support programmatic tab management.`\n );\n\n case 'pdf':\n return errorResponse(id, 'PDF generation is not supported on iOS Safari.');\n\n case 'screencast_start':\n case 'screencast_stop':\n return errorResponse(id, 'Screencast is not supported on iOS (requires CDP).');\n\n case 'recording_start':\n case 'recording_stop':\n case 'recording_restart':\n return errorResponse(id, 'Video recording is not yet supported on iOS.');\n\n default:\n return errorResponse(id, `Unknown or unsupported iOS command: ${action}`);\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return errorResponse(id, message);\n }\n}\n","import { WebSocketServer, WebSocket } from 'ws';\nimport type { BrowserManager, ScreencastFrame } from './browser.js';\nimport { setScreencastFrameCallback } from './actions.js';\n\n/**\n * Check whether a WebSocket connection origin should be allowed.\n * Allows: no origin (CLI tools), file:// origins, and localhost/loopback origins.\n * Rejects: all other origins (prevents malicious web pages from connecting).\n */\nexport function isAllowedOrigin(origin: string | undefined): boolean {\n // Allow connections with no origin (non-browser clients like CLI tools)\n if (!origin) {\n return true;\n }\n // Allow file:// origins (local HTML files)\n if (origin.startsWith('file://')) {\n return true;\n }\n // Allow localhost/loopback origins (browser-based stream viewers)\n try {\n const url = new URL(origin);\n const host = url.hostname;\n if (host === 'localhost' || host === '127.0.0.1' || host === '::1' || host === '[::1]') {\n return true;\n }\n } catch {\n // Invalid origin URL - reject\n }\n return false;\n}\n\n// Message types for WebSocket communication\nexport interface FrameMessage {\n type: 'frame';\n data: string; // base64 encoded image\n metadata: {\n offsetTop: number;\n pageScaleFactor: number;\n deviceWidth: number;\n deviceHeight: number;\n scrollOffsetX: number;\n scrollOffsetY: number;\n timestamp?: number;\n };\n}\n\nexport interface InputMouseMessage {\n type: 'input_mouse';\n eventType: 'mousePressed' | 'mouseReleased' | 'mouseMoved' | 'mouseWheel';\n x: number;\n y: number;\n button?: 'left' | 'right' | 'middle' | 'none';\n clickCount?: number;\n deltaX?: number;\n deltaY?: number;\n modifiers?: number;\n}\n\nexport interface InputKeyboardMessage {\n type: 'input_keyboard';\n eventType: 'keyDown' | 'keyUp' | 'char';\n key?: string;\n code?: string;\n text?: string;\n modifiers?: number;\n}\n\nexport interface InputTouchMessage {\n type: 'input_touch';\n eventType: 'touchStart' | 'touchEnd' | 'touchMove' | 'touchCancel';\n touchPoints: Array<{ x: number; y: number; id?: number }>;\n modifiers?: number;\n}\n\nexport interface StatusMessage {\n type: 'status';\n connected: boolean;\n screencasting: boolean;\n viewportWidth?: number;\n viewportHeight?: number;\n}\n\nexport interface ErrorMessage {\n type: 'error';\n message: string;\n}\n\nexport type StreamMessage =\n | FrameMessage\n | InputMouseMessage\n | InputKeyboardMessage\n | InputTouchMessage\n | StatusMessage\n | ErrorMessage;\n\n/**\n * WebSocket server for streaming browser viewport and receiving input\n */\nexport class StreamServer {\n private wss: WebSocketServer | null = null;\n private clients: Set<WebSocket> = new Set();\n private browser: BrowserManager;\n private port: number;\n private isScreencasting: boolean = false;\n\n constructor(browser: BrowserManager, port: number = 9223) {\n this.browser = browser;\n this.port = port;\n }\n\n /**\n * Start the WebSocket server\n */\n start(): Promise<void> {\n return new Promise((resolve, reject) => {\n try {\n this.wss = new WebSocketServer({\n port: this.port,\n // Security: Reject cross-origin WebSocket connections from untrusted origins.\n // This prevents malicious web pages from connecting and injecting input events.\n // Localhost origins are allowed so browser-based stream viewers can connect.\n verifyClient: (info: {\n origin: string;\n secure: boolean;\n req: import('http').IncomingMessage;\n }) => {\n if (isAllowedOrigin(info.origin)) {\n return true;\n }\n console.log(`[StreamServer] Rejected connection from origin: ${info.origin}`);\n return false;\n },\n });\n\n this.wss.on('connection', (ws) => {\n this.handleConnection(ws);\n });\n\n this.wss.on('error', (error) => {\n console.error('[StreamServer] WebSocket error:', error);\n reject(error);\n });\n\n this.wss.on('listening', () => {\n console.log(`[StreamServer] Listening on port ${this.port}`);\n\n // Set up the screencast frame callback\n setScreencastFrameCallback((frame) => {\n this.broadcastFrame(frame);\n });\n\n resolve();\n });\n } catch (error) {\n reject(error);\n }\n });\n }\n\n /**\n * Stop the WebSocket server\n */\n async stop(): Promise<void> {\n // Stop screencasting\n if (this.isScreencasting) {\n await this.stopScreencast();\n }\n\n // Clear the callback\n setScreencastFrameCallback(null);\n\n // Close all clients\n for (const client of this.clients) {\n client.close();\n }\n this.clients.clear();\n\n // Close the server\n if (this.wss) {\n return new Promise((resolve) => {\n this.wss!.close(() => {\n this.wss = null;\n resolve();\n });\n });\n }\n }\n\n /**\n * Handle a new WebSocket connection\n */\n private handleConnection(ws: WebSocket): void {\n console.log('[StreamServer] Client connected');\n this.clients.add(ws);\n\n // Send initial status\n this.sendStatus(ws);\n\n // Start screencasting if this is the first client\n if (this.clients.size === 1 && !this.isScreencasting) {\n this.startScreencast().catch((error) => {\n console.error('[StreamServer] Failed to start screencast:', error);\n this.sendError(ws, error.message);\n });\n }\n\n // Handle messages from client\n ws.on('message', (data) => {\n try {\n const message = JSON.parse(data.toString()) as StreamMessage;\n this.handleMessage(message, ws);\n } catch (error) {\n console.error('[StreamServer] Failed to parse message:', error);\n }\n });\n\n // Handle client disconnect\n ws.on('close', () => {\n console.log('[StreamServer] Client disconnected');\n this.clients.delete(ws);\n\n // Stop screencasting if no more clients\n if (this.clients.size === 0 && this.isScreencasting) {\n this.stopScreencast().catch((error) => {\n console.error('[StreamServer] Failed to stop screencast:', error);\n });\n }\n });\n\n ws.on('error', (error) => {\n console.error('[StreamServer] Client error:', error);\n this.clients.delete(ws);\n });\n }\n\n /**\n * Handle incoming messages from clients\n */\n private async handleMessage(message: StreamMessage, ws: WebSocket): Promise<void> {\n try {\n switch (message.type) {\n case 'input_mouse':\n await this.browser.injectMouseEvent({\n type: message.eventType,\n x: message.x,\n y: message.y,\n button: message.button,\n clickCount: message.clickCount,\n deltaX: message.deltaX,\n deltaY: message.deltaY,\n modifiers: message.modifiers,\n });\n break;\n\n case 'input_keyboard':\n await this.browser.injectKeyboardEvent({\n type: message.eventType,\n key: message.key,\n code: message.code,\n text: message.text,\n modifiers: message.modifiers,\n });\n break;\n\n case 'input_touch':\n await this.browser.injectTouchEvent({\n type: message.eventType,\n touchPoints: message.touchPoints,\n modifiers: message.modifiers,\n });\n break;\n\n case 'status':\n // Client is requesting status\n this.sendStatus(ws);\n break;\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n this.sendError(ws, errorMessage);\n }\n }\n\n /**\n * Broadcast a frame to all connected clients\n */\n private broadcastFrame(frame: ScreencastFrame): void {\n const message: FrameMessage = {\n type: 'frame',\n data: frame.data,\n metadata: frame.metadata,\n };\n\n const payload = JSON.stringify(message);\n\n for (const client of this.clients) {\n if (client.readyState === WebSocket.OPEN) {\n client.send(payload);\n }\n }\n }\n\n /**\n * Send status to a client\n */\n private sendStatus(ws: WebSocket): void {\n let viewportWidth: number | undefined;\n let viewportHeight: number | undefined;\n\n try {\n const page = this.browser.getPage();\n const viewport = page.viewportSize();\n viewportWidth = viewport?.width;\n viewportHeight = viewport?.height;\n } catch {\n // Browser not launched yet\n }\n\n const message: StatusMessage = {\n type: 'status',\n connected: true,\n screencasting: this.isScreencasting,\n viewportWidth,\n viewportHeight,\n };\n\n if (ws.readyState === WebSocket.OPEN) {\n ws.send(JSON.stringify(message));\n }\n }\n\n /**\n * Send an error to a client\n */\n private sendError(ws: WebSocket, errorMessage: string): void {\n const message: ErrorMessage = {\n type: 'error',\n message: errorMessage,\n };\n\n if (ws.readyState === WebSocket.OPEN) {\n ws.send(JSON.stringify(message));\n }\n }\n\n /**\n * Start screencasting\n */\n private async startScreencast(): Promise<void> {\n // Set flag immediately to prevent race conditions with concurrent calls\n if (this.isScreencasting) return;\n this.isScreencasting = true;\n\n try {\n // Check if browser is launched\n if (!this.browser.isLaunched()) {\n throw new Error('Browser not launched');\n }\n\n await this.browser.startScreencast((frame) => this.broadcastFrame(frame), {\n format: 'jpeg',\n quality: 80,\n maxWidth: 1280,\n maxHeight: 720,\n everyNthFrame: 1,\n });\n\n // Notify all clients\n for (const client of this.clients) {\n this.sendStatus(client);\n }\n } catch (error) {\n // Reset flag on failure so caller can retry\n this.isScreencasting = false;\n throw error;\n }\n }\n\n /**\n * Stop screencasting\n */\n private async stopScreencast(): Promise<void> {\n if (!this.isScreencasting) return;\n\n await this.browser.stopScreencast();\n this.isScreencasting = false;\n\n // Notify all clients\n for (const client of this.clients) {\n this.sendStatus(client);\n }\n }\n\n /**\n * Get the port the server is running on\n */\n getPort(): number {\n return this.port;\n }\n\n /**\n * Get the number of connected clients\n */\n getClientCount(): number {\n return this.clients.size;\n }\n}\n"],"mappings":"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A;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAUM,SAAS,aAAa,OAA4B;AAEvD,M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","names":["path","os","path","os","import_node_fs","import_node_path","import_node_os","devices","writeFileSync","mkdirSync","path","INTERACTIVE_ROLES","import_node_fs","import_node_path","path","successResponse","errorResponse","devices","devices","response"]}
|
|
1
|
+
{"version":3,"sources":["../src/daemon.ts","../src/browser.ts","../src/snapshot.ts","../src/taxtree.ts","../src/ios-manager.ts","../src/protocol.ts","../src/actions.ts","../src/ios-actions.ts","../src/stream-server.ts"],"sourcesContent":["import * as net from 'net';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { BrowserManager } from './browser.js';\nimport { IOSManager } from './ios-manager.js';\nimport { parseCommand, serializeResponse, errorResponse } from './protocol.js';\nimport { executeCommand } from './actions.js';\nimport { executeIOSCommand } from './ios-actions.js';\nimport { StreamServer } from './stream-server.js';\n\n// Manager type - either desktop browser or iOS\ntype Manager = BrowserManager | IOSManager;\n\n// Platform detection\nconst isWindows = process.platform === 'win32';\n\n// Session support - each session gets its own socket/pid\nlet currentSession = process.env.AGENT_BROWSER_SESSION || 'default';\n\n// Stream server for browser preview\nlet streamServer: StreamServer | null = null;\n\n// Default stream port (can be overridden with AGENT_BROWSER_STREAM_PORT)\nconst _DEFAULT_STREAM_PORT = 9223;\n\n/**\n * Set the current session\n */\nexport function setSession(session: string): void {\n currentSession = session;\n}\n\n/**\n * Get the current session\n */\nexport function getSession(): string {\n return currentSession;\n}\n\n/**\n * Get port number for TCP mode (Windows)\n * Uses a hash of the session name to get a consistent port\n */\nfunction getPortForSession(session: string): number {\n let hash = 0;\n for (let i = 0; i < session.length; i++) {\n hash = (hash << 5) - hash + session.charCodeAt(i);\n hash |= 0;\n }\n // Port range 49152-65535 (dynamic/private ports)\n return 49152 + (Math.abs(hash) % 16383);\n}\n\n/**\n * Get the base directory for socket/pid files.\n * Priority: AGENT_BROWSER_SOCKET_DIR > XDG_RUNTIME_DIR > ~/.agent-browser > tmpdir\n */\nexport function getAppDir(): string {\n // 1. XDG_RUNTIME_DIR (Linux standard)\n if (process.env.XDG_RUNTIME_DIR) {\n return path.join(process.env.XDG_RUNTIME_DIR, 'agent-browser');\n }\n\n // 2. Home directory fallback (like Docker Desktop's ~/.docker/run/)\n const homeDir = os.homedir();\n if (homeDir) {\n return path.join(homeDir, '.agent-browser');\n }\n\n // 3. Last resort: temp dir\n return path.join(os.tmpdir(), 'agent-browser');\n}\n\nexport function getSocketDir(): string {\n // Allow explicit override for socket directory\n if (process.env.AGENT_BROWSER_SOCKET_DIR) {\n return process.env.AGENT_BROWSER_SOCKET_DIR;\n }\n return getAppDir();\n}\n\n/**\n * Get the socket path for the current session (Unix) or port (Windows)\n */\nexport function getSocketPath(session?: string): string {\n const sess = session ?? currentSession;\n if (isWindows) {\n return String(getPortForSession(sess));\n }\n return path.join(getSocketDir(), `${sess}.sock`);\n}\n\n/**\n * Get the port file path for Windows (stores the port number)\n */\nexport function getPortFile(session?: string): string {\n const sess = session ?? currentSession;\n return path.join(getSocketDir(), `${sess}.port`);\n}\n\n/**\n * Get the PID file path for the current session\n */\nexport function getPidFile(session?: string): string {\n const sess = session ?? currentSession;\n return path.join(getSocketDir(), `${sess}.pid`);\n}\n\n/**\n * Check if daemon is running for the current session\n */\nexport function isDaemonRunning(session?: string): boolean {\n const pidFile = getPidFile(session);\n if (!fs.existsSync(pidFile)) return false;\n\n try {\n const pid = parseInt(fs.readFileSync(pidFile, 'utf8').trim(), 10);\n // Check if process exists (works on both Unix and Windows)\n process.kill(pid, 0);\n return true;\n } catch {\n // Process doesn't exist, clean up stale files\n cleanupSocket(session);\n return false;\n }\n}\n\n/**\n * Get connection info for the current session\n * Returns { type: 'unix', path: string } or { type: 'tcp', port: number }\n */\nexport function getConnectionInfo(\n session?: string\n): { type: 'unix'; path: string } | { type: 'tcp'; port: number } {\n const sess = session ?? currentSession;\n if (isWindows) {\n return { type: 'tcp', port: getPortForSession(sess) };\n }\n return { type: 'unix', path: path.join(getSocketDir(), `${sess}.sock`) };\n}\n\n/**\n * Clean up socket and PID file for the current session\n */\nexport function cleanupSocket(session?: string): void {\n const pidFile = getPidFile(session);\n const streamPortFile = getStreamPortFile(session);\n try {\n if (fs.existsSync(pidFile)) fs.unlinkSync(pidFile);\n if (fs.existsSync(streamPortFile)) fs.unlinkSync(streamPortFile);\n if (isWindows) {\n const portFile = getPortFile(session);\n if (fs.existsSync(portFile)) fs.unlinkSync(portFile);\n } else {\n const socketPath = getSocketPath(session);\n if (fs.existsSync(socketPath)) fs.unlinkSync(socketPath);\n }\n } catch {\n // Ignore cleanup errors\n }\n}\n\n/**\n * Get the stream port file path\n */\nexport function getStreamPortFile(session?: string): string {\n const sess = session ?? currentSession;\n return path.join(getSocketDir(), `${sess}.stream`);\n}\n\n/**\n * Start the daemon server\n * @param options.streamPort Port for WebSocket stream server (0 to disable)\n * @param options.provider Provider type ('ios' for iOS Simulator, undefined for desktop)\n */\nexport async function startDaemon(options?: {\n streamPort?: number;\n provider?: string;\n}): Promise<void> {\n // Ensure socket directory exists\n const socketDir = getSocketDir();\n if (!fs.existsSync(socketDir)) {\n fs.mkdirSync(socketDir, { recursive: true });\n }\n\n // Clean up any stale socket\n cleanupSocket();\n\n // Determine provider from options or environment\n const provider = options?.provider ?? process.env.AGENT_BROWSER_PROVIDER;\n const isIOS = provider === 'ios';\n\n // Create appropriate manager\n const manager: Manager = isIOS ? new IOSManager() : new BrowserManager();\n let shuttingDown = false;\n\n // Start stream server if port is specified (or use default if env var is set)\n // Note: Stream server only works with BrowserManager (desktop), not iOS\n const streamPort =\n options?.streamPort ??\n (process.env.AGENT_BROWSER_STREAM_PORT\n ? parseInt(process.env.AGENT_BROWSER_STREAM_PORT, 10)\n : 0);\n\n if (streamPort > 0 && !isIOS && manager instanceof BrowserManager) {\n streamServer = new StreamServer(manager, streamPort);\n await streamServer.start();\n\n // Write stream port to file for clients to discover\n const streamPortFile = getStreamPortFile();\n fs.writeFileSync(streamPortFile, streamPort.toString());\n }\n\n const server = net.createServer((socket) => {\n let buffer = '';\n let httpChecked = false;\n\n socket.on('data', async (data) => {\n buffer += data.toString();\n\n // Security: Detect and reject HTTP requests to prevent cross-origin attacks.\n // Browsers using fetch() must send HTTP headers (e.g., \"POST / HTTP/1.1\"),\n // while legitimate clients send raw JSON starting with \"{\".\n if (!httpChecked) {\n httpChecked = true;\n const trimmed = buffer.trimStart();\n if (/^(GET|POST|PUT|DELETE|HEAD|OPTIONS|PATCH|CONNECT|TRACE)\\s/i.test(trimmed)) {\n socket.destroy();\n return;\n }\n }\n\n // Process complete lines\n while (buffer.includes('\\n')) {\n const newlineIdx = buffer.indexOf('\\n');\n const line = buffer.substring(0, newlineIdx);\n buffer = buffer.substring(newlineIdx + 1);\n\n if (!line.trim()) continue;\n\n try {\n const parseResult = parseCommand(line);\n\n if (!parseResult.success) {\n const resp = errorResponse(parseResult.id ?? 'unknown', parseResult.error);\n socket.write(serializeResponse(resp) + '\\n');\n continue;\n }\n\n // Handle device_list specially - it works without a session and always uses IOSManager\n if (parseResult.command.action === 'device_list') {\n const iosManager = new IOSManager();\n try {\n const devices = await iosManager.listAllDevices();\n const response = {\n id: parseResult.command.id,\n success: true as const,\n data: { devices },\n };\n socket.write(serializeResponse(response) + '\\n');\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n socket.write(\n serializeResponse(errorResponse(parseResult.command.id, message)) + '\\n'\n );\n }\n continue;\n }\n\n // Auto-launch if not already launched and this isn't a launch/close command\n if (\n !manager.isLaunched() &&\n parseResult.command.action !== 'launch' &&\n parseResult.command.action !== 'close'\n ) {\n if (isIOS && manager instanceof IOSManager) {\n // Auto-launch iOS Safari\n // Check for device in command first (for reused daemons), then fall back to env vars\n const cmd = parseResult.command as { iosDevice?: string };\n const iosDevice = cmd.iosDevice || process.env.AGENT_BROWSER_IOS_DEVICE;\n await manager.launch({\n device: iosDevice,\n udid: process.env.AGENT_BROWSER_IOS_UDID,\n });\n } else if (manager instanceof BrowserManager) {\n // Auto-launch desktop browser\n const extensions = process.env.AGENT_BROWSER_EXTENSIONS\n ? process.env.AGENT_BROWSER_EXTENSIONS.split(',')\n .map((p) => p.trim())\n .filter(Boolean)\n : undefined;\n\n // Parse args from env (comma or newline separated)\n const argsEnv = process.env.AGENT_BROWSER_ARGS;\n const args = argsEnv\n ? argsEnv\n .split(/[,\\n]/)\n .map((a) => a.trim())\n .filter((a) => a.length > 0)\n : undefined;\n\n // Parse proxy from env\n const proxyServer = process.env.AGENT_BROWSER_PROXY;\n const proxyBypass = process.env.AGENT_BROWSER_PROXY_BYPASS;\n const proxy = proxyServer\n ? {\n server: proxyServer,\n ...(proxyBypass && { bypass: proxyBypass }),\n }\n : undefined;\n\n const ignoreHTTPSErrors = process.env.AGENT_BROWSER_IGNORE_HTTPS_ERRORS === '1';\n const allowFileAccess = process.env.AGENT_BROWSER_ALLOW_FILE_ACCESS === '1';\n await manager.launch({\n id: 'auto',\n action: 'launch' as const,\n headless: process.env.AGENT_BROWSER_HEADED !== '1',\n executablePath: process.env.AGENT_BROWSER_EXECUTABLE_PATH,\n extensions: extensions,\n profile: process.env.AGENT_BROWSER_PROFILE,\n storageState: process.env.AGENT_BROWSER_STATE,\n args,\n userAgent: process.env.AGENT_BROWSER_USER_AGENT,\n proxy,\n ignoreHTTPSErrors: ignoreHTTPSErrors,\n allowFileAccess: allowFileAccess,\n cdpUrl: process.env.AGENT_BROWSER_CDP_URL,\n });\n }\n }\n\n // Handle close command specially - shuts down daemon\n if (parseResult.command.action === 'close') {\n const response =\n isIOS && manager instanceof IOSManager\n ? await executeIOSCommand(parseResult.command, manager)\n : await executeCommand(parseResult.command, manager as BrowserManager);\n socket.write(serializeResponse(response) + '\\n');\n\n if (!shuttingDown) {\n shuttingDown = true;\n setTimeout(() => {\n server.close();\n cleanupSocket();\n process.exit(0);\n }, 100);\n }\n return;\n }\n\n // Execute command with appropriate handler\n const response =\n isIOS && manager instanceof IOSManager\n ? await executeIOSCommand(parseResult.command, manager)\n : await executeCommand(parseResult.command, manager as BrowserManager);\n socket.write(serializeResponse(response) + '\\n');\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n socket.write(serializeResponse(errorResponse('error', message)) + '\\n');\n }\n }\n });\n\n socket.on('error', () => {\n // Client disconnected, ignore\n });\n });\n\n const pidFile = getPidFile();\n\n // Write PID file before listening\n fs.writeFileSync(pidFile, process.pid.toString());\n\n // Check for explicit TCP port override (e.g. for Docker)\n const tcpPortEnv = process.env.AGENT_BROWSER_TCP_PORT;\n\n if (tcpPortEnv) {\n const port = parseInt(tcpPortEnv, 10);\n server.listen(port, '0.0.0.0', () => {\n console.log(`Daemon listening on TCP 0.0.0.0:${port}`);\n });\n } else if (isWindows) {\n // Windows: use TCP socket on localhost\n const port = getPortForSession(currentSession);\n const portFile = getPortFile();\n fs.writeFileSync(portFile, port.toString());\n server.listen(port, '127.0.0.1', () => {\n // Daemon is ready on TCP port\n });\n } else {\n // Unix: use Unix domain socket\n const socketPath = getSocketPath();\n server.listen(socketPath, () => {\n // Daemon is ready\n });\n }\n\n server.on('error', (err) => {\n console.error('Server error:', err);\n cleanupSocket();\n process.exit(1);\n });\n\n // Handle shutdown signals\n const shutdown = async () => {\n if (shuttingDown) return;\n shuttingDown = true;\n\n // Stop stream server if running\n if (streamServer) {\n await streamServer.stop();\n streamServer = null;\n // Clean up stream port file\n const streamPortFile = getStreamPortFile();\n try {\n if (fs.existsSync(streamPortFile)) fs.unlinkSync(streamPortFile);\n } catch {\n // Ignore cleanup errors\n }\n }\n\n await manager.close();\n server.close();\n cleanupSocket();\n process.exit(0);\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n process.on('SIGHUP', shutdown);\n\n // Handle unexpected errors - always cleanup\n process.on('uncaughtException', (err) => {\n console.error('Uncaught exception:', err);\n cleanupSocket();\n process.exit(1);\n });\n\n process.on('unhandledRejection', (reason) => {\n console.error('Unhandled rejection:', reason);\n cleanupSocket();\n process.exit(1);\n });\n\n // Cleanup on normal exit\n process.on('exit', () => {\n cleanupSocket();\n });\n\n // Keep process alive\n process.stdin.resume();\n}\n\n// Run daemon if this is the entry point\nif (process.argv[1]?.endsWith('daemon.js') || process.env.AGENT_BROWSER_DAEMON === '1') {\n startDaemon().catch((err) => {\n console.error('Daemon error:', err);\n cleanupSocket();\n process.exit(1);\n });\n}\n","import {\n chromium,\n firefox,\n webkit,\n devices,\n type Browser,\n type BrowserContext,\n type Page,\n type Frame,\n type Dialog,\n type Request,\n type Route,\n type Locator,\n type CDPSession,\n type Video,\n} from 'playwright-core';\nimport path from 'node:path';\nimport os from 'node:os';\nimport { existsSync, mkdirSync, rmSync } from 'node:fs';\nimport type { LaunchCommand } from './types.js';\nimport { type RefMap, type EnhancedSnapshot, parseRef } from './snapshot.js';\nimport { getDualModeSnapshot } from './taxtree.js';\n\n// Screencast frame data from CDP\nexport interface ScreencastFrame {\n data: string; // base64 encoded image\n metadata: {\n offsetTop: number;\n pageScaleFactor: number;\n deviceWidth: number;\n deviceHeight: number;\n scrollOffsetX: number;\n scrollOffsetY: number;\n timestamp?: number;\n };\n sessionId: number;\n}\n\n// Screencast options\nexport interface ScreencastOptions {\n format?: 'jpeg' | 'png';\n quality?: number; // 0-100, only for jpeg\n maxWidth?: number;\n maxHeight?: number;\n everyNthFrame?: number;\n}\n\ninterface TrackedRequest {\n url: string;\n method: string;\n headers: Record<string, string>;\n timestamp: number;\n resourceType: string;\n}\n\ninterface ConsoleMessage {\n type: string;\n text: string;\n timestamp: number;\n}\n\ninterface PageError {\n message: string;\n timestamp: number;\n}\n\n/**\n * Manages the Playwright browser lifecycle with multiple tabs/windows\n */\nexport class BrowserManager {\n private browser: Browser | null = null;\n private cdpEndpoint: string | null = null; // stores port number or full URL\n private isPersistentContext: boolean = false;\n private browserbaseSessionId: string | null = null;\n private browserbaseApiKey: string | null = null;\n private browserUseSessionId: string | null = null;\n private browserUseApiKey: string | null = null;\n private kernelSessionId: string | null = null;\n private kernelApiKey: string | null = null;\n private contexts: BrowserContext[] = [];\n private pages: Page[] = [];\n private activePageIndex: number = 0;\n private activeFrame: Frame | null = null;\n private dialogHandler: ((dialog: Dialog) => Promise<void>) | null = null;\n private trackedRequests: TrackedRequest[] = [];\n private routes: Map<string, (route: Route) => Promise<void>> = new Map();\n private consoleMessages: ConsoleMessage[] = [];\n private pageErrors: PageError[] = [];\n private isRecordingHar: boolean = false;\n private refMap: RefMap = {};\n private lastSnapshot: string = '';\n private scopedHeaderRoutes: Map<string, (route: Route) => Promise<void>> = new Map();\n\n // CDP session for screencast and input injection\n private cdpSession: CDPSession | null = null;\n private screencastActive: boolean = false;\n private screencastSessionId: number = 0;\n private frameCallback: ((frame: ScreencastFrame) => void) | null = null;\n private screencastFrameHandler: ((params: any) => void) | null = null;\n\n // Video recording (Playwright native)\n private recordingContext: BrowserContext | null = null;\n private recordingPage: Page | null = null;\n private recordingOutputPath: string = '';\n private recordingTempDir: string = '';\n\n /**\n * Check if browser is launched\n */\n isLaunched(): boolean {\n return this.browser !== null || this.isPersistentContext;\n }\n\n /**\n * Get enhanced snapshot with refs and cache the ref map\n */\n async getSnapshot(options?: {\n interactive?: boolean;\n cursor?: boolean;\n maxDepth?: number;\n compact?: boolean;\n selector?: string;\n }): Promise<EnhancedSnapshot> {\n const page = this.getPage();\n // Use DualMode AXTree (WootzApp) instead of Playwright's ariaSnapshot\n const snapshot = await getDualModeSnapshot(page, options);\n this.refMap = snapshot.refs;\n this.lastSnapshot = snapshot.tree;\n return snapshot;\n }\n\n /**\n * Get the cached ref map from last snapshot\n */\n getRefMap(): RefMap {\n return this.refMap;\n }\n\n /**\n * Get a locator from a ref (e.g., \"e1\", \"@e1\", \"ref=e1\")\n * Returns null if ref doesn't exist or is invalid\n */\n getLocatorFromRef(refArg: string): Locator | null {\n const ref = parseRef(refArg);\n if (!ref) return null;\n\n const refData = this.refMap[ref];\n if (!refData) return null;\n\n const page = this.getPage();\n\n // Check if this is a cursor-interactive element (uses CSS selector, not ARIA role)\n // These have pseudo-roles 'clickable' or 'focusable' and a CSS selector\n if (refData.role === 'clickable' || refData.role === 'focusable') {\n // The selector is a CSS selector, use it directly\n return page.locator(refData.selector);\n }\n\n // Build locator with exact: true to avoid substring matches\n let locator: Locator;\n if (refData.name) {\n locator = page.getByRole(refData.role as any, { name: refData.name, exact: true });\n } else {\n locator = page.getByRole(refData.role as any);\n }\n\n // If an nth index is stored (for disambiguation), use it\n if (refData.nth !== undefined) {\n locator = locator.nth(refData.nth);\n }\n\n return locator;\n }\n\n /**\n * Check if a selector looks like a ref\n */\n isRef(selector: string): boolean {\n return parseRef(selector) !== null;\n }\n\n /**\n * Get raw ref data (including bounds/nodeId)\n */\n getRefData(refArg: string): RefMap[string] | null {\n const ref = parseRef(refArg);\n if (!ref) return null;\n return this.refMap[ref] || null;\n }\n\n /**\n * Get locator - supports both refs and regular selectors\n */\n getLocator(selectorOrRef: string): Locator {\n // Check if it's a ref first\n const locator = this.getLocatorFromRef(selectorOrRef);\n if (locator) return locator;\n\n // Otherwise treat as regular selector\n const page = this.getPage();\n return page.locator(selectorOrRef);\n }\n\n /**\n * Get the current active page, throws if not launched\n */\n getPage(): Page {\n if (this.pages.length === 0) {\n throw new Error('Browser not launched. Call launch first.');\n }\n return this.pages[this.activePageIndex];\n }\n\n /**\n * Get the current frame (or page's main frame if no frame is selected)\n */\n getFrame(): Frame {\n if (this.activeFrame) {\n return this.activeFrame;\n }\n return this.getPage().mainFrame();\n }\n\n /**\n * Switch to a frame by selector, name, or URL\n */\n async switchToFrame(options: { selector?: string; name?: string; url?: string }): Promise<void> {\n const page = this.getPage();\n\n if (options.selector) {\n const frameElement = await page.$(options.selector);\n if (!frameElement) {\n throw new Error(`Frame not found: ${options.selector}`);\n }\n const frame = await frameElement.contentFrame();\n if (!frame) {\n throw new Error(`Element is not a frame: ${options.selector}`);\n }\n this.activeFrame = frame;\n } else if (options.name) {\n const frame = page.frame({ name: options.name });\n if (!frame) {\n throw new Error(`Frame not found with name: ${options.name}`);\n }\n this.activeFrame = frame;\n } else if (options.url) {\n const frame = page.frame({ url: options.url });\n if (!frame) {\n throw new Error(`Frame not found with URL: ${options.url}`);\n }\n this.activeFrame = frame;\n }\n }\n\n /**\n * Switch back to main frame\n */\n switchToMainFrame(): void {\n this.activeFrame = null;\n }\n\n /**\n * Set up dialog handler\n */\n setDialogHandler(response: 'accept' | 'dismiss', promptText?: string): void {\n const page = this.getPage();\n\n // Remove existing handler if any\n if (this.dialogHandler) {\n page.removeListener('dialog', this.dialogHandler);\n }\n\n this.dialogHandler = async (dialog: Dialog) => {\n if (response === 'accept') {\n await dialog.accept(promptText);\n } else {\n await dialog.dismiss();\n }\n };\n\n page.on('dialog', this.dialogHandler);\n }\n\n /**\n * Clear dialog handler\n */\n clearDialogHandler(): void {\n if (this.dialogHandler) {\n const page = this.getPage();\n page.removeListener('dialog', this.dialogHandler);\n this.dialogHandler = null;\n }\n }\n\n /**\n * Start tracking requests\n */\n startRequestTracking(): void {\n const page = this.getPage();\n page.on('request', (request: Request) => {\n this.trackedRequests.push({\n url: request.url(),\n method: request.method(),\n headers: request.headers(),\n timestamp: Date.now(),\n resourceType: request.resourceType(),\n });\n });\n }\n\n /**\n * Get tracked requests\n */\n getRequests(filter?: string): TrackedRequest[] {\n if (filter) {\n return this.trackedRequests.filter((r) => r.url.includes(filter));\n }\n return this.trackedRequests;\n }\n\n /**\n * Clear tracked requests\n */\n clearRequests(): void {\n this.trackedRequests = [];\n }\n\n /**\n * Add a route to intercept requests\n */\n async addRoute(\n url: string,\n options: {\n response?: {\n status?: number;\n body?: string;\n contentType?: string;\n headers?: Record<string, string>;\n };\n abort?: boolean;\n }\n ): Promise<void> {\n const page = this.getPage();\n\n const handler = async (route: Route) => {\n if (options.abort) {\n await route.abort();\n } else if (options.response) {\n await route.fulfill({\n status: options.response.status ?? 200,\n body: options.response.body ?? '',\n contentType: options.response.contentType ?? 'text/plain',\n headers: options.response.headers,\n });\n } else {\n await route.continue();\n }\n };\n\n this.routes.set(url, handler);\n await page.route(url, handler);\n }\n\n /**\n * Remove a route\n */\n async removeRoute(url?: string): Promise<void> {\n const page = this.getPage();\n\n if (url) {\n const handler = this.routes.get(url);\n if (handler) {\n await page.unroute(url, handler);\n this.routes.delete(url);\n }\n } else {\n // Remove all routes\n for (const [routeUrl, handler] of this.routes) {\n await page.unroute(routeUrl, handler);\n }\n this.routes.clear();\n }\n }\n\n /**\n * Set geolocation\n */\n async setGeolocation(latitude: number, longitude: number, accuracy?: number): Promise<void> {\n const context = this.contexts[0];\n if (context) {\n await context.setGeolocation({ latitude, longitude, accuracy });\n }\n }\n\n /**\n * Set permissions\n */\n async setPermissions(permissions: string[], grant: boolean): Promise<void> {\n const context = this.contexts[0];\n if (context) {\n if (grant) {\n await context.grantPermissions(permissions);\n } else {\n await context.clearPermissions();\n }\n }\n }\n\n /**\n * Set viewport\n */\n async setViewport(width: number, height: number): Promise<void> {\n const page = this.getPage();\n await page.setViewportSize({ width, height });\n }\n\n /**\n * Set device scale factor (devicePixelRatio) via CDP\n * This sets window.devicePixelRatio which affects how the page renders and responds to media queries\n *\n * Note: When using CDP to set deviceScaleFactor, screenshots will be at logical pixel dimensions\n * (viewport size), not physical pixel dimensions (viewport × scale). This is a Playwright limitation\n * when using CDP emulation on existing contexts. For true HiDPI screenshots with physical pixels,\n * deviceScaleFactor must be set at context creation time.\n *\n * Must be called after setViewport to work correctly\n */\n async setDeviceScaleFactor(\n deviceScaleFactor: number,\n width: number,\n height: number,\n mobile: boolean = false\n ): Promise<void> {\n const cdp = await this.getCDPSession();\n await cdp.send('Emulation.setDeviceMetricsOverride', {\n width,\n height,\n deviceScaleFactor,\n mobile,\n });\n }\n\n /**\n * Clear device metrics override to restore default devicePixelRatio\n */\n async clearDeviceMetricsOverride(): Promise<void> {\n const cdp = await this.getCDPSession();\n await cdp.send('Emulation.clearDeviceMetricsOverride');\n }\n\n /**\n * Get device descriptor\n */\n getDevice(deviceName: string): (typeof devices)[keyof typeof devices] | undefined {\n return devices[deviceName as keyof typeof devices];\n }\n\n /**\n * List available devices\n */\n listDevices(): string[] {\n return Object.keys(devices);\n }\n\n /**\n * Start console message tracking\n */\n startConsoleTracking(): void {\n const page = this.getPage();\n page.on('console', (msg) => {\n this.consoleMessages.push({\n type: msg.type(),\n text: msg.text(),\n timestamp: Date.now(),\n });\n });\n }\n\n /**\n * Get console messages\n */\n getConsoleMessages(): ConsoleMessage[] {\n return this.consoleMessages;\n }\n\n /**\n * Clear console messages\n */\n clearConsoleMessages(): void {\n this.consoleMessages = [];\n }\n\n /**\n * Start error tracking\n */\n startErrorTracking(): void {\n const page = this.getPage();\n page.on('pageerror', (error) => {\n this.pageErrors.push({\n message: error.message,\n timestamp: Date.now(),\n });\n });\n }\n\n /**\n * Get page errors\n */\n getPageErrors(): PageError[] {\n return this.pageErrors;\n }\n\n /**\n * Clear page errors\n */\n clearPageErrors(): void {\n this.pageErrors = [];\n }\n\n /**\n * Start HAR recording\n */\n async startHarRecording(): Promise<void> {\n // HAR is started at context level, flag for tracking\n this.isRecordingHar = true;\n }\n\n /**\n * Check if HAR recording\n */\n isHarRecording(): boolean {\n return this.isRecordingHar;\n }\n\n /**\n * Set offline mode\n */\n async setOffline(offline: boolean): Promise<void> {\n const context = this.contexts[0];\n if (context) {\n await context.setOffline(offline);\n }\n }\n\n /**\n * Set extra HTTP headers (global - all requests)\n */\n async setExtraHeaders(headers: Record<string, string>): Promise<void> {\n const context = this.contexts[0];\n if (context) {\n await context.setExtraHTTPHeaders(headers);\n }\n }\n\n /**\n * Set scoped HTTP headers (only for requests matching the origin)\n * Uses route interception to add headers only to matching requests\n */\n async setScopedHeaders(origin: string, headers: Record<string, string>): Promise<void> {\n const page = this.getPage();\n\n // Build URL pattern from origin (e.g., \"api.example.com\" -> \"**://api.example.com/**\")\n // Handle both full URLs and just hostnames\n let urlPattern: string;\n try {\n const url = new URL(origin.startsWith('http') ? origin : `https://${origin}`);\n // Match any protocol, the host, and any path\n urlPattern = `**://${url.host}/**`;\n } catch {\n // If parsing fails, treat as hostname pattern\n urlPattern = `**://${origin}/**`;\n }\n\n // Remove existing route for this origin if any\n const existingHandler = this.scopedHeaderRoutes.get(urlPattern);\n if (existingHandler) {\n await page.unroute(urlPattern, existingHandler);\n }\n\n // Create handler that adds headers to matching requests\n const handler = async (route: Route) => {\n const requestHeaders = route.request().headers();\n await route.continue({\n headers: {\n ...requestHeaders,\n ...headers,\n },\n });\n };\n\n // Store and register the route\n this.scopedHeaderRoutes.set(urlPattern, handler);\n await page.route(urlPattern, handler);\n }\n\n /**\n * Clear scoped headers for an origin (or all if no origin specified)\n */\n async clearScopedHeaders(origin?: string): Promise<void> {\n const page = this.getPage();\n\n if (origin) {\n let urlPattern: string;\n try {\n const url = new URL(origin.startsWith('http') ? origin : `https://${origin}`);\n urlPattern = `**://${url.host}/**`;\n } catch {\n urlPattern = `**://${origin}/**`;\n }\n\n const handler = this.scopedHeaderRoutes.get(urlPattern);\n if (handler) {\n await page.unroute(urlPattern, handler);\n this.scopedHeaderRoutes.delete(urlPattern);\n }\n } else {\n // Clear all scoped header routes\n for (const [pattern, handler] of this.scopedHeaderRoutes) {\n await page.unroute(pattern, handler);\n }\n this.scopedHeaderRoutes.clear();\n }\n }\n\n /**\n * Start tracing\n */\n async startTracing(options: { screenshots?: boolean; snapshots?: boolean }): Promise<void> {\n const context = this.contexts[0];\n if (context) {\n await context.tracing.start({\n screenshots: options.screenshots ?? true,\n snapshots: options.snapshots ?? true,\n });\n }\n }\n\n /**\n * Stop tracing and save\n */\n async stopTracing(path: string): Promise<void> {\n const context = this.contexts[0];\n if (context) {\n await context.tracing.stop({ path });\n }\n }\n\n /**\n * Save storage state (cookies, localStorage, etc.)\n */\n async saveStorageState(path: string): Promise<void> {\n const context = this.contexts[0];\n if (context) {\n await context.storageState({ path });\n }\n }\n\n /**\n * Get all pages\n */\n getPages(): Page[] {\n return this.pages;\n }\n\n /**\n * Get current page index\n */\n getActiveIndex(): number {\n return this.activePageIndex;\n }\n\n /**\n * Get the current browser instance\n */\n getBrowser(): Browser | null {\n return this.browser;\n }\n\n /**\n * Check if an existing CDP connection is still alive\n * by verifying we can access browser contexts and that at least one has pages\n */\n private isCdpConnectionAlive(): boolean {\n if (!this.browser) return false;\n try {\n const contexts = this.browser.contexts();\n if (contexts.length === 0) return false;\n return contexts.some((context) => context.pages().length > 0);\n } catch {\n return false;\n }\n }\n\n /**\n * Check if CDP connection needs to be re-established\n */\n private needsCdpReconnect(cdpEndpoint: string): boolean {\n if (!this.browser?.isConnected()) return true;\n if (this.cdpEndpoint !== cdpEndpoint) return true;\n if (!this.isCdpConnectionAlive()) return true;\n return false;\n }\n\n /**\n * Close a Browserbase session via API\n */\n private async closeBrowserbaseSession(sessionId: string, apiKey: string): Promise<void> {\n await fetch(`https://api.browserbase.com/v1/sessions/${sessionId}`, {\n method: 'DELETE',\n headers: {\n 'X-BB-API-Key': apiKey,\n },\n });\n }\n\n /**\n * Close a Browser Use session via API\n */\n private async closeBrowserUseSession(sessionId: string, apiKey: string): Promise<void> {\n const response = await fetch(`https://api.browser-use.com/api/v2/browsers/${sessionId}`, {\n method: 'PATCH',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Browser-Use-API-Key': apiKey,\n },\n body: JSON.stringify({ action: 'stop' }),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to close Browser Use session: ${response.statusText}`);\n }\n }\n\n /**\n * Close a Kernel session via API\n */\n private async closeKernelSession(sessionId: string, apiKey: string): Promise<void> {\n const response = await fetch(`https://api.onkernel.com/browsers/${sessionId}`, {\n method: 'DELETE',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to close Kernel session: ${response.statusText}`);\n }\n }\n\n /**\n * Connect to Browserbase remote browser via CDP.\n * Requires BROWSERBASE_API_KEY and BROWSERBASE_PROJECT_ID environment variables.\n */\n private async connectToBrowserbase(): Promise<void> {\n const browserbaseApiKey = process.env.BROWSERBASE_API_KEY;\n const browserbaseProjectId = process.env.BROWSERBASE_PROJECT_ID;\n\n if (!browserbaseApiKey || !browserbaseProjectId) {\n throw new Error(\n 'BROWSERBASE_API_KEY and BROWSERBASE_PROJECT_ID are required when using browserbase as a provider'\n );\n }\n\n const response = await fetch('https://api.browserbase.com/v1/sessions', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-BB-API-Key': browserbaseApiKey,\n },\n body: JSON.stringify({\n projectId: browserbaseProjectId,\n }),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to create Browserbase session: ${response.statusText}`);\n }\n\n const session = (await response.json()) as { id: string; connectUrl: string };\n\n const browser = await chromium.connectOverCDP(session.connectUrl).catch(() => {\n throw new Error('Failed to connect to Browserbase session via CDP');\n });\n\n try {\n const contexts = browser.contexts();\n if (contexts.length === 0) {\n throw new Error('No browser context found in Browserbase session');\n }\n\n const context = contexts[0];\n const pages = context.pages();\n const page = pages[0] ?? (await context.newPage());\n\n this.browserbaseSessionId = session.id;\n this.browserbaseApiKey = browserbaseApiKey;\n this.browser = browser;\n context.setDefaultTimeout(10000);\n this.contexts.push(context);\n this.setupContextTracking(context);\n this.pages.push(page);\n this.activePageIndex = 0;\n this.setupPageTracking(page);\n } catch (error) {\n await this.closeBrowserbaseSession(session.id, browserbaseApiKey).catch((sessionError) => {\n console.error('Failed to close Browserbase session during cleanup:', sessionError);\n });\n throw error;\n }\n }\n\n /**\n * Find or create a Kernel profile by name.\n * Returns the profile object if successful.\n */\n private async findOrCreateKernelProfile(\n profileName: string,\n apiKey: string\n ): Promise<{ name: string }> {\n // First, try to get the existing profile\n const getResponse = await fetch(\n `https://api.onkernel.com/profiles/${encodeURIComponent(profileName)}`,\n {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n },\n }\n );\n\n if (getResponse.ok) {\n // Profile exists, return it\n return { name: profileName };\n }\n\n if (getResponse.status !== 404) {\n throw new Error(`Failed to check Kernel profile: ${getResponse.statusText}`);\n }\n\n // Profile doesn't exist, create it\n const createResponse = await fetch('https://api.onkernel.com/profiles', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({ name: profileName }),\n });\n\n if (!createResponse.ok) {\n throw new Error(`Failed to create Kernel profile: ${createResponse.statusText}`);\n }\n\n return { name: profileName };\n }\n\n /**\n * Connect to Kernel remote browser via CDP.\n * Requires KERNEL_API_KEY environment variable.\n */\n private async connectToKernel(): Promise<void> {\n const kernelApiKey = process.env.KERNEL_API_KEY;\n if (!kernelApiKey) {\n throw new Error('KERNEL_API_KEY is required when using kernel as a provider');\n }\n\n // Find or create profile if KERNEL_PROFILE_NAME is set\n const profileName = process.env.KERNEL_PROFILE_NAME;\n let profileConfig: { profile: { name: string; save_changes: boolean } } | undefined;\n\n if (profileName) {\n await this.findOrCreateKernelProfile(profileName, kernelApiKey);\n profileConfig = {\n profile: {\n name: profileName,\n save_changes: true, // Save cookies/state back to the profile when session ends\n },\n };\n }\n\n const response = await fetch('https://api.onkernel.com/browsers', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${kernelApiKey}`,\n },\n body: JSON.stringify({\n // Kernel browsers are headful by default with stealth mode available\n // The user can configure these via environment variables if needed\n headless: process.env.KERNEL_HEADLESS?.toLowerCase() === 'true',\n stealth: process.env.KERNEL_STEALTH?.toLowerCase() !== 'false', // Default to stealth mode\n timeout_seconds: parseInt(process.env.KERNEL_TIMEOUT_SECONDS || '300', 10),\n // Load and save to a profile if specified\n ...profileConfig,\n }),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to create Kernel session: ${response.statusText}`);\n }\n\n let session: { session_id: string; cdp_ws_url: string };\n try {\n session = (await response.json()) as { session_id: string; cdp_ws_url: string };\n } catch (error) {\n throw new Error(\n `Failed to parse Kernel session response: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n\n if (!session.session_id || !session.cdp_ws_url) {\n throw new Error(\n `Invalid Kernel session response: missing ${!session.session_id ? 'session_id' : 'cdp_ws_url'}`\n );\n }\n\n const browser = await chromium.connectOverCDP(session.cdp_ws_url).catch(() => {\n throw new Error('Failed to connect to Kernel session via CDP');\n });\n\n try {\n const contexts = browser.contexts();\n let context: BrowserContext;\n let page: Page;\n\n // Kernel browsers launch with a default context and page\n if (contexts.length === 0) {\n context = await browser.newContext();\n page = await context.newPage();\n } else {\n context = contexts[0];\n const pages = context.pages();\n page = pages[0] ?? (await context.newPage());\n }\n\n this.kernelSessionId = session.session_id;\n this.kernelApiKey = kernelApiKey;\n this.browser = browser;\n context.setDefaultTimeout(60000);\n this.contexts.push(context);\n this.pages.push(page);\n this.activePageIndex = 0;\n this.setupPageTracking(page);\n this.setupContextTracking(context);\n } catch (error) {\n await this.closeKernelSession(session.session_id, kernelApiKey).catch((sessionError) => {\n console.error('Failed to close Kernel session during cleanup:', sessionError);\n });\n throw error;\n }\n }\n\n /**\n * Connect to Browser Use remote browser via CDP.\n * Requires BROWSER_USE_API_KEY environment variable.\n */\n private async connectToBrowserUse(): Promise<void> {\n const browserUseApiKey = process.env.BROWSER_USE_API_KEY;\n if (!browserUseApiKey) {\n throw new Error('BROWSER_USE_API_KEY is required when using browseruse as a provider');\n }\n\n const response = await fetch('https://api.browser-use.com/api/v2/browsers', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Browser-Use-API-Key': browserUseApiKey,\n },\n body: JSON.stringify({}),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to create Browser Use session: ${response.statusText}`);\n }\n\n let session: { id: string; cdpUrl: string };\n try {\n session = (await response.json()) as { id: string; cdpUrl: string };\n } catch (error) {\n throw new Error(\n `Failed to parse Browser Use session response: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n\n if (!session.id || !session.cdpUrl) {\n throw new Error(\n `Invalid Browser Use session response: missing ${!session.id ? 'id' : 'cdpUrl'}`\n );\n }\n\n const browser = await chromium.connectOverCDP(session.cdpUrl).catch(() => {\n throw new Error('Failed to connect to Browser Use session via CDP');\n });\n\n try {\n const contexts = browser.contexts();\n let context: BrowserContext;\n let page: Page;\n\n if (contexts.length === 0) {\n context = await browser.newContext();\n page = await context.newPage();\n } else {\n context = contexts[0];\n const pages = context.pages();\n page = pages[0] ?? (await context.newPage());\n }\n\n this.browserUseSessionId = session.id;\n this.browserUseApiKey = browserUseApiKey;\n this.browser = browser;\n context.setDefaultTimeout(60000);\n this.contexts.push(context);\n this.pages.push(page);\n this.activePageIndex = 0;\n this.setupPageTracking(page);\n this.setupContextTracking(context);\n } catch (error) {\n await this.closeBrowserUseSession(session.id, browserUseApiKey).catch((sessionError) => {\n console.error('Failed to close Browser Use session during cleanup:', sessionError);\n });\n throw error;\n }\n }\n\n /**\n * Launch the browser with the specified options\n * If already launched, this is a no-op (browser stays open)\n */\n async launch(options: LaunchCommand): Promise<void> {\n // Determine CDP endpoint: prefer cdpUrl over cdpPort for flexibility\n const cdpEndpoint = options.cdpUrl ?? (options.cdpPort ? String(options.cdpPort) : undefined);\n const hasExtensions = !!options.extensions?.length;\n const hasProfile = !!options.profile;\n const hasStorageState = !!options.storageState;\n\n if (hasExtensions && cdpEndpoint) {\n throw new Error('Extensions cannot be used with CDP connection');\n }\n\n if (hasProfile && cdpEndpoint) {\n throw new Error('Profile cannot be used with CDP connection');\n }\n\n if (hasStorageState && hasProfile) {\n throw new Error(\n 'Storage state cannot be used with profile (profile is already persistent storage)'\n );\n }\n\n if (hasStorageState && hasExtensions) {\n throw new Error(\n 'Storage state cannot be used with extensions (extensions require persistent context)'\n );\n }\n\n if (this.isLaunched()) {\n const needsRelaunch =\n (!cdpEndpoint && this.cdpEndpoint !== null) ||\n (!!cdpEndpoint && this.needsCdpReconnect(cdpEndpoint));\n if (needsRelaunch) {\n await this.close();\n } else {\n return;\n }\n }\n\n if (cdpEndpoint) {\n await this.connectViaCDP(cdpEndpoint);\n return;\n }\n\n // Cloud browser providers require explicit opt-in via -p flag or AGENT_BROWSER_PROVIDER env var\n // -p flag takes precedence over env var\n const provider = options.provider ?? process.env.AGENT_BROWSER_PROVIDER;\n if (provider === 'browserbase') {\n await this.connectToBrowserbase();\n return;\n }\n if (provider === 'browseruse') {\n await this.connectToBrowserUse();\n return;\n }\n\n // Kernel: requires explicit opt-in via -p kernel flag or AGENT_BROWSER_PROVIDER=kernel\n if (provider === 'kernel') {\n await this.connectToKernel();\n return;\n }\n\n const browserType = options.browser ?? 'chromium';\n if (hasExtensions && browserType !== 'chromium') {\n throw new Error('Extensions are only supported in Chromium');\n }\n\n // allowFileAccess is only supported in Chromium\n if (options.allowFileAccess && browserType !== 'chromium') {\n throw new Error('allowFileAccess is only supported in Chromium');\n }\n\n const launcher =\n browserType === 'firefox' ? firefox : browserType === 'webkit' ? webkit : chromium;\n const viewport = options.viewport ?? { width: 1280, height: 720 };\n\n // Build base args array with file access flags if enabled\n // --allow-file-access-from-files: allows file:// URLs to read other file:// URLs via XHR/fetch\n // --allow-file-access: allows the browser to access local files in general\n const fileAccessArgs = options.allowFileAccess\n ? ['--allow-file-access-from-files', '--allow-file-access']\n : [];\n const baseArgs = options.args\n ? [...fileAccessArgs, ...options.args]\n : fileAccessArgs.length > 0\n ? fileAccessArgs\n : undefined;\n\n let context: BrowserContext;\n if (hasExtensions) {\n // Extensions require persistent context in a temp directory\n const extPaths = options.extensions!.join(',');\n const session = process.env.AGENT_BROWSER_SESSION || 'default';\n // Combine extension args with custom args and file access args\n const extArgs = [`--disable-extensions-except=${extPaths}`, `--load-extension=${extPaths}`];\n const allArgs = baseArgs ? [...extArgs, ...baseArgs] : extArgs;\n context = await launcher.launchPersistentContext(\n path.join(os.tmpdir(), `agent-browser-ext-${session}`),\n {\n headless: false,\n executablePath: options.executablePath,\n args: allArgs,\n viewport,\n extraHTTPHeaders: options.headers,\n userAgent: options.userAgent,\n ...(options.proxy && { proxy: options.proxy }),\n ignoreHTTPSErrors: options.ignoreHTTPSErrors ?? false,\n }\n );\n this.isPersistentContext = true;\n } else if (hasProfile) {\n // Profile uses persistent context for durable cookies/storage\n // Expand ~ to home directory since it won't be shell-expanded\n const profilePath = options.profile!.replace(/^~\\//, os.homedir() + '/');\n context = await launcher.launchPersistentContext(profilePath, {\n headless: options.headless ?? true,\n executablePath: options.executablePath,\n args: baseArgs,\n viewport,\n extraHTTPHeaders: options.headers,\n userAgent: options.userAgent,\n ...(options.proxy && { proxy: options.proxy }),\n ignoreHTTPSErrors: options.ignoreHTTPSErrors ?? false,\n });\n this.isPersistentContext = true;\n } else {\n // Regular ephemeral browser\n this.browser = await launcher.launch({\n headless: options.headless ?? true,\n executablePath: options.executablePath,\n args: baseArgs,\n });\n this.cdpEndpoint = null;\n context = await this.browser.newContext({\n viewport,\n extraHTTPHeaders: options.headers,\n userAgent: options.userAgent,\n ...(options.proxy && { proxy: options.proxy }),\n ignoreHTTPSErrors: options.ignoreHTTPSErrors ?? false,\n ...(options.storageState && { storageState: options.storageState }),\n });\n }\n\n context.setDefaultTimeout(60000);\n this.contexts.push(context);\n this.setupContextTracking(context);\n\n const page = context.pages()[0] ?? (await context.newPage());\n // Only add if not already tracked (setupContextTracking may have already added it via 'page' event)\n if (!this.pages.includes(page)) {\n this.pages.push(page);\n this.setupPageTracking(page);\n }\n this.activePageIndex = this.pages.length > 0 ? this.pages.length - 1 : 0;\n }\n\n /**\n * Connect to a running browser via CDP (Chrome DevTools Protocol)\n * @param cdpEndpoint Either a port number (as string) or a full WebSocket URL (ws:// or wss://)\n */\n private async connectViaCDP(cdpEndpoint: string | undefined): Promise<void> {\n if (!cdpEndpoint) {\n throw new Error('CDP endpoint is required for CDP connection');\n }\n\n // Determine the connection URL:\n // - If it starts with ws://, wss://, http://, or https://, use it directly\n // - If it's a numeric string (e.g., \"9222\"), treat as port for localhost\n // - Otherwise, treat it as a port number for localhost\n let cdpUrl: string;\n if (\n cdpEndpoint.startsWith('ws://') ||\n cdpEndpoint.startsWith('wss://') ||\n cdpEndpoint.startsWith('http://') ||\n cdpEndpoint.startsWith('https://')\n ) {\n cdpUrl = cdpEndpoint;\n } else if (/^\\d+$/.test(cdpEndpoint)) {\n // Numeric string - treat as port number (handles JSON serialization quirks)\n cdpUrl = `http://localhost:${cdpEndpoint}`;\n } else {\n // Unknown format - still try as port for backward compatibility\n cdpUrl = `http://localhost:${cdpEndpoint}`;\n }\n\n const browser = await chromium.connectOverCDP(cdpUrl).catch(() => {\n throw new Error(\n `Failed to connect via CDP to ${cdpUrl}. ` +\n (cdpUrl.includes('localhost')\n ? `Make sure the app is running with --remote-debugging-port=${cdpEndpoint}`\n : 'Make sure the remote browser is accessible and the URL is correct.')\n );\n });\n\n // Validate and set up state, cleaning up browser connection if anything fails\n try {\n const contexts = browser.contexts();\n if (contexts.length === 0) {\n throw new Error('No browser context found. Make sure the app has an open window.');\n }\n\n // Filter out pages with empty URLs, which can cause Playwright to hang\n const allPages = contexts.flatMap((context) => context.pages()).filter((page) => page.url());\n\n if (allPages.length === 0) {\n throw new Error('No page found. Make sure the app has loaded content.');\n }\n\n // All validation passed - commit state\n this.browser = browser;\n this.cdpEndpoint = cdpEndpoint;\n\n for (const context of contexts) {\n context.setDefaultTimeout(10000);\n this.contexts.push(context);\n this.setupContextTracking(context);\n }\n\n for (const page of allPages) {\n this.pages.push(page);\n this.setupPageTracking(page);\n }\n\n this.activePageIndex = 0;\n } catch (error) {\n // Clean up browser connection if validation or setup failed\n await browser.close().catch(() => {});\n throw error;\n }\n }\n\n /**\n * Set up console, error, and close tracking for a page\n */\n private setupPageTracking(page: Page): void {\n page.on('console', (msg) => {\n this.consoleMessages.push({\n type: msg.type(),\n text: msg.text(),\n timestamp: Date.now(),\n });\n });\n\n page.on('pageerror', (error) => {\n this.pageErrors.push({\n message: error.message,\n timestamp: Date.now(),\n });\n });\n\n page.on('close', () => {\n const index = this.pages.indexOf(page);\n if (index !== -1) {\n this.pages.splice(index, 1);\n if (this.activePageIndex >= this.pages.length) {\n this.activePageIndex = Math.max(0, this.pages.length - 1);\n }\n }\n });\n }\n\n /**\n * Set up tracking for new pages in a context (for CDP connections and popups/new tabs)\n * This handles pages created externally (e.g., via target=\"_blank\" links, window.open)\n */\n private setupContextTracking(context: BrowserContext): void {\n context.on('page', (page) => {\n // Only add if not already tracked (avoids duplicates when newTab() creates pages)\n if (!this.pages.includes(page)) {\n this.pages.push(page);\n this.setupPageTracking(page);\n }\n\n // Auto-switch to the newly opened tab so subsequent commands target it.\n // For tabs created via newTab()/newWindow(), this is redundant (they set activePageIndex after),\n // but for externally opened tabs (window.open, target=\"_blank\"), this ensures the active tab\n // stays in sync with the browser.\n const newIndex = this.pages.indexOf(page);\n if (newIndex !== -1 && newIndex !== this.activePageIndex) {\n this.activePageIndex = newIndex;\n // Invalidate CDP session since the active page changed\n this.invalidateCDPSession().catch(() => {});\n }\n });\n }\n\n /**\n * Create a new tab in the current context\n */\n async newTab(): Promise<{ index: number; total: number }> {\n if (!this.browser || this.contexts.length === 0) {\n throw new Error('Browser not launched');\n }\n\n // Invalidate CDP session since we're switching to a new page\n await this.invalidateCDPSession();\n\n const context = this.contexts[0]; // Use first context for tabs\n const page = await context.newPage();\n // Only add if not already tracked (setupContextTracking may have already added it via 'page' event)\n if (!this.pages.includes(page)) {\n this.pages.push(page);\n this.setupPageTracking(page);\n }\n this.activePageIndex = this.pages.length - 1;\n\n return { index: this.activePageIndex, total: this.pages.length };\n }\n\n /**\n * Create a new window (new context)\n */\n async newWindow(viewport?: {\n width: number;\n height: number;\n }): Promise<{ index: number; total: number }> {\n if (!this.browser) {\n throw new Error('Browser not launched');\n }\n\n const context = await this.browser.newContext({\n viewport: viewport ?? { width: 1280, height: 720 },\n });\n context.setDefaultTimeout(60000);\n this.contexts.push(context);\n this.setupContextTracking(context);\n\n const page = await context.newPage();\n // Only add if not already tracked (setupContextTracking may have already added it via 'page' event)\n if (!this.pages.includes(page)) {\n this.pages.push(page);\n this.setupPageTracking(page);\n }\n this.activePageIndex = this.pages.length - 1;\n\n return { index: this.activePageIndex, total: this.pages.length };\n }\n\n /**\n * Invalidate the current CDP session (must be called before switching pages)\n * This ensures screencast and input injection work correctly after tab switch\n */\n private async invalidateCDPSession(): Promise<void> {\n // Stop screencast if active (it's tied to the current page's CDP session)\n if (this.screencastActive) {\n await this.stopScreencast();\n }\n\n // Detach and clear the CDP session\n if (this.cdpSession) {\n await this.cdpSession.detach().catch(() => {});\n this.cdpSession = null;\n }\n }\n\n /**\n * Switch to a specific tab/page by index\n */\n async switchTo(index: number): Promise<{ index: number; url: string; title: string }> {\n if (index < 0 || index >= this.pages.length) {\n throw new Error(`Invalid tab index: ${index}. Available: 0-${this.pages.length - 1}`);\n }\n\n // Invalidate CDP session before switching (it's page-specific)\n if (index !== this.activePageIndex) {\n await this.invalidateCDPSession();\n }\n\n this.activePageIndex = index;\n const page = this.pages[index];\n\n return {\n index: this.activePageIndex,\n url: page.url(),\n title: '', // Title requires async, will be fetched separately\n };\n }\n\n /**\n * Close a specific tab/page\n */\n async closeTab(index?: number): Promise<{ closed: number; remaining: number }> {\n const targetIndex = index ?? this.activePageIndex;\n\n if (targetIndex < 0 || targetIndex >= this.pages.length) {\n throw new Error(`Invalid tab index: ${targetIndex}`);\n }\n\n if (this.pages.length === 1) {\n throw new Error('Cannot close the last tab. Use \"close\" to close the browser.');\n }\n\n // If closing the active tab, invalidate CDP session first\n if (targetIndex === this.activePageIndex) {\n await this.invalidateCDPSession();\n }\n\n const page = this.pages[targetIndex];\n await page.close();\n this.pages.splice(targetIndex, 1);\n\n // Adjust active index if needed\n if (this.activePageIndex >= this.pages.length) {\n this.activePageIndex = this.pages.length - 1;\n } else if (this.activePageIndex > targetIndex) {\n this.activePageIndex--;\n }\n\n return { closed: targetIndex, remaining: this.pages.length };\n }\n\n /**\n * List all tabs with their info\n */\n async listTabs(): Promise<Array<{ index: number; url: string; title: string; active: boolean }>> {\n const tabs = await Promise.all(\n this.pages.map(async (page, index) => ({\n index,\n url: page.url(),\n title: await page.title().catch(() => ''),\n active: index === this.activePageIndex,\n }))\n );\n return tabs;\n }\n\n /**\n * Get or create a CDP session for the current page\n * Only works with Chromium-based browsers\n */\n async getCDPSession(): Promise<CDPSession> {\n if (this.cdpSession) {\n return this.cdpSession;\n }\n\n const page = this.getPage();\n const context = page.context();\n\n // Create a new CDP session attached to the page\n this.cdpSession = await context.newCDPSession(page);\n return this.cdpSession;\n }\n\n /**\n * Check if screencast is currently active\n */\n isScreencasting(): boolean {\n return this.screencastActive;\n }\n\n /**\n * Start screencast - streams viewport frames via CDP\n * @param callback Function called for each frame\n * @param options Screencast options\n */\n async startScreencast(\n callback: (frame: ScreencastFrame) => void,\n options?: ScreencastOptions\n ): Promise<void> {\n if (this.screencastActive) {\n throw new Error('Screencast already active');\n }\n\n const cdp = await this.getCDPSession();\n this.frameCallback = callback;\n this.screencastActive = true;\n\n // Create and store the frame handler so we can remove it later\n this.screencastFrameHandler = async (params: any) => {\n const frame: ScreencastFrame = {\n data: params.data,\n metadata: params.metadata,\n sessionId: params.sessionId,\n };\n\n // Acknowledge the frame to receive the next one\n await cdp.send('Page.screencastFrameAck', { sessionId: params.sessionId });\n\n // Call the callback with the frame\n if (this.frameCallback) {\n this.frameCallback(frame);\n }\n };\n\n // Listen for screencast frames\n cdp.on('Page.screencastFrame', this.screencastFrameHandler);\n\n // Start the screencast\n await cdp.send('Page.startScreencast', {\n format: options?.format ?? 'jpeg',\n quality: options?.quality ?? 80,\n maxWidth: options?.maxWidth ?? 1280,\n maxHeight: options?.maxHeight ?? 720,\n everyNthFrame: options?.everyNthFrame ?? 1,\n });\n }\n\n /**\n * Stop screencast\n */\n async stopScreencast(): Promise<void> {\n if (!this.screencastActive) {\n return;\n }\n\n try {\n const cdp = await this.getCDPSession();\n await cdp.send('Page.stopScreencast');\n\n // Remove the event listener to prevent accumulation\n if (this.screencastFrameHandler) {\n cdp.off('Page.screencastFrame', this.screencastFrameHandler);\n }\n } catch {\n // Ignore errors when stopping\n }\n\n this.screencastActive = false;\n this.frameCallback = null;\n this.screencastFrameHandler = null;\n }\n\n /**\n * Inject a mouse event via CDP\n */\n async injectMouseEvent(params: {\n type: 'mousePressed' | 'mouseReleased' | 'mouseMoved' | 'mouseWheel';\n x: number;\n y: number;\n button?: 'left' | 'right' | 'middle' | 'none';\n clickCount?: number;\n deltaX?: number;\n deltaY?: number;\n modifiers?: number; // 1=Alt, 2=Ctrl, 4=Meta, 8=Shift\n }): Promise<void> {\n const cdp = await this.getCDPSession();\n\n const cdpButton =\n params.button === 'left'\n ? 'left'\n : params.button === 'right'\n ? 'right'\n : params.button === 'middle'\n ? 'middle'\n : 'none';\n\n await cdp.send('Input.dispatchMouseEvent', {\n type: params.type,\n x: params.x,\n y: params.y,\n button: cdpButton,\n clickCount: params.clickCount ?? 1,\n deltaX: params.deltaX ?? 0,\n deltaY: params.deltaY ?? 0,\n modifiers: params.modifiers ?? 0,\n });\n }\n\n /**\n * Inject a keyboard event via CDP\n */\n async injectKeyboardEvent(params: {\n type: 'keyDown' | 'keyUp' | 'char';\n key?: string;\n code?: string;\n text?: string;\n modifiers?: number; // 1=Alt, 2=Ctrl, 4=Meta, 8=Shift\n }): Promise<void> {\n const cdp = await this.getCDPSession();\n\n await cdp.send('Input.dispatchKeyEvent', {\n type: params.type,\n key: params.key,\n code: params.code,\n text: params.text,\n modifiers: params.modifiers ?? 0,\n });\n }\n\n /**\n * Inject touch event via CDP (for mobile emulation)\n */\n async injectTouchEvent(params: {\n type: 'touchStart' | 'touchEnd' | 'touchMove' | 'touchCancel';\n touchPoints: Array<{ x: number; y: number; id?: number }>;\n modifiers?: number;\n }): Promise<void> {\n const cdp = await this.getCDPSession();\n\n await cdp.send('Input.dispatchTouchEvent', {\n type: params.type,\n touchPoints: params.touchPoints.map((tp, i) => ({\n x: tp.x,\n y: tp.y,\n id: tp.id ?? i,\n })),\n modifiers: params.modifiers ?? 0,\n });\n }\n\n /**\n * Check if video recording is currently active\n */\n isRecording(): boolean {\n return this.recordingContext !== null;\n }\n\n /**\n * Start recording to a video file using Playwright's native video recording.\n * Creates a fresh browser context with video recording enabled.\n * Automatically captures current URL and transfers cookies/storage if no URL provided.\n *\n * @param outputPath - Path to the output video file (will be .webm)\n * @param url - Optional URL to navigate to (defaults to current page URL)\n */\n async startRecording(outputPath: string, url?: string): Promise<void> {\n if (this.recordingContext) {\n throw new Error(\n \"Recording already in progress. Run 'record stop' first, or use 'record restart' to stop and start a new recording.\"\n );\n }\n\n if (!this.browser) {\n throw new Error('Browser not launched. Call launch first.');\n }\n\n // Check if output file already exists\n if (existsSync(outputPath)) {\n throw new Error(`Output file already exists: ${outputPath}`);\n }\n\n // Validate output path is .webm (Playwright native format)\n if (!outputPath.endsWith('.webm')) {\n throw new Error(\n 'Playwright native recording only supports WebM format. Please use a .webm extension.'\n );\n }\n\n // Auto-capture current URL if none provided\n const currentPage = this.pages.length > 0 ? this.pages[this.activePageIndex] : null;\n const currentContext = this.contexts.length > 0 ? this.contexts[0] : null;\n if (!url && currentPage) {\n const currentUrl = currentPage.url();\n if (currentUrl && currentUrl !== 'about:blank') {\n url = currentUrl;\n }\n }\n\n // Capture state from current context (cookies + storage)\n let storageState:\n | {\n cookies: Array<{\n name: string;\n value: string;\n domain: string;\n path: string;\n expires: number;\n httpOnly: boolean;\n secure: boolean;\n sameSite: 'Strict' | 'Lax' | 'None';\n }>;\n origins: Array<{\n origin: string;\n localStorage: Array<{ name: string; value: string }>;\n }>;\n }\n | undefined;\n\n if (currentContext) {\n try {\n storageState = await currentContext.storageState();\n } catch {\n // Ignore errors - context might be closed or invalid\n }\n }\n\n // Create a temp directory for video recording\n const session = process.env.AGENT_BROWSER_SESSION || 'default';\n this.recordingTempDir = path.join(\n os.tmpdir(),\n `agent-browser-recording-${session}-${Date.now()}`\n );\n mkdirSync(this.recordingTempDir, { recursive: true });\n\n this.recordingOutputPath = outputPath;\n\n // Create a new context with video recording enabled and restored state\n const viewport = { width: 1280, height: 720 };\n this.recordingContext = await this.browser.newContext({\n viewport,\n recordVideo: {\n dir: this.recordingTempDir,\n size: viewport,\n },\n storageState,\n });\n this.recordingContext.setDefaultTimeout(10000);\n\n // Create a page in the recording context\n this.recordingPage = await this.recordingContext.newPage();\n\n // Add the recording context and page to our managed lists\n this.contexts.push(this.recordingContext);\n this.pages.push(this.recordingPage);\n this.activePageIndex = this.pages.length - 1;\n\n // Set up page tracking\n this.setupPageTracking(this.recordingPage);\n\n // Invalidate CDP session since we switched pages\n await this.invalidateCDPSession();\n\n // Navigate to URL if provided or captured\n if (url) {\n await this.recordingPage.goto(url, { waitUntil: 'load' });\n }\n }\n\n /**\n * Stop recording and save the video file\n * @returns Recording result with path\n */\n async stopRecording(): Promise<{ path: string; frames: number; error?: string }> {\n if (!this.recordingContext || !this.recordingPage) {\n return { path: '', frames: 0, error: 'No recording in progress' };\n }\n\n const outputPath = this.recordingOutputPath;\n\n try {\n // Get the video object before closing the page\n const video = this.recordingPage.video();\n\n // Remove recording page/context from our managed lists before closing\n const pageIndex = this.pages.indexOf(this.recordingPage);\n if (pageIndex !== -1) {\n this.pages.splice(pageIndex, 1);\n }\n const contextIndex = this.contexts.indexOf(this.recordingContext);\n if (contextIndex !== -1) {\n this.contexts.splice(contextIndex, 1);\n }\n\n // Close the page to finalize the video\n await this.recordingPage.close();\n\n // Save the video to the desired output path\n if (video) {\n await video.saveAs(outputPath);\n }\n\n // Clean up temp directory\n if (this.recordingTempDir) {\n rmSync(this.recordingTempDir, { recursive: true, force: true });\n }\n\n // Close the recording context\n await this.recordingContext.close();\n\n // Reset recording state\n this.recordingContext = null;\n this.recordingPage = null;\n this.recordingOutputPath = '';\n this.recordingTempDir = '';\n\n // Adjust active page index\n if (this.pages.length > 0) {\n this.activePageIndex = Math.min(this.activePageIndex, this.pages.length - 1);\n } else {\n this.activePageIndex = 0;\n }\n\n // Invalidate CDP session since we may have switched pages\n await this.invalidateCDPSession();\n\n return { path: outputPath, frames: 0 }; // Playwright doesn't expose frame count\n } catch (error) {\n // Clean up temp directory on error\n if (this.recordingTempDir) {\n rmSync(this.recordingTempDir, { recursive: true, force: true });\n }\n\n // Reset state on error\n this.recordingContext = null;\n this.recordingPage = null;\n this.recordingOutputPath = '';\n this.recordingTempDir = '';\n\n const message = error instanceof Error ? error.message : String(error);\n return { path: outputPath, frames: 0, error: message };\n }\n }\n\n /**\n * Restart recording - stops current recording (if any) and starts a new one.\n * Convenience method that combines stopRecording and startRecording.\n *\n * @param outputPath - Path to the output video file (must be .webm)\n * @param url - Optional URL to navigate to (defaults to current page URL)\n * @returns Result from stopping the previous recording (if any)\n */\n async restartRecording(\n outputPath: string,\n url?: string\n ): Promise<{ previousPath?: string; stopped: boolean }> {\n let previousPath: string | undefined;\n let stopped = false;\n\n // Stop current recording if active\n if (this.recordingContext) {\n const result = await this.stopRecording();\n previousPath = result.path;\n stopped = true;\n }\n\n // Start new recording\n await this.startRecording(outputPath, url);\n\n return { previousPath, stopped };\n }\n\n /**\n * Close the browser and clean up\n */\n async close(): Promise<void> {\n // Stop recording if active (saves video)\n if (this.recordingContext) {\n await this.stopRecording();\n }\n\n // Stop screencast if active\n if (this.screencastActive) {\n await this.stopScreencast();\n }\n\n // Clean up CDP session\n if (this.cdpSession) {\n await this.cdpSession.detach().catch(() => {});\n this.cdpSession = null;\n }\n\n if (this.browserbaseSessionId && this.browserbaseApiKey) {\n await this.closeBrowserbaseSession(this.browserbaseSessionId, this.browserbaseApiKey).catch(\n (error) => {\n console.error('Failed to close Browserbase session:', error);\n }\n );\n this.browser = null;\n } else if (this.browserUseSessionId && this.browserUseApiKey) {\n await this.closeBrowserUseSession(this.browserUseSessionId, this.browserUseApiKey).catch(\n (error) => {\n console.error('Failed to close Browser Use session:', error);\n }\n );\n this.browser = null;\n } else if (this.kernelSessionId && this.kernelApiKey) {\n await this.closeKernelSession(this.kernelSessionId, this.kernelApiKey).catch((error) => {\n console.error('Failed to close Kernel session:', error);\n });\n this.browser = null;\n } else if (this.cdpEndpoint !== null) {\n // CDP: only disconnect, don't close external app's pages\n if (this.browser) {\n await this.browser.close().catch(() => {});\n this.browser = null;\n }\n } else {\n // Regular browser: close everything\n for (const page of this.pages) {\n await page.close().catch(() => {});\n }\n for (const context of this.contexts) {\n await context.close().catch(() => {});\n }\n if (this.browser) {\n await this.browser.close().catch(() => {});\n this.browser = null;\n }\n }\n\n this.pages = [];\n this.contexts = [];\n this.cdpEndpoint = null;\n this.browserbaseSessionId = null;\n this.browserbaseApiKey = null;\n this.browserUseSessionId = null;\n this.browserUseApiKey = null;\n this.kernelSessionId = null;\n this.kernelApiKey = null;\n this.isPersistentContext = false;\n this.activePageIndex = 0;\n this.refMap = {};\n this.lastSnapshot = '';\n this.frameCallback = null;\n }\n}\n","/**\n * Enhanced snapshot with element refs for deterministic element selection.\n *\n * This module generates accessibility snapshots with embedded refs that can be\n * used to click/fill/interact with elements without re-querying the DOM.\n *\n * Example output:\n * - heading \"Example Domain\" [ref=e1] [level=1]\n * - paragraph: Some text content\n * - button \"Submit\" [ref=e2]\n * - textbox \"Email\" [ref=e3]\n *\n * Usage:\n * agent-browser snapshot # Full snapshot\n * agent-browser snapshot -i # Interactive elements only\n * agent-browser snapshot --depth 3 # Limit depth\n * agent-browser click @e2 # Click element by ref\n */\n\nimport type { Page, Locator } from 'playwright-core';\n\nexport interface RefMap {\n [ref: string]: {\n selector: string;\n role: string;\n name?: string;\n /** Index for disambiguation when multiple elements have same role+name */\n nth?: number;\n /** Coordinate-based bounds from DualMode tree */\n bounds?: { left: number; top: number; right: number; bottom: number };\n /** CDP Node ID */\n nodeId?: number;\n };\n}\n\nexport interface EnhancedSnapshot {\n tree: string;\n refs: RefMap;\n}\n\nexport interface SnapshotOptions {\n /** Only include interactive elements (buttons, links, inputs, etc.) */\n interactive?: boolean;\n /** Include cursor-interactive elements (cursor:pointer, onclick, tabindex) */\n cursor?: boolean;\n /** Maximum depth of tree to include (0 = root only) */\n maxDepth?: number;\n /** Remove structural elements without meaningful content */\n compact?: boolean;\n /** CSS selector to scope the snapshot */\n selector?: string;\n}\n\n// Counter for generating refs\nlet refCounter = 0;\n\n/**\n * Reset ref counter (call at start of each snapshot)\n */\nexport function resetRefs(): void {\n refCounter = 0;\n}\n\n/**\n * Generate next ref ID\n */\nfunction nextRef(): string {\n return `e${++refCounter}`;\n}\n\n/**\n * Roles that are interactive and should get refs\n */\nconst INTERACTIVE_ROLES = new Set([\n 'button',\n 'link',\n 'textbox',\n 'checkbox',\n 'radio',\n 'combobox',\n 'listbox',\n 'menuitem',\n 'menuitemcheckbox',\n 'menuitemradio',\n 'option',\n 'searchbox',\n 'slider',\n 'spinbutton',\n 'switch',\n 'tab',\n 'treeitem',\n]);\n\n/**\n * Roles that provide structure/context (get refs for text extraction)\n */\nconst CONTENT_ROLES = new Set([\n 'heading',\n 'cell',\n 'gridcell',\n 'columnheader',\n 'rowheader',\n 'listitem',\n 'article',\n 'region',\n 'main',\n 'navigation',\n]);\n\n/**\n * Roles that are purely structural (can be filtered in compact mode)\n */\nconst STRUCTURAL_ROLES = new Set([\n 'generic',\n 'group',\n 'list',\n 'table',\n 'row',\n 'rowgroup',\n 'grid',\n 'treegrid',\n 'menu',\n 'menubar',\n 'toolbar',\n 'tablist',\n 'tree',\n 'directory',\n 'document',\n 'application',\n 'presentation',\n 'none',\n]);\n\n/**\n * Build a selector string for storing in ref map\n */\nfunction buildSelector(role: string, name?: string): string {\n if (name) {\n const escapedName = name.replace(/\"/g, '\\\\\"');\n return `getByRole('${role}', { name: \"${escapedName}\", exact: true })`;\n }\n return `getByRole('${role}')`;\n}\n\n/**\n * Query the page for clickable elements that might not have proper ARIA roles.\n * This finds elements with cursor: pointer or onclick handlers.\n */\nasync function findCursorInteractiveElements(\n page: Page,\n selector?: string\n): Promise<\n Array<{\n selector: string;\n text: string;\n tagName: string;\n hasOnClick: boolean;\n hasCursorPointer: boolean;\n hasTabIndex: boolean;\n }>\n> {\n const rootSelector = selector || 'body';\n\n // Use a string function body to avoid TypeScript transpilation issues\n const scriptBody = `(rootSel) => {\n const results = [];\n\n // Elements that already have interactive ARIA roles - skip these\n const interactiveRoles = new Set([\n 'button', 'link', 'textbox', 'checkbox', 'radio', 'combobox', 'listbox',\n 'menuitem', 'menuitemcheckbox', 'menuitemradio', 'option', 'searchbox',\n 'slider', 'spinbutton', 'switch', 'tab', 'treeitem'\n ]);\n\n // Tags that are already interactive by default\n const interactiveTags = new Set([\n 'a', 'button', 'input', 'select', 'textarea', 'details', 'summary'\n ]);\n\n const root = document.querySelector(rootSel) || document.body;\n const allElements = root.querySelectorAll('*');\n\n // Build a unique selector for an element\n const buildSelector = (el) => {\n const testId = el.getAttribute('data-testid');\n if (testId) return '[data-testid=\"' + testId + '\"]';\n if (el.id) return '#' + CSS.escape(el.id);\n\n const path = [];\n let current = el;\n while (current && current !== document.body) {\n let sel = current.tagName.toLowerCase();\n const classes = Array.from(current.classList).filter(c => c.trim());\n if (classes.length > 0) sel += '.' + CSS.escape(classes[0]);\n\n const parent = current.parentElement;\n if (parent) {\n const siblings = Array.from(parent.children);\n const matching = siblings.filter(s => {\n if (s.tagName !== current.tagName) return false;\n if (classes.length > 0 && !s.classList.contains(classes[0])) return false;\n return true;\n });\n if (matching.length > 1) {\n const idx = matching.indexOf(current) + 1;\n sel += ':nth-of-type(' + idx + ')';\n }\n }\n path.unshift(sel);\n current = current.parentElement;\n if (path.length >= 3) break;\n }\n return path.join(' > ');\n };\n\n for (const el of allElements) {\n const tagName = el.tagName.toLowerCase();\n if (interactiveTags.has(tagName)) continue;\n\n const role = el.getAttribute('role');\n if (role && interactiveRoles.has(role.toLowerCase())) continue;\n\n const computedStyle = getComputedStyle(el);\n const hasCursorPointer = computedStyle.cursor === 'pointer';\n const hasOnClick = el.hasAttribute('onclick') || el.onclick !== null;\n const tabIndex = el.getAttribute('tabindex');\n const hasTabIndex = tabIndex !== null && tabIndex !== '-1';\n\n if (!hasCursorPointer && !hasOnClick && !hasTabIndex) continue;\n\n const text = (el.textContent || '').trim().slice(0, 100);\n if (!text) continue;\n\n const rect = el.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) continue;\n\n results.push({\n selector: buildSelector(el),\n text,\n tagName,\n hasOnClick,\n hasCursorPointer,\n hasTabIndex\n });\n }\n return results;\n }`;\n\n \n const fn = new Function('return ' + scriptBody)();\n return page.evaluate(fn, rootSelector);\n}\n\n/**\n * Get enhanced snapshot with refs and optional filtering\n */\nexport async function getEnhancedSnapshot(\n page: Page,\n options: SnapshotOptions = {}\n): Promise<EnhancedSnapshot> {\n resetRefs();\n const refs: RefMap = {};\n\n // Get ARIA snapshot from Playwright\n const locator = options.selector ? page.locator(options.selector) : page.locator(':root');\n const ariaTree = await locator.ariaSnapshot();\n\n if (!ariaTree) {\n return {\n tree: '(empty)',\n refs: {},\n };\n }\n\n // Parse and enhance the ARIA tree\n const enhancedTree = processAriaTree(ariaTree, refs, options);\n\n // When cursor flag is set, also find cursor-interactive elements\n // that may not have proper ARIA roles\n if (options.cursor) {\n const cursorElements = await findCursorInteractiveElements(page, options.selector);\n\n // Filter out elements whose text is already captured in the snapshot\n const existingTexts = new Set(Object.values(refs).map((r) => r.name?.toLowerCase()));\n\n const additionalLines: string[] = [];\n for (const el of cursorElements) {\n // Skip if text already captured (likely already in ARIA tree)\n if (existingTexts.has(el.text.toLowerCase())) continue;\n\n const ref = nextRef();\n const role = el.hasCursorPointer ? 'clickable' : el.hasOnClick ? 'clickable' : 'focusable';\n\n refs[ref] = {\n selector: el.selector,\n role: role,\n name: el.text,\n };\n\n // Build description of why it's interactive\n const hints: string[] = [];\n if (el.hasCursorPointer) hints.push('cursor:pointer');\n if (el.hasOnClick) hints.push('onclick');\n if (el.hasTabIndex) hints.push('tabindex');\n\n additionalLines.push(`- ${role} \"${el.text}\" [ref=${ref}] [${hints.join(', ')}]`);\n }\n\n if (additionalLines.length > 0) {\n const separator =\n enhancedTree === '(no interactive elements)' ? '' : '\\n# Cursor-interactive elements:\\n';\n const base = enhancedTree === '(no interactive elements)' ? '' : enhancedTree;\n return {\n tree: base + separator + additionalLines.join('\\n'),\n refs,\n };\n }\n }\n\n return { tree: enhancedTree, refs };\n}\n\n/**\n * Track role+name combinations to detect duplicates\n */\ninterface RoleNameTracker {\n counts: Map<string, number>;\n /** Maps role+name key to array of ref IDs that use it */\n refsByKey: Map<string, string[]>;\n getKey(role: string, name?: string): string;\n getNextIndex(role: string, name?: string): number;\n trackRef(role: string, name: string | undefined, ref: string): void;\n /** Get all role+name keys that have duplicates */\n getDuplicateKeys(): Set<string>;\n}\n\nfunction createRoleNameTracker(): RoleNameTracker {\n const counts = new Map<string, number>();\n const refsByKey = new Map<string, string[]>();\n return {\n counts,\n refsByKey,\n getKey(role: string, name?: string): string {\n return `${role}:${name ?? ''}`;\n },\n getNextIndex(role: string, name?: string): number {\n const key = this.getKey(role, name);\n const current = counts.get(key) ?? 0;\n counts.set(key, current + 1);\n return current;\n },\n trackRef(role: string, name: string | undefined, ref: string): void {\n const key = this.getKey(role, name);\n const refs = refsByKey.get(key) ?? [];\n refs.push(ref);\n refsByKey.set(key, refs);\n },\n getDuplicateKeys(): Set<string> {\n const duplicates = new Set<string>();\n for (const [key, refs] of refsByKey) {\n if (refs.length > 1) {\n duplicates.add(key);\n }\n }\n return duplicates;\n },\n };\n}\n\n/**\n * Process ARIA snapshot: add refs and apply filters\n */\nfunction processAriaTree(ariaTree: string, refs: RefMap, options: SnapshotOptions): string {\n const lines = ariaTree.split('\\n');\n const result: string[] = [];\n const tracker = createRoleNameTracker();\n\n // For interactive-only mode, we collect just interactive elements\n if (options.interactive) {\n for (const line of lines) {\n const match = line.match(/^(\\s*-\\s*)(\\w+)(?:\\s+\"([^\"]*)\")?(.*)$/);\n if (!match) continue;\n\n const [, , role, name, suffix] = match;\n const roleLower = role.toLowerCase();\n\n if (INTERACTIVE_ROLES.has(roleLower)) {\n const ref = nextRef();\n const nth = tracker.getNextIndex(roleLower, name);\n tracker.trackRef(roleLower, name, ref);\n refs[ref] = {\n selector: buildSelector(roleLower, name),\n role: roleLower,\n name,\n nth, // Always store nth, we'll use it for duplicates\n };\n\n let enhanced = `- ${role}`;\n if (name) enhanced += ` \"${name}\"`;\n enhanced += ` [ref=${ref}]`;\n // Only show nth in output if it's > 0 (for readability)\n if (nth > 0) enhanced += ` [nth=${nth}]`;\n if (suffix && suffix.includes('[')) enhanced += suffix;\n\n result.push(enhanced);\n }\n }\n\n // Post-process: remove nth from refs that don't have duplicates\n removeNthFromNonDuplicates(refs, tracker);\n\n return result.join('\\n') || '(no interactive elements)';\n }\n\n // Normal processing with depth/compact filters\n for (const line of lines) {\n const processed = processLine(line, refs, options, tracker);\n if (processed !== null) {\n result.push(processed);\n }\n }\n\n // Post-process: remove nth from refs that don't have duplicates\n removeNthFromNonDuplicates(refs, tracker);\n\n // If compact mode, remove empty structural elements\n if (options.compact) {\n return compactTree(result.join('\\n'));\n }\n\n return result.join('\\n');\n}\n\n/**\n * Remove nth from refs that ended up not having duplicates\n * This keeps single-element locators simple (no unnecessary .nth(0))\n */\nfunction removeNthFromNonDuplicates(refs: RefMap, tracker: RoleNameTracker): void {\n const duplicateKeys = tracker.getDuplicateKeys();\n\n for (const [ref, data] of Object.entries(refs)) {\n const key = tracker.getKey(data.role, data.name);\n if (!duplicateKeys.has(key)) {\n // Not a duplicate, remove nth to keep locator simple\n delete refs[ref].nth;\n }\n }\n}\n\n/**\n * Get indentation level (number of spaces / 2)\n */\nfunction getIndentLevel(line: string): number {\n const match = line.match(/^(\\s*)/);\n return match ? Math.floor(match[1].length / 2) : 0;\n}\n\n/**\n * Process a single line: add ref if needed, filter if requested\n */\nfunction processLine(\n line: string,\n refs: RefMap,\n options: SnapshotOptions,\n tracker: RoleNameTracker\n): string | null {\n const depth = getIndentLevel(line);\n\n // Check max depth\n if (options.maxDepth !== undefined && depth > options.maxDepth) {\n return null;\n }\n\n // Match lines like:\n // - button \"Submit\"\n // - heading \"Title\" [level=1]\n // - link \"Click me\":\n const match = line.match(/^(\\s*-\\s*)(\\w+)(?:\\s+\"([^\"]*)\")?(.*)$/);\n\n if (!match) {\n // Metadata lines (like /url:) or text content\n if (options.interactive) {\n // In interactive mode, only keep metadata under interactive elements\n return null;\n }\n return line;\n }\n\n const [, prefix, role, name, suffix] = match;\n const roleLower = role.toLowerCase();\n\n // Skip metadata lines (like /url:)\n if (role.startsWith('/')) {\n return line;\n }\n\n const isInteractive = INTERACTIVE_ROLES.has(roleLower);\n const isContent = CONTENT_ROLES.has(roleLower);\n const isStructural = STRUCTURAL_ROLES.has(roleLower);\n\n // In interactive-only mode, filter non-interactive elements\n if (options.interactive && !isInteractive) {\n return null;\n }\n\n // In compact mode, skip unnamed structural elements\n if (options.compact && isStructural && !name) {\n return null;\n }\n\n // Add ref for interactive or named content elements\n const shouldHaveRef = isInteractive || (isContent && name);\n\n if (shouldHaveRef) {\n const ref = nextRef();\n const nth = tracker.getNextIndex(roleLower, name);\n tracker.trackRef(roleLower, name, ref);\n\n refs[ref] = {\n selector: buildSelector(roleLower, name),\n role: roleLower,\n name,\n nth, // Always store nth, we'll clean up non-duplicates later\n };\n\n // Build enhanced line with ref\n let enhanced = `${prefix}${role}`;\n if (name) enhanced += ` \"${name}\"`;\n enhanced += ` [ref=${ref}]`;\n // Only show nth in output if it's > 0 (for readability)\n if (nth > 0) enhanced += ` [nth=${nth}]`;\n if (suffix) enhanced += suffix;\n\n return enhanced;\n }\n\n return line;\n}\n\n/**\n * Remove empty structural branches in compact mode\n */\nfunction compactTree(tree: string): string {\n const lines = tree.split('\\n');\n const result: string[] = [];\n\n // Simple pass: keep lines that have content or refs\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Always keep lines with refs\n if (line.includes('[ref=')) {\n result.push(line);\n continue;\n }\n\n // Keep lines with text content (after :)\n if (line.includes(':') && !line.endsWith(':')) {\n result.push(line);\n continue;\n }\n\n // Check if this structural element has children with refs\n const currentIndent = getIndentLevel(line);\n let hasRelevantChildren = false;\n\n for (let j = i + 1; j < lines.length; j++) {\n const childIndent = getIndentLevel(lines[j]);\n if (childIndent <= currentIndent) break;\n if (lines[j].includes('[ref=')) {\n hasRelevantChildren = true;\n break;\n }\n }\n\n if (hasRelevantChildren) {\n result.push(line);\n }\n }\n\n return result.join('\\n');\n}\n\n/**\n * Parse a ref from command argument (e.g., \"@e1\" -> \"e1\")\n */\nexport function parseRef(arg: string): string | null {\n if (arg.startsWith('@')) {\n return arg.slice(1);\n }\n if (arg.startsWith('ref=')) {\n return arg.slice(4);\n }\n if (/^e\\d+$/.test(arg)) {\n return arg;\n }\n return null;\n}\n\n/**\n * Get snapshot statistics\n */\nexport function getSnapshotStats(\n tree: string,\n refs: RefMap\n): {\n lines: number;\n chars: number;\n tokens: number;\n refs: number;\n interactive: number;\n} {\n const interactive = Object.values(refs).filter((r) => INTERACTIVE_ROLES.has(r.role)).length;\n\n return {\n lines: tree.split('\\n').length,\n chars: tree.length,\n tokens: Math.ceil(tree.length / 4),\n refs: Object.keys(refs).length,\n interactive,\n };\n}\n","import type { Page } from 'playwright-core';\nimport type { EnhancedSnapshot, RefMap } from './snapshot.js';\n\ninterface DualModeNode {\n core: {\n nodeId: number;\n backendNodeId: number;\n childrenIds?: number[];\n parentId?: number;\n className?: string;\n text?: string;\n contentDescription?: string;\n bounds: {\n left: number;\n top: number;\n right: number;\n bottom: number;\n };\n clickable: boolean;\n longClickable: boolean;\n scrollable: boolean;\n focusable: boolean;\n editable: boolean;\n checkable: boolean;\n enabled: boolean;\n focused: boolean;\n selected: boolean;\n checked: boolean;\n visible: boolean;\n };\n designMode?: {\n visual?: {\n backgroundColor?: string;\n foregroundColor?: string;\n opacity?: number;\n fontSize?: number;\n fontWeight?: number;\n };\n layout?: {\n zIndex?: number;\n isFixedPosition?: boolean;\n isSticky?: boolean;\n };\n spatial?: {\n distanceFromViewportTop?: number;\n isAboveFold?: boolean;\n visualProminenceScore?: number;\n };\n };\n xrayMode?: {\n semantics?: {\n role?: string;\n name?: string;\n description?: string;\n intentTags?: string[];\n importanceScore?: number;\n };\n interaction?: {\n enabled?: boolean;\n selected?: boolean;\n checked?: boolean;\n expanded?: boolean;\n focused?: boolean;\n availableActions?: string[];\n affordanceScore?: number;\n };\n };\n children?: DualModeNode[];\n}\n\ninterface AXNode {\n nodeId: string;\n role?: { value: string };\n name?: { value: string };\n childIds?: string[];\n parentId?: string;\n}\n\ntype HydratedAXNode = AXNode & { children: HydratedAXNode[] };\n\nexport async function getDualModeSnapshot(\n page: Page,\n options: { interactive?: boolean } = {}\n): Promise<EnhancedSnapshot> {\n const session = await page.context().newCDPSession(page);\n let nodes: any[] = [];\n let isDualMode = false;\n\n try {\n const result = (await session.send('Accessibility.getDualModeAXTree' as any)) as any;\n nodes = result.nodes;\n isDualMode = true;\n } catch {\n try {\n const result = (await session.send('Accessibility.getFullAXTree')) as any;\n nodes = result.nodes;\n } catch (e2) {\n console.warn('Failed to fetch AXTree via CDP:', e2);\n return { tree: '(accessibility tree unavailable)', refs: {} };\n }\n } finally {\n await session.detach();\n }\n\n const refs: RefMap = {};\n let tree = '';\n\n resetRefs();\n\n if (isDualMode) {\n const rootNodes = buildTreeFromFlatNodes(nodes);\n tree = processDualModeTree(rootNodes, refs, options.interactive ?? false);\n } else {\n const rootNodes = buildStandardTree(nodes);\n tree = processStandardTree(rootNodes, refs, options.interactive ?? false);\n }\n\n return { tree, refs };\n}\n\nfunction buildTreeFromFlatNodes(nodes: DualModeNode[]): DualModeNode[] {\n const nodeMap = new Map<number, DualModeNode>();\n nodes.forEach((n) => nodeMap.set(n.core.nodeId, n));\n\n const roots: DualModeNode[] = [];\n\n nodes.forEach((node) => {\n if (node.core.childrenIds) {\n node.children = node.core.childrenIds\n .map((id) => nodeMap.get(id))\n .filter((n): n is DualModeNode => !!n);\n }\n\n const parentId = node.core.parentId;\n if (parentId === undefined || !nodeMap.has(parentId)) {\n roots.push(node);\n }\n });\n\n return roots;\n}\n\nfunction buildStandardTree(nodes: AXNode[]): HydratedAXNode[] {\n const nodeMap = new Map<string, HydratedAXNode>();\n // Initialize with empty children array\n nodes.forEach((n) => nodeMap.set(n.nodeId, { ...n, children: [] } as HydratedAXNode));\n\n const roots: HydratedAXNode[] = [];\n const childrenIdsSet = new Set<string>();\n\n nodes.forEach((node) => {\n if (node.childIds) {\n const parent = nodeMap.get(node.nodeId);\n if (parent) {\n node.childIds.forEach((childId) => {\n const child = nodeMap.get(childId);\n if (child) {\n parent.children.push(child);\n childrenIdsSet.add(childId);\n }\n });\n }\n }\n });\n\n nodes.forEach((node) => {\n if (!childrenIdsSet.has(node.nodeId)) {\n const root = nodeMap.get(node.nodeId);\n if (root) roots.push(root);\n }\n });\n\n return roots;\n}\n\nlet refCounter = 0;\nfunction resetRefs(): void {\n refCounter = 0;\n}\nfunction nextRef(): string {\n return `e${++refCounter}`;\n}\n\nconst INTERACTIVE_ROLES = new Set([\n 'button',\n 'link',\n 'textbox',\n 'checkbox',\n 'radio',\n 'combobox',\n 'listbox',\n 'menuitem',\n 'option',\n 'searchbox',\n 'slider',\n 'spinbutton',\n 'switch',\n 'tab',\n 'treeitem',\n]);\n\nfunction processDualModeTree(\n nodes: DualModeNode[],\n refs: RefMap,\n interactiveOnly: boolean = false,\n depth: number = 0\n): string {\n const lines: string[] = [];\n\n for (const node of nodes) {\n const core = node.core;\n if (!core.visible) continue;\n\n const semantics = node.xrayMode?.semantics || {};\n const interaction = node.xrayMode?.interaction || {};\n const design = node.designMode || {};\n\n const role = (semantics.role || core.className || 'unknown').toLowerCase();\n let name = semantics.name || core.text || core.contentDescription || '';\n name = name.replace(/\\s+/g, ' ').trim();\n\n // Smart Merge: Use child text if name is empty\n if (name === '' && node.children && node.children.length > 0) {\n const textChild = node.children.find((c) => c.core.className === '#text.StaticText');\n if (textChild) {\n name = (textChild.core.text || '').trim();\n }\n }\n\n const isInteractive =\n core.clickable ||\n INTERACTIVE_ROLES.has(role) ||\n semantics.intentTags?.includes('interactive');\n\n if (interactiveOnly && !isInteractive && (!node.children || node.children.length === 0)) {\n continue;\n }\n\n let line = `${' '.repeat(depth)}- ${role}`;\n if (name) line += ` \"${name.replace(/\"/g, '\\\\\"')}\"`;\n\n if (isInteractive || (name && !['unknown', 'generic', 'group'].includes(role))) {\n const ref = nextRef();\n line += ` [ref=${ref}]`;\n\n const safeNameDouble = name.replace(/\"/g, '\\\\\"');\n let selector = '';\n if (['button', 'link', 'textbox', 'checkbox', 'radio'].includes(role)) {\n if (name) selector = `getByRole('${role}', { name: \"${safeNameDouble}\" })`;\n else selector = `getByRole('${role}')`;\n } else if (name) {\n selector = `getByText(\"${safeNameDouble}\")`;\n } else {\n selector = `locator('.${core.className || role}')`;\n }\n\n refs[ref] = {\n selector,\n role,\n name,\n bounds: core.bounds,\n nodeId: core.nodeId,\n };\n }\n\n // --- FULL METADATA OUTPUT ---\n\n // 1. Core Info (filtered to interesting flags)\n const coreInfo: Record<string, boolean> = {};\n if (core.clickable) coreInfo.clickable = true;\n if (core.longClickable) coreInfo.longClickable = true;\n if (core.scrollable) coreInfo.scrollable = true;\n if (core.focusable) coreInfo.focusable = true;\n if (core.editable) coreInfo.editable = true;\n if (core.checkable) coreInfo.checkable = true;\n if (core.checked) coreInfo.checked = true;\n if (core.selected) coreInfo.selected = true;\n if (core.focused) coreInfo.focused = true;\n if (!core.enabled) coreInfo.disabled = true;\n\n // 2. Xray Info (semantics + interaction)\n const xrayInfo: any = {};\n if (semantics.importanceScore) xrayInfo.importance = semantics.importanceScore;\n if (semantics.intentTags?.length) xrayInfo.intent = semantics.intentTags;\n if (interaction.availableActions?.length) xrayInfo.actions = interaction.availableActions;\n if (interaction.affordanceScore) xrayInfo.affordance = interaction.affordanceScore;\n\n // 3. Design Info (visual + layout + spatial)\n // Only include if non-default/interesting\n const designInfo: any = {};\n if (design.visual) {\n if (design.visual.backgroundColor) designInfo.bg = design.visual.backgroundColor;\n if (design.visual.foregroundColor) designInfo.fg = design.visual.foregroundColor;\n if (design.visual.fontSize) designInfo.fontSize = design.visual.fontSize;\n if (design.visual.fontWeight && design.visual.fontWeight !== 400)\n designInfo.weight = design.visual.fontWeight;\n if (design.visual.opacity !== 1) designInfo.opacity = design.visual.opacity;\n }\n if (design.layout) {\n if (design.layout.zIndex !== 0) designInfo.zIndex = design.layout.zIndex;\n if (design.layout.isFixedPosition) designInfo.fixed = true;\n if (design.layout.isSticky) designInfo.sticky = true;\n }\n if (design.spatial) {\n if (!design.spatial.isAboveFold) designInfo.belowFold = true;\n if (design.spatial.visualProminenceScore)\n designInfo.prominence = design.spatial.visualProminenceScore;\n }\n\n // Append JSON objects to line, indented\n const indent = ' '.repeat(depth + 1);\n\n if (Object.keys(coreInfo).length > 0) {\n line += `\\n${indent}core: ${JSON.stringify(coreInfo)}`;\n }\n if (Object.keys(xrayInfo).length > 0) {\n line += `\\n${indent}xray: ${JSON.stringify(xrayInfo)}`;\n }\n if (Object.keys(designInfo).length > 0) {\n line += `\\n${indent}design: ${JSON.stringify(designInfo)}`;\n }\n\n lines.push(line);\n\n if (node.children) {\n const filteredChildren = node.children.filter((c) => c.core.className !== '#text.StaticText');\n if (filteredChildren.length > 0) {\n const childrenStr = processDualModeTree(filteredChildren, refs, interactiveOnly, depth + 1);\n if (childrenStr) lines.push(childrenStr);\n }\n }\n }\n\n return lines.join('\\n');\n}\n\nfunction processStandardTree(\n nodes: HydratedAXNode[],\n refs: RefMap,\n interactiveOnly: boolean,\n depth: number = 0\n): string {\n const lines: string[] = [];\n\n for (const node of nodes) {\n const role = (node.role?.value || 'unknown').toLowerCase();\n let name = node.name?.value || '';\n name = name.replace(/\\s+/g, ' ').trim();\n\n const isInteractive = INTERACTIVE_ROLES.has(role);\n\n let line = `${' '.repeat(depth)}- ${role}`;\n if (name) {\n line += ` \"${name.replace(/\"/g, '\\\\\"')}\"`;\n }\n\n if (isInteractive || (name && role !== 'unknown')) {\n const ref = nextRef();\n line += ` [ref=${ref}]`;\n\n const safeNameDouble = name.replace(/\"/g, '\\\\\"');\n let selector = '';\n if (isInteractive) {\n if (name) selector = `getByRole('${role}', { name: \"${safeNameDouble}\" })`;\n else selector = `getByRole('${role}')`;\n } else if (name) {\n selector = `getByText(\"${safeNameDouble}\")`;\n } else {\n selector = `locator('${role}')`;\n }\n\n refs[ref] = {\n selector: selector,\n role: role,\n name: name,\n };\n }\n\n lines.push(line);\n\n if (node.children && node.children.length > 0) {\n const childrenTree = processStandardTree(node.children, refs, interactiveOnly, depth + 1);\n if (childrenTree) lines.push(childrenTree);\n }\n }\n\n return lines.join('\\n');\n}\n","/**\n * iOS Simulator Manager - Manages iOS Simulator and Safari automation via Appium.\n *\n * This provides 1:1 command parity with BrowserManager for iOS Safari.\n */\n\n// Declare browser globals used in execute() callbacks - these run in browser context, not Node\ndeclare const document: any;\ndeclare const window: any;\n\nimport { Simctl } from 'node-simctl';\nimport { remote, type Browser as WDIOBrowser } from 'webdriverio';\nimport { spawn, type ChildProcess } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport path from 'node:path';\nimport 'node:os';\n\n// Ref map for element targeting (mirrors snapshot.ts)\nexport interface IOSRefMap {\n [ref: string]: {\n selector: string;\n role?: string;\n name?: string;\n xpath?: string;\n };\n}\n\nexport interface IOSEnhancedSnapshot {\n tree: string;\n refs: IOSRefMap;\n}\n\ninterface ConsoleMessage {\n type: string;\n text: string;\n timestamp: number;\n}\n\ninterface IOSDeviceInfo {\n name: string;\n udid: string;\n state: string;\n runtime: string;\n isAvailable: boolean;\n isRealDevice?: boolean;\n}\n\n/**\n * Manages iOS Simulator and Safari automation via Appium\n */\nexport class IOSManager {\n private simctl: Simctl;\n private browser: WDIOBrowser | null = null;\n private appiumProcess: ChildProcess | null = null;\n private deviceUdid: string | null = null;\n private deviceName: string | null = null;\n private consoleMessages: ConsoleMessage[] = [];\n private refMap: IOSRefMap = {};\n private lastSnapshot: string = '';\n private refCounter: number = 0;\n\n // Default Appium port\n private static readonly APPIUM_PORT = 4723;\n private static readonly APPIUM_HOST = '127.0.0.1';\n\n constructor() {\n this.simctl = new Simctl();\n }\n\n /**\n * Check if browser is launched\n */\n isLaunched(): boolean {\n return this.browser !== null;\n }\n\n /**\n * List connected real iOS devices\n */\n private async listRealDevices(): Promise<IOSDeviceInfo[]> {\n const devices: IOSDeviceInfo[] = [];\n\n try {\n // Use xcrun xctrace to list connected devices\n const { execSync } = await import('node:child_process');\n const output = execSync('xcrun xctrace list devices 2>/dev/null || true', {\n encoding: 'utf-8',\n timeout: 10000,\n });\n\n // Parse output - format is:\n // == Devices ==\n // Device Name (OS Version) (UDID)\n // Real devices show version as just \"26.2\", simulators as \"iOS 18.0\"\n const lines = output.split('\\n');\n let inDevicesSection = false;\n\n for (const line of lines) {\n if (line.includes('== Devices ==')) {\n inDevicesSection = true;\n continue;\n }\n // Stop at Simulators or Devices Offline section\n if (line.includes('== Simulators ==') || line.includes('== Devices Offline ==')) {\n break;\n }\n\n if (inDevicesSection && line.trim()) {\n // Match pattern: \"Device Name (version) (UDID)\"\n const match = line.match(/^(.+?)\\s+\\(([^)]+)\\)\\s+\\(([A-F0-9-]+)\\)$/i);\n if (match) {\n const [, name, version, udid] = match;\n const nameLower = name.toLowerCase();\n // Include iOS devices: either name contains iPhone/iPad, or version looks like iOS\n // (a simple version number like \"26.2\" or \"18.6\") and isn't a Mac\n const isIOS =\n nameLower.includes('iphone') ||\n nameLower.includes('ipad') ||\n version.includes('iOS') ||\n version.includes('iPadOS');\n const isMac =\n nameLower.includes('mac') ||\n nameLower.includes('macbook') ||\n nameLower.includes('imac');\n\n if (isIOS || (!isMac && /^\\d+\\.\\d+(\\.\\d+)?$/.test(version))) {\n devices.push({\n name: name.trim(),\n udid: udid,\n state: 'Connected',\n runtime: `iOS ${version}`,\n isAvailable: true,\n isRealDevice: true,\n });\n }\n }\n }\n }\n } catch {\n // Ignore errors - real device listing is optional\n }\n\n return devices;\n }\n\n /**\n * List available iOS simulators\n */\n async listDevices(): Promise<IOSDeviceInfo[]> {\n const devices: IOSDeviceInfo[] = [];\n\n try {\n const rawDevices = await this.simctl.getDevices();\n\n for (const [runtime, deviceList] of Object.entries(rawDevices)) {\n if (!Array.isArray(deviceList)) continue;\n\n for (const device of deviceList) {\n // Only include iPhone and iPad simulators\n if (device.name && (device.name.includes('iPhone') || device.name.includes('iPad'))) {\n devices.push({\n name: device.name,\n udid: device.udid,\n state: device.state,\n runtime: runtime,\n isAvailable: device.isAvailable ?? true,\n isRealDevice: false,\n });\n }\n }\n }\n } catch (error) {\n throw new Error(\n `Failed to list iOS simulators. Is Xcode installed? Error: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n\n return devices;\n }\n\n /**\n * List all devices (simulators + real devices)\n */\n async listAllDevices(): Promise<IOSDeviceInfo[]> {\n const [simulators, realDevices] = await Promise.all([\n this.listDevices(),\n this.listRealDevices(),\n ]);\n\n // Real devices first, then simulators\n return [...realDevices, ...simulators];\n }\n\n /**\n * Find the best default device (most recent iPhone)\n */\n private async findDefaultDevice(): Promise<IOSDeviceInfo | null> {\n const devices = await this.listDevices();\n\n // Filter to available iPhones, prefer Pro models, then by name (which typically indicates recency)\n const iphones = devices\n .filter((d) => d.isAvailable && d.name.includes('iPhone'))\n .sort((a, b) => {\n // Prefer Pro models\n const aIsPro = a.name.includes('Pro') ? 1 : 0;\n const bIsPro = b.name.includes('Pro') ? 1 : 0;\n if (aIsPro !== bIsPro) return bIsPro - aIsPro;\n\n // Then sort by name descending (iPhone 15 > iPhone 14)\n return b.name.localeCompare(a.name);\n });\n\n return iphones[0] ?? null;\n }\n\n /**\n * Find device by name or UDID (searches both simulators and real devices)\n */\n private async findDevice(nameOrUdid: string): Promise<IOSDeviceInfo | null> {\n const devices = await this.listAllDevices();\n\n // Try exact UDID match first\n const byUdid = devices.find((d) => d.udid === nameOrUdid);\n if (byUdid) return byUdid;\n\n // Try exact name match\n const byExactName = devices.find((d) => d.name === nameOrUdid);\n if (byExactName) return byExactName;\n\n // Try partial name match\n const byPartialName = devices.find((d) =>\n d.name.toLowerCase().includes(nameOrUdid.toLowerCase())\n );\n return byPartialName ?? null;\n }\n\n /**\n * Check if Appium is installed\n */\n private async checkAppiumInstalled(): Promise<boolean> {\n return new Promise((resolve) => {\n const proc = spawn('appium', ['--version'], { shell: true });\n proc.on('close', (code) => resolve(code === 0));\n proc.on('error', () => resolve(false));\n });\n }\n\n /**\n * Check if Appium server is already running\n */\n private async isAppiumRunning(): Promise<boolean> {\n try {\n const response = await fetch(\n `http://${IOSManager.APPIUM_HOST}:${IOSManager.APPIUM_PORT}/status`\n );\n return response.ok;\n } catch {\n return false;\n }\n }\n\n /**\n * Start Appium server if not already running\n */\n private async startAppiumServer(): Promise<void> {\n if (await this.isAppiumRunning()) {\n return; // Already running\n }\n\n if (!(await this.checkAppiumInstalled())) {\n throw new Error(\n 'Appium not installed. Run: npm install -g appium && appium driver install xcuitest'\n );\n }\n\n return new Promise((resolve, reject) => {\n this.appiumProcess = spawn(\n 'appium',\n ['--port', String(IOSManager.APPIUM_PORT), '--relaxed-security'],\n {\n shell: true,\n stdio: ['ignore', 'pipe', 'pipe'],\n }\n );\n\n let started = false;\n const timeout = setTimeout(() => {\n if (!started) {\n reject(new Error('Appium server failed to start within 30 seconds'));\n }\n }, 30000);\n\n this.appiumProcess.stdout?.on('data', (data: Buffer) => {\n const output = data.toString();\n if (output.includes('Appium REST http interface listener started')) {\n started = true;\n clearTimeout(timeout);\n resolve();\n }\n });\n\n this.appiumProcess.stderr?.on('data', (data: Buffer) => {\n const output = data.toString();\n // Appium logs to stderr for info messages too\n if (output.includes('Appium REST http interface listener started')) {\n started = true;\n clearTimeout(timeout);\n resolve();\n }\n });\n\n this.appiumProcess.on('error', (err) => {\n clearTimeout(timeout);\n reject(new Error(`Failed to start Appium: ${err.message}`));\n });\n\n this.appiumProcess.on('close', (code) => {\n if (!started) {\n clearTimeout(timeout);\n reject(new Error(`Appium exited with code ${code}`));\n }\n });\n });\n }\n\n /**\n * Boot the iOS simulator\n */\n private async bootSimulator(udid: string): Promise<void> {\n try {\n const devices = await this.simctl.getDevices();\n let currentState: string | undefined;\n\n // Find current device state\n for (const deviceList of Object.values(devices)) {\n if (!Array.isArray(deviceList)) continue;\n const device = (deviceList as any[]).find((d: any) => d.udid === udid);\n if (device) {\n currentState = device.state;\n break;\n }\n }\n\n if (currentState === 'Booted') {\n return; // Already booted\n }\n\n // node-simctl expects udid to be set on the instance\n this.simctl.udid = udid;\n await this.simctl.bootDevice();\n\n // Wait for device to be fully booted\n let attempts = 0;\n while (attempts < 60) {\n const updatedDevices = await this.simctl.getDevices();\n for (const deviceList of Object.values(updatedDevices)) {\n if (!Array.isArray(deviceList)) continue;\n const device = (deviceList as any[]).find((d: any) => d.udid === udid);\n if (device?.state === 'Booted') {\n return;\n }\n }\n await new Promise((r) => setTimeout(r, 1000));\n attempts++;\n }\n\n throw new Error('Simulator failed to boot within 60 seconds');\n } catch (error) {\n throw new Error(\n `Failed to boot simulator: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n /**\n * Launch iOS Safari via Appium\n */\n async launch(\n options: {\n device?: string;\n udid?: string;\n headless?: boolean;\n } = {}\n ): Promise<void> {\n if (this.isLaunched()) {\n return; // Already launched\n }\n\n // Find device\n let device: IOSDeviceInfo | null = null;\n\n if (options.udid) {\n device = await this.findDevice(options.udid);\n if (!device) {\n throw new Error(`Device with UDID ${options.udid} not found`);\n }\n } else if (options.device) {\n device = await this.findDevice(options.device);\n if (!device) {\n throw new Error(`Device \"${options.device}\" not found. Run: agent-browser device list`);\n }\n } else {\n // Check environment variable\n const envDevice = process.env.AGENT_BROWSER_IOS_DEVICE;\n const envUdid = process.env.AGENT_BROWSER_IOS_UDID;\n\n if (envUdid) {\n device = await this.findDevice(envUdid);\n if (!device) {\n throw new Error(`Device with UDID ${envUdid} not found. Run: agent-browser device list`);\n }\n } else if (envDevice) {\n device = await this.findDevice(envDevice);\n if (!device) {\n throw new Error(`Device \"${envDevice}\" not found. Run: agent-browser device list`);\n }\n } else {\n device = await this.findDefaultDevice();\n if (!device) {\n throw new Error(\n 'No iOS simulators available. Open Xcode and download simulator runtimes.'\n );\n }\n }\n }\n\n this.deviceUdid = device.udid;\n this.deviceName = device.name;\n\n // Start Appium server\n await this.startAppiumServer();\n\n // Boot simulator (skip for real devices - they're already running)\n if (!device.isRealDevice) {\n await this.bootSimulator(device.udid);\n }\n\n // Connect to Safari via Appium\n try {\n this.browser = await remote({\n hostname: IOSManager.APPIUM_HOST,\n port: IOSManager.APPIUM_PORT,\n path: '/',\n capabilities: {\n platformName: 'iOS',\n 'appium:automationName': 'XCUITest',\n 'appium:deviceName': device.name,\n 'appium:udid': device.udid,\n browserName: 'Safari',\n 'appium:noReset': true,\n 'appium:newCommandTimeout': 300,\n },\n connectionRetryTimeout: 120000,\n connectionRetryCount: 3,\n });\n } catch (error) {\n throw new Error(\n `Failed to connect to Safari: ${error instanceof Error ? error.message : String(error)}. ` +\n 'Make sure XCUITest driver is installed: appium driver install xcuitest'\n );\n }\n }\n\n /**\n * Navigate to URL\n */\n async navigate(url: string): Promise<{ url: string; title: string }> {\n if (!this.browser) {\n throw new Error('iOS browser not launched. Call launch first.');\n }\n\n await this.browser.url(url);\n\n // Wait for page to load\n await this.browser.waitUntil(\n async () => {\n const state = (await this.browser!.execute(\n 'return document.readyState'\n )) as unknown as string;\n return state === 'complete';\n },\n { timeout: 30000, interval: 500 }\n );\n\n const title = await this.browser.getTitle();\n const currentUrl = await this.browser.getUrl();\n\n return { url: currentUrl, title };\n }\n\n /**\n * Get current URL\n */\n async getUrl(): Promise<string> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n return this.browser.getUrl();\n }\n\n /**\n * Get page title\n */\n async getTitle(): Promise<string> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n return this.browser.getTitle();\n }\n\n /**\n * Click/tap an element\n */\n async click(selector: string): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const element = await this.getElement(selector);\n await element.click();\n }\n\n /**\n * Alias for click (semantic clarity for touch)\n */\n async tap(selector: string): Promise<void> {\n return this.click(selector);\n }\n\n /**\n * Type text into an element\n */\n async type(\n selector: string,\n text: string,\n options?: { delay?: number; clear?: boolean }\n ): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const element = await this.getElement(selector);\n\n if (options?.clear) {\n await element.clearValue();\n }\n\n // WebdriverIO doesn't have a delay option, so we simulate it\n if (options?.delay && options.delay > 0) {\n for (const char of text) {\n await element.addValue(char);\n await new Promise((r) => setTimeout(r, options.delay));\n }\n } else {\n await element.addValue(text);\n }\n }\n\n /**\n * Fill an element (clear first, then type)\n */\n async fill(selector: string, value: string): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const element = await this.getElement(selector);\n await element.clearValue();\n await element.setValue(value);\n }\n\n /**\n * Get element by selector or ref\n */\n private async getElement(selectorOrRef: string) {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n // Check if it's a ref\n const refData = this.getRefData(selectorOrRef);\n if (refData) {\n if (refData.xpath) {\n return this.browser.$(refData.xpath);\n }\n return this.browser.$(refData.selector);\n }\n\n // Regular CSS selector\n return this.browser.$(selectorOrRef);\n }\n\n /**\n * Get ref data from ref string\n */\n private getRefData(refArg: string): IOSRefMap[string] | null {\n let ref: string | null = null;\n\n if (refArg.startsWith('@')) {\n ref = refArg.slice(1);\n } else if (refArg.startsWith('ref=')) {\n ref = refArg.slice(4);\n } else if (/^e\\d+$/.test(refArg)) {\n ref = refArg;\n }\n\n if (ref && this.refMap[ref]) {\n return this.refMap[ref];\n }\n\n return null;\n }\n\n /**\n * Take a screenshot\n */\n async screenshot(options?: {\n path?: string;\n fullPage?: boolean;\n }): Promise<{ path?: string; base64?: string }> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const base64 = await this.browser.takeScreenshot();\n\n if (options?.path) {\n const { writeFileSync, mkdirSync } = await import('node:fs');\n const dir = path.dirname(options.path);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n writeFileSync(options.path, base64, 'base64');\n return { path: options.path };\n }\n\n return { base64 };\n }\n\n /**\n * Get page snapshot with refs\n */\n async getSnapshot(options?: { interactive?: boolean }): Promise<IOSEnhancedSnapshot> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n this.refCounter = 0;\n this.refMap = {};\n\n // Get page structure via JavaScript execution\n // Note: The function runs in browser context, so we use 'any' for DOM types\n const snapshot = await this.browser.execute(function (interactiveOnly: boolean): any {\n const INTERACTIVE_ROLES = new Set([\n 'button',\n 'link',\n 'textbox',\n 'checkbox',\n 'radio',\n 'combobox',\n 'listbox',\n 'menuitem',\n 'option',\n 'searchbox',\n 'slider',\n 'spinbutton',\n 'switch',\n 'tab',\n 'treeitem',\n ]);\n\n const INTERACTIVE_TAGS = new Set([\n 'A',\n 'BUTTON',\n 'INPUT',\n 'SELECT',\n 'TEXTAREA',\n 'DETAILS',\n 'SUMMARY',\n ]);\n\n function getXPath(element: any): string {\n if (element.id) {\n return `//*[@id=\"${element.id}\"]`;\n }\n\n const parts: string[] = [];\n let current: any = element;\n\n while (current && current.nodeType === 1) {\n // Node.ELEMENT_NODE = 1\n let index = 1;\n let sibling: any = current.previousElementSibling;\n\n while (sibling) {\n if (sibling.nodeName === current.nodeName) {\n index++;\n }\n sibling = sibling.previousElementSibling;\n }\n\n const tagName = current.nodeName.toLowerCase();\n parts.unshift(`${tagName}[${index}]`);\n current = current.parentElement;\n }\n\n return '/' + parts.join('/');\n }\n\n function getAccessibleName(element: any): string {\n // aria-label takes precedence\n const ariaLabel = element.getAttribute('aria-label');\n if (ariaLabel) return ariaLabel;\n\n // For inputs, check placeholder and label\n const tagName = element.tagName;\n if (tagName === 'INPUT' || tagName === 'TEXTAREA') {\n const id = element.id;\n if (id) {\n const label = (document as any).querySelector(`label[for=\"${id}\"]`);\n if (label) return label.textContent?.trim() || '';\n }\n if (element.placeholder) return element.placeholder;\n }\n\n // For buttons and links, use text content\n if (tagName === 'BUTTON' || tagName === 'A') {\n return element.textContent?.trim() || '';\n }\n\n // aria-labelledby\n const labelledBy = element.getAttribute('aria-labelledby');\n if (labelledBy) {\n const labelElement = (document as any).getElementById(labelledBy);\n if (labelElement) return labelElement.textContent?.trim() || '';\n }\n\n return element.textContent?.trim().slice(0, 50) || '';\n }\n\n function getRole(element: any): string | null {\n // Explicit role\n const role = element.getAttribute('role');\n if (role) return role;\n\n // Implicit roles\n const tag = element.tagName;\n if (tag === 'A' && element.hasAttribute('href')) return 'link';\n if (tag === 'BUTTON') return 'button';\n if (tag === 'INPUT') {\n const type = element.type;\n if (type === 'checkbox') return 'checkbox';\n if (type === 'radio') return 'radio';\n if (type === 'text' || type === 'email' || type === 'password' || type === 'search')\n return 'textbox';\n if (type === 'submit' || type === 'button') return 'button';\n }\n if (tag === 'TEXTAREA') return 'textbox';\n if (tag === 'SELECT') return 'combobox';\n if (\n tag === 'H1' ||\n tag === 'H2' ||\n tag === 'H3' ||\n tag === 'H4' ||\n tag === 'H5' ||\n tag === 'H6'\n )\n return 'heading';\n if (tag === 'IMG') return 'img';\n if (tag === 'NAV') return 'navigation';\n if (tag === 'MAIN') return 'main';\n if (tag === 'HEADER') return 'banner';\n if (tag === 'FOOTER') return 'contentinfo';\n\n return null;\n }\n\n function traverse(element: any, depth: number): any {\n if (depth > 10) return null; // Limit depth\n\n const tag = element.tagName;\n const role = getRole(element);\n const name = getAccessibleName(element);\n const isInteractive =\n INTERACTIVE_TAGS.has(tag) || (role !== null && INTERACTIVE_ROLES.has(role));\n\n // Skip hidden elements\n const style = (window as any).getComputedStyle(element);\n if (style.display === 'none' || style.visibility === 'hidden') {\n return null;\n }\n\n const children: any[] = [];\n for (const child of element.children) {\n const childInfo = traverse(child, depth + 1);\n if (childInfo) {\n children.push(childInfo);\n }\n }\n\n // In interactive mode, skip non-interactive elements without interactive children\n if (interactiveOnly && !isInteractive && children.length === 0) {\n return null;\n }\n\n return {\n tag,\n role,\n name,\n text: element.textContent?.trim().slice(0, 100) || '',\n isInteractive,\n xpath: getXPath(element),\n children,\n };\n }\n\n const root = traverse((document as any).body, 0);\n return root;\n }, options?.interactive ?? false);\n\n // Build tree string and refs\n const lines: string[] = [];\n const buildTree = (node: any, indent: number) => {\n if (!node) return;\n\n const prefix = ' '.repeat(indent) + '- ';\n const role = node.role || node.tag.toLowerCase();\n const name = node.name;\n\n let line = `${prefix}${role}`;\n if (name) {\n line += ` \"${name}\"`;\n }\n\n // Add ref for interactive elements\n if (node.isInteractive) {\n const ref = `e${++this.refCounter}`;\n line += ` [ref=${ref}]`;\n\n this.refMap[ref] = {\n selector: node.xpath.startsWith('/') ? node.xpath : `#${node.xpath}`,\n role: node.role,\n name: node.name,\n xpath: node.xpath,\n };\n }\n\n lines.push(line);\n\n for (const child of node.children || []) {\n buildTree(child, indent + 1);\n }\n };\n\n if (snapshot) {\n buildTree(snapshot, 0);\n }\n\n const tree = lines.join('\\n') || '(empty)';\n this.lastSnapshot = tree;\n\n return { tree, refs: this.refMap };\n }\n\n /**\n * Get cached ref map\n */\n getRefMap(): IOSRefMap {\n return this.refMap;\n }\n\n /**\n * Scroll the page\n */\n async scroll(options?: {\n selector?: string;\n x?: number;\n y?: number;\n direction?: 'up' | 'down' | 'left' | 'right';\n amount?: number;\n }): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const amount = options?.amount ?? 300;\n\n if (options?.selector) {\n const element = await this.getElement(options.selector);\n await element.scrollIntoView();\n return;\n }\n\n // Use JavaScript scrolling\n let deltaX = options?.x ?? 0;\n let deltaY = options?.y ?? 0;\n\n if (options?.direction) {\n switch (options.direction) {\n case 'up':\n deltaY = -amount;\n break;\n case 'down':\n deltaY = amount;\n break;\n case 'left':\n deltaX = -amount;\n break;\n case 'right':\n deltaX = amount;\n break;\n }\n }\n\n await this.browser.execute(\n function (x: number, y: number) {\n (window as any).scrollBy(x, y);\n },\n deltaX,\n deltaY\n );\n }\n\n /**\n * Swipe gesture (iOS-specific)\n */\n async swipe(\n direction: 'up' | 'down' | 'left' | 'right',\n options?: { distance?: number }\n ): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const distance = options?.distance ?? 300;\n\n // Map direction to scroll (opposite direction)\n const scrollDirection = {\n up: 'down',\n down: 'up',\n left: 'right',\n right: 'left',\n }[direction] as 'up' | 'down' | 'left' | 'right';\n\n await this.scroll({ direction: scrollDirection, amount: distance });\n }\n\n /**\n * Execute JavaScript\n */\n async evaluate<T = unknown>(script: string, ...args: unknown[]): Promise<T> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n // Execute the script directly - WebdriverIO handles the context\n const result = await this.browser.execute(\n function (code: string, evalArgs: any[]) {\n // Create a function from the code and execute it\n const fn = new Function(...evalArgs.map((_: any, i: number) => `arg${i}`), code);\n return fn(...evalArgs);\n },\n script.includes('return') ? script : `return (${script})`,\n args\n );\n\n return result as T;\n }\n\n /**\n * Wait for element\n */\n async wait(options: {\n selector?: string;\n timeout?: number;\n state?: 'attached' | 'detached' | 'visible' | 'hidden';\n }): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const timeout = options.timeout ?? 30000;\n\n if (options.selector) {\n const element = await this.getElement(options.selector);\n\n switch (options.state) {\n case 'detached':\n await element.waitForExist({ timeout, reverse: true });\n break;\n case 'hidden':\n await element.waitForDisplayed({ timeout, reverse: true });\n break;\n case 'visible':\n await element.waitForDisplayed({ timeout });\n break;\n case 'attached':\n default:\n await element.waitForExist({ timeout });\n break;\n }\n } else {\n // Just wait for timeout\n await new Promise((r) => setTimeout(r, timeout));\n }\n }\n\n /**\n * Press a key\n */\n async press(key: string): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n // Map common key names\n const keyMap: Record<string, string> = {\n Enter: '\\uE007',\n Tab: '\\uE004',\n Escape: '\\uE00C',\n Backspace: '\\uE003',\n Delete: '\\uE017',\n ArrowUp: '\\uE013',\n ArrowDown: '\\uE015',\n ArrowLeft: '\\uE012',\n ArrowRight: '\\uE014',\n };\n\n const mappedKey = keyMap[key] ?? key;\n await this.browser.keys(mappedKey);\n }\n\n /**\n * Hover over element (limited on touch - just scrolls into view)\n */\n async hover(selector: string): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const element = await this.getElement(selector);\n await element.scrollIntoView();\n }\n\n /**\n * Get page content (HTML)\n */\n async getContent(selector?: string): Promise<string> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n if (selector) {\n const element = await this.getElement(selector);\n return element.getHTML();\n }\n\n return this.browser.getPageSource();\n }\n\n /**\n * Get text content of element\n */\n async getText(selector: string): Promise<string> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const element = await this.getElement(selector);\n return element.getText();\n }\n\n /**\n * Get attribute value\n */\n async getAttribute(selector: string, attribute: string): Promise<string | null> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const element = await this.getElement(selector);\n return element.getAttribute(attribute);\n }\n\n /**\n * Check if element is visible\n */\n async isVisible(selector: string): Promise<boolean> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n try {\n const element = await this.getElement(selector);\n return element.isDisplayed();\n } catch {\n return false;\n }\n }\n\n /**\n * Check if element is enabled\n */\n async isEnabled(selector: string): Promise<boolean> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const element = await this.getElement(selector);\n return element.isEnabled();\n }\n\n /**\n * Navigate back\n */\n async goBack(): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n await this.browser.back();\n }\n\n /**\n * Navigate forward\n */\n async goForward(): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n await this.browser.forward();\n }\n\n /**\n * Reload page\n */\n async reload(): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n await this.browser.refresh();\n }\n\n /**\n * Select option(s) from dropdown\n */\n async select(selector: string, values: string | string[]): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const element = await this.getElement(selector);\n const valueArray = Array.isArray(values) ? values : [values];\n\n for (const value of valueArray) {\n await element.selectByAttribute('value', value);\n }\n }\n\n /**\n * Check a checkbox\n */\n async check(selector: string): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const element = await this.getElement(selector);\n const isChecked = await element.isSelected();\n if (!isChecked) {\n await element.click();\n }\n }\n\n /**\n * Uncheck a checkbox\n */\n async uncheck(selector: string): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const element = await this.getElement(selector);\n const isChecked = await element.isSelected();\n if (isChecked) {\n await element.click();\n }\n }\n\n /**\n * Focus an element\n */\n async focus(selector: string): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const element = await this.getElement(selector);\n await this.browser.execute(function (el: any) {\n el.focus();\n }, element as any);\n }\n\n /**\n * Clear input field\n */\n async clear(selector: string): Promise<void> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const element = await this.getElement(selector);\n await element.clearValue();\n }\n\n /**\n * Get element count\n */\n async count(selector: string): Promise<number> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n const elements = await this.browser.$$(selector);\n return elements.length;\n }\n\n /**\n * Get bounding box\n */\n async getBoundingBox(\n selector: string\n ): Promise<{ x: number; y: number; width: number; height: number } | null> {\n if (!this.browser) {\n throw new Error('iOS browser not launched');\n }\n\n try {\n const element = await this.getElement(selector);\n const location = await element.getLocation();\n const size = await element.getSize();\n return {\n x: location.x,\n y: location.y,\n width: size.width,\n height: size.height,\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Get device info\n */\n getDeviceInfo(): { name: string; udid: string } | null {\n if (!this.deviceName || !this.deviceUdid) {\n return null;\n }\n return {\n name: this.deviceName,\n udid: this.deviceUdid,\n };\n }\n\n /**\n * Close browser and cleanup\n */\n async close(): Promise<void> {\n if (this.browser) {\n try {\n await this.browser.deleteSession();\n } catch {\n // Ignore cleanup errors\n }\n this.browser = null;\n }\n\n if (this.appiumProcess) {\n this.appiumProcess.kill();\n this.appiumProcess = null;\n }\n\n // Optionally shutdown simulator\n if (this.deviceUdid) {\n try {\n this.simctl.udid = this.deviceUdid;\n await this.simctl.shutdownDevice();\n } catch {\n // Ignore - simulator might already be shutdown\n }\n }\n\n this.deviceUdid = null;\n this.deviceName = null;\n this.refMap = {};\n this.lastSnapshot = '';\n this.refCounter = 0;\n }\n}\n","import { z } from 'zod';\nimport type { Command, Response } from './types.js';\n\n// Base schema for all commands\nconst baseCommandSchema = z.object({\n id: z.string(),\n action: z.string(),\n});\n\n// Individual action schemas\nconst launchSchema = baseCommandSchema.extend({\n action: z.literal('launch'),\n headless: z.boolean().optional(),\n viewport: z\n .object({\n width: z.number().positive(),\n height: z.number().positive(),\n })\n .optional(),\n browser: z.enum(['chromium', 'firefox', 'webkit']).optional(),\n cdpPort: z.number().positive().optional(),\n cdpUrl: z\n .string()\n .url()\n .refine(\n (url) =>\n url.startsWith('ws://') ||\n url.startsWith('wss://') ||\n url.startsWith('http://') ||\n url.startsWith('https://'),\n { message: 'CDP URL must start with ws://, wss://, http://, or https://' }\n )\n .optional(),\n executablePath: z.string().optional(),\n extensions: z.array(z.string()).optional(),\n headers: z.record(z.string()).optional(),\n proxy: z\n .object({\n server: z.string().min(1),\n bypass: z.string().optional(),\n username: z.string().optional(),\n password: z.string().optional(),\n })\n .optional(),\n args: z.array(z.string()).optional(),\n userAgent: z.string().optional(),\n provider: z.string().optional(),\n ignoreHTTPSErrors: z.boolean().optional(),\n profile: z.string().optional(),\n storageState: z.string().optional(),\n});\n\nconst navigateSchema = baseCommandSchema.extend({\n action: z.literal('navigate'),\n url: z.string().min(1),\n waitUntil: z.enum(['load', 'domcontentloaded', 'networkidle']).optional(),\n headers: z.record(z.string()).optional(),\n});\n\nconst clickSchema = baseCommandSchema.extend({\n action: z.literal('click'),\n selector: z.string().min(1),\n button: z.enum(['left', 'right', 'middle']).optional(),\n clickCount: z.number().positive().optional(),\n delay: z.number().nonnegative().optional(),\n});\n\nconst typeSchema = baseCommandSchema.extend({\n action: z.literal('type'),\n selector: z.string().min(1),\n text: z.string(),\n delay: z.number().nonnegative().optional(),\n clear: z.boolean().optional(),\n});\n\nconst fillSchema = baseCommandSchema.extend({\n action: z.literal('fill'),\n selector: z.string().min(1),\n value: z.string(),\n});\n\nconst checkSchema = baseCommandSchema.extend({\n action: z.literal('check'),\n selector: z.string().min(1),\n});\n\nconst uncheckSchema = baseCommandSchema.extend({\n action: z.literal('uncheck'),\n selector: z.string().min(1),\n});\n\nconst uploadSchema = baseCommandSchema.extend({\n action: z.literal('upload'),\n selector: z.string().min(1),\n files: z.union([z.string(), z.array(z.string())]),\n});\n\nconst dblclickSchema = baseCommandSchema.extend({\n action: z.literal('dblclick'),\n selector: z.string().min(1),\n});\n\nconst focusSchema = baseCommandSchema.extend({\n action: z.literal('focus'),\n selector: z.string().min(1),\n});\n\nconst dragSchema = baseCommandSchema.extend({\n action: z.literal('drag'),\n source: z.string().min(1),\n target: z.string().min(1),\n});\n\nconst frameSchema = baseCommandSchema.extend({\n action: z.literal('frame'),\n selector: z.string().min(1).optional(),\n name: z.string().optional(),\n url: z.string().optional(),\n});\n\nconst mainframeSchema = baseCommandSchema.extend({\n action: z.literal('mainframe'),\n});\n\nconst getByRoleSchema = baseCommandSchema.extend({\n action: z.literal('getbyrole'),\n role: z.string().min(1),\n name: z.string().optional(),\n exact: z.boolean().optional(),\n subaction: z.enum(['click', 'fill', 'check', 'hover']),\n value: z.string().optional(),\n});\n\nconst getByTextSchema = baseCommandSchema.extend({\n action: z.literal('getbytext'),\n text: z.string().min(1),\n exact: z.boolean().optional(),\n subaction: z.enum(['click', 'hover']),\n});\n\nconst getByLabelSchema = baseCommandSchema.extend({\n action: z.literal('getbylabel'),\n label: z.string().min(1),\n exact: z.boolean().optional(),\n subaction: z.enum(['click', 'fill', 'check']),\n value: z.string().optional(),\n});\n\nconst getByPlaceholderSchema = baseCommandSchema.extend({\n action: z.literal('getbyplaceholder'),\n placeholder: z.string().min(1),\n exact: z.boolean().optional(),\n subaction: z.enum(['click', 'fill']),\n value: z.string().optional(),\n});\n\nconst cookiesGetSchema = baseCommandSchema.extend({\n action: z.literal('cookies_get'),\n urls: z.array(z.string()).optional(),\n});\n\nconst cookiesSetSchema = baseCommandSchema.extend({\n action: z.literal('cookies_set'),\n cookies: z.array(\n z.object({\n name: z.string(),\n value: z.string(),\n url: z.string().optional(),\n domain: z.string().optional(),\n path: z.string().optional(),\n expires: z.number().optional(),\n httpOnly: z.boolean().optional(),\n secure: z.boolean().optional(),\n sameSite: z.enum(['Strict', 'Lax', 'None']).optional(),\n })\n ),\n});\n\nconst cookiesClearSchema = baseCommandSchema.extend({\n action: z.literal('cookies_clear'),\n});\n\nconst storageGetSchema = baseCommandSchema.extend({\n action: z.literal('storage_get'),\n key: z.string().optional(),\n type: z.enum(['local', 'session']),\n});\n\nconst storageSetSchema = baseCommandSchema.extend({\n action: z.literal('storage_set'),\n key: z.string().min(1),\n value: z.string(),\n type: z.enum(['local', 'session']),\n});\n\nconst storageClearSchema = baseCommandSchema.extend({\n action: z.literal('storage_clear'),\n type: z.enum(['local', 'session']),\n});\n\nconst dialogSchema = baseCommandSchema.extend({\n action: z.literal('dialog'),\n response: z.enum(['accept', 'dismiss']),\n promptText: z.string().optional(),\n});\n\nconst pdfSchema = baseCommandSchema.extend({\n action: z.literal('pdf'),\n path: z.string().min(1),\n format: z\n .enum(['Letter', 'Legal', 'Tabloid', 'Ledger', 'A0', 'A1', 'A2', 'A3', 'A4', 'A5', 'A6'])\n .optional(),\n});\n\nconst routeSchema = baseCommandSchema.extend({\n action: z.literal('route'),\n url: z.string().min(1),\n response: z\n .object({\n status: z.number().optional(),\n body: z.string().optional(),\n contentType: z.string().optional(),\n headers: z.record(z.string()).optional(),\n })\n .optional(),\n abort: z.boolean().optional(),\n});\n\nconst unrouteSchema = baseCommandSchema.extend({\n action: z.literal('unroute'),\n url: z.string().optional(),\n});\n\nconst requestsSchema = baseCommandSchema.extend({\n action: z.literal('requests'),\n filter: z.string().optional(),\n clear: z.boolean().optional(),\n});\n\nconst downloadSchema = baseCommandSchema.extend({\n action: z.literal('download'),\n selector: z.string().min(1),\n path: z.string().min(1),\n});\n\nconst geolocationSchema = baseCommandSchema.extend({\n action: z.literal('geolocation'),\n latitude: z.number(),\n longitude: z.number(),\n accuracy: z.number().optional(),\n});\n\nconst permissionsSchema = baseCommandSchema.extend({\n action: z.literal('permissions'),\n permissions: z.array(z.string()),\n grant: z.boolean(),\n});\n\nconst viewportSchema = baseCommandSchema.extend({\n action: z.literal('viewport'),\n width: z.number().positive(),\n height: z.number().positive(),\n});\n\nconst userAgentSchema = baseCommandSchema.extend({\n action: z.literal('useragent'),\n userAgent: z.string().min(1),\n});\n\nconst deviceSchema = baseCommandSchema.extend({\n action: z.literal('device'),\n device: z.string().min(1),\n});\n\nconst backSchema = baseCommandSchema.extend({\n action: z.literal('back'),\n});\n\nconst forwardSchema = baseCommandSchema.extend({\n action: z.literal('forward'),\n});\n\nconst reloadSchema = baseCommandSchema.extend({\n action: z.literal('reload'),\n});\n\nconst urlSchema = baseCommandSchema.extend({\n action: z.literal('url'),\n});\n\nconst titleSchema = baseCommandSchema.extend({\n action: z.literal('title'),\n});\n\nconst getAttributeSchema = baseCommandSchema.extend({\n action: z.literal('getattribute'),\n selector: z.string().min(1),\n attribute: z.string().min(1),\n});\n\nconst getTextSchema = baseCommandSchema.extend({\n action: z.literal('gettext'),\n selector: z.string().min(1),\n});\n\nconst isVisibleSchema = baseCommandSchema.extend({\n action: z.literal('isvisible'),\n selector: z.string().min(1),\n});\n\nconst isEnabledSchema = baseCommandSchema.extend({\n action: z.literal('isenabled'),\n selector: z.string().min(1),\n});\n\nconst isCheckedSchema = baseCommandSchema.extend({\n action: z.literal('ischecked'),\n selector: z.string().min(1),\n});\n\nconst countSchema = baseCommandSchema.extend({\n action: z.literal('count'),\n selector: z.string().min(1),\n});\n\nconst boundingBoxSchema = baseCommandSchema.extend({\n action: z.literal('boundingbox'),\n selector: z.string().min(1),\n});\n\nconst stylesSchema = baseCommandSchema.extend({\n action: z.literal('styles'),\n selector: z.string().min(1),\n});\n\nconst videoStartSchema = baseCommandSchema.extend({\n action: z.literal('video_start'),\n path: z.string().min(1),\n});\n\nconst videoStopSchema = baseCommandSchema.extend({\n action: z.literal('video_stop'),\n});\n\n// Recording schemas (Playwright native video recording)\nconst recordingStartSchema = baseCommandSchema.extend({\n action: z.literal('recording_start'),\n path: z.string().min(1),\n url: z.string().min(1).optional(),\n});\n\nconst recordingStopSchema = baseCommandSchema.extend({\n action: z.literal('recording_stop'),\n});\n\nconst recordingRestartSchema = baseCommandSchema.extend({\n action: z.literal('recording_restart'),\n path: z.string().min(1),\n url: z.string().min(1).optional(),\n});\n\nconst traceStartSchema = baseCommandSchema.extend({\n action: z.literal('trace_start'),\n screenshots: z.boolean().optional(),\n snapshots: z.boolean().optional(),\n});\n\nconst traceStopSchema = baseCommandSchema.extend({\n action: z.literal('trace_stop'),\n path: z.string().min(1),\n});\n\nconst harStartSchema = baseCommandSchema.extend({\n action: z.literal('har_start'),\n});\n\nconst harStopSchema = baseCommandSchema.extend({\n action: z.literal('har_stop'),\n path: z.string().min(1),\n});\n\nconst stateSaveSchema = baseCommandSchema.extend({\n action: z.literal('state_save'),\n path: z.string().min(1),\n});\n\nconst stateLoadSchema = baseCommandSchema.extend({\n action: z.literal('state_load'),\n path: z.string().min(1),\n});\n\nconst consoleSchema = baseCommandSchema.extend({\n action: z.literal('console'),\n clear: z.boolean().optional(),\n});\n\nconst errorsSchema = baseCommandSchema.extend({\n action: z.literal('errors'),\n clear: z.boolean().optional(),\n});\n\nconst keyboardSchema = baseCommandSchema.extend({\n action: z.literal('keyboard'),\n keys: z.string().min(1),\n});\n\nconst wheelSchema = baseCommandSchema.extend({\n action: z.literal('wheel'),\n deltaX: z.number().optional(),\n deltaY: z.number().optional(),\n selector: z.string().optional(),\n});\n\nconst tapSchema = baseCommandSchema.extend({\n action: z.literal('tap'),\n selector: z.string().min(1),\n});\n\nconst clipboardSchema = baseCommandSchema.extend({\n action: z.literal('clipboard'),\n operation: z.enum(['copy', 'paste', 'read']),\n text: z.string().optional(),\n});\n\nconst highlightSchema = baseCommandSchema.extend({\n action: z.literal('highlight'),\n selector: z.string().min(1),\n});\n\nconst clearSchema = baseCommandSchema.extend({\n action: z.literal('clear'),\n selector: z.string().min(1),\n});\n\nconst selectAllSchema = baseCommandSchema.extend({\n action: z.literal('selectall'),\n selector: z.string().min(1),\n});\n\nconst innerTextSchema = baseCommandSchema.extend({\n action: z.literal('innertext'),\n selector: z.string().min(1),\n});\n\nconst innerHtmlSchema = baseCommandSchema.extend({\n action: z.literal('innerhtml'),\n selector: z.string().min(1),\n});\n\nconst inputValueSchema = baseCommandSchema.extend({\n action: z.literal('inputvalue'),\n selector: z.string().min(1),\n});\n\nconst setValueSchema = baseCommandSchema.extend({\n action: z.literal('setvalue'),\n selector: z.string().min(1),\n value: z.string(),\n});\n\nconst dispatchSchema = baseCommandSchema.extend({\n action: z.literal('dispatch'),\n selector: z.string().min(1),\n event: z.string().min(1),\n eventInit: z.record(z.unknown()).optional(),\n});\n\nconst evalHandleSchema = baseCommandSchema.extend({\n action: z.literal('evalhandle'),\n script: z.string().min(1),\n});\n\nconst exposeSchema = baseCommandSchema.extend({\n action: z.literal('expose'),\n name: z.string().min(1),\n});\n\nconst addScriptSchema = baseCommandSchema.extend({\n action: z.literal('addscript'),\n content: z.string().optional(),\n url: z.string().optional(),\n});\n\nconst addStyleSchema = baseCommandSchema.extend({\n action: z.literal('addstyle'),\n content: z.string().optional(),\n url: z.string().optional(),\n});\n\nconst emulateMediaSchema = baseCommandSchema.extend({\n action: z.literal('emulatemedia'),\n media: z.enum(['screen', 'print']).nullable().optional(),\n colorScheme: z.enum(['light', 'dark', 'no-preference']).nullable().optional(),\n reducedMotion: z.enum(['reduce', 'no-preference']).nullable().optional(),\n forcedColors: z.enum(['active', 'none']).nullable().optional(),\n});\n\nconst offlineSchema = baseCommandSchema.extend({\n action: z.literal('offline'),\n offline: z.boolean(),\n});\n\nconst headersSchema = baseCommandSchema.extend({\n action: z.literal('headers'),\n headers: z.record(z.string()),\n});\n\nconst pauseSchema = baseCommandSchema.extend({\n action: z.literal('pause'),\n});\n\nconst getByAltTextSchema = baseCommandSchema.extend({\n action: z.literal('getbyalttext'),\n text: z.string().min(1),\n exact: z.boolean().optional(),\n subaction: z.enum(['click', 'hover']),\n});\n\nconst getByTitleSchema = baseCommandSchema.extend({\n action: z.literal('getbytitle'),\n text: z.string().min(1),\n exact: z.boolean().optional(),\n subaction: z.enum(['click', 'hover']),\n});\n\nconst getByTestIdSchema = baseCommandSchema.extend({\n action: z.literal('getbytestid'),\n testId: z.string().min(1),\n subaction: z.enum(['click', 'fill', 'check', 'hover']),\n value: z.string().optional(),\n});\n\nconst nthSchema = baseCommandSchema.extend({\n action: z.literal('nth'),\n selector: z.string().min(1),\n index: z.number(),\n subaction: z.enum(['click', 'fill', 'check', 'hover', 'text']),\n value: z.string().optional(),\n});\n\nconst waitForUrlSchema = baseCommandSchema.extend({\n action: z.literal('waitforurl'),\n url: z.string().min(1),\n timeout: z.number().positive().optional(),\n});\n\nconst waitForLoadStateSchema = baseCommandSchema.extend({\n action: z.literal('waitforloadstate'),\n state: z.enum(['load', 'domcontentloaded', 'networkidle']),\n timeout: z.number().positive().optional(),\n});\n\nconst setContentSchema = baseCommandSchema.extend({\n action: z.literal('setcontent'),\n html: z.string(),\n});\n\nconst timezoneSchema = baseCommandSchema.extend({\n action: z.literal('timezone'),\n timezone: z.string().min(1),\n});\n\nconst localeSchema = baseCommandSchema.extend({\n action: z.literal('locale'),\n locale: z.string().min(1),\n});\n\nconst credentialsSchema = baseCommandSchema.extend({\n action: z.literal('credentials'),\n username: z.string(),\n password: z.string(),\n});\n\nconst mouseMoveSchema = baseCommandSchema.extend({\n action: z.literal('mousemove'),\n x: z.number(),\n y: z.number(),\n});\n\nconst mouseDownSchema = baseCommandSchema.extend({\n action: z.literal('mousedown'),\n button: z.enum(['left', 'right', 'middle']).optional(),\n});\n\nconst mouseUpSchema = baseCommandSchema.extend({\n action: z.literal('mouseup'),\n button: z.enum(['left', 'right', 'middle']).optional(),\n});\n\nconst bringToFrontSchema = baseCommandSchema.extend({\n action: z.literal('bringtofront'),\n});\n\nconst waitForFunctionSchema = baseCommandSchema.extend({\n action: z.literal('waitforfunction'),\n expression: z.string().min(1),\n timeout: z.number().positive().optional(),\n});\n\nconst scrollIntoViewSchema = baseCommandSchema.extend({\n action: z.literal('scrollintoview'),\n selector: z.string().min(1),\n});\n\nconst addInitScriptSchema = baseCommandSchema.extend({\n action: z.literal('addinitscript'),\n script: z.string().min(1),\n});\n\nconst keyDownSchema = baseCommandSchema.extend({\n action: z.literal('keydown'),\n key: z.string().min(1),\n});\n\nconst keyUpSchema = baseCommandSchema.extend({\n action: z.literal('keyup'),\n key: z.string().min(1),\n});\n\nconst insertTextSchema = baseCommandSchema.extend({\n action: z.literal('inserttext'),\n text: z.string(),\n});\n\nconst multiSelectSchema = baseCommandSchema.extend({\n action: z.literal('multiselect'),\n selector: z.string().min(1),\n values: z.array(z.string()),\n});\n\nconst waitForDownloadSchema = baseCommandSchema.extend({\n action: z.literal('waitfordownload'),\n path: z.string().optional(),\n timeout: z.number().positive().optional(),\n});\n\nconst responseBodySchema = baseCommandSchema.extend({\n action: z.literal('responsebody'),\n url: z.string().min(1),\n timeout: z.number().positive().optional(),\n});\n\n// Screencast schemas for streaming browser viewport\nconst screencastStartSchema = baseCommandSchema.extend({\n action: z.literal('screencast_start'),\n format: z.enum(['jpeg', 'png']).optional(),\n quality: z.number().min(0).max(100).optional(),\n maxWidth: z.number().positive().optional(),\n maxHeight: z.number().positive().optional(),\n everyNthFrame: z.number().positive().optional(),\n});\n\nconst screencastStopSchema = baseCommandSchema.extend({\n action: z.literal('screencast_stop'),\n});\n\n// Input injection schemas for pair browsing\nconst inputMouseSchema = baseCommandSchema.extend({\n action: z.literal('input_mouse'),\n type: z.enum(['mousePressed', 'mouseReleased', 'mouseMoved', 'mouseWheel']),\n x: z.number(),\n y: z.number(),\n button: z.enum(['left', 'right', 'middle', 'none']).optional(),\n clickCount: z.number().positive().optional(),\n deltaX: z.number().optional(),\n deltaY: z.number().optional(),\n modifiers: z.number().optional(),\n});\n\nconst inputKeyboardSchema = baseCommandSchema.extend({\n action: z.literal('input_keyboard'),\n type: z.enum(['keyDown', 'keyUp', 'char']),\n key: z.string().optional(),\n code: z.string().optional(),\n text: z.string().optional(),\n modifiers: z.number().optional(),\n});\n\nconst inputTouchSchema = baseCommandSchema.extend({\n action: z.literal('input_touch'),\n type: z.enum(['touchStart', 'touchEnd', 'touchMove', 'touchCancel']),\n touchPoints: z.array(\n z.object({\n x: z.number(),\n y: z.number(),\n id: z.number().optional(),\n })\n ),\n modifiers: z.number().optional(),\n});\n\n// iOS-specific schemas\nconst swipeSchema = baseCommandSchema.extend({\n action: z.literal('swipe'),\n direction: z.enum(['up', 'down', 'left', 'right']),\n distance: z.number().positive().optional(),\n});\n\nconst deviceListSchema = baseCommandSchema.extend({\n action: z.literal('device_list'),\n});\n\nconst pressSchema = baseCommandSchema.extend({\n action: z.literal('press'),\n key: z.string().min(1),\n selector: z.string().min(1).optional(),\n});\n\nconst screenshotSchema = baseCommandSchema.extend({\n action: z.literal('screenshot'),\n path: z.string().nullable().optional(),\n fullPage: z.boolean().optional(),\n selector: z.string().min(1).nullish(),\n format: z.enum(['png', 'jpeg']).optional(),\n quality: z.number().min(0).max(100).optional(),\n});\n\nconst snapshotSchema = baseCommandSchema.extend({\n action: z.literal('snapshot'),\n interactive: z.boolean().optional(),\n maxDepth: z.number().nonnegative().optional(),\n compact: z.boolean().optional(),\n selector: z.string().optional(),\n});\n\nconst evaluateSchema = baseCommandSchema.extend({\n action: z.literal('evaluate'),\n script: z.string().min(1),\n args: z.array(z.unknown()).optional(),\n});\n\nconst waitSchema = baseCommandSchema.extend({\n action: z.literal('wait'),\n selector: z.string().min(1).optional(),\n timeout: z.number().positive().optional(),\n state: z.enum(['attached', 'detached', 'visible', 'hidden']).optional(),\n});\n\nconst scrollSchema = baseCommandSchema.extend({\n action: z.literal('scroll'),\n selector: z.string().min(1).optional(),\n x: z.number().optional(),\n y: z.number().optional(),\n direction: z.enum(['up', 'down', 'left', 'right']).optional(),\n amount: z.number().positive().optional(),\n});\n\nconst selectSchema = baseCommandSchema.extend({\n action: z.literal('select'),\n selector: z.string().min(1),\n values: z.union([z.string(), z.array(z.string())]),\n});\n\nconst hoverSchema = baseCommandSchema.extend({\n action: z.literal('hover'),\n selector: z.string().min(1),\n});\n\nconst contentSchema = baseCommandSchema.extend({\n action: z.literal('content'),\n selector: z.string().min(1).optional(),\n});\n\nconst closeSchema = baseCommandSchema.extend({\n action: z.literal('close'),\n});\n\n// Tab/Window schemas\nconst tabNewSchema = baseCommandSchema.extend({\n action: z.literal('tab_new'),\n url: z.string().min(1).optional(),\n});\n\nconst tabListSchema = baseCommandSchema.extend({\n action: z.literal('tab_list'),\n});\n\nconst tabSwitchSchema = baseCommandSchema.extend({\n action: z.literal('tab_switch'),\n index: z.number().nonnegative(),\n});\n\nconst tabCloseSchema = baseCommandSchema.extend({\n action: z.literal('tab_close'),\n index: z.number().nonnegative().optional(),\n});\n\nconst windowNewSchema = baseCommandSchema.extend({\n action: z.literal('window_new'),\n viewport: z\n .object({\n width: z.number().positive(),\n height: z.number().positive(),\n })\n .optional(),\n});\n\n// Union schema for all commands\nconst commandSchema = z.discriminatedUnion('action', [\n launchSchema,\n navigateSchema,\n clickSchema,\n typeSchema,\n fillSchema,\n checkSchema,\n uncheckSchema,\n uploadSchema,\n dblclickSchema,\n focusSchema,\n dragSchema,\n frameSchema,\n mainframeSchema,\n getByRoleSchema,\n getByTextSchema,\n getByLabelSchema,\n getByPlaceholderSchema,\n pressSchema,\n screenshotSchema,\n snapshotSchema,\n evaluateSchema,\n waitSchema,\n scrollSchema,\n selectSchema,\n hoverSchema,\n contentSchema,\n closeSchema,\n tabNewSchema,\n tabListSchema,\n tabSwitchSchema,\n tabCloseSchema,\n windowNewSchema,\n cookiesGetSchema,\n cookiesSetSchema,\n cookiesClearSchema,\n storageGetSchema,\n storageSetSchema,\n storageClearSchema,\n dialogSchema,\n pdfSchema,\n routeSchema,\n unrouteSchema,\n requestsSchema,\n downloadSchema,\n geolocationSchema,\n permissionsSchema,\n viewportSchema,\n userAgentSchema,\n deviceSchema,\n backSchema,\n forwardSchema,\n reloadSchema,\n urlSchema,\n titleSchema,\n getAttributeSchema,\n getTextSchema,\n isVisibleSchema,\n isEnabledSchema,\n isCheckedSchema,\n countSchema,\n boundingBoxSchema,\n stylesSchema,\n videoStartSchema,\n videoStopSchema,\n recordingStartSchema,\n recordingStopSchema,\n recordingRestartSchema,\n traceStartSchema,\n traceStopSchema,\n harStartSchema,\n harStopSchema,\n stateSaveSchema,\n stateLoadSchema,\n consoleSchema,\n errorsSchema,\n keyboardSchema,\n wheelSchema,\n tapSchema,\n clipboardSchema,\n highlightSchema,\n clearSchema,\n selectAllSchema,\n innerTextSchema,\n innerHtmlSchema,\n inputValueSchema,\n setValueSchema,\n dispatchSchema,\n evalHandleSchema,\n exposeSchema,\n addScriptSchema,\n addStyleSchema,\n emulateMediaSchema,\n offlineSchema,\n headersSchema,\n pauseSchema,\n getByAltTextSchema,\n getByTitleSchema,\n getByTestIdSchema,\n nthSchema,\n waitForUrlSchema,\n waitForLoadStateSchema,\n setContentSchema,\n timezoneSchema,\n localeSchema,\n credentialsSchema,\n mouseMoveSchema,\n mouseDownSchema,\n mouseUpSchema,\n bringToFrontSchema,\n waitForFunctionSchema,\n scrollIntoViewSchema,\n addInitScriptSchema,\n keyDownSchema,\n keyUpSchema,\n insertTextSchema,\n multiSelectSchema,\n waitForDownloadSchema,\n responseBodySchema,\n screencastStartSchema,\n screencastStopSchema,\n inputMouseSchema,\n inputKeyboardSchema,\n inputTouchSchema,\n swipeSchema,\n deviceListSchema,\n]);\n\n// Parse result type\nexport type ParseResult =\n | { success: true; command: Command }\n | { success: false; error: string; id?: string };\n\n/**\n * Parse a JSON string into a validated command\n */\nexport function parseCommand(input: string): ParseResult {\n // First, try to parse JSON\n let json: unknown;\n try {\n json = JSON.parse(input);\n } catch {\n return { success: false, error: 'Invalid JSON' };\n }\n\n // Extract id for error responses if possible\n const id =\n typeof json === 'object' && json !== null && 'id' in json\n ? String((json as { id: unknown }).id)\n : undefined;\n\n // Validate against schema\n const result = commandSchema.safeParse(json);\n\n if (!result.success) {\n const errors = result.error.errors.map((e) => `${e.path.join('.')}: ${e.message}`).join(', ');\n return { success: false, error: `Validation error: ${errors}`, id };\n }\n\n return { success: true, command: result.data as Command };\n}\n\n/**\n * Create a success response\n */\nexport function successResponse<T>(id: string, data: T): Response<T> {\n return { id, success: true, data };\n}\n\n/**\n * Create an error response\n */\nexport function errorResponse(id: string, error: string): Response {\n return { id, success: false, error };\n}\n\n/**\n * Serialize a response to JSON string\n */\nexport function serializeResponse(response: Response): string {\n return JSON.stringify(response);\n}\n","import type { Page, Frame } from 'playwright-core';\nimport { mkdirSync } from 'node:fs';\nimport path from 'node:path';\nimport type { BrowserManager, ScreencastFrame } from './browser.js';\nimport { getAppDir } from './daemon.js';\nimport type {\n Command,\n Response,\n NavigateCommand,\n ClickCommand,\n TypeCommand,\n FillCommand,\n CheckCommand,\n UncheckCommand,\n UploadCommand,\n DoubleClickCommand,\n FocusCommand,\n DragCommand,\n FrameCommand,\n GetByRoleCommand,\n GetByTextCommand,\n GetByLabelCommand,\n GetByPlaceholderCommand,\n PressCommand,\n ScreenshotCommand,\n EvaluateCommand,\n WaitCommand,\n ScrollCommand,\n SelectCommand,\n HoverCommand,\n ContentCommand,\n TabNewCommand,\n TabSwitchCommand,\n TabCloseCommand,\n WindowNewCommand,\n CookiesSetCommand,\n StorageGetCommand,\n StorageSetCommand,\n StorageClearCommand,\n DialogCommand,\n PdfCommand,\n RouteCommand,\n RequestsCommand,\n DownloadCommand,\n GeolocationCommand,\n PermissionsCommand,\n ViewportCommand,\n DeviceCommand,\n GetAttributeCommand,\n GetTextCommand,\n IsVisibleCommand,\n IsEnabledCommand,\n IsCheckedCommand,\n CountCommand,\n BoundingBoxCommand,\n StylesCommand,\n TraceStartCommand,\n TraceStopCommand,\n HarStopCommand,\n StorageStateSaveCommand,\n ConsoleCommand,\n ErrorsCommand,\n KeyboardCommand,\n WheelCommand,\n TapCommand,\n ClipboardCommand,\n HighlightCommand,\n ClearCommand,\n SelectAllCommand,\n InnerTextCommand,\n InnerHtmlCommand,\n InputValueCommand,\n SetValueCommand,\n DispatchEventCommand,\n AddScriptCommand,\n AddStyleCommand,\n EmulateMediaCommand,\n OfflineCommand,\n HeadersCommand,\n GetByAltTextCommand,\n GetByTitleCommand,\n GetByTestIdCommand,\n NthCommand,\n WaitForUrlCommand,\n WaitForLoadStateCommand,\n SetContentCommand,\n TimezoneCommand,\n LocaleCommand,\n HttpCredentialsCommand,\n MouseMoveCommand,\n MouseDownCommand,\n MouseUpCommand,\n WaitForFunctionCommand,\n ScrollIntoViewCommand,\n AddInitScriptCommand,\n KeyDownCommand,\n KeyUpCommand,\n InsertTextCommand,\n MultiSelectCommand,\n WaitForDownloadCommand,\n ResponseBodyCommand,\n ScreencastStartCommand,\n ScreencastStopCommand,\n InputMouseCommand,\n InputKeyboardCommand,\n InputTouchCommand,\n RecordingStartCommand,\n RecordingStopCommand,\n RecordingRestartCommand,\n NavigateData,\n ScreenshotData,\n EvaluateData,\n ContentData,\n TabListData,\n TabNewData,\n TabSwitchData,\n TabCloseData,\n ScreencastStartData,\n ScreencastStopData,\n RecordingStartData,\n RecordingStopData,\n RecordingRestartData,\n InputEventData,\n StylesData,\n} from './types.js';\nimport { successResponse, errorResponse } from './protocol.js';\n\n// Callback for screencast frames - will be set by the daemon when streaming is active\nlet screencastFrameCallback: ((frame: ScreencastFrame) => void) | null = null;\n\n/**\n * Set the callback for screencast frames\n * This is called by the daemon to set up frame streaming\n */\nexport function setScreencastFrameCallback(\n callback: ((frame: ScreencastFrame) => void) | null\n): void {\n screencastFrameCallback = callback;\n}\n\n// Snapshot response type\ninterface SnapshotData {\n snapshot: string;\n refs?: Record<string, { role: string; name?: string }>;\n}\n\n/**\n * Convert Playwright errors to AI-friendly messages\n * @internal Exported for testing\n */\nexport function toAIFriendlyError(error: unknown, selector: string): Error {\n const message = error instanceof Error ? error.message : String(error);\n\n // Handle strict mode violation (multiple elements match)\n if (message.includes('strict mode violation')) {\n // Extract count if available\n const countMatch = message.match(/resolved to (\\d+) elements/);\n const count = countMatch ? countMatch[1] : 'multiple';\n\n return new Error(\n `Selector \"${selector}\" matched ${count} elements. ` +\n `Run 'snapshot' to get updated refs, or use a more specific CSS selector.`\n );\n }\n\n // Handle element not interactable (must be checked BEFORE timeout case)\n // This includes cases where an overlay/modal blocks the element\n if (message.includes('intercepts pointer events')) {\n return new Error(\n `Element \"${selector}\" is blocked by another element (likely a modal or overlay). ` +\n `Try dismissing any modals/cookie banners first.`\n );\n }\n\n // Handle element not visible\n if (message.includes('not visible') && !message.includes('Timeout')) {\n return new Error(\n `Element \"${selector}\" is not visible. ` +\n `Try scrolling it into view or check if it's hidden.`\n );\n }\n\n // Handle general timeout (element exists but action couldn't complete)\n if (message.includes('Timeout') && message.includes('exceeded')) {\n return new Error(\n `Action on \"${selector}\" timed out. The element may be blocked, still loading, or not interactable. ` +\n `Run 'snapshot' to check the current page state.`\n );\n }\n\n // Handle element not found (timeout waiting for element)\n if (\n message.includes('waiting for') &&\n (message.includes('to be visible') || message.includes('Timeout'))\n ) {\n return new Error(\n `Element \"${selector}\" not found or not visible. ` +\n `Run 'snapshot' to see current page elements.`\n );\n }\n\n // Return original error for unknown cases\n return error instanceof Error ? error : new Error(message);\n}\n\n/**\n * Execute a command and return a response\n */\nexport async function executeCommand(command: Command, browser: BrowserManager): Promise<Response> {\n try {\n switch (command.action) {\n case 'launch':\n return await handleLaunch(command, browser);\n case 'navigate':\n return await handleNavigate(command, browser);\n case 'click':\n return await handleClick(command, browser);\n case 'type':\n return await handleType(command, browser);\n case 'fill':\n return await handleFill(command, browser);\n case 'check':\n return await handleCheck(command, browser);\n case 'uncheck':\n return await handleUncheck(command, browser);\n case 'upload':\n return await handleUpload(command, browser);\n case 'dblclick':\n return await handleDoubleClick(command, browser);\n case 'focus':\n return await handleFocus(command, browser);\n case 'drag':\n return await handleDrag(command, browser);\n case 'frame':\n return await handleFrame(command, browser);\n case 'mainframe':\n return await handleMainFrame(command, browser);\n case 'getbyrole':\n return await handleGetByRole(command, browser);\n case 'getbytext':\n return await handleGetByText(command, browser);\n case 'getbylabel':\n return await handleGetByLabel(command, browser);\n case 'getbyplaceholder':\n return await handleGetByPlaceholder(command, browser);\n case 'press':\n return await handlePress(command, browser);\n case 'screenshot':\n return await handleScreenshot(command, browser);\n case 'snapshot':\n return await handleSnapshot(command, browser);\n case 'evaluate':\n return await handleEvaluate(command, browser);\n case 'wait':\n return await handleWait(command, browser);\n case 'scroll':\n return await handleScroll(command, browser);\n case 'select':\n return await handleSelect(command, browser);\n case 'hover':\n return await handleHover(command, browser);\n case 'content':\n return await handleContent(command, browser);\n case 'close':\n return await handleClose(command, browser);\n case 'tab_new':\n return await handleTabNew(command, browser);\n case 'tab_list':\n return await handleTabList(command, browser);\n case 'tab_switch':\n return await handleTabSwitch(command, browser);\n case 'tab_close':\n return await handleTabClose(command, browser);\n case 'window_new':\n return await handleWindowNew(command, browser);\n case 'cookies_get':\n return await handleCookiesGet(command, browser);\n case 'cookies_set':\n return await handleCookiesSet(command, browser);\n case 'cookies_clear':\n return await handleCookiesClear(command, browser);\n case 'storage_get':\n return await handleStorageGet(command, browser);\n case 'storage_set':\n return await handleStorageSet(command, browser);\n case 'storage_clear':\n return await handleStorageClear(command, browser);\n case 'dialog':\n return await handleDialog(command, browser);\n case 'pdf':\n return await handlePdf(command, browser);\n case 'route':\n return await handleRoute(command, browser);\n case 'unroute':\n return await handleUnroute(command, browser);\n case 'requests':\n return await handleRequests(command, browser);\n case 'download':\n return await handleDownload(command, browser);\n case 'geolocation':\n return await handleGeolocation(command, browser);\n case 'permissions':\n return await handlePermissions(command, browser);\n case 'viewport':\n return await handleViewport(command, browser);\n case 'useragent':\n return await handleUserAgent(command, browser);\n case 'device':\n return await handleDevice(command, browser);\n case 'back':\n return await handleBack(command, browser);\n case 'forward':\n return await handleForward(command, browser);\n case 'reload':\n return await handleReload(command, browser);\n case 'url':\n return await handleUrl(command, browser);\n case 'title':\n return await handleTitle(command, browser);\n case 'getattribute':\n return await handleGetAttribute(command, browser);\n case 'gettext':\n return await handleGetText(command, browser);\n case 'isvisible':\n return await handleIsVisible(command, browser);\n case 'isenabled':\n return await handleIsEnabled(command, browser);\n case 'ischecked':\n return await handleIsChecked(command, browser);\n case 'count':\n return await handleCount(command, browser);\n case 'boundingbox':\n return await handleBoundingBox(command, browser);\n case 'styles':\n return await handleStyles(command, browser);\n case 'video_start':\n return await handleVideoStart(command, browser);\n case 'video_stop':\n return await handleVideoStop(command, browser);\n case 'trace_start':\n return await handleTraceStart(command, browser);\n case 'trace_stop':\n return await handleTraceStop(command, browser);\n case 'har_start':\n return await handleHarStart(command, browser);\n case 'har_stop':\n return await handleHarStop(command, browser);\n case 'state_save':\n return await handleStateSave(command, browser);\n case 'state_load':\n return await handleStateLoad(command, browser);\n case 'console':\n return await handleConsole(command, browser);\n case 'errors':\n return await handleErrors(command, browser);\n case 'keyboard':\n return await handleKeyboard(command, browser);\n case 'wheel':\n return await handleWheel(command, browser);\n case 'tap':\n return await handleTap(command, browser);\n case 'clipboard':\n return await handleClipboard(command, browser);\n case 'highlight':\n return await handleHighlight(command, browser);\n case 'clear':\n return await handleClear(command, browser);\n case 'selectall':\n return await handleSelectAll(command, browser);\n case 'innertext':\n return await handleInnerText(command, browser);\n case 'innerhtml':\n return await handleInnerHtml(command, browser);\n case 'inputvalue':\n return await handleInputValue(command, browser);\n case 'setvalue':\n return await handleSetValue(command, browser);\n case 'dispatch':\n return await handleDispatch(command, browser);\n case 'evalhandle':\n return await handleEvalHandle(command, browser);\n case 'expose':\n return await handleExpose(command, browser);\n case 'addscript':\n return await handleAddScript(command, browser);\n case 'addstyle':\n return await handleAddStyle(command, browser);\n case 'emulatemedia':\n return await handleEmulateMedia(command, browser);\n case 'offline':\n return await handleOffline(command, browser);\n case 'headers':\n return await handleHeaders(command, browser);\n case 'pause':\n return await handlePause(command, browser);\n case 'getbyalttext':\n return await handleGetByAltText(command, browser);\n case 'getbytitle':\n return await handleGetByTitle(command, browser);\n case 'getbytestid':\n return await handleGetByTestId(command, browser);\n case 'nth':\n return await handleNth(command, browser);\n case 'waitforurl':\n return await handleWaitForUrl(command, browser);\n case 'waitforloadstate':\n return await handleWaitForLoadState(command, browser);\n case 'setcontent':\n return await handleSetContent(command, browser);\n case 'timezone':\n return await handleTimezone(command, browser);\n case 'locale':\n return await handleLocale(command, browser);\n case 'credentials':\n return await handleCredentials(command, browser);\n case 'mousemove':\n return await handleMouseMove(command, browser);\n case 'mousedown':\n return await handleMouseDown(command, browser);\n case 'mouseup':\n return await handleMouseUp(command, browser);\n case 'bringtofront':\n return await handleBringToFront(command, browser);\n case 'waitforfunction':\n return await handleWaitForFunction(command, browser);\n case 'scrollintoview':\n return await handleScrollIntoView(command, browser);\n case 'addinitscript':\n return await handleAddInitScript(command, browser);\n case 'keydown':\n return await handleKeyDown(command, browser);\n case 'keyup':\n return await handleKeyUp(command, browser);\n case 'inserttext':\n return await handleInsertText(command, browser);\n case 'multiselect':\n return await handleMultiSelect(command, browser);\n case 'waitfordownload':\n return await handleWaitForDownload(command, browser);\n case 'responsebody':\n return await handleResponseBody(command, browser);\n case 'screencast_start':\n return await handleScreencastStart(command, browser);\n case 'screencast_stop':\n return await handleScreencastStop(command, browser);\n case 'input_mouse':\n return await handleInputMouse(command, browser);\n case 'input_keyboard':\n return await handleInputKeyboard(command, browser);\n case 'input_touch':\n return await handleInputTouch(command, browser);\n case 'recording_start':\n return await handleRecordingStart(command, browser);\n case 'recording_stop':\n return await handleRecordingStop(command, browser);\n case 'recording_restart':\n return await handleRecordingRestart(command, browser);\n default: {\n // TypeScript narrows to never here, but we handle it for safety\n const unknownCommand = command as { id: string; action: string };\n return errorResponse(unknownCommand.id, `Unknown action: ${unknownCommand.action}`);\n }\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return errorResponse(command.id, message);\n }\n}\n\nasync function handleLaunch(\n command: Command & { action: 'launch' },\n browser: BrowserManager\n): Promise<Response> {\n await browser.launch(command);\n return successResponse(command.id, { launched: true });\n}\n\nasync function handleNavigate(\n command: NavigateCommand,\n browser: BrowserManager\n): Promise<Response<NavigateData>> {\n const page = browser.getPage();\n\n // If headers are provided, set up scoped headers for this origin\n if (command.headers && Object.keys(command.headers).length > 0) {\n await browser.setScopedHeaders(command.url, command.headers);\n }\n\n await page.goto(command.url, {\n waitUntil: command.waitUntil ?? 'load',\n });\n\n return successResponse(command.id, {\n url: page.url(),\n title: await page.title(),\n });\n}\n\nasync function handleClick(command: ClickCommand, browser: BrowserManager): Promise<Response> {\n // 1. Check if this is a ref with coordinate bounds\n if (browser.isRef(command.selector)) {\n const refData = browser.getRefData(command.selector);\n if (refData && refData.bounds) {\n const b = refData.bounds;\n // Calculate center of the bounds\n const centerX = b.left + (b.right - b.left) / 2;\n const centerY = b.top + (b.bottom - b.top) / 2;\n\n // Inject raw mouse events via CDP\n await browser.injectMouseEvent({\n type: 'mousePressed',\n x: centerX,\n y: centerY,\n button: command.button || 'left',\n clickCount: command.clickCount || 1,\n });\n await browser.injectMouseEvent({\n type: 'mouseReleased',\n x: centerX,\n y: centerY,\n button: command.button || 'left',\n });\n\n return successResponse(command.id, { clicked: true, method: 'cdp_coordinates' });\n }\n }\n\n // 2. Fallback to standard Playwright locator click\n const locator = browser.getLocator(command.selector);\n\n try {\n await locator.click({\n button: command.button,\n clickCount: command.clickCount,\n delay: command.delay,\n });\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n\n return successResponse(command.id, { clicked: true, method: 'playwright_locator' });\n}\n\nasync function handleType(command: TypeCommand, browser: BrowserManager): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n\n try {\n if (command.clear) {\n await locator.fill('');\n }\n\n await locator.pressSequentially(command.text, {\n delay: command.delay,\n });\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n\n return successResponse(command.id, { typed: true });\n}\n\nasync function handlePress(command: PressCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n\n if (command.selector) {\n await page.press(command.selector, command.key);\n } else {\n await page.keyboard.press(command.key);\n }\n\n return successResponse(command.id, { pressed: true });\n}\n\nasync function handleScreenshot(\n command: ScreenshotCommand,\n browser: BrowserManager\n): Promise<Response<ScreenshotData>> {\n const page = browser.getPage();\n\n const options: Parameters<Page['screenshot']>[0] = {\n fullPage: command.fullPage,\n type: command.format ?? 'png',\n };\n\n if (command.format === 'jpeg' && command.quality !== undefined) {\n options.quality = command.quality;\n }\n\n let target: Page | ReturnType<Page['locator']> = page;\n if (command.selector) {\n target = browser.getLocator(command.selector);\n }\n\n try {\n let savePath = command.path;\n if (!savePath) {\n const ext = command.format === 'jpeg' ? 'jpg' : 'png';\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const random = Math.random().toString(36).substring(2, 8);\n const filename = `screenshot-${timestamp}-${random}.${ext}`;\n const screenshotDir = path.join(getAppDir(), 'tmp', 'screenshots');\n mkdirSync(screenshotDir, { recursive: true });\n savePath = path.join(screenshotDir, filename);\n }\n\n await target.screenshot({ ...options, path: savePath });\n return successResponse(command.id, { path: savePath });\n } catch (error) {\n if (command.selector) {\n throw toAIFriendlyError(error, command.selector);\n }\n throw error;\n }\n}\n\nasync function handleSnapshot(\n command: Command & {\n action: 'snapshot';\n interactive?: boolean;\n cursor?: boolean;\n maxDepth?: number;\n compact?: boolean;\n selector?: string;\n },\n browser: BrowserManager\n): Promise<Response<SnapshotData>> {\n // Use enhanced snapshot with refs and optional filtering\n const { tree, refs } = await browser.getSnapshot({\n interactive: command.interactive,\n cursor: command.cursor,\n maxDepth: command.maxDepth,\n compact: command.compact,\n selector: command.selector,\n });\n\n // Simplify refs for output (just role and name)\n const simpleRefs: Record<string, { role: string; name?: string }> = {};\n for (const [ref, data] of Object.entries(refs)) {\n simpleRefs[ref] = { role: data.role, name: data.name };\n }\n\n return successResponse(command.id, {\n snapshot: tree || 'Empty page',\n refs: Object.keys(simpleRefs).length > 0 ? simpleRefs : undefined,\n });\n}\n\nasync function handleEvaluate(\n command: EvaluateCommand,\n browser: BrowserManager\n): Promise<Response<EvaluateData>> {\n const page = browser.getPage();\n\n // Evaluate the script directly as a string expression\n const result = await page.evaluate(command.script);\n\n return successResponse(command.id, { result });\n}\n\nasync function handleWait(command: WaitCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n\n if (command.selector) {\n await page.waitForSelector(command.selector, {\n state: command.state ?? 'visible',\n timeout: command.timeout,\n });\n } else if (command.timeout) {\n await page.waitForTimeout(command.timeout);\n } else {\n // Default: wait for load state\n await page.waitForLoadState('load');\n }\n\n return successResponse(command.id, { waited: true });\n}\n\nasync function handleScroll(command: ScrollCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n\n if (command.selector) {\n const element = page.locator(command.selector);\n await element.scrollIntoViewIfNeeded();\n\n if (command.x !== undefined || command.y !== undefined) {\n await element.evaluate(\n (el, { x, y }) => {\n el.scrollBy(x ?? 0, y ?? 0);\n },\n { x: command.x, y: command.y }\n );\n }\n } else {\n // Scroll the page\n let deltaX = command.x ?? 0;\n let deltaY = command.y ?? 0;\n\n if (command.direction) {\n const amount = command.amount ?? 100;\n switch (command.direction) {\n case 'up':\n deltaY = -amount;\n break;\n case 'down':\n deltaY = amount;\n break;\n case 'left':\n deltaX = -amount;\n break;\n case 'right':\n deltaX = amount;\n break;\n }\n }\n\n await page.evaluate(`window.scrollBy(${deltaX}, ${deltaY})`);\n }\n\n return successResponse(command.id, { scrolled: true });\n}\n\nasync function handleSelect(command: SelectCommand, browser: BrowserManager): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n const values = Array.isArray(command.values) ? command.values : [command.values];\n\n try {\n await locator.selectOption(values);\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n\n return successResponse(command.id, { selected: values });\n}\n\nasync function handleHover(command: HoverCommand, browser: BrowserManager): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n try {\n await locator.hover();\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n\n return successResponse(command.id, { hovered: true });\n}\n\nasync function handleContent(\n command: ContentCommand,\n browser: BrowserManager\n): Promise<Response<ContentData>> {\n const page = browser.getPage();\n\n let html: string;\n if (command.selector) {\n html = await page.locator(command.selector).innerHTML();\n } else {\n html = await page.content();\n }\n\n return successResponse(command.id, { html });\n}\n\nasync function handleClose(\n command: Command & { action: 'close' },\n browser: BrowserManager\n): Promise<Response> {\n await browser.close();\n return successResponse(command.id, { closed: true });\n}\n\nasync function handleTabNew(\n command: TabNewCommand,\n browser: BrowserManager\n): Promise<Response<TabNewData>> {\n const result = await browser.newTab();\n\n // Navigate to URL if provided (same pattern as handleNavigate)\n if (command.url) {\n const page = browser.getPage();\n await page.goto(command.url, { waitUntil: 'domcontentloaded' });\n }\n\n return successResponse(command.id, result);\n}\n\nasync function handleTabList(\n command: Command & { action: 'tab_list' },\n browser: BrowserManager\n): Promise<Response<TabListData>> {\n const tabs = await browser.listTabs();\n return successResponse(command.id, {\n tabs,\n active: browser.getActiveIndex(),\n });\n}\n\nasync function handleTabSwitch(\n command: TabSwitchCommand,\n browser: BrowserManager\n): Promise<Response<TabSwitchData>> {\n const result = await browser.switchTo(command.index);\n const page = browser.getPage();\n return successResponse(command.id, {\n ...result,\n title: await page.title(),\n });\n}\n\nasync function handleTabClose(\n command: TabCloseCommand,\n browser: BrowserManager\n): Promise<Response<TabCloseData>> {\n const result = await browser.closeTab(command.index);\n return successResponse(command.id, result);\n}\n\nasync function handleWindowNew(\n command: WindowNewCommand,\n browser: BrowserManager\n): Promise<Response<TabNewData>> {\n const result = await browser.newWindow(command.viewport);\n return successResponse(command.id, result);\n}\n\n// New handlers for enhanced Playwright parity\n\nasync function handleFill(command: FillCommand, browser: BrowserManager): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n try {\n await locator.fill(command.value);\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n return successResponse(command.id, { filled: true });\n}\n\nasync function handleCheck(command: CheckCommand, browser: BrowserManager): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n try {\n await locator.check();\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n return successResponse(command.id, { checked: true });\n}\n\nasync function handleUncheck(command: UncheckCommand, browser: BrowserManager): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n try {\n await locator.uncheck();\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n return successResponse(command.id, { unchecked: true });\n}\n\nasync function handleUpload(command: UploadCommand, browser: BrowserManager): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n const files = Array.isArray(command.files) ? command.files : [command.files];\n try {\n await locator.setInputFiles(files);\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n return successResponse(command.id, { uploaded: files });\n}\n\nasync function handleDoubleClick(\n command: DoubleClickCommand,\n browser: BrowserManager\n): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n try {\n await locator.dblclick();\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n return successResponse(command.id, { clicked: true });\n}\n\nasync function handleFocus(command: FocusCommand, browser: BrowserManager): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n try {\n await locator.focus();\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n return successResponse(command.id, { focused: true });\n}\n\nasync function handleDrag(command: DragCommand, browser: BrowserManager): Promise<Response> {\n const frame = browser.getFrame();\n await frame.dragAndDrop(command.source, command.target);\n return successResponse(command.id, { dragged: true });\n}\n\nasync function handleFrame(command: FrameCommand, browser: BrowserManager): Promise<Response> {\n await browser.switchToFrame({\n selector: command.selector,\n name: command.name,\n url: command.url,\n });\n return successResponse(command.id, { switched: true });\n}\n\nasync function handleMainFrame(\n command: Command & { action: 'mainframe' },\n browser: BrowserManager\n): Promise<Response> {\n browser.switchToMainFrame();\n return successResponse(command.id, { switched: true });\n}\n\nasync function handleGetByRole(\n command: GetByRoleCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const locator = page.getByRole(command.role as any, { name: command.name, exact: command.exact });\n\n switch (command.subaction) {\n case 'click':\n await locator.click();\n return successResponse(command.id, { clicked: true });\n case 'fill':\n await locator.fill(command.value ?? '');\n return successResponse(command.id, { filled: true });\n case 'check':\n await locator.check();\n return successResponse(command.id, { checked: true });\n case 'hover':\n await locator.hover();\n return successResponse(command.id, { hovered: true });\n }\n}\n\nasync function handleGetByText(\n command: GetByTextCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const locator = page.getByText(command.text, { exact: command.exact });\n\n switch (command.subaction) {\n case 'click':\n await locator.click();\n return successResponse(command.id, { clicked: true });\n case 'hover':\n await locator.hover();\n return successResponse(command.id, { hovered: true });\n }\n}\n\nasync function handleGetByLabel(\n command: GetByLabelCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const locator = page.getByLabel(command.label, { exact: command.exact });\n\n switch (command.subaction) {\n case 'click':\n await locator.click();\n return successResponse(command.id, { clicked: true });\n case 'fill':\n await locator.fill(command.value ?? '');\n return successResponse(command.id, { filled: true });\n case 'check':\n await locator.check();\n return successResponse(command.id, { checked: true });\n }\n}\n\nasync function handleGetByPlaceholder(\n command: GetByPlaceholderCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const locator = page.getByPlaceholder(command.placeholder, { exact: command.exact });\n\n switch (command.subaction) {\n case 'click':\n await locator.click();\n return successResponse(command.id, { clicked: true });\n case 'fill':\n await locator.fill(command.value ?? '');\n return successResponse(command.id, { filled: true });\n }\n}\n\nasync function handleCookiesGet(\n command: Command & { action: 'cookies_get'; urls?: string[] },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const context = page.context();\n const cookies = await context.cookies(command.urls);\n return successResponse(command.id, { cookies });\n}\n\nasync function handleCookiesSet(\n command: CookiesSetCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const context = page.context();\n // Auto-fill URL for cookies that don't have domain/path/url set\n const pageUrl = page.url();\n const cookies = command.cookies.map((cookie) => {\n if (!cookie.url && !cookie.domain && !cookie.path) {\n return { ...cookie, url: pageUrl };\n }\n return cookie;\n });\n await context.addCookies(cookies);\n return successResponse(command.id, { set: true });\n}\n\nasync function handleCookiesClear(\n command: Command & { action: 'cookies_clear' },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const context = page.context();\n await context.clearCookies();\n return successResponse(command.id, { cleared: true });\n}\n\nasync function handleStorageGet(\n command: StorageGetCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const storageType = command.type === 'local' ? 'localStorage' : 'sessionStorage';\n\n if (command.key) {\n const value = await page.evaluate(`${storageType}.getItem(${JSON.stringify(command.key)})`);\n return successResponse(command.id, { key: command.key, value });\n } else {\n const data = await page.evaluate(`\n (() => {\n const storage = ${storageType};\n const result = {};\n for (let i = 0; i < storage.length; i++) {\n const key = storage.key(i);\n if (key) result[key] = storage.getItem(key);\n }\n return result;\n })()\n `);\n return successResponse(command.id, { data });\n }\n}\n\nasync function handleStorageSet(\n command: StorageSetCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const storageType = command.type === 'local' ? 'localStorage' : 'sessionStorage';\n\n await page.evaluate(\n `${storageType}.setItem(${JSON.stringify(command.key)}, ${JSON.stringify(command.value)})`\n );\n return successResponse(command.id, { set: true });\n}\n\nasync function handleStorageClear(\n command: StorageClearCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const storageType = command.type === 'local' ? 'localStorage' : 'sessionStorage';\n\n await page.evaluate(`${storageType}.clear()`);\n return successResponse(command.id, { cleared: true });\n}\n\nasync function handleDialog(command: DialogCommand, browser: BrowserManager): Promise<Response> {\n browser.setDialogHandler(command.response, command.promptText);\n return successResponse(command.id, { handler: 'set', response: command.response });\n}\n\nasync function handlePdf(command: PdfCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n await page.pdf({\n path: command.path,\n format: command.format ?? 'Letter',\n });\n return successResponse(command.id, { path: command.path });\n}\n\n// Network & Request handlers\n\nasync function handleRoute(command: RouteCommand, browser: BrowserManager): Promise<Response> {\n await browser.addRoute(command.url, {\n response: command.response,\n abort: command.abort,\n });\n return successResponse(command.id, { routed: command.url });\n}\n\nasync function handleUnroute(\n command: Command & { action: 'unroute'; url?: string },\n browser: BrowserManager\n): Promise<Response> {\n await browser.removeRoute(command.url);\n return successResponse(command.id, { unrouted: command.url ?? 'all' });\n}\n\nasync function handleRequests(\n command: RequestsCommand,\n browser: BrowserManager\n): Promise<Response> {\n if (command.clear) {\n browser.clearRequests();\n return successResponse(command.id, { cleared: true });\n }\n\n // Start tracking if not already\n browser.startRequestTracking();\n\n const requests = browser.getRequests(command.filter);\n return successResponse(command.id, { requests });\n}\n\nasync function handleDownload(\n command: DownloadCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const locator = browser.getLocator(command.selector);\n\n const [download] = await Promise.all([page.waitForEvent('download'), locator.click()]);\n\n await download.saveAs(command.path);\n return successResponse(command.id, {\n path: command.path,\n suggestedFilename: download.suggestedFilename(),\n });\n}\n\nasync function handleGeolocation(\n command: GeolocationCommand,\n browser: BrowserManager\n): Promise<Response> {\n await browser.setGeolocation(command.latitude, command.longitude, command.accuracy);\n return successResponse(command.id, {\n latitude: command.latitude,\n longitude: command.longitude,\n });\n}\n\nasync function handlePermissions(\n command: PermissionsCommand,\n browser: BrowserManager\n): Promise<Response> {\n await browser.setPermissions(command.permissions, command.grant);\n return successResponse(command.id, {\n permissions: command.permissions,\n granted: command.grant,\n });\n}\n\nasync function handleViewport(\n command: ViewportCommand,\n browser: BrowserManager\n): Promise<Response> {\n await browser.setViewport(command.width, command.height);\n return successResponse(command.id, {\n width: command.width,\n height: command.height,\n });\n}\n\nasync function handleUserAgent(\n command: Command & { action: 'useragent'; userAgent: string },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const context = page.context();\n // Note: Can't change user agent after context is created, but we can for new pages\n return successResponse(command.id, {\n note: 'User agent can only be set at launch time. Use device command instead.',\n });\n}\n\nasync function handleDevice(command: DeviceCommand, browser: BrowserManager): Promise<Response> {\n const device = browser.getDevice(command.device);\n if (!device) {\n const available = browser.listDevices().slice(0, 10).join(', ');\n throw new Error(`Unknown device: ${command.device}. Available: ${available}...`);\n }\n\n // Apply device viewport\n await browser.setViewport(device.viewport.width, device.viewport.height);\n\n // Apply or clear device scale factor\n if (device.deviceScaleFactor && device.deviceScaleFactor !== 1) {\n // Apply device scale factor for HiDPI/retina displays\n await browser.setDeviceScaleFactor(\n device.deviceScaleFactor,\n device.viewport.width,\n device.viewport.height,\n device.isMobile ?? false\n );\n } else {\n // Clear device scale factor override to restore default (1x)\n try {\n await browser.clearDeviceMetricsOverride();\n } catch {\n // Ignore error if override was never set\n }\n }\n\n return successResponse(command.id, {\n device: command.device,\n viewport: device.viewport,\n userAgent: device.userAgent,\n deviceScaleFactor: device.deviceScaleFactor,\n });\n}\n\nasync function handleBack(\n command: Command & { action: 'back' },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.goBack();\n return successResponse(command.id, { url: page.url() });\n}\n\nasync function handleForward(\n command: Command & { action: 'forward' },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.goForward();\n return successResponse(command.id, { url: page.url() });\n}\n\nasync function handleReload(\n command: Command & { action: 'reload' },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.reload();\n return successResponse(command.id, { url: page.url() });\n}\n\nasync function handleUrl(\n command: Command & { action: 'url' },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n return successResponse(command.id, { url: page.url() });\n}\n\nasync function handleTitle(\n command: Command & { action: 'title' },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const title = await page.title();\n return successResponse(command.id, { title });\n}\n\nasync function handleGetAttribute(\n command: GetAttributeCommand,\n browser: BrowserManager\n): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n const value = await locator.getAttribute(command.attribute);\n return successResponse(command.id, { attribute: command.attribute, value });\n}\n\nasync function handleGetText(command: GetTextCommand, browser: BrowserManager): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n const text = await locator.textContent();\n return successResponse(command.id, { text });\n}\n\nasync function handleIsVisible(\n command: IsVisibleCommand,\n browser: BrowserManager\n): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n const visible = await locator.isVisible();\n return successResponse(command.id, { visible });\n}\n\nasync function handleIsEnabled(\n command: IsEnabledCommand,\n browser: BrowserManager\n): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n const enabled = await locator.isEnabled();\n return successResponse(command.id, { enabled });\n}\n\nasync function handleIsChecked(\n command: IsCheckedCommand,\n browser: BrowserManager\n): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n const checked = await locator.isChecked();\n return successResponse(command.id, { checked });\n}\n\nasync function handleCount(command: CountCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n const count = await page.locator(command.selector).count();\n return successResponse(command.id, { count });\n}\n\nasync function handleBoundingBox(\n command: BoundingBoxCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const box = await page.locator(command.selector).boundingBox();\n return successResponse(command.id, { box });\n}\n\nasync function handleStyles(\n command: StylesCommand,\n browser: BrowserManager\n): Promise<Response<StylesData>> {\n const page = browser.getPage();\n\n // Shared extraction logic as a string to be eval'd in browser context\n const extractStyles = (el: Element) => {\n const s = getComputedStyle(el);\n const r = el.getBoundingClientRect();\n return {\n tag: el.tagName.toLowerCase(),\n text: (el as HTMLElement).innerText?.trim().slice(0, 80) || null,\n box: {\n x: Math.round(r.x),\n y: Math.round(r.y),\n width: Math.round(r.width),\n height: Math.round(r.height),\n },\n styles: {\n fontSize: s.fontSize,\n fontWeight: s.fontWeight,\n fontFamily: s.fontFamily.split(',')[0].trim().replace(/\"/g, ''),\n color: s.color,\n backgroundColor: s.backgroundColor,\n borderRadius: s.borderRadius,\n border: s.border !== 'none' && s.borderWidth !== '0px' ? s.border : null,\n boxShadow: s.boxShadow !== 'none' ? s.boxShadow : null,\n padding: s.padding,\n },\n };\n };\n\n // Check if it's a ref - single element\n if (browser.isRef(command.selector)) {\n const locator = browser.getLocator(command.selector);\n const element = (await locator.evaluate(extractStyles)) as StylesData['elements'][0];\n return successResponse(command.id, { elements: [element] });\n }\n\n // CSS selector - can match multiple elements\n const elements = (await page.$$eval(command.selector, (els) => {\n return els.map((el) => {\n const s = getComputedStyle(el);\n const r = el.getBoundingClientRect();\n return {\n tag: el.tagName.toLowerCase(),\n text: (el as HTMLElement).innerText?.trim().slice(0, 80) || null,\n box: {\n x: Math.round(r.x),\n y: Math.round(r.y),\n width: Math.round(r.width),\n height: Math.round(r.height),\n },\n styles: {\n fontSize: s.fontSize,\n fontWeight: s.fontWeight,\n fontFamily: s.fontFamily.split(',')[0].trim().replace(/\"/g, ''),\n color: s.color,\n backgroundColor: s.backgroundColor,\n borderRadius: s.borderRadius,\n border: s.border !== 'none' && s.borderWidth !== '0px' ? s.border : null,\n boxShadow: s.boxShadow !== 'none' ? s.boxShadow : null,\n padding: s.padding,\n },\n };\n });\n })) as StylesData['elements'];\n\n return successResponse(command.id, { elements });\n}\n\n// Advanced handlers\n\nasync function handleVideoStart(\n command: Command & { action: 'video_start'; path: string },\n browser: BrowserManager\n): Promise<Response> {\n // Video recording requires context-level setup at launch\n // For now, return a note about this limitation\n return successResponse(command.id, {\n note: 'Video recording must be enabled at browser launch. Use --video flag when starting.',\n path: command.path,\n });\n}\n\nasync function handleVideoStop(\n command: Command & { action: 'video_stop' },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const video = page.video();\n if (video) {\n const path = await video.path();\n return successResponse(command.id, { path });\n }\n return successResponse(command.id, { note: 'No video recording active' });\n}\n\nasync function handleTraceStart(\n command: TraceStartCommand,\n browser: BrowserManager\n): Promise<Response> {\n await browser.startTracing({\n screenshots: command.screenshots,\n snapshots: command.snapshots,\n });\n return successResponse(command.id, { started: true });\n}\n\nasync function handleTraceStop(\n command: TraceStopCommand,\n browser: BrowserManager\n): Promise<Response> {\n await browser.stopTracing(command.path);\n return successResponse(command.id, { path: command.path });\n}\n\nasync function handleHarStart(\n command: Command & { action: 'har_start' },\n browser: BrowserManager\n): Promise<Response> {\n await browser.startHarRecording();\n browser.startRequestTracking();\n return successResponse(command.id, { started: true });\n}\n\nasync function handleHarStop(command: HarStopCommand, browser: BrowserManager): Promise<Response> {\n // HAR recording is handled at context level\n // For now, we save tracked requests as a simplified HAR-like format\n const requests = browser.getRequests();\n return successResponse(command.id, {\n path: command.path,\n requestCount: requests.length,\n });\n}\n\nasync function handleStateSave(\n command: StorageStateSaveCommand,\n browser: BrowserManager\n): Promise<Response> {\n await browser.saveStorageState(command.path);\n return successResponse(command.id, { path: command.path });\n}\n\nasync function handleStateLoad(\n command: Command & { action: 'state_load'; path: string },\n browser: BrowserManager\n): Promise<Response> {\n // Storage state is loaded at context creation\n return successResponse(command.id, {\n note: 'Storage state must be loaded at browser launch. Use --state flag.',\n path: command.path,\n });\n}\n\nasync function handleConsole(command: ConsoleCommand, browser: BrowserManager): Promise<Response> {\n if (command.clear) {\n browser.clearConsoleMessages();\n return successResponse(command.id, { cleared: true });\n }\n\n const messages = browser.getConsoleMessages();\n return successResponse(command.id, { messages });\n}\n\nasync function handleErrors(command: ErrorsCommand, browser: BrowserManager): Promise<Response> {\n if (command.clear) {\n browser.clearPageErrors();\n return successResponse(command.id, { cleared: true });\n }\n\n const errors = browser.getPageErrors();\n return successResponse(command.id, { errors });\n}\n\nasync function handleKeyboard(\n command: KeyboardCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.keyboard.press(command.keys);\n return successResponse(command.id, { pressed: command.keys });\n}\n\nasync function handleWheel(command: WheelCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n\n if (command.selector) {\n const element = page.locator(command.selector);\n await element.hover();\n }\n\n await page.mouse.wheel(command.deltaX ?? 0, command.deltaY ?? 0);\n return successResponse(command.id, { scrolled: true });\n}\n\nasync function handleTap(command: TapCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n await page.tap(command.selector);\n return successResponse(command.id, { tapped: true });\n}\n\nasync function handleClipboard(\n command: ClipboardCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n\n switch (command.operation) {\n case 'copy':\n await page.keyboard.press('Control+c');\n return successResponse(command.id, { copied: true });\n case 'paste':\n await page.keyboard.press('Control+v');\n return successResponse(command.id, { pasted: true });\n case 'read':\n const text = await page.evaluate('navigator.clipboard.readText()');\n return successResponse(command.id, { text });\n default:\n return errorResponse(command.id, 'Unknown clipboard operation');\n }\n}\n\nasync function handleHighlight(\n command: HighlightCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.locator(command.selector).highlight();\n return successResponse(command.id, { highlighted: true });\n}\n\nasync function handleClear(command: ClearCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n await page.locator(command.selector).clear();\n return successResponse(command.id, { cleared: true });\n}\n\nasync function handleSelectAll(\n command: SelectAllCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.locator(command.selector).selectText();\n return successResponse(command.id, { selected: true });\n}\n\nasync function handleInnerText(\n command: InnerTextCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const text = await page.locator(command.selector).innerText();\n return successResponse(command.id, { text });\n}\n\nasync function handleInnerHtml(\n command: InnerHtmlCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const html = await page.locator(command.selector).innerHTML();\n return successResponse(command.id, { html });\n}\n\nasync function handleInputValue(\n command: InputValueCommand,\n browser: BrowserManager\n): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n const value = await locator.inputValue();\n return successResponse(command.id, { value });\n}\n\nasync function handleSetValue(\n command: SetValueCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.locator(command.selector).fill(command.value);\n return successResponse(command.id, { set: true });\n}\n\nasync function handleDispatch(\n command: DispatchEventCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.locator(command.selector).dispatchEvent(command.event, command.eventInit);\n return successResponse(command.id, { dispatched: command.event });\n}\n\nasync function handleEvalHandle(\n command: Command & { action: 'evalhandle'; script: string },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const handle = await page.evaluateHandle(command.script);\n const result = await handle.jsonValue().catch(() => 'Handle (non-serializable)');\n return successResponse(command.id, { result });\n}\n\nasync function handleExpose(\n command: Command & { action: 'expose'; name: string },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.exposeFunction(command.name, () => {\n // Exposed function - can be extended\n return `Function ${command.name} called`;\n });\n return successResponse(command.id, { exposed: command.name });\n}\n\nasync function handleAddScript(\n command: AddScriptCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n\n if (command.content) {\n await page.addScriptTag({ content: command.content });\n } else if (command.url) {\n await page.addScriptTag({ url: command.url });\n }\n\n return successResponse(command.id, { added: true });\n}\n\nasync function handleAddStyle(\n command: AddStyleCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n\n if (command.content) {\n await page.addStyleTag({ content: command.content });\n } else if (command.url) {\n await page.addStyleTag({ url: command.url });\n }\n\n return successResponse(command.id, { added: true });\n}\n\nasync function handleEmulateMedia(\n command: EmulateMediaCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.emulateMedia({\n media: command.media,\n colorScheme: command.colorScheme,\n reducedMotion: command.reducedMotion,\n forcedColors: command.forcedColors,\n });\n return successResponse(command.id, { emulated: true });\n}\n\nasync function handleOffline(command: OfflineCommand, browser: BrowserManager): Promise<Response> {\n await browser.setOffline(command.offline);\n return successResponse(command.id, { offline: command.offline });\n}\n\nasync function handleHeaders(command: HeadersCommand, browser: BrowserManager): Promise<Response> {\n await browser.setExtraHeaders(command.headers);\n return successResponse(command.id, { set: true });\n}\n\nasync function handlePause(\n command: Command & { action: 'pause' },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.pause();\n return successResponse(command.id, { paused: true });\n}\n\nasync function handleGetByAltText(\n command: GetByAltTextCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const locator = page.getByAltText(command.text, { exact: command.exact });\n\n switch (command.subaction) {\n case 'click':\n await locator.click();\n return successResponse(command.id, { clicked: true });\n case 'hover':\n await locator.hover();\n return successResponse(command.id, { hovered: true });\n }\n}\n\nasync function handleGetByTitle(\n command: GetByTitleCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const locator = page.getByTitle(command.text, { exact: command.exact });\n\n switch (command.subaction) {\n case 'click':\n await locator.click();\n return successResponse(command.id, { clicked: true });\n case 'hover':\n await locator.hover();\n return successResponse(command.id, { hovered: true });\n }\n}\n\nasync function handleGetByTestId(\n command: GetByTestIdCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const locator = page.getByTestId(command.testId);\n\n switch (command.subaction) {\n case 'click':\n await locator.click();\n return successResponse(command.id, { clicked: true });\n case 'fill':\n await locator.fill(command.value ?? '');\n return successResponse(command.id, { filled: true });\n case 'check':\n await locator.check();\n return successResponse(command.id, { checked: true });\n case 'hover':\n await locator.hover();\n return successResponse(command.id, { hovered: true });\n }\n}\n\nasync function handleNth(command: NthCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n const base = page.locator(command.selector);\n const locator = command.index === -1 ? base.last() : base.nth(command.index);\n\n switch (command.subaction) {\n case 'click':\n await locator.click();\n return successResponse(command.id, { clicked: true });\n case 'fill':\n await locator.fill(command.value ?? '');\n return successResponse(command.id, { filled: true });\n case 'check':\n await locator.check();\n return successResponse(command.id, { checked: true });\n case 'hover':\n await locator.hover();\n return successResponse(command.id, { hovered: true });\n case 'text':\n const text = await locator.textContent();\n return successResponse(command.id, { text });\n }\n}\n\nasync function handleWaitForUrl(\n command: WaitForUrlCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.waitForURL(command.url, { timeout: command.timeout });\n return successResponse(command.id, { url: page.url() });\n}\n\nasync function handleWaitForLoadState(\n command: WaitForLoadStateCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.waitForLoadState(command.state, { timeout: command.timeout });\n return successResponse(command.id, { state: command.state });\n}\n\nasync function handleSetContent(\n command: SetContentCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.setContent(command.html);\n return successResponse(command.id, { set: true });\n}\n\nasync function handleTimezone(\n command: TimezoneCommand,\n browser: BrowserManager\n): Promise<Response> {\n // Timezone must be set at context level before navigation\n // This is a limitation - it sets for the current context\n const page = browser.getPage();\n await page.context().setGeolocation({ latitude: 0, longitude: 0 }); // Trigger context awareness\n return successResponse(command.id, {\n note: 'Timezone must be set at browser launch. Use --timezone flag.',\n timezone: command.timezone,\n });\n}\n\nasync function handleLocale(command: LocaleCommand, browser: BrowserManager): Promise<Response> {\n // Locale must be set at context creation\n return successResponse(command.id, {\n note: 'Locale must be set at browser launch. Use --locale flag.',\n locale: command.locale,\n });\n}\n\nasync function handleCredentials(\n command: HttpCredentialsCommand,\n browser: BrowserManager\n): Promise<Response> {\n const context = browser.getPage().context();\n await context.setHTTPCredentials({\n username: command.username,\n password: command.password,\n });\n return successResponse(command.id, { set: true });\n}\n\nasync function handleMouseMove(\n command: MouseMoveCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.mouse.move(command.x, command.y);\n return successResponse(command.id, { moved: true, x: command.x, y: command.y });\n}\n\nasync function handleMouseDown(\n command: MouseDownCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.mouse.down({ button: command.button ?? 'left' });\n return successResponse(command.id, { down: true });\n}\n\nasync function handleMouseUp(command: MouseUpCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n await page.mouse.up({ button: command.button ?? 'left' });\n return successResponse(command.id, { up: true });\n}\n\nasync function handleBringToFront(\n command: Command & { action: 'bringtofront' },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.bringToFront();\n return successResponse(command.id, { focused: true });\n}\n\nasync function handleWaitForFunction(\n command: WaitForFunctionCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.waitForFunction(command.expression, { timeout: command.timeout });\n return successResponse(command.id, { waited: true });\n}\n\nasync function handleScrollIntoView(\n command: ScrollIntoViewCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.locator(command.selector).scrollIntoViewIfNeeded();\n return successResponse(command.id, { scrolled: true });\n}\n\nasync function handleAddInitScript(\n command: AddInitScriptCommand,\n browser: BrowserManager\n): Promise<Response> {\n const context = browser.getPage().context();\n await context.addInitScript(command.script);\n return successResponse(command.id, { added: true });\n}\n\nasync function handleKeyDown(command: KeyDownCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n await page.keyboard.down(command.key);\n return successResponse(command.id, { down: true, key: command.key });\n}\n\nasync function handleKeyUp(command: KeyUpCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n await page.keyboard.up(command.key);\n return successResponse(command.id, { up: true, key: command.key });\n}\n\nasync function handleInsertText(\n command: InsertTextCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.keyboard.insertText(command.text);\n return successResponse(command.id, { inserted: true });\n}\n\nasync function handleMultiSelect(\n command: MultiSelectCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const selected = await page.locator(command.selector).selectOption(command.values);\n return successResponse(command.id, { selected });\n}\n\nasync function handleWaitForDownload(\n command: WaitForDownloadCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const download = await page.waitForEvent('download', { timeout: command.timeout });\n\n let filePath: string;\n if (command.path) {\n filePath = command.path;\n await download.saveAs(filePath);\n } else {\n filePath = (await download.path()) || download.suggestedFilename();\n }\n\n return successResponse(command.id, {\n path: filePath,\n filename: download.suggestedFilename(),\n url: download.url(),\n });\n}\n\nasync function handleResponseBody(\n command: ResponseBodyCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const response = await page.waitForResponse((resp) => resp.url().includes(command.url), {\n timeout: command.timeout,\n });\n\n const body = await response.text();\n let parsed: unknown = body;\n\n try {\n parsed = JSON.parse(body);\n } catch {\n // Keep as string if not JSON\n }\n\n return successResponse(command.id, {\n url: response.url(),\n status: response.status(),\n body: parsed,\n });\n}\n\n// Screencast and input injection handlers\n\nasync function handleScreencastStart(\n command: ScreencastStartCommand,\n browser: BrowserManager\n): Promise<Response<ScreencastStartData>> {\n if (!screencastFrameCallback) {\n throw new Error('Screencast frame callback not set. Start the streaming server first.');\n }\n\n await browser.startScreencast(screencastFrameCallback, {\n format: command.format,\n quality: command.quality,\n maxWidth: command.maxWidth,\n maxHeight: command.maxHeight,\n everyNthFrame: command.everyNthFrame,\n });\n\n return successResponse(command.id, {\n started: true,\n format: command.format ?? 'jpeg',\n quality: command.quality ?? 80,\n });\n}\n\nasync function handleScreencastStop(\n command: ScreencastStopCommand,\n browser: BrowserManager\n): Promise<Response<ScreencastStopData>> {\n await browser.stopScreencast();\n return successResponse(command.id, { stopped: true });\n}\n\nasync function handleInputMouse(\n command: InputMouseCommand,\n browser: BrowserManager\n): Promise<Response<InputEventData>> {\n await browser.injectMouseEvent({\n type: command.type,\n x: command.x,\n y: command.y,\n button: command.button,\n clickCount: command.clickCount,\n deltaX: command.deltaX,\n deltaY: command.deltaY,\n modifiers: command.modifiers,\n });\n return successResponse(command.id, { injected: true });\n}\n\nasync function handleInputKeyboard(\n command: InputKeyboardCommand,\n browser: BrowserManager\n): Promise<Response<InputEventData>> {\n await browser.injectKeyboardEvent({\n type: command.type,\n key: command.key,\n code: command.code,\n text: command.text,\n modifiers: command.modifiers,\n });\n return successResponse(command.id, { injected: true });\n}\n\nasync function handleInputTouch(\n command: InputTouchCommand,\n browser: BrowserManager\n): Promise<Response<InputEventData>> {\n await browser.injectTouchEvent({\n type: command.type,\n touchPoints: command.touchPoints,\n modifiers: command.modifiers,\n });\n return successResponse(command.id, { injected: true });\n}\n\n// Recording handlers (Playwright native video recording)\n\nasync function handleRecordingStart(\n command: RecordingStartCommand,\n browser: BrowserManager\n): Promise<Response<RecordingStartData>> {\n await browser.startRecording(command.path, command.url);\n return successResponse(command.id, {\n started: true,\n path: command.path,\n });\n}\n\nasync function handleRecordingStop(\n command: RecordingStopCommand,\n browser: BrowserManager\n): Promise<Response<RecordingStopData>> {\n const result = await browser.stopRecording();\n return successResponse(command.id, result);\n}\n\nasync function handleRecordingRestart(\n command: RecordingRestartCommand,\n browser: BrowserManager\n): Promise<Response<RecordingRestartData>> {\n const result = await browser.restartRecording(command.path, command.url);\n return successResponse(command.id, {\n started: true,\n path: command.path,\n previousPath: result.previousPath,\n stopped: result.stopped,\n });\n}\n","/**\n * iOS command execution - mirrors actions.ts but for iOS Safari via Appium.\n * Provides 1:1 command parity where possible.\n */\n\nimport type { IOSManager } from './ios-manager.js';\nimport type { Command, Response } from './types.js';\n\nfunction successResponse<T>(id: string, data: T): Response<T> {\n return { id, success: true, data };\n}\n\nfunction errorResponse(id: string, error: string): Response {\n return { id, success: false, error };\n}\n\n/**\n * Execute a command on the iOS manager\n */\nexport async function executeIOSCommand(command: Command, manager: IOSManager): Promise<Response> {\n const { id, action } = command;\n\n try {\n switch (action) {\n case 'launch': {\n const cmd = command as any;\n await manager.launch({\n device: cmd.device,\n udid: cmd.udid,\n });\n const info = manager.getDeviceInfo();\n return successResponse(id, {\n launched: true,\n device: info?.name ?? 'iOS Simulator',\n udid: info?.udid,\n });\n }\n\n case 'navigate': {\n const cmd = command as any;\n const result = await manager.navigate(cmd.url);\n return successResponse(id, result);\n }\n\n case 'click': {\n const cmd = command as any;\n await manager.click(cmd.selector);\n return successResponse(id, { clicked: true });\n }\n\n case 'tap': {\n const cmd = command as any;\n await manager.tap(cmd.selector);\n return successResponse(id, { tapped: true });\n }\n\n case 'type': {\n const cmd = command as any;\n await manager.type(cmd.selector, cmd.text, {\n delay: cmd.delay,\n clear: cmd.clear,\n });\n return successResponse(id, { typed: true });\n }\n\n case 'fill': {\n const cmd = command as any;\n await manager.fill(cmd.selector, cmd.value);\n return successResponse(id, { filled: true });\n }\n\n case 'screenshot': {\n const cmd = command as any;\n const result = await manager.screenshot({\n path: cmd.path,\n fullPage: cmd.fullPage,\n });\n return successResponse(id, result);\n }\n\n case 'snapshot': {\n const cmd = command as any;\n const result = await manager.getSnapshot({\n interactive: cmd.interactive,\n });\n return successResponse(id, { snapshot: result.tree, refs: result.refs });\n }\n\n case 'scroll': {\n const cmd = command as any;\n await manager.scroll({\n selector: cmd.selector,\n x: cmd.x,\n y: cmd.y,\n direction: cmd.direction,\n amount: cmd.amount,\n });\n return successResponse(id, { scrolled: true });\n }\n\n case 'swipe': {\n const cmd = command as any;\n await manager.swipe(cmd.direction, { distance: cmd.distance });\n return successResponse(id, { swiped: true });\n }\n\n case 'evaluate': {\n const cmd = command as any;\n const result = await manager.evaluate(cmd.script, ...(cmd.args ?? []));\n return successResponse(id, { result });\n }\n\n case 'wait': {\n const cmd = command as any;\n await manager.wait({\n selector: cmd.selector,\n timeout: cmd.timeout,\n state: cmd.state,\n });\n return successResponse(id, { waited: true });\n }\n\n case 'press': {\n const cmd = command as any;\n await manager.press(cmd.key);\n return successResponse(id, { pressed: true });\n }\n\n case 'hover': {\n const cmd = command as any;\n await manager.hover(cmd.selector);\n return successResponse(id, { hovered: true });\n }\n\n case 'content': {\n const cmd = command as any;\n const html = await manager.getContent(cmd.selector);\n return successResponse(id, { html });\n }\n\n case 'gettext': {\n const cmd = command as any;\n const text = await manager.getText(cmd.selector);\n return successResponse(id, { text });\n }\n\n case 'getattribute': {\n const cmd = command as any;\n const value = await manager.getAttribute(cmd.selector, cmd.attribute);\n return successResponse(id, { value });\n }\n\n case 'isvisible': {\n const cmd = command as any;\n const visible = await manager.isVisible(cmd.selector);\n return successResponse(id, { visible });\n }\n\n case 'isenabled': {\n const cmd = command as any;\n const enabled = await manager.isEnabled(cmd.selector);\n return successResponse(id, { enabled });\n }\n\n case 'url': {\n const url = await manager.getUrl();\n return successResponse(id, { url });\n }\n\n case 'title': {\n const title = await manager.getTitle();\n return successResponse(id, { title });\n }\n\n case 'back': {\n await manager.goBack();\n return successResponse(id, { navigated: 'back' });\n }\n\n case 'forward': {\n await manager.goForward();\n return successResponse(id, { navigated: 'forward' });\n }\n\n case 'reload': {\n await manager.reload();\n return successResponse(id, { reloaded: true });\n }\n\n case 'select': {\n const cmd = command as any;\n await manager.select(cmd.selector, cmd.values);\n return successResponse(id, { selected: true });\n }\n\n case 'check': {\n const cmd = command as any;\n await manager.check(cmd.selector);\n return successResponse(id, { checked: true });\n }\n\n case 'uncheck': {\n const cmd = command as any;\n await manager.uncheck(cmd.selector);\n return successResponse(id, { unchecked: true });\n }\n\n case 'focus': {\n const cmd = command as any;\n await manager.focus(cmd.selector);\n return successResponse(id, { focused: true });\n }\n\n case 'clear': {\n const cmd = command as any;\n await manager.clear(cmd.selector);\n return successResponse(id, { cleared: true });\n }\n\n case 'count': {\n const cmd = command as any;\n const count = await manager.count(cmd.selector);\n return successResponse(id, { count });\n }\n\n case 'boundingbox': {\n const cmd = command as any;\n const box = await manager.getBoundingBox(cmd.selector);\n return successResponse(id, { box });\n }\n\n case 'close': {\n await manager.close();\n return successResponse(id, { closed: true });\n }\n\n // iOS-specific: device list\n case 'device_list': {\n const devices = await manager.listDevices();\n return successResponse(id, { devices });\n }\n\n // Commands that don't apply to iOS Safari\n case 'tab_new':\n case 'tab_list':\n case 'tab_switch':\n case 'tab_close':\n case 'window_new':\n return errorResponse(\n id,\n `Command '${action}' is not supported on iOS Safari. Mobile Safari does not support programmatic tab management.`\n );\n\n case 'pdf':\n return errorResponse(id, 'PDF generation is not supported on iOS Safari.');\n\n case 'screencast_start':\n case 'screencast_stop':\n return errorResponse(id, 'Screencast is not supported on iOS (requires CDP).');\n\n case 'recording_start':\n case 'recording_stop':\n case 'recording_restart':\n return errorResponse(id, 'Video recording is not yet supported on iOS.');\n\n default:\n return errorResponse(id, `Unknown or unsupported iOS command: ${action}`);\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return errorResponse(id, message);\n }\n}\n","import { WebSocketServer, WebSocket } from 'ws';\nimport type { BrowserManager, ScreencastFrame } from './browser.js';\nimport { setScreencastFrameCallback } from './actions.js';\n\n/**\n * Check whether a WebSocket connection origin should be allowed.\n * Allows: no origin (CLI tools), file:// origins, and localhost/loopback origins.\n * Rejects: all other origins (prevents malicious web pages from connecting).\n */\nexport function isAllowedOrigin(origin: string | undefined): boolean {\n // Allow connections with no origin (non-browser clients like CLI tools)\n if (!origin) {\n return true;\n }\n // Allow file:// origins (local HTML files)\n if (origin.startsWith('file://')) {\n return true;\n }\n // Allow localhost/loopback origins (browser-based stream viewers)\n try {\n const url = new URL(origin);\n const host = url.hostname;\n if (host === 'localhost' || host === '127.0.0.1' || host === '::1' || host === '[::1]') {\n return true;\n }\n } catch {\n // Invalid origin URL - reject\n }\n return false;\n}\n\n// Message types for WebSocket communication\nexport interface FrameMessage {\n type: 'frame';\n data: string; // base64 encoded image\n metadata: {\n offsetTop: number;\n pageScaleFactor: number;\n deviceWidth: number;\n deviceHeight: number;\n scrollOffsetX: number;\n scrollOffsetY: number;\n timestamp?: number;\n };\n}\n\nexport interface InputMouseMessage {\n type: 'input_mouse';\n eventType: 'mousePressed' | 'mouseReleased' | 'mouseMoved' | 'mouseWheel';\n x: number;\n y: number;\n button?: 'left' | 'right' | 'middle' | 'none';\n clickCount?: number;\n deltaX?: number;\n deltaY?: number;\n modifiers?: number;\n}\n\nexport interface InputKeyboardMessage {\n type: 'input_keyboard';\n eventType: 'keyDown' | 'keyUp' | 'char';\n key?: string;\n code?: string;\n text?: string;\n modifiers?: number;\n}\n\nexport interface InputTouchMessage {\n type: 'input_touch';\n eventType: 'touchStart' | 'touchEnd' | 'touchMove' | 'touchCancel';\n touchPoints: Array<{ x: number; y: number; id?: number }>;\n modifiers?: number;\n}\n\nexport interface StatusMessage {\n type: 'status';\n connected: boolean;\n screencasting: boolean;\n viewportWidth?: number;\n viewportHeight?: number;\n}\n\nexport interface ErrorMessage {\n type: 'error';\n message: string;\n}\n\nexport type StreamMessage =\n | FrameMessage\n | InputMouseMessage\n | InputKeyboardMessage\n | InputTouchMessage\n | StatusMessage\n | ErrorMessage;\n\n/**\n * WebSocket server for streaming browser viewport and receiving input\n */\nexport class StreamServer {\n private wss: WebSocketServer | null = null;\n private clients: Set<WebSocket> = new Set();\n private browser: BrowserManager;\n private port: number;\n private isScreencasting: boolean = false;\n\n constructor(browser: BrowserManager, port: number = 9223) {\n this.browser = browser;\n this.port = port;\n }\n\n /**\n * Start the WebSocket server\n */\n start(): Promise<void> {\n return new Promise((resolve, reject) => {\n try {\n this.wss = new WebSocketServer({\n port: this.port,\n // Security: Reject cross-origin WebSocket connections from untrusted origins.\n // This prevents malicious web pages from connecting and injecting input events.\n // Localhost origins are allowed so browser-based stream viewers can connect.\n verifyClient: (info: {\n origin: string;\n secure: boolean;\n req: import('http').IncomingMessage;\n }) => {\n if (isAllowedOrigin(info.origin)) {\n return true;\n }\n console.log(`[StreamServer] Rejected connection from origin: ${info.origin}`);\n return false;\n },\n });\n\n this.wss.on('connection', (ws) => {\n this.handleConnection(ws);\n });\n\n this.wss.on('error', (error) => {\n console.error('[StreamServer] WebSocket error:', error);\n reject(error);\n });\n\n this.wss.on('listening', () => {\n console.log(`[StreamServer] Listening on port ${this.port}`);\n\n // Set up the screencast frame callback\n setScreencastFrameCallback((frame) => {\n this.broadcastFrame(frame);\n });\n\n resolve();\n });\n } catch (error) {\n reject(error);\n }\n });\n }\n\n /**\n * Stop the WebSocket server\n */\n async stop(): Promise<void> {\n // Stop screencasting\n if (this.isScreencasting) {\n await this.stopScreencast();\n }\n\n // Clear the callback\n setScreencastFrameCallback(null);\n\n // Close all clients\n for (const client of this.clients) {\n client.close();\n }\n this.clients.clear();\n\n // Close the server\n if (this.wss) {\n return new Promise((resolve) => {\n this.wss!.close(() => {\n this.wss = null;\n resolve();\n });\n });\n }\n }\n\n /**\n * Handle a new WebSocket connection\n */\n private handleConnection(ws: WebSocket): void {\n console.log('[StreamServer] Client connected');\n this.clients.add(ws);\n\n // Send initial status\n this.sendStatus(ws);\n\n // Start screencasting if this is the first client\n if (this.clients.size === 1 && !this.isScreencasting) {\n this.startScreencast().catch((error) => {\n console.error('[StreamServer] Failed to start screencast:', error);\n this.sendError(ws, error.message);\n });\n }\n\n // Handle messages from client\n ws.on('message', (data) => {\n try {\n const message = JSON.parse(data.toString()) as StreamMessage;\n this.handleMessage(message, ws);\n } catch (error) {\n console.error('[StreamServer] Failed to parse message:', error);\n }\n });\n\n // Handle client disconnect\n ws.on('close', () => {\n console.log('[StreamServer] Client disconnected');\n this.clients.delete(ws);\n\n // Stop screencasting if no more clients\n if (this.clients.size === 0 && this.isScreencasting) {\n this.stopScreencast().catch((error) => {\n console.error('[StreamServer] Failed to stop screencast:', error);\n });\n }\n });\n\n ws.on('error', (error) => {\n console.error('[StreamServer] Client error:', error);\n this.clients.delete(ws);\n });\n }\n\n /**\n * Handle incoming messages from clients\n */\n private async handleMessage(message: StreamMessage, ws: WebSocket): Promise<void> {\n try {\n switch (message.type) {\n case 'input_mouse':\n await this.browser.injectMouseEvent({\n type: message.eventType,\n x: message.x,\n y: message.y,\n button: message.button,\n clickCount: message.clickCount,\n deltaX: message.deltaX,\n deltaY: message.deltaY,\n modifiers: message.modifiers,\n });\n break;\n\n case 'input_keyboard':\n await this.browser.injectKeyboardEvent({\n type: message.eventType,\n key: message.key,\n code: message.code,\n text: message.text,\n modifiers: message.modifiers,\n });\n break;\n\n case 'input_touch':\n await this.browser.injectTouchEvent({\n type: message.eventType,\n touchPoints: message.touchPoints,\n modifiers: message.modifiers,\n });\n break;\n\n case 'status':\n // Client is requesting status\n this.sendStatus(ws);\n break;\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n this.sendError(ws, errorMessage);\n }\n }\n\n /**\n * Broadcast a frame to all connected clients\n */\n private broadcastFrame(frame: ScreencastFrame): void {\n const message: FrameMessage = {\n type: 'frame',\n data: frame.data,\n metadata: frame.metadata,\n };\n\n const payload = JSON.stringify(message);\n\n for (const client of this.clients) {\n if (client.readyState === WebSocket.OPEN) {\n client.send(payload);\n }\n }\n }\n\n /**\n * Send status to a client\n */\n private sendStatus(ws: WebSocket): void {\n let viewportWidth: number | undefined;\n let viewportHeight: number | undefined;\n\n try {\n const page = this.browser.getPage();\n const viewport = page.viewportSize();\n viewportWidth = viewport?.width;\n viewportHeight = viewport?.height;\n } catch {\n // Browser not launched yet\n }\n\n const message: StatusMessage = {\n type: 'status',\n connected: true,\n screencasting: this.isScreencasting,\n viewportWidth,\n viewportHeight,\n };\n\n if (ws.readyState === WebSocket.OPEN) {\n ws.send(JSON.stringify(message));\n }\n }\n\n /**\n * Send an error to a client\n */\n private sendError(ws: WebSocket, errorMessage: string): void {\n const message: ErrorMessage = {\n type: 'error',\n message: errorMessage,\n };\n\n if (ws.readyState === WebSocket.OPEN) {\n ws.send(JSON.stringify(message));\n }\n }\n\n /**\n * Start screencasting\n */\n private async startScreencast(): Promise<void> {\n // Set flag immediately to prevent race conditions with concurrent calls\n if (this.isScreencasting) return;\n this.isScreencasting = true;\n\n try {\n // Check if browser is launched\n if (!this.browser.isLaunched()) {\n throw new Error('Browser not launched');\n }\n\n await this.browser.startScreencast((frame) => this.broadcastFrame(frame), {\n format: 'jpeg',\n quality: 80,\n maxWidth: 1280,\n maxHeight: 720,\n everyNthFrame: 1,\n });\n\n // Notify all clients\n for (const client of this.clients) {\n this.sendStatus(client);\n }\n } catch (error) {\n // Reset flag on failure so caller can retry\n this.isScreencasting = false;\n throw error;\n }\n }\n\n /**\n * Stop screencasting\n */\n private async stopScreencast(): Promise<void> {\n if (!this.isScreencasting) return;\n\n await this.browser.stopScreencast();\n this.isScreencasting = false;\n\n // Notify all clients\n for (const client of this.clients) {\n this.sendStatus(client);\n }\n }\n\n /**\n * Get the port the server is running on\n */\n getPort(): number {\n return this.port;\n }\n\n /**\n * Get the number of connected clients\n */\n getClientCount(): number {\n return this.clients.size;\n }\n}\n"],"mappings":"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A,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAUM,SAAS,aAAa,OAA4B;AAEvD,MAAI;A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","names":["path","os","path","os","import_node_fs","import_node_path","import_node_os","devices","writeFileSync","mkdirSync","path","INTERACTIVE_ROLES","import_node_fs","import_node_path","path","successResponse","errorResponse","devices","devices","response"]}
|