@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/index.cjs CHANGED
@@ -85,7 +85,7 @@ var Orchestrator = class {
85
85
  env: { ...process.env, ...env }
86
86
  });
87
87
  return true;
88
- } catch (e) {
88
+ } catch {
89
89
  return false;
90
90
  }
91
91
  }
@@ -173,7 +173,7 @@ var Orchestrator = class {
173
173
  { stdio: "ignore" }
174
174
  );
175
175
  await new Promise((r) => setTimeout(r, 3e3));
176
- } catch (e) {
176
+ } catch {
177
177
  this.log(`Network rehydration warning: ${e}`, "warn");
178
178
  }
179
179
  }
@@ -237,7 +237,6 @@ var Orchestrator = class {
237
237
  } catch {
238
238
  }
239
239
  this.log("Waiting for device to come online...", "info");
240
- const start = Date.now();
241
240
  let online = false;
242
241
  while (Date.now() - start < 3e4) {
243
242
  try {
@@ -284,7 +283,6 @@ var Orchestrator = class {
284
283
  }
285
284
  waitForLog(container, pattern, timeoutMs = 12e4) {
286
285
  return new Promise((resolve, reject) => {
287
- const start = Date.now();
288
286
  const tail = (0, import_child_process.spawn)("docker", ["logs", "-f", container]);
289
287
  const timer = setTimeout(() => {
290
288
  tail.kill();
@@ -380,12 +378,12 @@ var WootzAgent = class {
380
378
  * @param timeoutMs The maximum amount of time (in ms) to wait for the daemon.
381
379
  */
382
380
  async waitForDaemon(timeoutMs = 18e4) {
383
- const start = Date.now();
384
- while (Date.now() - start < timeoutMs) {
381
+ const start2 = Date.now();
382
+ while (Date.now() - start2 < timeoutMs) {
385
383
  try {
386
384
  await this.sendCommand({ action: "tab_list" });
387
385
  return;
388
- } catch (e) {
386
+ } catch {
389
387
  await new Promise((r) => setTimeout(r, 1e3));
390
388
  }
391
389
  }
@@ -609,7 +607,7 @@ var WootzAgent = class {
609
607
  } else {
610
608
  reject(new Error(response.error || "Unknown error"));
611
609
  }
612
- } catch (e) {
610
+ } catch {
613
611
  reject(new Error(`Invalid response from daemon: ${responseBuffer}`));
614
612
  }
615
613
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../node_modules/tsup/assets/cjs_shims.js","../src/orchestrator.ts"],"sourcesContent":["import * as net from 'net';\nimport { randomUUID } from 'crypto';\nimport { Orchestrator } from './orchestrator.js';\nimport { z } from 'zod';\nimport pino from 'pino';\n\nconst DAEMON_PORT = 32001;\n\n// --- Custom Errors ---\nexport class WootzConnectionError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'WootzConnectionError';\n }\n}\n\nexport class WootzTimeoutError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'WootzTimeoutError';\n }\n}\n\nexport class WootzValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'WootzValidationError';\n }\n}\n\n// --- Schema Validation ---\nconst AgentOptionsSchema = z.object({\n dist: z.boolean().optional().default(true),\n logLevel: z.enum(['debug', 'info', 'warn', 'error', 'silent']).optional().default('info'),\n}).passthrough();\n\n/**\n * Options for initializing the WootzAgent.\n */\nexport interface AgentOptions extends z.input<typeof AgentOptionsSchema> {}\n\n/**\n * Main entry point for interacting with the Agent Browser environment.\n */\nexport class WootzAgent {\n private options: AgentOptions;\n private orchestrator: Orchestrator;\n public logger: pino.Logger;\n\n /**\n * Creates a new instance of the WootzAgent.\n * @param options Configuration options.\n * @throws {WootzValidationError} If the provided options do not match the expected schema.\n */\n constructor(options: AgentOptions = {}) {\n const parsedOptions = AgentOptionsSchema.safeParse(options);\n if (!parsedOptions.success) {\n throw new WootzValidationError(`Invalid agent options: ${parsedOptions.error.message}`);\n }\n \n this.options = parsedOptions.data;\n \n this.logger = pino({\n level: this.options.logLevel,\n transport: this.options.logLevel !== 'silent' ? {\n target: 'pino-pretty',\n options: {\n colorize: true,\n translateTime: 'HH:MM:ss Z',\n ignore: 'pid,hostname',\n },\n } : undefined,\n });\n\n this.orchestrator = new Orchestrator(this.options.dist!, this.logger);\n }\n\n // --- Lifecycle Management (Infrastructure) ---\n\n /**\n * Starts the underlying orchestrator and waits for the browser daemon to be ready.\n * @throws {WootzTimeoutError} If the daemon fails to become available within the timeout.\n */\n async start(): Promise<void> {\n await this.orchestrator.start();\n await this.waitForDaemon();\n }\n\n /**\n * Polls the daemon port until it accepts connections.\n * @param timeoutMs The maximum amount of time (in ms) to wait for the daemon.\n */\n private async waitForDaemon(timeoutMs = 180000): Promise<void> {\n const start = Date.now();\n while (Date.now() - start < timeoutMs) {\n try {\n await this.sendCommand({ action: 'tab_list' }); // Health check\n return; // Success\n } catch (e) {\n await new Promise((r) => setTimeout(r, 1000));\n }\n }\n throw new WootzTimeoutError(\n `Timed out waiting for Agent Daemon on port ${DAEMON_PORT} after ${timeoutMs / 1000}s`\n );\n }\n\n /**\n * Stops the orchestrator and cleans up resources.\n */\n async stop(): Promise<void> {\n await this.orchestrator.stop();\n }\n\n /**\n * Resets the environment completely.\n */\n async reset(): Promise<void> {\n await this.orchestrator.reset();\n }\n\n // --- Core Browser Actions (Direct Daemon) ---\n\n /**\n * Navigates the current tab to a specified URL.\n * @param url The URL to navigate to.\n * @param waitUntil The load state to wait for ('load', 'domcontentloaded', 'networkidle').\n */\n async navigate(\n url: string,\n waitUntil: 'load' | 'domcontentloaded' | 'networkidle' = 'load'\n ): Promise<string> {\n return await this.sendCommand({ action: 'navigate', url, waitUntil });\n }\n\n /**\n * Clicks on an element matching the given selector.\n * @param selector The CSS or semantic selector of the element to click.\n */\n async click(selector: string): Promise<string> {\n return await this.sendCommand({ action: 'click', selector });\n }\n\n /**\n * Double-clicks on an element matching the given selector.\n * @param selector The CSS or semantic selector.\n */\n async doubleClick(selector: string): Promise<string> {\n return await this.sendCommand({ action: 'dblclick', selector });\n }\n\n /**\n * Types text into a form field character by character.\n * @param selector The CSS or semantic selector of the input field.\n * @param text The text to type.\n * @param delay Delay between keystrokes in milliseconds.\n */\n async type(selector: string, text: string, delay?: number): Promise<string> {\n return await this.sendCommand({ action: 'type', selector, text, delay });\n }\n\n /**\n * Fills an input field directly with a value (faster than type).\n * @param selector The CSS or semantic selector of the input field.\n * @param value The value to fill.\n */\n async fill(selector: string, value: string): Promise<string> {\n return await this.sendCommand({ action: 'fill', selector, value });\n }\n\n async check(selector: string): Promise<string> {\n return await this.sendCommand({ action: 'check', selector });\n }\n\n async uncheck(selector: string): Promise<string> {\n return await this.sendCommand({ action: 'uncheck', selector });\n }\n\n async hover(selector: string): Promise<string> {\n return await this.sendCommand({ action: 'hover', selector });\n }\n\n async focus(selector: string): Promise<string> {\n return await this.sendCommand({ action: 'focus', selector });\n }\n\n async press(key: string, selector?: string): Promise<string> {\n return await this.sendCommand({ action: 'press', key, selector });\n }\n\n async selectOption(selector: string, value: string | string[]): Promise<string> {\n return await this.sendCommand({ action: 'select', selector, values: value });\n }\n\n // --- Introspection & State ---\n\n /**\n * Captures the full DOM/AXTree snapshot of the current page.\n * @returns A string representation of the interactive accessibility tree.\n */\n async snapshot(): Promise<string> {\n const result = await this.sendCommand({ action: 'snapshot' }, true);\n return result.snapshot || '';\n }\n\n async innerText(selector: string): Promise<string> {\n const res = await this.sendCommand({ action: 'innertext', selector }, true);\n return res.text;\n }\n\n async innerHTML(selector: string): Promise<string> {\n const res = await this.sendCommand({ action: 'innerhtml', selector }, true);\n return res.html;\n }\n\n async getAttribute(selector: string, attribute: string): Promise<string> {\n const res = await this.sendCommand({ action: 'getattribute', selector, attribute }, true);\n return res.value;\n }\n\n async inputValue(selector: string): Promise<string> {\n const res = await this.sendCommand({ action: 'inputvalue', selector }, true);\n return res.value;\n }\n\n async isVisible(selector: string): Promise<boolean> {\n const res = await this.sendCommand({ action: 'isvisible', selector }, true);\n return res.visible;\n }\n\n async isEnabled(selector: string): Promise<boolean> {\n const res = await this.sendCommand({ action: 'isenabled', selector }, true);\n return res.enabled;\n }\n\n async isChecked(selector: string): Promise<boolean> {\n const res = await this.sendCommand({ action: 'ischecked', selector }, true);\n return res.checked;\n }\n\n // --- Waiting & Navigation ---\n\n async waitForSelector(\n selector: string,\n state: 'attached' | 'detached' | 'visible' | 'hidden' = 'visible',\n timeout?: number\n ): Promise<string> {\n return await this.sendCommand({ action: 'wait', selector, state, timeout });\n }\n\n async waitForTimeout(ms: number): Promise<string> {\n return await this.sendCommand({ action: 'wait', timeout: ms });\n }\n\n async waitForLoadState(\n state: 'load' | 'domcontentloaded' | 'networkidle' = 'load'\n ): Promise<string> {\n return await this.sendCommand({ action: 'waitforloadstate', state });\n }\n\n async reload(): Promise<string> {\n return await this.sendCommand({ action: 'reload' });\n }\n\n async goBack(): Promise<string> {\n return await this.sendCommand({ action: 'back' });\n }\n\n async goForward(): Promise<string> {\n return await this.sendCommand({ action: 'forward' });\n }\n\n // --- Semantic Locators ---\n\n async getByRole(role: string, name?: string, _exact: boolean = false): Promise<string> {\n throw new Error(\n 'Locator builders (getByRole) are not fully supported in stateless mode yet. Use standard selectors.'\n );\n }\n\n // --- Utilities ---\n\n /**\n * Captures a screenshot of the current page.\n * @param path Optional file path to save the screenshot.\n */\n async screenshot(path?: string): Promise<string> {\n const res = await this.sendCommand({ action: 'screenshot', path }, true);\n return res.path;\n }\n\n async scroll(x: number, y: number): Promise<string> {\n return await this.sendCommand({ action: 'scroll', x, y });\n }\n\n async evaluate(script: string): Promise<any> {\n const res = await this.sendCommand({ action: 'evaluate', script }, true);\n return res.result;\n }\n\n // --- Tab Management ---\n\n async newTab(url?: string): Promise<string> {\n return await this.sendCommand({ action: 'tab_new', url });\n }\n\n async switchTab(index: number): Promise<string> {\n return await this.sendCommand({ action: 'tab_switch', index });\n }\n\n async closeTab(index?: number): Promise<string> {\n return await this.sendCommand({ action: 'tab_close', index });\n }\n\n async listTabs(): Promise<any[]> {\n const res = await this.sendCommand({ action: 'tab_list' }, true);\n return res.tabs;\n }\n\n // --- Generic Execution ---\n\n async command(action: string, ...args: string[]): Promise<string> {\n const cmd: any = { action };\n\n if (action === 'open' || action === 'navigate') {\n cmd.action = 'navigate';\n cmd.url = args[0];\n } else if (action === 'click') {\n cmd.selector = args[0];\n } else if (action === 'type') {\n cmd.selector = args[0];\n cmd.text = args[1];\n } else if (action === 'press') {\n cmd.key = args[0];\n } else if (action === 'scroll') {\n cmd.x = parseInt(args[0] || '0');\n cmd.y = parseInt(args[1] || '0');\n } else if (action === 'wait') {\n if (/^\\d+$/.test(args[0])) cmd.timeout = parseInt(args[0]);\n else cmd.selector = args[0];\n } else {\n if (args[0]) cmd.selector = args[0];\n if (args[1]) cmd.text = args[1] || args[1]; // value/text\n }\n\n const res = await this.sendCommand(cmd, true);\n\n if (typeof res === 'object') {\n if (res.text) return res.text;\n if (res.url) return res.url;\n if (res.snapshot) return res.snapshot;\n return JSON.stringify(res);\n }\n return String(res);\n }\n\n private sendCommand(command: any, returnData = false): Promise<any> {\n return new Promise((resolve, reject) => {\n if (!command.id) command.id = randomUUID();\n\n const client = new net.Socket();\n\n client.connect(DAEMON_PORT, '127.0.0.1', () => {\n client.write(JSON.stringify(command) + '\\n');\n });\n\n let responseBuffer = '';\n\n client.on('data', (data) => {\n responseBuffer += data.toString();\n if (responseBuffer.includes('\\n')) {\n client.end();\n }\n });\n\n client.on('end', () => {\n try {\n const response = JSON.parse(responseBuffer.trim());\n if (response.success) {\n resolve(returnData ? response.data : 'OK');\n } else {\n reject(new Error(response.error || 'Unknown error'));\n }\n } catch (e) {\n reject(new Error(`Invalid response from daemon: ${responseBuffer}`));\n }\n });\n\n client.on('error', (err) => {\n reject(new WootzConnectionError(`Failed to connect to agent daemon (is it running?): ${err.message}`));\n });\n });\n }\n}\n\nexport default WootzAgent;","// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","import { spawn, spawnSync, execSync } from 'child_process';\nimport path from 'path';\nimport 'fs';\nimport { fileURLToPath } from 'url';\nimport pino from 'pino';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst PROJECT_ROOT = path.resolve(__dirname, '..');\n\nexport class Orchestrator {\n private composeFile: string;\n private logger: pino.Logger;\n\n constructor(distMode: boolean, logger?: pino.Logger) {\n this.composeFile = path.join(\n PROJECT_ROOT,\n distMode ? 'docker-compose.sdk.yml' : 'docker-compose.prod.yml'\n );\n this.logger = logger || pino();\n }\n\n private log(msg: string, level: 'info' | 'success' | 'warn' | 'error' = 'info') {\n switch (level) {\n case 'success':\n this.logger.info({ sdk: true }, msg);\n break;\n case 'warn':\n this.logger.warn({ sdk: true }, msg);\n break;\n case 'error':\n this.logger.error({ sdk: true }, msg);\n break;\n default:\n this.logger.info({ sdk: true }, msg);\n }\n }\n\n private runCommand(cmd: string, env: Record<string, string> = {}): boolean {\n try {\n execSync(cmd, {\n stdio: 'inherit',\n env: { ...process.env, ...env },\n });\n return true;\n } catch (e) {\n return false;\n }\n }\n\n private getContainerId(serviceName: string): string | null {\n try {\n const output = execSync(`docker compose -f \"${this.composeFile}\" ps -q ${serviceName}`, {\n encoding: 'utf-8',\n });\n return output.trim() || null;\n } catch {\n return null;\n }\n }\n\n private isPortMapped(containerId: string, port: number): boolean {\n try {\n const output = execSync(`docker port \"${containerId}\" ${port}`, { encoding: 'utf-8' });\n return output.includes('0.0.0.0:') || output.includes(':::');\n } catch {\n return false;\n }\n }\n\n private async pullImagesWithRetry(): Promise<void> {\n if (!this.composeFile.endsWith('docker-compose.sdk.yml')) return;\n\n this.log('Please wait while we get things ready...', 'info');\n const maxRetries = 10;\n\n for (let count = 0; count < maxRetries; count++) {\n if (this.runCommand(`docker compose -f \"${this.composeFile}\" pull`)) {\n return;\n }\n this.log(\n `Download failed/interrupted. Retrying (${count + 1}/${maxRetries}) in 10s...`,\n 'warn'\n );\n await new Promise((r) => setTimeout(r, 10000));\n }\n\n this.log(\n `Failed to download images after ${maxRetries} attempts. Check internet connection.`,\n 'error'\n );\n process.exit(1);\n }\n\n private async hasSnapshot(): Promise<boolean> {\n try {\n // 1. Check if volume exists\n execSync(`docker volume inspect agent-snapshots`, { stdio: 'ignore' });\n\n // 2. Check if volume contains the 'quickboot' directory\n // We use a tiny helper container to look inside the managed volume\n const output = execSync(`docker run --rm -v agent-snapshots:/data busybox ls /data`, {\n encoding: 'utf-8',\n });\n return output.includes('quickboot');\n } catch {\n return false;\n }\n }\n\n public async start(): Promise<void> {\n this.log(`Initializing Agent Environment...`, 'info');\n\n await this.pullImagesWithRetry();\n\n this.log('Cleaning up previous container state...', 'info');\n this.runCommand(`docker compose -f \"${this.composeFile}\" down -v --remove-orphans`);\n\n const hasSnapshot = await this.hasSnapshot();\n\n if (hasSnapshot) {\n // === WARM START ===\n this.log('Found cached baseline snapshot. Performing HYPER-SPEED WARM BOOT...', 'success');\n\n const success = this.runCommand(`docker compose -f \"${this.composeFile}\" up -d`, {\n EMULATOR_SNAPSHOT_NAME: 'quickboot',\n });\n\n if (!success) throw new Error('Startup failed during docker compose up.');\n\n const agentCont = this.getContainerId('agent-service');\n const androidCont = this.getContainerId('android-service');\n\n // Verify Port Mapping\n if (agentCont && !this.isPortMapped(agentCont, 3000)) {\n this.log('Port 3000 (Host 32001) is not mapped! Container config is stale.', 'warn');\n this.log('Forcing full restart to apply network settings...', 'info');\n this.runCommand(`docker compose -f \"${this.composeFile}\" down -v --remove-orphans`);\n await new Promise((r) => setTimeout(r, 5000));\n this.runCommand(`docker compose -f \"${this.composeFile}\" up -d`, {\n EMULATOR_SNAPSHOT_NAME: 'quickboot',\n });\n }\n\n if (androidCont) {\n this.log('Rehydrating Android network connection...', 'info');\n try {\n execSync(`docker exec \"${androidCont}\" adb shell cmd connectivity airplane-mode enable`, {\n stdio: 'ignore',\n });\n await new Promise((r) => setTimeout(r, 2000));\n execSync(\n `docker exec \"${androidCont}\" adb shell cmd connectivity airplane-mode disable`,\n { stdio: 'ignore' }\n );\n await new Promise((r) => setTimeout(r, 3000));\n } catch (e) {\n this.log(`Network rehydration warning: ${e}`, 'warn');\n }\n }\n\n this.log('Waiting for Daemon Connection...');\n if (agentCont) await this.waitForLog(agentCont, 'Daemon listening on TCP', 180000);\n } else {\n // === COLD START ===\n this.log('No baseline found. Performing FIRST RUN SETUP (Cold Boot)...', 'warn');\n this.log('This will take ~60-90 seconds, but only once.', 'warn');\n\n const success = this.runCommand(`docker compose -f \"${this.composeFile}\" up -d`, {\n EMULATOR_SNAPSHOT_NAME: '',\n });\n\n if (!success) throw new Error('Startup failed during docker compose up.');\n\n let androidCont = this.getContainerId('android-service');\n const agentCont = this.getContainerId('agent-service');\n\n if (!androidCont) throw new Error('Error: Android container not found.');\n\n // Verify Port Mapping\n if (agentCont && !this.isPortMapped(agentCont, 3000)) {\n this.log('Port 3000 (Host 32001) is not mapped! Container config is stale.', 'warn');\n this.log('Forcing full restart to apply network settings...', 'info');\n this.runCommand(`docker compose -f \"${this.composeFile}\" down -v --remove-orphans`);\n await new Promise((r) => setTimeout(r, 5000));\n this.runCommand(`docker compose -f \"${this.composeFile}\" up -d`, {\n EMULATOR_SNAPSHOT_NAME: '',\n });\n androidCont = this.getContainerId('android-service') || androidCont;\n }\n\n this.log('Waiting for Android OS to boot (this takes a moment)...', 'info');\n await this.waitForLog(androidCont, 'Emulator boot complete');\n\n this.log('Waiting for Browser Installation...', 'info');\n await this.waitForLog(androidCont, 'APK installation complete');\n\n this.log('Waiting for CDP Bridge...', 'info');\n await this.waitForLog(androidCont, 'CDP Bridge ready');\n\n this.log('Waiting for Agent Daemon Connection...');\n if (agentCont) await this.waitForLog(agentCont, 'Daemon listening on TCP');\n\n // Save Snapshot\n this.log('Saving emulator state (quickboot)...', 'info');\n const saved = this.runCommand(\n `docker exec \"${androidCont}\" adb emu avd snapshot save quickboot`\n );\n if (saved) {\n this.log('Snapshot saved to host volume.', 'success');\n this.log('Setup Complete! Future runs will launch instantly.', 'success');\n } else {\n throw new Error('Failed to save snapshot inside emulator.');\n }\n }\n }\n\n public async stop(): Promise<void> {\n this.log('Stopping environment...', 'info');\n this.runCommand(`docker compose -f \"${this.composeFile}\" down -v --remove-orphans`);\n this.log('Environment cleaned and stopped.', 'success');\n }\n\n public async reset(): Promise<void> {\n this.log('Performing Fast Browser Reset...', 'info');\n const androidCont = this.getContainerId('android-service');\n if (!androidCont) {\n this.log('Android container not running.', 'error');\n return;\n }\n\n this.log('Initiating fast reset (userspace reboot)...', 'info');\n try {\n execSync(`docker exec \"${androidCont}\" adb shell reboot userspace`, { stdio: 'ignore' });\n } catch {\n // Ignored\n }\n\n this.log('Waiting for device to come online...', 'info');\n const start = Date.now();\n let online = false;\n\n while (Date.now() - start < 30000) {\n try {\n const state = execSync(`docker exec \"${androidCont}\" adb get-state`, {\n encoding: 'utf-8',\n }).trim();\n if (state === 'device') {\n execSync(`docker exec \"${androidCont}\" adb shell echo ok`, { stdio: 'ignore' });\n online = true;\n break;\n }\n } catch {\n // Still offline\n }\n await new Promise((r) => setTimeout(r, 1000));\n }\n\n if (!online) throw new Error('Timeout waiting for device after reboot');\n this.log('Device online', 'success');\n\n this.log('Waiting for browser CDP...', 'info');\n const cdpStart = Date.now();\n let cdpReady = false;\n\n while (Date.now() - cdpStart < 30000) {\n try {\n execSync(\n `docker exec \"${androidCont}\" curl -s --connect-timeout 2 http://localhost:9224/json/version`,\n { stdio: 'ignore' }\n );\n cdpReady = true;\n break;\n } catch {\n if (Date.now() - cdpStart > 15000) {\n try {\n execSync(\n `docker exec \"${androidCont}\" adb shell am start -n com.wootzapp.web/com.aspect.chromium.ChromiumMain -a android.intent.action.VIEW -d 'about:blank'`,\n { stdio: 'ignore' }\n );\n } catch {}\n }\n }\n await new Promise((r) => setTimeout(r, 1000));\n }\n\n if (!cdpReady) throw new Error('Timeout waiting for CDP');\n this.log('Fast reset complete!', 'success');\n }\n\n private waitForLog(container: string, pattern: string, timeoutMs = 120000): Promise<void> {\n return new Promise((resolve, reject) => {\n const start = Date.now();\n const tail = spawn('docker', ['logs', '-f', container]);\n\n const timer = setTimeout(() => {\n tail.kill();\n reject(new Error(`Timeout waiting for log pattern \"${pattern}\" in container ${container}`));\n }, timeoutMs);\n\n tail.stdout.on('data', (data) => {\n if (data.toString().includes(pattern)) {\n clearTimeout(timer);\n tail.kill();\n resolve();\n }\n });\n\n tail.stderr.on('data', (data) => {\n if (data.toString().includes(pattern)) {\n clearTimeout(timer);\n tail.kill();\n resolve();\n }\n });\n\n tail.on('error', (err) => {\n clearTimeout(timer);\n reject(err);\n });\n });\n }\n}\n"],"mappings":"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","names":["path","pino","import_pino","pino","path"]}
1
+ {"version":3,"sources":["../src/index.ts","../node_modules/tsup/assets/cjs_shims.js","../src/orchestrator.ts"],"sourcesContent":["import * as net from 'net';\nimport { randomUUID } from 'crypto';\nimport { Orchestrator } from './orchestrator.js';\nimport { z } from 'zod';\nimport pino from 'pino';\n\nconst DAEMON_PORT = 32001;\n\n// --- Custom Errors ---\nexport class WootzConnectionError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'WootzConnectionError';\n }\n}\n\nexport class WootzTimeoutError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'WootzTimeoutError';\n }\n}\n\nexport class WootzValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'WootzValidationError';\n }\n}\n\n// --- Schema Validation ---\nconst AgentOptionsSchema = z.object({\n dist: z.boolean().optional().default(true),\n logLevel: z.enum(['debug', 'info', 'warn', 'error', 'silent']).optional().default('info'),\n}).passthrough();\n\n/**\n * Options for initializing the WootzAgent.\n */\nexport type AgentOptions = z.input<typeof AgentOptionsSchema>;\n\n/**\n * Main entry point for interacting with the Agent Browser environment.\n */\nexport class WootzAgent {\n private options: AgentOptions;\n private orchestrator: Orchestrator;\n public logger: pino.Logger;\n\n /**\n * Creates a new instance of the WootzAgent.\n * @param options Configuration options.\n * @throws {WootzValidationError} If the provided options do not match the expected schema.\n */\n constructor(options: AgentOptions = {}) {\n const parsedOptions = AgentOptionsSchema.safeParse(options);\n if (!parsedOptions.success) {\n throw new WootzValidationError(`Invalid agent options: ${parsedOptions.error.message}`);\n }\n \n this.options = parsedOptions.data;\n \n this.logger = pino({\n level: this.options.logLevel,\n transport: this.options.logLevel !== 'silent' ? {\n target: 'pino-pretty',\n options: {\n colorize: true,\n translateTime: 'HH:MM:ss Z',\n ignore: 'pid,hostname',\n },\n } : undefined,\n });\n\n this.orchestrator = new Orchestrator(this.options.dist!, this.logger);\n }\n\n // --- Lifecycle Management (Infrastructure) ---\n\n /**\n * Starts the underlying orchestrator and waits for the browser daemon to be ready.\n * @throws {WootzTimeoutError} If the daemon fails to become available within the timeout.\n */\n async start(): Promise<void> {\n await this.orchestrator.start();\n await this.waitForDaemon();\n }\n\n /**\n * Polls the daemon port until it accepts connections.\n * @param timeoutMs The maximum amount of time (in ms) to wait for the daemon.\n */\n private async waitForDaemon(timeoutMs = 180000): Promise<void> {\n const start = Date.now();\n while (Date.now() - start < timeoutMs) {\n try {\n await this.sendCommand({ action: 'tab_list' }); // Health check\n return; // Success\n } catch {\n await new Promise((r) => setTimeout(r, 1000));\n }\n }\n throw new WootzTimeoutError(\n `Timed out waiting for Agent Daemon on port ${DAEMON_PORT} after ${timeoutMs / 1000}s`\n );\n }\n\n /**\n * Stops the orchestrator and cleans up resources.\n */\n async stop(): Promise<void> {\n await this.orchestrator.stop();\n }\n\n /**\n * Resets the environment completely.\n */\n async reset(): Promise<void> {\n await this.orchestrator.reset();\n }\n\n // --- Core Browser Actions (Direct Daemon) ---\n\n /**\n * Navigates the current tab to a specified URL.\n * @param url The URL to navigate to.\n * @param waitUntil The load state to wait for ('load', 'domcontentloaded', 'networkidle').\n */\n async navigate(\n url: string,\n waitUntil: 'load' | 'domcontentloaded' | 'networkidle' = 'load'\n ): Promise<string> {\n return await this.sendCommand({ action: 'navigate', url, waitUntil });\n }\n\n /**\n * Clicks on an element matching the given selector.\n * @param selector The CSS or semantic selector of the element to click.\n */\n async click(selector: string): Promise<string> {\n return await this.sendCommand({ action: 'click', selector });\n }\n\n /**\n * Double-clicks on an element matching the given selector.\n * @param selector The CSS or semantic selector.\n */\n async doubleClick(selector: string): Promise<string> {\n return await this.sendCommand({ action: 'dblclick', selector });\n }\n\n /**\n * Types text into a form field character by character.\n * @param selector The CSS or semantic selector of the input field.\n * @param text The text to type.\n * @param delay Delay between keystrokes in milliseconds.\n */\n async type(selector: string, text: string, delay?: number): Promise<string> {\n return await this.sendCommand({ action: 'type', selector, text, delay });\n }\n\n /**\n * Fills an input field directly with a value (faster than type).\n * @param selector The CSS or semantic selector of the input field.\n * @param value The value to fill.\n */\n async fill(selector: string, value: string): Promise<string> {\n return await this.sendCommand({ action: 'fill', selector, value });\n }\n\n async check(selector: string): Promise<string> {\n return await this.sendCommand({ action: 'check', selector });\n }\n\n async uncheck(selector: string): Promise<string> {\n return await this.sendCommand({ action: 'uncheck', selector });\n }\n\n async hover(selector: string): Promise<string> {\n return await this.sendCommand({ action: 'hover', selector });\n }\n\n async focus(selector: string): Promise<string> {\n return await this.sendCommand({ action: 'focus', selector });\n }\n\n async press(key: string, selector?: string): Promise<string> {\n return await this.sendCommand({ action: 'press', key, selector });\n }\n\n async selectOption(selector: string, value: string | string[]): Promise<string> {\n return await this.sendCommand({ action: 'select', selector, values: value });\n }\n\n // --- Introspection & State ---\n\n /**\n * Captures the full DOM/AXTree snapshot of the current page.\n * @returns A string representation of the interactive accessibility tree.\n */\n async snapshot(): Promise<string> {\n const result = await this.sendCommand({ action: 'snapshot' }, true);\n return result.snapshot || '';\n }\n\n async innerText(selector: string): Promise<string> {\n const res = await this.sendCommand({ action: 'innertext', selector }, true);\n return res.text;\n }\n\n async innerHTML(selector: string): Promise<string> {\n const res = await this.sendCommand({ action: 'innerhtml', selector }, true);\n return res.html;\n }\n\n async getAttribute(selector: string, attribute: string): Promise<string> {\n const res = await this.sendCommand({ action: 'getattribute', selector, attribute }, true);\n return res.value;\n }\n\n async inputValue(selector: string): Promise<string> {\n const res = await this.sendCommand({ action: 'inputvalue', selector }, true);\n return res.value;\n }\n\n async isVisible(selector: string): Promise<boolean> {\n const res = await this.sendCommand({ action: 'isvisible', selector }, true);\n return res.visible;\n }\n\n async isEnabled(selector: string): Promise<boolean> {\n const res = await this.sendCommand({ action: 'isenabled', selector }, true);\n return res.enabled;\n }\n\n async isChecked(selector: string): Promise<boolean> {\n const res = await this.sendCommand({ action: 'ischecked', selector }, true);\n return res.checked;\n }\n\n // --- Waiting & Navigation ---\n\n async waitForSelector(\n selector: string,\n state: 'attached' | 'detached' | 'visible' | 'hidden' = 'visible',\n timeout?: number\n ): Promise<string> {\n return await this.sendCommand({ action: 'wait', selector, state, timeout });\n }\n\n async waitForTimeout(ms: number): Promise<string> {\n return await this.sendCommand({ action: 'wait', timeout: ms });\n }\n\n async waitForLoadState(\n state: 'load' | 'domcontentloaded' | 'networkidle' = 'load'\n ): Promise<string> {\n return await this.sendCommand({ action: 'waitforloadstate', state });\n }\n\n async reload(): Promise<string> {\n return await this.sendCommand({ action: 'reload' });\n }\n\n async goBack(): Promise<string> {\n return await this.sendCommand({ action: 'back' });\n }\n\n async goForward(): Promise<string> {\n return await this.sendCommand({ action: 'forward' });\n }\n\n // --- Semantic Locators ---\n\n async getByRole(role: string, name?: string, _exact: boolean = false): Promise<string> {\n throw new Error(\n 'Locator builders (getByRole) are not fully supported in stateless mode yet. Use standard selectors.'\n );\n }\n\n // --- Utilities ---\n\n /**\n * Captures a screenshot of the current page.\n * @param path Optional file path to save the screenshot.\n */\n async screenshot(path?: string): Promise<string> {\n const res = await this.sendCommand({ action: 'screenshot', path }, true);\n return res.path;\n }\n\n async scroll(x: number, y: number): Promise<string> {\n return await this.sendCommand({ action: 'scroll', x, y });\n }\n\n async evaluate(script: string): Promise<any> {\n const res = await this.sendCommand({ action: 'evaluate', script }, true);\n return res.result;\n }\n\n // --- Tab Management ---\n\n async newTab(url?: string): Promise<string> {\n return await this.sendCommand({ action: 'tab_new', url });\n }\n\n async switchTab(index: number): Promise<string> {\n return await this.sendCommand({ action: 'tab_switch', index });\n }\n\n async closeTab(index?: number): Promise<string> {\n return await this.sendCommand({ action: 'tab_close', index });\n }\n\n async listTabs(): Promise<any[]> {\n const res = await this.sendCommand({ action: 'tab_list' }, true);\n return res.tabs;\n }\n\n // --- Generic Execution ---\n\n async command(action: string, ...args: string[]): Promise<string> {\n const cmd: any = { action };\n\n if (action === 'open' || action === 'navigate') {\n cmd.action = 'navigate';\n cmd.url = args[0];\n } else if (action === 'click') {\n cmd.selector = args[0];\n } else if (action === 'type') {\n cmd.selector = args[0];\n cmd.text = args[1];\n } else if (action === 'press') {\n cmd.key = args[0];\n } else if (action === 'scroll') {\n cmd.x = parseInt(args[0] || '0');\n cmd.y = parseInt(args[1] || '0');\n } else if (action === 'wait') {\n if (/^\\d+$/.test(args[0])) cmd.timeout = parseInt(args[0]);\n else cmd.selector = args[0];\n } else {\n if (args[0]) cmd.selector = args[0];\n if (args[1]) cmd.text = args[1] || args[1]; // value/text\n }\n\n const res = await this.sendCommand(cmd, true);\n\n if (typeof res === 'object') {\n if (res.text) return res.text;\n if (res.url) return res.url;\n if (res.snapshot) return res.snapshot;\n return JSON.stringify(res);\n }\n return String(res);\n }\n\n private sendCommand(command: any, returnData = false): Promise<any> {\n return new Promise((resolve, reject) => {\n if (!command.id) command.id = randomUUID();\n\n const client = new net.Socket();\n\n client.connect(DAEMON_PORT, '127.0.0.1', () => {\n client.write(JSON.stringify(command) + '\\n');\n });\n\n let responseBuffer = '';\n\n client.on('data', (data) => {\n responseBuffer += data.toString();\n if (responseBuffer.includes('\\n')) {\n client.end();\n }\n });\n\n client.on('end', () => {\n try {\n const response = JSON.parse(responseBuffer.trim());\n if (response.success) {\n resolve(returnData ? response.data : 'OK');\n } else {\n reject(new Error(response.error || 'Unknown error'));\n }\n } catch {\n reject(new Error(`Invalid response from daemon: ${responseBuffer}`));\n }\n });\n\n client.on('error', (err) => {\n reject(new WootzConnectionError(`Failed to connect to agent daemon (is it running?): ${err.message}`));\n });\n });\n }\n}\n\nexport default WootzAgent;","// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","import { spawn, execSync } from 'child_process';\nimport path from 'path';\nimport 'fs';\nimport { fileURLToPath } from 'url';\nimport pino from 'pino';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst PROJECT_ROOT = path.resolve(__dirname, '..');\n\nexport class Orchestrator {\n private composeFile: string;\n private logger: pino.Logger;\n\n constructor(distMode: boolean, logger?: pino.Logger) {\n this.composeFile = path.join(\n PROJECT_ROOT,\n distMode ? 'docker-compose.sdk.yml' : 'docker-compose.prod.yml'\n );\n this.logger = logger || pino();\n }\n\n private log(msg: string, level: 'info' | 'success' | 'warn' | 'error' = 'info') {\n switch (level) {\n case 'success':\n this.logger.info({ sdk: true }, msg);\n break;\n case 'warn':\n this.logger.warn({ sdk: true }, msg);\n break;\n case 'error':\n this.logger.error({ sdk: true }, msg);\n break;\n default:\n this.logger.info({ sdk: true }, msg);\n }\n }\n\n private runCommand(cmd: string, env: Record<string, string> = {}): boolean {\n try {\n execSync(cmd, {\n stdio: 'inherit',\n env: { ...process.env, ...env },\n });\n return true;\n } catch {\n return false;\n }\n }\n\n private getContainerId(serviceName: string): string | null {\n try {\n const output = execSync(`docker compose -f \"${this.composeFile}\" ps -q ${serviceName}`, {\n encoding: 'utf-8',\n });\n return output.trim() || null;\n } catch {\n return null;\n }\n }\n\n private isPortMapped(containerId: string, port: number): boolean {\n try {\n const output = execSync(`docker port \"${containerId}\" ${port}`, { encoding: 'utf-8' });\n return output.includes('0.0.0.0:') || output.includes(':::');\n } catch {\n return false;\n }\n }\n\n private async pullImagesWithRetry(): Promise<void> {\n if (!this.composeFile.endsWith('docker-compose.sdk.yml')) return;\n\n this.log('Please wait while we get things ready...', 'info');\n const maxRetries = 10;\n\n for (let count = 0; count < maxRetries; count++) {\n if (this.runCommand(`docker compose -f \"${this.composeFile}\" pull`)) {\n return;\n }\n this.log(\n `Download failed/interrupted. Retrying (${count + 1}/${maxRetries}) in 10s...`,\n 'warn'\n );\n await new Promise((r) => setTimeout(r, 10000));\n }\n\n this.log(\n `Failed to download images after ${maxRetries} attempts. Check internet connection.`,\n 'error'\n );\n process.exit(1);\n }\n\n private async hasSnapshot(): Promise<boolean> {\n try {\n // 1. Check if volume exists\n execSync(`docker volume inspect agent-snapshots`, { stdio: 'ignore' });\n\n // 2. Check if volume contains the 'quickboot' directory\n // We use a tiny helper container to look inside the managed volume\n const output = execSync(`docker run --rm -v agent-snapshots:/data busybox ls /data`, {\n encoding: 'utf-8',\n });\n return output.includes('quickboot');\n } catch {\n return false;\n }\n }\n\n public async start(): Promise<void> {\n this.log(`Initializing Agent Environment...`, 'info');\n\n await this.pullImagesWithRetry();\n\n this.log('Cleaning up previous container state...', 'info');\n this.runCommand(`docker compose -f \"${this.composeFile}\" down -v --remove-orphans`);\n\n const hasSnapshot = await this.hasSnapshot();\n\n if (hasSnapshot) {\n // === WARM START ===\n this.log('Found cached baseline snapshot. Performing HYPER-SPEED WARM BOOT...', 'success');\n\n const success = this.runCommand(`docker compose -f \"${this.composeFile}\" up -d`, {\n EMULATOR_SNAPSHOT_NAME: 'quickboot',\n });\n\n if (!success) throw new Error('Startup failed during docker compose up.');\n\n const agentCont = this.getContainerId('agent-service');\n const androidCont = this.getContainerId('android-service');\n\n // Verify Port Mapping\n if (agentCont && !this.isPortMapped(agentCont, 3000)) {\n this.log('Port 3000 (Host 32001) is not mapped! Container config is stale.', 'warn');\n this.log('Forcing full restart to apply network settings...', 'info');\n this.runCommand(`docker compose -f \"${this.composeFile}\" down -v --remove-orphans`);\n await new Promise((r) => setTimeout(r, 5000));\n this.runCommand(`docker compose -f \"${this.composeFile}\" up -d`, {\n EMULATOR_SNAPSHOT_NAME: 'quickboot',\n });\n }\n\n if (androidCont) {\n this.log('Rehydrating Android network connection...', 'info');\n try {\n execSync(`docker exec \"${androidCont}\" adb shell cmd connectivity airplane-mode enable`, {\n stdio: 'ignore',\n });\n await new Promise((r) => setTimeout(r, 2000));\n execSync(\n `docker exec \"${androidCont}\" adb shell cmd connectivity airplane-mode disable`,\n { stdio: 'ignore' }\n );\n await new Promise((r) => setTimeout(r, 3000));\n } catch {\n this.log(`Network rehydration warning: ${e}`, 'warn');\n }\n }\n\n this.log('Waiting for Daemon Connection...');\n if (agentCont) await this.waitForLog(agentCont, 'Daemon listening on TCP', 180000);\n } else {\n // === COLD START ===\n this.log('No baseline found. Performing FIRST RUN SETUP (Cold Boot)...', 'warn');\n this.log('This will take ~60-90 seconds, but only once.', 'warn');\n\n const success = this.runCommand(`docker compose -f \"${this.composeFile}\" up -d`, {\n EMULATOR_SNAPSHOT_NAME: '',\n });\n\n if (!success) throw new Error('Startup failed during docker compose up.');\n\n let androidCont = this.getContainerId('android-service');\n const agentCont = this.getContainerId('agent-service');\n\n if (!androidCont) throw new Error('Error: Android container not found.');\n\n // Verify Port Mapping\n if (agentCont && !this.isPortMapped(agentCont, 3000)) {\n this.log('Port 3000 (Host 32001) is not mapped! Container config is stale.', 'warn');\n this.log('Forcing full restart to apply network settings...', 'info');\n this.runCommand(`docker compose -f \"${this.composeFile}\" down -v --remove-orphans`);\n await new Promise((r) => setTimeout(r, 5000));\n this.runCommand(`docker compose -f \"${this.composeFile}\" up -d`, {\n EMULATOR_SNAPSHOT_NAME: '',\n });\n androidCont = this.getContainerId('android-service') || androidCont;\n }\n\n this.log('Waiting for Android OS to boot (this takes a moment)...', 'info');\n await this.waitForLog(androidCont, 'Emulator boot complete');\n\n this.log('Waiting for Browser Installation...', 'info');\n await this.waitForLog(androidCont, 'APK installation complete');\n\n this.log('Waiting for CDP Bridge...', 'info');\n await this.waitForLog(androidCont, 'CDP Bridge ready');\n\n this.log('Waiting for Agent Daemon Connection...');\n if (agentCont) await this.waitForLog(agentCont, 'Daemon listening on TCP');\n\n // Save Snapshot\n this.log('Saving emulator state (quickboot)...', 'info');\n const saved = this.runCommand(\n `docker exec \"${androidCont}\" adb emu avd snapshot save quickboot`\n );\n if (saved) {\n this.log('Snapshot saved to host volume.', 'success');\n this.log('Setup Complete! Future runs will launch instantly.', 'success');\n } else {\n throw new Error('Failed to save snapshot inside emulator.');\n }\n }\n }\n\n public async stop(): Promise<void> {\n this.log('Stopping environment...', 'info');\n this.runCommand(`docker compose -f \"${this.composeFile}\" down -v --remove-orphans`);\n this.log('Environment cleaned and stopped.', 'success');\n }\n\n public async reset(): Promise<void> {\n this.log('Performing Fast Browser Reset...', 'info');\n const androidCont = this.getContainerId('android-service');\n if (!androidCont) {\n this.log('Android container not running.', 'error');\n return;\n }\n\n this.log('Initiating fast reset (userspace reboot)...', 'info');\n try {\n execSync(`docker exec \"${androidCont}\" adb shell reboot userspace`, { stdio: 'ignore' });\n } catch {\n // Ignored\n }\n\n this.log('Waiting for device to come online...', 'info');\n \n let online = false;\n\n while (Date.now() - start < 30000) {\n try {\n const state = execSync(`docker exec \"${androidCont}\" adb get-state`, {\n encoding: 'utf-8',\n }).trim();\n if (state === 'device') {\n execSync(`docker exec \"${androidCont}\" adb shell echo ok`, { stdio: 'ignore' });\n online = true;\n break;\n }\n } catch {\n // Still offline\n }\n await new Promise((r) => setTimeout(r, 1000));\n }\n\n if (!online) throw new Error('Timeout waiting for device after reboot');\n this.log('Device online', 'success');\n\n this.log('Waiting for browser CDP...', 'info');\n const cdpStart = Date.now();\n let cdpReady = false;\n\n while (Date.now() - cdpStart < 30000) {\n try {\n execSync(\n `docker exec \"${androidCont}\" curl -s --connect-timeout 2 http://localhost:9224/json/version`,\n { stdio: 'ignore' }\n );\n cdpReady = true;\n break;\n } catch {\n if (Date.now() - cdpStart > 15000) {\n try {\n execSync(\n `docker exec \"${androidCont}\" adb shell am start -n com.wootzapp.web/com.aspect.chromium.ChromiumMain -a android.intent.action.VIEW -d 'about:blank'`,\n { stdio: 'ignore' }\n );\n } catch {}\n }\n }\n await new Promise((r) => setTimeout(r, 1000));\n }\n\n if (!cdpReady) throw new Error('Timeout waiting for CDP');\n this.log('Fast reset complete!', 'success');\n }\n\n private waitForLog(container: string, pattern: string, timeoutMs = 120000): Promise<void> {\n return new Promise((resolve, reject) => {\n \n const tail = spawn('docker', ['logs', '-f', container]);\n\n const timer = setTimeout(() => {\n tail.kill();\n reject(new Error(`Timeout waiting for log pattern \"${pattern}\" in container ${container}`));\n }, timeoutMs);\n\n tail.stdout.on('data', (data) => {\n if (data.toString().includes(pattern)) {\n clearTimeout(timer);\n tail.kill();\n resolve();\n }\n });\n\n tail.stderr.on('data', (data) => {\n if (data.toString().includes(pattern)) {\n clearTimeout(timer);\n tail.kill();\n resolve();\n }\n });\n\n tail.on('error', (err) => {\n clearTimeout(timer);\n reject(err);\n });\n });\n }\n}\n"],"mappings":"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","names":["path","pino","import_pino","pino","start","path"]}
package/dist/index.d.cts CHANGED
@@ -23,8 +23,7 @@ declare const AgentOptionsSchema: z.ZodObject<{
23
23
  /**
24
24
  * Options for initializing the WootzAgent.
25
25
  */
26
- interface AgentOptions extends z.input<typeof AgentOptionsSchema> {
27
- }
26
+ type AgentOptions = z.input<typeof AgentOptionsSchema>;
28
27
  /**
29
28
  * Main entry point for interacting with the Agent Browser environment.
30
29
  */
package/dist/index.d.ts CHANGED
@@ -23,8 +23,7 @@ declare const AgentOptionsSchema: z.ZodObject<{
23
23
  /**
24
24
  * Options for initializing the WootzAgent.
25
25
  */
26
- interface AgentOptions extends z.input<typeof AgentOptionsSchema> {
27
- }
26
+ type AgentOptions = z.input<typeof AgentOptionsSchema>;
28
27
  /**
29
28
  * Main entry point for interacting with the Agent Browser environment.
30
29
  */
package/dist/index.js CHANGED
@@ -41,7 +41,7 @@ var Orchestrator = class {
41
41
  env: { ...process.env, ...env }
42
42
  });
43
43
  return true;
44
- } catch (e) {
44
+ } catch {
45
45
  return false;
46
46
  }
47
47
  }
@@ -129,7 +129,7 @@ var Orchestrator = class {
129
129
  { stdio: "ignore" }
130
130
  );
131
131
  await new Promise((r) => setTimeout(r, 3e3));
132
- } catch (e) {
132
+ } catch {
133
133
  this.log(`Network rehydration warning: ${e}`, "warn");
134
134
  }
135
135
  }
@@ -193,7 +193,6 @@ var Orchestrator = class {
193
193
  } catch {
194
194
  }
195
195
  this.log("Waiting for device to come online...", "info");
196
- const start = Date.now();
197
196
  let online = false;
198
197
  while (Date.now() - start < 3e4) {
199
198
  try {
@@ -240,7 +239,6 @@ var Orchestrator = class {
240
239
  }
241
240
  waitForLog(container, pattern, timeoutMs = 12e4) {
242
241
  return new Promise((resolve, reject) => {
243
- const start = Date.now();
244
242
  const tail = spawn("docker", ["logs", "-f", container]);
245
243
  const timer = setTimeout(() => {
246
244
  tail.kill();
@@ -336,12 +334,12 @@ var WootzAgent = class {
336
334
  * @param timeoutMs The maximum amount of time (in ms) to wait for the daemon.
337
335
  */
338
336
  async waitForDaemon(timeoutMs = 18e4) {
339
- const start = Date.now();
340
- while (Date.now() - start < timeoutMs) {
337
+ const start2 = Date.now();
338
+ while (Date.now() - start2 < timeoutMs) {
341
339
  try {
342
340
  await this.sendCommand({ action: "tab_list" });
343
341
  return;
344
- } catch (e) {
342
+ } catch {
345
343
  await new Promise((r) => setTimeout(r, 1e3));
346
344
  }
347
345
  }
@@ -565,7 +563,7 @@ var WootzAgent = class {
565
563
  } else {
566
564
  reject(new Error(response.error || "Unknown error"));
567
565
  }
568
- } catch (e) {
566
+ } catch {
569
567
  reject(new Error(`Invalid response from daemon: ${responseBuffer}`));
570
568
  }
571
569
  });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/orchestrator.ts"],"sourcesContent":["import * as net from 'net';\nimport { randomUUID } from 'crypto';\nimport { Orchestrator } from './orchestrator.js';\nimport { z } from 'zod';\nimport pino from 'pino';\n\nconst DAEMON_PORT = 32001;\n\n// --- Custom Errors ---\nexport class WootzConnectionError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'WootzConnectionError';\n }\n}\n\nexport class WootzTimeoutError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'WootzTimeoutError';\n }\n}\n\nexport class WootzValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'WootzValidationError';\n }\n}\n\n// --- Schema Validation ---\nconst AgentOptionsSchema = z.object({\n dist: z.boolean().optional().default(true),\n logLevel: z.enum(['debug', 'info', 'warn', 'error', 'silent']).optional().default('info'),\n}).passthrough();\n\n/**\n * Options for initializing the WootzAgent.\n */\nexport interface AgentOptions extends z.input<typeof AgentOptionsSchema> {}\n\n/**\n * Main entry point for interacting with the Agent Browser environment.\n */\nexport class WootzAgent {\n private options: AgentOptions;\n private orchestrator: Orchestrator;\n public logger: pino.Logger;\n\n /**\n * Creates a new instance of the WootzAgent.\n * @param options Configuration options.\n * @throws {WootzValidationError} If the provided options do not match the expected schema.\n */\n constructor(options: AgentOptions = {}) {\n const parsedOptions = AgentOptionsSchema.safeParse(options);\n if (!parsedOptions.success) {\n throw new WootzValidationError(`Invalid agent options: ${parsedOptions.error.message}`);\n }\n \n this.options = parsedOptions.data;\n \n this.logger = pino({\n level: this.options.logLevel,\n transport: this.options.logLevel !== 'silent' ? {\n target: 'pino-pretty',\n options: {\n colorize: true,\n translateTime: 'HH:MM:ss Z',\n ignore: 'pid,hostname',\n },\n } : undefined,\n });\n\n this.orchestrator = new Orchestrator(this.options.dist!, this.logger);\n }\n\n // --- Lifecycle Management (Infrastructure) ---\n\n /**\n * Starts the underlying orchestrator and waits for the browser daemon to be ready.\n * @throws {WootzTimeoutError} If the daemon fails to become available within the timeout.\n */\n async start(): Promise<void> {\n await this.orchestrator.start();\n await this.waitForDaemon();\n }\n\n /**\n * Polls the daemon port until it accepts connections.\n * @param timeoutMs The maximum amount of time (in ms) to wait for the daemon.\n */\n private async waitForDaemon(timeoutMs = 180000): Promise<void> {\n const start = Date.now();\n while (Date.now() - start < timeoutMs) {\n try {\n await this.sendCommand({ action: 'tab_list' }); // Health check\n return; // Success\n } catch (e) {\n await new Promise((r) => setTimeout(r, 1000));\n }\n }\n throw new WootzTimeoutError(\n `Timed out waiting for Agent Daemon on port ${DAEMON_PORT} after ${timeoutMs / 1000}s`\n );\n }\n\n /**\n * Stops the orchestrator and cleans up resources.\n */\n async stop(): Promise<void> {\n await this.orchestrator.stop();\n }\n\n /**\n * Resets the environment completely.\n */\n async reset(): Promise<void> {\n await this.orchestrator.reset();\n }\n\n // --- Core Browser Actions (Direct Daemon) ---\n\n /**\n * Navigates the current tab to a specified URL.\n * @param url The URL to navigate to.\n * @param waitUntil The load state to wait for ('load', 'domcontentloaded', 'networkidle').\n */\n async navigate(\n url: string,\n waitUntil: 'load' | 'domcontentloaded' | 'networkidle' = 'load'\n ): Promise<string> {\n return await this.sendCommand({ action: 'navigate', url, waitUntil });\n }\n\n /**\n * Clicks on an element matching the given selector.\n * @param selector The CSS or semantic selector of the element to click.\n */\n async click(selector: string): Promise<string> {\n return await this.sendCommand({ action: 'click', selector });\n }\n\n /**\n * Double-clicks on an element matching the given selector.\n * @param selector The CSS or semantic selector.\n */\n async doubleClick(selector: string): Promise<string> {\n return await this.sendCommand({ action: 'dblclick', selector });\n }\n\n /**\n * Types text into a form field character by character.\n * @param selector The CSS or semantic selector of the input field.\n * @param text The text to type.\n * @param delay Delay between keystrokes in milliseconds.\n */\n async type(selector: string, text: string, delay?: number): Promise<string> {\n return await this.sendCommand({ action: 'type', selector, text, delay });\n }\n\n /**\n * Fills an input field directly with a value (faster than type).\n * @param selector The CSS or semantic selector of the input field.\n * @param value The value to fill.\n */\n async fill(selector: string, value: string): Promise<string> {\n return await this.sendCommand({ action: 'fill', selector, value });\n }\n\n async check(selector: string): Promise<string> {\n return await this.sendCommand({ action: 'check', selector });\n }\n\n async uncheck(selector: string): Promise<string> {\n return await this.sendCommand({ action: 'uncheck', selector });\n }\n\n async hover(selector: string): Promise<string> {\n return await this.sendCommand({ action: 'hover', selector });\n }\n\n async focus(selector: string): Promise<string> {\n return await this.sendCommand({ action: 'focus', selector });\n }\n\n async press(key: string, selector?: string): Promise<string> {\n return await this.sendCommand({ action: 'press', key, selector });\n }\n\n async selectOption(selector: string, value: string | string[]): Promise<string> {\n return await this.sendCommand({ action: 'select', selector, values: value });\n }\n\n // --- Introspection & State ---\n\n /**\n * Captures the full DOM/AXTree snapshot of the current page.\n * @returns A string representation of the interactive accessibility tree.\n */\n async snapshot(): Promise<string> {\n const result = await this.sendCommand({ action: 'snapshot' }, true);\n return result.snapshot || '';\n }\n\n async innerText(selector: string): Promise<string> {\n const res = await this.sendCommand({ action: 'innertext', selector }, true);\n return res.text;\n }\n\n async innerHTML(selector: string): Promise<string> {\n const res = await this.sendCommand({ action: 'innerhtml', selector }, true);\n return res.html;\n }\n\n async getAttribute(selector: string, attribute: string): Promise<string> {\n const res = await this.sendCommand({ action: 'getattribute', selector, attribute }, true);\n return res.value;\n }\n\n async inputValue(selector: string): Promise<string> {\n const res = await this.sendCommand({ action: 'inputvalue', selector }, true);\n return res.value;\n }\n\n async isVisible(selector: string): Promise<boolean> {\n const res = await this.sendCommand({ action: 'isvisible', selector }, true);\n return res.visible;\n }\n\n async isEnabled(selector: string): Promise<boolean> {\n const res = await this.sendCommand({ action: 'isenabled', selector }, true);\n return res.enabled;\n }\n\n async isChecked(selector: string): Promise<boolean> {\n const res = await this.sendCommand({ action: 'ischecked', selector }, true);\n return res.checked;\n }\n\n // --- Waiting & Navigation ---\n\n async waitForSelector(\n selector: string,\n state: 'attached' | 'detached' | 'visible' | 'hidden' = 'visible',\n timeout?: number\n ): Promise<string> {\n return await this.sendCommand({ action: 'wait', selector, state, timeout });\n }\n\n async waitForTimeout(ms: number): Promise<string> {\n return await this.sendCommand({ action: 'wait', timeout: ms });\n }\n\n async waitForLoadState(\n state: 'load' | 'domcontentloaded' | 'networkidle' = 'load'\n ): Promise<string> {\n return await this.sendCommand({ action: 'waitforloadstate', state });\n }\n\n async reload(): Promise<string> {\n return await this.sendCommand({ action: 'reload' });\n }\n\n async goBack(): Promise<string> {\n return await this.sendCommand({ action: 'back' });\n }\n\n async goForward(): Promise<string> {\n return await this.sendCommand({ action: 'forward' });\n }\n\n // --- Semantic Locators ---\n\n async getByRole(role: string, name?: string, _exact: boolean = false): Promise<string> {\n throw new Error(\n 'Locator builders (getByRole) are not fully supported in stateless mode yet. Use standard selectors.'\n );\n }\n\n // --- Utilities ---\n\n /**\n * Captures a screenshot of the current page.\n * @param path Optional file path to save the screenshot.\n */\n async screenshot(path?: string): Promise<string> {\n const res = await this.sendCommand({ action: 'screenshot', path }, true);\n return res.path;\n }\n\n async scroll(x: number, y: number): Promise<string> {\n return await this.sendCommand({ action: 'scroll', x, y });\n }\n\n async evaluate(script: string): Promise<any> {\n const res = await this.sendCommand({ action: 'evaluate', script }, true);\n return res.result;\n }\n\n // --- Tab Management ---\n\n async newTab(url?: string): Promise<string> {\n return await this.sendCommand({ action: 'tab_new', url });\n }\n\n async switchTab(index: number): Promise<string> {\n return await this.sendCommand({ action: 'tab_switch', index });\n }\n\n async closeTab(index?: number): Promise<string> {\n return await this.sendCommand({ action: 'tab_close', index });\n }\n\n async listTabs(): Promise<any[]> {\n const res = await this.sendCommand({ action: 'tab_list' }, true);\n return res.tabs;\n }\n\n // --- Generic Execution ---\n\n async command(action: string, ...args: string[]): Promise<string> {\n const cmd: any = { action };\n\n if (action === 'open' || action === 'navigate') {\n cmd.action = 'navigate';\n cmd.url = args[0];\n } else if (action === 'click') {\n cmd.selector = args[0];\n } else if (action === 'type') {\n cmd.selector = args[0];\n cmd.text = args[1];\n } else if (action === 'press') {\n cmd.key = args[0];\n } else if (action === 'scroll') {\n cmd.x = parseInt(args[0] || '0');\n cmd.y = parseInt(args[1] || '0');\n } else if (action === 'wait') {\n if (/^\\d+$/.test(args[0])) cmd.timeout = parseInt(args[0]);\n else cmd.selector = args[0];\n } else {\n if (args[0]) cmd.selector = args[0];\n if (args[1]) cmd.text = args[1] || args[1]; // value/text\n }\n\n const res = await this.sendCommand(cmd, true);\n\n if (typeof res === 'object') {\n if (res.text) return res.text;\n if (res.url) return res.url;\n if (res.snapshot) return res.snapshot;\n return JSON.stringify(res);\n }\n return String(res);\n }\n\n private sendCommand(command: any, returnData = false): Promise<any> {\n return new Promise((resolve, reject) => {\n if (!command.id) command.id = randomUUID();\n\n const client = new net.Socket();\n\n client.connect(DAEMON_PORT, '127.0.0.1', () => {\n client.write(JSON.stringify(command) + '\\n');\n });\n\n let responseBuffer = '';\n\n client.on('data', (data) => {\n responseBuffer += data.toString();\n if (responseBuffer.includes('\\n')) {\n client.end();\n }\n });\n\n client.on('end', () => {\n try {\n const response = JSON.parse(responseBuffer.trim());\n if (response.success) {\n resolve(returnData ? response.data : 'OK');\n } else {\n reject(new Error(response.error || 'Unknown error'));\n }\n } catch (e) {\n reject(new Error(`Invalid response from daemon: ${responseBuffer}`));\n }\n });\n\n client.on('error', (err) => {\n reject(new WootzConnectionError(`Failed to connect to agent daemon (is it running?): ${err.message}`));\n });\n });\n }\n}\n\nexport default WootzAgent;","import { spawn, spawnSync, execSync } from 'child_process';\nimport path from 'path';\nimport 'fs';\nimport { fileURLToPath } from 'url';\nimport pino from 'pino';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst PROJECT_ROOT = path.resolve(__dirname, '..');\n\nexport class Orchestrator {\n private composeFile: string;\n private logger: pino.Logger;\n\n constructor(distMode: boolean, logger?: pino.Logger) {\n this.composeFile = path.join(\n PROJECT_ROOT,\n distMode ? 'docker-compose.sdk.yml' : 'docker-compose.prod.yml'\n );\n this.logger = logger || pino();\n }\n\n private log(msg: string, level: 'info' | 'success' | 'warn' | 'error' = 'info') {\n switch (level) {\n case 'success':\n this.logger.info({ sdk: true }, msg);\n break;\n case 'warn':\n this.logger.warn({ sdk: true }, msg);\n break;\n case 'error':\n this.logger.error({ sdk: true }, msg);\n break;\n default:\n this.logger.info({ sdk: true }, msg);\n }\n }\n\n private runCommand(cmd: string, env: Record<string, string> = {}): boolean {\n try {\n execSync(cmd, {\n stdio: 'inherit',\n env: { ...process.env, ...env },\n });\n return true;\n } catch (e) {\n return false;\n }\n }\n\n private getContainerId(serviceName: string): string | null {\n try {\n const output = execSync(`docker compose -f \"${this.composeFile}\" ps -q ${serviceName}`, {\n encoding: 'utf-8',\n });\n return output.trim() || null;\n } catch {\n return null;\n }\n }\n\n private isPortMapped(containerId: string, port: number): boolean {\n try {\n const output = execSync(`docker port \"${containerId}\" ${port}`, { encoding: 'utf-8' });\n return output.includes('0.0.0.0:') || output.includes(':::');\n } catch {\n return false;\n }\n }\n\n private async pullImagesWithRetry(): Promise<void> {\n if (!this.composeFile.endsWith('docker-compose.sdk.yml')) return;\n\n this.log('Please wait while we get things ready...', 'info');\n const maxRetries = 10;\n\n for (let count = 0; count < maxRetries; count++) {\n if (this.runCommand(`docker compose -f \"${this.composeFile}\" pull`)) {\n return;\n }\n this.log(\n `Download failed/interrupted. Retrying (${count + 1}/${maxRetries}) in 10s...`,\n 'warn'\n );\n await new Promise((r) => setTimeout(r, 10000));\n }\n\n this.log(\n `Failed to download images after ${maxRetries} attempts. Check internet connection.`,\n 'error'\n );\n process.exit(1);\n }\n\n private async hasSnapshot(): Promise<boolean> {\n try {\n // 1. Check if volume exists\n execSync(`docker volume inspect agent-snapshots`, { stdio: 'ignore' });\n\n // 2. Check if volume contains the 'quickboot' directory\n // We use a tiny helper container to look inside the managed volume\n const output = execSync(`docker run --rm -v agent-snapshots:/data busybox ls /data`, {\n encoding: 'utf-8',\n });\n return output.includes('quickboot');\n } catch {\n return false;\n }\n }\n\n public async start(): Promise<void> {\n this.log(`Initializing Agent Environment...`, 'info');\n\n await this.pullImagesWithRetry();\n\n this.log('Cleaning up previous container state...', 'info');\n this.runCommand(`docker compose -f \"${this.composeFile}\" down -v --remove-orphans`);\n\n const hasSnapshot = await this.hasSnapshot();\n\n if (hasSnapshot) {\n // === WARM START ===\n this.log('Found cached baseline snapshot. Performing HYPER-SPEED WARM BOOT...', 'success');\n\n const success = this.runCommand(`docker compose -f \"${this.composeFile}\" up -d`, {\n EMULATOR_SNAPSHOT_NAME: 'quickboot',\n });\n\n if (!success) throw new Error('Startup failed during docker compose up.');\n\n const agentCont = this.getContainerId('agent-service');\n const androidCont = this.getContainerId('android-service');\n\n // Verify Port Mapping\n if (agentCont && !this.isPortMapped(agentCont, 3000)) {\n this.log('Port 3000 (Host 32001) is not mapped! Container config is stale.', 'warn');\n this.log('Forcing full restart to apply network settings...', 'info');\n this.runCommand(`docker compose -f \"${this.composeFile}\" down -v --remove-orphans`);\n await new Promise((r) => setTimeout(r, 5000));\n this.runCommand(`docker compose -f \"${this.composeFile}\" up -d`, {\n EMULATOR_SNAPSHOT_NAME: 'quickboot',\n });\n }\n\n if (androidCont) {\n this.log('Rehydrating Android network connection...', 'info');\n try {\n execSync(`docker exec \"${androidCont}\" adb shell cmd connectivity airplane-mode enable`, {\n stdio: 'ignore',\n });\n await new Promise((r) => setTimeout(r, 2000));\n execSync(\n `docker exec \"${androidCont}\" adb shell cmd connectivity airplane-mode disable`,\n { stdio: 'ignore' }\n );\n await new Promise((r) => setTimeout(r, 3000));\n } catch (e) {\n this.log(`Network rehydration warning: ${e}`, 'warn');\n }\n }\n\n this.log('Waiting for Daemon Connection...');\n if (agentCont) await this.waitForLog(agentCont, 'Daemon listening on TCP', 180000);\n } else {\n // === COLD START ===\n this.log('No baseline found. Performing FIRST RUN SETUP (Cold Boot)...', 'warn');\n this.log('This will take ~60-90 seconds, but only once.', 'warn');\n\n const success = this.runCommand(`docker compose -f \"${this.composeFile}\" up -d`, {\n EMULATOR_SNAPSHOT_NAME: '',\n });\n\n if (!success) throw new Error('Startup failed during docker compose up.');\n\n let androidCont = this.getContainerId('android-service');\n const agentCont = this.getContainerId('agent-service');\n\n if (!androidCont) throw new Error('Error: Android container not found.');\n\n // Verify Port Mapping\n if (agentCont && !this.isPortMapped(agentCont, 3000)) {\n this.log('Port 3000 (Host 32001) is not mapped! Container config is stale.', 'warn');\n this.log('Forcing full restart to apply network settings...', 'info');\n this.runCommand(`docker compose -f \"${this.composeFile}\" down -v --remove-orphans`);\n await new Promise((r) => setTimeout(r, 5000));\n this.runCommand(`docker compose -f \"${this.composeFile}\" up -d`, {\n EMULATOR_SNAPSHOT_NAME: '',\n });\n androidCont = this.getContainerId('android-service') || androidCont;\n }\n\n this.log('Waiting for Android OS to boot (this takes a moment)...', 'info');\n await this.waitForLog(androidCont, 'Emulator boot complete');\n\n this.log('Waiting for Browser Installation...', 'info');\n await this.waitForLog(androidCont, 'APK installation complete');\n\n this.log('Waiting for CDP Bridge...', 'info');\n await this.waitForLog(androidCont, 'CDP Bridge ready');\n\n this.log('Waiting for Agent Daemon Connection...');\n if (agentCont) await this.waitForLog(agentCont, 'Daemon listening on TCP');\n\n // Save Snapshot\n this.log('Saving emulator state (quickboot)...', 'info');\n const saved = this.runCommand(\n `docker exec \"${androidCont}\" adb emu avd snapshot save quickboot`\n );\n if (saved) {\n this.log('Snapshot saved to host volume.', 'success');\n this.log('Setup Complete! Future runs will launch instantly.', 'success');\n } else {\n throw new Error('Failed to save snapshot inside emulator.');\n }\n }\n }\n\n public async stop(): Promise<void> {\n this.log('Stopping environment...', 'info');\n this.runCommand(`docker compose -f \"${this.composeFile}\" down -v --remove-orphans`);\n this.log('Environment cleaned and stopped.', 'success');\n }\n\n public async reset(): Promise<void> {\n this.log('Performing Fast Browser Reset...', 'info');\n const androidCont = this.getContainerId('android-service');\n if (!androidCont) {\n this.log('Android container not running.', 'error');\n return;\n }\n\n this.log('Initiating fast reset (userspace reboot)...', 'info');\n try {\n execSync(`docker exec \"${androidCont}\" adb shell reboot userspace`, { stdio: 'ignore' });\n } catch {\n // Ignored\n }\n\n this.log('Waiting for device to come online...', 'info');\n const start = Date.now();\n let online = false;\n\n while (Date.now() - start < 30000) {\n try {\n const state = execSync(`docker exec \"${androidCont}\" adb get-state`, {\n encoding: 'utf-8',\n }).trim();\n if (state === 'device') {\n execSync(`docker exec \"${androidCont}\" adb shell echo ok`, { stdio: 'ignore' });\n online = true;\n break;\n }\n } catch {\n // Still offline\n }\n await new Promise((r) => setTimeout(r, 1000));\n }\n\n if (!online) throw new Error('Timeout waiting for device after reboot');\n this.log('Device online', 'success');\n\n this.log('Waiting for browser CDP...', 'info');\n const cdpStart = Date.now();\n let cdpReady = false;\n\n while (Date.now() - cdpStart < 30000) {\n try {\n execSync(\n `docker exec \"${androidCont}\" curl -s --connect-timeout 2 http://localhost:9224/json/version`,\n { stdio: 'ignore' }\n );\n cdpReady = true;\n break;\n } catch {\n if (Date.now() - cdpStart > 15000) {\n try {\n execSync(\n `docker exec \"${androidCont}\" adb shell am start -n com.wootzapp.web/com.aspect.chromium.ChromiumMain -a android.intent.action.VIEW -d 'about:blank'`,\n { stdio: 'ignore' }\n );\n } catch {}\n }\n }\n await new Promise((r) => setTimeout(r, 1000));\n }\n\n if (!cdpReady) throw new Error('Timeout waiting for CDP');\n this.log('Fast reset complete!', 'success');\n }\n\n private waitForLog(container: string, pattern: string, timeoutMs = 120000): Promise<void> {\n return new Promise((resolve, reject) => {\n const start = Date.now();\n const tail = spawn('docker', ['logs', '-f', container]);\n\n const timer = setTimeout(() => {\n tail.kill();\n reject(new Error(`Timeout waiting for log pattern \"${pattern}\" in container ${container}`));\n }, timeoutMs);\n\n tail.stdout.on('data', (data) => {\n if (data.toString().includes(pattern)) {\n clearTimeout(timer);\n tail.kill();\n resolve();\n }\n });\n\n tail.stderr.on('data', (data) => {\n if (data.toString().includes(pattern)) {\n clearTimeout(timer);\n tail.kill();\n resolve();\n }\n });\n\n tail.on('error', (err) => {\n clearTimeout(timer);\n reject(err);\n });\n });\n }\n}\n"],"mappings":";AAAA,YAAY,SAAS;AACrB,SAAS,kBAAkB;;;ACD3B,SAAS,OAAkB,gBAAgB;AAC3C,OAAO,UAAU;AAEjB,SAAS,qBAAqB;AAC9B,OAAO,UAAU;AAEjB,IAAM,YAAY,KAAK,QAAQ,cAAc,YAAY,GAAG,CAAC;AAC7D,IAAM,eAAe,KAAK,QAAQ,WAAW,IAAI;AAE1C,IAAM,eAAN,MAAmB;AAAA,EAChB;AAAA,EACA;AAAA,EAER,YAAY,UAAmB,QAAsB;AACnD,SAAK,cAAc,KAAK;AAAA,MACtB;AAAA,MACA,WAAW,2BAA2B;AAAA,IACxC;AACA,SAAK,SAAS,UAAU,KAAK;AAAA,EAC/B;AAAA,EAEQ,IAAI,KAAa,QAA+C,QAAQ;AAC9E,YAAQ,OAAO;AAAA,MACb,KAAK;AACH,aAAK,OAAO,KAAK,EAAE,KAAK,KAAK,GAAG,GAAG;AACnC;AAAA,MACF,KAAK;AACH,aAAK,OAAO,KAAK,EAAE,KAAK,KAAK,GAAG,GAAG;AACnC;AAAA,MACF,KAAK;AACH,aAAK,OAAO,MAAM,EAAE,KAAK,KAAK,GAAG,GAAG;AACpC;AAAA,MACF;AACE,aAAK,OAAO,KAAK,EAAE,KAAK,KAAK,GAAG,GAAG;AAAA,IACvC;AAAA,EACF;AAAA,EAEQ,WAAW,KAAa,MAA8B,CAAC,GAAY;AACzE,QAAI;AACF,eAAS,KAAK;AAAA,QACZ,OAAO;AAAA,QACP,KAAK,EAAE,GAAG,QAAQ,KAAK,GAAG,IAAI;AAAA,MAChC,CAAC;AACD,aAAO;AAAA,IACT,SAAS,GAAG;AACV,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,eAAe,aAAoC;AACzD,QAAI;AACF,YAAM,SAAS,SAAS,sBAAsB,KAAK,WAAW,WAAW,WAAW,IAAI;AAAA,QACtF,UAAU;AAAA,MACZ,CAAC;AACD,aAAO,OAAO,KAAK,KAAK;AAAA,IAC1B,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,aAAa,aAAqB,MAAuB;AAC/D,QAAI;AACF,YAAM,SAAS,SAAS,gBAAgB,WAAW,KAAK,IAAI,IAAI,EAAE,UAAU,QAAQ,CAAC;AACrF,aAAO,OAAO,SAAS,UAAU,KAAK,OAAO,SAAS,KAAK;AAAA,IAC7D,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAc,sBAAqC;AACjD,QAAI,CAAC,KAAK,YAAY,SAAS,wBAAwB,EAAG;AAE1D,SAAK,IAAI,4CAA4C,MAAM;AAC3D,UAAM,aAAa;AAEnB,aAAS,QAAQ,GAAG,QAAQ,YAAY,SAAS;AAC/C,UAAI,KAAK,WAAW,sBAAsB,KAAK,WAAW,QAAQ,GAAG;AACnE;AAAA,MACF;AACA,WAAK;AAAA,QACH,0CAA0C,QAAQ,CAAC,IAAI,UAAU;AAAA,QACjE;AAAA,MACF;AACA,YAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,GAAK,CAAC;AAAA,IAC/C;AAEA,SAAK;AAAA,MACH,mCAAmC,UAAU;AAAA,MAC7C;AAAA,IACF;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAAA,EAEA,MAAc,cAAgC;AAC5C,QAAI;AAEF,eAAS,yCAAyC,EAAE,OAAO,SAAS,CAAC;AAIrE,YAAM,SAAS,SAAS,6DAA6D;AAAA,QACnF,UAAU;AAAA,MACZ,CAAC;AACD,aAAO,OAAO,SAAS,WAAW;AAAA,IACpC,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAa,QAAuB;AAClC,SAAK,IAAI,qCAAqC,MAAM;AAEpD,UAAM,KAAK,oBAAoB;AAE/B,SAAK,IAAI,2CAA2C,MAAM;AAC1D,SAAK,WAAW,sBAAsB,KAAK,WAAW,4BAA4B;AAElF,UAAM,cAAc,MAAM,KAAK,YAAY;AAE3C,QAAI,aAAa;AAEf,WAAK,IAAI,uEAAuE,SAAS;AAEzF,YAAM,UAAU,KAAK,WAAW,sBAAsB,KAAK,WAAW,WAAW;AAAA,QAC/E,wBAAwB;AAAA,MAC1B,CAAC;AAED,UAAI,CAAC,QAAS,OAAM,IAAI,MAAM,0CAA0C;AAExE,YAAM,YAAY,KAAK,eAAe,eAAe;AACrD,YAAM,cAAc,KAAK,eAAe,iBAAiB;AAGzD,UAAI,aAAa,CAAC,KAAK,aAAa,WAAW,GAAI,GAAG;AACpD,aAAK,IAAI,oEAAoE,MAAM;AACnF,aAAK,IAAI,qDAAqD,MAAM;AACpE,aAAK,WAAW,sBAAsB,KAAK,WAAW,4BAA4B;AAClF,cAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,GAAI,CAAC;AAC5C,aAAK,WAAW,sBAAsB,KAAK,WAAW,WAAW;AAAA,UAC/D,wBAAwB;AAAA,QAC1B,CAAC;AAAA,MACH;AAEA,UAAI,aAAa;AACf,aAAK,IAAI,6CAA6C,MAAM;AAC5D,YAAI;AACF,mBAAS,gBAAgB,WAAW,qDAAqD;AAAA,YACvF,OAAO;AAAA,UACT,CAAC;AACD,gBAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,GAAI,CAAC;AAC5C;AAAA,YACE,gBAAgB,WAAW;AAAA,YAC3B,EAAE,OAAO,SAAS;AAAA,UACpB;AACA,gBAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,GAAI,CAAC;AAAA,QAC9C,SAAS,GAAG;AACV,eAAK,IAAI,gCAAgC,CAAC,IAAI,MAAM;AAAA,QACtD;AAAA,MACF;AAEA,WAAK,IAAI,kCAAkC;AAC3C,UAAI,UAAW,OAAM,KAAK,WAAW,WAAW,2BAA2B,IAAM;AAAA,IACnF,OAAO;AAEL,WAAK,IAAI,gEAAgE,MAAM;AAC/E,WAAK,IAAI,iDAAiD,MAAM;AAEhE,YAAM,UAAU,KAAK,WAAW,sBAAsB,KAAK,WAAW,WAAW;AAAA,QAC/E,wBAAwB;AAAA,MAC1B,CAAC;AAED,UAAI,CAAC,QAAS,OAAM,IAAI,MAAM,0CAA0C;AAExE,UAAI,cAAc,KAAK,eAAe,iBAAiB;AACvD,YAAM,YAAY,KAAK,eAAe,eAAe;AAErD,UAAI,CAAC,YAAa,OAAM,IAAI,MAAM,qCAAqC;AAGvE,UAAI,aAAa,CAAC,KAAK,aAAa,WAAW,GAAI,GAAG;AACpD,aAAK,IAAI,oEAAoE,MAAM;AACnF,aAAK,IAAI,qDAAqD,MAAM;AACpE,aAAK,WAAW,sBAAsB,KAAK,WAAW,4BAA4B;AAClF,cAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,GAAI,CAAC;AAC5C,aAAK,WAAW,sBAAsB,KAAK,WAAW,WAAW;AAAA,UAC/D,wBAAwB;AAAA,QAC1B,CAAC;AACD,sBAAc,KAAK,eAAe,iBAAiB,KAAK;AAAA,MAC1D;AAEA,WAAK,IAAI,2DAA2D,MAAM;AAC1E,YAAM,KAAK,WAAW,aAAa,wBAAwB;AAE3D,WAAK,IAAI,uCAAuC,MAAM;AACtD,YAAM,KAAK,WAAW,aAAa,2BAA2B;AAE9D,WAAK,IAAI,6BAA6B,MAAM;AAC5C,YAAM,KAAK,WAAW,aAAa,kBAAkB;AAErD,WAAK,IAAI,wCAAwC;AACjD,UAAI,UAAW,OAAM,KAAK,WAAW,WAAW,yBAAyB;AAGzE,WAAK,IAAI,wCAAwC,MAAM;AACvD,YAAM,QAAQ,KAAK;AAAA,QACjB,gBAAgB,WAAW;AAAA,MAC7B;AACA,UAAI,OAAO;AACT,aAAK,IAAI,kCAAkC,SAAS;AACpD,aAAK,IAAI,sDAAsD,SAAS;AAAA,MAC1E,OAAO;AACL,cAAM,IAAI,MAAM,0CAA0C;AAAA,MAC5D;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAa,OAAsB;AACjC,SAAK,IAAI,2BAA2B,MAAM;AAC1C,SAAK,WAAW,sBAAsB,KAAK,WAAW,4BAA4B;AAClF,SAAK,IAAI,oCAAoC,SAAS;AAAA,EACxD;AAAA,EAEA,MAAa,QAAuB;AAClC,SAAK,IAAI,oCAAoC,MAAM;AACnD,UAAM,cAAc,KAAK,eAAe,iBAAiB;AACzD,QAAI,CAAC,aAAa;AAChB,WAAK,IAAI,kCAAkC,OAAO;AAClD;AAAA,IACF;AAEA,SAAK,IAAI,+CAA+C,MAAM;AAC9D,QAAI;AACF,eAAS,gBAAgB,WAAW,gCAAgC,EAAE,OAAO,SAAS,CAAC;AAAA,IACzF,QAAQ;AAAA,IAER;AAEA,SAAK,IAAI,wCAAwC,MAAM;AACvD,UAAM,QAAQ,KAAK,IAAI;AACvB,QAAI,SAAS;AAEb,WAAO,KAAK,IAAI,IAAI,QAAQ,KAAO;AACjC,UAAI;AACF,cAAM,QAAQ,SAAS,gBAAgB,WAAW,mBAAmB;AAAA,UACnE,UAAU;AAAA,QACZ,CAAC,EAAE,KAAK;AACR,YAAI,UAAU,UAAU;AACtB,mBAAS,gBAAgB,WAAW,uBAAuB,EAAE,OAAO,SAAS,CAAC;AAC9E,mBAAS;AACT;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAER;AACA,YAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,GAAI,CAAC;AAAA,IAC9C;AAEA,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,yCAAyC;AACtE,SAAK,IAAI,iBAAiB,SAAS;AAEnC,SAAK,IAAI,8BAA8B,MAAM;AAC7C,UAAM,WAAW,KAAK,IAAI;AAC1B,QAAI,WAAW;AAEf,WAAO,KAAK,IAAI,IAAI,WAAW,KAAO;AACpC,UAAI;AACF;AAAA,UACE,gBAAgB,WAAW;AAAA,UAC3B,EAAE,OAAO,SAAS;AAAA,QACpB;AACA,mBAAW;AACX;AAAA,MACF,QAAQ;AACN,YAAI,KAAK,IAAI,IAAI,WAAW,MAAO;AACjC,cAAI;AACF;AAAA,cACE,gBAAgB,WAAW;AAAA,cAC3B,EAAE,OAAO,SAAS;AAAA,YACpB;AAAA,UACF,QAAQ;AAAA,UAAC;AAAA,QACX;AAAA,MACF;AACA,YAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,GAAI,CAAC;AAAA,IAC9C;AAEA,QAAI,CAAC,SAAU,OAAM,IAAI,MAAM,yBAAyB;AACxD,SAAK,IAAI,wBAAwB,SAAS;AAAA,EAC5C;AAAA,EAEQ,WAAW,WAAmB,SAAiB,YAAY,MAAuB;AACxF,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAM,QAAQ,KAAK,IAAI;AACvB,YAAM,OAAO,MAAM,UAAU,CAAC,QAAQ,MAAM,SAAS,CAAC;AAEtD,YAAM,QAAQ,WAAW,MAAM;AAC7B,aAAK,KAAK;AACV,eAAO,IAAI,MAAM,oCAAoC,OAAO,kBAAkB,SAAS,EAAE,CAAC;AAAA,MAC5F,GAAG,SAAS;AAEZ,WAAK,OAAO,GAAG,QAAQ,CAAC,SAAS;AAC/B,YAAI,KAAK,SAAS,EAAE,SAAS,OAAO,GAAG;AACrC,uBAAa,KAAK;AAClB,eAAK,KAAK;AACV,kBAAQ;AAAA,QACV;AAAA,MACF,CAAC;AAED,WAAK,OAAO,GAAG,QAAQ,CAAC,SAAS;AAC/B,YAAI,KAAK,SAAS,EAAE,SAAS,OAAO,GAAG;AACrC,uBAAa,KAAK;AAClB,eAAK,KAAK;AACV,kBAAQ;AAAA,QACV;AAAA,MACF,CAAC;AAED,WAAK,GAAG,SAAS,CAAC,QAAQ;AACxB,qBAAa,KAAK;AAClB,eAAO,GAAG;AAAA,MACZ,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACF;;;AD9TA,SAAS,SAAS;AAClB,OAAOA,WAAU;AAEjB,IAAM,cAAc;AAGb,IAAM,uBAAN,cAAmC,MAAM;AAAA,EAC9C,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,oBAAN,cAAgC,MAAM;AAAA,EAC3C,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,uBAAN,cAAmC,MAAM;AAAA,EAC9C,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAGA,IAAM,qBAAqB,EAAE,OAAO;AAAA,EAClC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,IAAI;AAAA,EACzC,UAAU,EAAE,KAAK,CAAC,SAAS,QAAQ,QAAQ,SAAS,QAAQ,CAAC,EAAE,SAAS,EAAE,QAAQ,MAAM;AAC1F,CAAC,EAAE,YAAY;AAUR,IAAM,aAAN,MAAiB;AAAA,EACd;AAAA,EACA;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOP,YAAY,UAAwB,CAAC,GAAG;AACtC,UAAM,gBAAgB,mBAAmB,UAAU,OAAO;AAC1D,QAAI,CAAC,cAAc,SAAS;AAC1B,YAAM,IAAI,qBAAqB,0BAA0B,cAAc,MAAM,OAAO,EAAE;AAAA,IACxF;AAEA,SAAK,UAAU,cAAc;AAE7B,SAAK,SAASA,MAAK;AAAA,MACjB,OAAO,KAAK,QAAQ;AAAA,MACpB,WAAW,KAAK,QAAQ,aAAa,WAAW;AAAA,QAC9C,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,UAAU;AAAA,UACV,eAAe;AAAA,UACf,QAAQ;AAAA,QACV;AAAA,MACF,IAAI;AAAA,IACN,CAAC;AAED,SAAK,eAAe,IAAI,aAAa,KAAK,QAAQ,MAAO,KAAK,MAAM;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,QAAuB;AAC3B,UAAM,KAAK,aAAa,MAAM;AAC9B,UAAM,KAAK,cAAc;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,cAAc,YAAY,MAAuB;AAC7D,UAAM,QAAQ,KAAK,IAAI;AACvB,WAAO,KAAK,IAAI,IAAI,QAAQ,WAAW;AACrC,UAAI;AACF,cAAM,KAAK,YAAY,EAAE,QAAQ,WAAW,CAAC;AAC7C;AAAA,MACF,SAAS,GAAG;AACV,cAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,GAAI,CAAC;AAAA,MAC9C;AAAA,IACF;AACA,UAAM,IAAI;AAAA,MACR,8CAA8C,WAAW,UAAU,YAAY,GAAI;AAAA,IACrF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAsB;AAC1B,UAAM,KAAK,aAAa,KAAK;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAuB;AAC3B,UAAM,KAAK,aAAa,MAAM;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,SACJ,KACA,YAAyD,QACxC;AACjB,WAAO,MAAM,KAAK,YAAY,EAAE,QAAQ,YAAY,KAAK,UAAU,CAAC;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,MAAM,UAAmC;AAC7C,WAAO,MAAM,KAAK,YAAY,EAAE,QAAQ,SAAS,SAAS,CAAC;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,YAAY,UAAmC;AACnD,WAAO,MAAM,KAAK,YAAY,EAAE,QAAQ,YAAY,SAAS,CAAC;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,KAAK,UAAkB,MAAc,OAAiC;AAC1E,WAAO,MAAM,KAAK,YAAY,EAAE,QAAQ,QAAQ,UAAU,MAAM,MAAM,CAAC;AAAA,EACzE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,KAAK,UAAkB,OAAgC;AAC3D,WAAO,MAAM,KAAK,YAAY,EAAE,QAAQ,QAAQ,UAAU,MAAM,CAAC;AAAA,EACnE;AAAA,EAEA,MAAM,MAAM,UAAmC;AAC7C,WAAO,MAAM,KAAK,YAAY,EAAE,QAAQ,SAAS,SAAS,CAAC;AAAA,EAC7D;AAAA,EAEA,MAAM,QAAQ,UAAmC;AAC/C,WAAO,MAAM,KAAK,YAAY,EAAE,QAAQ,WAAW,SAAS,CAAC;AAAA,EAC/D;AAAA,EAEA,MAAM,MAAM,UAAmC;AAC7C,WAAO,MAAM,KAAK,YAAY,EAAE,QAAQ,SAAS,SAAS,CAAC;AAAA,EAC7D;AAAA,EAEA,MAAM,MAAM,UAAmC;AAC7C,WAAO,MAAM,KAAK,YAAY,EAAE,QAAQ,SAAS,SAAS,CAAC;AAAA,EAC7D;AAAA,EAEA,MAAM,MAAM,KAAa,UAAoC;AAC3D,WAAO,MAAM,KAAK,YAAY,EAAE,QAAQ,SAAS,KAAK,SAAS,CAAC;AAAA,EAClE;AAAA,EAEA,MAAM,aAAa,UAAkB,OAA2C;AAC9E,WAAO,MAAM,KAAK,YAAY,EAAE,QAAQ,UAAU,UAAU,QAAQ,MAAM,CAAC;AAAA,EAC7E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,WAA4B;AAChC,UAAM,SAAS,MAAM,KAAK,YAAY,EAAE,QAAQ,WAAW,GAAG,IAAI;AAClE,WAAO,OAAO,YAAY;AAAA,EAC5B;AAAA,EAEA,MAAM,UAAU,UAAmC;AACjD,UAAM,MAAM,MAAM,KAAK,YAAY,EAAE,QAAQ,aAAa,SAAS,GAAG,IAAI;AAC1E,WAAO,IAAI;AAAA,EACb;AAAA,EAEA,MAAM,UAAU,UAAmC;AACjD,UAAM,MAAM,MAAM,KAAK,YAAY,EAAE,QAAQ,aAAa,SAAS,GAAG,IAAI;AAC1E,WAAO,IAAI;AAAA,EACb;AAAA,EAEA,MAAM,aAAa,UAAkB,WAAoC;AACvE,UAAM,MAAM,MAAM,KAAK,YAAY,EAAE,QAAQ,gBAAgB,UAAU,UAAU,GAAG,IAAI;AACxF,WAAO,IAAI;AAAA,EACb;AAAA,EAEA,MAAM,WAAW,UAAmC;AAClD,UAAM,MAAM,MAAM,KAAK,YAAY,EAAE,QAAQ,cAAc,SAAS,GAAG,IAAI;AAC3E,WAAO,IAAI;AAAA,EACb;AAAA,EAEA,MAAM,UAAU,UAAoC;AAClD,UAAM,MAAM,MAAM,KAAK,YAAY,EAAE,QAAQ,aAAa,SAAS,GAAG,IAAI;AAC1E,WAAO,IAAI;AAAA,EACb;AAAA,EAEA,MAAM,UAAU,UAAoC;AAClD,UAAM,MAAM,MAAM,KAAK,YAAY,EAAE,QAAQ,aAAa,SAAS,GAAG,IAAI;AAC1E,WAAO,IAAI;AAAA,EACb;AAAA,EAEA,MAAM,UAAU,UAAoC;AAClD,UAAM,MAAM,MAAM,KAAK,YAAY,EAAE,QAAQ,aAAa,SAAS,GAAG,IAAI;AAC1E,WAAO,IAAI;AAAA,EACb;AAAA;AAAA,EAIA,MAAM,gBACJ,UACA,QAAwD,WACxD,SACiB;AACjB,WAAO,MAAM,KAAK,YAAY,EAAE,QAAQ,QAAQ,UAAU,OAAO,QAAQ,CAAC;AAAA,EAC5E;AAAA,EAEA,MAAM,eAAe,IAA6B;AAChD,WAAO,MAAM,KAAK,YAAY,EAAE,QAAQ,QAAQ,SAAS,GAAG,CAAC;AAAA,EAC/D;AAAA,EAEA,MAAM,iBACJ,QAAqD,QACpC;AACjB,WAAO,MAAM,KAAK,YAAY,EAAE,QAAQ,oBAAoB,MAAM,CAAC;AAAA,EACrE;AAAA,EAEA,MAAM,SAA0B;AAC9B,WAAO,MAAM,KAAK,YAAY,EAAE,QAAQ,SAAS,CAAC;AAAA,EACpD;AAAA,EAEA,MAAM,SAA0B;AAC9B,WAAO,MAAM,KAAK,YAAY,EAAE,QAAQ,OAAO,CAAC;AAAA,EAClD;AAAA,EAEA,MAAM,YAA6B;AACjC,WAAO,MAAM,KAAK,YAAY,EAAE,QAAQ,UAAU,CAAC;AAAA,EACrD;AAAA;AAAA,EAIA,MAAM,UAAU,MAAc,MAAe,SAAkB,OAAwB;AACrF,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,WAAWC,OAAgC;AAC/C,UAAM,MAAM,MAAM,KAAK,YAAY,EAAE,QAAQ,cAAc,MAAAA,MAAK,GAAG,IAAI;AACvE,WAAO,IAAI;AAAA,EACb;AAAA,EAEA,MAAM,OAAO,GAAW,GAA4B;AAClD,WAAO,MAAM,KAAK,YAAY,EAAE,QAAQ,UAAU,GAAG,EAAE,CAAC;AAAA,EAC1D;AAAA,EAEA,MAAM,SAAS,QAA8B;AAC3C,UAAM,MAAM,MAAM,KAAK,YAAY,EAAE,QAAQ,YAAY,OAAO,GAAG,IAAI;AACvE,WAAO,IAAI;AAAA,EACb;AAAA;AAAA,EAIA,MAAM,OAAO,KAA+B;AAC1C,WAAO,MAAM,KAAK,YAAY,EAAE,QAAQ,WAAW,IAAI,CAAC;AAAA,EAC1D;AAAA,EAEA,MAAM,UAAU,OAAgC;AAC9C,WAAO,MAAM,KAAK,YAAY,EAAE,QAAQ,cAAc,MAAM,CAAC;AAAA,EAC/D;AAAA,EAEA,MAAM,SAAS,OAAiC;AAC9C,WAAO,MAAM,KAAK,YAAY,EAAE,QAAQ,aAAa,MAAM,CAAC;AAAA,EAC9D;AAAA,EAEA,MAAM,WAA2B;AAC/B,UAAM,MAAM,MAAM,KAAK,YAAY,EAAE,QAAQ,WAAW,GAAG,IAAI;AAC/D,WAAO,IAAI;AAAA,EACb;AAAA;AAAA,EAIA,MAAM,QAAQ,WAAmB,MAAiC;AAChE,UAAM,MAAW,EAAE,OAAO;AAE1B,QAAI,WAAW,UAAU,WAAW,YAAY;AAC9C,UAAI,SAAS;AACb,UAAI,MAAM,KAAK,CAAC;AAAA,IAClB,WAAW,WAAW,SAAS;AAC7B,UAAI,WAAW,KAAK,CAAC;AAAA,IACvB,WAAW,WAAW,QAAQ;AAC5B,UAAI,WAAW,KAAK,CAAC;AACrB,UAAI,OAAO,KAAK,CAAC;AAAA,IACnB,WAAW,WAAW,SAAS;AAC7B,UAAI,MAAM,KAAK,CAAC;AAAA,IAClB,WAAW,WAAW,UAAU;AAC9B,UAAI,IAAI,SAAS,KAAK,CAAC,KAAK,GAAG;AAC/B,UAAI,IAAI,SAAS,KAAK,CAAC,KAAK,GAAG;AAAA,IACjC,WAAW,WAAW,QAAQ;AAC5B,UAAI,QAAQ,KAAK,KAAK,CAAC,CAAC,EAAG,KAAI,UAAU,SAAS,KAAK,CAAC,CAAC;AAAA,UACpD,KAAI,WAAW,KAAK,CAAC;AAAA,IAC5B,OAAO;AACL,UAAI,KAAK,CAAC,EAAG,KAAI,WAAW,KAAK,CAAC;AAClC,UAAI,KAAK,CAAC,EAAG,KAAI,OAAO,KAAK,CAAC,KAAK,KAAK,CAAC;AAAA,IAC3C;AAEA,UAAM,MAAM,MAAM,KAAK,YAAY,KAAK,IAAI;AAE5C,QAAI,OAAO,QAAQ,UAAU;AAC3B,UAAI,IAAI,KAAM,QAAO,IAAI;AACzB,UAAI,IAAI,IAAK,QAAO,IAAI;AACxB,UAAI,IAAI,SAAU,QAAO,IAAI;AAC7B,aAAO,KAAK,UAAU,GAAG;AAAA,IAC3B;AACA,WAAO,OAAO,GAAG;AAAA,EACnB;AAAA,EAEQ,YAAY,SAAc,aAAa,OAAqB;AAClE,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAI,CAAC,QAAQ,GAAI,SAAQ,KAAK,WAAW;AAEzC,YAAM,SAAS,IAAQ,WAAO;AAE9B,aAAO,QAAQ,aAAa,aAAa,MAAM;AAC7C,eAAO,MAAM,KAAK,UAAU,OAAO,IAAI,IAAI;AAAA,MAC7C,CAAC;AAED,UAAI,iBAAiB;AAErB,aAAO,GAAG,QAAQ,CAAC,SAAS;AAC1B,0BAAkB,KAAK,SAAS;AAChC,YAAI,eAAe,SAAS,IAAI,GAAG;AACjC,iBAAO,IAAI;AAAA,QACb;AAAA,MACF,CAAC;AAED,aAAO,GAAG,OAAO,MAAM;AACrB,YAAI;AACF,gBAAM,WAAW,KAAK,MAAM,eAAe,KAAK,CAAC;AACjD,cAAI,SAAS,SAAS;AACpB,oBAAQ,aAAa,SAAS,OAAO,IAAI;AAAA,UAC3C,OAAO;AACL,mBAAO,IAAI,MAAM,SAAS,SAAS,eAAe,CAAC;AAAA,UACrD;AAAA,QACF,SAAS,GAAG;AACV,iBAAO,IAAI,MAAM,iCAAiC,cAAc,EAAE,CAAC;AAAA,QACrE;AAAA,MACF,CAAC;AAED,aAAO,GAAG,SAAS,CAAC,QAAQ;AAC1B,eAAO,IAAI,qBAAqB,uDAAuD,IAAI,OAAO,EAAE,CAAC;AAAA,MACvG,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACF;AAEA,IAAO,gBAAQ;","names":["pino","path"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/orchestrator.ts"],"sourcesContent":["import * as net from 'net';\nimport { randomUUID } from 'crypto';\nimport { Orchestrator } from './orchestrator.js';\nimport { z } from 'zod';\nimport pino from 'pino';\n\nconst DAEMON_PORT = 32001;\n\n// --- Custom Errors ---\nexport class WootzConnectionError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'WootzConnectionError';\n }\n}\n\nexport class WootzTimeoutError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'WootzTimeoutError';\n }\n}\n\nexport class WootzValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'WootzValidationError';\n }\n}\n\n// --- Schema Validation ---\nconst AgentOptionsSchema = z.object({\n dist: z.boolean().optional().default(true),\n logLevel: z.enum(['debug', 'info', 'warn', 'error', 'silent']).optional().default('info'),\n}).passthrough();\n\n/**\n * Options for initializing the WootzAgent.\n */\nexport type AgentOptions = z.input<typeof AgentOptionsSchema>;\n\n/**\n * Main entry point for interacting with the Agent Browser environment.\n */\nexport class WootzAgent {\n private options: AgentOptions;\n private orchestrator: Orchestrator;\n public logger: pino.Logger;\n\n /**\n * Creates a new instance of the WootzAgent.\n * @param options Configuration options.\n * @throws {WootzValidationError} If the provided options do not match the expected schema.\n */\n constructor(options: AgentOptions = {}) {\n const parsedOptions = AgentOptionsSchema.safeParse(options);\n if (!parsedOptions.success) {\n throw new WootzValidationError(`Invalid agent options: ${parsedOptions.error.message}`);\n }\n \n this.options = parsedOptions.data;\n \n this.logger = pino({\n level: this.options.logLevel,\n transport: this.options.logLevel !== 'silent' ? {\n target: 'pino-pretty',\n options: {\n colorize: true,\n translateTime: 'HH:MM:ss Z',\n ignore: 'pid,hostname',\n },\n } : undefined,\n });\n\n this.orchestrator = new Orchestrator(this.options.dist!, this.logger);\n }\n\n // --- Lifecycle Management (Infrastructure) ---\n\n /**\n * Starts the underlying orchestrator and waits for the browser daemon to be ready.\n * @throws {WootzTimeoutError} If the daemon fails to become available within the timeout.\n */\n async start(): Promise<void> {\n await this.orchestrator.start();\n await this.waitForDaemon();\n }\n\n /**\n * Polls the daemon port until it accepts connections.\n * @param timeoutMs The maximum amount of time (in ms) to wait for the daemon.\n */\n private async waitForDaemon(timeoutMs = 180000): Promise<void> {\n const start = Date.now();\n while (Date.now() - start < timeoutMs) {\n try {\n await this.sendCommand({ action: 'tab_list' }); // Health check\n return; // Success\n } catch {\n await new Promise((r) => setTimeout(r, 1000));\n }\n }\n throw new WootzTimeoutError(\n `Timed out waiting for Agent Daemon on port ${DAEMON_PORT} after ${timeoutMs / 1000}s`\n );\n }\n\n /**\n * Stops the orchestrator and cleans up resources.\n */\n async stop(): Promise<void> {\n await this.orchestrator.stop();\n }\n\n /**\n * Resets the environment completely.\n */\n async reset(): Promise<void> {\n await this.orchestrator.reset();\n }\n\n // --- Core Browser Actions (Direct Daemon) ---\n\n /**\n * Navigates the current tab to a specified URL.\n * @param url The URL to navigate to.\n * @param waitUntil The load state to wait for ('load', 'domcontentloaded', 'networkidle').\n */\n async navigate(\n url: string,\n waitUntil: 'load' | 'domcontentloaded' | 'networkidle' = 'load'\n ): Promise<string> {\n return await this.sendCommand({ action: 'navigate', url, waitUntil });\n }\n\n /**\n * Clicks on an element matching the given selector.\n * @param selector The CSS or semantic selector of the element to click.\n */\n async click(selector: string): Promise<string> {\n return await this.sendCommand({ action: 'click', selector });\n }\n\n /**\n * Double-clicks on an element matching the given selector.\n * @param selector The CSS or semantic selector.\n */\n async doubleClick(selector: string): Promise<string> {\n return await this.sendCommand({ action: 'dblclick', selector });\n }\n\n /**\n * Types text into a form field character by character.\n * @param selector The CSS or semantic selector of the input field.\n * @param text The text to type.\n * @param delay Delay between keystrokes in milliseconds.\n */\n async type(selector: string, text: string, delay?: number): Promise<string> {\n return await this.sendCommand({ action: 'type', selector, text, delay });\n }\n\n /**\n * Fills an input field directly with a value (faster than type).\n * @param selector The CSS or semantic selector of the input field.\n * @param value The value to fill.\n */\n async fill(selector: string, value: string): Promise<string> {\n return await this.sendCommand({ action: 'fill', selector, value });\n }\n\n async check(selector: string): Promise<string> {\n return await this.sendCommand({ action: 'check', selector });\n }\n\n async uncheck(selector: string): Promise<string> {\n return await this.sendCommand({ action: 'uncheck', selector });\n }\n\n async hover(selector: string): Promise<string> {\n return await this.sendCommand({ action: 'hover', selector });\n }\n\n async focus(selector: string): Promise<string> {\n return await this.sendCommand({ action: 'focus', selector });\n }\n\n async press(key: string, selector?: string): Promise<string> {\n return await this.sendCommand({ action: 'press', key, selector });\n }\n\n async selectOption(selector: string, value: string | string[]): Promise<string> {\n return await this.sendCommand({ action: 'select', selector, values: value });\n }\n\n // --- Introspection & State ---\n\n /**\n * Captures the full DOM/AXTree snapshot of the current page.\n * @returns A string representation of the interactive accessibility tree.\n */\n async snapshot(): Promise<string> {\n const result = await this.sendCommand({ action: 'snapshot' }, true);\n return result.snapshot || '';\n }\n\n async innerText(selector: string): Promise<string> {\n const res = await this.sendCommand({ action: 'innertext', selector }, true);\n return res.text;\n }\n\n async innerHTML(selector: string): Promise<string> {\n const res = await this.sendCommand({ action: 'innerhtml', selector }, true);\n return res.html;\n }\n\n async getAttribute(selector: string, attribute: string): Promise<string> {\n const res = await this.sendCommand({ action: 'getattribute', selector, attribute }, true);\n return res.value;\n }\n\n async inputValue(selector: string): Promise<string> {\n const res = await this.sendCommand({ action: 'inputvalue', selector }, true);\n return res.value;\n }\n\n async isVisible(selector: string): Promise<boolean> {\n const res = await this.sendCommand({ action: 'isvisible', selector }, true);\n return res.visible;\n }\n\n async isEnabled(selector: string): Promise<boolean> {\n const res = await this.sendCommand({ action: 'isenabled', selector }, true);\n return res.enabled;\n }\n\n async isChecked(selector: string): Promise<boolean> {\n const res = await this.sendCommand({ action: 'ischecked', selector }, true);\n return res.checked;\n }\n\n // --- Waiting & Navigation ---\n\n async waitForSelector(\n selector: string,\n state: 'attached' | 'detached' | 'visible' | 'hidden' = 'visible',\n timeout?: number\n ): Promise<string> {\n return await this.sendCommand({ action: 'wait', selector, state, timeout });\n }\n\n async waitForTimeout(ms: number): Promise<string> {\n return await this.sendCommand({ action: 'wait', timeout: ms });\n }\n\n async waitForLoadState(\n state: 'load' | 'domcontentloaded' | 'networkidle' = 'load'\n ): Promise<string> {\n return await this.sendCommand({ action: 'waitforloadstate', state });\n }\n\n async reload(): Promise<string> {\n return await this.sendCommand({ action: 'reload' });\n }\n\n async goBack(): Promise<string> {\n return await this.sendCommand({ action: 'back' });\n }\n\n async goForward(): Promise<string> {\n return await this.sendCommand({ action: 'forward' });\n }\n\n // --- Semantic Locators ---\n\n async getByRole(role: string, name?: string, _exact: boolean = false): Promise<string> {\n throw new Error(\n 'Locator builders (getByRole) are not fully supported in stateless mode yet. Use standard selectors.'\n );\n }\n\n // --- Utilities ---\n\n /**\n * Captures a screenshot of the current page.\n * @param path Optional file path to save the screenshot.\n */\n async screenshot(path?: string): Promise<string> {\n const res = await this.sendCommand({ action: 'screenshot', path }, true);\n return res.path;\n }\n\n async scroll(x: number, y: number): Promise<string> {\n return await this.sendCommand({ action: 'scroll', x, y });\n }\n\n async evaluate(script: string): Promise<any> {\n const res = await this.sendCommand({ action: 'evaluate', script }, true);\n return res.result;\n }\n\n // --- Tab Management ---\n\n async newTab(url?: string): Promise<string> {\n return await this.sendCommand({ action: 'tab_new', url });\n }\n\n async switchTab(index: number): Promise<string> {\n return await this.sendCommand({ action: 'tab_switch', index });\n }\n\n async closeTab(index?: number): Promise<string> {\n return await this.sendCommand({ action: 'tab_close', index });\n }\n\n async listTabs(): Promise<any[]> {\n const res = await this.sendCommand({ action: 'tab_list' }, true);\n return res.tabs;\n }\n\n // --- Generic Execution ---\n\n async command(action: string, ...args: string[]): Promise<string> {\n const cmd: any = { action };\n\n if (action === 'open' || action === 'navigate') {\n cmd.action = 'navigate';\n cmd.url = args[0];\n } else if (action === 'click') {\n cmd.selector = args[0];\n } else if (action === 'type') {\n cmd.selector = args[0];\n cmd.text = args[1];\n } else if (action === 'press') {\n cmd.key = args[0];\n } else if (action === 'scroll') {\n cmd.x = parseInt(args[0] || '0');\n cmd.y = parseInt(args[1] || '0');\n } else if (action === 'wait') {\n if (/^\\d+$/.test(args[0])) cmd.timeout = parseInt(args[0]);\n else cmd.selector = args[0];\n } else {\n if (args[0]) cmd.selector = args[0];\n if (args[1]) cmd.text = args[1] || args[1]; // value/text\n }\n\n const res = await this.sendCommand(cmd, true);\n\n if (typeof res === 'object') {\n if (res.text) return res.text;\n if (res.url) return res.url;\n if (res.snapshot) return res.snapshot;\n return JSON.stringify(res);\n }\n return String(res);\n }\n\n private sendCommand(command: any, returnData = false): Promise<any> {\n return new Promise((resolve, reject) => {\n if (!command.id) command.id = randomUUID();\n\n const client = new net.Socket();\n\n client.connect(DAEMON_PORT, '127.0.0.1', () => {\n client.write(JSON.stringify(command) + '\\n');\n });\n\n let responseBuffer = '';\n\n client.on('data', (data) => {\n responseBuffer += data.toString();\n if (responseBuffer.includes('\\n')) {\n client.end();\n }\n });\n\n client.on('end', () => {\n try {\n const response = JSON.parse(responseBuffer.trim());\n if (response.success) {\n resolve(returnData ? response.data : 'OK');\n } else {\n reject(new Error(response.error || 'Unknown error'));\n }\n } catch {\n reject(new Error(`Invalid response from daemon: ${responseBuffer}`));\n }\n });\n\n client.on('error', (err) => {\n reject(new WootzConnectionError(`Failed to connect to agent daemon (is it running?): ${err.message}`));\n });\n });\n }\n}\n\nexport default WootzAgent;","import { spawn, execSync } from 'child_process';\nimport path from 'path';\nimport 'fs';\nimport { fileURLToPath } from 'url';\nimport pino from 'pino';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst PROJECT_ROOT = path.resolve(__dirname, '..');\n\nexport class Orchestrator {\n private composeFile: string;\n private logger: pino.Logger;\n\n constructor(distMode: boolean, logger?: pino.Logger) {\n this.composeFile = path.join(\n PROJECT_ROOT,\n distMode ? 'docker-compose.sdk.yml' : 'docker-compose.prod.yml'\n );\n this.logger = logger || pino();\n }\n\n private log(msg: string, level: 'info' | 'success' | 'warn' | 'error' = 'info') {\n switch (level) {\n case 'success':\n this.logger.info({ sdk: true }, msg);\n break;\n case 'warn':\n this.logger.warn({ sdk: true }, msg);\n break;\n case 'error':\n this.logger.error({ sdk: true }, msg);\n break;\n default:\n this.logger.info({ sdk: true }, msg);\n }\n }\n\n private runCommand(cmd: string, env: Record<string, string> = {}): boolean {\n try {\n execSync(cmd, {\n stdio: 'inherit',\n env: { ...process.env, ...env },\n });\n return true;\n } catch {\n return false;\n }\n }\n\n private getContainerId(serviceName: string): string | null {\n try {\n const output = execSync(`docker compose -f \"${this.composeFile}\" ps -q ${serviceName}`, {\n encoding: 'utf-8',\n });\n return output.trim() || null;\n } catch {\n return null;\n }\n }\n\n private isPortMapped(containerId: string, port: number): boolean {\n try {\n const output = execSync(`docker port \"${containerId}\" ${port}`, { encoding: 'utf-8' });\n return output.includes('0.0.0.0:') || output.includes(':::');\n } catch {\n return false;\n }\n }\n\n private async pullImagesWithRetry(): Promise<void> {\n if (!this.composeFile.endsWith('docker-compose.sdk.yml')) return;\n\n this.log('Please wait while we get things ready...', 'info');\n const maxRetries = 10;\n\n for (let count = 0; count < maxRetries; count++) {\n if (this.runCommand(`docker compose -f \"${this.composeFile}\" pull`)) {\n return;\n }\n this.log(\n `Download failed/interrupted. Retrying (${count + 1}/${maxRetries}) in 10s...`,\n 'warn'\n );\n await new Promise((r) => setTimeout(r, 10000));\n }\n\n this.log(\n `Failed to download images after ${maxRetries} attempts. Check internet connection.`,\n 'error'\n );\n process.exit(1);\n }\n\n private async hasSnapshot(): Promise<boolean> {\n try {\n // 1. Check if volume exists\n execSync(`docker volume inspect agent-snapshots`, { stdio: 'ignore' });\n\n // 2. Check if volume contains the 'quickboot' directory\n // We use a tiny helper container to look inside the managed volume\n const output = execSync(`docker run --rm -v agent-snapshots:/data busybox ls /data`, {\n encoding: 'utf-8',\n });\n return output.includes('quickboot');\n } catch {\n return false;\n }\n }\n\n public async start(): Promise<void> {\n this.log(`Initializing Agent Environment...`, 'info');\n\n await this.pullImagesWithRetry();\n\n this.log('Cleaning up previous container state...', 'info');\n this.runCommand(`docker compose -f \"${this.composeFile}\" down -v --remove-orphans`);\n\n const hasSnapshot = await this.hasSnapshot();\n\n if (hasSnapshot) {\n // === WARM START ===\n this.log('Found cached baseline snapshot. Performing HYPER-SPEED WARM BOOT...', 'success');\n\n const success = this.runCommand(`docker compose -f \"${this.composeFile}\" up -d`, {\n EMULATOR_SNAPSHOT_NAME: 'quickboot',\n });\n\n if (!success) throw new Error('Startup failed during docker compose up.');\n\n const agentCont = this.getContainerId('agent-service');\n const androidCont = this.getContainerId('android-service');\n\n // Verify Port Mapping\n if (agentCont && !this.isPortMapped(agentCont, 3000)) {\n this.log('Port 3000 (Host 32001) is not mapped! Container config is stale.', 'warn');\n this.log('Forcing full restart to apply network settings...', 'info');\n this.runCommand(`docker compose -f \"${this.composeFile}\" down -v --remove-orphans`);\n await new Promise((r) => setTimeout(r, 5000));\n this.runCommand(`docker compose -f \"${this.composeFile}\" up -d`, {\n EMULATOR_SNAPSHOT_NAME: 'quickboot',\n });\n }\n\n if (androidCont) {\n this.log('Rehydrating Android network connection...', 'info');\n try {\n execSync(`docker exec \"${androidCont}\" adb shell cmd connectivity airplane-mode enable`, {\n stdio: 'ignore',\n });\n await new Promise((r) => setTimeout(r, 2000));\n execSync(\n `docker exec \"${androidCont}\" adb shell cmd connectivity airplane-mode disable`,\n { stdio: 'ignore' }\n );\n await new Promise((r) => setTimeout(r, 3000));\n } catch {\n this.log(`Network rehydration warning: ${e}`, 'warn');\n }\n }\n\n this.log('Waiting for Daemon Connection...');\n if (agentCont) await this.waitForLog(agentCont, 'Daemon listening on TCP', 180000);\n } else {\n // === COLD START ===\n this.log('No baseline found. Performing FIRST RUN SETUP (Cold Boot)...', 'warn');\n this.log('This will take ~60-90 seconds, but only once.', 'warn');\n\n const success = this.runCommand(`docker compose -f \"${this.composeFile}\" up -d`, {\n EMULATOR_SNAPSHOT_NAME: '',\n });\n\n if (!success) throw new Error('Startup failed during docker compose up.');\n\n let androidCont = this.getContainerId('android-service');\n const agentCont = this.getContainerId('agent-service');\n\n if (!androidCont) throw new Error('Error: Android container not found.');\n\n // Verify Port Mapping\n if (agentCont && !this.isPortMapped(agentCont, 3000)) {\n this.log('Port 3000 (Host 32001) is not mapped! Container config is stale.', 'warn');\n this.log('Forcing full restart to apply network settings...', 'info');\n this.runCommand(`docker compose -f \"${this.composeFile}\" down -v --remove-orphans`);\n await new Promise((r) => setTimeout(r, 5000));\n this.runCommand(`docker compose -f \"${this.composeFile}\" up -d`, {\n EMULATOR_SNAPSHOT_NAME: '',\n });\n androidCont = this.getContainerId('android-service') || androidCont;\n }\n\n this.log('Waiting for Android OS to boot (this takes a moment)...', 'info');\n await this.waitForLog(androidCont, 'Emulator boot complete');\n\n this.log('Waiting for Browser Installation...', 'info');\n await this.waitForLog(androidCont, 'APK installation complete');\n\n this.log('Waiting for CDP Bridge...', 'info');\n await this.waitForLog(androidCont, 'CDP Bridge ready');\n\n this.log('Waiting for Agent Daemon Connection...');\n if (agentCont) await this.waitForLog(agentCont, 'Daemon listening on TCP');\n\n // Save Snapshot\n this.log('Saving emulator state (quickboot)...', 'info');\n const saved = this.runCommand(\n `docker exec \"${androidCont}\" adb emu avd snapshot save quickboot`\n );\n if (saved) {\n this.log('Snapshot saved to host volume.', 'success');\n this.log('Setup Complete! Future runs will launch instantly.', 'success');\n } else {\n throw new Error('Failed to save snapshot inside emulator.');\n }\n }\n }\n\n public async stop(): Promise<void> {\n this.log('Stopping environment...', 'info');\n this.runCommand(`docker compose -f \"${this.composeFile}\" down -v --remove-orphans`);\n this.log('Environment cleaned and stopped.', 'success');\n }\n\n public async reset(): Promise<void> {\n this.log('Performing Fast Browser Reset...', 'info');\n const androidCont = this.getContainerId('android-service');\n if (!androidCont) {\n this.log('Android container not running.', 'error');\n return;\n }\n\n this.log('Initiating fast reset (userspace reboot)...', 'info');\n try {\n execSync(`docker exec \"${androidCont}\" adb shell reboot userspace`, { stdio: 'ignore' });\n } catch {\n // Ignored\n }\n\n this.log('Waiting for device to come online...', 'info');\n \n let online = false;\n\n while (Date.now() - start < 30000) {\n try {\n const state = execSync(`docker exec \"${androidCont}\" adb get-state`, {\n encoding: 'utf-8',\n }).trim();\n if (state === 'device') {\n execSync(`docker exec \"${androidCont}\" adb shell echo ok`, { stdio: 'ignore' });\n online = true;\n break;\n }\n } catch {\n // Still offline\n }\n await new Promise((r) => setTimeout(r, 1000));\n }\n\n if (!online) throw new Error('Timeout waiting for device after reboot');\n this.log('Device online', 'success');\n\n this.log('Waiting for browser CDP...', 'info');\n const cdpStart = Date.now();\n let cdpReady = false;\n\n while (Date.now() - cdpStart < 30000) {\n try {\n execSync(\n `docker exec \"${androidCont}\" curl -s --connect-timeout 2 http://localhost:9224/json/version`,\n { stdio: 'ignore' }\n );\n cdpReady = true;\n break;\n } catch {\n if (Date.now() - cdpStart > 15000) {\n try {\n execSync(\n `docker exec \"${androidCont}\" adb shell am start -n com.wootzapp.web/com.aspect.chromium.ChromiumMain -a android.intent.action.VIEW -d 'about:blank'`,\n { stdio: 'ignore' }\n );\n } catch {}\n }\n }\n await new Promise((r) => setTimeout(r, 1000));\n }\n\n if (!cdpReady) throw new Error('Timeout waiting for CDP');\n this.log('Fast reset complete!', 'success');\n }\n\n private waitForLog(container: string, pattern: string, timeoutMs = 120000): Promise<void> {\n return new Promise((resolve, reject) => {\n \n const tail = spawn('docker', ['logs', '-f', container]);\n\n const timer = setTimeout(() => {\n tail.kill();\n reject(new Error(`Timeout waiting for log pattern \"${pattern}\" in container ${container}`));\n }, timeoutMs);\n\n tail.stdout.on('data', (data) => {\n if (data.toString().includes(pattern)) {\n clearTimeout(timer);\n tail.kill();\n resolve();\n }\n });\n\n tail.stderr.on('data', (data) => {\n if (data.toString().includes(pattern)) {\n clearTimeout(timer);\n tail.kill();\n resolve();\n }\n });\n\n tail.on('error', (err) => {\n clearTimeout(timer);\n reject(err);\n });\n });\n }\n}\n"],"mappings":"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","names":["pino","start","path"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kritchoff/agent-browser",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "Headless browser automation CLI for AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",