@refrainai/cli 0.4.1 → 0.4.3
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/{ai-model-FM6GWCID.js → ai-model-DP5PKGM6.js} +2 -2
- package/dist/{chunk-IGFCYKHC.js → chunk-5CKPPEYP.js} +262 -305
- package/dist/chunk-5CKPPEYP.js.map +1 -0
- package/dist/{chunk-7UCVPKD4.js → chunk-6FGCPMBU.js} +34 -74
- package/dist/chunk-6FGCPMBU.js.map +1 -0
- package/dist/{chunk-2BVDAJZT.js → chunk-A5X2VF5G.js} +9 -6
- package/dist/chunk-A5X2VF5G.js.map +1 -0
- package/dist/{chunk-H47NWH7N.js → chunk-AOCGSFRM.js} +611 -73
- package/dist/chunk-AOCGSFRM.js.map +1 -0
- package/dist/{chunk-CLYJHKPY.js → chunk-CMWLFQXD.js} +43 -42
- package/dist/chunk-CMWLFQXD.js.map +1 -0
- package/dist/chunk-GC7I5SGK.js +1146 -0
- package/dist/chunk-GC7I5SGK.js.map +1 -0
- package/dist/{chunk-WEYR56ZN.js → chunk-HHRHHFSK.js} +4 -4
- package/dist/chunk-IGJNT457.js +30 -0
- package/dist/chunk-IGJNT457.js.map +1 -0
- package/dist/{chunk-UGPXCQY3.js → chunk-KFNW4XR2.js} +13 -4
- package/dist/chunk-KFNW4XR2.js.map +1 -0
- package/dist/{chunk-RT664YIO.js → chunk-LZDZGI4M.js} +3 -1
- package/dist/chunk-LZDZGI4M.js.map +1 -0
- package/dist/{chunk-RYIJPYM3.js → chunk-MYITSQYV.js} +25 -8
- package/dist/chunk-MYITSQYV.js.map +1 -0
- package/dist/chunk-NRKZJVPE.js +74 -0
- package/dist/chunk-NRKZJVPE.js.map +1 -0
- package/dist/chunk-RBZK7T76.js +349 -0
- package/dist/chunk-RBZK7T76.js.map +1 -0
- package/dist/{chunk-HQDXLWAY.js → chunk-SDV3X5UN.js} +2 -2
- package/dist/{chunk-Z33FCOTZ.js → chunk-VVXNFUPL.js} +4 -2
- package/dist/chunk-VVXNFUPL.js.map +1 -0
- package/dist/chunk-YTVEYQGA.js +64 -0
- package/dist/chunk-YTVEYQGA.js.map +1 -0
- package/dist/{chunk-DJVUITRB.js → chunk-ZEBQWBEU.js} +898 -1135
- package/dist/chunk-ZEBQWBEU.js.map +1 -0
- package/dist/cli.js +5 -5
- package/dist/{compose-MTSIJY5D.js → compose-AVX5RU67.js} +9 -7
- package/dist/{compose-MTSIJY5D.js.map → compose-AVX5RU67.js.map} +1 -1
- package/dist/extraction-prompt-VDCKIFLB.js +17 -0
- package/dist/extraction-prompt-VDCKIFLB.js.map +1 -0
- package/dist/{fix-runbook-ZSBOTLC2.js → fix-runbook-6L5ZMA5G.js} +12 -10
- package/dist/{fix-runbook-ZSBOTLC2.js.map → fix-runbook-6L5ZMA5G.js.map} +1 -1
- package/dist/prompts-AGUYYIOM.js +13 -0
- package/dist/runbook-builder-2ZLE2AEO.js +11 -0
- package/dist/{runbook-data-helpers-KRR2SH76.js → runbook-data-helpers-5UAO65TZ.js} +3 -3
- package/dist/{runbook-executor-K7T6RJWJ.js → runbook-executor-OJXJTN6A.js} +41 -444
- package/dist/runbook-executor-OJXJTN6A.js.map +1 -0
- package/dist/{runbook-generator-MPXJBQ5N.js → runbook-generator-UIHWBEYC.js} +61 -136
- package/dist/runbook-generator-UIHWBEYC.js.map +1 -0
- package/dist/{runbook-schema-3T6TP3JJ.js → runbook-schema-X7DW725O.js} +2 -2
- package/dist/runbook-store-S24PXIHD.js +11 -0
- package/dist/{schema-5G6UQSPT.js → schema-XFSD5EWN.js} +2 -2
- package/dist/{server-AG3LXQBI.js → server-MULT5ZWG.js} +1176 -128
- package/dist/server-MULT5ZWG.js.map +1 -0
- package/dist/{tenant-ai-config-QPFEJUVJ.js → tenant-ai-config-4NHKRW7O.js} +4 -4
- package/dist/tenant-ai-config-4NHKRW7O.js.map +1 -0
- package/dist/yaml-patcher-GOCLYKZZ.js +18 -0
- package/dist/yaml-patcher-GOCLYKZZ.js.map +1 -0
- package/package.json +3 -2
- package/dist/chunk-2BVDAJZT.js.map +0 -1
- package/dist/chunk-7UCVPKD4.js.map +0 -1
- package/dist/chunk-CLYJHKPY.js.map +0 -1
- package/dist/chunk-DJVUITRB.js.map +0 -1
- package/dist/chunk-H47NWH7N.js.map +0 -1
- package/dist/chunk-IGFCYKHC.js.map +0 -1
- package/dist/chunk-RT664YIO.js.map +0 -1
- package/dist/chunk-RYIJPYM3.js.map +0 -1
- package/dist/chunk-UGPXCQY3.js.map +0 -1
- package/dist/chunk-VPK2MQAZ.js +0 -589
- package/dist/chunk-VPK2MQAZ.js.map +0 -1
- package/dist/chunk-Z33FCOTZ.js.map +0 -1
- package/dist/runbook-executor-K7T6RJWJ.js.map +0 -1
- package/dist/runbook-generator-MPXJBQ5N.js.map +0 -1
- package/dist/runbook-store-G5GUOWRR.js +0 -11
- package/dist/server-AG3LXQBI.js.map +0 -1
- package/dist/yaml-patcher-VGUS2JGH.js +0 -15
- /package/dist/{ai-model-FM6GWCID.js.map → ai-model-DP5PKGM6.js.map} +0 -0
- /package/dist/{chunk-WEYR56ZN.js.map → chunk-HHRHHFSK.js.map} +0 -0
- /package/dist/{chunk-HQDXLWAY.js.map → chunk-SDV3X5UN.js.map} +0 -0
- /package/dist/{runbook-data-helpers-KRR2SH76.js.map → prompts-AGUYYIOM.js.map} +0 -0
- /package/dist/{runbook-schema-3T6TP3JJ.js.map → runbook-builder-2ZLE2AEO.js.map} +0 -0
- /package/dist/{runbook-store-G5GUOWRR.js.map → runbook-data-helpers-5UAO65TZ.js.map} +0 -0
- /package/dist/{schema-5G6UQSPT.js.map → runbook-schema-X7DW725O.js.map} +0 -0
- /package/dist/{tenant-ai-config-QPFEJUVJ.js.map → runbook-store-S24PXIHD.js.map} +0 -0
- /package/dist/{yaml-patcher-VGUS2JGH.js.map → schema-XFSD5EWN.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/cli/debug-logger.ts","../../../src/context/data-store.ts","../../../src/context/download-manager.ts","../../../src/cli/format.ts","../../../src/cli/secrets-loader.ts","../../../src/logger.ts","../../../src/browser/browser-client.ts","../../../src/browser/engine/browser-manager.ts","../../../src/browser/engine/snapshot.ts","../../../src/browser/engine/state-utils.ts","../../../src/browser/engine/encryption.ts","../../../src/browser/engine/domain-filter.ts","../../../src/browser/engine/actions.ts","../../../src/browser/engine/action-policy.ts","../../../src/browser/engine/confirmation.ts","../../../src/browser/engine/auth-vault.ts","../../../src/browser/engine/protocol.ts","../../../src/browser/engine/diff.ts","../../../src/browser/stealth.ts","../../../src/browser/snapshot-parser.ts","../../../src/harness/error-classifier.ts","../../../src/context/memory-operations.ts","../../../src/harness/sleep.ts","../../../src/i18n/prompts/en/exploration.ts","../../../src/i18n/prompts/ja/exploration.ts","../../../src/i18n/prompts/en/review.ts","../../../src/i18n/prompts/ja/review.ts","../../../src/i18n/prompts/en/selector.ts","../../../src/i18n/prompts/ja/selector.ts","../../../src/i18n/prompts/en/goal-agent.ts","../../../src/i18n/prompts/ja/goal-agent.ts","../../../src/i18n/prompts/en/vision.ts","../../../src/i18n/prompts/ja/vision.ts","../../../src/i18n/prompts/en/self-heal.ts","../../../src/i18n/prompts/ja/self-heal.ts","../../../src/i18n/prompts/index.ts"],"sourcesContent":["/**\n * cli/debug-logger — デバッグログのJSONLファイル出力 + コンソール出力\n *\n * --debug-log <path> 指定時にファイルロガーが有効化。\n * --debug 指定時にコンソールロガーが有効化。\n * null-object パターンにより、呼び出し側は分岐不要。\n */\n\nimport { appendFile, writeFile } from \"node:fs/promises\";\nimport * as p from \"@clack/prompts\";\n\nexport interface DebugLogEntry {\n phase: \"generator\" | \"executor\";\n event: string;\n step?: number;\n data: Record<string, unknown>;\n}\n\nexport interface DebugLogger {\n log(entry: DebugLogEntry): void;\n flush(): Promise<void>;\n}\n\nclass FileDebugLogger implements DebugLogger {\n private buffer: string[] = [];\n private writing = false;\n private pending: Promise<void> = Promise.resolve();\n private initialized = false;\n\n constructor(private filePath: string) {}\n\n log(entry: DebugLogEntry): void {\n const line = JSON.stringify({ ts: new Date().toISOString(), ...entry });\n this.buffer.push(line);\n this.scheduleWrite();\n }\n\n async flush(): Promise<void> {\n await this.pending;\n if (this.buffer.length > 0) {\n await this.writeBuffer();\n }\n }\n\n private scheduleWrite(): void {\n if (this.writing) return;\n this.pending = this.writeBuffer();\n }\n\n private async writeBuffer(): Promise<void> {\n if (this.buffer.length === 0) return;\n this.writing = true;\n const lines = this.buffer.splice(0, this.buffer.length);\n const content = lines.join(\"\\n\") + \"\\n\";\n try {\n if (!this.initialized) {\n await writeFile(this.filePath, content, \"utf-8\");\n this.initialized = true;\n } else {\n await appendFile(this.filePath, content, \"utf-8\");\n }\n } catch {\n // ログ書き込み失敗は操作をブロックしない\n }\n this.writing = false;\n // バッファに追加分があれば再度書き込み\n if (this.buffer.length > 0) {\n this.pending = this.writeBuffer();\n }\n }\n}\n\n/** コンソールにデバッグ情報を出力する実装 */\nclass ConsoleDebugLogger implements DebugLogger {\n log(entry: DebugLogEntry): void {\n const stepPrefix = entry.step !== undefined ? `step#${entry.step}` : \"\";\n const prefix = `[debug] [${entry.event}]${stepPrefix ? ` ${stepPrefix}` : \"\"}`;\n\n switch (entry.event) {\n case \"extract\":\n case \"extract_result\":\n this.logExtract(prefix, entry.data);\n break;\n case \"memory_append\":\n this.logMemoryAppend(prefix, entry.data);\n break;\n case \"memory_aggregate\":\n this.logMemoryAggregate(prefix, entry.data);\n break;\n case \"export\":\n this.logExport(prefix, entry.data);\n break;\n case \"action\":\n this.logAction(prefix, entry.data);\n break;\n default:\n this.logGeneric(prefix, entry.data);\n break;\n }\n }\n\n async flush(): Promise<void> {\n // コンソール出力は即時なので flush 不要\n }\n\n private logExtract(prefix: string, data: Record<string, unknown>): void {\n if (data.script) {\n p.log.info(`${prefix} script: \"${truncate(String(data.script), 120)}\"`);\n }\n if (data.extractPrompt) {\n p.log.info(`${prefix} extractPrompt: \"${truncate(String(data.extractPrompt), 120)}\"`);\n }\n if (data.resultType !== undefined) {\n const typeInfo = data.isArray\n ? `${data.resultType} (array), length: ${data.arrayLength}`\n : String(data.resultType);\n p.log.info(`${prefix} result typeof: \"${typeInfo}\"`);\n }\n if (data.resultPreview !== undefined) {\n p.log.info(`${prefix} result preview: ${truncate(String(data.resultPreview), 200)}`);\n }\n if (data.storedLength !== undefined) {\n const note = data.stringifyApplied ? \" ← JSON.stringify applied\" : \"\";\n p.log.info(`${prefix} stored as string (length: ${data.storedLength})${note}`);\n }\n }\n\n private logMemoryAppend(prefix: string, data: Record<string, unknown>): void {\n if (data.collection) {\n p.log.info(`${prefix} collection: \"${data.collection}\"`);\n }\n if (data.rawValuePreview !== undefined) {\n p.log.info(`${prefix} rawValue preview (200 chars): ${truncate(String(data.rawValuePreview), 200)}`);\n }\n if (data.doubleStringifyDetected) {\n p.log.warn(`${prefix} double-stringify detected! Unquoting before parse.`);\n }\n if (data.parseResult !== undefined) {\n const result = data.parseResult as string;\n if (result === \"array\") {\n p.log.info(\n `${prefix} JSON.parse OK → Array(${data.arrayLength}), element[0] keys: ${data.firstElementKeys ?? \"N/A\"}`,\n );\n } else if (result === \"object\") {\n p.log.info(`${prefix} JSON.parse OK → Object, keys: ${data.objectKeys ?? \"N/A\"}`);\n } else if (result === \"fallback\") {\n p.log.warn(`${prefix} JSON.parse FAILED → storing as {value: \"...\"}`);\n }\n }\n if (data.count !== undefined && data.parseResult === undefined) {\n p.log.info(`${prefix} stored ${data.count} items`);\n }\n }\n\n private logMemoryAggregate(prefix: string, data: Record<string, unknown>): void {\n p.log.info(\n `${prefix} ${data.operation}(${data.collection}.${data.field}) = \"${data.result}\" → {{${data.outputVariable}}}`,\n );\n }\n\n private logExport(prefix: string, data: Record<string, unknown>): void {\n p.log.info(`${prefix} collection: \"${data.collection}\", items: ${data.itemCount}, format: ${data.format}`);\n if (data.sampleKeys) {\n p.log.info(`${prefix} sample keys: ${data.sampleKeys}`);\n }\n if (data.path) {\n p.log.info(`${prefix} → ${data.path}`);\n }\n }\n\n private logAction(prefix: string, data: Record<string, unknown>): void {\n p.log.info(\n `${prefix} type=${data.type} ref=${data.ref ?? \"N/A\"} value=\"${truncate(String(data.value ?? \"\"), 80)}\" status=${data.status}`,\n );\n }\n\n private logGeneric(prefix: string, data: Record<string, unknown>): void {\n const preview = JSON.stringify(data);\n p.log.info(`${prefix} ${truncate(preview, 200)}`);\n }\n}\n\n/** 複数のロガーに委譲する Composite 実装 */\nclass CompositeDebugLogger implements DebugLogger {\n constructor(private loggers: DebugLogger[]) {}\n\n log(entry: DebugLogEntry): void {\n for (const logger of this.loggers) {\n logger.log(entry);\n }\n }\n\n async flush(): Promise<void> {\n await Promise.all(this.loggers.map((l) => l.flush()));\n }\n}\n\n/** ログ無効時の noop 実装 */\nexport const noopLogger: DebugLogger = {\n log() {},\n async flush() {},\n};\n\n/** 文字列を指定長で切り詰め */\nfunction truncate(str: string, maxLen: number): string {\n if (str.length <= maxLen) return str;\n return `${str.slice(0, maxLen)}...`;\n}\n\n/**\n * デバッグロガーを生成\n *\n * @param opts.filePath JSONL ファイル出力先パス\n * @param opts.console コンソール出力を有効にするか\n */\nexport function createDebugLogger(opts?: {\n filePath?: string;\n console?: boolean;\n}): DebugLogger {\n if (!opts) return noopLogger;\n\n const loggers: DebugLogger[] = [];\n\n if (opts.filePath) {\n loggers.push(new FileDebugLogger(opts.filePath));\n }\n if (opts.console) {\n loggers.push(new ConsoleDebugLogger());\n }\n\n if (loggers.length === 0) return noopLogger;\n if (loggers.length === 1) return loggers[0];\n return new CompositeDebugLogger(loggers);\n}\n","/**\n * data-store — データ蓄積と集計のインターフェース + インメモリ実装\n *\n * DataStore: データの蓄積・取得を抽象化\n * DataAggregator: 集計操作を抽象化\n * InMemoryDataStore: 初期のインメモリ実装(将来 DuckDB 等に差し替え可能)\n */\n\nimport { writeFile } from \"node:fs/promises\";\n\n// ── 型定義 ──\n\nexport type AggregateOperation =\n | \"sum\"\n | \"count\"\n | \"concat\"\n | \"min\"\n | \"max\"\n | \"avg\"\n | \"unique_count\";\n\nexport interface AggregateQuery {\n collection: string;\n field: string;\n operation: AggregateOperation;\n /** 将来拡張: WHERE 条件 */\n filter?: Record<string, unknown>;\n}\n\n// ── インターフェース ──\n\nexport interface DataStore {\n append(collection: string, item: Record<string, unknown>): void;\n extend(collection: string, items: Record<string, unknown>[]): void;\n getAll(collection: string): Record<string, unknown>[];\n count(collection: string): number;\n clear(collection: string): void;\n listCollections(): string[];\n toJSON(): Record<string, Record<string, unknown>[]>;\n /** コレクションをファイルに書き出し */\n writeToFile(collection: string, path: string, format: \"json\" | \"csv\"): Promise<void>;\n}\n\nexport interface DataAggregator {\n aggregate(query: AggregateQuery): string;\n}\n\n// ── インメモリ実装 ──\n\nexport class InMemoryDataStore implements DataStore, DataAggregator {\n private collections = new Map<string, Record<string, unknown>[]>();\n\n append(collection: string, item: Record<string, unknown>): void {\n const items = this.collections.get(collection) ?? [];\n items.push(item);\n this.collections.set(collection, items);\n }\n\n extend(collection: string, newItems: Record<string, unknown>[]): void {\n const items = this.collections.get(collection) ?? [];\n items.push(...newItems);\n this.collections.set(collection, items);\n }\n\n getAll(collection: string): Record<string, unknown>[] {\n return this.collections.get(collection) ?? [];\n }\n\n count(collection: string): number {\n return (this.collections.get(collection) ?? []).length;\n }\n\n clear(collection: string): void {\n this.collections.delete(collection);\n }\n\n listCollections(): string[] {\n return Array.from(this.collections.keys());\n }\n\n toJSON(): Record<string, Record<string, unknown>[]> {\n const result: Record<string, Record<string, unknown>[]> = {};\n for (const [key, items] of this.collections) {\n result[key] = items;\n }\n return result;\n }\n\n aggregate(query: AggregateQuery): string {\n const items = this.getAll(query.collection);\n if (items.length === 0) return \"0\";\n\n const values = items.map((item) => item[query.field]);\n\n switch (query.operation) {\n case \"sum\": {\n const total = values.reduce(\n (acc: number, v) => acc + (Number(v) || 0),\n 0,\n );\n return String(total);\n }\n case \"count\":\n return String(values.length);\n case \"concat\":\n return values.map(String).join(\", \");\n case \"min\": {\n const nums = values.map(Number).filter((n) => !Number.isNaN(n));\n return nums.length > 0 ? String(Math.min(...nums)) : \"0\";\n }\n case \"max\": {\n const nums = values.map(Number).filter((n) => !Number.isNaN(n));\n return nums.length > 0 ? String(Math.max(...nums)) : \"0\";\n }\n case \"avg\": {\n const nums = values.map(Number).filter((n) => !Number.isNaN(n));\n if (nums.length === 0) return \"0\";\n const sum = nums.reduce((a, b) => a + b, 0);\n return String(sum / nums.length);\n }\n case \"unique_count\": {\n const unique = new Set(values.map(String));\n return String(unique.size);\n }\n }\n }\n\n /**\n * コレクションごとのメモリ圧迫状況を返す。\n * low: <1000, medium: 1000-5000, high: >5000\n */\n getPressureStatus(): Record<string, { count: number; pressure: \"low\" | \"medium\" | \"high\" }> {\n const result: Record<string, { count: number; pressure: \"low\" | \"medium\" | \"high\" }> = {};\n for (const [name, items] of this.collections) {\n const count = items.length;\n const pressure = count >= 5000 ? \"high\" : count >= 1000 ? \"medium\" : \"low\";\n result[name] = { count, pressure };\n }\n return result;\n }\n\n /** コレクションを CSV 文字列として出力 */\n toCSV(collection: string): string {\n const items = this.getAll(collection);\n if (items.length === 0) return \"\";\n\n // 全アイテムからキーを収集(順序保持)\n const keys = new Set<string>();\n for (const item of items) {\n for (const key of Object.keys(item)) {\n keys.add(key);\n }\n }\n const headers = Array.from(keys);\n\n const escapeCSV = (val: unknown): string => {\n const str = val === null || val === undefined ? \"\" : String(val);\n if (str.includes(\",\") || str.includes('\"') || str.includes(\"\\n\")) {\n return `\"${str.replace(/\"/g, '\"\"')}\"`;\n }\n return str;\n };\n\n const rows = items.map((item) =>\n headers.map((h) => escapeCSV(item[h])).join(\",\"),\n );\n return [headers.join(\",\"), ...rows].join(\"\\n\");\n }\n\n /** コレクションをファイルに書き出し */\n async writeToFile(\n collection: string,\n path: string,\n format: \"json\" | \"csv\",\n ): Promise<void> {\n const content =\n format === \"csv\"\n ? this.toCSV(collection)\n : JSON.stringify(this.getAll(collection), null, 2);\n await writeFile(path, content, \"utf-8\");\n }\n}\n","/**\n * download-manager — ファイルダウンロードの追跡と結合\n *\n * OutputStorage: ファイルI/Oの抽象化(将来 S3/GCS 対応用)\n * LocalStorage: ローカルファイルシステム実装\n * DownloadManager: ダウンロード追跡 + CSV マージ\n */\n\nimport { readFile, writeFile, mkdir, stat } from \"node:fs/promises\";\nimport { join, basename } from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\n\n// ── 型定義 ──\n\nexport interface DownloadRecord {\n id: string;\n path: string;\n filename: string;\n stepOrdinal: number;\n timestamp: string;\n sizeBytes?: number;\n}\n\n// ── OutputStorage インターフェース ──\n\nexport interface OutputStorage {\n write(filename: string, content: Buffer | string): Promise<string>;\n read(filename: string): Promise<Buffer>;\n exists(filename: string): Promise<boolean>;\n}\n\nexport class LocalStorage implements OutputStorage {\n constructor(private baseDir: string) {}\n\n async write(filename: string, content: Buffer | string): Promise<string> {\n await mkdir(this.baseDir, { recursive: true });\n const filePath = join(this.baseDir, filename);\n await writeFile(filePath, content);\n return filePath;\n }\n\n async read(filename: string): Promise<Buffer> {\n const filePath = join(this.baseDir, filename);\n return readFile(filePath);\n }\n\n async exists(filename: string): Promise<boolean> {\n try {\n await stat(join(this.baseDir, filename));\n return true;\n } catch {\n return false;\n }\n }\n}\n\n// ── DownloadManager ──\n\nexport class DownloadManager {\n private downloads: DownloadRecord[] = [];\n private storage: OutputStorage;\n\n constructor(outputDir: string) {\n this.storage = new LocalStorage(outputDir);\n }\n\n addDownload(\n record: Omit<DownloadRecord, \"id\">,\n ): DownloadRecord {\n const download: DownloadRecord = {\n ...record,\n id: randomUUID(),\n };\n this.downloads.push(download);\n return download;\n }\n\n getDownloads(): DownloadRecord[] {\n return [...this.downloads];\n }\n\n getDownloadsByStep(stepOrdinal: number): DownloadRecord[] {\n return this.downloads.filter((d) => d.stepOrdinal === stepOrdinal);\n }\n\n /**\n * 複数のダウンロード済みCSVファイルを結合する。\n * 1つ目のファイルのヘッダを使用し、2つ目以降はヘッダ行をスキップ。\n */\n async mergeCSVFiles(\n downloadIds: string[],\n outputFilename: string,\n ): Promise<string> {\n const targets = downloadIds\n .map((id) => this.downloads.find((d) => d.id === id))\n .filter((d): d is DownloadRecord => d !== undefined);\n\n if (targets.length === 0) {\n throw new Error(\"No downloads found for the given IDs\");\n }\n\n const chunks: string[] = [];\n let headerLine: string | null = null;\n\n for (let i = 0; i < targets.length; i++) {\n const content = await readFile(targets[i].path, \"utf-8\");\n const lines = content.split(\"\\n\").filter((l) => l.trim().length > 0);\n\n if (lines.length === 0) continue;\n\n if (i === 0) {\n // 1つ目: ヘッダ含む全行\n headerLine = lines[0];\n chunks.push(content.trimEnd());\n } else {\n // 2つ目以降: ヘッダ行をスキップ\n const dataLines = lines.slice(1);\n if (dataLines.length > 0) {\n chunks.push(dataLines.join(\"\\n\"));\n }\n }\n }\n\n const merged = chunks.join(\"\\n\") + \"\\n\";\n const outputPath = await this.storage.write(outputFilename, merged);\n return outputPath;\n }\n\n /** 全ダウンロードの ID 一覧 */\n getAllDownloadIds(): string[] {\n return this.downloads.map((d) => d.id);\n }\n\n /** ダウンロードのファイルパス一覧 */\n getAllPaths(): string[] {\n return this.downloads.map((d) => d.path);\n }\n}\n","/**\n * cli/format --- 共通フォーマットユーティリティ\n */\n\nexport function formatDuration(ms: number): string {\n return ms >= 1000 ? `${(ms / 1000).toFixed(1)}s` : `${Math.round(ms)}ms`;\n}\n","/**\n * cli/secrets-loader --- secrets JSON ファイルの読み込み\n *\n * key-value 形式の JSON を読み込み、全値を sensitive 扱いで管理する。\n */\n\nimport { readFile } from \"node:fs/promises\";\nimport { cancel } from \"./prompts\";\n\nexport interface SecretsData {\n /** 変数名→値のマップ */\n values: Record<string, string>;\n /** すべてのキー(全て sensitive 扱い) */\n keys: Set<string>;\n}\n\n/**\n * secrets JSON ファイルを読み込み、バリデーション後に返す。\n * パスが未指定の場合は空の SecretsData を返す。\n */\n/**\n * runbook の変数定義から値を取り出し、既存の secrets にマージする。\n * 変数の値は AI プロンプトの「入力値(secrets)」セクションに含まれ、\n * 「フォーム入力時に使用してください」指示が付く。\n *\n * CLI の --secrets + runbook 変数、サーバーの DB secrets + DB 変数のどちらでも利用可能。\n */\nexport function mergeVariablesIntoSecrets(\n secrets: SecretsData | undefined,\n variables: Record<string, { value?: string; sensitive?: boolean }> | undefined,\n): SecretsData | undefined {\n const mergedValues = { ...(secrets?.values ?? {}) };\n const mergedKeys = new Set(secrets?.keys ?? []);\n\n if (variables) {\n for (const [name, def] of Object.entries(variables)) {\n if (def.value && !(name in mergedValues)) {\n mergedValues[name] = def.value;\n mergedKeys.add(name);\n }\n }\n }\n\n if (Object.keys(mergedValues).length === 0) return undefined;\n return { values: mergedValues, keys: mergedKeys };\n}\n\n/** Inngest step.run 用: SecretsData → JSON シリアライズ可能な形式 */\nexport function serializeSecrets(\n secrets: SecretsData,\n): { values: Record<string, string>; keys: string[] } {\n return { values: secrets.values, keys: [...secrets.keys] };\n}\n\n/** Inngest step.run 用: JSON → SecretsData 復元 */\nexport function deserializeSecrets(\n data: { values: Record<string, string>; keys: string[] },\n): SecretsData {\n return { values: data.values, keys: new Set(data.keys) };\n}\n\n/**\n * secrets JSON ファイルを読み込み、バリデーション後に返す。\n * パスが未指定の場合は空の SecretsData を返す。\n */\nexport async function loadSecrets(path?: string): Promise<SecretsData> {\n if (!path) {\n return { values: {}, keys: new Set() };\n }\n\n const raw = await readFile(path, \"utf-8\").catch(() => {\n cancel(`secrets ファイルが読み込めません: ${path}`);\n process.exit(1);\n });\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n cancel(`secrets ファイルの JSON パースに失敗しました: ${path}`);\n process.exit(1);\n }\n\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n cancel('secrets ファイルはオブジェクト形式 {\"key\": \"value\"} である必要があります');\n process.exit(1);\n }\n\n const values: Record<string, string> = {};\n for (const [key, val] of Object.entries(parsed as Record<string, unknown>)) {\n if (typeof val !== \"string\") {\n cancel(`secrets の値は文字列である必要があります (key: \"${key}\")`);\n process.exit(1);\n }\n values[key] = val;\n }\n\n return {\n values,\n keys: new Set(Object.keys(values)),\n };\n}\n","/**\n * logger — ログ出力の抽象化\n *\n * SDK から @clack/prompts への直接依存を除去するためのインターフェース。\n * CLI は CliLogger / CliSpinner で @clack/prompts をデリゲートし、\n * SDK / テストは NoopLogger や CallbackLogger を利用する。\n */\n\nexport interface Logger {\n step(message: string): void;\n success(message: string): void;\n error(message: string): void;\n warn(message: string): void;\n info(message: string): void;\n debug(message: string): void;\n}\n\nexport interface SpinnerLike {\n start(message: string): void;\n stop(message: string): void;\n}\n\nexport interface LoggerFactory {\n createLogger(): Logger;\n createSpinner(): SpinnerLike;\n}\n\n// ── NoopLogger ──\n\nexport class NoopLogger implements Logger {\n step(_message: string): void {}\n success(_message: string): void {}\n error(_message: string): void {}\n warn(_message: string): void {}\n info(_message: string): void {}\n debug(_message: string): void {}\n}\n\nexport class NoopSpinner implements SpinnerLike {\n start(_message: string): void {}\n stop(_message: string): void {}\n}\n\nexport const noopLoggerFactory: LoggerFactory = {\n createLogger: () => new NoopLogger(),\n createSpinner: () => new NoopSpinner(),\n};\n\n// ── CallbackLogger ──\n\nexport type LogLevel = \"step\" | \"success\" | \"error\" | \"warn\" | \"info\" | \"debug\";\n\nexport class CallbackLogger implements Logger {\n constructor(private readonly onLog: (level: LogLevel, message: string) => void) {}\n\n step(message: string): void {\n this.onLog(\"step\", message);\n }\n success(message: string): void {\n this.onLog(\"success\", message);\n }\n error(message: string): void {\n this.onLog(\"error\", message);\n }\n warn(message: string): void {\n this.onLog(\"warn\", message);\n }\n info(message: string): void {\n this.onLog(\"info\", message);\n }\n debug(message: string): void {\n this.onLog(\"debug\", message);\n }\n}\n","/**\n * agent-browser 内部API直接利用ラッパー\n *\n * BrowserManager + executeCommand() でインプロセス実行。\n * CLI子プロセス呼び出しを排除。\n */\n\nimport { copyFile, mkdir, readFile, rm, unlink } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { type ChildProcess, spawn, execSync } from \"node:child_process\";\nimport { BrowserManager, executeCommand } from \"./engine\";\nimport type {\n Command,\n LaunchCommand,\n Response,\n RefMap,\n SnapshotOptions,\n Annotation,\n ScreenshotData,\n ScreencastFrame,\n} from \"./engine\";\nimport type { Logger } from \"../logger\";\nimport { NoopLogger } from \"../logger\";\nimport type { ExplorationAction, StepResult } from \"../runbook-generator/types\";\nimport { applyStealthScripts } from \"./stealth\";\n\nexport interface BrowserOpenOptions {\n headless?: boolean;\n stealth?: boolean;\n proxy?: string;\n colorScheme?: \"light\" | \"dark\" | \"no-preference\";\n downloadPath?: string;\n}\n\n/**\n * プロキシ URL を LaunchCommand.proxy 形式にパースする。\n * 対応形式: http://user:pass@host:port, socks5://host:port, http://host:port\n */\nfunction parseProxyUrl(\n proxyUrl: string,\n): { server: string; username?: string; password?: string } {\n try {\n const url = new URL(proxyUrl);\n const server = `${url.protocol}//${url.hostname}${url.port ? `:${url.port}` : \"\"}`;\n const username = url.username || undefined;\n const password = url.password || undefined;\n return { server, username, password };\n } catch {\n // パース失敗時はそのまま server として扱う\n return { server: proxyUrl };\n }\n}\n\nlet commandId = 0;\nfunction nextId(): string {\n return String(++commandId);\n}\n\n/** CDP Screencast の FPS(フレームポンプ間隔の基準) */\nconst SCREENCAST_FPS = 5;\n/** フレームポンプ間隔 (ms) */\nconst FRAME_PUMP_INTERVAL_MS = Math.round(1000 / SCREENCAST_FPS);\n/** screencast 回復ポーリング間隔 (ms) */\nconst SCREENCAST_RECOVERY_INTERVAL_MS = 500;\n\nexport class AgentBrowser {\n private browser = new BrowserManager();\n private logger: Logger;\n\n // CDP Screencast + ffmpeg 録画用プロパティ\n private ffmpegProcess: ChildProcess | null = null;\n private latestFrame: Buffer | null = null;\n private framePumpInterval: ReturnType<typeof setInterval> | null = null;\n private screencastRecoveryInterval: ReturnType<typeof setInterval> | null = null;\n private isScreencastRecording = false;\n private screencastOutputPath: string | null = null;\n\n constructor(logger?: Logger) {\n this.logger = logger ?? new NoopLogger();\n }\n\n /**\n * Playwright Page オブジェクトを取得する(スクリーンショット撮影用)。\n * ブラウザ未起動時は null を返す。\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n getPage(): any {\n try {\n return (this.browser as any).getPage?.() ?? null;\n } catch {\n return null;\n }\n }\n\n /**\n * executeCommand のラッパー。失敗時はthrow。\n */\n private async exec(command: Command): Promise<Response> {\n const response = await executeCommand(command, this.browser);\n if (!response.success) {\n throw new Error(response.error);\n }\n return response;\n }\n\n async open(url: string, options?: BrowserOpenOptions): Promise<void> {\n if (!this.browser.isLaunched()) {\n const launchCommand = {\n id: nextId(),\n action: \"launch\" as const,\n headless: options?.headless ?? true,\n viewport: { width: 1280, height: 720 },\n colorScheme: options?.colorScheme,\n downloadPath: options?.downloadPath,\n proxy: options?.proxy ? parseProxyUrl(options.proxy) : undefined,\n } satisfies LaunchCommand;\n\n await this.browser.launch(launchCommand);\n\n if (options?.stealth) {\n await applyStealthScripts(this.browser.getPage());\n this.logger.debug(\"[stealth] patches applied\");\n }\n }\n await this.exec({ id: nextId(), action: \"navigate\", url });\n }\n\n async snapshot(options?: SnapshotOptions): Promise<string> {\n const result = await this.browser.getSnapshot({ compact: true, cursor: true, ...options });\n return result.tree;\n }\n\n async snapshotWithRefs(options?: SnapshotOptions): Promise<{ tree: string; refs: RefMap }> {\n const result = await this.browser.getSnapshot({ compact: true, cursor: true, ...options });\n return { tree: result.tree, refs: result.refs };\n }\n\n async click(ref: string): Promise<void> {\n await this.exec({ id: nextId(), action: \"click\", selector: ref });\n }\n\n async fill(ref: string, value: string): Promise<void> {\n await this.exec({ id: nextId(), action: \"fill\", selector: ref, value });\n }\n\n async type(ref: string, text: string): Promise<void> {\n await this.exec({\n id: nextId(),\n action: \"type\",\n selector: ref,\n text,\n });\n }\n\n async select(ref: string, value: string): Promise<void> {\n await this.exec({\n id: nextId(),\n action: \"select\",\n selector: ref,\n values: value,\n });\n }\n\n async check(ref: string): Promise<void> {\n await this.exec({ id: nextId(), action: \"check\", selector: ref });\n }\n\n async uncheck(ref: string): Promise<void> {\n await this.exec({ id: nextId(), action: \"uncheck\", selector: ref });\n }\n\n async navigate(url: string): Promise<void> {\n await this.exec({ id: nextId(), action: \"navigate\", url });\n }\n\n async wait(ms: number): Promise<void> {\n await this.exec({ id: nextId(), action: \"wait\", timeout: ms });\n }\n\n async scroll(direction: string, amount = 500, options?: { selector?: string }): Promise<void> {\n await this.exec({\n id: nextId(),\n action: \"scroll\",\n direction: direction as \"up\" | \"down\" | \"left\" | \"right\",\n amount,\n selector: options?.selector,\n });\n }\n\n async screenshot(\n path: string,\n options?: { annotate?: boolean; fullPage?: boolean },\n ): Promise<Annotation[]> {\n const response = await this.exec({\n id: nextId(),\n action: \"screenshot\",\n path,\n ...options,\n });\n const data = (response as { data?: ScreenshotData }).data;\n return data?.annotations ?? [];\n }\n\n /**\n * アノテーション付きスクリーンショットを撮影し、画像バッファとアノテーション配列を返す。\n * Vision Fallback 用: AI にスクリーンショットを渡して視覚的にセレクタを解決する。\n */\n async screenshotWithAnnotations(): Promise<{\n imageBuffer: Buffer;\n annotations: Annotation[];\n }> {\n const tempPath = join(tmpdir(), `vision-fallback-${Date.now()}.png`);\n const annotations = await this.screenshot(tempPath, { annotate: true });\n const imageBuffer = await readFile(tempPath);\n unlink(tempPath).catch(() => {}); // fire-and-forget cleanup\n return { imageBuffer, annotations };\n }\n\n /**\n * ダウンロード監視をセットアップする。\n * CDP セットアップは完全に await してからリターンするため、\n * 呼び出し元が click を開始する時点で全リスナーが登録済みであることを保証する。\n *\n * Strategy 1 (CDP): Browser.setDownloadBehavior + Browser.downloadWillBegin/downloadProgress\n * → ブラウザレベルのイベント。window.open / blob URL / Service Worker 等あらゆるメカニズムに対応。\n * Strategy 2 (Playwright): page.on(\"download\") + context.on(\"page\") → newPage.on(\"download\")\n * → Playwright が検知できる通常のダウンロード用。\n *\n * 両方を並行で起動し、先に検知した方を採用。\n */\n private async _setupDownloadWatch(\n savePath: string,\n timeout: number,\n ): Promise<{ detectionPromise: Promise<void>; cleanup: () => void }> {\n const page = this.getPage();\n if (!page) throw new Error(\"Browser not launched\");\n\n const context = page.context();\n const cleanupFns: Array<() => void> = [];\n\n // --- Timeout ---\n let timeoutId: ReturnType<typeof setTimeout>;\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(\n () =>\n reject(\n new Error(\n `Download timeout: ${timeout}ms exceeded while waiting for event \"download\"`,\n ),\n ),\n timeout,\n );\n });\n cleanupFns.push(() => clearTimeout(timeoutId));\n\n // --- Strategy 1: CDP (トップレベル await でセットアップ完了を保証) ---\n let cdpPromise: Promise<void> = new Promise(() => {}); // never-settling default\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const playwrightBrowser = (this.browser as any).getBrowser?.();\n if (playwrightBrowser) {\n const cdp = await playwrightBrowser.newBrowserCDPSession();\n const tempDir = join(tmpdir(), `rfn-dl-${Date.now()}`);\n await mkdir(tempDir, { recursive: true });\n\n await cdp.send(\"Browser.setDownloadBehavior\", {\n behavior: \"allowAndName\",\n downloadPath: tempDir,\n eventsEnabled: true,\n });\n\n // CDP セットアップ完了 → リスナー登録(同期)\n let guid: string | null = null;\n cdpPromise = new Promise<void>((resolve, reject) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const onBegin = (event: any) => {\n guid = event.guid;\n this.logger.debug?.(\n `[download] CDP: started (guid=${guid}, file=${event.suggestedFilename})`,\n );\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const onProgress = async (event: any) => {\n if (event.state === \"completed\" && guid && event.guid === guid) {\n const src = join(tempDir, guid);\n let copied = false;\n for (let attempt = 0; attempt < 5; attempt++) {\n try {\n await copyFile(src, savePath);\n copied = true;\n break;\n } catch (err: unknown) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code !== \"ENOENT\") break; // リトライ不要なエラー\n this.logger.debug?.(\n `[download] CDP: copyFile ENOENT, retry ${attempt + 1}/5`,\n );\n await new Promise((r) => setTimeout(r, 200));\n }\n }\n if (copied) {\n await rm(tempDir, { recursive: true }).catch(() => {});\n resolve();\n } else {\n // 全リトライ失敗 — promise を未解決のまま残し Playwright 側に委ねる\n this.logger.debug?.(\n `[download] CDP: copyFile failed after retries, falling back to Playwright`,\n );\n }\n } else if (event.state === \"canceled\") {\n reject(new Error(\"Download was canceled\"));\n }\n };\n\n cdp.on(\"Browser.downloadWillBegin\", onBegin);\n cdp.on(\"Browser.downloadProgress\", onProgress);\n\n cleanupFns.push(() => {\n cdp.off(\"Browser.downloadWillBegin\", onBegin);\n cdp.off(\"Browser.downloadProgress\", onProgress);\n // ダウンロード動作を元に戻す\n cdp\n .send(\"Browser.setDownloadBehavior\", {\n behavior: \"allow\",\n eventsEnabled: false,\n })\n .catch(() => {});\n cdp.detach().catch(() => {});\n });\n });\n }\n } catch {\n // CDP 取得失敗 — Strategy 2 に委ねる\n }\n\n // --- Strategy 2: Playwright download events (全ページ監視、同期セットアップ) ---\n const playwrightPromise = new Promise<void>((resolve) => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const trackedPages: any[] = [];\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const onDownload = async (dl: any) => {\n await dl.saveAs(savePath);\n resolve();\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const onNewPage = (newPage: any) => {\n trackedPages.push(newPage);\n newPage.on(\"download\", onDownload);\n };\n\n for (const p of context.pages()) p.on(\"download\", onDownload);\n context.on(\"page\", onNewPage);\n\n cleanupFns.push(() => {\n for (const p of context.pages()) p.removeListener(\"download\", onDownload);\n for (const p of trackedPages) p.removeListener(\"download\", onDownload);\n context.removeListener(\"page\", onNewPage);\n });\n });\n\n // CDP の reject が Playwright フォールバックを巻き添えにしないようラップ\n const safeCdpPromise = cdpPromise.catch((err: Error) => {\n if (err.message === \"Download was canceled\") throw err; // 正当なキャンセルは伝播\n this.logger.debug?.(\n `[download] CDP error suppressed, deferring to Playwright: ${err.message}`,\n );\n return new Promise<void>(() => {}); // never-settling — Playwright or timeout が勝つ\n });\n const detectionPromise = Promise.race([safeCdpPromise, playwrightPromise, timeoutPromise]);\n const cleanup = () => { for (const fn of cleanupFns) fn(); };\n\n return { detectionPromise, cleanup };\n }\n\n async download(\n selector: string,\n savePath: string,\n timeout = 60_000,\n ): Promise<string> {\n const page = this.getPage();\n if (!page) throw new Error(\"Browser not launched\");\n\n // savePath の親ディレクトリを事前作成\n const dir = savePath.substring(0, savePath.lastIndexOf(\"/\"));\n if (dir) await mkdir(dir, { recursive: true });\n\n // Phase 1: 全リスナーのセットアップ完了を await(CDP の async 処理含む)\n const { detectionPromise, cleanup } = await this._setupDownloadWatch(savePath, timeout);\n\n try {\n // Phase 2: リスナー登録済みの状態でクリック + 検知待ち\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const locator = (this.browser as any).getLocator(selector);\n await Promise.all([detectionPromise, locator.click()]);\n } finally {\n cleanup();\n }\n\n return savePath;\n }\n\n async waitForDownload(\n savePath?: string,\n timeout?: number,\n ): Promise<void> {\n if (!savePath) {\n // savePath なしの場合は従来通り agent-browser に委譲\n await this.exec({\n id: nextId(),\n action: \"waitfordownload\",\n timeout: timeout ?? 30000,\n });\n return;\n }\n\n const dir = savePath.substring(0, savePath.lastIndexOf(\"/\"));\n if (dir) await mkdir(dir, { recursive: true });\n\n const { detectionPromise, cleanup } = await this._setupDownloadWatch(savePath, timeout ?? 30000);\n try {\n await detectionPromise;\n } finally {\n cleanup();\n }\n }\n\n async evaluate(script: string): Promise<unknown> {\n // await を含むスクリプトは async IIFE でラップ\n const wrappedScript = /\\bawait\\b/.test(script)\n ? `(async () => { ${script} })()`\n : script;\n const response = await this.exec({\n id: nextId(),\n action: \"evaluate\",\n script: wrappedScript,\n });\n // agent-browser returns { result: unknown } in data\n const data = (response as { data?: { result?: unknown } }).data;\n return data?.result ?? data;\n }\n\n async getText(selector: string): Promise<string> {\n const response = await this.exec({\n id: nextId(),\n action: \"gettext\",\n selector,\n });\n const data = (response as { data?: unknown }).data;\n return String(data ?? \"\");\n }\n\n async getInnerText(selector: string): Promise<string> {\n const response = await this.exec({\n id: nextId(),\n action: \"innertext\",\n selector,\n });\n const data = (response as { data?: unknown }).data;\n return String(data ?? \"\");\n }\n\n /**\n * キーボードショートカットを送信する。\n * Playwright の key combination 形式(例: \"Meta+Alt+z\", \"Control+Alt+z\")。\n */\n async pressKeys(combination: string): Promise<void> {\n await this.browser.getPage().keyboard.press(combination);\n }\n\n async url(): Promise<string> {\n return this.browser.getPage().url();\n }\n\n /** アクション前のページ数を返す */\n async pageCount(): Promise<number> {\n return this.browser.getPages().length;\n }\n\n /**\n * 新しいタブが開かれた場合、最新のタブに切り替える。\n * @returns 切り替えが発生したかどうか\n */\n async switchToLatestTab(pageCountBefore: number): Promise<boolean> {\n const pages = this.browser.getPages();\n if (pages.length > pageCountBefore) {\n const latestIndex = pages.length - 1;\n await this.browser.switchTo(latestIndex);\n return true;\n }\n return false;\n }\n\n /**\n * DOM が安定するまで待機(SPA遷移後のレンダリング完了検出用)。\n * Phase 1: networkidle を最大3秒待つ\n * Phase 2: スナップショットをアダプティブ間隔でポーリングし、\n * 2回連続で同一なら安定と判定。\n * 初期100ms → 200ms → 300ms と段階的に延長(高速ページで早期検出)\n */\n async waitForDOMStability(timeoutMs = 5000): Promise<void> {\n const page = this.browser.getPage();\n\n // Phase 1: networkidle\n try {\n await page.waitForLoadState(\"networkidle\", { timeout: Math.min(timeoutMs, 3000) });\n } catch {\n // タイムアウトは無視\n }\n\n // Phase 2: アダプティブポーリング\n const pollEnd = Date.now() + timeoutMs;\n let prevSnapshot = \"\";\n let stableCount = 0;\n let pollCount = 0;\n\n while (Date.now() < pollEnd) {\n const current = await this.snapshot();\n if (current === prevSnapshot) {\n stableCount++;\n if (stableCount >= 2) {\n this.logger.debug(\"[dom-stability] snapshot stable\");\n return;\n }\n } else {\n stableCount = 0;\n }\n prevSnapshot = current;\n pollCount++;\n // アダプティブ間隔: 100ms → 200ms → 300ms(以降300ms固定)\n const interval = pollCount <= 1 ? 100 : pollCount <= 2 ? 200 : 300;\n await new Promise((r) => setTimeout(r, interval));\n }\n this.logger.debug(\"[dom-stability] timeout, proceeding\");\n }\n\n /**\n * スナップショットが変化するまでポーリングで待機。\n * SPA遷移がまだ始まっていないケースに対応。\n * waitForDOMStability(変化が止まるのを待つ)とは逆で、変化が始まるのを待つ。\n */\n async waitForSnapshotChange(\n baselineSnapshot: string,\n timeoutMs = 10000,\n pollIntervalMs = 500,\n ): Promise<{ changed: boolean; snapshot: string }> {\n const deadline = Date.now() + timeoutMs;\n while (Date.now() < deadline) {\n await new Promise((r) => setTimeout(r, pollIntervalMs));\n const current = await this.snapshot();\n if (current !== baselineSnapshot) {\n this.logger.debug(\"[snapshot-change] transition detected\");\n await this.waitForDOMStability();\n return { changed: true, snapshot: await this.snapshot() };\n }\n }\n this.logger.debug(\"[snapshot-change] timeout, no change\");\n return { changed: false, snapshot: baselineSnapshot };\n }\n\n /**\n * アクション後のナビゲーション/タブ切替を待機。\n * Stage 1: 新タブが開いていたら切り替え + ロード待機\n * Stage 2: 同一タブ内のナビゲーションなら URL 変化を待機\n * Stage 3: URL変化なしの場合、スナップショット変化でSPA遷移を検知し安定化待機\n */\n async waitForPossibleNavigation(\n urlBefore: string,\n pageCountBefore: number,\n timeout = 3000,\n ): Promise<void> {\n // Stage 1: 新タブ検知\n const pollEnd = Date.now() + 500;\n let switched = false;\n while (Date.now() < pollEnd) {\n const currentCount = this.browser.getPages().length;\n this.logger.debug(`[nav] polling tabs: before=${pageCountBefore} now=${currentCount}`);\n if (currentCount > pageCountBefore) {\n switched = true;\n break;\n }\n await new Promise((r) => setTimeout(r, 100));\n }\n\n if (switched) {\n const pages = this.browser.getPages();\n const latestIndex = pages.length - 1;\n this.logger.debug(`[nav] new tab detected, switching to index ${latestIndex}`);\n await this.browser.switchTo(latestIndex);\n const page = this.browser.getPage();\n this.logger.debug(`[nav] switched, url=${page.url()}`);\n try {\n await page.waitForLoadState(\"load\", { timeout });\n } catch {\n // タイムアウトは無視\n }\n this.logger.debug(`[nav] load complete, url=${page.url()}`);\n return;\n }\n\n // Stage 2: 同一タブ内のナビゲーション待機\n this.logger.debug(`[nav] no new tab, checking same-tab navigation (urlBefore=${urlBefore})`);\n const page = this.browser.getPage();\n let urlChanged = false;\n try {\n await page.waitForURL(\n (url) => url.toString() !== urlBefore,\n { timeout, waitUntil: \"load\" },\n );\n urlChanged = true;\n this.logger.debug(`[nav] URL changed to ${page.url()}`);\n // URL変化後、ハイドレーション/レンダリング完了を待機\n await this.waitForDOMStability();\n } catch {\n this.logger.debug(`[nav] no URL change detected`);\n }\n\n // Stage 3: URL変化なし → スナップショットでSPA遷移を検知\n // URL変化済みの場合は Stage 2 で waitForDOMStability 済みなのでスキップ\n if (!urlChanged) {\n this.logger.debug(\"[nav] checking SPA transition via snapshot diff\");\n const snapshotBefore = await this.snapshot();\n const spaPollEnd = Date.now() + 5000;\n const stageStart = Date.now();\n let spaDetected = false;\n let stableCount = 0;\n\n while (Date.now() < spaPollEnd) {\n await new Promise((r) => setTimeout(r, 300));\n const current = await this.snapshot();\n if (current !== snapshotBefore) {\n spaDetected = true;\n this.logger.debug(\"[nav] SPA transition detected (snapshot changed)\");\n break;\n }\n // 最低1秒はポーリングを継続(遅延APIレスポンスのSPA遷移を逃さない)\n // 1秒経過後、3回連続で変化なければ安定と判定して早期終了\n stableCount++;\n if (Date.now() - stageStart >= 1000 && stableCount >= 3) {\n this.logger.debug(\"[nav] snapshot stable, no SPA transition\");\n break;\n }\n }\n\n if (spaDetected) {\n await this.waitForDOMStability();\n }\n }\n }\n\n /**\n * CDP Screencast + ffmpeg でビューポート全体を録画開始する。\n * タブ切り替えを含む単一動画を生成する。\n * @param outputDir 動画ファイル保存先ディレクトリ\n * @param _url 未使用(後方互換性のため残す)\n */\n async startRecording(outputDir: string, _url?: string): Promise<void> {\n if (this.isScreencastRecording) {\n return;\n }\n\n // ffmpeg 存在チェック\n try {\n execSync(\"which ffmpeg\", { stdio: \"ignore\" });\n } catch {\n this.logger.warn(\n \"ffmpeg が見つかりません。--video を使用するには ffmpeg をインストールしてください\",\n );\n return;\n }\n\n await mkdir(outputDir, { recursive: true });\n\n const now = new Date();\n const pad = (n: number) => String(n).padStart(2, \"0\");\n const ts = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}T${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;\n const outputPath = join(outputDir, `recording-${ts}.webm`);\n this.screencastOutputPath = outputPath;\n\n // ffmpeg プロセス起動: MJPEG over pipe → WebM (VP8)\n // ビットレート 500kbps + CRF 30 で品質と圧縮のバランスを確保\n this.ffmpegProcess = spawn(\"ffmpeg\", [\n \"-f\", \"image2pipe\",\n \"-framerate\", String(SCREENCAST_FPS),\n \"-vcodec\", \"mjpeg\",\n \"-i\", \"pipe:0\",\n \"-c:v\", \"libvpx\",\n \"-b:v\", \"500k\",\n \"-crf\", \"30\",\n \"-auto-alt-ref\", \"0\",\n \"-y\",\n outputPath,\n ], { stdio: [\"pipe\", \"ignore\", \"ignore\"] });\n\n this.ffmpegProcess.on(\"error\", (err) => {\n this.logger.warn(`ffmpeg プロセスエラー: ${err.message}`);\n });\n\n // screencast フレームコールバック: 最新フレームを保持\n this.latestFrame = null;\n const frameCallback = (frame: { data: string }) => {\n this.latestFrame = Buffer.from(frame.data, \"base64\");\n };\n\n // CDP Screencast 開始\n try {\n await this.browser.startScreencast(frameCallback, {\n format: \"jpeg\",\n quality: 80,\n });\n } catch (err) {\n this.logger.warn(\n `screencast 開始に失敗: ${err instanceof Error ? err.message : String(err)}`,\n );\n this.cleanupFfmpeg();\n return;\n }\n\n this.isScreencastRecording = true;\n\n // フレームポンプ: 一定間隔で latestFrame を ffmpeg stdin に書き込み\n this.framePumpInterval = setInterval(() => {\n if (this.latestFrame && this.ffmpegProcess?.stdin?.writable) {\n try {\n this.ffmpegProcess.stdin.write(this.latestFrame);\n } catch {\n // 書き込み失敗は無視(ffmpeg 終了中など)\n }\n }\n }, FRAME_PUMP_INTERVAL_MS);\n\n // screencast 回復ポーリング: タブ切替で停止した screencast を再開\n this.screencastRecoveryInterval = setInterval(async () => {\n if (!this.isScreencastRecording) return;\n try {\n if (!this.browser.isScreencasting()) {\n this.logger.debug(\"[screencast] 回復: screencast を再開\");\n await this.browser.startScreencast(frameCallback, {\n format: \"jpeg\",\n quality: 80,\n });\n }\n } catch {\n // 回復失敗は次回ポーリングでリトライ\n }\n }, SCREENCAST_RECOVERY_INTERVAL_MS);\n }\n\n /**\n * ffmpeg プロセスをクリーンアップする内部ヘルパー。\n */\n private cleanupFfmpeg(): void {\n if (this.ffmpegProcess) {\n try {\n this.ffmpegProcess.stdin?.end();\n this.ffmpegProcess.kill();\n } catch {\n // kill 失敗は無視\n }\n this.ffmpegProcess = null;\n }\n this.screencastOutputPath = null;\n }\n\n /**\n * 録画を停止し、動画ファイルパスを返す。\n * @returns paths: 保存された動画ファイルパス一覧, frames: 0(CDP screencast ではフレーム数不明)\n */\n async stopRecording(): Promise<{ paths: string[]; frames: number; error?: string }> {\n if (!this.isScreencastRecording) {\n return { paths: [], frames: 0, error: \"No recording in progress\" };\n }\n\n // フレームポンプ停止\n if (this.framePumpInterval) {\n clearInterval(this.framePumpInterval);\n this.framePumpInterval = null;\n }\n\n // screencast 回復ポーリング停止\n if (this.screencastRecoveryInterval) {\n clearInterval(this.screencastRecoveryInterval);\n this.screencastRecoveryInterval = null;\n }\n\n // CDP Screencast 停止\n try {\n await this.browser.stopScreencast();\n } catch {\n // 停止失敗は無視\n }\n\n const outputPath = this.screencastOutputPath;\n this.isScreencastRecording = false;\n this.latestFrame = null;\n\n // ffmpeg stdin を閉じてプロセス終了を待機\n if (this.ffmpegProcess) {\n const ffmpeg = this.ffmpegProcess;\n this.ffmpegProcess = null;\n\n await new Promise<void>((resolve) => {\n const timeout = setTimeout(() => {\n ffmpeg.kill(\"SIGKILL\");\n resolve();\n }, 10000);\n\n ffmpeg.on(\"close\", () => {\n clearTimeout(timeout);\n resolve();\n });\n\n try {\n ffmpeg.stdin?.end();\n } catch {\n clearTimeout(timeout);\n resolve();\n }\n });\n }\n\n this.screencastOutputPath = null;\n\n if (outputPath) {\n return { paths: [outputPath], frames: 0 };\n }\n return { paths: [], frames: 0 };\n }\n\n /**\n * 現在録画中かどうかを返す。\n */\n isRecording(): boolean {\n return this.isScreencastRecording;\n }\n\n async close(): Promise<void> {\n // 録画中なら停止\n if (this.isScreencastRecording) {\n try {\n await this.stopRecording();\n } catch {\n // 停止失敗は無視\n }\n }\n // ffmpeg プロセスが残っていたらクリーンアップ\n this.cleanupFfmpeg();\n await this.browser.close();\n }\n\n /**\n * ExplorationAction を適切なコマンドにディスパッチ\n */\n async executeStep(step: ExplorationAction): Promise<StepResult> {\n const start = Date.now();\n try {\n let output = \"\";\n switch (step.action) {\n case \"click\":\n await this.click(step.selector!);\n break;\n case \"fill\":\n await this.fill(step.selector!, step.value || \"\");\n break;\n case \"type\":\n await this.type(step.selector!, step.value || \"\");\n break;\n case \"select\":\n await this.select(step.selector!, step.value || \"\");\n break;\n case \"check\":\n await this.check(step.selector!);\n break;\n case \"uncheck\":\n await this.uncheck(step.selector!);\n break;\n case \"navigate\":\n await this.navigate(step.value!);\n break;\n case \"wait\":\n await this.wait(Number(step.value) || 1000);\n break;\n case \"scroll\":\n await this.scroll(step.value || \"down\");\n break;\n case \"extract\": {\n const script = step.value || step.script || \"\";\n if (script) {\n const result = await this.evaluate(script);\n output = typeof result === \"string\" ? result : JSON.stringify(result);\n }\n break;\n }\n case \"download\": {\n const downloadPath = step.downloadPath || `/tmp/download-${Date.now()}.bin`;\n await this.download(step.selector!, downloadPath);\n output = downloadPath;\n break;\n }\n default:\n output = `Unknown action: ${step.action}`;\n }\n return {\n success: true,\n output,\n durationMs: Date.now() - start,\n };\n } catch (error) {\n return {\n success: false,\n output: \"\",\n error: error instanceof Error ? error.message : String(error),\n durationMs: Date.now() - start,\n };\n }\n }\n}\n","import {\n chromium,\n firefox,\n webkit,\n devices,\n type Browser,\n type BrowserContext,\n type Page,\n type Frame,\n type Dialog,\n type Request,\n type Route,\n type Locator,\n type CDPSession,\n type Video,\n} from 'playwright-core';\nimport path from 'node:path';\nimport os from 'node:os';\nimport { existsSync, mkdirSync, rmSync, readFileSync, statSync } from 'node:fs';\nimport { writeFile, mkdir } from 'node:fs/promises';\nimport type { LaunchCommand, TraceEvent } from './types.js';\n/**\n * Minimal InspectServer interface (inspect-server.ts is CLI-only, not included in engine).\n * Only the stop() method is needed by BrowserManager.\n */\ninterface InspectServer {\n stop(): void;\n}\nimport { type RefMap, type EnhancedSnapshot, getEnhancedSnapshot, parseRef } from './snapshot.js';\nimport { safeHeaderMerge } from './state-utils.js';\nimport { isDomainAllowed, installDomainFilter, parseDomainList } from './domain-filter.js';\nimport {\n getEncryptionKey,\n isEncryptedPayload,\n decryptData,\n ENCRYPTION_KEY_ENV,\n} from './state-utils.js';\n\n/**\n * Returns the default Playwright timeout in milliseconds for standard operations.\n * Can be overridden via the AGENT_BROWSER_DEFAULT_TIMEOUT environment variable.\n * Default is 25s, which is below the CLI's 30s IPC read timeout to ensure\n * Playwright errors are returned before the CLI gives up with EAGAIN.\n * Recording contexts use a shorter fixed timeout (10s) and are not affected.\n */\nexport function getDefaultTimeout(): number {\n const envValue = process.env.AGENT_BROWSER_DEFAULT_TIMEOUT;\n if (envValue) {\n const parsed = parseInt(envValue, 10);\n if (!isNaN(parsed) && parsed >= 1000) {\n return parsed;\n }\n }\n return 25000;\n}\n\n/**\n * Handles boolean env vars and parsing (e.g., \"true\", \"1\", \"false\", \"0\"),\n * with a default value if not set or invalid\n */\nexport function parseBooleanEnvVar(name: string, defaultValue: boolean): boolean {\n const truthyVals = ['1', 'true'];\n const falsyVals = ['0', 'false'];\n\n if (!Object.hasOwn(process.env, name)) {\n return defaultValue;\n }\n\n const param = process.env[name]!.toLowerCase();\n\n if (truthyVals.includes(param)) {\n return true;\n }\n\n if (falsyVals.includes(param)) {\n return false;\n }\n\n return defaultValue;\n}\n\n// Screencast frame data from CDP\nexport interface ScreencastFrame {\n data: string; // base64 encoded image\n metadata: {\n offsetTop: number;\n pageScaleFactor: number;\n deviceWidth: number;\n deviceHeight: number;\n scrollOffsetX: number;\n scrollOffsetY: number;\n timestamp?: number;\n };\n sessionId: number;\n}\n\n// Screencast options\nexport interface ScreencastOptions {\n format?: 'jpeg' | 'png';\n quality?: number; // 0-100, only for jpeg\n maxWidth?: number;\n maxHeight?: number;\n everyNthFrame?: number;\n}\n\nexport interface NavigateOptions {\n waitUntil?: 'load' | 'domcontentloaded' | 'networkidle';\n headers?: Record<string, string>;\n}\n\nexport type BrowserLaunchOptions = Pick<\n LaunchCommand,\n | 'headless'\n | 'viewport'\n | 'browser'\n | 'headers'\n | 'executablePath'\n | 'cdpPort'\n | 'cdpUrl'\n | 'autoConnect'\n | 'extensions'\n | 'profile'\n | 'storageState'\n | 'proxy'\n | 'args'\n | 'userAgent'\n | 'provider'\n | 'ignoreHTTPSErrors'\n | 'allowFileAccess'\n | 'colorScheme'\n | 'downloadPath'\n | 'allowedDomains'\n | 'autoStateFilePath'\n>;\n\ninterface TrackedRequest {\n url: string;\n method: string;\n headers: Record<string, string>;\n timestamp: number;\n resourceType: string;\n}\n\ninterface ConsoleMessage {\n type: string;\n text: string;\n timestamp: number;\n}\n\ninterface PageError {\n message: string;\n timestamp: number;\n}\n\n/**\n * Manages the Playwright browser lifecycle with multiple tabs/windows\n */\nexport class BrowserManager {\n private browser: Browser | null = null;\n private cdpEndpoint: string | null = null; // stores port number or full URL\n private resolvedWsUrl: string | null = null;\n private isPersistentContext: boolean = false;\n private browserbaseSessionId: string | null = null;\n private browserbaseApiKey: string | null = null;\n private browserUseSessionId: string | null = null;\n private browserUseApiKey: string | null = null;\n private kernelSessionId: string | null = null;\n private kernelApiKey: string | null = null;\n private browserlessStopUrl: string | null = null;\n private contexts: BrowserContext[] = [];\n private pages: Page[] = [];\n private activePageIndex: number = 0;\n private activeFrame: Frame | null = null;\n private dialogHandler: ((dialog: Dialog) => Promise<void>) | null = null;\n private trackedRequests: TrackedRequest[] = [];\n private routes: Map<string, (route: Route) => Promise<void>> = new Map();\n private consoleMessages: ConsoleMessage[] = [];\n private pageErrors: PageError[] = [];\n private isRecordingHar: boolean = false;\n private refMap: RefMap = {};\n private lastSnapshot: string = '';\n private scopedHeaderRoutes: Map<string, (route: Route) => Promise<void>> = new Map();\n private colorScheme: 'light' | 'dark' | 'no-preference' | null = null;\n private downloadPath: string | null = null;\n private allowedDomains: string[] = [];\n private inspectServer: InspectServer | null = null;\n\n stopInspectServer(): void {\n if (this.inspectServer) {\n this.inspectServer.stop();\n this.inspectServer = null;\n }\n }\n\n setInspectServer(server: InspectServer): void {\n this.stopInspectServer();\n this.inspectServer = server;\n }\n\n /**\n * Set the persistent color scheme preference.\n * Applied automatically to all new pages and contexts.\n */\n setColorScheme(scheme: 'light' | 'dark' | 'no-preference' | null): void {\n this.colorScheme = scheme;\n }\n\n // CDP session for screencast and input injection\n private cdpSession: CDPSession | null = null;\n private screencastActive: boolean = false;\n private screencastSessionId: number = 0;\n private frameCallback: ((frame: ScreencastFrame) => void) | null = null;\n private screencastFrameHandler: ((params: any) => void) | null = null;\n\n // Video recording (Playwright native)\n private recordingContext: BrowserContext | null = null;\n private recordingPage: Page | null = null;\n private recordingOutputPath: string = '';\n private recordingTempDir: string = '';\n private launchWarnings: string[] = [];\n\n /**\n * Get and clear launch warnings (e.g., decryption failures)\n */\n getAndClearWarnings(): string[] {\n const warnings = this.launchWarnings;\n this.launchWarnings = [];\n return warnings;\n }\n\n // CDP profiling state\n private static readonly MAX_PROFILE_EVENTS = 5_000_000;\n private profilingActive: boolean = false;\n private profileChunks: TraceEvent[] = [];\n private profileEventsDropped: boolean = false;\n private profileCompleteResolver: (() => void) | null = null;\n private profileDataHandler: ((params: { value?: TraceEvent[] }) => void) | null = null;\n private profileCompleteHandler: (() => void) | null = null;\n\n /**\n * Check if browser is launched\n */\n isLaunched(): boolean {\n return this.browser !== null || this.isPersistentContext;\n }\n\n getCdpUrl(): string | null {\n if (this.resolvedWsUrl) return this.resolvedWsUrl;\n if (this.cdpEndpoint?.startsWith('ws://') || this.cdpEndpoint?.startsWith('wss://')) {\n return this.cdpEndpoint;\n }\n try {\n return (this.browser as any)?.wsEndpoint?.() ?? null;\n } catch {\n return null;\n }\n }\n\n /**\n * Get enhanced snapshot with refs and cache the ref map\n */\n async getSnapshot(options?: {\n interactive?: boolean;\n cursor?: boolean;\n maxDepth?: number;\n compact?: boolean;\n selector?: string;\n }): Promise<EnhancedSnapshot> {\n const page = this.getPage();\n const snapshot = await getEnhancedSnapshot(page, options);\n this.refMap = snapshot.refs;\n this.lastSnapshot = snapshot.tree;\n return snapshot;\n }\n\n /**\n * Get the last snapshot tree text (empty string if no snapshot has been taken)\n */\n getLastSnapshot(): string {\n return this.lastSnapshot;\n }\n\n /**\n * Update the stored snapshot (used by diff to keep the baseline current)\n */\n setLastSnapshot(snapshot: string): void {\n this.lastSnapshot = snapshot;\n }\n\n /**\n * Get the cached ref map from last snapshot\n */\n getRefMap(): RefMap {\n return this.refMap;\n }\n\n /**\n * Get a locator from a ref (e.g., \"e1\", \"@e1\", \"ref=e1\")\n * Returns null if ref doesn't exist or is invalid\n */\n getLocatorFromRef(refArg: string): Locator | null {\n const ref = parseRef(refArg);\n if (!ref) return null;\n\n const refData = this.refMap[ref];\n if (!refData) return null;\n\n const page = this.getPage();\n\n // Check if this is a cursor-interactive element (uses CSS selector, not ARIA role)\n // These have pseudo-roles 'clickable' or 'focusable' and a CSS selector\n if (refData.role === 'clickable' || refData.role === 'focusable') {\n // The selector is a CSS selector, use it directly\n return page.locator(refData.selector);\n }\n\n // Build locator with exact: true to avoid substring matches\n let locator: Locator = page.getByRole(refData.role as any, {\n name: refData.name,\n exact: true,\n });\n\n // If an nth index is stored (for disambiguation), use it\n if (refData.nth !== undefined) {\n locator = locator.nth(refData.nth);\n }\n\n return locator;\n }\n\n /**\n * Check if a selector looks like a ref\n */\n isRef(selector: string): boolean {\n return parseRef(selector) !== null;\n }\n\n /**\n * Install the domain filter on a context if an allowlist is configured.\n * Should be called before any pages navigate on the context.\n */\n private async ensureDomainFilter(context: BrowserContext): Promise<void> {\n if (this.allowedDomains.length > 0) {\n await installDomainFilter(context, this.allowedDomains);\n }\n }\n\n /**\n * After installing the domain filter, verify existing pages are on allowed\n * domains. Pages that pre-date the filter (e.g. CDP/cloud connect) may have\n * already navigated to disallowed domains. Navigate them to about:blank.\n */\n private async sanitizeExistingPages(pages: Page[]): Promise<void> {\n if (this.allowedDomains.length === 0) return;\n for (const page of pages) {\n const url = page.url();\n if (!url || url === 'about:blank') continue;\n try {\n const hostname = new URL(url).hostname.toLowerCase();\n if (!isDomainAllowed(hostname, this.allowedDomains)) {\n await page.goto('about:blank');\n }\n } catch {\n await page.goto('about:blank').catch(() => {});\n }\n }\n }\n\n /**\n * Check if a URL is allowed by the domain allowlist.\n * Throws if the URL's domain is blocked. No-op if no allowlist is set.\n * Blocks non-http(s) schemes and unparseable URLs by default.\n */\n checkDomainAllowed(url: string): void {\n if (this.allowedDomains.length === 0) return;\n\n if (!url.startsWith('http://') && !url.startsWith('https://')) {\n throw new Error(`Navigation blocked: non-http(s) scheme in URL \"${url}\"`);\n }\n\n let hostname: string;\n try {\n hostname = new URL(url).hostname.toLowerCase();\n } catch {\n throw new Error(`Navigation blocked: unable to parse URL \"${url}\"`);\n }\n\n if (!isDomainAllowed(hostname, this.allowedDomains)) {\n throw new Error(`Navigation blocked: ${hostname} is not in the allowed domains list`);\n }\n }\n\n /**\n * Get locator - supports both refs and regular selectors\n */\n getLocator(selectorOrRef: string): Locator {\n // Check if it's a ref first\n const locator = this.getLocatorFromRef(selectorOrRef);\n if (locator) return locator;\n\n // Otherwise treat as regular selector\n const page = this.getPage();\n return page.locator(selectorOrRef);\n }\n\n /**\n * Check if the browser has any usable pages\n */\n hasPages(): boolean {\n return this.pages.length > 0;\n }\n\n /**\n * Ensure at least one page exists. If the browser is launched but all pages\n * were closed (stale session), creates a new page on the existing context.\n * No-op if pages already exist.\n */\n async ensurePage(): Promise<void> {\n if (this.pages.length > 0) return;\n if (!this.browser && !this.isPersistentContext) return;\n\n // Use the last existing context, or create a new one\n let context: BrowserContext;\n if (this.contexts.length > 0) {\n context = this.contexts[this.contexts.length - 1];\n } else if (this.browser) {\n context = await this.browser.newContext({\n ...(this.colorScheme && { colorScheme: this.colorScheme }),\n });\n context.setDefaultTimeout(getDefaultTimeout());\n this.contexts.push(context);\n this.setupContextTracking(context);\n await this.ensureDomainFilter(context);\n } else {\n return;\n }\n\n const page = await context.newPage();\n if (!this.pages.includes(page)) {\n this.pages.push(page);\n this.setupPageTracking(page);\n }\n this.activePageIndex = this.pages.length - 1;\n }\n\n /**\n * Get the current active page, throws if not launched\n */\n getPage(): Page {\n if (this.pages.length === 0) {\n throw new Error('Browser not launched. Call launch first.');\n }\n return this.pages[this.activePageIndex];\n }\n\n /**\n * Get the current frame (or page's main frame if no frame is selected)\n */\n getFrame(): Frame {\n if (this.activeFrame) {\n return this.activeFrame;\n }\n return this.getPage().mainFrame();\n }\n\n /**\n * Switch to a frame by selector, name, or URL\n */\n async switchToFrame(options: { selector?: string; name?: string; url?: string }): Promise<void> {\n const page = this.getPage();\n\n if (options.selector) {\n const frameElement = await page.$(options.selector);\n if (!frameElement) {\n throw new Error(`Frame not found: ${options.selector}`);\n }\n const frame = await frameElement.contentFrame();\n if (!frame) {\n throw new Error(`Element is not a frame: ${options.selector}`);\n }\n this.activeFrame = frame;\n } else if (options.name) {\n const frame = page.frame({ name: options.name });\n if (!frame) {\n throw new Error(`Frame not found with name: ${options.name}`);\n }\n this.activeFrame = frame;\n } else if (options.url) {\n const frame = page.frame({ url: options.url });\n if (!frame) {\n throw new Error(`Frame not found with URL: ${options.url}`);\n }\n this.activeFrame = frame;\n }\n }\n\n /**\n * Navigate the active page to a URL and return the resolved URL + title.\n * If the browser is launched but all pages have been closed, a new page is\n * created automatically before navigating (stale-session recovery).\n */\n async navigate(\n url: string,\n options: NavigateOptions = {}\n ): Promise<{ url: string; title: string }> {\n this.checkDomainAllowed(url);\n await this.ensurePage();\n\n if (options.headers && Object.keys(options.headers).length > 0) {\n await this.setScopedHeaders(url, options.headers);\n }\n\n const page = this.getPage();\n await page.goto(url, {\n waitUntil: options.waitUntil ?? 'load',\n });\n\n return {\n url: page.url(),\n title: await page.title(),\n };\n }\n\n /**\n * Get the active page URL.\n */\n async getUrl(): Promise<string> {\n await this.ensurePage();\n return this.getPage().url();\n }\n\n /**\n * Get the active page title.\n */\n async getTitle(): Promise<string> {\n await this.ensurePage();\n return this.getPage().title();\n }\n\n /**\n * Switch back to main frame\n */\n switchToMainFrame(): void {\n this.activeFrame = null;\n }\n\n /**\n * Set up dialog handler\n */\n setDialogHandler(response: 'accept' | 'dismiss', promptText?: string): void {\n const page = this.getPage();\n\n // Remove existing handler if any\n if (this.dialogHandler) {\n page.removeListener('dialog', this.dialogHandler);\n }\n\n this.dialogHandler = async (dialog: Dialog) => {\n if (response === 'accept') {\n await dialog.accept(promptText);\n } else {\n await dialog.dismiss();\n }\n };\n\n page.on('dialog', this.dialogHandler);\n }\n\n /**\n * Clear dialog handler\n */\n clearDialogHandler(): void {\n if (this.dialogHandler) {\n const page = this.getPage();\n page.removeListener('dialog', this.dialogHandler);\n this.dialogHandler = null;\n }\n }\n\n /**\n * Start tracking requests\n */\n startRequestTracking(): void {\n const page = this.getPage();\n page.on('request', (request: Request) => {\n this.trackedRequests.push({\n url: request.url(),\n method: request.method(),\n headers: request.headers(),\n timestamp: Date.now(),\n resourceType: request.resourceType(),\n });\n });\n }\n\n /**\n * Get tracked requests\n */\n getRequests(filter?: string): TrackedRequest[] {\n if (filter) {\n return this.trackedRequests.filter((r) => r.url.includes(filter));\n }\n return this.trackedRequests;\n }\n\n /**\n * Clear tracked requests\n */\n clearRequests(): void {\n this.trackedRequests = [];\n }\n\n /**\n * Add a route to intercept requests\n */\n async addRoute(\n url: string,\n options: {\n response?: {\n status?: number;\n body?: string;\n contentType?: string;\n headers?: Record<string, string>;\n };\n abort?: boolean;\n }\n ): Promise<void> {\n const page = this.getPage();\n\n const handler = async (route: Route) => {\n if (options.abort) {\n await route.abort();\n } else if (options.response) {\n await route.fulfill({\n status: options.response.status ?? 200,\n body: options.response.body ?? '',\n contentType: options.response.contentType ?? 'text/plain',\n headers: options.response.headers,\n });\n } else {\n await route.continue();\n }\n };\n\n this.routes.set(url, handler);\n await page.route(url, handler);\n }\n\n /**\n * Remove a route\n */\n async removeRoute(url?: string): Promise<void> {\n const page = this.getPage();\n\n if (url) {\n const handler = this.routes.get(url);\n if (handler) {\n await page.unroute(url, handler);\n this.routes.delete(url);\n }\n } else {\n // Remove all routes\n for (const [routeUrl, handler] of this.routes) {\n await page.unroute(routeUrl, handler);\n }\n this.routes.clear();\n }\n }\n\n /**\n * Set geolocation\n */\n async setGeolocation(latitude: number, longitude: number, accuracy?: number): Promise<void> {\n const context = this.contexts[0];\n if (context) {\n await context.setGeolocation({ latitude, longitude, accuracy });\n }\n }\n\n /**\n * Set permissions\n */\n async setPermissions(permissions: string[], grant: boolean): Promise<void> {\n const context = this.contexts[0];\n if (context) {\n if (grant) {\n await context.grantPermissions(permissions);\n } else {\n await context.clearPermissions();\n }\n }\n }\n\n /**\n * Set viewport\n */\n async setViewport(width: number, height: number): Promise<void> {\n const page = this.getPage();\n await page.setViewportSize({ width, height });\n }\n\n /**\n * Set device scale factor (devicePixelRatio) via CDP\n * This sets window.devicePixelRatio which affects how the page renders and responds to media queries\n *\n * Note: When using CDP to set deviceScaleFactor, screenshots will be at logical pixel dimensions\n * (viewport size), not physical pixel dimensions (viewport × scale). This is a Playwright limitation\n * when using CDP emulation on existing contexts. For true HiDPI screenshots with physical pixels,\n * deviceScaleFactor must be set at context creation time.\n *\n * Must be called after setViewport to work correctly\n */\n async setDeviceScaleFactor(\n deviceScaleFactor: number,\n width: number,\n height: number,\n mobile: boolean = false\n ): Promise<void> {\n const cdp = await this.getCDPSession();\n await cdp.send('Emulation.setDeviceMetricsOverride', {\n width,\n height,\n deviceScaleFactor,\n mobile,\n });\n }\n\n /**\n * Clear device metrics override to restore default devicePixelRatio\n */\n async clearDeviceMetricsOverride(): Promise<void> {\n const cdp = await this.getCDPSession();\n await cdp.send('Emulation.clearDeviceMetricsOverride');\n }\n\n /**\n * Get device descriptor\n */\n getDevice(deviceName: string): (typeof devices)[keyof typeof devices] | undefined {\n return devices[deviceName as keyof typeof devices];\n }\n\n /**\n * List available devices\n */\n listDevices(): string[] {\n return Object.keys(devices);\n }\n\n /**\n * Start console message tracking\n */\n startConsoleTracking(): void {\n const page = this.getPage();\n page.on('console', (msg) => {\n this.consoleMessages.push({\n type: msg.type(),\n text: msg.text(),\n timestamp: Date.now(),\n });\n });\n }\n\n /**\n * Get console messages\n */\n getConsoleMessages(): ConsoleMessage[] {\n return this.consoleMessages;\n }\n\n /**\n * Clear console messages\n */\n clearConsoleMessages(): void {\n this.consoleMessages = [];\n }\n\n /**\n * Start error tracking\n */\n startErrorTracking(): void {\n const page = this.getPage();\n page.on('pageerror', (error) => {\n this.pageErrors.push({\n message: error.message,\n timestamp: Date.now(),\n });\n });\n }\n\n /**\n * Get page errors\n */\n getPageErrors(): PageError[] {\n return this.pageErrors;\n }\n\n /**\n * Clear page errors\n */\n clearPageErrors(): void {\n this.pageErrors = [];\n }\n\n /**\n * Start HAR recording\n */\n async startHarRecording(): Promise<void> {\n // HAR is started at context level, flag for tracking\n this.isRecordingHar = true;\n }\n\n /**\n * Check if HAR recording\n */\n isHarRecording(): boolean {\n return this.isRecordingHar;\n }\n\n /**\n * Set offline mode\n */\n async setOffline(offline: boolean): Promise<void> {\n const context = this.contexts[0];\n if (context) {\n await context.setOffline(offline);\n }\n }\n\n /**\n * Set extra HTTP headers (global - all requests)\n */\n async setExtraHeaders(headers: Record<string, string>): Promise<void> {\n const context = this.contexts[0];\n if (context) {\n await context.setExtraHTTPHeaders(headers);\n }\n }\n\n /**\n * Set scoped HTTP headers (only for requests matching the origin)\n * Uses route interception to add headers only to matching requests\n */\n async setScopedHeaders(origin: string, headers: Record<string, string>): Promise<void> {\n const page = this.getPage();\n\n // Build URL pattern from origin (e.g., \"api.example.com\" -> \"**://api.example.com/**\")\n // Handle both full URLs and just hostnames\n let urlPattern: string;\n try {\n const url = new URL(origin.startsWith('http') ? origin : `https://${origin}`);\n // Match any protocol, the host, and any path\n urlPattern = `**://${url.host}/**`;\n } catch {\n // If parsing fails, treat as hostname pattern\n urlPattern = `**://${origin}/**`;\n }\n\n // Remove existing route for this origin if any\n const existingHandler = this.scopedHeaderRoutes.get(urlPattern);\n if (existingHandler) {\n await page.unroute(urlPattern, existingHandler);\n }\n\n // Create handler that adds headers to matching requests\n const handler = async (route: Route) => {\n const requestHeaders = route.request().headers();\n await route.continue({\n headers: safeHeaderMerge(requestHeaders, headers),\n });\n };\n\n // Store and register the route\n this.scopedHeaderRoutes.set(urlPattern, handler);\n await page.route(urlPattern, handler);\n }\n\n /**\n * Clear scoped headers for an origin (or all if no origin specified)\n */\n async clearScopedHeaders(origin?: string): Promise<void> {\n const page = this.getPage();\n\n if (origin) {\n let urlPattern: string;\n try {\n const url = new URL(origin.startsWith('http') ? origin : `https://${origin}`);\n urlPattern = `**://${url.host}/**`;\n } catch {\n urlPattern = `**://${origin}/**`;\n }\n\n const handler = this.scopedHeaderRoutes.get(urlPattern);\n if (handler) {\n await page.unroute(urlPattern, handler);\n this.scopedHeaderRoutes.delete(urlPattern);\n }\n } else {\n // Clear all scoped header routes\n for (const [pattern, handler] of this.scopedHeaderRoutes) {\n await page.unroute(pattern, handler);\n }\n this.scopedHeaderRoutes.clear();\n }\n }\n\n /**\n * Start tracing\n */\n async startTracing(options: { screenshots?: boolean; snapshots?: boolean }): Promise<void> {\n const context = this.contexts[0];\n if (context) {\n await context.tracing.start({\n screenshots: options.screenshots ?? true,\n snapshots: options.snapshots ?? true,\n });\n }\n }\n\n /**\n * Stop tracing and save\n */\n async stopTracing(path?: string): Promise<void> {\n const context = this.contexts[0];\n if (context) {\n await context.tracing.stop(path ? { path } : undefined);\n }\n }\n\n /**\n * Get the current browser context (first context)\n */\n getContext(): BrowserContext | null {\n return this.contexts[0] ?? null;\n }\n\n /**\n * Save storage state (cookies, localStorage, etc.)\n */\n async saveStorageState(path: string): Promise<void> {\n const context = this.contexts[0];\n if (context) {\n await context.storageState({ path });\n }\n }\n\n /**\n * Get all pages\n */\n getPages(): Page[] {\n return this.pages;\n }\n\n /**\n * Get current page index\n */\n getActiveIndex(): number {\n return this.activePageIndex;\n }\n\n /**\n * Get the current browser instance\n */\n getBrowser(): Browser | null {\n return this.browser;\n }\n\n /**\n * Check if an existing CDP connection is still alive\n * by verifying we can access browser contexts and that at least one has pages\n */\n private isCdpConnectionAlive(): boolean {\n if (!this.browser) return false;\n try {\n const contexts = this.browser.contexts();\n if (contexts.length === 0) return false;\n return contexts.some((context) => context.pages().length > 0);\n } catch {\n return false;\n }\n }\n\n /**\n * Check if CDP connection needs to be re-established\n */\n private needsCdpReconnect(cdpEndpoint: string): boolean {\n if (!this.browser?.isConnected()) return true;\n if (this.cdpEndpoint !== cdpEndpoint) return true;\n if (!this.isCdpConnectionAlive()) return true;\n return false;\n }\n\n /**\n * Close a Browserbase session via API\n */\n private async closeBrowserbaseSession(sessionId: string, apiKey: string): Promise<void> {\n const response = await fetch(`https://api.browserbase.com/v1/sessions/${sessionId}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-BB-API-Key': apiKey,\n },\n body: JSON.stringify({ status: 'REQUEST_RELEASE' }),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to close Browserbase session: ${response.statusText}`);\n }\n }\n\n /**\n * Close a Browser Use session via API\n */\n private async closeBrowserUseSession(sessionId: string, apiKey: string): Promise<void> {\n const response = await fetch(`https://api.browser-use.com/api/v2/browsers/${sessionId}`, {\n method: 'PATCH',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Browser-Use-API-Key': apiKey,\n },\n body: JSON.stringify({ action: 'stop' }),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to close Browser Use session: ${response.statusText}`);\n }\n }\n\n /**\n * Close a Kernel session via API\n */\n private async closeKernelSession(sessionId: string, apiKey: string | undefined): Promise<void> {\n const headers: Record<string, string> = {};\n if (apiKey) {\n headers['Authorization'] = `Bearer ${apiKey}`;\n }\n const response = await fetch(`https://api.onkernel.com/browsers/${sessionId}`, {\n method: 'DELETE',\n headers,\n });\n\n if (!response.ok) {\n throw new Error(`Failed to close Kernel session: ${response.statusText}`);\n }\n }\n\n /**\n * Close a Browserless session via its stop URL\n */\n private async closeBrowserlessSession(stopUrl: string): Promise<void> {\n const response = await fetch(stopUrl, {\n method: 'DELETE',\n });\n\n if (!response.ok) {\n throw new Error(`Failed to close Browserless session: ${response.statusText}`);\n }\n }\n\n /**\n * Connect to Browserbase remote browser via CDP.\n * Requires BROWSERBASE_API_KEY environment variable.\n */\n private async connectToBrowserbase(): Promise<void> {\n const browserbaseApiKey = process.env.BROWSERBASE_API_KEY;\n\n if (!browserbaseApiKey) {\n throw new Error('BROWSERBASE_API_KEY is required when using browserbase as a provider');\n }\n\n const response = await fetch('https://api.browserbase.com/v1/sessions', {\n method: 'POST',\n headers: {\n 'X-BB-API-Key': browserbaseApiKey,\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to create Browserbase session: ${response.statusText}`);\n }\n\n const session = (await response.json()) as { id: string; connectUrl: string };\n\n const browser = await chromium.connectOverCDP(session.connectUrl).catch(() => {\n throw new Error('Failed to connect to Browserbase session via CDP');\n });\n\n try {\n const contexts = browser.contexts();\n if (contexts.length === 0) {\n throw new Error('No browser context found in Browserbase session');\n }\n\n const context = contexts[0];\n const pages = context.pages();\n const page = pages[0] ?? (await context.newPage());\n\n this.browserbaseSessionId = session.id;\n this.browserbaseApiKey = browserbaseApiKey;\n this.browser = browser;\n context.setDefaultTimeout(getDefaultTimeout());\n this.contexts.push(context);\n this.setupContextTracking(context);\n await this.ensureDomainFilter(context);\n await this.sanitizeExistingPages([page]);\n this.pages.push(page);\n this.activePageIndex = 0;\n this.setupPageTracking(page);\n } catch (error) {\n await this.closeBrowserbaseSession(session.id, browserbaseApiKey).catch((sessionError) => {\n console.error('Failed to close Browserbase session during cleanup:', sessionError);\n });\n throw error;\n }\n }\n\n /**\n * Find or create a Kernel profile by name.\n * Returns the profile object if successful.\n */\n private async findOrCreateKernelProfile(\n profileName: string,\n apiKey: string | undefined\n ): Promise<{ name: string }> {\n const headers: Record<string, string> = {};\n if (apiKey) {\n headers['Authorization'] = `Bearer ${apiKey}`;\n }\n\n // First, try to get the existing profile\n const getResponse = await fetch(\n `https://api.onkernel.com/profiles/${encodeURIComponent(profileName)}`,\n {\n method: 'GET',\n headers,\n }\n );\n\n if (getResponse.ok) {\n // Profile exists, return it\n return { name: profileName };\n }\n\n if (getResponse.status !== 404) {\n throw new Error(`Failed to check Kernel profile: ${getResponse.statusText}`);\n }\n\n // Profile doesn't exist, create it\n const createResponse = await fetch('https://api.onkernel.com/profiles', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n body: JSON.stringify({ name: profileName }),\n });\n\n if (!createResponse.ok) {\n throw new Error(`Failed to create Kernel profile: ${createResponse.statusText}`);\n }\n\n return { name: profileName };\n }\n\n /**\n * Connect to Kernel remote browser via CDP.\n * Uses KERNEL_API_KEY environment variable for authentication when set.\n * When running inside environments with external credential injection\n * (e.g. Vercel Sandbox credentials brokering), the API key can be omitted\n * and auth headers will be injected at the network layer.\n */\n private async connectToKernel(): Promise<void> {\n const kernelApiKey = process.env.KERNEL_API_KEY;\n\n // Find or create profile if KERNEL_PROFILE_NAME is set\n const profileName = process.env.KERNEL_PROFILE_NAME;\n let profileConfig: { profile: { name: string; save_changes: boolean } } | undefined;\n\n if (profileName) {\n await this.findOrCreateKernelProfile(profileName, kernelApiKey);\n profileConfig = {\n profile: {\n name: profileName,\n save_changes: true, // Save cookies/state back to the profile when session ends\n },\n };\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n if (kernelApiKey) {\n headers['Authorization'] = `Bearer ${kernelApiKey}`;\n }\n\n const response = await fetch('https://api.onkernel.com/browsers', {\n method: 'POST',\n headers,\n body: JSON.stringify({\n // Kernel browsers are headful by default with stealth mode available\n // The user can configure these via environment variables if needed\n headless: process.env.KERNEL_HEADLESS?.toLowerCase() === 'true',\n stealth: process.env.KERNEL_STEALTH?.toLowerCase() !== 'false', // Default to stealth mode\n timeout_seconds: parseInt(process.env.KERNEL_TIMEOUT_SECONDS || '300', 10),\n // Load and save to a profile if specified\n ...profileConfig,\n }),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to create Kernel session: ${response.statusText}`);\n }\n\n let session: { session_id: string; cdp_ws_url: string };\n try {\n session = (await response.json()) as { session_id: string; cdp_ws_url: string };\n } catch (error) {\n throw new Error(\n `Failed to parse Kernel session response: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n\n if (!session.session_id || !session.cdp_ws_url) {\n throw new Error(\n `Invalid Kernel session response: missing ${!session.session_id ? 'session_id' : 'cdp_ws_url'}`\n );\n }\n\n const browser = await chromium.connectOverCDP(session.cdp_ws_url).catch(() => {\n throw new Error('Failed to connect to Kernel session via CDP');\n });\n\n try {\n const contexts = browser.contexts();\n let context: BrowserContext;\n let page: Page;\n\n // Kernel browsers launch with a default context and page\n if (contexts.length === 0) {\n context = await browser.newContext();\n page = await context.newPage();\n } else {\n context = contexts[0];\n const pages = context.pages();\n page = pages[0] ?? (await context.newPage());\n }\n\n this.kernelSessionId = session.session_id;\n this.kernelApiKey = kernelApiKey ?? null;\n this.browser = browser;\n context.setDefaultTimeout(getDefaultTimeout());\n this.contexts.push(context);\n this.setupContextTracking(context);\n await this.ensureDomainFilter(context);\n await this.sanitizeExistingPages([page]);\n this.pages.push(page);\n this.activePageIndex = 0;\n this.setupPageTracking(page);\n } catch (error) {\n await this.closeKernelSession(session.session_id, kernelApiKey).catch((sessionError) => {\n console.error('Failed to close Kernel session during cleanup:', sessionError);\n });\n throw error;\n }\n }\n\n /**\n * Connect to Browser Use remote browser via CDP.\n * Requires BROWSER_USE_API_KEY environment variable.\n */\n private async connectToBrowserUse(): Promise<void> {\n const browserUseApiKey = process.env.BROWSER_USE_API_KEY;\n if (!browserUseApiKey) {\n throw new Error('BROWSER_USE_API_KEY is required when using browseruse as a provider');\n }\n\n const response = await fetch('https://api.browser-use.com/api/v2/browsers', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-Browser-Use-API-Key': browserUseApiKey,\n },\n body: JSON.stringify({}),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to create Browser Use session: ${response.statusText}`);\n }\n\n let session: { id: string; cdpUrl: string };\n try {\n session = (await response.json()) as { id: string; cdpUrl: string };\n } catch (error) {\n throw new Error(\n `Failed to parse Browser Use session response: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n\n if (!session.id || !session.cdpUrl) {\n throw new Error(\n `Invalid Browser Use session response: missing ${!session.id ? 'id' : 'cdpUrl'}`\n );\n }\n\n const browser = await chromium.connectOverCDP(session.cdpUrl).catch(() => {\n throw new Error('Failed to connect to Browser Use session via CDP');\n });\n\n try {\n const contexts = browser.contexts();\n let context: BrowserContext;\n let page: Page;\n\n if (contexts.length === 0) {\n context = await browser.newContext();\n page = await context.newPage();\n } else {\n context = contexts[0];\n const pages = context.pages();\n page = pages[0] ?? (await context.newPage());\n }\n\n this.browserUseSessionId = session.id;\n this.browserUseApiKey = browserUseApiKey;\n this.browser = browser;\n context.setDefaultTimeout(getDefaultTimeout());\n this.contexts.push(context);\n this.setupContextTracking(context);\n await this.ensureDomainFilter(context);\n await this.sanitizeExistingPages([page]);\n this.pages.push(page);\n this.activePageIndex = 0;\n this.setupPageTracking(page);\n } catch (error) {\n await this.closeBrowserUseSession(session.id, browserUseApiKey).catch((sessionError) => {\n console.error('Failed to close Browser Use session during cleanup:', sessionError);\n });\n throw error;\n }\n }\n\n /**\n * Connect to Browserless remote browser via CDP.\n * Requires BROWSERLESS_API_KEY environment variable.\n */\n private async connectToBrowserless(): Promise<void> {\n const browserlessToken = process.env.BROWSERLESS_API_KEY;\n if (!browserlessToken) {\n throw new Error('BROWSERLESS_API_KEY is required when using browserless as a provider');\n }\n\n const supportedBrowsers = ['chromium', 'chrome'];\n const apiUrl = process.env.BROWSERLESS_API_URL || 'https://production-sfo.browserless.io';\n const browserType = process.env.BROWSERLESS_BROWSER_TYPE || 'chromium';\n const ttl = parseInt(process.env.BROWSERLESS_TTL || '300000', 10);\n const stealth = parseBooleanEnvVar('BROWSERLESS_STEALTH', true);\n\n if (!supportedBrowsers.includes(browserType)) {\n throw new Error(\n `BROWSERLESS_BROWSER_TYPE \"${browserType}\" is not supported. Only ${supportedBrowsers.join(', ')} are allowed.`\n );\n }\n\n const response = await fetch(\n `${apiUrl}/session?token=${encodeURIComponent(browserlessToken)}`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n ttl,\n stealth,\n browser: browserType,\n }),\n }\n );\n\n if (!response.ok) {\n throw new Error(`Failed to create Browserless session: ${response.statusText}`);\n }\n\n let session: { connect: string; stop: string };\n try {\n session = (await response.json()) as { connect: string; stop: string };\n } catch (error) {\n throw new Error(\n `Failed to parse Browserless session response: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n\n if (!session.connect || !session.stop) {\n throw new Error(\n `Invalid Browserless session response: missing ${!session.connect ? 'connect' : 'stop'}`\n );\n }\n\n const browser = await chromium.connectOverCDP(session.connect).catch(() => {\n throw new Error('Failed to connect to Browserless session via CDP');\n });\n\n try {\n const contexts = browser.contexts();\n let context: BrowserContext;\n let page: Page;\n\n if (contexts.length === 0) {\n context = await browser.newContext();\n page = await context.newPage();\n } else {\n context = contexts[0];\n const pages = context.pages();\n page = pages[0] ?? (await context.newPage());\n }\n\n this.browser = browser;\n this.browserlessStopUrl = session.stop;\n context.setDefaultTimeout(getDefaultTimeout());\n this.contexts.push(context);\n this.setupContextTracking(context);\n await this.ensureDomainFilter(context);\n await this.sanitizeExistingPages([page]);\n this.pages.push(page);\n this.activePageIndex = 0;\n this.setupPageTracking(page);\n } catch (error) {\n await this.closeBrowserlessSession(session.stop).catch((sessionError) => {\n console.error('Failed to close Browserless session during cleanup:', sessionError);\n });\n this.browserlessStopUrl = null;\n throw error;\n }\n }\n\n /**\n * Launch the browser with the specified options\n * If already launched, this is a no-op (browser stays open)\n */\n async launch(options: BrowserLaunchOptions): Promise<void> {\n // Determine CDP endpoint: prefer cdpUrl over cdpPort for flexibility\n const cdpEndpoint = options.cdpUrl ?? (options.cdpPort ? String(options.cdpPort) : undefined);\n const hasExtensions = !!options.extensions?.length;\n const hasProfile = !!options.profile;\n const hasStorageState = !!options.storageState;\n\n if (hasExtensions && cdpEndpoint) {\n throw new Error('Extensions cannot be used with CDP connection');\n }\n\n if (hasProfile && cdpEndpoint) {\n throw new Error('Profile cannot be used with CDP connection');\n }\n\n if (hasStorageState && hasProfile) {\n throw new Error(\n 'Storage state cannot be used with profile (profile is already persistent storage)'\n );\n }\n\n if (hasStorageState && hasExtensions) {\n throw new Error(\n 'Storage state cannot be used with extensions (extensions require persistent context)'\n );\n }\n\n if (this.isLaunched()) {\n const needsRelaunch =\n (!cdpEndpoint && !options.autoConnect && this.cdpEndpoint !== null) ||\n (!!cdpEndpoint && this.needsCdpReconnect(cdpEndpoint)) ||\n (!!options.autoConnect && !this.isCdpConnectionAlive());\n if (needsRelaunch) {\n await this.close();\n } else if (options.autoConnect && this.isCdpConnectionAlive()) {\n // Already connected via auto-connect, no need to reconnect\n return;\n } else {\n return;\n }\n }\n\n if (options.colorScheme) {\n this.colorScheme = options.colorScheme;\n }\n\n if (options.downloadPath) {\n this.downloadPath = options.downloadPath;\n }\n\n if (options.allowedDomains && options.allowedDomains.length > 0) {\n this.allowedDomains = options.allowedDomains.map((d: string) => d.toLowerCase());\n } else {\n const envDomains = process.env.AGENT_BROWSER_ALLOWED_DOMAINS;\n if (envDomains) {\n this.allowedDomains = parseDomainList(envDomains);\n }\n }\n\n if (this.downloadPath && (cdpEndpoint || options.autoConnect)) {\n const warning =\n \"--download-path is ignored when connecting via CDP or auto-connect (downloads use the remote browser's configuration)\";\n this.launchWarnings.push(warning);\n console.error(`[WARN] ${warning}`);\n }\n\n if (cdpEndpoint) {\n await this.connectViaCDP(cdpEndpoint);\n return;\n }\n\n if (options.autoConnect) {\n await this.autoConnectViaCDP();\n return;\n }\n\n // Cloud browser providers require explicit opt-in via -p flag or AGENT_BROWSER_PROVIDER env var\n // -p flag takes precedence over env var\n const provider = options.provider ?? process.env.AGENT_BROWSER_PROVIDER;\n if (this.downloadPath && provider) {\n const warning =\n \"--download-path is ignored when using a cloud provider (downloads use the remote browser's configuration)\";\n this.launchWarnings.push(warning);\n console.error(`[WARN] ${warning}`);\n }\n if (provider === 'browserbase') {\n await this.connectToBrowserbase();\n return;\n }\n if (provider === 'browseruse') {\n await this.connectToBrowserUse();\n return;\n }\n\n // Kernel: requires explicit opt-in via -p kernel flag or AGENT_BROWSER_PROVIDER=kernel\n if (provider === 'kernel') {\n await this.connectToKernel();\n return;\n }\n if (provider === 'browserless') {\n await this.connectToBrowserless();\n return;\n }\n\n if (this.downloadPath) {\n const resolved = path.resolve(this.downloadPath);\n const stat = statSync(resolved, { throwIfNoEntry: false });\n if (stat && !stat.isDirectory()) {\n throw new Error(`Download path is not a directory: ${resolved}`);\n }\n if (!stat) {\n try {\n mkdirSync(resolved, { recursive: true });\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n throw new Error(`Cannot create download directory '${resolved}': ${msg}`);\n }\n }\n this.downloadPath = resolved;\n }\n\n const browserType = options.browser ?? 'chromium';\n if (hasExtensions && browserType !== 'chromium') {\n throw new Error('Extensions are only supported in Chromium');\n }\n\n // allowFileAccess is only supported in Chromium\n if (options.allowFileAccess && browserType !== 'chromium') {\n throw new Error('allowFileAccess is only supported in Chromium');\n }\n\n const launcher =\n browserType === 'firefox' ? firefox : browserType === 'webkit' ? webkit : chromium;\n\n // Build base args array with file access flags if enabled\n // --allow-file-access-from-files: allows file:// URLs to read other file:// URLs via XHR/fetch\n // --allow-file-access: allows the browser to access local files in general\n const fileAccessArgs = options.allowFileAccess\n ? ['--allow-file-access-from-files', '--allow-file-access']\n : [];\n const baseArgs = options.args\n ? [...fileAccessArgs, ...options.args]\n : fileAccessArgs.length > 0\n ? fileAccessArgs\n : undefined;\n\n // Auto-detect args that control window size and disable viewport emulation\n // so Playwright doesn't override the browser's own sizing behavior\n const hasWindowSizeArgs = baseArgs?.some(\n (arg) => arg === '--start-maximized' || arg.startsWith('--window-size=')\n );\n const viewport =\n options.viewport !== undefined\n ? options.viewport\n : hasWindowSizeArgs\n ? null\n : { width: 1280, height: 720 };\n\n let context: BrowserContext;\n if (hasExtensions) {\n // Extensions require persistent context in a temp directory\n const extPaths = options.extensions!.join(',');\n const session = process.env.AGENT_BROWSER_SESSION || 'default';\n // Combine extension args with custom args and file access args\n const extArgs = [`--disable-extensions-except=${extPaths}`, `--load-extension=${extPaths}`];\n const allArgs = baseArgs ? [...extArgs, ...baseArgs] : extArgs;\n context = await launcher.launchPersistentContext(\n path.join(os.tmpdir(), `agent-browser-ext-${session}`),\n {\n headless: options.headless ?? true,\n executablePath: options.executablePath,\n args: allArgs,\n viewport,\n extraHTTPHeaders: options.headers,\n userAgent: options.userAgent,\n ...(options.proxy && { proxy: options.proxy }),\n ignoreHTTPSErrors: options.ignoreHTTPSErrors ?? false,\n ...(this.colorScheme && { colorScheme: this.colorScheme }),\n ...(this.downloadPath && { downloadsPath: this.downloadPath }),\n }\n );\n this.isPersistentContext = true;\n } else if (hasProfile) {\n // Profile uses persistent context for durable cookies/storage\n // Expand ~ to home directory since it won't be shell-expanded\n const profilePath = options.profile!.replace(/^~\\//, os.homedir() + '/');\n context = await launcher.launchPersistentContext(profilePath, {\n headless: options.headless ?? true,\n executablePath: options.executablePath,\n args: baseArgs,\n viewport,\n extraHTTPHeaders: options.headers,\n userAgent: options.userAgent,\n ...(options.proxy && { proxy: options.proxy }),\n ignoreHTTPSErrors: options.ignoreHTTPSErrors ?? false,\n ...(this.colorScheme && { colorScheme: this.colorScheme }),\n ...(this.downloadPath && { downloadsPath: this.downloadPath }),\n });\n this.isPersistentContext = true;\n } else {\n // Regular ephemeral browser\n this.browser = await launcher.launch({\n headless: options.headless ?? true,\n executablePath: options.executablePath,\n args: baseArgs,\n ...(this.downloadPath && { downloadsPath: this.downloadPath }),\n });\n this.cdpEndpoint = null;\n this.resolvedWsUrl = null;\n\n // Check for auto-load state file (supports encrypted files)\n let storageState:\n | string\n | {\n cookies: Array<{\n name: string;\n value: string;\n domain: string;\n path: string;\n expires: number;\n httpOnly: boolean;\n secure: boolean;\n sameSite: 'Strict' | 'Lax' | 'None';\n }>;\n origins: Array<{\n origin: string;\n localStorage: Array<{ name: string; value: string }>;\n }>;\n }\n | undefined = options.storageState ? options.storageState : undefined;\n\n if (!storageState && options.autoStateFilePath) {\n try {\n const fs = await import('fs');\n if (fs.existsSync(options.autoStateFilePath)) {\n const content = fs.readFileSync(options.autoStateFilePath, 'utf8');\n const parsed = JSON.parse(content);\n\n if (isEncryptedPayload(parsed)) {\n const key = getEncryptionKey();\n if (key) {\n try {\n const decrypted = decryptData(parsed, key);\n storageState = JSON.parse(decrypted);\n if (process.env.AGENT_BROWSER_DEBUG === '1') {\n console.error(\n `[DEBUG] Auto-loading session state (decrypted): ${options.autoStateFilePath}`\n );\n }\n } catch (decryptErr) {\n const warning =\n 'Failed to decrypt state file - wrong encryption key? Starting fresh.';\n this.launchWarnings.push(warning);\n console.error(`[WARN] ${warning}`);\n if (process.env.AGENT_BROWSER_DEBUG === '1') {\n console.error(`[DEBUG] Decryption error:`, decryptErr);\n }\n }\n } else {\n const warning = `State file is encrypted but ${ENCRYPTION_KEY_ENV} not set - starting fresh`;\n this.launchWarnings.push(warning);\n console.error(`[WARN] ${warning}`);\n }\n } else {\n storageState = options.autoStateFilePath;\n if (process.env.AGENT_BROWSER_DEBUG === '1') {\n console.error(`[DEBUG] Auto-loading session state: ${options.autoStateFilePath}`);\n }\n }\n }\n } catch (err) {\n if (process.env.AGENT_BROWSER_DEBUG === '1') {\n console.error(`[DEBUG] Failed to load state file, starting fresh:`, err);\n }\n }\n }\n\n context = await this.browser.newContext({\n viewport,\n extraHTTPHeaders: options.headers,\n userAgent: options.userAgent,\n storageState,\n ...(options.proxy && { proxy: options.proxy }),\n ignoreHTTPSErrors: options.ignoreHTTPSErrors ?? false,\n ...(this.colorScheme && { colorScheme: this.colorScheme }),\n });\n }\n\n context.setDefaultTimeout(getDefaultTimeout());\n this.contexts.push(context);\n this.setupContextTracking(context);\n await this.ensureDomainFilter(context);\n\n const page = context.pages()[0] ?? (await context.newPage());\n await this.sanitizeExistingPages([page]);\n // Only add if not already tracked (setupContextTracking may have already added it via 'page' event)\n if (!this.pages.includes(page)) {\n this.pages.push(page);\n this.setupPageTracking(page);\n }\n this.activePageIndex = this.pages.length > 0 ? this.pages.length - 1 : 0;\n }\n\n /**\n * Connect to a running browser via CDP (Chrome DevTools Protocol)\n * @param cdpEndpoint Either a port number (as string) or a full WebSocket URL (ws:// or wss://)\n */\n private async connectViaCDP(\n cdpEndpoint: string | undefined,\n options?: { timeout?: number }\n ): Promise<void> {\n if (!cdpEndpoint) {\n throw new Error('CDP endpoint is required for CDP connection');\n }\n\n // Determine the connection URL:\n // - If it starts with ws://, wss://, http://, or https://, use it directly\n // - If it's a numeric string (e.g., \"9222\"), treat as port for localhost\n // - Otherwise, treat it as a port number for localhost\n let cdpUrl: string;\n if (\n cdpEndpoint.startsWith('ws://') ||\n cdpEndpoint.startsWith('wss://') ||\n cdpEndpoint.startsWith('http://') ||\n cdpEndpoint.startsWith('https://')\n ) {\n cdpUrl = cdpEndpoint;\n } else if (/^\\d+$/.test(cdpEndpoint)) {\n // Numeric string - treat as port number (handles JSON serialization quirks)\n cdpUrl = `http://127.0.0.1:${cdpEndpoint}`;\n } else {\n // Unknown format - still try as port for backward compatibility\n cdpUrl = `http://127.0.0.1:${cdpEndpoint}`;\n }\n\n const browser = await chromium\n .connectOverCDP(cdpUrl, { timeout: options?.timeout })\n .catch(() => {\n throw new Error(\n `Failed to connect via CDP to ${cdpUrl}. ` +\n (cdpUrl.includes('127.0.0.1')\n ? `Make sure the app is running with --remote-debugging-port=${cdpEndpoint}`\n : 'Make sure the remote browser is accessible and the URL is correct.')\n );\n });\n\n // Validate and set up state, cleaning up browser connection if anything fails\n try {\n const contexts = browser.contexts();\n if (contexts.length === 0) {\n throw new Error('No browser context found. Make sure the app has an open window.');\n }\n\n // Filter out pages with empty URLs, which can cause Playwright to hang\n const allPages = contexts.flatMap((context) => context.pages()).filter((page) => page.url());\n\n if (allPages.length === 0) {\n throw new Error('No page found. Make sure the app has loaded content.');\n }\n\n // All validation passed - commit state\n this.browser = browser;\n this.cdpEndpoint = cdpEndpoint;\n\n let resolvedWs: string | null = null;\n try {\n resolvedWs = (browser as any).wsEndpoint?.() ?? null;\n } catch (err) {\n console.error('[inspect] wsEndpoint() failed:', err);\n }\n if (!resolvedWs && (cdpUrl.startsWith('http://') || cdpUrl.startsWith('https://'))) {\n try {\n const resp = await fetch(`${cdpUrl}/json/version`);\n const info: any = await resp.json();\n resolvedWs = info.webSocketDebuggerUrl ?? null;\n } catch (err) {\n console.error('[inspect] /json/version fetch failed:', err);\n }\n }\n this.resolvedWsUrl = resolvedWs;\n\n for (const context of contexts) {\n context.setDefaultTimeout(getDefaultTimeout());\n this.contexts.push(context);\n this.setupContextTracking(context);\n await this.ensureDomainFilter(context);\n }\n\n await this.sanitizeExistingPages(allPages);\n\n for (const page of allPages) {\n this.pages.push(page);\n this.setupPageTracking(page);\n }\n\n this.activePageIndex = 0;\n } catch (error) {\n // Clean up browser connection if validation or setup failed\n await browser.close().catch(() => {});\n throw error;\n }\n }\n\n /**\n * Get Chrome's default user data directory paths for the current platform.\n * Returns an array of candidate paths to check (stable, then beta/canary).\n */\n private getChromeUserDataDirs(): string[] {\n const home = os.homedir();\n const platform = os.platform();\n\n if (platform === 'darwin') {\n return [\n path.join(home, 'Library', 'Application Support', 'Google', 'Chrome'),\n path.join(home, 'Library', 'Application Support', 'Google', 'Chrome Canary'),\n path.join(home, 'Library', 'Application Support', 'Chromium'),\n ];\n } else if (platform === 'win32') {\n const localAppData = process.env.LOCALAPPDATA ?? path.join(home, 'AppData', 'Local');\n return [\n path.join(localAppData, 'Google', 'Chrome', 'User Data'),\n path.join(localAppData, 'Google', 'Chrome SxS', 'User Data'),\n path.join(localAppData, 'Chromium', 'User Data'),\n ];\n } else {\n // Linux\n return [\n path.join(home, '.config', 'google-chrome'),\n path.join(home, '.config', 'google-chrome-unstable'),\n path.join(home, '.config', 'chromium'),\n ];\n }\n }\n\n /**\n * Try to read the DevToolsActivePort file from a Chrome user data directory.\n * Returns { port, wsPath } if found, or null if not available.\n */\n private readDevToolsActivePort(userDataDir: string): { port: number; wsPath: string } | null {\n const filePath = path.join(userDataDir, 'DevToolsActivePort');\n try {\n if (!existsSync(filePath)) return null;\n const content = readFileSync(filePath, 'utf-8').trim();\n const lines = content.split('\\n');\n if (lines.length < 2) return null;\n\n const port = parseInt(lines[0].trim(), 10);\n const wsPath = lines[1].trim();\n\n if (isNaN(port) || port <= 0 || port > 65535) return null;\n if (!wsPath) return null;\n\n return { port, wsPath };\n } catch {\n return null;\n }\n }\n\n /**\n * Try to discover a Chrome CDP endpoint by querying an HTTP debug port.\n * Returns the WebSocket debugger URL if available.\n */\n private async probeDebugPort(port: number): Promise<string | null> {\n try {\n const response = await fetch(`http://127.0.0.1:${port}/json/version`, {\n signal: AbortSignal.timeout(2000),\n });\n if (!response.ok) return null;\n const data = (await response.json()) as { webSocketDebuggerUrl?: string };\n return data.webSocketDebuggerUrl ?? null;\n } catch {\n return null;\n }\n }\n\n /**\n * Auto-discover and connect to a running Chrome/Chromium instance.\n *\n * Discovery strategy:\n * 1. Read DevToolsActivePort from Chrome's default user data directories\n * 2. If found, connect using the port and WebSocket path from that file\n * 3. If not found, probe common debugging ports (9222, 9229)\n * 4. If a port responds, connect via CDP\n */\n private async autoConnectViaCDP(): Promise<void> {\n // Strategy 1: Check DevToolsActivePort files\n const userDataDirs = this.getChromeUserDataDirs();\n for (const dir of userDataDirs) {\n const activePort = this.readDevToolsActivePort(dir);\n if (activePort) {\n // Try HTTP discovery first (works with --remote-debugging-port mode)\n const wsUrl = await this.probeDebugPort(activePort.port);\n if (wsUrl) {\n await this.connectViaCDP(wsUrl);\n return;\n }\n // HTTP probe failed -- Chrome M144+ chrome://inspect remote debugging uses a\n // WebSocket-only server with no HTTP endpoints. Connect using the WebSocket\n // path read directly from DevToolsActivePort.\n const directWsUrl = `ws://127.0.0.1:${activePort.port}${activePort.wsPath}`;\n try {\n if (process.env.AGENT_BROWSER_DEBUG === '1') {\n console.error(\n `[DEBUG] HTTP probe failed on port ${activePort.port}, ` +\n `attempting direct WebSocket connection to ${directWsUrl}`\n );\n }\n await this.connectViaCDP(directWsUrl, { timeout: 60_000 });\n return;\n } catch {\n // Direct WebSocket also failed, try next directory\n }\n }\n }\n\n // Strategy 2: Probe common debugging ports\n const commonPorts = [9222, 9229];\n for (const port of commonPorts) {\n const wsUrl = await this.probeDebugPort(port);\n if (wsUrl) {\n await this.connectViaCDP(wsUrl);\n return;\n }\n }\n\n // Nothing found\n const platform = os.platform();\n let hint: string;\n if (platform === 'darwin') {\n hint =\n 'Start Chrome with: /Applications/Google\\\\ Chrome.app/Contents/MacOS/Google\\\\ Chrome --remote-debugging-port=9222\\n' +\n 'Or enable remote debugging in Chrome 144+ at chrome://inspect/#remote-debugging';\n } else if (platform === 'win32') {\n hint =\n 'Start Chrome with: chrome.exe --remote-debugging-port=9222\\n' +\n 'Or enable remote debugging in Chrome 144+ at chrome://inspect/#remote-debugging';\n } else {\n hint =\n 'Start Chrome with: google-chrome --remote-debugging-port=9222\\n' +\n 'Or enable remote debugging in Chrome 144+ at chrome://inspect/#remote-debugging';\n }\n\n throw new Error(`No running Chrome instance with remote debugging found.\\n${hint}`);\n }\n\n /**\n * Set up console, error, and close tracking for a page\n */\n private setupPageTracking(page: Page): void {\n if (this.colorScheme) {\n page.emulateMedia({ colorScheme: this.colorScheme }).catch(() => {});\n }\n\n page.on('console', (msg) => {\n this.consoleMessages.push({\n type: msg.type(),\n text: msg.text(),\n timestamp: Date.now(),\n });\n });\n\n page.on('pageerror', (error) => {\n this.pageErrors.push({\n message: error.message,\n timestamp: Date.now(),\n });\n });\n\n page.on('close', () => {\n const index = this.pages.indexOf(page);\n if (index !== -1) {\n this.pages.splice(index, 1);\n if (this.activePageIndex >= this.pages.length) {\n this.activePageIndex = Math.max(0, this.pages.length - 1);\n }\n }\n });\n }\n\n /**\n * Set up tracking for new pages in a context (for CDP connections and popups/new tabs)\n * This handles pages created externally (e.g., via target=\"_blank\" links, window.open)\n */\n private setupContextTracking(context: BrowserContext): void {\n context.on('page', (page) => {\n // Only add if not already tracked (avoids duplicates when newTab() creates pages)\n if (!this.pages.includes(page)) {\n this.pages.push(page);\n this.setupPageTracking(page);\n }\n\n // Auto-switch to the newly opened tab so subsequent commands target it.\n // For tabs created via newTab()/newWindow(), this is redundant (they set activePageIndex after),\n // but for externally opened tabs (window.open, target=\"_blank\"), this ensures the active tab\n // stays in sync with the browser.\n const newIndex = this.pages.indexOf(page);\n if (newIndex !== -1 && newIndex !== this.activePageIndex) {\n this.activePageIndex = newIndex;\n // Invalidate CDP session since the active page changed\n this.invalidateCDPSession().catch(() => {});\n }\n });\n }\n\n /**\n * Create a new tab in the current context\n */\n async newTab(): Promise<{ index: number; total: number }> {\n if (!this.isLaunched() || this.contexts.length === 0) {\n throw new Error('Browser not launched');\n }\n\n // Invalidate CDP session since we're switching to a new page\n await this.invalidateCDPSession();\n\n const context = this.contexts[0]; // Use first context for tabs\n const page = await context.newPage();\n // Only add if not already tracked (setupContextTracking may have already added it via 'page' event)\n if (!this.pages.includes(page)) {\n this.pages.push(page);\n this.setupPageTracking(page);\n }\n this.activePageIndex = this.pages.length - 1;\n\n return { index: this.activePageIndex, total: this.pages.length };\n }\n\n /**\n * Create a new window (new context)\n */\n async newWindow(viewport?: { width: number; height: number } | null): Promise<{\n index: number;\n total: number;\n }> {\n if (!this.browser) {\n throw new Error(\n this.isPersistentContext\n ? 'newWindow is not supported in extension (persistent context) mode'\n : 'Browser not launched'\n );\n }\n\n const context = await this.browser.newContext({\n viewport: viewport === undefined ? { width: 1280, height: 720 } : viewport,\n ...(this.colorScheme && { colorScheme: this.colorScheme }),\n });\n context.setDefaultTimeout(getDefaultTimeout());\n this.contexts.push(context);\n this.setupContextTracking(context);\n await this.ensureDomainFilter(context);\n\n const page = await context.newPage();\n // Only add if not already tracked (setupContextTracking may have already added it via 'page' event)\n if (!this.pages.includes(page)) {\n this.pages.push(page);\n this.setupPageTracking(page);\n }\n this.activePageIndex = this.pages.length - 1;\n\n return { index: this.activePageIndex, total: this.pages.length };\n }\n\n /**\n * Invalidate the current CDP session (must be called before switching pages)\n * This ensures screencast and input injection work correctly after tab switch\n */\n private async invalidateCDPSession(): Promise<void> {\n // Stop screencast if active (it's tied to the current page's CDP session)\n if (this.screencastActive) {\n await this.stopScreencast();\n }\n\n // Detach and clear the CDP session\n if (this.cdpSession) {\n await this.cdpSession.detach().catch(() => {});\n this.cdpSession = null;\n }\n }\n\n /**\n * Switch to a specific tab/page by index\n */\n async switchTo(index: number): Promise<{ index: number; url: string; title: string }> {\n if (index < 0 || index >= this.pages.length) {\n throw new Error(`Invalid tab index: ${index}. Available: 0-${this.pages.length - 1}`);\n }\n\n // Invalidate CDP session before switching (it's page-specific)\n if (index !== this.activePageIndex) {\n await this.invalidateCDPSession();\n }\n\n this.activePageIndex = index;\n const page = this.pages[index];\n\n return {\n index: this.activePageIndex,\n url: page.url(),\n title: '', // Title requires async, will be fetched separately\n };\n }\n\n /**\n * Close a specific tab/page\n */\n async closeTab(index?: number): Promise<{ closed: number; remaining: number }> {\n const targetIndex = index ?? this.activePageIndex;\n\n if (targetIndex < 0 || targetIndex >= this.pages.length) {\n throw new Error(`Invalid tab index: ${targetIndex}`);\n }\n\n if (this.pages.length === 1) {\n throw new Error('Cannot close the last tab. Use \"close\" to close the browser.');\n }\n\n // If closing the active tab, invalidate CDP session first\n if (targetIndex === this.activePageIndex) {\n await this.invalidateCDPSession();\n }\n\n const page = this.pages[targetIndex];\n await page.close();\n this.pages.splice(targetIndex, 1);\n\n // Adjust active index if needed\n if (this.activePageIndex >= this.pages.length) {\n this.activePageIndex = this.pages.length - 1;\n } else if (this.activePageIndex > targetIndex) {\n this.activePageIndex--;\n }\n\n return { closed: targetIndex, remaining: this.pages.length };\n }\n\n /**\n * List all tabs with their info\n */\n async listTabs(): Promise<Array<{ index: number; url: string; title: string; active: boolean }>> {\n const tabs = await Promise.all(\n this.pages.map(async (page, index) => ({\n index,\n url: page.url(),\n title: await page.title().catch(() => ''),\n active: index === this.activePageIndex,\n }))\n );\n return tabs;\n }\n\n /**\n * Get or create a CDP session for the current page\n * Only works with Chromium-based browsers\n */\n async getCDPSession(): Promise<CDPSession> {\n if (this.cdpSession) {\n return this.cdpSession;\n }\n\n const page = this.getPage();\n const context = page.context();\n\n // Create a new CDP session attached to the page\n this.cdpSession = await context.newCDPSession(page);\n return this.cdpSession;\n }\n\n /**\n * Check if screencast is currently active\n */\n isScreencasting(): boolean {\n return this.screencastActive;\n }\n\n /**\n * Start screencast - streams viewport frames via CDP\n * @param callback Function called for each frame\n * @param options Screencast options\n */\n async startScreencast(\n callback: (frame: ScreencastFrame) => void,\n options?: ScreencastOptions\n ): Promise<void> {\n if (this.screencastActive) {\n throw new Error('Screencast already active');\n }\n\n const cdp = await this.getCDPSession();\n this.frameCallback = callback;\n this.screencastActive = true;\n\n // Create and store the frame handler so we can remove it later\n this.screencastFrameHandler = async (params: any) => {\n const frame: ScreencastFrame = {\n data: params.data,\n metadata: params.metadata,\n sessionId: params.sessionId,\n };\n\n // Acknowledge the frame to receive the next one\n await cdp.send('Page.screencastFrameAck', { sessionId: params.sessionId });\n\n // Call the callback with the frame\n if (this.frameCallback) {\n this.frameCallback(frame);\n }\n };\n\n // Listen for screencast frames\n cdp.on('Page.screencastFrame', this.screencastFrameHandler);\n\n // Start the screencast\n await cdp.send('Page.startScreencast', {\n format: options?.format ?? 'jpeg',\n quality: options?.quality ?? 80,\n maxWidth: options?.maxWidth ?? 1280,\n maxHeight: options?.maxHeight ?? 720,\n everyNthFrame: options?.everyNthFrame ?? 1,\n });\n }\n\n /**\n * Stop screencast\n */\n async stopScreencast(): Promise<void> {\n if (!this.screencastActive) {\n return;\n }\n\n try {\n const cdp = await this.getCDPSession();\n await cdp.send('Page.stopScreencast');\n\n // Remove the event listener to prevent accumulation\n if (this.screencastFrameHandler) {\n cdp.off('Page.screencastFrame', this.screencastFrameHandler);\n }\n } catch {\n // Ignore errors when stopping\n }\n\n this.screencastActive = false;\n this.frameCallback = null;\n this.screencastFrameHandler = null;\n }\n\n /**\n * Check if profiling is currently active\n */\n isProfilingActive(): boolean {\n return this.profilingActive;\n }\n\n /**\n * Start CDP profiling (Tracing)\n */\n async startProfiling(options?: { categories?: string[] }): Promise<void> {\n if (this.profilingActive) {\n throw new Error('Profiling already active');\n }\n\n const cdp = await this.getCDPSession();\n\n const dataHandler = (params: { value?: TraceEvent[] }) => {\n if (params.value) {\n for (const evt of params.value) {\n if (this.profileChunks.length >= BrowserManager.MAX_PROFILE_EVENTS) {\n if (!this.profileEventsDropped) {\n this.profileEventsDropped = true;\n console.warn(\n `Profiling: exceeded ${BrowserManager.MAX_PROFILE_EVENTS} events, dropping further data`\n );\n }\n return;\n }\n this.profileChunks.push(evt);\n }\n }\n };\n\n const completeHandler = () => {\n if (this.profileCompleteResolver) {\n this.profileCompleteResolver();\n }\n };\n\n cdp.on('Tracing.dataCollected', dataHandler);\n cdp.on('Tracing.tracingComplete', completeHandler);\n\n const categories = options?.categories ?? [\n 'devtools.timeline',\n 'disabled-by-default-devtools.timeline',\n 'disabled-by-default-devtools.timeline.frame',\n 'disabled-by-default-devtools.timeline.stack',\n 'v8.execute',\n 'disabled-by-default-v8.cpu_profiler',\n 'disabled-by-default-v8.cpu_profiler.hires',\n 'v8',\n 'disabled-by-default-v8.runtime_stats',\n 'blink',\n 'blink.user_timing',\n 'latencyInfo',\n 'renderer.scheduler',\n 'sequence_manager',\n 'toplevel',\n ];\n\n try {\n await cdp.send('Tracing.start', {\n traceConfig: {\n includedCategories: categories,\n enableSampling: true,\n },\n transferMode: 'ReportEvents',\n });\n } catch (error) {\n cdp.off('Tracing.dataCollected', dataHandler);\n cdp.off('Tracing.tracingComplete', completeHandler);\n throw error;\n }\n\n // Only commit state after the CDP call succeeds\n this.profilingActive = true;\n this.profileChunks = [];\n this.profileEventsDropped = false;\n this.profileDataHandler = dataHandler;\n this.profileCompleteHandler = completeHandler;\n }\n\n /**\n * Stop CDP profiling and save to file\n */\n async stopProfiling(outputPath: string): Promise<{ path: string; eventCount: number }> {\n if (!this.profilingActive) {\n throw new Error('No profiling session active');\n }\n\n const cdp = await this.getCDPSession();\n\n const TRACE_TIMEOUT_MS = 30_000;\n const completePromise = new Promise<void>((resolve, reject) => {\n const timer = setTimeout(\n () => reject(new Error('Profiling data collection timed out')),\n TRACE_TIMEOUT_MS\n );\n this.profileCompleteResolver = () => {\n clearTimeout(timer);\n resolve();\n };\n });\n\n await cdp.send('Tracing.end');\n\n let chunks: TraceEvent[];\n try {\n await completePromise;\n chunks = this.profileChunks;\n } finally {\n if (this.profileDataHandler) {\n cdp.off('Tracing.dataCollected', this.profileDataHandler);\n }\n if (this.profileCompleteHandler) {\n cdp.off('Tracing.tracingComplete', this.profileCompleteHandler);\n }\n this.profilingActive = false;\n this.profileChunks = [];\n this.profileEventsDropped = false;\n this.profileCompleteResolver = null;\n this.profileDataHandler = null;\n this.profileCompleteHandler = null;\n }\n\n const clockDomain =\n process.platform === 'linux'\n ? 'LINUX_CLOCK_MONOTONIC'\n : process.platform === 'darwin'\n ? 'MAC_MACH_ABSOLUTE_TIME'\n : undefined;\n\n const traceData: Record<string, unknown> = {\n traceEvents: chunks,\n };\n if (clockDomain) {\n traceData.metadata = { 'clock-domain': clockDomain };\n }\n\n const dir = path.dirname(outputPath);\n await mkdir(dir, { recursive: true });\n\n await writeFile(outputPath, JSON.stringify(traceData));\n\n const eventCount = chunks.length;\n\n return { path: outputPath, eventCount };\n }\n\n /**\n * Inject a mouse event via CDP\n */\n async injectMouseEvent(params: {\n type: 'mousePressed' | 'mouseReleased' | 'mouseMoved' | 'mouseWheel';\n x: number;\n y: number;\n button?: 'left' | 'right' | 'middle' | 'none';\n clickCount?: number;\n deltaX?: number;\n deltaY?: number;\n modifiers?: number; // 1=Alt, 2=Ctrl, 4=Meta, 8=Shift\n }): Promise<void> {\n const cdp = await this.getCDPSession();\n\n const cdpButton =\n params.button === 'left'\n ? 'left'\n : params.button === 'right'\n ? 'right'\n : params.button === 'middle'\n ? 'middle'\n : 'none';\n\n await cdp.send('Input.dispatchMouseEvent', {\n type: params.type,\n x: params.x,\n y: params.y,\n button: cdpButton,\n clickCount: params.clickCount ?? 1,\n deltaX: params.deltaX ?? 0,\n deltaY: params.deltaY ?? 0,\n modifiers: params.modifiers ?? 0,\n });\n }\n\n /**\n * Inject a keyboard event via CDP\n */\n async injectKeyboardEvent(params: {\n type: 'keyDown' | 'keyUp' | 'char';\n key?: string;\n code?: string;\n text?: string;\n modifiers?: number; // 1=Alt, 2=Ctrl, 4=Meta, 8=Shift\n }): Promise<void> {\n const cdp = await this.getCDPSession();\n\n await cdp.send('Input.dispatchKeyEvent', {\n type: params.type,\n key: params.key,\n code: params.code,\n text: params.text,\n modifiers: params.modifiers ?? 0,\n });\n }\n\n /**\n * Inject touch event via CDP (for mobile emulation)\n */\n async injectTouchEvent(params: {\n type: 'touchStart' | 'touchEnd' | 'touchMove' | 'touchCancel';\n touchPoints: Array<{ x: number; y: number; id?: number }>;\n modifiers?: number;\n }): Promise<void> {\n const cdp = await this.getCDPSession();\n\n await cdp.send('Input.dispatchTouchEvent', {\n type: params.type,\n touchPoints: params.touchPoints.map((tp, i) => ({\n x: tp.x,\n y: tp.y,\n id: tp.id ?? i,\n })),\n modifiers: params.modifiers ?? 0,\n });\n }\n\n /**\n * Check if video recording is currently active\n */\n isRecording(): boolean {\n return this.recordingContext !== null;\n }\n\n /**\n * Start recording to a video file using Playwright's native video recording.\n * Creates a fresh browser context with video recording enabled.\n * Automatically captures current URL and transfers cookies/storage if no URL provided.\n *\n * @param outputPath - Path to the output video file (will be .webm)\n * @param url - Optional URL to navigate to (defaults to current page URL)\n */\n async startRecording(outputPath: string, url?: string): Promise<void> {\n if (this.recordingContext) {\n throw new Error(\n \"Recording already in progress. Run 'record stop' first, or use 'record restart' to stop and start a new recording.\"\n );\n }\n\n if (!this.browser) {\n throw new Error('Browser not launched. Call launch first.');\n }\n\n // Check if output file already exists\n if (existsSync(outputPath)) {\n throw new Error(`Output file already exists: ${outputPath}`);\n }\n\n // Validate output path is .webm (Playwright native format)\n if (!outputPath.endsWith('.webm')) {\n throw new Error(\n 'Playwright native recording only supports WebM format. Please use a .webm extension.'\n );\n }\n\n // Auto-capture current URL if none provided\n const currentPage = this.pages.length > 0 ? this.pages[this.activePageIndex] : null;\n const currentContext = this.contexts.length > 0 ? this.contexts[0] : null;\n if (!url && currentPage) {\n const currentUrl = currentPage.url();\n if (currentUrl && currentUrl !== 'about:blank') {\n url = currentUrl;\n }\n }\n\n // Capture state from current context (cookies + storage)\n let storageState:\n | {\n cookies: Array<{\n name: string;\n value: string;\n domain: string;\n path: string;\n expires: number;\n httpOnly: boolean;\n secure: boolean;\n sameSite: 'Strict' | 'Lax' | 'None';\n }>;\n origins: Array<{\n origin: string;\n localStorage: Array<{ name: string; value: string }>;\n }>;\n }\n | undefined;\n\n if (currentContext) {\n try {\n storageState = await currentContext.storageState();\n } catch {\n // Ignore errors - context might be closed or invalid\n }\n }\n\n // Create a temp directory for video recording\n const session = process.env.AGENT_BROWSER_SESSION || 'default';\n this.recordingTempDir = path.join(\n os.tmpdir(),\n `agent-browser-recording-${session}-${Date.now()}`\n );\n mkdirSync(this.recordingTempDir, { recursive: true });\n\n this.recordingOutputPath = outputPath;\n\n // Reuse the active page viewport when available so recording matches the current layout.\n const viewport = currentPage?.viewportSize() ?? { width: 1280, height: 720 };\n this.recordingContext = await this.browser.newContext({\n viewport,\n recordVideo: {\n dir: this.recordingTempDir,\n size: viewport,\n },\n storageState,\n });\n this.recordingContext.setDefaultTimeout(10000);\n\n // Create a page in the recording context\n this.recordingPage = await this.recordingContext.newPage();\n\n // Add the recording context and page to our managed lists\n this.contexts.push(this.recordingContext);\n this.pages.push(this.recordingPage);\n this.activePageIndex = this.pages.length - 1;\n\n // Set up page tracking\n this.setupPageTracking(this.recordingPage);\n\n // Invalidate CDP session since we switched pages\n await this.invalidateCDPSession();\n\n // Navigate to URL if provided or captured\n if (url) {\n await this.recordingPage.goto(url, { waitUntil: 'load' });\n }\n }\n\n /**\n * Stop recording and save the video file\n * @returns Recording result with path\n */\n async stopRecording(): Promise<{ path: string; frames: number; error?: string }> {\n if (!this.recordingContext || !this.recordingPage) {\n return { path: '', frames: 0, error: 'No recording in progress' };\n }\n\n const outputPath = this.recordingOutputPath;\n\n try {\n // Get the video object before closing the page\n const video = this.recordingPage.video();\n\n // Remove recording page/context from our managed lists before closing\n const pageIndex = this.pages.indexOf(this.recordingPage);\n if (pageIndex !== -1) {\n this.pages.splice(pageIndex, 1);\n }\n const contextIndex = this.contexts.indexOf(this.recordingContext);\n if (contextIndex !== -1) {\n this.contexts.splice(contextIndex, 1);\n }\n\n // Close the page to finalize the video\n await this.recordingPage.close();\n\n // Save the video to the desired output path\n if (video) {\n await video.saveAs(outputPath);\n }\n\n // Clean up temp directory\n if (this.recordingTempDir) {\n rmSync(this.recordingTempDir, { recursive: true, force: true });\n }\n\n // Close the recording context\n await this.recordingContext.close();\n\n // Reset recording state\n this.recordingContext = null;\n this.recordingPage = null;\n this.recordingOutputPath = '';\n this.recordingTempDir = '';\n\n // Adjust active page index\n if (this.pages.length > 0) {\n this.activePageIndex = Math.min(this.activePageIndex, this.pages.length - 1);\n } else {\n this.activePageIndex = 0;\n }\n\n // Invalidate CDP session since we may have switched pages\n await this.invalidateCDPSession();\n\n return { path: outputPath, frames: 0 }; // Playwright doesn't expose frame count\n } catch (error) {\n // Clean up temp directory on error\n if (this.recordingTempDir) {\n rmSync(this.recordingTempDir, { recursive: true, force: true });\n }\n\n // Reset state on error\n this.recordingContext = null;\n this.recordingPage = null;\n this.recordingOutputPath = '';\n this.recordingTempDir = '';\n\n const message = error instanceof Error ? error.message : String(error);\n return { path: outputPath, frames: 0, error: message };\n }\n }\n\n /**\n * Restart recording - stops current recording (if any) and starts a new one.\n * Convenience method that combines stopRecording and startRecording.\n *\n * @param outputPath - Path to the output video file (must be .webm)\n * @param url - Optional URL to navigate to (defaults to current page URL)\n * @returns Result from stopping the previous recording (if any)\n */\n async restartRecording(\n outputPath: string,\n url?: string\n ): Promise<{ previousPath?: string; stopped: boolean }> {\n let previousPath: string | undefined;\n let stopped = false;\n\n // Stop current recording if active\n if (this.recordingContext) {\n const result = await this.stopRecording();\n previousPath = result.path;\n stopped = true;\n }\n\n // Start new recording\n await this.startRecording(outputPath, url);\n\n return { previousPath, stopped };\n }\n\n /**\n * Close the browser and clean up\n */\n async close(): Promise<void> {\n this.stopInspectServer();\n\n // Stop recording if active (saves video)\n if (this.recordingContext) {\n await this.stopRecording();\n }\n\n // Stop screencast if active\n if (this.screencastActive) {\n await this.stopScreencast();\n }\n\n // Clean up profiling state if active (without saving)\n if (this.profilingActive) {\n const cdp = this.cdpSession;\n if (cdp) {\n if (this.profileDataHandler) {\n cdp.off('Tracing.dataCollected', this.profileDataHandler);\n }\n if (this.profileCompleteHandler) {\n cdp.off('Tracing.tracingComplete', this.profileCompleteHandler);\n }\n await cdp.send('Tracing.end').catch(() => {});\n }\n this.profilingActive = false;\n this.profileChunks = [];\n this.profileEventsDropped = false;\n this.profileCompleteResolver = null;\n this.profileDataHandler = null;\n this.profileCompleteHandler = null;\n }\n\n // Clean up CDP session\n if (this.cdpSession) {\n await this.cdpSession.detach().catch(() => {});\n this.cdpSession = null;\n }\n\n if (this.browserbaseSessionId && this.browserbaseApiKey) {\n await this.closeBrowserbaseSession(this.browserbaseSessionId, this.browserbaseApiKey).catch(\n (error) => {\n console.error('Failed to close Browserbase session:', error);\n }\n );\n this.browser = null;\n } else if (this.browserUseSessionId && this.browserUseApiKey) {\n await this.closeBrowserUseSession(this.browserUseSessionId, this.browserUseApiKey).catch(\n (error) => {\n console.error('Failed to close Browser Use session:', error);\n }\n );\n this.browser = null;\n } else if (this.kernelSessionId) {\n await this.closeKernelSession(this.kernelSessionId, this.kernelApiKey ?? undefined).catch(\n (error) => {\n console.error('Failed to close Kernel session:', error);\n }\n );\n this.browser = null;\n } else if (this.browserlessStopUrl) {\n await this.closeBrowserlessSession(this.browserlessStopUrl).catch((error) => {\n console.error('Failed to close Browserless session:', error);\n });\n this.browser = null;\n } else if (this.cdpEndpoint !== null) {\n // CDP: only disconnect, don't close external app's pages\n if (this.browser) {\n await this.browser.close().catch(() => {});\n this.browser = null;\n }\n } else {\n // Regular browser: close everything\n for (const page of this.pages) {\n await page.close().catch(() => {});\n }\n for (const context of this.contexts) {\n await context.close().catch(() => {});\n }\n if (this.browser) {\n await this.browser.close().catch(() => {});\n this.browser = null;\n }\n }\n\n this.pages = [];\n this.contexts = [];\n this.cdpEndpoint = null;\n this.resolvedWsUrl = null;\n this.browserbaseSessionId = null;\n this.browserbaseApiKey = null;\n this.browserUseSessionId = null;\n this.browserUseApiKey = null;\n this.kernelSessionId = null;\n this.kernelApiKey = null;\n this.browserlessStopUrl = null;\n this.isPersistentContext = false;\n this.activePageIndex = 0;\n this.colorScheme = null;\n this.refMap = {};\n this.lastSnapshot = '';\n this.frameCallback = null;\n }\n}\n","/**\n * Enhanced snapshot with element refs for deterministic element selection.\n *\n * This module generates accessibility snapshots with embedded refs that can be\n * used to click/fill/interact with elements without re-querying the DOM.\n *\n * Example output:\n * - heading \"Example Domain\" [ref=e1] [level=1]\n * - paragraph: Some text content\n * - button \"Submit\" [ref=e2]\n * - textbox \"Email\" [ref=e3]\n *\n * Usage:\n * agent-browser snapshot # Full snapshot\n * agent-browser snapshot -i # Interactive elements only\n * agent-browser snapshot --depth 3 # Limit depth\n * agent-browser click @e2 # Click element by ref\n */\n\nimport type { Page, Locator } from 'playwright-core';\n\nexport interface RefMap {\n [ref: string]: {\n selector: string;\n role: string;\n name: string;\n /** Index for disambiguation when multiple elements have same role+name */\n nth?: number;\n };\n}\n\nexport interface EnhancedSnapshot {\n tree: string;\n refs: RefMap;\n}\n\nexport interface SnapshotOptions {\n /** Only include interactive elements (buttons, links, inputs, etc.) */\n interactive?: boolean;\n /** Include cursor-interactive elements (cursor:pointer, onclick, tabindex) */\n cursor?: boolean;\n /** Maximum depth of tree to include (0 = root only) */\n maxDepth?: number;\n /** Remove structural elements without meaningful content */\n compact?: boolean;\n /** CSS selector to scope the snapshot */\n selector?: string;\n}\n\n// Counter for generating refs\nlet refCounter = 0;\n\n/**\n * Reset ref counter (call at start of each snapshot)\n */\nexport function resetRefs(): void {\n refCounter = 0;\n}\n\n/**\n * Generate next ref ID\n */\nfunction nextRef(): string {\n return `e${++refCounter}`;\n}\n\n/**\n * Roles that are interactive and should get refs\n */\nconst INTERACTIVE_ROLES = new Set([\n 'button',\n 'link',\n 'textbox',\n 'checkbox',\n 'radio',\n 'combobox',\n 'listbox',\n 'menuitem',\n 'menuitemcheckbox',\n 'menuitemradio',\n 'option',\n 'searchbox',\n 'slider',\n 'spinbutton',\n 'switch',\n 'tab',\n 'treeitem',\n]);\n\n/**\n * Roles that provide structure/context (get refs for text extraction)\n */\nconst CONTENT_ROLES = new Set([\n 'heading',\n 'cell',\n 'gridcell',\n 'columnheader',\n 'rowheader',\n 'listitem',\n 'article',\n 'region',\n 'main',\n 'navigation',\n]);\n\n/**\n * Roles that are purely structural (can be filtered in compact mode)\n */\nconst STRUCTURAL_ROLES = new Set([\n 'generic',\n 'group',\n 'list',\n 'table',\n 'row',\n 'rowgroup',\n 'grid',\n 'treegrid',\n 'menu',\n 'menubar',\n 'toolbar',\n 'tablist',\n 'tree',\n 'directory',\n 'document',\n 'application',\n 'presentation',\n 'none',\n]);\n\n/**\n * Build a selector string for storing in ref map\n */\nfunction buildSelector(role: string, name: string): string {\n const escapedName = JSON.stringify(name);\n return `getByRole('${role}', { name: ${escapedName}, exact: true })`;\n}\n\n/**\n * Query the page for clickable elements that might not have proper ARIA roles.\n * This finds elements with cursor: pointer or onclick handlers.\n */\nasync function findCursorInteractiveElements(\n page: Page,\n selector?: string\n): Promise<\n Array<{\n selector: string;\n text: string;\n tagName: string;\n hasOnClick: boolean;\n hasCursorPointer: boolean;\n hasTabIndex: boolean;\n }>\n> {\n const rootSelector = selector || 'body';\n\n // Use a string function body to avoid TypeScript transpilation issues\n const scriptBody = `(rootSel) => {\n const results = [];\n\n // Elements that already have interactive ARIA roles - skip these\n const interactiveRoles = new Set([\n 'button', 'link', 'textbox', 'checkbox', 'radio', 'combobox', 'listbox',\n 'menuitem', 'menuitemcheckbox', 'menuitemradio', 'option', 'searchbox',\n 'slider', 'spinbutton', 'switch', 'tab', 'treeitem'\n ]);\n\n // Tags that are already interactive by default\n const interactiveTags = new Set([\n 'a', 'button', 'input', 'select', 'textarea', 'details', 'summary'\n ]);\n\n const root = document.querySelector(rootSel) || document.body;\n const allElements = root.querySelectorAll('*');\n\n // Build a unique selector for an element\n const buildSelector = (el) => {\n const testId = el.getAttribute('data-testid');\n if (testId) return '[data-testid=\"' + testId + '\"]';\n if (el.id) return '#' + CSS.escape(el.id);\n\n const path = [];\n let current = el;\n while (current && current !== document.body) {\n let sel = current.tagName.toLowerCase();\n const classes = Array.from(current.classList).filter(c => c.trim());\n if (classes.length > 0) sel += '.' + CSS.escape(classes[0]);\n\n const parent = current.parentElement;\n if (parent) {\n const siblings = Array.from(parent.children);\n const matching = siblings.filter(s => {\n if (s.tagName !== current.tagName) return false;\n if (classes.length > 0 && !s.classList.contains(classes[0])) return false;\n return true;\n });\n if (matching.length > 1) {\n const idx = matching.indexOf(current) + 1;\n sel += ':nth-of-type(' + idx + ')';\n }\n }\n path.unshift(sel);\n current = current.parentElement;\n // Stop once the selector uniquely identifies the element (max 10 levels)\n if (path.length >= 1) {\n try {\n const candidate = path.join(' > ');\n if (document.querySelectorAll(candidate).length === 1) break;\n } catch (e) {\n // If selector is invalid, keep building\n }\n }\n if (path.length >= 10) break;\n }\n return path.join(' > ');\n };\n\n for (const el of allElements) {\n const tagName = el.tagName.toLowerCase();\n if (interactiveTags.has(tagName)) continue;\n\n const role = el.getAttribute('role');\n if (role && interactiveRoles.has(role.toLowerCase())) continue;\n\n const computedStyle = getComputedStyle(el);\n const hasCursorPointer = computedStyle.cursor === 'pointer';\n const hasOnClick = el.hasAttribute('onclick') || el.onclick !== null;\n const tabIndex = el.getAttribute('tabindex');\n const hasTabIndex = tabIndex !== null && tabIndex !== '-1';\n\n if (!hasCursorPointer && !hasOnClick && !hasTabIndex) continue;\n\n // Skip elements that only inherit cursor:pointer from an ancestor\n // (the ancestor itself will be captured instead)\n if (hasCursorPointer && !hasOnClick && !hasTabIndex) {\n const parent = el.parentElement;\n if (parent && getComputedStyle(parent).cursor === 'pointer') continue;\n }\n\n const text = (el.textContent || '').trim().slice(0, 100);\n if (!text) continue;\n\n const rect = el.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) continue;\n\n results.push({\n selector: buildSelector(el),\n text,\n tagName,\n hasOnClick,\n hasCursorPointer,\n hasTabIndex\n });\n }\n return results;\n }`;\n\n // eslint-disable-next-line @typescript-eslint/no-implied-eval\n const fn = new Function('return ' + scriptBody)();\n return page.evaluate(fn, rootSelector);\n}\n\n/**\n * Get enhanced snapshot with refs and optional filtering\n */\nexport async function getEnhancedSnapshot(\n page: Page,\n options: SnapshotOptions = {}\n): Promise<EnhancedSnapshot> {\n resetRefs();\n const refs: RefMap = {};\n\n // Get ARIA snapshot from Playwright\n const locator = options.selector ? page.locator(options.selector) : page.locator(':root');\n const ariaTree = await locator.ariaSnapshot();\n\n if (!ariaTree) {\n return {\n tree: '(empty)',\n refs: {},\n };\n }\n\n // Parse and enhance the ARIA tree\n const enhancedTree = processAriaTree(ariaTree, refs, options);\n\n // When cursor flag is set, also find cursor-interactive elements\n // that may not have proper ARIA roles\n if (options.cursor) {\n const cursorElements = await findCursorInteractiveElements(page, options.selector);\n\n // Filter out elements whose text is already captured in the snapshot\n const existingTexts = new Set(Object.values(refs).map((r) => r.name.toLowerCase()));\n // Also extract quoted strings from the ARIA tree for broader dedup\n for (const m of enhancedTree.matchAll(/\"([^\"]+)\"/g)) {\n existingTexts.add(m[1].toLowerCase());\n }\n\n const additionalLines: string[] = [];\n for (const el of cursorElements) {\n const elTextLower = el.text.toLowerCase();\n // Skip if text already captured in the ARIA tree\n if (existingTexts.has(elTextLower)) continue;\n existingTexts.add(elTextLower);\n\n const ref = nextRef();\n const role = el.hasCursorPointer || el.hasOnClick ? 'clickable' : 'focusable';\n\n refs[ref] = {\n selector: el.selector,\n role: role,\n name: el.text,\n };\n\n // Build description of why it's interactive\n const hints: string[] = [];\n if (el.hasCursorPointer) hints.push('cursor:pointer');\n if (el.hasOnClick) hints.push('onclick');\n if (el.hasTabIndex) hints.push('tabindex');\n\n additionalLines.push(`- ${role} \"${el.text}\" [ref=${ref}] [${hints.join(', ')}]`);\n }\n\n if (additionalLines.length > 0) {\n const separator =\n enhancedTree === '(no interactive elements)' ? '' : '\\n# Cursor-interactive elements:\\n';\n const base = enhancedTree === '(no interactive elements)' ? '' : enhancedTree;\n return {\n tree: base + separator + additionalLines.join('\\n'),\n refs,\n };\n }\n }\n\n return { tree: enhancedTree, refs };\n}\n\n/**\n * Track role+name combinations to detect duplicates\n */\ninterface RoleNameTracker {\n counts: Map<string, number>;\n /** Maps role+name key to array of ref IDs that use it */\n refsByKey: Map<string, string[]>;\n getKey(role: string, name?: string): string;\n getNextIndex(role: string, name?: string): number;\n trackRef(role: string, name: string | undefined, ref: string): void;\n /** Get all role+name keys that have duplicates */\n getDuplicateKeys(): Set<string>;\n}\n\nfunction createRoleNameTracker(): RoleNameTracker {\n const counts = new Map<string, number>();\n const refsByKey = new Map<string, string[]>();\n return {\n counts,\n refsByKey,\n getKey(role: string, name?: string): string {\n return `${role}:${name ?? ''}`;\n },\n getNextIndex(role: string, name?: string): number {\n const key = this.getKey(role, name);\n const current = counts.get(key) ?? 0;\n counts.set(key, current + 1);\n return current;\n },\n trackRef(role: string, name: string | undefined, ref: string): void {\n const key = this.getKey(role, name);\n const refs = refsByKey.get(key) ?? [];\n refs.push(ref);\n refsByKey.set(key, refs);\n },\n getDuplicateKeys(): Set<string> {\n const duplicates = new Set<string>();\n for (const [key, refs] of refsByKey) {\n if (refs.length > 1) {\n duplicates.add(key);\n }\n }\n return duplicates;\n },\n };\n}\n\n/**\n * Process ARIA snapshot: add refs and apply filters\n */\nfunction processAriaTree(ariaTree: string, refs: RefMap, options: SnapshotOptions): string {\n const lines = ariaTree.split('\\n');\n const result: string[] = [];\n const tracker = createRoleNameTracker();\n\n // For interactive-only mode, we collect just interactive elements\n if (options.interactive) {\n for (const line of lines) {\n const match = line.match(/^(\\s*-\\s*)(\\w+)(?:\\s+\"([^\"]*)\")?(.*)$/);\n if (!match) continue;\n\n const [, , role, name, suffix] = match;\n const roleLower = role.toLowerCase();\n\n if (INTERACTIVE_ROLES.has(roleLower)) {\n const ref = nextRef();\n const resolvedName = name ?? '';\n const nth = tracker.getNextIndex(roleLower, resolvedName);\n tracker.trackRef(roleLower, resolvedName, ref);\n refs[ref] = {\n selector: buildSelector(roleLower, resolvedName),\n role: roleLower,\n name: resolvedName,\n nth, // Always store nth, we'll use it for duplicates\n };\n\n let enhanced = `- ${role}`;\n if (name) enhanced += ` \"${name}\"`;\n enhanced += ` [ref=${ref}]`;\n // Only show nth in output if it's > 0 (for readability)\n if (nth > 0) enhanced += ` [nth=${nth}]`;\n if (suffix && suffix.includes('[')) enhanced += suffix;\n\n result.push(enhanced);\n }\n }\n\n // Post-process: remove nth from refs that don't have duplicates\n removeNthFromNonDuplicates(refs, tracker);\n\n return result.join('\\n') || '(no interactive elements)';\n }\n\n // Normal processing with depth/compact filters\n for (const line of lines) {\n const processed = processLine(line, refs, options, tracker);\n if (processed !== null) {\n result.push(processed);\n }\n }\n\n // Post-process: remove nth from refs that don't have duplicates\n removeNthFromNonDuplicates(refs, tracker);\n\n // If compact mode, remove empty structural elements\n if (options.compact) {\n return compactTree(result.join('\\n'));\n }\n\n return result.join('\\n');\n}\n\n/**\n * Remove nth from refs that ended up not having duplicates\n * This keeps single-element locators simple (no unnecessary .nth(0))\n */\nfunction removeNthFromNonDuplicates(refs: RefMap, tracker: RoleNameTracker): void {\n const duplicateKeys = tracker.getDuplicateKeys();\n\n for (const [ref, data] of Object.entries(refs)) {\n const key = tracker.getKey(data.role, data.name);\n if (!duplicateKeys.has(key)) {\n // Not a duplicate, remove nth to keep locator simple\n delete refs[ref].nth;\n }\n }\n}\n\n/**\n * Get indentation level (number of spaces / 2)\n */\nfunction getIndentLevel(line: string): number {\n const match = line.match(/^(\\s*)/);\n return match ? Math.floor(match[1].length / 2) : 0;\n}\n\n/**\n * Process a single line: add ref if needed, filter if requested\n */\nfunction processLine(\n line: string,\n refs: RefMap,\n options: SnapshotOptions,\n tracker: RoleNameTracker\n): string | null {\n const depth = getIndentLevel(line);\n\n // Check max depth\n if (options.maxDepth !== undefined && depth > options.maxDepth) {\n return null;\n }\n\n // Match lines like:\n // - button \"Submit\"\n // - heading \"Title\" [level=1]\n // - link \"Click me\":\n const match = line.match(/^(\\s*-\\s*)(\\w+)(?:\\s+\"([^\"]*)\")?(.*)$/);\n\n if (!match) {\n // Metadata lines (like /url:) or text content\n if (options.interactive) {\n // In interactive mode, only keep metadata under interactive elements\n return null;\n }\n return line;\n }\n\n const [, prefix, role, name, suffix] = match;\n const roleLower = role.toLowerCase();\n\n // Skip metadata lines (like /url:)\n if (role.startsWith('/')) {\n return line;\n }\n\n const isInteractive = INTERACTIVE_ROLES.has(roleLower);\n const isContent = CONTENT_ROLES.has(roleLower);\n const isStructural = STRUCTURAL_ROLES.has(roleLower);\n\n // In interactive-only mode, filter non-interactive elements\n if (options.interactive && !isInteractive) {\n return null;\n }\n\n // In compact mode, skip unnamed structural elements\n if (options.compact && isStructural && !name) {\n return null;\n }\n\n // Add ref for interactive or named content elements\n const shouldHaveRef = isInteractive || (isContent && name);\n\n if (shouldHaveRef) {\n const ref = nextRef();\n // Normalize to \"\" so unnamed elements get exact-match selectors\n const resolvedName = isInteractive ? (name ?? '') : name!;\n const nth = tracker.getNextIndex(roleLower, resolvedName);\n tracker.trackRef(roleLower, resolvedName, ref);\n\n refs[ref] = {\n selector: buildSelector(roleLower, resolvedName),\n role: roleLower,\n name: resolvedName,\n nth, // Always store nth, we'll clean up non-duplicates later\n };\n\n // Build enhanced line with ref\n let enhanced = `${prefix}${role}`;\n if (name) enhanced += ` \"${name}\"`;\n enhanced += ` [ref=${ref}]`;\n // Only show nth in output if it's > 0 (for readability)\n if (nth > 0) enhanced += ` [nth=${nth}]`;\n if (suffix) enhanced += suffix;\n\n return enhanced;\n }\n\n return line;\n}\n\n/**\n * Remove empty structural branches in compact mode\n */\nfunction compactTree(tree: string): string {\n const lines = tree.split('\\n');\n const result: string[] = [];\n\n // Simple pass: keep lines that have content or refs\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Always keep lines with refs\n if (line.includes('[ref=')) {\n result.push(line);\n continue;\n }\n\n // Keep lines with text content (after :)\n if (line.includes(':') && !line.endsWith(':')) {\n result.push(line);\n continue;\n }\n\n // Check if this structural element has children with refs\n const currentIndent = getIndentLevel(line);\n let hasRelevantChildren = false;\n\n for (let j = i + 1; j < lines.length; j++) {\n const childIndent = getIndentLevel(lines[j]);\n if (childIndent <= currentIndent) break;\n if (lines[j].includes('[ref=')) {\n hasRelevantChildren = true;\n break;\n }\n }\n\n if (hasRelevantChildren) {\n result.push(line);\n }\n }\n\n return result.join('\\n');\n}\n\n/**\n * Parse a ref from command argument (e.g., \"@e1\" -> \"e1\")\n */\nexport function parseRef(arg: string): string | null {\n if (arg.startsWith('@')) {\n return arg.slice(1);\n }\n if (arg.startsWith('ref=')) {\n return arg.slice(4);\n }\n if (/^e\\d+$/.test(arg)) {\n return arg;\n }\n return null;\n}\n\n/**\n * Get snapshot statistics\n */\nexport function getSnapshotStats(\n tree: string,\n refs: RefMap\n): {\n lines: number;\n chars: number;\n tokens: number;\n refs: number;\n interactive: number;\n} {\n const interactive = Object.values(refs).filter((r) => INTERACTIVE_ROLES.has(r.role)).length;\n\n return {\n lines: tree.split('\\n').length,\n chars: tree.length,\n tokens: Math.ceil(tree.length / 4),\n refs: Object.keys(refs).length,\n interactive,\n };\n}\n","/**\n * Shared utilities for session state management.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport {\n getEncryptionKey,\n encryptData,\n decryptData,\n isEncryptedPayload,\n type EncryptedPayload,\n ENCRYPTION_KEY_ENV,\n} from './encryption.js';\n\n/**\n * Get the session persistence directory.\n * Located at ~/.agent-browser/sessions/\n */\nexport function getSessionsDir(): string {\n return path.join(os.homedir(), '.agent-browser', 'sessions');\n}\n\n/**\n * Ensure the sessions directory exists with proper permissions.\n * Creates directory with mode 0o700 (owner only).\n */\nexport function ensureSessionsDir(): string {\n const sessionsDir = getSessionsDir();\n if (!fs.existsSync(sessionsDir)) {\n fs.mkdirSync(sessionsDir, { recursive: true, mode: 0o700 });\n }\n return sessionsDir;\n}\n\n/**\n * Validate a session ID to prevent path traversal attacks.\n * Only allows alphanumeric characters, hyphens, and underscores.\n */\nfunction isValidSessionId(id: string): boolean {\n return /^[a-zA-Z0-9_-]+$/.test(id);\n}\n\n/**\n * Validate a session name for safety (no path traversal).\n * Only allows alphanumeric characters, dashes, and underscores.\n * This validation is critical for security - the daemon reads session names\n * from environment variables which can be set by attackers bypassing CLI validation.\n */\nexport function isValidSessionName(name: string): boolean {\n return /^[a-zA-Z0-9_-]+$/.test(name);\n}\n\n/**\n * Get the auto-save state file path for a session.\n * Pattern: {SESSION_NAME}-{SESSION_ID}.json\n *\n * @param sessionName - The session name (e.g., \"twitter\")\n * @param sessionId - The session ID (e.g., \"default\" or \"agent1\")\n * @returns Full path to the state file, or null if sessionName is empty\n * @throws Error if sessionName or sessionId contains invalid characters (path traversal prevention)\n */\nexport function getAutoStateFilePath(sessionName: string, sessionId: string): string | null {\n if (!sessionName) return null;\n\n // SECURITY: Validate sessionName to prevent path traversal attacks.\n // The daemon reads AGENT_BROWSER_SESSION_NAME from environment which\n // can be set directly by attackers, bypassing CLI validation.\n if (!isValidSessionName(sessionName)) {\n throw new Error(\n `Invalid session name '${sessionName}'. Only alphanumeric characters, hyphens, and underscores are allowed.`\n );\n }\n\n if (!isValidSessionId(sessionId)) {\n throw new Error(\n `Invalid session ID '${sessionId}'. Only alphanumeric characters, hyphens, and underscores are allowed.`\n );\n }\n const sessionsDir = ensureSessionsDir();\n return path.join(sessionsDir, `${sessionName}-${sessionId}.json`);\n}\n\n/**\n * Check if an auto-state file exists for a session.\n */\nexport function autoStateFileExists(sessionName: string, sessionId: string): boolean {\n const filePath = getAutoStateFilePath(sessionName, sessionId);\n return filePath ? fs.existsSync(filePath) : false;\n}\n\n/**\n * Write state data to file, encrypting if encryption key is available.\n *\n * @param filepath - Path to write the state file\n * @param data - State data object to write\n * @returns Object indicating whether the file was encrypted\n */\nexport function writeStateFile(filepath: string, data: object): { encrypted: boolean } {\n const key = getEncryptionKey();\n const jsonData = JSON.stringify(data, null, 2);\n\n if (key) {\n const encrypted = encryptData(jsonData, key);\n fs.writeFileSync(filepath, JSON.stringify(encrypted, null, 2));\n return { encrypted: true };\n }\n\n fs.writeFileSync(filepath, jsonData);\n return { encrypted: false };\n}\n\n/**\n * Read state data from file, decrypting if necessary.\n *\n * @param filepath - Path to the state file\n * @returns Object containing the data and whether it was encrypted\n * @throws Error if file is encrypted but no key is available\n */\nexport function readStateFile(filepath: string): { data: object; wasEncrypted: boolean } {\n const content = fs.readFileSync(filepath, 'utf-8');\n const parsed = JSON.parse(content);\n\n if (isEncryptedPayload(parsed)) {\n const key = getEncryptionKey();\n if (!key) {\n throw new Error(\n `State file is encrypted but ${ENCRYPTION_KEY_ENV} is not set. ` +\n `Set the environment variable to decrypt.`\n );\n }\n const decrypted = decryptData(parsed, key);\n return { data: JSON.parse(decrypted), wasEncrypted: true };\n }\n\n return { data: parsed, wasEncrypted: false };\n}\n\n/**\n * List all state files in the sessions directory.\n * @returns Array of filenames ending in .json\n */\nexport function listStateFiles(): string[] {\n const sessionsDir = getSessionsDir();\n if (!fs.existsSync(sessionsDir)) {\n return [];\n }\n return fs.readdirSync(sessionsDir).filter((f) => f.endsWith('.json'));\n}\n\n/**\n * Clean up state files older than specified days.\n * @param days - Maximum age in days (files older than this are deleted)\n * @returns Array of deleted filenames\n */\nexport function cleanupExpiredStates(days: number): string[] {\n if (days <= 0) return [];\n\n const sessionsDir = getSessionsDir();\n if (!fs.existsSync(sessionsDir)) {\n return [];\n }\n\n const now = Date.now();\n const maxAge = days * 24 * 60 * 60 * 1000;\n const deleted: string[] = [];\n\n const files = listStateFiles();\n for (const file of files) {\n const filepath = path.join(sessionsDir, file);\n try {\n const stats = fs.statSync(filepath);\n if (now - stats.mtime.getTime() > maxAge) {\n fs.unlinkSync(filepath);\n deleted.push(file);\n }\n } catch {\n // Ignore individual file errors\n }\n }\n\n return deleted;\n}\n\nconst DANGEROUS_KEYS = ['__proto__', 'constructor', 'prototype'];\n\n/**\n * Safely merge headers without prototype pollution risk.\n * Filters out dangerous keys like __proto__, constructor, prototype.\n * @param base - Base headers object\n * @param override - Headers to merge (takes precedence)\n * @returns Merged headers object (null-prototype)\n */\nexport function safeHeaderMerge(\n base: Record<string, string>,\n override: Record<string, string>\n): Record<string, string> {\n const result: Record<string, string> = Object.create(null);\n\n for (const [key, value] of Object.entries(base)) {\n if (!DANGEROUS_KEYS.includes(key)) {\n result[key] = value;\n }\n }\n\n for (const [key, value] of Object.entries(override)) {\n if (!DANGEROUS_KEYS.includes(key)) {\n result[key] = value;\n }\n }\n\n return result;\n}\n\n// Re-export encryption utilities\nexport {\n getEncryptionKey,\n encryptData,\n decryptData,\n isEncryptedPayload,\n type EncryptedPayload,\n ENCRYPTION_KEY_ENV,\n};\n","/**\n * Encryption utilities for state file protection using AES-256-GCM.\n */\n\nimport * as crypto from 'crypto';\nimport { execSync } from 'node:child_process';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport os from 'node:os';\n\n// ============================================\n// Constants\n// ============================================\nexport const ENCRYPTION_ALGORITHM = 'aes-256-gcm';\nexport const ENCRYPTION_KEY_ENV = 'AGENT_BROWSER_ENCRYPTION_KEY';\nexport const IV_LENGTH = 12; // 96 bits for GCM\nconst KEY_FILE_NAME = '.encryption-key';\n\n/**\n * Encrypted payload structure.\n */\nexport interface EncryptedPayload {\n version: 1;\n encrypted: true;\n iv: string; // Base64 encoded\n authTag: string; // Base64 encoded\n data: string; // Base64 encoded ciphertext\n}\n\nexport function getKeyFilePath(): string {\n return join(os.homedir(), '.agent-browser', KEY_FILE_NAME);\n}\n\n/**\n * Restrict file permissions to the current user only.\n * On Unix, the caller should use `mode: 0o600` when writing. This function\n * handles Windows where Node's mode parameter is ignored.\n */\nexport function restrictFilePermissions(filePath: string): void {\n if (os.platform() !== 'win32') return;\n try {\n execSync(`icacls \"${filePath}\" /inheritance:r /grant:r \"%USERNAME%:F\"`, {\n stdio: 'ignore',\n windowsHide: true,\n });\n } catch {\n // Best-effort; may fail in some environments (containers, restricted shells)\n }\n}\n\n/**\n * Restrict directory permissions to the current user only.\n * On Unix, the caller should use `mode: 0o700` when creating. This function\n * handles Windows where Node's mode parameter is ignored.\n */\nexport function restrictDirPermissions(dirPath: string): void {\n if (os.platform() !== 'win32') return;\n try {\n execSync(`icacls \"${dirPath}\" /inheritance:r /grant:r \"%USERNAME%:(OI)(CI)F\"`, {\n stdio: 'ignore',\n windowsHide: true,\n });\n } catch {\n // Best-effort\n }\n}\n\nfunction parseKeyHex(keyHex: string): Buffer | null {\n if (!/^[a-fA-F0-9]{64}$/.test(keyHex.trim())) return null;\n return Buffer.from(keyHex.trim(), 'hex');\n}\n\n/**\n * Get encryption key from environment variable or key file.\n * The key should be a 32-byte (256-bit) hex-encoded string (64 characters).\n * Generate with: openssl rand -hex 32\n *\n * Checks (in order):\n * 1. AGENT_BROWSER_ENCRYPTION_KEY env var\n * 2. ~/.agent-browser/.encryption-key file\n *\n * @returns Buffer containing the key, or null if not available\n */\nexport function getEncryptionKey(): Buffer | null {\n const keyHex = process.env[ENCRYPTION_KEY_ENV];\n if (keyHex) {\n const key = parseKeyHex(keyHex);\n if (!key) {\n console.warn(\n `Warning: ${ENCRYPTION_KEY_ENV} should be a 64-character hex string (256 bits). ` +\n `Generate one with: openssl rand -hex 32`\n );\n return null;\n }\n return key;\n }\n\n const keyFilePath = getKeyFilePath();\n if (existsSync(keyFilePath)) {\n try {\n const fileHex = readFileSync(keyFilePath, 'utf-8');\n return parseKeyHex(fileHex);\n } catch {\n return null;\n }\n }\n\n return null;\n}\n\n/**\n * Ensure an encryption key is available, auto-generating one if needed.\n * On first call without an existing key, generates a random 256-bit key\n * and writes it to ~/.agent-browser/.encryption-key (mode 0600).\n */\nexport function ensureEncryptionKey(): Buffer {\n const existing = getEncryptionKey();\n if (existing) return existing;\n\n const key = crypto.randomBytes(32);\n const keyHex = key.toString('hex');\n\n const dir = join(os.homedir(), '.agent-browser');\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n restrictDirPermissions(dir);\n }\n\n const keyFilePath = getKeyFilePath();\n writeFileSync(keyFilePath, keyHex + '\\n', { mode: 0o600 });\n restrictFilePermissions(keyFilePath);\n\n console.error(\n `[agent-browser] Auto-generated encryption key at ${keyFilePath} -- back up this file or set ${ENCRYPTION_KEY_ENV}`\n );\n\n return key;\n}\n\n/**\n * Encrypt data using AES-256-GCM.\n * Returns a JSON-serializable payload with IV, auth tag, and encrypted data.\n *\n * @param plaintext - The string to encrypt\n * @param key - The 256-bit encryption key\n * @returns Encrypted payload object\n */\nexport function encryptData(plaintext: string, key: Buffer): EncryptedPayload {\n const iv = crypto.randomBytes(IV_LENGTH);\n const cipher = crypto.createCipheriv(ENCRYPTION_ALGORITHM, key, iv);\n\n let encrypted = cipher.update(plaintext, 'utf8');\n encrypted = Buffer.concat([encrypted, cipher.final()]);\n\n return {\n version: 1,\n encrypted: true,\n iv: iv.toString('base64'),\n authTag: cipher.getAuthTag().toString('base64'),\n data: encrypted.toString('base64'),\n };\n}\n\n/**\n * Decrypt data using AES-256-GCM.\n *\n * @param payload - The encrypted payload object\n * @param key - The 256-bit encryption key\n * @returns Decrypted plaintext string\n * @throws Error if decryption fails (wrong key, tampered data, etc.)\n */\nexport function decryptData(payload: EncryptedPayload, key: Buffer): string {\n const iv = Buffer.from(payload.iv, 'base64');\n const authTag = Buffer.from(payload.authTag, 'base64');\n const encryptedData = Buffer.from(payload.data, 'base64');\n\n const decipher = crypto.createDecipheriv(ENCRYPTION_ALGORITHM, key, iv);\n decipher.setAuthTag(authTag);\n\n let decrypted = decipher.update(encryptedData);\n decrypted = Buffer.concat([decrypted, decipher.final()]);\n\n return decrypted.toString('utf8');\n}\n\n/**\n * Check if a parsed JSON object is an encrypted payload.\n *\n * @param data - The object to check\n * @returns True if the object is a valid encrypted payload\n */\nexport function isEncryptedPayload(data: unknown): data is EncryptedPayload {\n return (\n typeof data === 'object' &&\n data !== null &&\n 'encrypted' in data &&\n (data as EncryptedPayload).encrypted === true &&\n 'version' in data &&\n 'iv' in data &&\n 'authTag' in data &&\n 'data' in data\n );\n}\n","import type { BrowserContext, Route } from 'playwright-core';\n\n/**\n * Checks whether a hostname matches one of the allowed domain patterns.\n * Patterns support exact match (\"example.com\") and wildcard prefix (\"*.example.com\").\n */\nexport function isDomainAllowed(hostname: string, allowedDomains: string[]): boolean {\n for (const pattern of allowedDomains) {\n if (pattern.startsWith('*.')) {\n const suffix = pattern.slice(1); // \".example.com\"\n if (hostname === pattern.slice(2) || hostname.endsWith(suffix)) {\n return true;\n }\n } else if (hostname === pattern) {\n return true;\n }\n }\n return false;\n}\n\nexport function parseDomainList(raw: string): string[] {\n return raw\n .split(',')\n .map((d) => d.trim().toLowerCase())\n .filter((d) => d.length > 0);\n}\n\n/**\n * Build the init script source that monkey-patches WebSocket, EventSource,\n * and navigator.sendBeacon to block connections to non-allowed domains.\n * Exported for testing.\n */\nexport function buildWebSocketFilterScript(allowedDomains: string[]): string {\n const serialized = JSON.stringify(allowedDomains);\n return `(function() {\n var _allowedDomains = ${serialized};\n function _isDomainAllowed(hostname) {\n hostname = hostname.toLowerCase();\n for (var i = 0; i < _allowedDomains.length; i++) {\n var pattern = _allowedDomains[i];\n if (pattern.indexOf('*.') === 0) {\n var suffix = pattern.slice(1);\n if (hostname === pattern.slice(2) || hostname.slice(-suffix.length) === suffix) {\n return true;\n }\n } else if (hostname === pattern) {\n return true;\n }\n }\n return false;\n }\n function _checkUrl(url) {\n try {\n var parsed = new URL(url);\n return _isDomainAllowed(parsed.hostname);\n } catch(e) {\n return false;\n }\n }\n if (typeof WebSocket !== 'undefined') {\n var _OrigWS = WebSocket;\n WebSocket = function(url, protocols) {\n if (!_checkUrl(url)) {\n throw new DOMException(\n 'WebSocket connection to ' + url + ' blocked by domain allowlist',\n 'SecurityError'\n );\n }\n if (protocols !== undefined) {\n return new _OrigWS(url, protocols);\n }\n return new _OrigWS(url);\n };\n WebSocket.prototype = _OrigWS.prototype;\n WebSocket.CONNECTING = _OrigWS.CONNECTING;\n WebSocket.OPEN = _OrigWS.OPEN;\n WebSocket.CLOSING = _OrigWS.CLOSING;\n WebSocket.CLOSED = _OrigWS.CLOSED;\n }\n if (typeof EventSource !== 'undefined') {\n var _OrigES = EventSource;\n EventSource = function(url, opts) {\n if (!_checkUrl(url)) {\n throw new DOMException(\n 'EventSource connection to ' + url + ' blocked by domain allowlist',\n 'SecurityError'\n );\n }\n return new _OrigES(url, opts);\n };\n EventSource.prototype = _OrigES.prototype;\n EventSource.CONNECTING = _OrigES.CONNECTING;\n EventSource.OPEN = _OrigES.OPEN;\n EventSource.CLOSED = _OrigES.CLOSED;\n }\n if (typeof navigator !== 'undefined' && typeof navigator.sendBeacon === 'function') {\n var _origSendBeacon = navigator.sendBeacon.bind(navigator);\n navigator.sendBeacon = function(url, data) {\n if (!_checkUrl(url)) {\n return false;\n }\n return _origSendBeacon(url, data);\n };\n }\n})();`;\n}\n\n/**\n * Installs a context-level route that enforces the domain allowlist.\n * Both document navigations and sub-resource requests (scripts, images, fetch, etc.)\n * to non-allowed domains are blocked, preventing data exfiltration.\n * Non-http(s) schemes (data:, blob:, etc.) are allowed for sub-resources\n * but blocked for document navigations.\n *\n * Also installs an init script that patches WebSocket, EventSource, and\n * navigator.sendBeacon to block connections to non-allowed domains. This is\n * a best-effort defense: if eval is permitted by action policy, page scripts\n * could theoretically restore the originals. Denying the eval action\n * category closes that loophole.\n */\nexport async function installDomainFilter(\n context: BrowserContext,\n allowedDomains: string[]\n): Promise<void> {\n if (allowedDomains.length === 0) return;\n\n await context.addInitScript(buildWebSocketFilterScript(allowedDomains));\n\n await context.route('**/*', async (route: Route) => {\n const request = route.request();\n const urlStr = request.url();\n\n if (!urlStr.startsWith('http://') && !urlStr.startsWith('https://')) {\n if (request.resourceType() === 'document') {\n await route.abort('blockedbyclient');\n } else {\n await route.continue();\n }\n return;\n }\n\n let hostname: string;\n try {\n hostname = new URL(urlStr).hostname.toLowerCase();\n } catch {\n await route.abort('blockedbyclient');\n return;\n }\n\n if (isDomainAllowed(hostname, allowedDomains)) {\n await route.continue();\n } else {\n await route.abort('blockedbyclient');\n }\n });\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport type { Page, Frame } from 'playwright-core';\nimport { mkdirSync } from 'node:fs';\nimport type { BrowserManager, ScreencastFrame } from './browser-manager.js';\nimport os from 'node:os';\n\n/**\n * Get the base directory for app data files.\n * Extracted from daemon.ts to avoid CLI daemon dependency.\n * Priority: XDG_RUNTIME_DIR > ~/.agent-browser > tmpdir\n */\nfunction getAppDir(): string {\n if (process.env.XDG_RUNTIME_DIR) {\n return path.join(process.env.XDG_RUNTIME_DIR, 'agent-browser');\n }\n const homeDir = os.homedir();\n if (homeDir) {\n return path.join(homeDir, '.agent-browser');\n }\n return path.join(os.tmpdir(), 'agent-browser');\n}\nimport {\n type ActionPolicy,\n checkPolicy,\n describeAction,\n getActionCategory,\n loadPolicyFile,\n initPolicyReloader,\n reloadPolicyIfChanged,\n} from './action-policy.js';\nimport { requestConfirmation, getAndRemovePending } from './confirmation.js';\nimport { getAuthProfile, updateLastLogin } from './auth-vault.js';\nimport {\n getSessionsDir,\n readStateFile,\n isValidSessionName,\n isEncryptedPayload,\n listStateFiles,\n cleanupExpiredStates,\n} from './state-utils.js';\nimport type {\n Command,\n Response,\n NavigateCommand,\n ClickCommand,\n TypeCommand,\n FillCommand,\n CheckCommand,\n UncheckCommand,\n UploadCommand,\n DoubleClickCommand,\n FocusCommand,\n DragCommand,\n FrameCommand,\n GetByRoleCommand,\n GetByTextCommand,\n GetByLabelCommand,\n GetByPlaceholderCommand,\n PressCommand,\n ScreenshotCommand,\n EvaluateCommand,\n WaitCommand,\n ScrollCommand,\n SelectCommand,\n HoverCommand,\n ContentCommand,\n TabNewCommand,\n TabSwitchCommand,\n TabCloseCommand,\n WindowNewCommand,\n CookiesSetCommand,\n StorageGetCommand,\n StorageSetCommand,\n StorageClearCommand,\n DialogCommand,\n PdfCommand,\n RouteCommand,\n RequestsCommand,\n DownloadCommand,\n GeolocationCommand,\n PermissionsCommand,\n ViewportCommand,\n DeviceCommand,\n GetAttributeCommand,\n GetTextCommand,\n IsVisibleCommand,\n IsEnabledCommand,\n IsCheckedCommand,\n CountCommand,\n BoundingBoxCommand,\n StylesCommand,\n TraceStartCommand,\n TraceStopCommand,\n ProfilerStartCommand,\n ProfilerStopCommand,\n HarStopCommand,\n StorageStateSaveCommand,\n StateListCommand,\n StateClearCommand,\n StateShowCommand,\n StateCleanCommand,\n StateRenameCommand,\n ConsoleCommand,\n ErrorsCommand,\n KeyboardCommand,\n WheelCommand,\n TapCommand,\n ClipboardCommand,\n HighlightCommand,\n ClearCommand,\n SelectAllCommand,\n InnerTextCommand,\n InnerHtmlCommand,\n InputValueCommand,\n SetValueCommand,\n DispatchEventCommand,\n AddScriptCommand,\n AddStyleCommand,\n EmulateMediaCommand,\n OfflineCommand,\n HeadersCommand,\n GetByAltTextCommand,\n GetByTitleCommand,\n GetByTestIdCommand,\n NthCommand,\n WaitForUrlCommand,\n WaitForLoadStateCommand,\n SetContentCommand,\n TimezoneCommand,\n LocaleCommand,\n HttpCredentialsCommand,\n MouseMoveCommand,\n MouseDownCommand,\n MouseUpCommand,\n WaitForFunctionCommand,\n ScrollIntoViewCommand,\n AddInitScriptCommand,\n KeyDownCommand,\n KeyUpCommand,\n InsertTextCommand,\n MultiSelectCommand,\n WaitForDownloadCommand,\n ResponseBodyCommand,\n ScreencastStartCommand,\n ScreencastStopCommand,\n InputMouseCommand,\n InputKeyboardCommand,\n InputTouchCommand,\n RecordingStartCommand,\n RecordingStopCommand,\n RecordingRestartCommand,\n DiffSnapshotCommand,\n DiffScreenshotCommand,\n DiffUrlCommand,\n AuthLoginCommand,\n ConfirmCommand,\n DenyCommand,\n Annotation,\n NavigateData,\n ScreenshotData,\n EvaluateData,\n DiffSnapshotData,\n DiffScreenshotData,\n DiffUrlData,\n ContentData,\n TabListData,\n TabNewData,\n TabSwitchData,\n TabCloseData,\n ScreencastStartData,\n ScreencastStopData,\n RecordingStartData,\n RecordingStopData,\n RecordingRestartData,\n InputEventData,\n StylesData,\n} from './types.js';\nimport { successResponse, errorResponse, parseCommand } from './protocol.js';\nimport { diffSnapshots, diffScreenshots } from './diff.js';\nimport { getEnhancedSnapshot } from './snapshot.js';\n\n// Callback for screencast frames - will be set by the daemon when streaming is active\nlet screencastFrameCallback: ((frame: ScreencastFrame) => void) | null = null;\n\n/**\n * Set the callback for screencast frames\n * This is called by the daemon to set up frame streaming\n */\nexport function setScreencastFrameCallback(\n callback: ((frame: ScreencastFrame) => void) | null\n): void {\n screencastFrameCallback = callback;\n}\n\n// Snapshot response type\ninterface SnapshotData {\n snapshot: string;\n refs?: Record<string, { role: string; name?: string }>;\n}\n\n/**\n * Convert Playwright errors to AI-friendly messages\n * @internal Exported for testing\n */\nexport function toAIFriendlyError(error: unknown, selector: string): Error {\n const message = error instanceof Error ? error.message : String(error);\n\n // Handle strict mode violation (multiple elements match)\n if (message.includes('strict mode violation')) {\n // Extract count if available\n const countMatch = message.match(/resolved to (\\d+) elements/);\n const count = countMatch ? countMatch[1] : 'multiple';\n\n return new Error(\n `Selector \"${selector}\" matched ${count} elements. ` +\n `Run 'snapshot' to get updated refs, or use a more specific CSS selector.`\n );\n }\n\n // Handle element not interactable (must be checked BEFORE timeout case)\n // This includes cases where an overlay/modal blocks the element\n if (message.includes('intercepts pointer events')) {\n return new Error(\n `Element \"${selector}\" is blocked by another element (likely a modal or overlay). ` +\n `Try dismissing any modals/cookie banners first.`\n );\n }\n\n // Handle element not visible\n if (message.includes('not visible') && !message.includes('Timeout')) {\n return new Error(\n `Element \"${selector}\" is not visible. ` +\n `Try scrolling it into view or check if it's hidden.`\n );\n }\n\n // Handle general timeout (element exists but action couldn't complete)\n if (message.includes('Timeout') && message.includes('exceeded')) {\n return new Error(\n `Action on \"${selector}\" timed out. The element may be blocked, still loading, or not interactable. ` +\n `Run 'snapshot' to check the current page state.`\n );\n }\n\n // Handle element not found (timeout waiting for element)\n if (\n message.includes('waiting for') &&\n (message.includes('to be visible') || message.includes('Timeout'))\n ) {\n return new Error(\n `Element \"${selector}\" not found or not visible. ` +\n `Run 'snapshot' to see current page elements.`\n );\n }\n\n // Return original error for unknown cases\n return error instanceof Error ? error : new Error(message);\n}\n\nlet actionPolicy: ActionPolicy | null = null;\nlet confirmCategories = new Set<string>();\n\nexport function initActionPolicy(): void {\n const policyPath = process.env.AGENT_BROWSER_ACTION_POLICY;\n if (policyPath) {\n try {\n actionPolicy = loadPolicyFile(policyPath);\n initPolicyReloader(policyPath, actionPolicy);\n } catch (err) {\n console.error(\n `[ERROR] Failed to load action policy from ${policyPath}: ${err instanceof Error ? err.message : err}`\n );\n process.exit(1);\n }\n }\n\n const confirmActionsEnv = process.env.AGENT_BROWSER_CONFIRM_ACTIONS;\n if (confirmActionsEnv) {\n confirmCategories = new Set(\n confirmActionsEnv\n .split(',')\n .map((c) => c.trim().toLowerCase())\n .filter((c) => c.length > 0)\n );\n }\n}\n\n/**\n * Execute a command and return a response\n */\nexport async function executeCommand(command: Command, browser: BrowserManager): Promise<Response> {\n try {\n // Handle confirm/deny actions (bypass policy check)\n if (command.action === 'confirm') {\n return await handleConfirm(command, browser);\n }\n if (command.action === 'deny') {\n return handleDeny(command);\n }\n\n // Hot-reload policy file if it changed on disk\n actionPolicy = reloadPolicyIfChanged();\n\n // Policy enforcement\n const decision = checkPolicy(command.action, actionPolicy, confirmCategories);\n if (decision === 'deny') {\n const category = getActionCategory(command.action);\n return errorResponse(command.id, `Action denied by policy: '${category}' is not allowed`);\n }\n if (decision === 'confirm') {\n const category = getActionCategory(command.action);\n const description = describeAction(\n command.action,\n command as unknown as Record<string, unknown>\n );\n const { confirmationId } = requestConfirmation(\n command.action,\n category,\n description,\n command as unknown as Record<string, unknown>\n );\n return successResponse(command.id, {\n confirmation_required: true,\n action: command.action,\n category,\n description,\n confirmation_id: confirmationId,\n });\n }\n\n return await dispatchAction(command, browser);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return errorResponse(command.id, message);\n }\n}\n\n/**\n * Dispatch a command to its handler after policy checks have passed.\n */\nasync function dispatchAction(command: Command, browser: BrowserManager): Promise<Response> {\n switch (command.action) {\n case 'launch':\n return await handleLaunch(command, browser);\n case 'navigate':\n return await handleNavigate(command, browser);\n case 'click':\n return await handleClick(command, browser);\n case 'type':\n return await handleType(command, browser);\n case 'fill':\n return await handleFill(command, browser);\n case 'check':\n return await handleCheck(command, browser);\n case 'uncheck':\n return await handleUncheck(command, browser);\n case 'upload':\n return await handleUpload(command, browser);\n case 'dblclick':\n return await handleDoubleClick(command, browser);\n case 'focus':\n return await handleFocus(command, browser);\n case 'drag':\n return await handleDrag(command, browser);\n case 'frame':\n return await handleFrame(command, browser);\n case 'mainframe':\n return await handleMainFrame(command, browser);\n case 'getbyrole':\n return await handleGetByRole(command, browser);\n case 'getbytext':\n return await handleGetByText(command, browser);\n case 'getbylabel':\n return await handleGetByLabel(command, browser);\n case 'getbyplaceholder':\n return await handleGetByPlaceholder(command, browser);\n case 'press':\n return await handlePress(command, browser);\n case 'screenshot':\n return await handleScreenshot(command, browser);\n case 'snapshot':\n return await handleSnapshot(command, browser);\n case 'evaluate':\n return await handleEvaluate(command, browser);\n case 'wait':\n return await handleWait(command, browser);\n case 'scroll':\n return await handleScroll(command, browser);\n case 'select':\n return await handleSelect(command, browser);\n case 'hover':\n return await handleHover(command, browser);\n case 'content':\n return await handleContent(command, browser);\n case 'close':\n return await handleClose(command, browser);\n case 'tab_new':\n return await handleTabNew(command, browser);\n case 'tab_list':\n return await handleTabList(command, browser);\n case 'tab_switch':\n return await handleTabSwitch(command, browser);\n case 'tab_close':\n return await handleTabClose(command, browser);\n case 'window_new':\n return await handleWindowNew(command, browser);\n case 'cookies_get':\n return await handleCookiesGet(command, browser);\n case 'cookies_set':\n return await handleCookiesSet(command, browser);\n case 'cookies_clear':\n return await handleCookiesClear(command, browser);\n case 'storage_get':\n return await handleStorageGet(command, browser);\n case 'storage_set':\n return await handleStorageSet(command, browser);\n case 'storage_clear':\n return await handleStorageClear(command, browser);\n case 'dialog':\n return await handleDialog(command, browser);\n case 'pdf':\n return await handlePdf(command, browser);\n case 'route':\n return await handleRoute(command, browser);\n case 'unroute':\n return await handleUnroute(command, browser);\n case 'requests':\n return await handleRequests(command, browser);\n case 'download':\n return await handleDownload(command, browser);\n case 'geolocation':\n return await handleGeolocation(command, browser);\n case 'permissions':\n return await handlePermissions(command, browser);\n case 'viewport':\n return await handleViewport(command, browser);\n case 'useragent':\n return await handleUserAgent(command, browser);\n case 'device':\n return await handleDevice(command, browser);\n case 'back':\n return await handleBack(command, browser);\n case 'forward':\n return await handleForward(command, browser);\n case 'reload':\n return await handleReload(command, browser);\n case 'url':\n return await handleUrl(command, browser);\n case 'cdp_url':\n return handleCdpUrl(command, browser);\n case 'inspect':\n return await handleInspect(command, browser);\n case 'title':\n return await handleTitle(command, browser);\n case 'getattribute':\n return await handleGetAttribute(command, browser);\n case 'gettext':\n return await handleGetText(command, browser);\n case 'isvisible':\n return await handleIsVisible(command, browser);\n case 'isenabled':\n return await handleIsEnabled(command, browser);\n case 'ischecked':\n return await handleIsChecked(command, browser);\n case 'count':\n return await handleCount(command, browser);\n case 'boundingbox':\n return await handleBoundingBox(command, browser);\n case 'styles':\n return await handleStyles(command, browser);\n case 'video_start':\n return await handleVideoStart(command, browser);\n case 'video_stop':\n return await handleVideoStop(command, browser);\n case 'trace_start':\n return await handleTraceStart(command, browser);\n case 'trace_stop':\n return await handleTraceStop(command, browser);\n case 'profiler_start':\n return await handleProfilerStart(command, browser);\n case 'profiler_stop':\n return await handleProfilerStop(command, browser);\n case 'har_start':\n return await handleHarStart(command, browser);\n case 'har_stop':\n return await handleHarStop(command, browser);\n case 'state_save':\n return await handleStateSave(command, browser);\n case 'state_load':\n return await handleStateLoad(command, browser);\n case 'state_list':\n return await handleStateList(command);\n case 'state_clear':\n return await handleStateClear(command);\n case 'state_show':\n return await handleStateShow(command);\n case 'state_clean':\n return await handleStateClean(command);\n case 'state_rename':\n return await handleStateRename(command);\n case 'console':\n return await handleConsole(command, browser);\n case 'errors':\n return await handleErrors(command, browser);\n case 'keyboard':\n return await handleKeyboard(command, browser);\n case 'wheel':\n return await handleWheel(command, browser);\n case 'tap':\n return await handleTap(command, browser);\n case 'clipboard':\n return await handleClipboard(command, browser);\n case 'highlight':\n return await handleHighlight(command, browser);\n case 'clear':\n return await handleClear(command, browser);\n case 'selectall':\n return await handleSelectAll(command, browser);\n case 'innertext':\n return await handleInnerText(command, browser);\n case 'innerhtml':\n return await handleInnerHtml(command, browser);\n case 'inputvalue':\n return await handleInputValue(command, browser);\n case 'setvalue':\n return await handleSetValue(command, browser);\n case 'dispatch':\n return await handleDispatch(command, browser);\n case 'evalhandle':\n return await handleEvalHandle(command, browser);\n case 'expose':\n return await handleExpose(command, browser);\n case 'addscript':\n return await handleAddScript(command, browser);\n case 'addstyle':\n return await handleAddStyle(command, browser);\n case 'emulatemedia':\n return await handleEmulateMedia(command, browser);\n case 'offline':\n return await handleOffline(command, browser);\n case 'headers':\n return await handleHeaders(command, browser);\n case 'pause':\n return await handlePause(command, browser);\n case 'getbyalttext':\n return await handleGetByAltText(command, browser);\n case 'getbytitle':\n return await handleGetByTitle(command, browser);\n case 'getbytestid':\n return await handleGetByTestId(command, browser);\n case 'nth':\n return await handleNth(command, browser);\n case 'waitforurl':\n return await handleWaitForUrl(command, browser);\n case 'waitforloadstate':\n return await handleWaitForLoadState(command, browser);\n case 'setcontent':\n return await handleSetContent(command, browser);\n case 'timezone':\n return await handleTimezone(command, browser);\n case 'locale':\n return await handleLocale(command, browser);\n case 'credentials':\n return await handleCredentials(command, browser);\n case 'mousemove':\n return await handleMouseMove(command, browser);\n case 'mousedown':\n return await handleMouseDown(command, browser);\n case 'mouseup':\n return await handleMouseUp(command, browser);\n case 'bringtofront':\n return await handleBringToFront(command, browser);\n case 'waitforfunction':\n return await handleWaitForFunction(command, browser);\n case 'scrollintoview':\n return await handleScrollIntoView(command, browser);\n case 'addinitscript':\n return await handleAddInitScript(command, browser);\n case 'keydown':\n return await handleKeyDown(command, browser);\n case 'keyup':\n return await handleKeyUp(command, browser);\n case 'inserttext':\n return await handleInsertText(command, browser);\n case 'multiselect':\n return await handleMultiSelect(command, browser);\n case 'waitfordownload':\n return await handleWaitForDownload(command, browser);\n case 'responsebody':\n return await handleResponseBody(command, browser);\n case 'screencast_start':\n return await handleScreencastStart(command, browser);\n case 'screencast_stop':\n return await handleScreencastStop(command, browser);\n case 'input_mouse':\n return await handleInputMouse(command, browser);\n case 'input_keyboard':\n return await handleInputKeyboard(command, browser);\n case 'input_touch':\n return await handleInputTouch(command, browser);\n case 'recording_start':\n return await handleRecordingStart(command, browser);\n case 'recording_stop':\n return await handleRecordingStop(command, browser);\n case 'recording_restart':\n return await handleRecordingRestart(command, browser);\n case 'diff_snapshot':\n return await handleDiffSnapshot(command, browser);\n case 'diff_screenshot':\n return await handleDiffScreenshot(command, browser);\n case 'diff_url':\n return await handleDiffUrl(command, browser);\n case 'auth_login':\n return await handleAuthLogin(command, browser);\n default: {\n // TypeScript narrows to never here, but we handle it for safety\n const unknownCommand = command as { id: string; action: string };\n return errorResponse(unknownCommand.id, `Unknown action: ${unknownCommand.action}`);\n }\n }\n}\n\nasync function handleLaunch(\n command: Command & { action: 'launch' },\n browser: BrowserManager\n): Promise<Response> {\n if (command.engine === 'lightpanda') {\n return errorResponse(command.id, 'Lightpanda engine requires --native mode');\n }\n await browser.launch(command);\n return successResponse(command.id, { launched: true });\n}\n\nasync function handleNavigate(\n command: NavigateCommand,\n browser: BrowserManager\n): Promise<Response<NavigateData>> {\n const result = await browser.navigate(command.url, {\n headers: command.headers,\n waitUntil: command.waitUntil,\n });\n\n return successResponse(command.id, result);\n}\n\nasync function handleClick(command: ClickCommand, browser: BrowserManager): Promise<Response> {\n // Support both refs (@e1) and regular selectors\n const locator = browser.getLocator(command.selector);\n\n try {\n // If --new-tab flag is set, get the href and open in a new tab\n if (command.newTab) {\n const fullUrl = await locator.evaluate((el) => {\n const href = el.getAttribute('href');\n // URL and document.baseURI are available in the browser context\n return href\n ? new (globalThis as any).URL(href, (globalThis as any).document.baseURI).toString()\n : '';\n });\n if (!fullUrl) {\n throw new Error(\n `Element '${command.selector}' does not have an href attribute. --new-tab only works on links.`\n );\n }\n\n await browser.newTab();\n const newPage = browser.getPage();\n await newPage.goto(fullUrl);\n\n return successResponse(command.id, {\n clicked: true,\n newTab: true,\n url: fullUrl,\n });\n }\n\n await locator.click({\n button: command.button,\n clickCount: command.clickCount,\n delay: command.delay,\n });\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n\n return successResponse(command.id, { clicked: true });\n}\n\nasync function handleType(command: TypeCommand, browser: BrowserManager): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n\n try {\n if (command.clear) {\n await locator.fill('');\n }\n\n await locator.pressSequentially(command.text, {\n delay: command.delay,\n });\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n\n return successResponse(command.id, { typed: true });\n}\n\nasync function handlePress(command: PressCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n\n if (command.selector) {\n await page.press(command.selector, command.key);\n } else {\n await page.keyboard.press(command.key);\n }\n\n return successResponse(command.id, { pressed: true });\n}\n\nconst ANNOTATION_OVERLAY_ID = '__agent_browser_annotations__';\n\nasync function removeAnnotationOverlay(page: Page): Promise<void> {\n await page\n .evaluate(\n `(() => { const el = document.getElementById(${JSON.stringify(ANNOTATION_OVERLAY_ID)}); if (el) el.remove(); })()`\n )\n .catch(() => {});\n}\n\nasync function handleScreenshot(\n command: ScreenshotCommand,\n browser: BrowserManager\n): Promise<Response<ScreenshotData>> {\n const page = browser.getPage();\n\n const options: Parameters<Page['screenshot']>[0] = {\n fullPage: command.fullPage,\n type: command.format ?? 'png',\n };\n\n if (command.format === 'jpeg' && command.quality !== undefined) {\n options.quality = command.quality;\n }\n\n let target: Page | ReturnType<Page['locator']> = page;\n if (command.selector) {\n target = browser.getLocator(command.selector);\n }\n\n let overlayInjected = false;\n\n try {\n let savePath = command.path;\n if (!savePath) {\n const ext = command.format === 'jpeg' ? 'jpg' : 'png';\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const random = Math.random().toString(36).substring(2, 8);\n const filename = `screenshot-${timestamp}-${random}.${ext}`;\n const screenshotDir = command.screenshotDir ?? path.join(getAppDir(), 'tmp', 'screenshots');\n mkdirSync(screenshotDir, { recursive: true });\n savePath = path.join(screenshotDir, filename);\n }\n\n let annotations: Annotation[] | undefined;\n\n if (command.annotate) {\n const { refs } = await browser.getSnapshot({ interactive: true });\n\n const entries = Object.entries(refs);\n const results = await Promise.all(\n entries.map(async ([ref, data]): Promise<Annotation | null> => {\n try {\n const locator = browser.getLocatorFromRef(ref);\n if (!locator) return null;\n const box = await locator.boundingBox();\n if (!box || box.width === 0 || box.height === 0) return null;\n const num = parseInt(ref.replace('e', ''), 10);\n return {\n ref,\n number: num,\n role: data.role,\n name: data.name || undefined,\n box: {\n x: Math.round(box.x),\n y: Math.round(box.y),\n width: Math.round(box.width),\n height: Math.round(box.height),\n },\n };\n } catch {\n return null;\n }\n })\n );\n\n // When a selector is provided the screenshot is cropped to that element,\n // so filter to annotations that overlap the target and shift coordinates.\n let targetBox: { x: number; y: number; width: number; height: number } | null = null;\n if (command.selector) {\n const raw = await browser.getLocator(command.selector).boundingBox();\n if (raw) {\n targetBox = {\n x: Math.round(raw.x),\n y: Math.round(raw.y),\n width: Math.round(raw.width),\n height: Math.round(raw.height),\n };\n }\n }\n\n const filtered = results.filter((a): a is Annotation => a !== null);\n\n // Filter by selector overlap if needed, but keep viewport-relative coords\n // for overlay positioning. Coordinate shifting happens later for metadata only.\n let overlayItems: Annotation[];\n if (targetBox) {\n const tb = targetBox;\n overlayItems = filtered\n .filter((a) => {\n const ax2 = a.box.x + a.box.width;\n const ay2 = a.box.y + a.box.height;\n const bx2 = tb.x + tb.width;\n const by2 = tb.y + tb.height;\n return a.box.x < bx2 && ax2 > tb.x && a.box.y < by2 && ay2 > tb.y;\n })\n .sort((a, b) => a.number - b.number);\n } else {\n overlayItems = filtered.sort((a, b) => a.number - b.number);\n }\n\n if (overlayItems.length > 0) {\n const overlayData = overlayItems.map((a) => ({\n number: a.number,\n x: a.box.x,\n y: a.box.y,\n width: a.box.width,\n height: a.box.height,\n }));\n\n // Uses position:absolute with document-relative coords so labels render\n // correctly for both viewport and fullPage screenshots, and when the\n // screenshot is scoped to a selector element.\n await page.evaluate(`(() => {\n var items = ${JSON.stringify(overlayData)};\n var id = ${JSON.stringify(ANNOTATION_OVERLAY_ID)};\n var sx = window.scrollX || 0;\n var sy = window.scrollY || 0;\n var c = document.createElement('div');\n c.id = id;\n c.style.cssText = 'position:absolute;top:0;left:0;width:0;height:0;pointer-events:none;z-index:2147483647;';\n for (var i = 0; i < items.length; i++) {\n var it = items[i];\n var dx = it.x + sx;\n var dy = it.y + sy;\n var b = document.createElement('div');\n b.style.cssText = 'position:absolute;left:' + dx + 'px;top:' + dy + 'px;width:' + it.width + 'px;height:' + it.height + 'px;border:2px solid rgba(255,0,0,0.8);box-sizing:border-box;pointer-events:none;';\n var l = document.createElement('div');\n l.textContent = String(it.number);\n var labelTop = dy < 14 ? '2px' : '-14px';\n l.style.cssText = 'position:absolute;top:' + labelTop + ';left:-2px;background:rgba(255,0,0,0.9);color:#fff;font:bold 11px/14px monospace;padding:0 4px;border-radius:2px;white-space:nowrap;';\n b.appendChild(l);\n c.appendChild(b);\n }\n document.documentElement.appendChild(c);\n })()`);\n overlayInjected = true;\n }\n\n // Build returned annotation metadata with image-relative coordinates.\n // Selector: shift to target-element-relative.\n // fullPage: convert to document-relative (matching fullPage image origin).\n // Default: viewport-relative (unchanged).\n if (targetBox) {\n const tb = targetBox;\n annotations = overlayItems.map((a) => ({\n ...a,\n box: {\n x: a.box.x - tb.x,\n y: a.box.y - tb.y,\n width: a.box.width,\n height: a.box.height,\n },\n }));\n } else if (command.fullPage) {\n const scroll = (await page.evaluate(\n `({x: window.scrollX || 0, y: window.scrollY || 0})`\n )) as { x: number; y: number };\n annotations = overlayItems.map((a) => ({\n ...a,\n box: {\n x: a.box.x + scroll.x,\n y: a.box.y + scroll.y,\n width: a.box.width,\n height: a.box.height,\n },\n }));\n } else {\n annotations = overlayItems;\n }\n }\n\n await target.screenshot({ ...options, path: savePath });\n\n if (overlayInjected) {\n await removeAnnotationOverlay(page);\n }\n\n return successResponse(command.id, {\n path: savePath,\n ...(annotations && annotations.length > 0 ? { annotations } : {}),\n });\n } catch (error) {\n if (overlayInjected) {\n await removeAnnotationOverlay(page);\n }\n if (command.selector) {\n throw toAIFriendlyError(error, command.selector);\n }\n throw error;\n }\n}\n\nasync function handleSnapshot(\n command: Command & {\n action: 'snapshot';\n interactive?: boolean;\n cursor?: boolean;\n maxDepth?: number;\n compact?: boolean;\n selector?: string;\n },\n browser: BrowserManager\n): Promise<Response<SnapshotData>> {\n // Use enhanced snapshot with refs and optional filtering\n const { tree, refs } = await browser.getSnapshot({\n interactive: command.interactive,\n cursor: command.cursor,\n maxDepth: command.maxDepth,\n compact: command.compact,\n selector: command.selector,\n });\n\n // Simplify refs for output (just role and name)\n const simpleRefs: Record<string, { role: string; name: string }> = {};\n for (const [ref, data] of Object.entries(refs)) {\n simpleRefs[ref] = { role: data.role, name: data.name };\n }\n\n const page = browser.getPage();\n return successResponse(command.id, {\n snapshot: tree || 'Empty page',\n refs: Object.keys(simpleRefs).length > 0 ? simpleRefs : undefined,\n origin: page.url(),\n });\n}\n\nasync function handleEvaluate(\n command: EvaluateCommand,\n browser: BrowserManager\n): Promise<Response<EvaluateData>> {\n const page = browser.getPage();\n\n // Evaluate the script directly as a string expression\n const result = await page.evaluate(command.script);\n\n return successResponse(command.id, { result, origin: page.url() });\n}\n\nasync function handleWait(command: WaitCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n\n if (command.text) {\n await page.waitForFunction(\n `(document.body.innerText || '').includes(${JSON.stringify(command.text)})`,\n { timeout: command.timeout }\n );\n } else if (command.selector) {\n await page.waitForSelector(command.selector, {\n state: command.state ?? 'visible',\n timeout: command.timeout,\n });\n } else if (command.timeout) {\n await page.waitForTimeout(command.timeout);\n } else {\n await page.waitForLoadState('load');\n }\n\n return successResponse(command.id, { waited: true });\n}\n\nasync function handleScroll(command: ScrollCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n\n let deltaX = command.x ?? 0;\n let deltaY = command.y ?? 0;\n const hasExplicitDelta = command.x !== undefined || command.y !== undefined;\n\n if (command.direction) {\n const amount = command.amount ?? 100;\n switch (command.direction) {\n case 'up':\n deltaY = -amount;\n break;\n case 'down':\n deltaY = amount;\n break;\n case 'left':\n deltaX = -amount;\n break;\n case 'right':\n deltaX = amount;\n break;\n }\n }\n\n if (command.selector) {\n const element = browser.getLocator(command.selector);\n await element.scrollIntoViewIfNeeded();\n\n if (hasExplicitDelta || deltaX !== 0 || deltaY !== 0) {\n await element.evaluate(\n (el, { x, y }) => {\n el.scrollBy(x, y);\n },\n { x: deltaX, y: deltaY }\n );\n }\n } else {\n await page.evaluate(`window.scrollBy(${deltaX}, ${deltaY})`);\n }\n\n return successResponse(command.id, { scrolled: true });\n}\n\nasync function handleSelect(command: SelectCommand, browser: BrowserManager): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n const values = Array.isArray(command.values) ? command.values : [command.values];\n\n try {\n await locator.selectOption(values);\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n\n return successResponse(command.id, { selected: values });\n}\n\nasync function handleHover(command: HoverCommand, browser: BrowserManager): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n try {\n await locator.hover();\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n\n return successResponse(command.id, { hovered: true });\n}\n\nasync function handleContent(\n command: ContentCommand,\n browser: BrowserManager\n): Promise<Response<ContentData>> {\n const page = browser.getPage();\n\n let html: string;\n if (command.selector) {\n const locator = browser.getLocator(command.selector);\n html = await locator.innerHTML();\n } else {\n html = await page.content();\n }\n\n return successResponse(command.id, { html, origin: page.url() });\n}\n\nasync function handleClose(\n command: Command & { action: 'close' },\n browser: BrowserManager\n): Promise<Response> {\n await browser.close();\n return successResponse(command.id, { closed: true });\n}\n\nasync function handleTabNew(\n command: TabNewCommand,\n browser: BrowserManager\n): Promise<Response<TabNewData>> {\n const result = await browser.newTab();\n\n // Navigate to URL if provided (same pattern as handleNavigate)\n if (command.url) {\n const page = browser.getPage();\n await page.goto(command.url, { waitUntil: 'domcontentloaded' });\n }\n\n return successResponse(command.id, result);\n}\n\nasync function handleTabList(\n command: Command & { action: 'tab_list' },\n browser: BrowserManager\n): Promise<Response<TabListData>> {\n const tabs = await browser.listTabs();\n return successResponse(command.id, {\n tabs,\n active: browser.getActiveIndex(),\n });\n}\n\nasync function handleTabSwitch(\n command: TabSwitchCommand,\n browser: BrowserManager\n): Promise<Response<TabSwitchData>> {\n const result = await browser.switchTo(command.index);\n const page = browser.getPage();\n return successResponse(command.id, {\n ...result,\n title: await page.title(),\n });\n}\n\nasync function handleTabClose(\n command: TabCloseCommand,\n browser: BrowserManager\n): Promise<Response<TabCloseData>> {\n const result = await browser.closeTab(command.index);\n return successResponse(command.id, result);\n}\n\nasync function handleWindowNew(\n command: WindowNewCommand,\n browser: BrowserManager\n): Promise<Response<TabNewData>> {\n const result = await browser.newWindow(command.viewport);\n return successResponse(command.id, result);\n}\n\n// New handlers for enhanced Playwright parity\n\nasync function handleFill(command: FillCommand, browser: BrowserManager): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n try {\n await locator.fill(command.value);\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n return successResponse(command.id, { filled: true });\n}\n\nasync function handleCheck(command: CheckCommand, browser: BrowserManager): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n try {\n await locator.check();\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n return successResponse(command.id, { checked: true });\n}\n\nasync function handleUncheck(command: UncheckCommand, browser: BrowserManager): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n try {\n await locator.uncheck();\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n return successResponse(command.id, { unchecked: true });\n}\n\nasync function handleUpload(command: UploadCommand, browser: BrowserManager): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n const files = Array.isArray(command.files) ? command.files : [command.files];\n try {\n await locator.setInputFiles(files);\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n return successResponse(command.id, { uploaded: files });\n}\n\nasync function handleDoubleClick(\n command: DoubleClickCommand,\n browser: BrowserManager\n): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n try {\n await locator.dblclick();\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n return successResponse(command.id, { clicked: true });\n}\n\nasync function handleFocus(command: FocusCommand, browser: BrowserManager): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n try {\n await locator.focus();\n } catch (error) {\n throw toAIFriendlyError(error, command.selector);\n }\n return successResponse(command.id, { focused: true });\n}\n\nasync function handleDrag(command: DragCommand, browser: BrowserManager): Promise<Response> {\n const frame = browser.getFrame();\n await frame.dragAndDrop(command.source, command.target);\n return successResponse(command.id, { dragged: true });\n}\n\nasync function handleFrame(command: FrameCommand, browser: BrowserManager): Promise<Response> {\n await browser.switchToFrame({\n selector: command.selector,\n name: command.name,\n url: command.url,\n });\n return successResponse(command.id, { switched: true });\n}\n\nasync function handleMainFrame(\n command: Command & { action: 'mainframe' },\n browser: BrowserManager\n): Promise<Response> {\n browser.switchToMainFrame();\n return successResponse(command.id, { switched: true });\n}\n\nasync function handleGetByRole(\n command: GetByRoleCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const locator = page.getByRole(command.role as any, { name: command.name, exact: command.exact });\n\n switch (command.subaction) {\n case 'click':\n await locator.click();\n return successResponse(command.id, { clicked: true });\n case 'fill':\n await locator.fill(command.value ?? '');\n return successResponse(command.id, { filled: true });\n case 'check':\n await locator.check();\n return successResponse(command.id, { checked: true });\n case 'hover':\n await locator.hover();\n return successResponse(command.id, { hovered: true });\n }\n}\n\nasync function handleGetByText(\n command: GetByTextCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const locator = page.getByText(command.text, { exact: command.exact });\n\n switch (command.subaction) {\n case 'click':\n await locator.click();\n return successResponse(command.id, { clicked: true });\n case 'hover':\n await locator.hover();\n return successResponse(command.id, { hovered: true });\n }\n}\n\nasync function handleGetByLabel(\n command: GetByLabelCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const locator = page.getByLabel(command.label, { exact: command.exact });\n\n switch (command.subaction) {\n case 'click':\n await locator.click();\n return successResponse(command.id, { clicked: true });\n case 'fill':\n await locator.fill(command.value ?? '');\n return successResponse(command.id, { filled: true });\n case 'check':\n await locator.check();\n return successResponse(command.id, { checked: true });\n }\n}\n\nasync function handleGetByPlaceholder(\n command: GetByPlaceholderCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const locator = page.getByPlaceholder(command.placeholder, { exact: command.exact });\n\n switch (command.subaction) {\n case 'click':\n await locator.click();\n return successResponse(command.id, { clicked: true });\n case 'fill':\n await locator.fill(command.value ?? '');\n return successResponse(command.id, { filled: true });\n }\n}\n\nasync function handleCookiesGet(\n command: Command & { action: 'cookies_get'; urls?: string[] },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const context = page.context();\n const cookies = await context.cookies(command.urls);\n return successResponse(command.id, { cookies });\n}\n\nasync function handleCookiesSet(\n command: CookiesSetCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const context = page.context();\n // Auto-fill URL for cookies that don't have domain/path/url set\n const pageUrl = page.url();\n const cookies = command.cookies.map((cookie) => {\n if (!cookie.url && !cookie.domain && !cookie.path) {\n return { ...cookie, url: pageUrl };\n }\n return cookie;\n });\n await context.addCookies(cookies);\n return successResponse(command.id, { set: true });\n}\n\nasync function handleCookiesClear(\n command: Command & { action: 'cookies_clear' },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const context = page.context();\n await context.clearCookies();\n return successResponse(command.id, { cleared: true });\n}\n\nasync function handleStorageGet(\n command: StorageGetCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const storageType = command.type === 'local' ? 'localStorage' : 'sessionStorage';\n\n if (command.key) {\n const value = await page.evaluate(`${storageType}.getItem(${JSON.stringify(command.key)})`);\n return successResponse(command.id, { key: command.key, value });\n } else {\n const data = await page.evaluate(`\n (() => {\n const storage = ${storageType};\n const result = {};\n for (let i = 0; i < storage.length; i++) {\n const key = storage.key(i);\n if (key) result[key] = storage.getItem(key);\n }\n return result;\n })()\n `);\n return successResponse(command.id, { data });\n }\n}\n\nasync function handleStorageSet(\n command: StorageSetCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const storageType = command.type === 'local' ? 'localStorage' : 'sessionStorage';\n\n await page.evaluate(\n `${storageType}.setItem(${JSON.stringify(command.key)}, ${JSON.stringify(command.value)})`\n );\n return successResponse(command.id, { set: true });\n}\n\nasync function handleStorageClear(\n command: StorageClearCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const storageType = command.type === 'local' ? 'localStorage' : 'sessionStorage';\n\n await page.evaluate(`${storageType}.clear()`);\n return successResponse(command.id, { cleared: true });\n}\n\nasync function handleDialog(command: DialogCommand, browser: BrowserManager): Promise<Response> {\n browser.setDialogHandler(command.response, command.promptText);\n return successResponse(command.id, { handler: 'set', response: command.response });\n}\n\nasync function handlePdf(command: PdfCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n await page.pdf({\n path: command.path,\n format: command.format ?? 'Letter',\n });\n return successResponse(command.id, { path: command.path });\n}\n\n// Network & Request handlers\n\nasync function handleRoute(command: RouteCommand, browser: BrowserManager): Promise<Response> {\n await browser.addRoute(command.url, {\n response: command.response,\n abort: command.abort,\n });\n return successResponse(command.id, { routed: command.url });\n}\n\nasync function handleUnroute(\n command: Command & { action: 'unroute'; url?: string },\n browser: BrowserManager\n): Promise<Response> {\n await browser.removeRoute(command.url);\n return successResponse(command.id, { unrouted: command.url ?? 'all' });\n}\n\nasync function handleRequests(\n command: RequestsCommand,\n browser: BrowserManager\n): Promise<Response> {\n if (command.clear) {\n browser.clearRequests();\n return successResponse(command.id, { cleared: true });\n }\n\n // Start tracking if not already\n browser.startRequestTracking();\n\n const requests = browser.getRequests(command.filter);\n return successResponse(command.id, { requests });\n}\n\nasync function handleDownload(\n command: DownloadCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const locator = browser.getLocator(command.selector);\n\n const [download] = await Promise.all([page.waitForEvent('download'), locator.click()]);\n\n await download.saveAs(command.path);\n return successResponse(command.id, {\n path: command.path,\n suggestedFilename: download.suggestedFilename(),\n });\n}\n\nasync function handleGeolocation(\n command: GeolocationCommand,\n browser: BrowserManager\n): Promise<Response> {\n await browser.setGeolocation(command.latitude, command.longitude, command.accuracy);\n return successResponse(command.id, {\n latitude: command.latitude,\n longitude: command.longitude,\n });\n}\n\nasync function handlePermissions(\n command: PermissionsCommand,\n browser: BrowserManager\n): Promise<Response> {\n await browser.setPermissions(command.permissions, command.grant);\n return successResponse(command.id, {\n permissions: command.permissions,\n granted: command.grant,\n });\n}\n\nasync function handleViewport(\n command: ViewportCommand,\n browser: BrowserManager\n): Promise<Response> {\n if (command.deviceScaleFactor && command.deviceScaleFactor !== 1) {\n await browser.setViewport(command.width, command.height);\n await browser.setDeviceScaleFactor(\n command.deviceScaleFactor,\n command.width,\n command.height,\n false\n );\n } else {\n // deviceScaleFactor is 1 or undefined -- clear any previously-set CDP\n // Emulation.setDeviceMetricsOverride so stale DPR doesn't persist.\n try {\n await browser.clearDeviceMetricsOverride();\n } catch {\n // Ignore if override was never set\n }\n await browser.setViewport(command.width, command.height);\n }\n\n const result: Record<string, unknown> = {\n width: command.width,\n height: command.height,\n };\n if (command.deviceScaleFactor !== undefined) {\n result.deviceScaleFactor = command.deviceScaleFactor;\n }\n return successResponse(command.id, result);\n}\n\nasync function handleUserAgent(\n command: Command & { action: 'useragent'; userAgent: string },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const context = page.context();\n // Note: Can't change user agent after context is created, but we can for new pages\n return successResponse(command.id, {\n note: 'User agent can only be set at launch time. Use device command instead.',\n });\n}\n\nasync function handleDevice(command: DeviceCommand, browser: BrowserManager): Promise<Response> {\n const device = browser.getDevice(command.device);\n if (!device) {\n const available = browser.listDevices().slice(0, 10).join(', ');\n throw new Error(`Unknown device: ${command.device}. Available: ${available}...`);\n }\n\n // Apply device viewport\n await browser.setViewport(device.viewport.width, device.viewport.height);\n\n // Apply or clear device scale factor\n if (device.deviceScaleFactor && device.deviceScaleFactor !== 1) {\n // Apply device scale factor for HiDPI/retina displays\n await browser.setDeviceScaleFactor(\n device.deviceScaleFactor,\n device.viewport.width,\n device.viewport.height,\n device.isMobile ?? false\n );\n } else {\n // Clear device scale factor override to restore default (1x)\n try {\n await browser.clearDeviceMetricsOverride();\n } catch {\n // Ignore error if override was never set\n }\n }\n\n return successResponse(command.id, {\n device: command.device,\n viewport: device.viewport,\n userAgent: device.userAgent,\n deviceScaleFactor: device.deviceScaleFactor,\n });\n}\n\nasync function handleBack(\n command: Command & { action: 'back' },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.goBack();\n return successResponse(command.id, { url: page.url() });\n}\n\nasync function handleForward(\n command: Command & { action: 'forward' },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.goForward();\n return successResponse(command.id, { url: page.url() });\n}\n\nasync function handleReload(\n command: Command & { action: 'reload' },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.reload();\n return successResponse(command.id, { url: page.url() });\n}\n\nasync function handleUrl(\n command: Command & { action: 'url' },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n return successResponse(command.id, { url: page.url() });\n}\n\nfunction handleCdpUrl(command: Command & { action: 'cdp_url' }, browser: BrowserManager): Response {\n const cdpUrl = browser.getCdpUrl();\n if (!cdpUrl) {\n return errorResponse(command.id, 'CDP URL not available (browser may not be launched)');\n }\n return successResponse(command.id, { cdpUrl });\n}\n\nasync function handleInspect(\n command: Command & { action: 'inspect' },\n _browser: BrowserManager\n): Promise<Response> {\n return errorResponse(command.id, 'Inspect server is not available in embedded engine mode');\n}\n\nasync function handleTitle(\n command: Command & { action: 'title' },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const title = await page.title();\n return successResponse(command.id, { title });\n}\n\nasync function handleGetAttribute(\n command: GetAttributeCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const locator = browser.getLocator(command.selector);\n const value = await locator.getAttribute(command.attribute);\n return successResponse(command.id, { attribute: command.attribute, value, origin: page.url() });\n}\n\nasync function handleGetText(command: GetTextCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n const locator = browser.getLocator(command.selector);\n const inner = await locator.innerText();\n const text = inner || (await locator.textContent()) || '';\n return successResponse(command.id, { text, origin: page.url() });\n}\n\nasync function handleIsVisible(\n command: IsVisibleCommand,\n browser: BrowserManager\n): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n const visible = await locator.isVisible();\n return successResponse(command.id, { visible });\n}\n\nasync function handleIsEnabled(\n command: IsEnabledCommand,\n browser: BrowserManager\n): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n const enabled = await locator.isEnabled();\n return successResponse(command.id, { enabled });\n}\n\nasync function handleIsChecked(\n command: IsCheckedCommand,\n browser: BrowserManager\n): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n const checked = await locator.isChecked();\n return successResponse(command.id, { checked });\n}\n\nasync function handleCount(command: CountCommand, browser: BrowserManager): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n const count = await locator.count();\n return successResponse(command.id, { count });\n}\n\nasync function handleBoundingBox(\n command: BoundingBoxCommand,\n browser: BrowserManager\n): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n const box = await locator.boundingBox();\n return successResponse(command.id, { box });\n}\n\nasync function handleStyles(\n command: StylesCommand,\n browser: BrowserManager\n): Promise<Response<StylesData>> {\n const page = browser.getPage();\n\n // Shared extraction logic as a string to be eval'd in browser context\n const extractStylesScript = `(function(el) {\n const s = getComputedStyle(el);\n const r = el.getBoundingClientRect();\n return {\n tag: el.tagName.toLowerCase(),\n text: el.innerText?.trim().slice(0, 80) || null,\n box: {\n x: Math.round(r.x),\n y: Math.round(r.y),\n width: Math.round(r.width),\n height: Math.round(r.height),\n },\n styles: {\n fontSize: s.fontSize,\n fontWeight: s.fontWeight,\n fontFamily: s.fontFamily.split(',')[0].trim().replace(/\"/g, ''),\n color: s.color,\n backgroundColor: s.backgroundColor,\n borderRadius: s.borderRadius,\n border: s.border !== 'none' && s.borderWidth !== '0px' ? s.border : null,\n boxShadow: s.boxShadow !== 'none' ? s.boxShadow : null,\n padding: s.padding,\n },\n };\n })`;\n\n // Check if it's a ref - single element\n if (browser.isRef(command.selector)) {\n const locator = browser.getLocator(command.selector);\n const element = (await locator.evaluate((el, script) => {\n const fn = eval(script);\n return fn(el);\n }, extractStylesScript)) as StylesData['elements'][0];\n return successResponse(command.id, { elements: [element] });\n }\n\n // CSS selector - can match multiple elements\n const elements = (await page.$$eval(\n command.selector,\n (els, script) => {\n const fn = eval(script);\n return els.map((el) => fn(el));\n },\n extractStylesScript\n )) as StylesData['elements'];\n\n return successResponse(command.id, { elements });\n}\n\n// Advanced handlers\n\nasync function handleVideoStart(\n command: Command & { action: 'video_start'; path: string },\n browser: BrowserManager\n): Promise<Response> {\n // Video recording requires context-level setup at launch\n // For now, return a note about this limitation\n return successResponse(command.id, {\n note: 'Video recording must be enabled at browser launch. Use --video flag when starting.',\n path: command.path,\n });\n}\n\nasync function handleVideoStop(\n command: Command & { action: 'video_stop' },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const video = page.video();\n if (video) {\n const path = await video.path();\n return successResponse(command.id, { path });\n }\n return successResponse(command.id, { note: 'No video recording active' });\n}\n\nasync function handleTraceStart(\n command: TraceStartCommand,\n browser: BrowserManager\n): Promise<Response> {\n await browser.startTracing({\n screenshots: command.screenshots,\n snapshots: command.snapshots,\n });\n return successResponse(command.id, { started: true });\n}\n\nasync function handleTraceStop(\n command: TraceStopCommand,\n browser: BrowserManager\n): Promise<Response> {\n await browser.stopTracing(command.path);\n return successResponse(\n command.id,\n command.path ? { path: command.path } : { traceStopped: true }\n );\n}\n\nasync function handleProfilerStart(\n command: ProfilerStartCommand,\n browser: BrowserManager\n): Promise<Response> {\n await browser.startProfiling({ categories: command.categories });\n return successResponse(command.id, { started: true });\n}\n\nasync function handleProfilerStop(\n command: ProfilerStopCommand,\n browser: BrowserManager\n): Promise<Response> {\n let outputPath = command.path;\n if (!outputPath) {\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const random = Math.random().toString(36).substring(2, 8);\n const filename = `profile-${timestamp}-${random}.json`;\n const profileDir = path.join(getAppDir(), 'tmp', 'profiles');\n mkdirSync(profileDir, { recursive: true });\n outputPath = path.join(profileDir, filename);\n }\n const result = await browser.stopProfiling(outputPath);\n return successResponse(command.id, result);\n}\n\nasync function handleHarStart(\n command: Command & { action: 'har_start' },\n browser: BrowserManager\n): Promise<Response> {\n await browser.startHarRecording();\n browser.startRequestTracking();\n return successResponse(command.id, { started: true });\n}\n\nasync function handleHarStop(command: HarStopCommand, browser: BrowserManager): Promise<Response> {\n // HAR recording is handled at context level\n // For now, we save tracked requests as a simplified HAR-like format\n const requests = browser.getRequests();\n return successResponse(command.id, {\n path: command.path,\n requestCount: requests.length,\n });\n}\n\nasync function handleStateSave(\n command: StorageStateSaveCommand,\n browser: BrowserManager\n): Promise<Response> {\n await browser.saveStorageState(command.path);\n return successResponse(command.id, { path: command.path });\n}\n\nasync function handleStateLoad(\n command: Command & { action: 'state_load'; path: string },\n browser: BrowserManager\n): Promise<Response> {\n if (browser.isLaunched()) {\n return errorResponse(\n command.id,\n 'Cannot load state while browser is running. Close browser first, then relaunch with loaded state.'\n );\n }\n\n if (!fs.existsSync(command.path)) {\n return errorResponse(command.id, `State file not found: ${command.path}`);\n }\n\n await browser.launch({\n headless: true,\n autoStateFilePath: command.path,\n });\n\n return successResponse(command.id, {\n loaded: true,\n path: command.path,\n });\n}\n\nasync function handleStateList(command: StateListCommand): Promise<Response> {\n const sessionsDir = getSessionsDir();\n const files = listStateFiles();\n\n if (files.length === 0) {\n return successResponse(command.id, { files: [], directory: sessionsDir });\n }\n\n const stateFiles = files\n .map((filename) => {\n const filepath = path.join(sessionsDir, filename);\n const stats = fs.statSync(filepath);\n\n let encrypted = false;\n try {\n const content = fs.readFileSync(filepath, 'utf-8');\n const parsed = JSON.parse(content);\n encrypted = isEncryptedPayload(parsed);\n } catch {\n // Ignore parse errors\n }\n\n return {\n filename,\n path: filepath,\n size: stats.size,\n modified: stats.mtime.toISOString(),\n encrypted,\n };\n })\n .sort((a, b) => new Date(b.modified).getTime() - new Date(a.modified).getTime());\n\n return successResponse(command.id, { files: stateFiles, directory: sessionsDir });\n}\n\nasync function handleStateClear(command: StateClearCommand): Promise<Response> {\n const sessionsDir = getSessionsDir();\n\n if (command.sessionName && !isValidSessionName(command.sessionName)) {\n return errorResponse(\n command.id,\n 'Invalid session name. Use only letters, numbers, dashes, and underscores.'\n );\n }\n\n const files = listStateFiles();\n if (files.length === 0) {\n return successResponse(command.id, { cleared: 0, deleted: [] });\n }\n\n const deleted: string[] = [];\n\n if (command.all) {\n for (const file of files) {\n fs.unlinkSync(path.join(sessionsDir, file));\n deleted.push(file);\n }\n } else if (command.sessionName) {\n for (const file of files) {\n if (file.startsWith(`${command.sessionName}-`)) {\n fs.unlinkSync(path.join(sessionsDir, file));\n deleted.push(file);\n }\n }\n }\n\n return successResponse(command.id, { cleared: deleted.length, deleted });\n}\n\nasync function handleStateShow(command: StateShowCommand): Promise<Response> {\n const sessionsDir = getSessionsDir();\n\n const baseName = command.filename.replace(/\\.json$/, '');\n if (!command.filename.endsWith('.json') || !isValidSessionName(baseName)) {\n return errorResponse(\n command.id,\n 'Invalid filename. Use only letters, numbers, dashes, and underscores (with .json extension).'\n );\n }\n\n const filepath = path.join(sessionsDir, command.filename);\n\n if (!fs.existsSync(filepath)) {\n return errorResponse(command.id, `State file not found: ${command.filename}`);\n }\n\n try {\n const { data: state, wasEncrypted } = readStateFile(filepath);\n const stats = fs.statSync(filepath);\n\n const stateObj = state as {\n cookies?: Array<{ domain: string }>;\n origins?: unknown[];\n };\n const cookies = stateObj.cookies?.length || 0;\n const origins = stateObj.origins?.length || 0;\n const domains = [...new Set((stateObj.cookies || []).map((c) => c.domain))];\n\n return successResponse(command.id, {\n filename: command.filename,\n path: filepath,\n size: stats.size,\n modified: stats.mtime.toISOString(),\n encrypted: wasEncrypted,\n summary: {\n cookies,\n origins,\n domains,\n },\n state,\n });\n } catch (e) {\n return errorResponse(command.id, `Failed to parse state file: ${(e as Error).message}`);\n }\n}\n\nasync function handleStateClean(command: StateCleanCommand): Promise<Response> {\n const deleted = cleanupExpiredStates(command.days);\n const keptCount = listStateFiles().length;\n\n return successResponse(command.id, {\n cleaned: deleted.length,\n deleted,\n keptCount,\n days: command.days,\n });\n}\n\nasync function handleStateRename(command: StateRenameCommand): Promise<Response> {\n const sessionsDir = getSessionsDir();\n\n if (!isValidSessionName(command.oldName) || !isValidSessionName(command.newName)) {\n return errorResponse(\n command.id,\n 'Invalid name. Use only letters, numbers, dashes, and underscores.'\n );\n }\n\n const oldPath = path.join(sessionsDir, `${command.oldName}.json`);\n const newPath = path.join(sessionsDir, `${command.newName}.json`);\n\n if (!fs.existsSync(oldPath)) {\n return errorResponse(command.id, `State file not found: ${command.oldName}.json`);\n }\n\n if (fs.existsSync(newPath)) {\n return errorResponse(command.id, `Destination already exists: ${command.newName}.json`);\n }\n\n fs.renameSync(oldPath, newPath);\n\n return successResponse(command.id, {\n renamed: true,\n oldName: `${command.oldName}.json`,\n newName: `${command.newName}.json`,\n path: newPath,\n });\n}\n\nasync function handleConsole(command: ConsoleCommand, browser: BrowserManager): Promise<Response> {\n if (command.clear) {\n browser.clearConsoleMessages();\n return successResponse(command.id, { cleared: true });\n }\n\n const page = browser.getPage();\n const messages = browser.getConsoleMessages();\n return successResponse(command.id, { messages, origin: page.url() });\n}\n\nasync function handleErrors(command: ErrorsCommand, browser: BrowserManager): Promise<Response> {\n if (command.clear) {\n browser.clearPageErrors();\n return successResponse(command.id, { cleared: true });\n }\n\n const errors = browser.getPageErrors();\n return successResponse(command.id, { errors });\n}\n\nasync function handleKeyboard(\n command: KeyboardCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const sub = command.subaction ?? 'press';\n\n switch (sub) {\n case 'type':\n await page.keyboard.type(command.text ?? '', { delay: command.delay });\n return successResponse(command.id, { typed: true, text: command.text });\n case 'press':\n await page.keyboard.press(command.keys ?? '');\n return successResponse(command.id, { pressed: command.keys });\n case 'insertText':\n await page.keyboard.insertText(command.text ?? '');\n return successResponse(command.id, { inserted: true, text: command.text });\n default:\n return errorResponse(command.id, `Unknown keyboard subaction: ${sub}`);\n }\n}\n\nasync function handleWheel(command: WheelCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n\n if (command.selector) {\n const element = browser.getLocator(command.selector);\n await element.hover();\n }\n\n await page.mouse.wheel(command.deltaX ?? 0, command.deltaY ?? 0);\n return successResponse(command.id, { scrolled: true });\n}\n\nasync function handleTap(command: TapCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n await page.tap(command.selector);\n return successResponse(command.id, { tapped: true });\n}\n\nasync function handleClipboard(\n command: ClipboardCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n\n switch (command.operation) {\n case 'copy':\n await page.keyboard.press('ControlOrMeta+c');\n return successResponse(command.id, { copied: true });\n case 'paste':\n await page.keyboard.press('ControlOrMeta+v');\n return successResponse(command.id, { pasted: true });\n case 'read': {\n const text = await page.evaluate('navigator.clipboard.readText()');\n return successResponse(command.id, { text });\n }\n case 'write': {\n if (!command.text) {\n return errorResponse(command.id, \"Missing 'text' parameter for clipboard write\");\n }\n await page.evaluate(`navigator.clipboard.writeText(${JSON.stringify(command.text)})`);\n return successResponse(command.id, { written: command.text });\n }\n default:\n return errorResponse(command.id, 'Unknown clipboard operation');\n }\n}\n\nasync function handleHighlight(\n command: HighlightCommand,\n browser: BrowserManager\n): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n await locator.highlight();\n return successResponse(command.id, { highlighted: true });\n}\n\nasync function handleClear(command: ClearCommand, browser: BrowserManager): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n await locator.clear();\n return successResponse(command.id, { cleared: true });\n}\n\nasync function handleSelectAll(\n command: SelectAllCommand,\n browser: BrowserManager\n): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n await locator.selectText();\n return successResponse(command.id, { selected: true });\n}\n\nasync function handleInnerText(\n command: InnerTextCommand,\n browser: BrowserManager\n): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n const text = await locator.innerText();\n return successResponse(command.id, { text });\n}\n\nasync function handleInnerHtml(\n command: InnerHtmlCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const locator = browser.getLocator(command.selector);\n const html = await locator.innerHTML();\n return successResponse(command.id, { html, origin: page.url() });\n}\n\nasync function handleInputValue(\n command: InputValueCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const locator = browser.getLocator(command.selector);\n const value = await locator.inputValue();\n return successResponse(command.id, { value, origin: page.url() });\n}\n\nasync function handleSetValue(\n command: SetValueCommand,\n browser: BrowserManager\n): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n await locator.fill(command.value);\n return successResponse(command.id, { set: true });\n}\n\nasync function handleDispatch(\n command: DispatchEventCommand,\n browser: BrowserManager\n): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n await locator.dispatchEvent(command.event, command.eventInit);\n return successResponse(command.id, { dispatched: command.event });\n}\n\nasync function handleEvalHandle(\n command: Command & { action: 'evalhandle'; script: string },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const handle = await page.evaluateHandle(command.script);\n const result = await handle.jsonValue().catch(() => 'Handle (non-serializable)');\n return successResponse(command.id, { result });\n}\n\nasync function handleExpose(\n command: Command & { action: 'expose'; name: string },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.exposeFunction(command.name, () => {\n // Exposed function - can be extended\n return `Function ${command.name} called`;\n });\n return successResponse(command.id, { exposed: command.name });\n}\n\nasync function handleAddScript(\n command: AddScriptCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n\n if (command.content) {\n await page.addScriptTag({ content: command.content });\n } else if (command.url) {\n await page.addScriptTag({ url: command.url });\n }\n\n return successResponse(command.id, { added: true });\n}\n\nasync function handleAddStyle(\n command: AddStyleCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n\n if (command.content) {\n await page.addStyleTag({ content: command.content });\n } else if (command.url) {\n await page.addStyleTag({ url: command.url });\n }\n\n return successResponse(command.id, { added: true });\n}\n\nasync function handleEmulateMedia(\n command: EmulateMediaCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.emulateMedia({\n media: command.media,\n colorScheme: command.colorScheme,\n reducedMotion: command.reducedMotion,\n forcedColors: command.forcedColors,\n });\n if (command.colorScheme) {\n browser.setColorScheme(command.colorScheme);\n }\n return successResponse(command.id, { emulated: true });\n}\n\nasync function handleOffline(command: OfflineCommand, browser: BrowserManager): Promise<Response> {\n await browser.setOffline(command.offline);\n return successResponse(command.id, { offline: command.offline });\n}\n\nasync function handleHeaders(command: HeadersCommand, browser: BrowserManager): Promise<Response> {\n await browser.setExtraHeaders(command.headers);\n return successResponse(command.id, { set: true });\n}\n\nasync function handlePause(\n command: Command & { action: 'pause' },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.pause();\n return successResponse(command.id, { paused: true });\n}\n\nasync function handleGetByAltText(\n command: GetByAltTextCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const locator = page.getByAltText(command.text, { exact: command.exact });\n\n switch (command.subaction) {\n case 'click':\n await locator.click();\n return successResponse(command.id, { clicked: true });\n case 'hover':\n await locator.hover();\n return successResponse(command.id, { hovered: true });\n }\n}\n\nasync function handleGetByTitle(\n command: GetByTitleCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const locator = page.getByTitle(command.text, { exact: command.exact });\n\n switch (command.subaction) {\n case 'click':\n await locator.click();\n return successResponse(command.id, { clicked: true });\n case 'hover':\n await locator.hover();\n return successResponse(command.id, { hovered: true });\n }\n}\n\nasync function handleGetByTestId(\n command: GetByTestIdCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const locator = page.getByTestId(command.testId);\n\n switch (command.subaction) {\n case 'click':\n await locator.click();\n return successResponse(command.id, { clicked: true });\n case 'fill':\n await locator.fill(command.value ?? '');\n return successResponse(command.id, { filled: true });\n case 'check':\n await locator.check();\n return successResponse(command.id, { checked: true });\n case 'hover':\n await locator.hover();\n return successResponse(command.id, { hovered: true });\n }\n}\n\nasync function handleNth(command: NthCommand, browser: BrowserManager): Promise<Response> {\n const base = browser.getLocator(command.selector);\n const locator = command.index === -1 ? base.last() : base.nth(command.index);\n\n switch (command.subaction) {\n case 'click':\n await locator.click();\n return successResponse(command.id, { clicked: true });\n case 'fill':\n await locator.fill(command.value ?? '');\n return successResponse(command.id, { filled: true });\n case 'check':\n await locator.check();\n return successResponse(command.id, { checked: true });\n case 'hover':\n await locator.hover();\n return successResponse(command.id, { hovered: true });\n case 'text':\n const text = await locator.textContent();\n return successResponse(command.id, { text });\n }\n}\n\nasync function handleWaitForUrl(\n command: WaitForUrlCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.waitForURL(command.url, { timeout: command.timeout });\n return successResponse(command.id, { url: page.url() });\n}\n\nasync function handleWaitForLoadState(\n command: WaitForLoadStateCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.waitForLoadState(command.state, { timeout: command.timeout });\n return successResponse(command.id, { state: command.state });\n}\n\nasync function handleSetContent(\n command: SetContentCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.setContent(command.html);\n return successResponse(command.id, { set: true });\n}\n\nasync function handleTimezone(\n command: TimezoneCommand,\n browser: BrowserManager\n): Promise<Response> {\n // Timezone must be set at context level before navigation\n // This is a limitation - it sets for the current context\n const page = browser.getPage();\n await page.context().setGeolocation({ latitude: 0, longitude: 0 }); // Trigger context awareness\n return successResponse(command.id, {\n note: 'Timezone must be set at browser launch. Use --timezone flag.',\n timezone: command.timezone,\n });\n}\n\nasync function handleLocale(command: LocaleCommand, browser: BrowserManager): Promise<Response> {\n // Locale must be set at context creation\n return successResponse(command.id, {\n note: 'Locale must be set at browser launch. Use --locale flag.',\n locale: command.locale,\n });\n}\n\nasync function handleCredentials(\n command: HttpCredentialsCommand,\n browser: BrowserManager\n): Promise<Response> {\n const context = browser.getPage().context();\n await context.setHTTPCredentials({\n username: command.username,\n password: command.password,\n });\n return successResponse(command.id, { set: true });\n}\n\nasync function handleMouseMove(\n command: MouseMoveCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.mouse.move(command.x, command.y);\n return successResponse(command.id, { moved: true, x: command.x, y: command.y });\n}\n\nasync function handleMouseDown(\n command: MouseDownCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.mouse.down({ button: command.button ?? 'left' });\n return successResponse(command.id, { down: true });\n}\n\nasync function handleMouseUp(command: MouseUpCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n await page.mouse.up({ button: command.button ?? 'left' });\n return successResponse(command.id, { up: true });\n}\n\nasync function handleBringToFront(\n command: Command & { action: 'bringtofront' },\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.bringToFront();\n return successResponse(command.id, { focused: true });\n}\n\nasync function handleWaitForFunction(\n command: WaitForFunctionCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.waitForFunction(command.expression, { timeout: command.timeout });\n return successResponse(command.id, { waited: true });\n}\n\nasync function handleScrollIntoView(\n command: ScrollIntoViewCommand,\n browser: BrowserManager\n): Promise<Response> {\n await browser.getLocator(command.selector).scrollIntoViewIfNeeded();\n return successResponse(command.id, { scrolled: true });\n}\n\nasync function handleAddInitScript(\n command: AddInitScriptCommand,\n browser: BrowserManager\n): Promise<Response> {\n const context = browser.getPage().context();\n await context.addInitScript(command.script);\n return successResponse(command.id, { added: true });\n}\n\nasync function handleKeyDown(command: KeyDownCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n await page.keyboard.down(command.key);\n return successResponse(command.id, { down: true, key: command.key });\n}\n\nasync function handleKeyUp(command: KeyUpCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n await page.keyboard.up(command.key);\n return successResponse(command.id, { up: true, key: command.key });\n}\n\nasync function handleInsertText(\n command: InsertTextCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n await page.keyboard.insertText(command.text);\n return successResponse(command.id, { inserted: true });\n}\n\nasync function handleMultiSelect(\n command: MultiSelectCommand,\n browser: BrowserManager\n): Promise<Response> {\n const locator = browser.getLocator(command.selector);\n const selected = await locator.selectOption(command.values);\n return successResponse(command.id, { selected });\n}\n\nasync function handleWaitForDownload(\n command: WaitForDownloadCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const download = await page.waitForEvent('download', { timeout: command.timeout });\n\n let filePath: string;\n if (command.path) {\n filePath = command.path;\n await download.saveAs(filePath);\n } else {\n filePath = (await download.path()) || download.suggestedFilename();\n }\n\n return successResponse(command.id, {\n path: filePath,\n filename: download.suggestedFilename(),\n url: download.url(),\n });\n}\n\nasync function handleResponseBody(\n command: ResponseBodyCommand,\n browser: BrowserManager\n): Promise<Response> {\n const page = browser.getPage();\n const response = await page.waitForResponse((resp) => resp.url().includes(command.url), {\n timeout: command.timeout,\n });\n\n const body = await response.text();\n let parsed: unknown = body;\n\n try {\n parsed = JSON.parse(body);\n } catch {\n // Keep as string if not JSON\n }\n\n return successResponse(command.id, {\n url: response.url(),\n status: response.status(),\n body: parsed,\n });\n}\n\n// Screencast and input injection handlers\n\nasync function handleScreencastStart(\n command: ScreencastStartCommand,\n browser: BrowserManager\n): Promise<Response<ScreencastStartData>> {\n if (!screencastFrameCallback) {\n throw new Error('Screencast frame callback not set. Start the streaming server first.');\n }\n\n await browser.startScreencast(screencastFrameCallback, {\n format: command.format,\n quality: command.quality,\n maxWidth: command.maxWidth,\n maxHeight: command.maxHeight,\n everyNthFrame: command.everyNthFrame,\n });\n\n return successResponse(command.id, {\n started: true,\n format: command.format ?? 'jpeg',\n quality: command.quality ?? 80,\n });\n}\n\nasync function handleScreencastStop(\n command: ScreencastStopCommand,\n browser: BrowserManager\n): Promise<Response<ScreencastStopData>> {\n await browser.stopScreencast();\n return successResponse(command.id, { stopped: true });\n}\n\nasync function handleInputMouse(\n command: InputMouseCommand,\n browser: BrowserManager\n): Promise<Response<InputEventData>> {\n await browser.injectMouseEvent({\n type: command.type,\n x: command.x,\n y: command.y,\n button: command.button,\n clickCount: command.clickCount,\n deltaX: command.deltaX,\n deltaY: command.deltaY,\n modifiers: command.modifiers,\n });\n return successResponse(command.id, { injected: true });\n}\n\nasync function handleInputKeyboard(\n command: InputKeyboardCommand,\n browser: BrowserManager\n): Promise<Response<InputEventData>> {\n await browser.injectKeyboardEvent({\n type: command.type,\n key: command.key,\n code: command.code,\n text: command.text,\n modifiers: command.modifiers,\n });\n return successResponse(command.id, { injected: true });\n}\n\nasync function handleInputTouch(\n command: InputTouchCommand,\n browser: BrowserManager\n): Promise<Response<InputEventData>> {\n await browser.injectTouchEvent({\n type: command.type,\n touchPoints: command.touchPoints,\n modifiers: command.modifiers,\n });\n return successResponse(command.id, { injected: true });\n}\n\n// Recording handlers (Playwright native video recording)\n\nasync function handleRecordingStart(\n command: RecordingStartCommand,\n browser: BrowserManager\n): Promise<Response<RecordingStartData>> {\n await browser.startRecording(command.path, command.url);\n return successResponse(command.id, {\n started: true,\n path: command.path,\n });\n}\n\nasync function handleRecordingStop(\n command: RecordingStopCommand,\n browser: BrowserManager\n): Promise<Response<RecordingStopData>> {\n const result = await browser.stopRecording();\n return successResponse(command.id, result);\n}\n\nasync function handleRecordingRestart(\n command: RecordingRestartCommand,\n browser: BrowserManager\n): Promise<Response<RecordingRestartData>> {\n const result = await browser.restartRecording(command.path, command.url);\n return successResponse(command.id, {\n started: true,\n path: command.path,\n previousPath: result.previousPath,\n stopped: result.stopped,\n });\n}\n\n// Diff handlers\n\nasync function handleDiffSnapshot(\n command: DiffSnapshotCommand,\n browser: BrowserManager\n): Promise<Response> {\n let before: string;\n\n if (command.baseline) {\n try {\n before = fs.readFileSync(command.baseline, 'utf-8');\n } catch {\n return errorResponse(command.id, `Cannot read baseline file: ${command.baseline}`);\n }\n } else {\n before = browser.getLastSnapshot();\n if (!before) {\n return errorResponse(\n command.id,\n 'No previous snapshot in this session. Take a snapshot first, or use --baseline <file>.'\n );\n }\n }\n\n const page = browser.getPage();\n const { tree } = await getEnhancedSnapshot(page, {\n selector: command.selector,\n compact: command.compact,\n maxDepth: command.maxDepth,\n });\n\n const after = tree || 'Empty page';\n const result = diffSnapshots(before, after);\n browser.setLastSnapshot(after);\n return successResponse(command.id, result);\n}\n\nasync function handleDiffScreenshot(\n command: DiffScreenshotCommand,\n browser: BrowserManager\n): Promise<Response> {\n if (!fs.existsSync(command.baseline)) {\n return errorResponse(command.id, `Baseline file not found: ${command.baseline}`);\n }\n\n const page = browser.getPage();\n let screenshotBuffer: Buffer;\n if (command.selector) {\n const locator = browser.getLocator(command.selector);\n screenshotBuffer = await locator.screenshot({ type: 'png' });\n } else {\n screenshotBuffer = await page.screenshot({ fullPage: command.fullPage, type: 'png' });\n }\n\n const baselineBuffer = fs.readFileSync(command.baseline);\n const ext = path.extname(command.baseline).toLowerCase();\n const baselineMime = ext === '.jpg' || ext === '.jpeg' ? 'image/jpeg' : 'image/png';\n\n const result = await diffScreenshots(page.context(), baselineBuffer, screenshotBuffer, {\n threshold: command.threshold,\n outputPath: command.output,\n baselineMime,\n });\n\n return successResponse(command.id, result);\n}\n\nasync function handleDiffUrl(command: DiffUrlCommand, browser: BrowserManager): Promise<Response> {\n const page = browser.getPage();\n\n const waitUntil = command.waitUntil ?? 'load';\n const snapshotOpts = {\n selector: command.selector,\n compact: command.compact,\n maxDepth: command.maxDepth,\n };\n\n // Capture state of url1\n await page.goto(command.url1, { waitUntil });\n const { tree: tree1 } = await getEnhancedSnapshot(page, snapshotOpts);\n const snapshot1 = tree1 || 'Empty page';\n let screenshot1: Buffer | undefined;\n if (command.screenshot) {\n screenshot1 = await page.screenshot({ fullPage: command.fullPage, type: 'png' });\n }\n\n // Capture state of url2\n await page.goto(command.url2, { waitUntil });\n const { tree: tree2 } = await getEnhancedSnapshot(page, snapshotOpts);\n const snapshot2 = tree2 || 'Empty page';\n\n const snapshotDiff = diffSnapshots(snapshot1, snapshot2);\n\n const result: DiffUrlData = { snapshot: snapshotDiff };\n\n if (command.screenshot && screenshot1) {\n const screenshot2 = await page.screenshot({ fullPage: command.fullPage, type: 'png' });\n result.screenshot = await diffScreenshots(page.context(), screenshot1, screenshot2, {});\n }\n\n return successResponse(command.id, result);\n}\n\nasync function handleAuthLogin(\n command: AuthLoginCommand,\n browser: BrowserManager\n): Promise<Response> {\n const profile = getAuthProfile(command.name);\n if (!profile) {\n return errorResponse(command.id, `Auth profile '${command.name}' not found`);\n }\n\n browser.checkDomainAllowed(profile.url);\n\n const page = browser.getPage();\n await page.goto(profile.url, { waitUntil: 'load' });\n\n const usingAutoDetect =\n !profile.usernameSelector && !profile.passwordSelector && !profile.submitSelector;\n if (usingAutoDetect) {\n console.error(\n `[agent-browser] Auth login '${command.name}': using auto-detected form selectors. ` +\n `If login fails, specify --username-selector/--password-selector/--submit-selector with auth save.`\n );\n }\n\n const passSel = profile.passwordSelector || 'input[type=\"password\"]:visible';\n\n // Auto-detect selectors ordered from most specific to broadest.\n // Locale-dependent text matchers (e.g. \"Sign in\") are intentionally\n // excluded -- they break on non-English pages.\n const AUTO_USER_SELECTORS = [\n 'input[autocomplete=\"username\"]:visible',\n 'input[type=\"email\"]:visible',\n 'input[name=\"username\"]:visible',\n 'input[name=\"email\"]:visible',\n ];\n const AUTO_SUBMIT_SELECTORS = ['button[type=\"submit\"]:visible', 'input[type=\"submit\"]:visible'];\n\n try {\n // Resolve username field: custom selector or sequential auto-detect\n let userLocator;\n if (profile.usernameSelector) {\n userLocator = page.locator(profile.usernameSelector).first();\n } else {\n userLocator = null;\n for (const sel of AUTO_USER_SELECTORS) {\n const loc = page.locator(sel).first();\n if (await loc.isVisible({ timeout: 1000 }).catch(() => false)) {\n userLocator = loc;\n break;\n }\n }\n if (!userLocator) {\n return errorResponse(\n command.id,\n `Auth login failed for '${command.name}': could not find username field. ` +\n `Specify --username-selector with auth save.`\n );\n }\n }\n\n // Resolve submit button: custom selector or sequential auto-detect\n let submitLocator;\n if (profile.submitSelector) {\n submitLocator = page.locator(profile.submitSelector).first();\n } else {\n submitLocator = null;\n for (const sel of AUTO_SUBMIT_SELECTORS) {\n const loc = page.locator(sel).first();\n if (await loc.isVisible({ timeout: 1000 }).catch(() => false)) {\n submitLocator = loc;\n break;\n }\n }\n if (!submitLocator) {\n return errorResponse(\n command.id,\n `Auth login failed for '${command.name}': could not find submit button. ` +\n `Specify --submit-selector with auth save.`\n );\n }\n }\n\n await userLocator.fill(profile.username);\n await page.locator(passSel).first().fill(profile.password);\n await submitLocator.click();\n await page.waitForLoadState('load');\n } catch (err) {\n return errorResponse(\n command.id,\n `Auth login failed for '${command.name}': ${err instanceof Error ? err.message : err}. ` +\n `Try specifying custom selectors with auth save --username-selector/--password-selector/--submit-selector`\n );\n }\n\n updateLastLogin(command.name);\n\n return successResponse(command.id, {\n loggedIn: true,\n name: command.name,\n url: page.url(),\n title: await page.title(),\n });\n}\n\nasync function handleConfirm(command: ConfirmCommand, browser: BrowserManager): Promise<Response> {\n const entry = getAndRemovePending(command.confirmationId);\n if (!entry) {\n return errorResponse(command.id, `No pending confirmation with id '${command.confirmationId}'`);\n }\n\n // Re-validate the stored command through the schema to guard against\n // shape drift between when the confirmation was issued and now.\n const parseResult = parseCommand(JSON.stringify(entry.command));\n if (!parseResult.success) {\n return errorResponse(command.id, `Stored command is no longer valid: ${parseResult.error}`);\n }\n const originalCommand = parseResult.command;\n\n // Re-check deny list in case policy was updated since the confirmation was issued\n actionPolicy = reloadPolicyIfChanged();\n const decision = checkPolicy(originalCommand.action, actionPolicy, new Set());\n if (decision === 'deny') {\n const category = getActionCategory(originalCommand.action);\n return errorResponse(command.id, `Action denied by policy: '${category}' is not allowed`);\n }\n\n return await dispatchAction(originalCommand, browser);\n}\n\nfunction handleDeny(command: DenyCommand): Response {\n const entry = getAndRemovePending(command.confirmationId);\n if (!entry) {\n return errorResponse(command.id, `No pending confirmation with id '${command.confirmationId}'`);\n }\n return successResponse(command.id, { denied: true });\n}\n","import { readFileSync, statSync } from 'node:fs';\nimport { resolve } from 'node:path';\n\nexport interface ActionPolicy {\n default: 'allow' | 'deny';\n allow?: string[];\n deny?: string[];\n}\n\nexport type PolicyDecision = 'allow' | 'deny' | 'confirm';\n\nconst ACTION_CATEGORIES: Record<string, string> = {\n navigate: 'navigate',\n back: 'navigate',\n forward: 'navigate',\n reload: 'navigate',\n tab_new: 'navigate',\n\n click: 'click',\n dblclick: 'click',\n tap: 'click',\n\n fill: 'fill',\n type: 'fill',\n // The `keyboard` action is a compound command that dispatches to sub-actions\n // (type, inserttext, press, down, up). Its primary use is text input, so it\n // maps to 'fill'. The interact-like sub-actions (press, down, up) are less\n // common and don't have separate top-level action names in the protocol.\n keyboard: 'fill',\n inserttext: 'fill',\n select: 'fill',\n multiselect: 'fill',\n check: 'fill',\n uncheck: 'fill',\n clear: 'fill',\n selectall: 'fill',\n setvalue: 'fill',\n\n download: 'download',\n waitfordownload: 'download',\n\n upload: 'upload',\n\n evaluate: 'eval',\n evalhandle: 'eval',\n addscript: 'eval',\n addinitscript: 'eval',\n\n snapshot: 'snapshot',\n screenshot: 'snapshot',\n pdf: 'snapshot',\n diff_snapshot: 'snapshot',\n diff_screenshot: 'snapshot',\n diff_url: 'snapshot',\n\n scroll: 'scroll',\n scrollintoview: 'scroll',\n\n wait: 'wait',\n waitforurl: 'wait',\n waitforloadstate: 'wait',\n waitforfunction: 'wait',\n\n gettext: 'get',\n content: 'get',\n innerhtml: 'get',\n innertext: 'get',\n inputvalue: 'get',\n url: 'get',\n title: 'get',\n getattribute: 'get',\n count: 'get',\n boundingbox: 'get',\n styles: 'get',\n isvisible: 'get',\n isenabled: 'get',\n ischecked: 'get',\n responsebody: 'get',\n\n route: 'network',\n unroute: 'network',\n requests: 'network',\n\n state_save: 'state',\n state_load: 'state',\n cookies_set: 'state',\n storage_set: 'state',\n credentials: 'state',\n\n hover: 'interact',\n focus: 'interact',\n drag: 'interact',\n press: 'interact',\n keydown: 'interact',\n keyup: 'interact',\n mousemove: 'interact',\n mousedown: 'interact',\n mouseup: 'interact',\n wheel: 'interact',\n dispatch: 'interact',\n\n // These are always allowed (internal/meta operations)\n launch: '_internal',\n close: '_internal',\n tab_list: '_internal',\n tab_switch: '_internal',\n tab_close: '_internal',\n window_new: '_internal',\n frame: '_internal',\n mainframe: '_internal',\n dialog: '_internal',\n session: '_internal',\n console: '_internal',\n errors: '_internal',\n cookies_get: '_internal',\n cookies_clear: '_internal',\n storage_get: '_internal',\n storage_clear: '_internal',\n state_list: '_internal',\n state_show: '_internal',\n state_clear: '_internal',\n state_clean: '_internal',\n state_rename: '_internal',\n highlight: '_internal',\n bringtofront: '_internal',\n trace_start: '_internal',\n trace_stop: '_internal',\n har_start: '_internal',\n har_stop: '_internal',\n video_start: '_internal',\n video_stop: '_internal',\n recording_start: '_internal',\n recording_stop: '_internal',\n recording_restart: '_internal',\n profiler_start: '_internal',\n profiler_stop: '_internal',\n clipboard: '_internal',\n viewport: '_internal',\n useragent: '_internal',\n device: '_internal',\n geolocation: '_internal',\n permissions: '_internal',\n emulatemedia: '_internal',\n offline: '_internal',\n headers: '_internal',\n addstyle: 'eval',\n expose: 'eval',\n timezone: '_internal',\n locale: '_internal',\n pause: '_internal',\n setcontent: 'eval',\n screencast_start: '_internal',\n screencast_stop: '_internal',\n input_mouse: '_internal',\n input_keyboard: '_internal',\n input_touch: '_internal',\n\n auth_save: '_internal',\n auth_login: '_internal',\n auth_list: '_internal',\n auth_delete: '_internal',\n auth_show: '_internal',\n confirm: '_internal',\n deny: '_internal',\n\n // Find/semantic locator actions (read-only element resolution)\n getbyrole: 'get',\n getbytext: 'get',\n getbylabel: 'get',\n getbyplaceholder: 'get',\n getbyalttext: 'get',\n getbytitle: 'get',\n getbytestid: 'get',\n nth: 'get',\n};\n\n// User-facing categories used in policy files. '_internal' is excluded because\n// internal actions always bypass policy. 'unknown' is intentionally not a value\n// in ACTION_CATEGORIES -- it is only the fallback return of getActionCategory()\n// for unrecognized actions. If a user puts \"unknown\" in a policy file,\n// loadPolicyFile will warn about it as unrecognized, which is correct.\nexport const KNOWN_CATEGORIES = new Set(\n Object.values(ACTION_CATEGORIES).filter((c) => c !== '_internal')\n);\n\nexport function getActionCategory(action: string): string {\n return ACTION_CATEGORIES[action] ?? 'unknown';\n}\n\nexport function loadPolicyFile(policyPath: string): ActionPolicy {\n const resolved = resolve(policyPath);\n const content = readFileSync(resolved, 'utf-8');\n const policy = JSON.parse(content) as ActionPolicy;\n\n if (policy.default !== 'allow' && policy.default !== 'deny') {\n throw new Error(\n `Invalid action policy: \"default\" must be \"allow\" or \"deny\", got \"${policy.default}\"`\n );\n }\n\n for (const list of [policy.allow, policy.deny]) {\n if (!list) continue;\n for (const category of list) {\n if (!KNOWN_CATEGORIES.has(category)) {\n console.warn(\n `[agent-browser] Warning: unrecognized action category \"${category}\" in policy file. ` +\n `Known categories: ${[...KNOWN_CATEGORIES].sort().join(', ')}`\n );\n }\n }\n }\n\n return policy;\n}\n\nlet cachedPolicyPath: string | null = null;\nlet cachedPolicyMtimeMs = 0;\nlet cachedPolicy: ActionPolicy | null = null;\nconst RELOAD_CHECK_INTERVAL_MS = 5_000;\nlet lastCheckMs = 0;\n\nexport function initPolicyReloader(policyPath: string, policy: ActionPolicy): void {\n cachedPolicyPath = resolve(policyPath);\n cachedPolicyMtimeMs = statSync(cachedPolicyPath).mtimeMs;\n cachedPolicy = policy;\n}\n\nexport function reloadPolicyIfChanged(): ActionPolicy | null {\n if (!cachedPolicyPath) return cachedPolicy;\n\n const now = Date.now();\n if (now - lastCheckMs < RELOAD_CHECK_INTERVAL_MS) return cachedPolicy;\n lastCheckMs = now;\n\n try {\n const currentMtime = statSync(cachedPolicyPath).mtimeMs;\n if (currentMtime !== cachedPolicyMtimeMs) {\n cachedPolicy = loadPolicyFile(cachedPolicyPath);\n cachedPolicyMtimeMs = currentMtime;\n }\n } catch {\n // File may have been removed; keep using cached policy\n }\n\n return cachedPolicy;\n}\n\nexport function checkPolicy(\n action: string,\n policy: ActionPolicy | null,\n confirmCategories: Set<string>\n): PolicyDecision {\n const category = getActionCategory(action);\n\n // Internal actions are always allowed\n if (category === '_internal') return 'allow';\n\n // Explicit deny takes precedence over confirmation\n if (policy?.deny?.includes(category)) return 'deny';\n\n // Check if this category requires confirmation\n if (confirmCategories.has(category)) return 'confirm';\n\n if (!policy) return 'allow';\n\n // Explicit allow list\n if (policy.allow?.includes(category)) return 'allow';\n\n return policy.default;\n}\n\nexport function describeAction(action: string, command: Record<string, unknown>): string {\n const category = getActionCategory(action);\n switch (action) {\n case 'navigate':\n return `Navigate to ${command.url}`;\n case 'evaluate':\n case 'evalhandle':\n return `Evaluate JavaScript: ${String(command.script ?? '').slice(0, 80)}`;\n case 'fill':\n return `Fill ${command.selector}`;\n case 'type':\n return `Type into ${command.selector}`;\n case 'click':\n return `Click ${command.selector}`;\n case 'dblclick':\n return `Double-click ${command.selector}`;\n case 'tap':\n return `Tap ${command.selector}`;\n case 'download':\n return `Download via ${command.selector} to ${command.path}`;\n case 'upload':\n return `Upload files to ${command.selector}`;\n default:\n return `${category}: ${action}`;\n }\n}\n","import { randomBytes } from 'node:crypto';\n\ninterface PendingConfirmation {\n id: string;\n action: string;\n category: string;\n description: string;\n command: Record<string, unknown>;\n timer: ReturnType<typeof setTimeout>;\n}\n\nconst AUTO_DENY_TIMEOUT_MS = 60_000;\n\nconst pending = new Map<string, PendingConfirmation>();\n\nfunction generateId(): string {\n return `c_${randomBytes(8).toString('hex')}`;\n}\n\nexport function requestConfirmation(\n action: string,\n category: string,\n description: string,\n command: Record<string, unknown>\n): { confirmationId: string } {\n const id = generateId();\n\n const timer = setTimeout(() => {\n pending.delete(id);\n }, AUTO_DENY_TIMEOUT_MS);\n\n pending.set(id, {\n id,\n action,\n category,\n description,\n command,\n timer,\n });\n\n return { confirmationId: id };\n}\n\nexport function getAndRemovePending(\n id: string\n): { command: Record<string, unknown>; action: string } | null {\n const entry = pending.get(id);\n if (!entry) return null;\n\n clearTimeout(entry.timer);\n pending.delete(id);\n return { command: entry.command, action: entry.action };\n}\n","import {\n existsSync,\n mkdirSync,\n readFileSync,\n writeFileSync,\n readdirSync,\n unlinkSync,\n} from 'node:fs';\nimport path from 'node:path';\nimport os from 'node:os';\nimport {\n getEncryptionKey,\n ensureEncryptionKey,\n encryptData,\n decryptData,\n isEncryptedPayload,\n getKeyFilePath,\n restrictFilePermissions,\n restrictDirPermissions,\n type EncryptedPayload,\n} from './encryption.js';\n\nconst AUTH_DIR = 'auth';\n\ninterface AuthProfile {\n name: string;\n url: string;\n username: string;\n password: string;\n usernameSelector?: string;\n passwordSelector?: string;\n submitSelector?: string;\n createdAt: string;\n lastLoginAt?: string;\n}\n\nexport interface AuthProfileMeta {\n name: string;\n url: string;\n username: string;\n createdAt: string;\n lastLoginAt?: string;\n}\n\nfunction getAuthDir(): string {\n const dir = path.join(os.homedir(), '.agent-browser', AUTH_DIR);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n restrictDirPermissions(dir);\n }\n return dir;\n}\n\nconst SAFE_NAME_RE = /^[a-zA-Z0-9_-]+$/;\n\nfunction validateProfileName(name: string): void {\n if (!SAFE_NAME_RE.test(name)) {\n throw new Error(\n `Invalid auth profile name '${name}': only alphanumeric characters, hyphens, and underscores are allowed`\n );\n }\n}\n\nfunction profilePath(name: string): string {\n validateProfileName(name);\n return path.join(getAuthDir(), `${name}.json`);\n}\n\nfunction readProfile(name: string): AuthProfile | null {\n const p = profilePath(name);\n if (!existsSync(p)) return null;\n\n const raw = readFileSync(p, 'utf-8');\n const parsed = JSON.parse(raw);\n\n if (isEncryptedPayload(parsed)) {\n const key = getEncryptionKey();\n if (!key) {\n throw new Error(\n `Encryption key required to read encrypted auth profiles. ` +\n `Set AGENT_BROWSER_ENCRYPTION_KEY or ensure ${getKeyFilePath()} exists.`\n );\n }\n const decrypted = decryptData(parsed as EncryptedPayload, key);\n return JSON.parse(decrypted) as AuthProfile;\n }\n\n return parsed as AuthProfile;\n}\n\nfunction writeProfile(profile: AuthProfile): void {\n const key = ensureEncryptionKey();\n const serialized = JSON.stringify(profile, null, 2);\n const encrypted = encryptData(serialized, key);\n const filePath = profilePath(profile.name);\n writeFileSync(filePath, JSON.stringify(encrypted, null, 2), {\n mode: 0o600,\n });\n restrictFilePermissions(filePath);\n}\n\nexport function saveAuthProfile(opts: {\n name: string;\n url: string;\n username: string;\n password: string;\n usernameSelector?: string;\n passwordSelector?: string;\n submitSelector?: string;\n}): AuthProfileMeta & { updated: boolean } {\n const existing = readProfile(opts.name);\n\n const profile: AuthProfile = {\n name: opts.name,\n url: opts.url,\n username: opts.username,\n password: opts.password,\n usernameSelector: opts.usernameSelector,\n passwordSelector: opts.passwordSelector,\n submitSelector: opts.submitSelector,\n createdAt: existing?.createdAt ?? new Date().toISOString(),\n lastLoginAt: existing?.lastLoginAt,\n };\n\n writeProfile(profile);\n\n return {\n name: profile.name,\n url: profile.url,\n username: profile.username,\n createdAt: profile.createdAt,\n lastLoginAt: profile.lastLoginAt,\n updated: existing !== null,\n };\n}\n\nexport function getAuthProfile(name: string): AuthProfile | null {\n return readProfile(name);\n}\n\nexport function getAuthProfileMeta(name: string): AuthProfileMeta | null {\n const profile = readProfile(name);\n if (!profile) return null;\n return {\n name: profile.name,\n url: profile.url,\n username: profile.username,\n createdAt: profile.createdAt,\n lastLoginAt: profile.lastLoginAt,\n };\n}\n\nexport function listAuthProfiles(): AuthProfileMeta[] {\n const dir = getAuthDir();\n const files = readdirSync(dir).filter((f) => f.endsWith('.json'));\n const profiles: AuthProfileMeta[] = [];\n\n for (const file of files) {\n const name = file.replace(/\\.json$/, '');\n try {\n const meta = getAuthProfileMeta(name);\n if (meta) profiles.push(meta);\n } catch {\n profiles.push({\n name,\n url: '(encrypted)',\n username: '(encrypted)',\n createdAt: '(unknown)',\n });\n }\n }\n\n return profiles;\n}\n\nexport function deleteAuthProfile(name: string): boolean {\n const p = profilePath(name);\n if (!existsSync(p)) return false;\n unlinkSync(p);\n return true;\n}\n\nexport function updateLastLogin(name: string): void {\n const profile = readProfile(name);\n if (profile) {\n profile.lastLoginAt = new Date().toISOString();\n writeProfile(profile);\n }\n}\n","import { z } from 'zod';\nimport type { Command, Response } from './types.js';\n\n// Base schema for all commands\nconst baseCommandSchema = z.object({\n id: z.string(),\n action: z.string(),\n});\n\n// Individual action schemas\nconst launchSchema = baseCommandSchema.extend({\n action: z.literal('launch'),\n headless: z.boolean().optional(),\n viewport: z\n .object({\n width: z.number().positive(),\n height: z.number().positive(),\n })\n .nullable()\n .optional(),\n browser: z.enum(['chromium', 'firefox', 'webkit']).optional(),\n cdpPort: z.number().positive().optional(),\n cdpUrl: z\n .string()\n .url()\n .refine(\n (url) =>\n url.startsWith('ws://') ||\n url.startsWith('wss://') ||\n url.startsWith('http://') ||\n url.startsWith('https://'),\n { message: 'CDP URL must start with ws://, wss://, http://, or https://' }\n )\n .optional(),\n autoConnect: z.boolean().optional(),\n executablePath: z.string().optional(),\n extensions: z.array(z.string()).optional(),\n headers: z.record(z.string(), z.string()).optional(),\n proxy: z\n .object({\n server: z.string().min(1),\n bypass: z.string().optional(),\n username: z.string().optional(),\n password: z.string().optional(),\n })\n .optional(),\n args: z.array(z.string()).optional(),\n userAgent: z.string().optional(),\n provider: z.string().optional(),\n ignoreHTTPSErrors: z.boolean().optional(),\n allowFileAccess: z.boolean().optional(),\n colorScheme: z.enum(['light', 'dark', 'no-preference']).optional(),\n downloadPath: z.string().optional(),\n profile: z.string().optional(),\n storageState: z.string().optional(),\n allowedDomains: z.array(z.string()).optional(),\n actionPolicy: z.string().optional(),\n confirmActions: z.array(z.string()).optional(),\n engine: z.enum(['chrome', 'lightpanda']).optional(),\n});\n\nconst navigateSchema = baseCommandSchema.extend({\n action: z.literal('navigate'),\n url: z.string().min(1),\n waitUntil: z.enum(['load', 'domcontentloaded', 'networkidle']).optional(),\n headers: z.record(z.string(), z.string()).optional(),\n});\n\nconst clickSchema = baseCommandSchema.extend({\n action: z.literal('click'),\n selector: z.string().min(1),\n button: z.enum(['left', 'right', 'middle']).optional(),\n clickCount: z.number().positive().optional(),\n delay: z.number().nonnegative().optional(),\n newTab: z.boolean().optional(),\n});\n\nconst typeSchema = baseCommandSchema.extend({\n action: z.literal('type'),\n selector: z.string().min(1),\n text: z.string(),\n delay: z.number().nonnegative().optional(),\n clear: z.boolean().optional(),\n});\n\nconst fillSchema = baseCommandSchema.extend({\n action: z.literal('fill'),\n selector: z.string().min(1),\n value: z.string(),\n});\n\nconst checkSchema = baseCommandSchema.extend({\n action: z.literal('check'),\n selector: z.string().min(1),\n});\n\nconst uncheckSchema = baseCommandSchema.extend({\n action: z.literal('uncheck'),\n selector: z.string().min(1),\n});\n\nconst uploadSchema = baseCommandSchema.extend({\n action: z.literal('upload'),\n selector: z.string().min(1),\n files: z.union([z.string(), z.array(z.string())]),\n});\n\nconst dblclickSchema = baseCommandSchema.extend({\n action: z.literal('dblclick'),\n selector: z.string().min(1),\n});\n\nconst focusSchema = baseCommandSchema.extend({\n action: z.literal('focus'),\n selector: z.string().min(1),\n});\n\nconst dragSchema = baseCommandSchema.extend({\n action: z.literal('drag'),\n source: z.string().min(1),\n target: z.string().min(1),\n});\n\nconst frameSchema = baseCommandSchema.extend({\n action: z.literal('frame'),\n selector: z.string().min(1).optional(),\n name: z.string().optional(),\n url: z.string().optional(),\n});\n\nconst mainframeSchema = baseCommandSchema.extend({\n action: z.literal('mainframe'),\n});\n\nconst getByRoleSchema = baseCommandSchema.extend({\n action: z.literal('getbyrole'),\n role: z.string().min(1),\n name: z.string().optional(),\n exact: z.boolean().optional(),\n subaction: z.enum(['click', 'fill', 'check', 'hover']),\n value: z.string().optional(),\n});\n\nconst getByTextSchema = baseCommandSchema.extend({\n action: z.literal('getbytext'),\n text: z.string().min(1),\n exact: z.boolean().optional(),\n subaction: z.enum(['click', 'hover']),\n});\n\nconst getByLabelSchema = baseCommandSchema.extend({\n action: z.literal('getbylabel'),\n label: z.string().min(1),\n exact: z.boolean().optional(),\n subaction: z.enum(['click', 'fill', 'check']),\n value: z.string().optional(),\n});\n\nconst getByPlaceholderSchema = baseCommandSchema.extend({\n action: z.literal('getbyplaceholder'),\n placeholder: z.string().min(1),\n exact: z.boolean().optional(),\n subaction: z.enum(['click', 'fill']),\n value: z.string().optional(),\n});\n\nconst cookiesGetSchema = baseCommandSchema.extend({\n action: z.literal('cookies_get'),\n urls: z.array(z.string()).optional(),\n});\n\nconst cookiesSetSchema = baseCommandSchema.extend({\n action: z.literal('cookies_set'),\n cookies: z.array(\n z.object({\n name: z.string(),\n value: z.string(),\n url: z.string().optional(),\n domain: z.string().optional(),\n path: z.string().optional(),\n expires: z.number().optional(),\n httpOnly: z.boolean().optional(),\n secure: z.boolean().optional(),\n sameSite: z.enum(['Strict', 'Lax', 'None']).optional(),\n })\n ),\n});\n\nconst cookiesClearSchema = baseCommandSchema.extend({\n action: z.literal('cookies_clear'),\n});\n\nconst storageGetSchema = baseCommandSchema.extend({\n action: z.literal('storage_get'),\n key: z.string().optional(),\n type: z.enum(['local', 'session']),\n});\n\nconst storageSetSchema = baseCommandSchema.extend({\n action: z.literal('storage_set'),\n key: z.string().min(1),\n value: z.string(),\n type: z.enum(['local', 'session']),\n});\n\nconst storageClearSchema = baseCommandSchema.extend({\n action: z.literal('storage_clear'),\n type: z.enum(['local', 'session']),\n});\n\nconst dialogSchema = baseCommandSchema.extend({\n action: z.literal('dialog'),\n response: z.enum(['accept', 'dismiss']),\n promptText: z.string().optional(),\n});\n\nconst pdfSchema = baseCommandSchema.extend({\n action: z.literal('pdf'),\n path: z.string().min(1),\n format: z\n .enum(['Letter', 'Legal', 'Tabloid', 'Ledger', 'A0', 'A1', 'A2', 'A3', 'A4', 'A5', 'A6'])\n .optional(),\n});\n\nconst routeSchema = baseCommandSchema.extend({\n action: z.literal('route'),\n url: z.string().min(1),\n response: z\n .object({\n status: z.number().optional(),\n body: z.string().optional(),\n contentType: z.string().optional(),\n headers: z.record(z.string(), z.string()).optional(),\n })\n .optional(),\n abort: z.boolean().optional(),\n});\n\nconst unrouteSchema = baseCommandSchema.extend({\n action: z.literal('unroute'),\n url: z.string().optional(),\n});\n\nconst requestsSchema = baseCommandSchema.extend({\n action: z.literal('requests'),\n filter: z.string().optional(),\n clear: z.boolean().optional(),\n});\n\nconst downloadSchema = baseCommandSchema.extend({\n action: z.literal('download'),\n selector: z.string().min(1),\n path: z.string().min(1),\n});\n\nconst geolocationSchema = baseCommandSchema.extend({\n action: z.literal('geolocation'),\n latitude: z.number(),\n longitude: z.number(),\n accuracy: z.number().optional(),\n});\n\nconst permissionsSchema = baseCommandSchema.extend({\n action: z.literal('permissions'),\n permissions: z.array(z.string()),\n grant: z.boolean(),\n});\n\nconst viewportSchema = baseCommandSchema.extend({\n action: z.literal('viewport'),\n width: z.number().positive(),\n height: z.number().positive(),\n deviceScaleFactor: z.number().positive().optional(),\n});\n\nconst userAgentSchema = baseCommandSchema.extend({\n action: z.literal('useragent'),\n userAgent: z.string().min(1),\n});\n\nconst deviceSchema = baseCommandSchema.extend({\n action: z.literal('device'),\n device: z.string().min(1),\n});\n\nconst backSchema = baseCommandSchema.extend({\n action: z.literal('back'),\n});\n\nconst forwardSchema = baseCommandSchema.extend({\n action: z.literal('forward'),\n});\n\nconst reloadSchema = baseCommandSchema.extend({\n action: z.literal('reload'),\n});\n\nconst urlSchema = baseCommandSchema.extend({\n action: z.literal('url'),\n});\n\nconst titleSchema = baseCommandSchema.extend({\n action: z.literal('title'),\n});\n\nconst getAttributeSchema = baseCommandSchema.extend({\n action: z.literal('getattribute'),\n selector: z.string().min(1),\n attribute: z.string().min(1),\n});\n\nconst getTextSchema = baseCommandSchema.extend({\n action: z.literal('gettext'),\n selector: z.string().min(1),\n});\n\nconst isVisibleSchema = baseCommandSchema.extend({\n action: z.literal('isvisible'),\n selector: z.string().min(1),\n});\n\nconst isEnabledSchema = baseCommandSchema.extend({\n action: z.literal('isenabled'),\n selector: z.string().min(1),\n});\n\nconst isCheckedSchema = baseCommandSchema.extend({\n action: z.literal('ischecked'),\n selector: z.string().min(1),\n});\n\nconst countSchema = baseCommandSchema.extend({\n action: z.literal('count'),\n selector: z.string().min(1),\n});\n\nconst boundingBoxSchema = baseCommandSchema.extend({\n action: z.literal('boundingbox'),\n selector: z.string().min(1),\n});\n\nconst stylesSchema = baseCommandSchema.extend({\n action: z.literal('styles'),\n selector: z.string().min(1),\n});\n\nconst videoStartSchema = baseCommandSchema.extend({\n action: z.literal('video_start'),\n path: z.string().min(1),\n});\n\nconst videoStopSchema = baseCommandSchema.extend({\n action: z.literal('video_stop'),\n});\n\n// Recording schemas (Playwright native video recording)\nconst recordingStartSchema = baseCommandSchema.extend({\n action: z.literal('recording_start'),\n path: z.string().min(1),\n url: z.string().min(1).optional(),\n});\n\nconst recordingStopSchema = baseCommandSchema.extend({\n action: z.literal('recording_stop'),\n});\n\nconst recordingRestartSchema = baseCommandSchema.extend({\n action: z.literal('recording_restart'),\n path: z.string().min(1),\n url: z.string().min(1).optional(),\n});\n\nconst traceStartSchema = baseCommandSchema.extend({\n action: z.literal('trace_start'),\n screenshots: z.boolean().optional(),\n snapshots: z.boolean().optional(),\n});\n\nconst traceStopSchema = baseCommandSchema.extend({\n action: z.literal('trace_stop'),\n path: z.string().min(1).optional(),\n});\n\nconst profilerStartSchema = baseCommandSchema.extend({\n action: z.literal('profiler_start'),\n categories: z.array(z.string()).optional(),\n});\n\nconst profilerStopSchema = baseCommandSchema.extend({\n action: z.literal('profiler_stop'),\n path: z.string().min(1).optional(),\n});\n\nconst harStartSchema = baseCommandSchema.extend({\n action: z.literal('har_start'),\n});\n\nconst harStopSchema = baseCommandSchema.extend({\n action: z.literal('har_stop'),\n path: z.string().min(1),\n});\n\nconst stateSaveSchema = baseCommandSchema.extend({\n action: z.literal('state_save'),\n path: z.string().min(1),\n});\n\nconst stateLoadSchema = baseCommandSchema.extend({\n action: z.literal('state_load'),\n path: z.string().min(1),\n});\n\nconst stateListSchema = baseCommandSchema.extend({\n action: z.literal('state_list'),\n});\n\nconst stateClearSchema = baseCommandSchema.extend({\n action: z.literal('state_clear'),\n sessionName: z.string().optional(),\n all: z.boolean().optional(),\n});\n\nconst stateShowSchema = baseCommandSchema.extend({\n action: z.literal('state_show'),\n filename: z.string().min(1),\n});\n\nconst stateCleanSchema = baseCommandSchema.extend({\n action: z.literal('state_clean'),\n days: z.number().int().positive(),\n});\n\nconst stateRenameSchema = baseCommandSchema.extend({\n action: z.literal('state_rename'),\n oldName: z.string().min(1),\n newName: z.string().min(1),\n});\n\nconst consoleSchema = baseCommandSchema.extend({\n action: z.literal('console'),\n clear: z.boolean().optional(),\n});\n\nconst errorsSchema = baseCommandSchema.extend({\n action: z.literal('errors'),\n clear: z.boolean().optional(),\n});\n\nconst keyboardSchema = baseCommandSchema.extend({\n action: z.literal('keyboard'),\n subaction: z.enum(['type', 'press', 'insertText']).optional(),\n keys: z.string().min(1).optional(),\n text: z.string().min(1).optional(),\n delay: z.number().optional(),\n});\n\nconst wheelSchema = baseCommandSchema.extend({\n action: z.literal('wheel'),\n deltaX: z.number().optional(),\n deltaY: z.number().optional(),\n selector: z.string().optional(),\n});\n\nconst tapSchema = baseCommandSchema.extend({\n action: z.literal('tap'),\n selector: z.string().min(1),\n});\n\nconst clipboardSchema = baseCommandSchema.extend({\n action: z.literal('clipboard'),\n operation: z.enum(['copy', 'paste', 'read', 'write']),\n text: z.string().optional(),\n});\n\nconst highlightSchema = baseCommandSchema.extend({\n action: z.literal('highlight'),\n selector: z.string().min(1),\n});\n\nconst clearSchema = baseCommandSchema.extend({\n action: z.literal('clear'),\n selector: z.string().min(1),\n});\n\nconst selectAllSchema = baseCommandSchema.extend({\n action: z.literal('selectall'),\n selector: z.string().min(1),\n});\n\nconst innerTextSchema = baseCommandSchema.extend({\n action: z.literal('innertext'),\n selector: z.string().min(1),\n});\n\nconst innerHtmlSchema = baseCommandSchema.extend({\n action: z.literal('innerhtml'),\n selector: z.string().min(1),\n});\n\nconst inputValueSchema = baseCommandSchema.extend({\n action: z.literal('inputvalue'),\n selector: z.string().min(1),\n});\n\nconst setValueSchema = baseCommandSchema.extend({\n action: z.literal('setvalue'),\n selector: z.string().min(1),\n value: z.string(),\n});\n\nconst dispatchSchema = baseCommandSchema.extend({\n action: z.literal('dispatch'),\n selector: z.string().min(1),\n event: z.string().min(1),\n eventInit: z.record(z.string(), z.unknown()).optional(),\n});\n\nconst evalHandleSchema = baseCommandSchema.extend({\n action: z.literal('evalhandle'),\n script: z.string().min(1),\n});\n\nconst exposeSchema = baseCommandSchema.extend({\n action: z.literal('expose'),\n name: z.string().min(1),\n});\n\nconst addScriptSchema = baseCommandSchema.extend({\n action: z.literal('addscript'),\n content: z.string().optional(),\n url: z.string().optional(),\n});\n\nconst addStyleSchema = baseCommandSchema.extend({\n action: z.literal('addstyle'),\n content: z.string().optional(),\n url: z.string().optional(),\n});\n\nconst emulateMediaSchema = baseCommandSchema.extend({\n action: z.literal('emulatemedia'),\n media: z.enum(['screen', 'print']).nullable().optional(),\n colorScheme: z.enum(['light', 'dark', 'no-preference']).nullable().optional(),\n reducedMotion: z.enum(['reduce', 'no-preference']).nullable().optional(),\n forcedColors: z.enum(['active', 'none']).nullable().optional(),\n});\n\nconst offlineSchema = baseCommandSchema.extend({\n action: z.literal('offline'),\n offline: z.boolean(),\n});\n\nconst headersSchema = baseCommandSchema.extend({\n action: z.literal('headers'),\n headers: z.record(z.string(), z.string()),\n});\n\nconst pauseSchema = baseCommandSchema.extend({\n action: z.literal('pause'),\n});\n\nconst getByAltTextSchema = baseCommandSchema.extend({\n action: z.literal('getbyalttext'),\n text: z.string().min(1),\n exact: z.boolean().optional(),\n subaction: z.enum(['click', 'hover']),\n});\n\nconst getByTitleSchema = baseCommandSchema.extend({\n action: z.literal('getbytitle'),\n text: z.string().min(1),\n exact: z.boolean().optional(),\n subaction: z.enum(['click', 'hover']),\n});\n\nconst getByTestIdSchema = baseCommandSchema.extend({\n action: z.literal('getbytestid'),\n testId: z.string().min(1),\n subaction: z.enum(['click', 'fill', 'check', 'hover']),\n value: z.string().optional(),\n});\n\nconst nthSchema = baseCommandSchema.extend({\n action: z.literal('nth'),\n selector: z.string().min(1),\n index: z.number(),\n subaction: z.enum(['click', 'fill', 'check', 'hover', 'text']),\n value: z.string().optional(),\n});\n\nconst waitForUrlSchema = baseCommandSchema.extend({\n action: z.literal('waitforurl'),\n url: z.string().min(1),\n timeout: z.number().positive().optional(),\n});\n\nconst waitForLoadStateSchema = baseCommandSchema.extend({\n action: z.literal('waitforloadstate'),\n state: z.enum(['load', 'domcontentloaded', 'networkidle']),\n timeout: z.number().positive().optional(),\n});\n\nconst setContentSchema = baseCommandSchema.extend({\n action: z.literal('setcontent'),\n html: z.string(),\n});\n\nconst timezoneSchema = baseCommandSchema.extend({\n action: z.literal('timezone'),\n timezone: z.string().min(1),\n});\n\nconst localeSchema = baseCommandSchema.extend({\n action: z.literal('locale'),\n locale: z.string().min(1),\n});\n\nconst credentialsSchema = baseCommandSchema.extend({\n action: z.literal('credentials'),\n username: z.string(),\n password: z.string(),\n});\n\nconst mouseMoveSchema = baseCommandSchema.extend({\n action: z.literal('mousemove'),\n x: z.number(),\n y: z.number(),\n});\n\nconst mouseDownSchema = baseCommandSchema.extend({\n action: z.literal('mousedown'),\n button: z.enum(['left', 'right', 'middle']).optional(),\n});\n\nconst mouseUpSchema = baseCommandSchema.extend({\n action: z.literal('mouseup'),\n button: z.enum(['left', 'right', 'middle']).optional(),\n});\n\nconst bringToFrontSchema = baseCommandSchema.extend({\n action: z.literal('bringtofront'),\n});\n\nconst waitForFunctionSchema = baseCommandSchema.extend({\n action: z.literal('waitforfunction'),\n expression: z.string().min(1),\n timeout: z.number().positive().optional(),\n});\n\nconst scrollIntoViewSchema = baseCommandSchema.extend({\n action: z.literal('scrollintoview'),\n selector: z.string().min(1),\n});\n\nconst addInitScriptSchema = baseCommandSchema.extend({\n action: z.literal('addinitscript'),\n script: z.string().min(1),\n});\n\nconst keyDownSchema = baseCommandSchema.extend({\n action: z.literal('keydown'),\n key: z.string().min(1),\n});\n\nconst keyUpSchema = baseCommandSchema.extend({\n action: z.literal('keyup'),\n key: z.string().min(1),\n});\n\nconst insertTextSchema = baseCommandSchema.extend({\n action: z.literal('inserttext'),\n text: z.string(),\n});\n\nconst multiSelectSchema = baseCommandSchema.extend({\n action: z.literal('multiselect'),\n selector: z.string().min(1),\n values: z.array(z.string()),\n});\n\nconst waitForDownloadSchema = baseCommandSchema.extend({\n action: z.literal('waitfordownload'),\n path: z.string().optional(),\n timeout: z.number().positive().optional(),\n});\n\nconst responseBodySchema = baseCommandSchema.extend({\n action: z.literal('responsebody'),\n url: z.string().min(1),\n timeout: z.number().positive().optional(),\n});\n\n// Screencast schemas for streaming browser viewport\nconst screencastStartSchema = baseCommandSchema.extend({\n action: z.literal('screencast_start'),\n format: z.enum(['jpeg', 'png']).optional(),\n quality: z.number().min(0).max(100).optional(),\n maxWidth: z.number().positive().optional(),\n maxHeight: z.number().positive().optional(),\n everyNthFrame: z.number().positive().optional(),\n});\n\nconst screencastStopSchema = baseCommandSchema.extend({\n action: z.literal('screencast_stop'),\n});\n\n// Input injection schemas for pair browsing\nconst inputMouseSchema = baseCommandSchema.extend({\n action: z.literal('input_mouse'),\n type: z.enum(['mousePressed', 'mouseReleased', 'mouseMoved', 'mouseWheel']),\n x: z.number(),\n y: z.number(),\n button: z.enum(['left', 'right', 'middle', 'none']).optional(),\n clickCount: z.number().positive().optional(),\n deltaX: z.number().optional(),\n deltaY: z.number().optional(),\n modifiers: z.number().optional(),\n});\n\nconst inputKeyboardSchema = baseCommandSchema.extend({\n action: z.literal('input_keyboard'),\n type: z.enum(['keyDown', 'keyUp', 'char']),\n key: z.string().optional(),\n code: z.string().optional(),\n text: z.string().optional(),\n modifiers: z.number().optional(),\n});\n\nconst inputTouchSchema = baseCommandSchema.extend({\n action: z.literal('input_touch'),\n type: z.enum(['touchStart', 'touchEnd', 'touchMove', 'touchCancel']),\n touchPoints: z.array(\n z.object({\n x: z.number(),\n y: z.number(),\n id: z.number().optional(),\n })\n ),\n modifiers: z.number().optional(),\n});\n\n// iOS-specific schemas\nconst swipeSchema = baseCommandSchema.extend({\n action: z.literal('swipe'),\n direction: z.enum(['up', 'down', 'left', 'right']),\n distance: z.number().positive().optional(),\n});\n\nconst deviceListSchema = baseCommandSchema.extend({\n action: z.literal('device_list'),\n});\n\n// Diff schemas\nconst diffSnapshotSchema = baseCommandSchema.extend({\n action: z.literal('diff_snapshot'),\n baseline: z.string().optional(),\n selector: z.string().optional(),\n compact: z.boolean().optional(),\n maxDepth: z.number().nonnegative().optional(),\n});\n\nconst diffScreenshotSchema = baseCommandSchema.extend({\n action: z.literal('diff_screenshot'),\n baseline: z.string().min(1),\n output: z.string().optional(),\n threshold: z.number().min(0).max(1).optional(),\n selector: z.string().min(1).optional(),\n fullPage: z.boolean().optional(),\n});\n\nconst diffUrlSchema = baseCommandSchema.extend({\n action: z.literal('diff_url'),\n url1: z.string().min(1),\n url2: z.string().min(1),\n screenshot: z.boolean().optional(),\n fullPage: z.boolean().optional(),\n waitUntil: z.enum(['load', 'domcontentloaded', 'networkidle']).optional(),\n selector: z.string().optional(),\n compact: z.boolean().optional(),\n maxDepth: z.number().nonnegative().optional(),\n});\n\nconst pressSchema = baseCommandSchema.extend({\n action: z.literal('press'),\n key: z.string().min(1),\n selector: z.string().min(1).optional(),\n});\n\nconst screenshotSchema = baseCommandSchema.extend({\n action: z.literal('screenshot'),\n path: z.string().nullable().optional(),\n fullPage: z.boolean().optional(),\n selector: z.string().min(1).nullish(),\n format: z.enum(['png', 'jpeg']).optional(),\n quality: z.number().min(0).max(100).optional(),\n annotate: z.boolean().optional(),\n screenshotDir: z.string().optional(),\n});\n\nconst snapshotSchema = baseCommandSchema.extend({\n action: z.literal('snapshot'),\n interactive: z.boolean().optional(),\n cursor: z.boolean().optional(),\n maxDepth: z.number().nonnegative().optional(),\n compact: z.boolean().optional(),\n selector: z.string().optional(),\n});\n\nconst evaluateSchema = baseCommandSchema.extend({\n action: z.literal('evaluate'),\n script: z.string().min(1),\n args: z.array(z.unknown()).optional(),\n});\n\nconst waitSchema = baseCommandSchema.extend({\n action: z.literal('wait'),\n selector: z.string().min(1).optional(),\n text: z.string().min(1).optional(),\n timeout: z.number().positive().optional(),\n state: z.enum(['attached', 'detached', 'visible', 'hidden']).optional(),\n});\n\nconst scrollSchema = baseCommandSchema.extend({\n action: z.literal('scroll'),\n selector: z.string().min(1).optional(),\n x: z.number().optional(),\n y: z.number().optional(),\n direction: z.enum(['up', 'down', 'left', 'right']).optional(),\n amount: z.number().positive().optional(),\n});\n\nconst selectSchema = baseCommandSchema.extend({\n action: z.literal('select'),\n selector: z.string().min(1),\n values: z.union([z.string(), z.array(z.string())]),\n});\n\nconst hoverSchema = baseCommandSchema.extend({\n action: z.literal('hover'),\n selector: z.string().min(1),\n});\n\nconst contentSchema = baseCommandSchema.extend({\n action: z.literal('content'),\n selector: z.string().min(1).optional(),\n});\n\nconst closeSchema = baseCommandSchema.extend({\n action: z.literal('close'),\n});\n\n// Tab/Window schemas\nconst tabNewSchema = baseCommandSchema.extend({\n action: z.literal('tab_new'),\n url: z.string().min(1).optional(),\n});\n\nconst tabListSchema = baseCommandSchema.extend({\n action: z.literal('tab_list'),\n});\n\nconst tabSwitchSchema = baseCommandSchema.extend({\n action: z.literal('tab_switch'),\n index: z.number().nonnegative(),\n});\n\nconst tabCloseSchema = baseCommandSchema.extend({\n action: z.literal('tab_close'),\n index: z.number().nonnegative().optional(),\n});\n\nconst windowNewSchema = baseCommandSchema.extend({\n action: z.literal('window_new'),\n viewport: z\n .object({\n width: z.number().positive(),\n height: z.number().positive(),\n })\n .nullable()\n .optional(),\n});\n\nconst authProfileName = z\n .string()\n .min(1)\n .regex(/^[a-zA-Z0-9_-]+$/, {\n message: 'Profile name must contain only alphanumeric characters, hyphens, and underscores',\n });\n\nconst authSaveSchema = baseCommandSchema.extend({\n action: z.literal('auth_save'),\n name: authProfileName,\n url: z.string().min(1),\n username: z.string().min(1),\n password: z.string().min(1),\n usernameSelector: z.string().optional(),\n passwordSelector: z.string().optional(),\n submitSelector: z.string().optional(),\n});\n\nconst authLoginSchema = baseCommandSchema.extend({\n action: z.literal('auth_login'),\n name: authProfileName,\n});\n\nconst authListSchema = baseCommandSchema.extend({\n action: z.literal('auth_list'),\n});\n\nconst authDeleteSchema = baseCommandSchema.extend({\n action: z.literal('auth_delete'),\n name: authProfileName,\n});\n\nconst authShowSchema = baseCommandSchema.extend({\n action: z.literal('auth_show'),\n name: authProfileName,\n});\n\nconst confirmSchema = baseCommandSchema.extend({\n action: z.literal('confirm'),\n confirmationId: z.string().min(1),\n});\n\nconst denySchema = baseCommandSchema.extend({\n action: z.literal('deny'),\n confirmationId: z.string().min(1),\n});\n\n// Union schema for all commands\nconst commandSchema = z.discriminatedUnion('action', [\n launchSchema,\n navigateSchema,\n clickSchema,\n typeSchema,\n fillSchema,\n checkSchema,\n uncheckSchema,\n uploadSchema,\n dblclickSchema,\n focusSchema,\n dragSchema,\n frameSchema,\n mainframeSchema,\n getByRoleSchema,\n getByTextSchema,\n getByLabelSchema,\n getByPlaceholderSchema,\n pressSchema,\n screenshotSchema,\n snapshotSchema,\n evaluateSchema,\n waitSchema,\n scrollSchema,\n selectSchema,\n hoverSchema,\n contentSchema,\n closeSchema,\n tabNewSchema,\n tabListSchema,\n tabSwitchSchema,\n tabCloseSchema,\n windowNewSchema,\n cookiesGetSchema,\n cookiesSetSchema,\n cookiesClearSchema,\n storageGetSchema,\n storageSetSchema,\n storageClearSchema,\n dialogSchema,\n pdfSchema,\n routeSchema,\n unrouteSchema,\n requestsSchema,\n downloadSchema,\n geolocationSchema,\n permissionsSchema,\n viewportSchema,\n userAgentSchema,\n deviceSchema,\n backSchema,\n forwardSchema,\n reloadSchema,\n urlSchema,\n titleSchema,\n getAttributeSchema,\n getTextSchema,\n isVisibleSchema,\n isEnabledSchema,\n isCheckedSchema,\n countSchema,\n boundingBoxSchema,\n stylesSchema,\n videoStartSchema,\n videoStopSchema,\n recordingStartSchema,\n recordingStopSchema,\n recordingRestartSchema,\n traceStartSchema,\n traceStopSchema,\n profilerStartSchema,\n profilerStopSchema,\n harStartSchema,\n harStopSchema,\n stateSaveSchema,\n stateLoadSchema,\n stateListSchema,\n stateClearSchema,\n stateShowSchema,\n stateCleanSchema,\n stateRenameSchema,\n consoleSchema,\n errorsSchema,\n keyboardSchema,\n wheelSchema,\n tapSchema,\n clipboardSchema,\n highlightSchema,\n clearSchema,\n selectAllSchema,\n innerTextSchema,\n innerHtmlSchema,\n inputValueSchema,\n setValueSchema,\n dispatchSchema,\n evalHandleSchema,\n exposeSchema,\n addScriptSchema,\n addStyleSchema,\n emulateMediaSchema,\n offlineSchema,\n headersSchema,\n pauseSchema,\n getByAltTextSchema,\n getByTitleSchema,\n getByTestIdSchema,\n nthSchema,\n waitForUrlSchema,\n waitForLoadStateSchema,\n setContentSchema,\n timezoneSchema,\n localeSchema,\n credentialsSchema,\n mouseMoveSchema,\n mouseDownSchema,\n mouseUpSchema,\n bringToFrontSchema,\n waitForFunctionSchema,\n scrollIntoViewSchema,\n addInitScriptSchema,\n keyDownSchema,\n keyUpSchema,\n insertTextSchema,\n multiSelectSchema,\n waitForDownloadSchema,\n responseBodySchema,\n screencastStartSchema,\n screencastStopSchema,\n inputMouseSchema,\n inputKeyboardSchema,\n inputTouchSchema,\n swipeSchema,\n deviceListSchema,\n diffSnapshotSchema,\n diffScreenshotSchema,\n diffUrlSchema,\n confirmSchema,\n denySchema,\n authSaveSchema,\n authLoginSchema,\n authListSchema,\n authDeleteSchema,\n authShowSchema,\n]);\n\n// Parse result type\nexport type ParseResult =\n | { success: true; command: Command }\n | { success: false; error: string; id?: string };\n\n/**\n * Parse a JSON string into a validated command\n */\nexport function parseCommand(input: string): ParseResult {\n // First, try to parse JSON\n let json: unknown;\n try {\n json = JSON.parse(input);\n } catch {\n return { success: false, error: 'Invalid JSON' };\n }\n\n // Extract id for error responses if possible\n const id =\n typeof json === 'object' && json !== null && 'id' in json\n ? String((json as { id: unknown }).id)\n : undefined;\n\n // Validate against schema\n const result = commandSchema.safeParse(json);\n\n if (!result.success) {\n const errors = result.error.issues.map((e) => `${(e.path as (string | number)[]).join('.')}: ${e.message}`).join(', ');\n return { success: false, error: `Validation error: ${errors}`, id };\n }\n\n const command = result.data as Command;\n\n // Post-parse validation for commands that need cross-field checks\n if (\n (command.action === 'addscript' || command.action === 'addstyle') &&\n !command.content &&\n !command.url\n ) {\n return { success: false, error: 'Either content or url must be provided', id };\n }\n\n if (command.action === 'frame' && !command.selector && !command.name && !command.url) {\n return {\n success: false,\n error: 'frame command requires at least one of: selector, name, or url',\n id,\n };\n }\n\n if (command.action === 'keyboard') {\n const sub = command.subaction ?? 'press';\n if ((sub === 'type' || sub === 'insertText') && !command.text) {\n return { success: false, error: `keyboard ${sub} requires text`, id };\n }\n if (sub === 'press' && !command.keys) {\n return { success: false, error: 'keyboard press requires keys', id };\n }\n }\n\n return { success: true, command };\n}\n\n/**\n * Create a success response\n */\nexport function successResponse<T>(id: string, data: T): Response<T> {\n return { id, success: true, data };\n}\n\n/**\n * Create an error response\n */\nexport function errorResponse(id: string, error: string): Response {\n return { id, success: false, error };\n}\n\n/**\n * Serialize a response to JSON string.\n * Replaces lone Unicode surrogates with U+FFFD to prevent\n * serde_json parsing errors on the Rust side.\n */\nexport function serializeResponse(response: Response): string {\n return JSON.stringify(response, (_key, value) =>\n typeof value === 'string' && !value.isWellFormed() ? value.toWellFormed() : value\n );\n}\n","import type { BrowserContext } from 'playwright-core';\nimport type { DiffSnapshotData, DiffScreenshotData } from './types.js';\nimport { writeFile, mkdir } from 'node:fs/promises';\nimport path from 'node:path';\n\n// --- Text diffing (Myers algorithm, line-level) ---\n\ninterface DiffEdit {\n type: 'equal' | 'insert' | 'delete';\n line: string;\n}\n\n/**\n * Myers diff algorithm operating on arrays of lines.\n * Returns a minimal edit script.\n */\nfunction myersDiff(a: string[], b: string[]): DiffEdit[] {\n const n = a.length;\n const m = b.length;\n const max = n + m;\n\n if (max === 0) return [];\n\n // Optimize: if both are identical, skip diff\n if (n === m) {\n let identical = true;\n for (let i = 0; i < n; i++) {\n if (a[i] !== b[i]) {\n identical = false;\n break;\n }\n }\n if (identical) return a.map((line) => ({ type: 'equal' as const, line }));\n }\n\n const vSize = 2 * max + 1;\n const v = new Int32Array(vSize);\n v.fill(-1);\n const trace: Int32Array[] = [];\n\n v[max + 1] = 0;\n for (let d = 0; d <= max; d++) {\n const snapshot = new Int32Array(v);\n trace.push(snapshot);\n\n for (let k = -d; k <= d; k += 2) {\n const idx = k + max;\n let x: number;\n if (k === -d || (k !== d && v[idx - 1] < v[idx + 1])) {\n x = v[idx + 1];\n } else {\n x = v[idx - 1] + 1;\n }\n let y = x - k;\n\n while (x < n && y < m && a[x] === b[y]) {\n x++;\n y++;\n }\n\n v[idx] = x;\n\n if (x >= n && y >= m) {\n return buildEditScript(trace, a, b, max);\n }\n }\n }\n\n return buildEditScript(trace, a, b, max);\n}\n\nfunction buildEditScript(trace: Int32Array[], a: string[], b: string[], max: number): DiffEdit[] {\n const edits: DiffEdit[] = [];\n let x = a.length;\n let y = b.length;\n\n for (let d = trace.length - 1; d > 0; d--) {\n const v = trace[d];\n const k = x - y;\n const idx = k + max;\n\n let prevK: number;\n if (k === -d || (k !== d && v[idx - 1] < v[idx + 1])) {\n prevK = k + 1;\n } else {\n prevK = k - 1;\n }\n\n const prevIdx = prevK + max;\n let prevX = v[prevIdx];\n let prevY = prevX - prevK;\n\n // Diagonal (equal lines)\n while (x > prevX && y > prevY) {\n x--;\n y--;\n edits.push({ type: 'equal', line: a[x] });\n }\n\n if (x === prevX) {\n y--;\n edits.push({ type: 'insert', line: b[y] });\n } else {\n x--;\n edits.push({ type: 'delete', line: a[x] });\n }\n }\n\n // Remaining diagonal at d=0\n while (x > 0 && y > 0) {\n x--;\n y--;\n edits.push({ type: 'equal', line: a[x] });\n }\n\n edits.reverse();\n return edits;\n}\n\n/**\n * Produce a unified diff string and stats from two snapshot texts.\n */\nexport function diffSnapshots(before: string, after: string): DiffSnapshotData {\n const linesA = before.split('\\n');\n const linesB = after.split('\\n');\n\n const edits = myersDiff(linesA, linesB);\n\n let additions = 0;\n let removals = 0;\n let unchanged = 0;\n const diffLines: string[] = [];\n\n for (const edit of edits) {\n switch (edit.type) {\n case 'equal':\n unchanged++;\n diffLines.push(` ${edit.line}`);\n break;\n case 'insert':\n additions++;\n diffLines.push(`+ ${edit.line}`);\n break;\n case 'delete':\n removals++;\n diffLines.push(`- ${edit.line}`);\n break;\n }\n }\n\n return {\n diff: diffLines.join('\\n'),\n additions,\n removals,\n unchanged,\n changed: additions > 0 || removals > 0,\n };\n}\n\n// --- Image diffing (via browser Canvas API) ---\n\ninterface PixelDiffResult {\n totalPixels: number;\n differentPixels: number;\n mismatchPercentage: number;\n diffBase64: string;\n dimensionMismatch: boolean;\n}\n\nconst DIFF_ROUTE_PREFIX = 'https://agent-browser-diff.localhost';\n\n/**\n * Compare two image buffers using the browser's Canvas API for pixel comparison.\n * Uses an isolated blank page to avoid CSP interference or DOM side effects on the\n * user's page. Images are served via intercepted routes to avoid large base64 payloads\n * through page.evaluate (which can be slow or hit CDP message size limits).\n */\nexport async function diffScreenshots(\n context: BrowserContext,\n baselineBuffer: Buffer,\n currentBuffer: Buffer,\n opts: { threshold?: number; outputPath?: string; baselineMime?: string }\n): Promise<DiffScreenshotData> {\n const baselineMime = opts.baselineMime ?? 'image/png';\n const threshold = opts.threshold ?? 0.1;\n\n const nonce = Math.random().toString(36).slice(2, 10);\n const blankUrl = `${DIFF_ROUTE_PREFIX}/${nonce}/index.html`;\n const baselineUrl = `${DIFF_ROUTE_PREFIX}/${nonce}/baseline.png`;\n const currentUrl = `${DIFF_ROUTE_PREFIX}/${nonce}/current.png`;\n\n const diffPage = await context.newPage();\n\n let blankRouted = false;\n let baselineRouted = false;\n let currentRouted = false;\n try {\n await diffPage.route(blankUrl, (route) =>\n route.fulfill({ body: '<html><body></body></html>', contentType: 'text/html' })\n );\n blankRouted = true;\n await diffPage.route(baselineUrl, (route) =>\n route.fulfill({ body: baselineBuffer, contentType: baselineMime })\n );\n baselineRouted = true;\n await diffPage.route(currentUrl, (route) =>\n route.fulfill({ body: currentBuffer, contentType: 'image/png' })\n );\n currentRouted = true;\n\n await diffPage.goto(blankUrl);\n\n const pixelDiffFn = async (args: {\n baselineUrl: string;\n currentUrl: string;\n threshold: number;\n }) => {\n const g = globalThis as any;\n const doc = g.document;\n const Img = g.Image as new () => any;\n function loadImage(url: string) {\n return new Promise((resolve, reject) => {\n const img = new Img();\n img.onload = () => resolve(img);\n img.onerror = () => reject(new Error('Failed to load image'));\n img.src = url;\n });\n }\n const [imgA, imgB] = (await Promise.all([\n loadImage(args.baselineUrl),\n loadImage(args.currentUrl),\n ])) as any[];\n if (imgA.width !== imgB.width || imgA.height !== imgB.height) {\n const c = doc.createElement('canvas');\n c.width = 1;\n c.height = 1;\n return {\n totalPixels: Math.max(imgA.width * imgA.height, imgB.width * imgB.height),\n differentPixels: Math.max(imgA.width * imgA.height, imgB.width * imgB.height),\n mismatchPercentage: 100,\n diffBase64: c.toDataURL('image/png').split(',')[1],\n dimensionMismatch: true,\n };\n }\n const w = imgA.width;\n const h = imgA.height;\n const canvasA = doc.createElement('canvas');\n canvasA.width = w;\n canvasA.height = h;\n const ctxA = canvasA.getContext('2d')!;\n ctxA.drawImage(imgA, 0, 0);\n const dataA = ctxA.getImageData(0, 0, w, h).data;\n const canvasB = doc.createElement('canvas');\n canvasB.width = w;\n canvasB.height = h;\n const ctxB = canvasB.getContext('2d')!;\n ctxB.drawImage(imgB, 0, 0);\n const dataB = ctxB.getImageData(0, 0, w, h).data;\n const diffCanvas = doc.createElement('canvas');\n diffCanvas.width = w;\n diffCanvas.height = h;\n const ctxDiff = diffCanvas.getContext('2d')!;\n const diffImageData = ctxDiff.createImageData(w, h);\n const diffData = diffImageData.data;\n const maxColorDistance = args.threshold * 255 * Math.sqrt(3);\n let differentPixels = 0;\n const totalPixels = w * h;\n for (let i = 0; i < totalPixels; i++) {\n const offset = i * 4;\n const rA = dataA[offset],\n gA = dataA[offset + 1],\n bA = dataA[offset + 2];\n const rB = dataB[offset],\n gB = dataB[offset + 1],\n bB = dataB[offset + 2];\n const dr = rA - rB,\n dg = gA - gB,\n db = bA - bB;\n const dist = Math.sqrt(dr * dr + dg * dg + db * db);\n if (dist > maxColorDistance) {\n differentPixels++;\n diffData[offset] = 255;\n diffData[offset + 1] = 0;\n diffData[offset + 2] = 0;\n diffData[offset + 3] = 255;\n } else {\n diffData[offset] = Math.round(rA * 0.3);\n diffData[offset + 1] = Math.round(gA * 0.3);\n diffData[offset + 2] = Math.round(bA * 0.3);\n diffData[offset + 3] = 255;\n }\n }\n ctxDiff.putImageData(diffImageData, 0, 0);\n const diffBase64 = diffCanvas.toDataURL('image/png').split(',')[1];\n return {\n totalPixels,\n differentPixels,\n mismatchPercentage: Math.round((differentPixels / totalPixels) * 10000) / 100,\n diffBase64,\n dimensionMismatch: false,\n };\n };\n\n const result = (await diffPage.evaluate(pixelDiffFn, {\n baselineUrl,\n currentUrl,\n threshold,\n })) as PixelDiffResult;\n\n let outputPath = opts.outputPath;\n if (!outputPath) {\n const tmpDir = path.join(\n process.env.HOME || process.env.USERPROFILE || '/tmp',\n '.agent-browser',\n 'tmp',\n 'diffs'\n );\n await mkdir(tmpDir, { recursive: true });\n outputPath = path.join(tmpDir, `diff-${Date.now()}.png`);\n }\n\n const diffBuffer = Buffer.from(result.diffBase64, 'base64');\n await writeFile(outputPath, diffBuffer);\n\n return {\n diffPath: outputPath,\n totalPixels: result.totalPixels,\n differentPixels: result.differentPixels,\n mismatchPercentage: result.mismatchPercentage,\n match: result.differentPixels === 0,\n ...(result.dimensionMismatch ? { dimensionMismatch: true } : {}),\n };\n } finally {\n if (blankRouted) await diffPage.unroute(blankUrl).catch(() => {});\n if (baselineRouted) await diffPage.unroute(baselineUrl).catch(() => {});\n if (currentRouted) await diffPage.unroute(currentUrl).catch(() => {});\n await diffPage.close().catch(() => {});\n }\n}\n","/**\n * browser/stealth --- Playwright ステルスパッチ\n *\n * puppeteer-extra-plugin-stealth の手法を Playwright 用に移植。\n * page.context().addInitScript() で各パッチをブラウザコンテキストに注入する。\n * addInitScript はコンテキストレベルで適用されるため、\n * 以後のナビゲーションや新しいページでも自動的に再実行される。\n */\n\n/** Playwright Page の最小インターフェース(playwright-core を直接参照しない) */\ninterface StealthPage {\n context(): {\n addInitScript(script: string): Promise<void>;\n };\n}\n\n// ── 個別パッチスクリプト生成関数 ──\n\n/** navigator.webdriver を undefined にする */\nexport function webdriverPatch(): string {\n return `\n Object.defineProperty(navigator, 'webdriver', {\n get: () => undefined,\n });\n `;\n}\n\n/** window.chrome オブジェクトを注入(chrome.runtime 含む) */\nexport function chromePatch(): string {\n return `\n if (!window.chrome) {\n Object.defineProperty(window, 'chrome', {\n writable: true,\n enumerable: true,\n configurable: true,\n value: {},\n });\n }\n if (!window.chrome.runtime) {\n window.chrome.runtime = {\n connect: function() { return { onMessage: { addListener: function() {} }, postMessage: function() {}, onDisconnect: { addListener: function() {} } }; },\n sendMessage: function(a, b, c) { if (typeof c === 'function') c(); },\n };\n }\n `;\n}\n\n/** navigator.plugins をエミュレーション(Chrome 標準プラグイン) */\nexport function pluginsPatch(): string {\n return `\n Object.defineProperty(navigator, 'plugins', {\n get: () => {\n const plugins = [\n { name: 'Chrome PDF Plugin', filename: 'internal-pdf-viewer', description: 'Portable Document Format' },\n { name: 'Chrome PDF Viewer', filename: 'mhjfbmdgcfjbbpaeojofohoefgiehjai', description: '' },\n { name: 'Native Client', filename: 'internal-nacl-plugin', description: '' },\n ];\n plugins.refresh = () => {};\n return plugins;\n },\n });\n Object.defineProperty(navigator, 'mimeTypes', {\n get: () => {\n const mimeTypes = [\n { type: 'application/pdf', suffixes: 'pdf', description: 'Portable Document Format' },\n { type: 'application/x-google-chrome-pdf', suffixes: 'pdf', description: 'Portable Document Format' },\n ];\n mimeTypes.refresh = () => {};\n return mimeTypes;\n },\n });\n `;\n}\n\n/** navigator.languages パッチ */\nexport function languagesPatch(): string {\n return `\n Object.defineProperty(navigator, 'languages', {\n get: () => ['en-US', 'en'],\n });\n `;\n}\n\n/** navigator.permissions.query パッチ(notification → denied) */\nexport function permissionsPatch(): string {\n return `\n const originalQuery = navigator.permissions.query.bind(navigator.permissions);\n navigator.permissions.query = (parameters) => {\n if (parameters.name === 'notifications') {\n return Promise.resolve({ state: Notification.permission });\n }\n return originalQuery(parameters);\n };\n `;\n}\n\n/** WebGL vendor/renderer の正規化 */\nexport function webglPatch(): string {\n return `\n const getParameter = WebGLRenderingContext.prototype.getParameter;\n WebGLRenderingContext.prototype.getParameter = function(parameter) {\n // UNMASKED_VENDOR_WEBGL\n if (parameter === 37445) return 'Google Inc. (Intel)';\n // UNMASKED_RENDERER_WEBGL\n if (parameter === 37446) return 'ANGLE (Intel, Intel(R) UHD Graphics, OpenGL 4.1)';\n return getParameter.call(this, parameter);\n };\n if (typeof WebGL2RenderingContext !== 'undefined') {\n const getParameter2 = WebGL2RenderingContext.prototype.getParameter;\n WebGL2RenderingContext.prototype.getParameter = function(parameter) {\n if (parameter === 37445) return 'Google Inc. (Intel)';\n if (parameter === 37446) return 'ANGLE (Intel, Intel(R) UHD Graphics, OpenGL 4.1)';\n return getParameter2.call(this, parameter);\n };\n }\n `;\n}\n\n/** navigator.hardwareConcurrency を 4 に固定 */\nexport function hardwareConcurrencyPatch(): string {\n return `\n Object.defineProperty(navigator, 'hardwareConcurrency', {\n get: () => 4,\n });\n `;\n}\n\n/** iframe contentWindow 検出回避 */\nexport function iframePatch(): string {\n return `\n try {\n if (window.self !== window.top) return;\n const originalAttachShadow = Element.prototype.attachShadow;\n if (originalAttachShadow) {\n Element.prototype.attachShadow = function() {\n return originalAttachShadow.call(this, ...arguments);\n };\n }\n } catch {}\n `;\n}\n\n/** navigator.userAgent / navigator.appVersion から HeadlessChrome を除去 */\nexport function userAgentPatch(): string {\n return `\n (function() {\n var ua = navigator.userAgent || '';\n if (ua.indexOf('HeadlessChrome') !== -1) {\n var cleanUA = ua.replace('HeadlessChrome', 'Chrome');\n Object.defineProperty(navigator, 'userAgent', {\n get: () => cleanUA,\n });\n }\n var av = navigator.appVersion || '';\n if (av.indexOf('HeadlessChrome') !== -1) {\n var cleanAV = av.replace('HeadlessChrome', 'Chrome');\n Object.defineProperty(navigator, 'appVersion', {\n get: () => cleanAV,\n });\n }\n })();\n `;\n}\n\n// ── メインの適用関数 ──\n\n/** 全ステルスパッチを生成 */\nexport function getStealthScripts(): string[] {\n return [\n webdriverPatch(),\n chromePatch(),\n pluginsPatch(),\n languagesPatch(),\n permissionsPatch(),\n webglPatch(),\n hardwareConcurrencyPatch(),\n iframePatch(),\n userAgentPatch(),\n ];\n}\n\n/**\n * Playwright Page にステルスパッチを適用する。\n * page.context().addInitScript() で登録するため、\n * 以後のナビゲーション・新規ページでも自動再適用される。\n */\nexport async function applyStealthScripts(page: StealthPage): Promise<void> {\n const context = page.context();\n const scripts = getStealthScripts();\n for (const script of scripts) {\n await context.addInitScript(script);\n }\n}\n","/**\n * snapshot-parser — アクセシビリティスナップショット行パース\n *\n * Playwright のアクセシビリティスナップショット出力形式:\n * role \"name\" [ref=eN] [attrs]\n *\n * から構造化データを抽出する純粋関数群\n */\n\nexport interface ParsedSnapshotElement {\n /** 参照ID(例: \"e3\") */\n ref: string;\n /** ロール(例: \"textbox\", \"button\", \"link\") */\n role: string;\n /** 名前(例: \"Email\", \"ログイン\") */\n name: string;\n /** 追加属性 */\n attributes: Record<string, string>;\n}\n\n/**\n * スナップショットの1行をパースして構造化データに変換\n *\n * 入力例:\n * textbox \"Email\" [ref=e3] [required] [focused]\n * - button \"ログイン\" [ref=e5]\n * heading \"Title\" [ref=e1] [level=2]\n * textbox \"サブドメイン\" [ref=e3]:\n * img [ref=e10]\n *\n * @returns パースされた要素、またはマッチしない場合 null\n */\nexport function parseSnapshotLine(\n line: string,\n): ParsedSnapshotElement | null {\n // [ref=eN] を抽出\n const refMatch = line.match(/\\[ref=(e\\d+)\\]/);\n if (!refMatch) return null;\n\n const ref = refMatch[1];\n const refIndex = line.indexOf(refMatch[0]);\n\n // ref より前のテキスト(role \"name\" が先頭にある)\n const beforeRef = line.slice(0, refIndex).trim();\n // ref より後のテキスト(属性のみ)\n const afterRef = line.slice(refIndex + refMatch[0].length).trim();\n\n // 先頭の \"- \" (Playwright リストbullet) を除去\n const cleanBefore = beforeRef.replace(/^-\\s+/, \"\");\n\n let role: string;\n let name: string;\n\n // role \"name\" パターン\n const roleNameMatch = cleanBefore.match(/^(\\S+)\\s+\"([^\"]*)\"$/);\n const roleOnlyMatch = cleanBefore.match(/^(\\S+)$/);\n\n if (roleNameMatch) {\n role = roleNameMatch[1];\n name = roleNameMatch[2];\n } else if (roleOnlyMatch && !roleOnlyMatch[1].startsWith(\"[\")) {\n role = roleOnlyMatch[1];\n name = \"\";\n } else {\n return null;\n }\n\n // 末尾 \":\" (子要素インジケータ) を除去して属性を抽出\n const attrSource = afterRef.replace(/:$/, \"\").trim();\n\n // 属性を抽出([key=value] または [key] 形式、[ref=...] はスキップ)\n const attributes: Record<string, string> = {};\n const attrRegex = /\\[(\\w+)(?:=([^\\]]*))?\\]/g;\n let attrMatch: RegExpExecArray | null;\n while ((attrMatch = attrRegex.exec(attrSource)) !== null) {\n const key = attrMatch[1];\n if (key === \"ref\") continue;\n const value = attrMatch[2] ?? \"true\";\n attributes[key] = value;\n }\n\n return { ref, role, name, attributes };\n}\n\n/**\n * スナップショット全体から指定refの要素を検索\n */\nexport function findElementInSnapshot(\n snapshot: string,\n ref: string,\n): ParsedSnapshotElement | null {\n const lines = snapshot.split(\"\\n\");\n for (const line of lines) {\n if (!line.includes(`[ref=${ref}]`)) continue;\n const parsed = parseSnapshotLine(line);\n if (parsed && parsed.ref === ref) return parsed;\n }\n return null;\n}\n\n/**\n * スナップショットからインタラクティブ要素一覧を抽出\n */\nexport function parseAllElements(\n snapshot: string,\n): ParsedSnapshotElement[] {\n const lines = snapshot.split(\"\\n\");\n const elements: ParsedSnapshotElement[] = [];\n for (const line of lines) {\n const parsed = parseSnapshotLine(line);\n if (parsed) elements.push(parsed);\n }\n return elements;\n}\n\n/**\n * スナップショット内の [ref=eN] 要素の総数を返す。\n */\nexport function countElements(snapshot: string): number {\n return parseAllElements(snapshot).length;\n}\n","/**\n * error-classifier — エラー分類の共通ロジック\n *\n * generator / executor / debugger から利用可能。\n * 失敗原因を型付きカテゴリに分類し、カテゴリ別の推奨対応テキストを提供する。\n */\n\nimport type { StepRetryDetail } from \"../runbook-executor/types\";\nimport { t } from \"../i18n\";\nimport type { MessageKey } from \"../i18n\";\n\nexport type FailureCategory =\n | \"element_not_found\"\n | \"element_stale\"\n | \"page_structure_changed\"\n | \"navigation_timeout\"\n | \"action_failed\"\n | \"unknown\";\n\nexport interface ClassificationContext {\n /** エラーメッセージ */\n error: string;\n /** AI がセレクタ解決で ref を返したか */\n selectorResolved: boolean;\n /** アクション実行まで到達したか */\n actionExecuted: boolean;\n /** リトライ詳細(executor のみ) */\n retryDetails?: StepRetryDetail[];\n /** キャッシュから取得した ref を使用したか */\n cachedRefUsed?: boolean;\n}\n\n/**\n * 失敗コンテキストからカテゴリを判定する。\n * 優先度順: action_failed > element_stale > page_structure_changed > element_not_found > navigation_timeout > unknown\n */\nexport function classifyFailure(ctx: ClassificationContext): FailureCategory {\n // アクション実行まで到達したが例外\n if (ctx.actionExecuted) {\n return \"action_failed\";\n }\n\n // キャッシュ ref がスナップショットに見つからなかった\n if (ctx.cachedRefUsed && !ctx.selectorResolved) {\n return \"element_stale\";\n }\n\n // セレクタ解決失敗(リトライ詳細あり)\n if (!ctx.selectorResolved && ctx.retryDetails && ctx.retryDetails.length > 0) {\n const anySnapshotChange = ctx.retryDetails.some((d) => d.snapshotChanged);\n if (anySnapshotChange) {\n return \"page_structure_changed\";\n }\n return \"element_not_found\";\n }\n\n // セレクタ解決失敗(リトライ詳細なし: generator 側など)\n if (!ctx.selectorResolved) {\n return \"element_not_found\";\n }\n\n // タイムアウト / ナビゲーション系\n const lowerError = ctx.error.toLowerCase();\n if (lowerError.includes(\"timeout\") || lowerError.includes(\"navigation\")) {\n return \"navigation_timeout\";\n }\n\n return \"unknown\";\n}\n\n/**\n * カテゴリ別の推奨対応テキスト。\n * reporter / chat-notifier 共通で使用。\n */\nexport function getRecoveryHint(category: FailureCategory): string {\n const keyMap: Record<FailureCategory, string> = {\n element_not_found: \"errors.elementNotFound\",\n element_stale: \"errors.elementStale\",\n page_structure_changed: \"errors.pageStructureChanged\",\n navigation_timeout: \"errors.navigationTimeout\",\n action_failed: \"errors.actionFailed\",\n unknown: \"errors.unknownError\",\n };\n return t(keyMap[category] as MessageKey);\n}\n\n/**\n * 技術的なブラウザエラーメッセージをユーザーフレンドリーなメッセージに変換する。\n * デバッグログには rawError をそのまま記録し、ユーザー向けにはサニタイズ済みを使用。\n */\nexport function sanitizeBrowserError(rawError: string): string {\n // page.evaluate エラー: スタックトレースを除去して本質的なエラーのみ\n const evalMatch = rawError.match(/^page\\.evaluate:\\s*([\\s\\S]+?)(?:\\n\\s+at\\s|$)/);\n if (evalMatch) {\n return `${t(\"errors.scriptExecutionError\" as MessageKey)}: ${evalMatch[1].trim()}`;\n }\n\n // Playwright の \"page.xxx:\" プレフィックス付きエラー\n const playwrightMatch = rawError.match(/^page\\.\\w+:\\s*([\\s\\S]+?)(?:\\n\\s+at\\s|$)/);\n if (playwrightMatch) {\n return `${t(\"errors.browserActionError\" as MessageKey)}: ${playwrightMatch[1].trim()}`;\n }\n\n // Timeout 系\n if (/Timeout \\d+ms exceeded/i.test(rawError)) {\n return t(\"errors.operationTimedOut\" as MessageKey);\n }\n\n return rawError;\n}\n","/**\n * orchestrator/memory-operations — メモリ追記のJSONパース共通処理\n *\n * runbook-generator (browser-tool.ts) と runbook-executor (executor.ts) の\n * memory_append ロジックを統合。\n */\n\nimport type { DataStore, DataAggregator } from \"./data-store\";\nimport type { DebugLogger } from \"../cli/debug-logger\";\nimport { log } from \"../cli/prompts\";\n\nexport interface MemoryAppendContext {\n dataStore: DataStore & DataAggregator;\n debugLogger: DebugLogger;\n phase: \"generator\" | \"executor\";\n step: number;\n collection: string;\n}\n\n/**\n * rawValue をパースして DataStore に追記する。\n *\n * - 二重 stringify 検出(JSON文字列のさらにJSONエスケープ)→ unwrap\n * - JSON配列 → dataStore.extend()(プリミティブは {index, value} にラップ)\n * - JSONオブジェクト → dataStore.append()\n * - フォールバック: {value: rawValue} として dataStore.append()\n */\nexport function parseAndAppendToMemory(\n rawValue: string,\n ctx: MemoryAppendContext,\n): { appended: number } {\n const { dataStore, debugLogger, phase, step, collection } = ctx;\n\n debugLogger.log({\n phase,\n event: \"memory_append\",\n step,\n data: {\n collection,\n rawValuePreview: rawValue.slice(0, 200),\n rawValueLength: rawValue.length,\n },\n });\n\n try {\n let dataToParse = rawValue;\n\n // 二重 stringify 検出: 文字列が JSON 文字列のさらに JSON エスケープの場合\n if (dataToParse.startsWith('\"') && dataToParse.endsWith('\"')) {\n try {\n const unquoted = JSON.parse(dataToParse);\n if (typeof unquoted === \"string\") {\n debugLogger.log({\n phase,\n event: \"memory_append\",\n step,\n data: { doubleStringifyDetected: true },\n });\n dataToParse = unquoted;\n }\n } catch {\n // 二重 stringify ではない — 元の値を使う\n }\n }\n\n const parsed = JSON.parse(dataToParse);\n\n if (Array.isArray(parsed)) {\n const items = parsed.map((item: unknown, i: number) => {\n if (typeof item === \"object\" && item !== null && !Array.isArray(item)) {\n return item as Record<string, unknown>;\n }\n return { index: i, value: item };\n });\n const firstKeys =\n items.length > 0\n ? JSON.stringify(Object.keys(items[0]))\n : \"N/A\";\n debugLogger.log({\n phase,\n event: \"memory_append\",\n step,\n data: {\n parseResult: \"array\",\n arrayLength: items.length,\n firstElementKeys: firstKeys,\n collection,\n count: items.length,\n },\n });\n dataStore.extend(collection, items);\n log.success(`Memory: appended ${items.length} items to \"${collection}\"`);\n return { appended: items.length };\n }\n\n const item =\n typeof parsed === \"object\" && parsed !== null\n ? (parsed as Record<string, unknown>)\n : { value: parsed };\n debugLogger.log({\n phase,\n event: \"memory_append\",\n step,\n data: {\n parseResult: \"object\",\n objectKeys: JSON.stringify(Object.keys(item)),\n collection,\n },\n });\n dataStore.append(collection, item);\n log.success(`Memory: appended 1 item to \"${collection}\"`);\n return { appended: 1 };\n } catch {\n debugLogger.log({\n phase,\n event: \"memory_append\",\n step,\n data: {\n parseResult: \"fallback\",\n collection,\n rawValuePreview: rawValue.slice(0, 200),\n },\n });\n log.warn(\n `Memory: could not parse as JSON, storing as {value: \"...\"} — extract script should return an array of objects`,\n );\n dataStore.append(collection, { value: rawValue });\n return { appended: 1 };\n }\n}\n","/**\n * performance/sleep — 共有 sleep ユーティリティ\n */\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","/**\n * Exploration agent prompt — English\n */\n\nimport type { SecretsData } from \"../../../cli/secrets-loader\";\n\nconst COMMAND_SCHEMA = `### Basic Operations\n- \\`click\\`: Click element by selector\n- \\`fill\\`: Fill value in selector (clears existing value)\n- \\`type\\`: Type value into selector character by character\n- \\`select\\`: Select value from dropdown by selector\n- \\`check\\` / \\`uncheck\\`: Toggle checkbox by selector\n\n### Navigation\n- \\`navigate\\`: Navigate to URL in value (only URLs explicitly stated in goal/context; use click for page links)\n- \\`wait\\`: Wait for value ms\n- \\`scroll\\`: value: \"up\"|\"down\"|\"left\"|\"right\"\n\n### Data Extraction\n- \\`extract\\`: Extract data via script (JS) or extractPrompt (AI). Result in extractedData\n - **script must return a flat array of objects. No JSON.stringify() needed**\n - When extracting tables, dynamically get column names from header row\n- \\`download\\`: Download by clicking selector (specify save path with downloadPath)\n- \\`export\\`: Export memory data to file (exportCollection, exportFormat: csv|json, exportPath)\n\n### Memory Operations\n- \\`memory_append\\`: Accumulate data in memoryCollection (value or previous extract result)\n - **extract and memory_append must be in the same actions array**\n- \\`memory_aggregate\\`: aggregation: {collection, field, operation: sum|count|concat|min|max|avg|unique_count, outputVariable}\n\n**Use only the actions listed above.**`;\n\nexport function getAgentInstructions(\n goal: string,\n contextMarkdown: string,\n secrets?: SecretsData,\n): string {\n const contextSection = contextMarkdown\n ? `\\n## Supplementary Information\\n${contextMarkdown}\\n`\n : \"\";\n\n let secretsSection = \"\";\n if (secrets && Object.keys(secrets.values).length > 0) {\n const entries = Object.entries(secrets.values)\n .map(([key, value]) => `- ${key}: ${value}`)\n .join(\"\\n\");\n secretsSection = `\\n## Input Values (secrets)\\nUse the following values when filling forms:\\n${entries}\\n\\n**Important**: Use these values verbatim. Do not replace them with sample data, test data, or guessed alternatives. If a required value is missing, do not invent, normalize, or paraphrase one.\\n\\n**Important**: When using these values, set the corresponding \\`variableName\\` and choose the appropriate \\`inputCategory\\` (\\`credential\\` or \\`user_data\\`).\\n`;\n }\n\n return `You are an AI explorer that navigates web pages to achieve goals.\nUse the browser tool to operate the browser and achieve the goal.\n\n## How to use the browser tool\n\n### Getting a Snapshot\nCall the browser tool with \\`actions: []\\` (empty array) to get the current page's snapshot (accessibility tree) and URL.\n\n### Executing Actions\nPass operations as an array in the browser tool's \\`actions\\`. Keep to 1-3 actions per call.\n\n### Selector Format\nUse \\`@eN\\` format corresponding to \\`[ref=eN]\\` in the snapshot (e.g., \\`@e1\\`, \\`@e10\\`)\n\n### Available Commands\n${COMMAND_SCHEMA}\n\n### Input Category (inputCategory)\nWhen entering values with fill/type, always include inputCategory:\n- \\`credential\\`: Authentication info (username, email, password, etc.)\n- \\`user_data\\`: User-specific data (name, address, phone number, etc.)\n- \\`fixed\\`: Fixed values (test values, constants, etc.)\n- \\`navigation\\`: URLs, search keywords, etc.\n\n### Variable Name (variableName)\nWhen entering values with fill/type, assign a short English camelCase variable name to \\`variableName\\`.\nExample: \\`email\\`, \\`password\\`, \\`searchQuery\\`, \\`companyName\\`, \\`firstName\\`\nAlways use the same name for the same concept (e.g., if email input appears in 2 places, use \\`email\\` for both).\n\n### Data Capture (suggestedCaptures)\nWhen important data appears on the page as a result of operations (IDs, order numbers, URL changes, amounts, etc.),\nrecord them with \\`suggestedCaptures\\`. Prioritize values needed in subsequent steps.\nAvailable strategies:\n- \\`snapshot\\`: Regex match on snapshot (pattern required)\n- \\`url\\`: Regex match on URL (pattern required)\n- \\`ai\\`: AI extraction with natural language (prompt required)\n- \\`expression\\`: Template from existing variables (expression required)\n- \\`evaluate\\`: Execute JavaScript on page and capture result (expression contains JS code)\n\nExample:\n\\`\\`\\`json\n{\n \"suggestedCaptures\": [\n { \"name\": \"orderId\", \"strategy\": \"snapshot\", \"pattern\": \"Order[::]\\\\\\\\s*([A-Z]+-\\\\\\\\d+)\", \"description\": \"Order confirmation number\" },\n { \"name\": \"resourceId\", \"strategy\": \"url\", \"pattern\": \"/orders/(\\\\\\\\d+)\" }\n ]\n}\n\\`\\`\\`\n\n## Critical Rules\n- **Only interact with elements visible in the snapshot.** Never guess about elements or URLs that may not exist\n- **Never guess input values.** Do not fabricate email addresses, passwords, names, phone numbers, or any other user data that is not present in Input Values (secrets), context, or the page itself\n- Navigate pages by clicking links/buttons on screen. Do not guess/construct URLs with \\`navigate\\` (except URLs explicitly stated in goal or context)\n- Only use \\`@eN\\` refs that exist as \\`[ref=eN]\\` in the most recent snapshot\n- If context (supplementary info) is provided, prioritize the procedures, paths, and hints described there\n- If the snapshot shows \\`[... N items omitted]\\`, the target element may be in the omitted section. Try \\`scroll\\` to move the view and re-fetch\n\n## Exploration Strategy\n1. First check page state with \\`actions: []\\`\n2. **Carefully read** the snapshot and identify elements related to the goal using keyword matching:\n - Break down the goal into keywords (e.g., \"Log in to the dashboard\" → \"login\", \"sign in\", \"dashboard\") and scan link/button names\n - Prioritize exact keyword matches over vague labels (e.g., prefer \"Login\" over \"Click here\")\n3. Execute operations using the identified \\`@eN\\` refs\n4. Check results and decide next operation (observe → decide → act cycle)\n5. If target element is not found, \\`scroll\\` to move the view and check the snapshot again\n6. Use \\`select\\` command for SELECT elements, not \\`click\\`\n7. Use \\`check\\` / \\`uncheck\\` commands for checkboxes\n8. Use \\`click\\` command for radio buttons — just click the desired option directly\n9. Never use \\`extract\\` to investigate form elements. If radio buttons, checkboxes, or dropdowns are visible in the snapshot, interact with them directly using the appropriate command\n\n## Link Selection and Navigation Recovery\nWhen a page has many links:\n1. **Relevance check before clicking**: Only click links whose name clearly relates to a goal keyword. Links with generic names are a last resort\n2. **Avoid exploratory clicking**: Do not click links just to \"see what happens.\" Each click must have a clear rationale tied to the goal\n3. **Recovery from wrong navigation**: If a clicked page is unrelated to the goal, \\`navigate\\` back to the starting URL and look for alternative links\n\n## Form Input Efficiency\nWhen filling large forms, strictly follow these rules:\n1. **Enter each field only once** — Do not re-operate on fields that already have values\n2. **Check filled fields in snapshot** — After fill/type, the field value appears in the snapshot. Skip fields showing values\n3. **Progress systematically top to bottom** — Process fieldsets/sections in order. Don't go back to previous sections\n4. **Track filled field count** — Reference operation history to know what you've already entered. Duplicate operations on the same selector are forbidden\n5. **Submit after all fields are filled** — Once all required fields are complete, promptly click the submit button\n6. **Check filledFields** — The browser tool result includes filledFields listing filled fields. Never re-enter fields in this list\n\n## Form Completion Verification\nBefore returning your final report when filling forms:\n1. Scan the ENTIRE current snapshot for remaining unfilled fields — check every fieldset/section\n2. Look for: empty textboxes (no value), comboboxes showing placeholder like \"Select...\", unchecked checkboxes\n3. The LAST section of a form is commonly missed — always verify the bottom of the form\n4. After all fields are filled, click the submit/register button\n5. Verify the success confirmation appears before declaring goalAchieved: true\nDo NOT declare goalAchieved without first confirming all form sections are complete and the form is submitted.\n\n## Data Collection Pattern (Pagination Traversal)\nProcedure: extract → memory_append → click \"Next\" → repeat → memory_aggregate for aggregation\n\nExample (table extract → accumulate → next page → aggregate → CSV export):\n\\`\\`\\`json\n[\n {\"action\":\"extract\",\"description\":\"Extract table\",\"script\":\"(()=>{const h=[...document.querySelectorAll('table thead th')].map(t=>t.textContent.trim());return[...document.querySelectorAll('table tbody tr')].map(r=>{const c=r.querySelectorAll('td');return Object.fromEntries([...c].map((c,i)=>[h[i]||'col'+i,c.textContent.trim()]));});})()\"},\n {\"action\":\"memory_append\",\"description\":\"Accumulate\",\"memoryCollection\":\"data\"},\n {\"action\":\"click\",\"description\":\"Next page\",\"selector\":\"@e15\"}\n]\n\\`\\`\\`\nAggregate: \\`[{\"action\":\"memory_aggregate\",\"description\":\"Sum total\",\"aggregation\":{\"collection\":\"data\",\"field\":\"amount\",\"operation\":\"sum\",\"outputVariable\":\"total\"}}]\\`\nCSV export: \\`[{\"action\":\"export\",\"description\":\"CSV export\",\"exportCollection\":\"data\",\"exportFormat\":\"csv\",\"exportPath\":\"/tmp/data.csv\"}]\\`\n\nNote: No JSON.stringify() needed in script. Each row is a flat object. Check collection item count via memoryStatus.\n\n**Important**: When paginating, you MUST continue until the LAST page. Check the page indicator (e.g., \"Page X of Y\") and keep clicking \"Next\" until you reach the final page. Do NOT stop after a few pages — process every single page. The goal is not to demonstrate the pattern but to complete the full traversal.\n\n## Using filledFields\nIf the browser tool result includes \\`filledFields\\`, this is a list of already-filled form fields.\nDo not re-enter fields in this list. Only operate on unfilled fields.\n\n## Diff Snapshots\nAfter text input (fill/type), if page structure hasn't changed, you'll receive a compact snapshot listing all refs.\n- \\`Unfilled:\\` shows elements you still need to interact with\n- \\`Filled:\\` shows elements already filled\n- All refs from the compact snapshot are valid and usable\n- If you need full page context, call the browser tool with \\`actions: []\\`\n\n## Responding to nudgeMessage\nIf the browser tool result includes \\`nudgeMessage\\`, it contains important guidance:\n- **Pagination progress**: Shows current page and remaining pages. You MUST continue until ALL pages are processed.\n- **Loop warning**: Indicates you are repeating the same actions without progress. Try a different approach.\n- **Form hints**: Lists remaining unfilled form fields.\nAlways follow the instructions in the message.\n\n## Compound Goal Verification\nWhen the goal contains multiple steps (e.g., \"Do A, then navigate to B, then execute C\"):\n1. Break down the goal into individual sub-tasks\n2. Verify each sub-task is completed by checking the current page state\n3. **Do NOT declare goalAchieved until ALL sub-tasks are completed**\n4. Even if login or page navigation succeeds, the goal is NOT achieved if subsequent tasks remain\n5. If some sub-tasks have been completed, keep working on the remaining ones. Only declare goalAchieved: false when you encounter an unrecoverable error or have exhausted all reasonable approaches\n\nExample: If the goal is \"Log in and then execute X in the action list\":\n- Login succeeds → NOT goalAchieved yet (executing X remains)\n- X executed in action list → goalAchieved: true\n\n## When Goal is Achieved\n**CRITICAL: Your goal achievement claim will be independently verified against the final page state. False claims will be overridden.**\n\nBefore declaring goalAchieved: true, you MUST complete this mandatory checklist:\n1. **Re-read the original goal** and break it into every sub-task\n2. **Check the current page state** — does the snapshot show clear evidence of completion?\n3. **For form tasks**: Is a success/confirmation message visible? (NOT just \"fields are filled\" — the form must be SUBMITTED and confirmed)\n4. **For navigation tasks**: Is the target page actually displayed?\n5. **For compound goals** (A then B then C): Verify evidence for EACH part, not just the first\n6. **Look for failure signals**: Error messages, validation warnings, login forms still visible, \"try again\" prompts\n7. **Include specific evidence** in your summary: quote the confirmation message, success banner, or page title that proves completion\n\nCommon false positive patterns to AVOID:\n- Declaring success after login when the goal includes post-login tasks\n- Declaring success after filling a form but before submitting it\n- Declaring success based on clicking a button without waiting for confirmation\n- Declaring success when the page shows an error or is still loading\n\nWhen you have verified ALL checklist items, stop calling the browser tool and return:\n\\`\\`\\`json\n{ \"goalAchieved\": true, \"summary\": \"Evidence: [specific confirmation message or page state]. Completed: [list of sub-tasks done]\" }\n\\`\\`\\`\n\nIf the goal cannot be achieved:\n\\`\\`\\`json\n{ \"goalAchieved\": false, \"summary\": \"Summary of the situation and reasons\" }\n\\`\\`\\`\n\n---\nThe following is task-specific information.\n\n## Goal\n${goal}\n${contextSection}${secretsSection}\nRespond in English.`;\n}\n\nexport function getInitialUserMessage(): string {\n return \"Call the browser tool with actions:[] (empty array) to check the current page state. Then begin exploring toward the goal.\";\n}\n","/**\n * Exploration agent prompt — Japanese (current production)\n */\n\nimport type { SecretsData } from \"../../../cli/secrets-loader\";\n\nconst COMMAND_SCHEMA = `### 基本操作\n- \\`click\\`: selector で要素クリック\n- \\`fill\\`: selector に value を入力(既存値クリア)\n- \\`type\\`: selector に value を1文字ずつ入力\n- \\`select\\`: selector のドロップダウンで value を選択\n- \\`check\\` / \\`uncheck\\`: selector のチェックボックス操作\n\n### ナビゲーション\n- \\`navigate\\`: value のURLに移動(ゴール/コンテキストで明示されたURLのみ。ページ内リンクは click)\n- \\`wait\\`: value ms待機\n- \\`scroll\\`: value: \"up\"|\"down\"|\"left\"|\"right\"\n\n### データ抽出\n- \\`extract\\`: script(JS) または extractPrompt(AI) でデータ抽出。結果は extractedData\n - **script はフラットなオブジェクト配列を返すこと。JSON.stringify()不要**\n - テーブル抽出時はヘッダー行からカラム名を動的取得\n- \\`download\\`: selector クリックでダウンロード(downloadPath で保存先指定可)\n- \\`export\\`: メモリデータをファイル出力(exportCollection, exportFormat: csv|json, exportPath)\n\n### メモリ操作\n- \\`memory_append\\`: memoryCollection にデータ蓄積(value または直前 extract 結果)\n - **extract と memory_append は必ず同じ actions 配列に含めること**\n- \\`memory_aggregate\\`: aggregation: {collection, field, operation: sum|count|concat|min|max|avg|unique_count, outputVariable}\n\n**上記のアクションのみ使用。**`;\n\nexport function getAgentInstructions(\n goal: string,\n contextMarkdown: string,\n secrets?: SecretsData,\n): string {\n const contextSection = contextMarkdown\n ? `\\n## 補足情報\\n${contextMarkdown}\\n`\n : \"\";\n\n let secretsSection = \"\";\n if (secrets && Object.keys(secrets.values).length > 0) {\n const entries = Object.entries(secrets.values)\n .map(([key, value]) => `- ${key}: ${value}`)\n .join(\"\\n\");\n secretsSection = `\\n## 入力値(secrets)\\nフォーム入力時に以下の値を使用してください:\\n${entries}\\n\\n**重要**: これらの値はそのまま厳密に使用してください。別のテスト値・サンプル値・推測値に置き換えてはいけません。必要な値が不足している場合も、補完・正規化・言い換えで埋めず、未提供として扱ってください。\\n\\n**重要**: これらの値を使用する際は、対応する \\`variableName\\` を設定し、\\`inputCategory\\` は \\`credential\\` または \\`user_data\\` を適切に選択してください。\\n`;\n }\n\n return `あなたはWebページを探索してゴールを達成するAIエクスプローラーです。\nbrowserツールを使ってブラウザを操作し、ゴールを達成してください。\n\n## browserツールの使い方\n\n### スナップショット取得\nbrowserツールを \\`actions: []\\`(空配列)で呼ぶと、現在のページのスナップショット(アクセシビリティツリー)とURLが返ります。\n\n### アクション実行\nbrowserツールの \\`actions\\` に操作を配列で渡すと順次実行されます。1回の呼び出しで1〜3アクション程度に抑えてください。\n\n### セレクタ形式\nスナップショットの \\`[ref=eN]\\` に対応する \\`@eN\\` 形式で指定(例: \\`@e1\\`, \\`@e10\\`)\n\n### 利用可能なコマンド\n${COMMAND_SCHEMA}\n\n### 入力値のカテゴリ(inputCategory)\nfill/type で値を入力する場合、必ず inputCategory を付与:\n- \\`credential\\`: ユーザー名、メールアドレス、パスワード等の認証情報\n- \\`user_data\\`: ユーザー固有のデータ(名前、住所、電話番号等)\n- \\`fixed\\`: 固定値(テスト値、定数等)\n- \\`navigation\\`: URL、検索キーワード等\n\n### 変数名(variableName)\nfill/type で値を入力する場合、短い英語 camelCase の変数名を \\`variableName\\` に付与してください。\n例: \\`email\\`, \\`password\\`, \\`searchQuery\\`, \\`companyName\\`, \\`firstName\\`\n同じ概念の値には必ず同じ名前を使用してください(例: メールアドレス入力が2箇所あれば両方 \\`email\\`)。\n\n### データキャプチャ(suggestedCaptures)\n操作結果として重要なデータ(ID、注文番号、URL変化、金額等)がページに現れた場合、\n\\`suggestedCaptures\\` で記録してください。後続ステップで参照が必要になる値を優先。\n利用可能な strategy:\n- \\`snapshot\\`: スナップショットに正規表現マッチ(pattern 必須)\n- \\`url\\`: URLに正規表現マッチ(pattern 必須)\n- \\`ai\\`: AIに自然言語で抽出させる(prompt 必須)\n- \\`expression\\`: 既存変数からテンプレート組み立て(expression 必須)\n- \\`evaluate\\`: ページ内でJavaScriptを実行して結果をキャプチャ(expression にJSコードを指定)\n\n例:\n\\`\\`\\`json\n{\n \"suggestedCaptures\": [\n { \"name\": \"orderId\", \"strategy\": \"snapshot\", \"pattern\": \"注文番号[::]\\\\\\\\s*([A-Z]+-\\\\\\\\d+)\", \"description\": \"注文確認番号\" },\n { \"name\": \"resourceId\", \"strategy\": \"url\", \"pattern\": \"/orders/(\\\\\\\\d+)\" }\n ]\n}\n\\`\\`\\`\n\n## 最重要ルール\n- **スナップショットに見えている要素だけを操作すること。** 存在するか分からない要素やURLを推測してはいけない\n- **入力値を推測してはいけない。** 入力値(secrets)・コンテキスト・ページ上に存在しないメールアドレス、パスワード、氏名、電話番号などを勝手に作らない\n- ページ遷移は画面上のリンクやボタンを \\`click\\` で行う。\\`navigate\\` でURLを推測・組み立てることは禁止(ゴールやコンテキストで明示されたURLは除く)\n- 操作対象の \\`@eN\\` は、直前のスナップショットに \\`[ref=eN]\\` として存在するものだけを使用する\n- コンテキスト(補足情報)が提供されている場合、そこに記載された手順・導線・ヒントを優先的に参照する\n- スナップショットに \\`[... N件省略]\\` とある場合、目的の要素が省略部分にある可能性がある。\\`scroll\\` で画面を動かして再取得を試みること\n\n## 探索戦略\n1. まず \\`actions: []\\` でページ状態を確認\n2. スナップショットを**注意深く読み**、ゴールのキーワードを使って関連要素を特定:\n - ゴールをキーワードに分解し(例: 「ログインしてダッシュボード表示」→ 「ログイン」「サインイン」「ダッシュボード」)、リンク・ボタン名から検索する\n - 曖昧なラベル(「詳細」「こちら」)より、キーワードに一致するリンクを優先する\n3. 特定した要素の \\`@eN\\` を使って操作を実行\n4. 結果を確認し、次の操作を決定(観察→判断→行動の繰り返し)\n5. 目的の要素が見つからない場合は \\`scroll\\` で画面を移動し、再度スナップショットを確認する\n6. SELECT要素には \\`click\\` ではなく \\`select\\` コマンドを使用\n7. チェックボックスには \\`check\\` / \\`uncheck\\` コマンドを使用\n8. ラジオボタンには \\`click\\` コマンドを使用 — 選択したいオプションを直接クリックする\n9. フォーム要素の調査に \\`extract\\` を使わないこと。スナップショットにラジオボタン・チェックボックス・ドロップダウンが見えていれば、適切なコマンドで直接操作する\n\n## リンク選択とナビゲーション回復\nページに多数のリンクがある場合:\n1. **クリック前の関連性チェック**: リンクの名前がゴールのキーワードに関連する場合のみクリックする。汎用的な名前のリンクは最後の手段\n2. **探索的クリックの回避**: 「どうなるか見てみよう」でリンクをクリックしない。各クリックにはゴールに紐づいた根拠が必要\n3. **誤遷移からの回復**: クリック後のページがゴールに無関係な場合、開始URLに \\`navigate\\` で戻り、別のリンクを探す\n\n## フォーム入力の効率化\n大きなフォームを入力する際は、以下のルールを厳守してください:\n1. **各フィールドは1回だけ入力する** — 既に値が入力されたフィールドを再度操作しないこと\n2. **スナップショットで入力済みフィールドを確認する** — fill/type 後のフィールドはスナップショットに入力値が表示される。値が表示されているフィールドはスキップする\n3. **上から下へ体系的に進む** — フォーム内のフィールドセット/セクションを上から順に処理する。前のセクションに戻らない\n4. **入力済みフィールド数を意識する** — 操作履歴を参照し、既に何を入力したかを把握する。同じセレクタへの重複操作は禁止\n5. **全フィールド入力後に送信する** — フォーム内の全必須フィールドが埋まったら、速やかに送信ボタンをクリックする\n6. **filledFields を確認する** — browserツールの結果に含まれる filledFields は入力済みフィールドの一覧。この一覧にあるフィールドは絶対に再入力しないこと\n\n## フォーム完了の検証\nフォーム入力のゴールで最終報告を返す前に:\n1. 現在のスナップショット全体をスキャンし、未入力フィールドがないか確認 — 全フィールドセット/セクションをチェック\n2. 以下を探す: 値のないテキストボックス、「Select...」プレースホルダー表示のドロップダウン、未チェックのチェックボックス\n3. フォームの最後のセクションは見落としやすい — フォーム最下部を必ず確認\n4. 全フィールド入力後、送信/登録ボタンをクリック\n5. goalAchieved: true を宣言する前に成功確認メッセージの表示を確認\n全セクション完了・フォーム送信を確認するまで goalAchieved を宣言しないこと。\n\n## データ収集パターン(ページネーション走査)\n手順: extract → memory_append → click「次へ」→ 繰り返し → memory_aggregate で集計\n\n例(テーブル抽出 → 蓄積 → 次ページ → 集計 → CSV出力):\n\\`\\`\\`json\n[\n {\"action\":\"extract\",\"description\":\"テーブル抽出\",\"script\":\"(()=>{const h=[...document.querySelectorAll('table thead th')].map(t=>t.textContent.trim());return[...document.querySelectorAll('table tbody tr')].map(r=>{const c=r.querySelectorAll('td');return Object.fromEntries([...c].map((c,i)=>[h[i]||'col'+i,c.textContent.trim()]));});})()\"},\n {\"action\":\"memory_append\",\"description\":\"蓄積\",\"memoryCollection\":\"data\"},\n {\"action\":\"click\",\"description\":\"次ページ\",\"selector\":\"@e15\"}\n]\n\\`\\`\\`\n集計: \\`[{\"action\":\"memory_aggregate\",\"description\":\"合計\",\"aggregation\":{\"collection\":\"data\",\"field\":\"amount\",\"operation\":\"sum\",\"outputVariable\":\"total\"}}]\\`\nCSV出力: \\`[{\"action\":\"export\",\"description\":\"CSV出力\",\"exportCollection\":\"data\",\"exportFormat\":\"csv\",\"exportPath\":\"/tmp/data.csv\"}]\\`\n\n注意: script で JSON.stringify() 不要。各行はフラットなオブジェクト。memoryStatus でコレクションのアイテム数を確認可能。\n\n**重要**: ページネーション走査時は最後のページまで必ず継続してください。ページ表示(例: \"Page X of Y\")を確認し、最終ページに到達するまで「次へ」をクリックし続けてください。数ページで止めず、全ページを処理してください。パターンを示すことが目的ではなく、全データの走査を完了することが目的です。\n\n## filledFields の活用\nbrowserツールの結果に \\`filledFields\\` が含まれている場合、これは既に入力済みのフォームフィールドの一覧です。\nリストに含まれるフィールドには再度入力しないでください。未入力のフィールドのみを操作してください。\n\n## 差分スナップショット\nテキスト入力(fill/type)後にページ構造が変わっていない場合、全refを一覧にしたコンパクトなスナップショットが返されます。\n- \\`Unfilled:\\` はまだ操作が必要な要素を示します\n- \\`Filled:\\` は入力済みの要素を示します\n- コンパクトスナップショット内の全refは有効で使用可能です\n- 完全なページコンテキストが必要な場合は \\`actions: []\\` でブラウザツールを呼び出してください\n\n## nudgeMessage への対応\nbrowserツールの結果に \\`nudgeMessage\\` が含まれている場合、重要なガイダンスが記載されています:\n- **ページネーション進捗**: 現在のページと残りページ数を示します。全ページの処理が完了するまで続行してください。\n- **ループ警告**: 同じ操作を繰り返している可能性があります。別のアプローチを試してください。\n- **フォームヒント**: 未入力のフォームフィールド一覧です。\nメッセージの指示に必ず従ってください。\n\n## 複合ゴールの検証\nゴールに複数のステップが含まれている場合(例: 「Aして、Bに遷移し、Cを実行する」):\n1. ゴールを個別のサブタスクに分解する\n2. 各サブタスクが完了したかどうかを現在のページ状態から確認する\n3. **全てのサブタスクが完了するまで goalAchieved を宣言しないこと**\n4. ログインやページ遷移が成功しても、後続のタスクがあればまだゴールは未達成\n5. 一部のサブタスクが完了している場合は、残りのサブタスクに取り組み続けること。回復不能なエラーや全てのアプローチを試した場合にのみ goalAchieved: false を宣言する\n\n例: ゴールが「ログインしてアクション一覧でXを実行する」の場合:\n- ログイン成功 → まだ goalAchieved ではない(アクション実行が残っている)\n- アクション一覧でXを実行完了 → goalAchieved: true\n\n## ゴール達成時\n**重要: goalAchieved の申告は最終ページ状態から独立検証されます。虚偽の申告は上書きされます。**\n\ngoalAchieved: true を宣言する前に、以下のチェックリストを必ず完了してください:\n1. **元のゴールを再確認** — 全てのサブタスクに分解する\n2. **現在のページ状態を確認** — スナップショットに達成の明確な証拠があるか?\n3. **フォームタスク**: 成功/確認メッセージが表示されているか?(「フィールドを入力した」だけでは不十分 — フォームが送信され、確認が表示されていること)\n4. **ナビゲーションタスク**: 目的のページが実際に表示されているか?\n5. **複合ゴール**(A → B → C): 最初の部分だけでなく、全パートの証拠を確認\n6. **失敗シグナルの確認**: エラーメッセージ、バリデーション警告、ログインフォームがまだ表示されていないか、「再試行」プロンプトがないか\n7. **summary に具体的な証拠を含める**: 完了を証明する確認メッセージ、成功バナー、ページタイトルを引用する\n\nよくある偽陽性パターン(避けるべき):\n- ログイン後のタスクがあるのに、ログイン成功だけで達成と宣言する\n- フォーム入力後、送信前に達成と宣言する\n- ボタンクリック後、確認を待たずに達成と宣言する\n- ページがエラーを表示している、またはロード中なのに達成と宣言する\n\n全チェック項目を確認した上で、browserツールの呼び出しを停止し、以下のJSON形式で最終報告を返してください:\n\\`\\`\\`json\n{ \"goalAchieved\": true, \"summary\": \"証拠: [具体的な確認メッセージやページ状態]。完了: [実行したサブタスク一覧]\" }\n\\`\\`\\`\n\nゴールが達成できないと判断した場合:\n\\`\\`\\`json\n{ \"goalAchieved\": false, \"summary\": \"状況の要約と理由\" }\n\\`\\`\\`\n\n---\n以下はこのタスク固有の情報です。\n\n## ゴール\n${goal}\n${contextSection}${secretsSection}\n日本語で応答してください。`;\n}\n\nexport function getInitialUserMessage(): string {\n return \"browserツールをactions:[](空配列)で呼び出し、現在のページ状態を確認してください。その後、ゴール達成に向けて探索を開始してください。\";\n}\n","/**\n * Review prompt — English\n */\n\nimport type { RecordedStep, InterventionRecord } from \"../../../runbook-generator/types\";\n\nexport function getReviewSystemPrompt(): string {\n return `You are an expert reviewer of web browser automation procedures.\n\n## Task\nAnalyze the recorded steps and determine the following:\n\n1. **Remove unnecessary steps**: Identify and exclude trial-and-error during exploration, dead ends, unnecessary navigation, and duplicate operations\n2. **Risk level assessment**: Assess the risk of each step\n - \\`low\\`: Low side-effect operations like input, scrolling, navigation\n - \\`medium\\`: Login, form submission, settings changes, etc.\n - \\`high\\`: Irreversible operations like deletion, payment, data modification\n3. **Approval requirement**: Whether user approval is needed before execution\n\n## Capture Candidate Identification\nIf you detect important data used in subsequent steps (IDs, order numbers, URL changes, amounts, etc.),\ninclude them as suggestedCaptures in each step's response.\nAvailable strategies: snapshot (regex), url (URL regex), ai (AI extraction), expression (template)\n\n## Notes\n- Failed steps (success=false) should generally be excluded\n- Keep only the shortest path steps needed to achieve the goal\n- riskLevel is used in the Chrome extension approval flow (medium/high requires approval)\n- Respond in English`;\n}\n\nexport function createReviewUserPrompt(\n goal: string,\n recordedSteps: RecordedStep[],\n goalAchieved: boolean,\n interventions?: InterventionRecord[],\n): string {\n const stepsList = recordedSteps\n .map(\n (s) =>\n `${s.ordinal}. [${s.success ? \"OK\" : \"FAIL\"}] ${s.action.description} (action: ${s.action.action}, url: ${s.url})${s.error ? ` Error: ${s.error}` : \"\"}`,\n )\n .join(\"\\n\");\n\n const interventionsSection =\n interventions && interventions.length > 0\n ? `\\n## User Interventions During Exploration\nThe user modified the exploration direction at the following points.\nSteps before the intervention likely contain trial-and-error, while steps after are more accurate.\n\n${interventions\n .map(\n (iv, i) =>\n `${i + 1}. Around step #${iv.stepIndex}: \"${iv.userInstruction}\" (URL: ${iv.url})`,\n )\n .join(\"\\n\")}\n\n**Review note**: Actively exclude unnecessary steps before intervention points.\n`\n : \"\";\n\n return `## Goal\n${goal}\n\n## Goal Achievement Status\n${goalAchieved ? \"Achieved\" : \"Not achieved\"}\n${interventionsSection}\n## All Recorded Steps\n${stepsList}`;\n}\n","/**\n * Review prompt — Japanese (current production)\n */\n\nimport type { RecordedStep, InterventionRecord } from \"../../../runbook-generator/types\";\n\nexport function getReviewSystemPrompt(): string {\n return `あなたはWebブラウザ自動操作の手順書をレビューするエキスパートです。\n\n## タスク\n記録されたステップを分析し、以下を判定してください:\n\n1. **不要ステップの除外**: 探索中の試行錯誤、行き止まり、不要なナビゲーション、重複操作を特定し除外\n2. **リスクレベル判定**: 各ステップのリスクを判定\n - \\`low\\`: 入力、スクロール、ナビゲーションなど副作用の少ない操作\n - \\`medium\\`: ログイン、フォーム送信、設定変更など\n - \\`high\\`: 削除、決済、データ変更など不可逆な操作\n3. **承認要否判定**: 実行前にユーザー承認が必要かどうか\n\n## キャプチャ候補の識別\n操作結果として後続ステップで使用される重要なデータ(ID、注文番号、URL変化、金額など)を検出した場合、\nsuggestedCaptures としてレスポンスの各ステップに含めてください。\n利用可能な strategy: snapshot(正規表現), url(URL正規表現), ai(AI抽出), expression(テンプレート)\n\n## 注意事項\n- 失敗ステップ(success=false)は基本的に除外してください\n- ゴール達成に必要な最短経路のステップのみ残してください\n- riskLevel は Chrome拡張の承認フローで使用されます(medium/high は承認が必要)\n- 日本語で応答してください`;\n}\n\nexport function createReviewUserPrompt(\n goal: string,\n recordedSteps: RecordedStep[],\n goalAchieved: boolean,\n interventions?: InterventionRecord[],\n): string {\n const stepsList = recordedSteps\n .map(\n (s) =>\n `${s.ordinal}. [${s.success ? \"成功\" : \"失敗\"}] ${s.action.description} (action: ${s.action.action}, url: ${s.url})${s.error ? ` エラー: ${s.error}` : \"\"}`,\n )\n .join(\"\\n\");\n\n const interventionsSection =\n interventions && interventions.length > 0\n ? `\\n## 探索中のユーザー介入\n以下のタイミングでユーザーが探索方針を修正しました。\n介入前のステップには探索の試行錯誤が含まれている可能性が高く、介入後のステップがより正確な手順です。\n\n${interventions\n .map(\n (iv, i) =>\n `${i + 1}. ステップ#${iv.stepIndex}付近: \"${iv.userInstruction}\" (URL: ${iv.url})`,\n )\n .join(\"\\n\")}\n\n**レビュー時の注意**: 介入ポイントより前の不要なステップは積極的に除外してください。\n`\n : \"\";\n\n return `## ゴール\n${goal}\n\n## ゴール達成状況\n${goalAchieved ? \"達成済み\" : \"未達成\"}\n${interventionsSection}\n## 記録された全ステップ\n${stepsList}`;\n}\n","/**\n * Selector resolver prompt — English\n */\n\nimport type { Selector } from \"../../../runbook-executor/types\";\nimport type { RetryContext } from \"../../../harness/selector-resolver\";\n\nexport function buildSelectorMessages(\n snapshot: string,\n selector: Selector,\n stepDescription: string,\n url: string,\n contextMarkdown: string,\n retryContext?: RetryContext,\n workingMemorySummary?: string,\n): { system: string; userPrompt: string } {\n const system = [\n \"You are a selector resolver for browser automation.\",\n \"Based on the step description, identify the target element in the accessibility snapshot.\",\n \"\",\n \"## Matching Guidelines\",\n \"1. Infer the type of target element (button, input field, link, etc.) from the step description\",\n \"2. Find the element in the snapshot that semantically best matches the step description\",\n \"3. Use surrounding text, labels, placeholders, and roles as clues\",\n \"4. Even without an exact match, return the ref of the most likely element\",\n \"5. Return an empty string only if the target element truly does not exist in the snapshot\",\n ].join(\"\\n\");\n\n const parts: string[] = [\n \"## Step Description (Most Important)\",\n stepDescription,\n \"\",\n \"## Selector Hints (Reference)\",\n \"The following is reference information for identifying the element. Even without an exact match, choose the element semantically closest to the step description.\",\n JSON.stringify(pruneSelectorHints(selector)),\n \"\",\n \"Notes:\",\n '- If tagName is \"unknown\" or \":\", there is no tag name information',\n \"- ariaLabel is auto-generated from the step description and may not match the actual aria-label attribute\",\n \"- Prioritize semantic match with the step description over exact selector match\",\n \"\",\n \"## Current URL\",\n url,\n ];\n\n if (workingMemorySummary) {\n parts.push(\"\", \"## Execution Context\", workingMemorySummary);\n }\n\n parts.push(\n \"\",\n \"## Accessibility Snapshot\",\n snapshot,\n );\n\n const includeContext = contextMarkdown && !(retryContext && retryContext.attempt > 0);\n if (includeContext) {\n parts.push(\"\", \"## Supplementary Context\", contextMarkdown);\n }\n\n if (retryContext && retryContext.attempt > 0) {\n parts.push(\n \"\",\n \"## Recovery Context (Attempt \" + (retryContext.attempt + 1) + \")\",\n );\n\n // Failure pattern hints from registry\n if (retryContext.failureHints) {\n parts.push(`Pattern: ${retryContext.failureHints}`);\n }\n\n if (retryContext.failureHistory.length > 0) {\n const recent = retryContext.failureHistory.slice(-2);\n parts.push(`Previous: ${recent.join(\"; \")}`);\n }\n if (retryContext.previousAiResponse) {\n // Extract only the reasoning from the previous AI response\n try {\n const parsed = JSON.parse(retryContext.previousAiResponse);\n if (parsed.reasoning) {\n parts.push(`Last reasoning: \"${parsed.reasoning}\"`);\n }\n } catch {\n parts.push(`Last response: ${retryContext.previousAiResponse.slice(0, 200)}`);\n }\n }\n if (!retryContext.snapshotChanged) {\n parts.push(\n \"Snapshot unchanged — try partial matching, role-based matching, or inference from nearby elements.\",\n );\n }\n }\n\n return { system, userPrompt: parts.join(\"\\n\") };\n}\n\nfunction pruneSelectorHints(selector: Selector): Record<string, unknown> {\n const pruned: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(selector)) {\n if (value === null || value === undefined || value === \"\" || value === \"unknown\" || value === \":\") continue;\n pruned[key] = value;\n }\n return pruned;\n}\n","/**\n * Selector resolver prompt — Japanese (current production)\n */\n\nimport type { Selector } from \"../../../runbook-executor/types\";\nimport type { RetryContext } from \"../../../harness/selector-resolver\";\n\nexport function buildSelectorMessages(\n snapshot: string,\n selector: Selector,\n stepDescription: string,\n url: string,\n contextMarkdown: string,\n retryContext?: RetryContext,\n workingMemorySummary?: string,\n): { system: string; userPrompt: string } {\n const system = [\n \"あなたはブラウザ自動操作のセレクタリゾルバーです。\",\n \"ステップの説明に基づいて、アクセシビリティスナップショット内の操作対象要素を特定してください。\",\n \"\",\n \"## マッチングの指針\",\n \"1. ステップの説明から操作対象の要素の種類(ボタン、入力フィールド、リンク等)を推定する\",\n \"2. スナップショット内で、ステップの説明と意味的に最も一致する要素を探す\",\n \"3. 周辺のテキスト、ラベル、プレースホルダー、role も手がかりにする\",\n \"4. 完全一致がなくても最も可能性の高い要素の ref を返す\",\n \"5. 該当する要素がスナップショット内に本当に存在しない場合のみ空文字を返す\",\n ].join(\"\\n\");\n\n const parts: string[] = [\n \"## ステップの説明(最重要)\",\n stepDescription,\n \"\",\n \"## セレクタのヒント(参考情報)\",\n \"以下は要素を特定するための参考情報です。完全一致しない場合でも、ステップの説明から意味的に最も近い要素を選んでください。\",\n JSON.stringify(pruneSelectorHints(selector)),\n \"\",\n \"注意:\",\n '- tagName が \"unknown\" や \":\" の場合はタグ名情報がありません',\n \"- ariaLabel はステップ説明から自動生成されたものであり、実際の aria-label 属性と一致しないことがあります\",\n \"- セレクタの完全一致よりもステップの説明との意味的一致を優先してください\",\n \"\",\n \"## 現在のURL\",\n url,\n ];\n\n if (workingMemorySummary) {\n parts.push(\"\", \"## 実行コンテキスト\", workingMemorySummary);\n }\n\n parts.push(\n \"\",\n \"## アクセシビリティスナップショット\",\n snapshot,\n );\n\n const includeContext = contextMarkdown && !(retryContext && retryContext.attempt > 0);\n if (includeContext) {\n parts.push(\"\", \"## 補足コンテキスト\", contextMarkdown);\n }\n\n if (retryContext && retryContext.attempt > 0) {\n parts.push(\n \"\",\n \"## 回復コンテキスト(試行\" + (retryContext.attempt + 1) + \"回目)\",\n );\n\n // FailureRegistry からの回復ヒント\n if (retryContext.failureHints) {\n parts.push(`パターン: ${retryContext.failureHints}`);\n }\n\n if (retryContext.failureHistory.length > 0) {\n const recent = retryContext.failureHistory.slice(-2);\n parts.push(`直近の失敗: ${recent.join(\"; \")}`);\n }\n if (retryContext.previousAiResponse) {\n try {\n const parsed = JSON.parse(retryContext.previousAiResponse);\n if (parsed.reasoning) {\n parts.push(`前回の推論: \"${parsed.reasoning}\"`);\n }\n } catch {\n parts.push(`前回の応答: ${retryContext.previousAiResponse.slice(0, 200)}`);\n }\n }\n if (!retryContext.snapshotChanged) {\n parts.push(\n \"スナップショット未変化 — 部分一致、roleベースのマッチング、近接要素からの推定を試みてください。\",\n );\n }\n }\n\n return { system, userPrompt: parts.join(\"\\n\") };\n}\n\nfunction pruneSelectorHints(selector: Selector): Record<string, unknown> {\n const pruned: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(selector)) {\n if (value === null || value === undefined || value === \"\" || value === \"unknown\" || value === \":\") continue;\n pruned[key] = value;\n }\n return pruned;\n}\n","/**\n * Goal agent (fallback) prompt — English\n */\n\nimport type { GoalAgentStep } from \"../../../harness/goal-agent\";\n\nexport function buildFallbackMessages(\n snapshot: string,\n step: GoalAgentStep,\n failureHistory: string[],\n url: string,\n contextMarkdown: string,\n): { system: string; userPrompt: string } {\n const system = [\n \"You are a problem-solving agent for browser automation.\",\n \"Normal selector resolution has failed at all phases. Analyze the entire page and find an alternative operation path.\",\n \"\",\n \"## Alternative Path Search Guidelines\",\n \"1. Check if the target element is hidden inside a hamburger menu, dropdown, or accordion\",\n \"2. Check if a modal or overlay is covering the target element\",\n \"3. Check if the page is in an unexpected state (not logged in, error state, loading)\",\n \"4. Check if the target element is above the current scroll position\",\n \"5. Check if a semantically equivalent alternative element exists (e.g., a button instead of a link)\",\n \"\",\n \"## Alternative Strategy Selection Criteria\",\n \"- direct_ref: Try a different ref directly (when a semantically equivalent element is found)\",\n \"- scroll_up_and_retry: When the target element might be above the current view\",\n \"- expand_collapsed: When a collapsed section/menu needs to be expanded (prerequisiteRef required)\",\n \"- dismiss_overlay: When a modal/overlay needs to be closed (prerequisiteRef required)\",\n \"- tab_navigation: When the element can be reached via Tab key focus navigation\",\n \"- not_found: When the target element truly does not exist on the page\",\n ].join(\"\\n\");\n\n const parts = [\n \"## Step Being Attempted\",\n `Description: ${step.description}`,\n `Action: ${step.action.type}`,\n `Selector hints: ${JSON.stringify(step.action.selector, null, 2)}`,\n `URL: ${url}`,\n \"\",\n \"## Failure History\",\n ...failureHistory.map((f, i) => ` ${i + 1}. ${f}`),\n \"\",\n \"## Current Page Snapshot (Filtered)\",\n snapshot,\n ];\n\n if (contextMarkdown) {\n parts.push(\"\", \"## Supplementary Context\", contextMarkdown);\n }\n\n return { system, userPrompt: parts.join(\"\\n\") };\n}\n","/**\n * Goal agent (fallback) prompt — Japanese (current production)\n */\n\nimport type { GoalAgentStep } from \"../../../harness/goal-agent\";\n\nexport function buildFallbackMessages(\n snapshot: string,\n step: GoalAgentStep,\n failureHistory: string[],\n url: string,\n contextMarkdown: string,\n): { system: string; userPrompt: string } {\n const system = [\n \"あなたはブラウザ自動操作の問題解決エージェントです。\",\n \"通常のセレクタ解決が全フェーズ失敗しました。ページ全体を分析して代替操作パスを見つけてください。\",\n \"\",\n \"## 代替パス探索の指針\",\n \"1. ハンバーガーメニュー、ドロップダウン、アコーディオンの中に対象要素が隠れていないか確認\",\n \"2. モーダルやオーバーレイが前面にあって対象要素を隠していないか確認\",\n \"3. ページが想定と異なる状態(未ログイン、エラー状態、ローディング中)でないか確認\",\n \"4. 対象要素が上方にあってスクロールで隠れていないか確認\",\n \"5. 意味的に同等な別の要素(リンクではなくボタン、等)が存在しないか確認\",\n \"\",\n \"## 代替戦略の選択基準\",\n \"- direct_ref: 別の ref を直接試す(意味的に同等な要素が見つかった場合)\",\n \"- scroll_up_and_retry: 対象要素が上方にある可能性がある場合\",\n \"- expand_collapsed: 折り畳まれたセクション/メニューを展開する必要がある場合(prerequisiteRef 必須)\",\n \"- dismiss_overlay: モーダル/オーバーレイを閉じる必要がある場合(prerequisiteRef 必須)\",\n \"- tab_navigation: Tab キーでフォーカス移動して到達できる場合\",\n \"- not_found: 本当にページ上に対象要素が存在しない場合\",\n ].join(\"\\n\");\n\n const parts = [\n \"## 達成しようとしていたステップ\",\n `説明: ${step.description}`,\n `アクション: ${step.action.type}`,\n `セレクタヒント: ${JSON.stringify(step.action.selector, null, 2)}`,\n `URL: ${url}`,\n \"\",\n \"## これまでの失敗履歴\",\n ...failureHistory.map((f, i) => ` ${i + 1}. ${f}`),\n \"\",\n \"## 現在のページスナップショット(フィルタ済み)\",\n snapshot,\n ];\n\n if (contextMarkdown) {\n parts.push(\"\", \"## 補足コンテキスト\", contextMarkdown);\n }\n\n return { system, userPrompt: parts.join(\"\\n\") };\n}\n","/**\n * Vision resolver prompt — English\n */\n\nimport type { Selector } from \"../../../runbook-executor/types\";\nimport type { Annotation } from \"../../../browser/engine\";\n\nexport function buildVisionMessages(\n annotations: Annotation[],\n selector: Selector,\n stepDescription: string,\n url: string,\n failureHistory: string[],\n): { system: string; userTextContent: string } {\n const system = [\n \"You are a visual selector resolver for browser automation.\",\n \"The text-based accessibility tree could not find the element.\",\n \"Analyze the screenshot visually to identify the target element.\",\n \"\",\n \"## How to Read the Screenshot\",\n \"- Each interactive element has a red border and number label\",\n \"- Number labels are displayed at the top-left of each element\",\n \"- Each number corresponds to the number field in the annotation list below\",\n \"\",\n \"## Matching Guidelines\",\n \"1. Infer the type of target element (button, input field, link, etc.) from the step description\",\n \"2. Find the element in the screenshot that visually best matches\",\n \"3. Use element text, position, and appearance as clues\",\n \"4. Also reference the role and name from the annotation list\",\n \"5. Target elements not in the A11y tree (canvas, Shadow DOM, iframe, etc.) are also in scope\",\n \"6. Return empty string if confidence is low (below 0.5)\",\n ].join(\"\\n\");\n\n const annotationList = annotations\n .map((a) => {\n const nameStr = a.name ? ` \"${a.name}\"` : \"\";\n return ` #${a.number} ref=${a.ref} ${a.role}${nameStr} @(${a.box.x},${a.box.y})`;\n })\n .join(\"\\n\");\n\n const selectorHints = pruneSelectorHints(selector);\n\n const parts: string[] = [\n \"## Step Description (Most Important)\",\n stepDescription,\n \"\",\n \"## Selector Hints (Reference)\",\n JSON.stringify(selectorHints),\n \"\",\n \"## Current URL\",\n url,\n \"\",\n \"## Annotation List (Corresponds to Numbers on Screenshot)\",\n annotationList,\n ];\n\n if (failureHistory.length > 0) {\n const recent = failureHistory.slice(-3);\n parts.push(\n \"\",\n \"## Text-based Resolution Failure History (Recent 3)\",\n ...recent.map((f, i) => ` ${i + 1}. ${f}`),\n );\n }\n\n return { system, userTextContent: parts.join(\"\\n\") };\n}\n\nfunction pruneSelectorHints(selector: Selector): Record<string, unknown> {\n const pruned: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(selector)) {\n if (value === null || value === undefined || value === \"\" || value === \"unknown\" || value === \":\") continue;\n pruned[key] = value;\n }\n return pruned;\n}\n","/**\n * Vision resolver prompt — Japanese (current production)\n */\n\nimport type { Selector } from \"../../../runbook-executor/types\";\nimport type { Annotation } from \"../../../browser/engine\";\n\nexport function buildVisionMessages(\n annotations: Annotation[],\n selector: Selector,\n stepDescription: string,\n url: string,\n failureHistory: string[],\n): { system: string; userTextContent: string } {\n const system = [\n \"あなたはブラウザ自動操作のビジュアルセレクタリゾルバーです。\",\n \"テキストベースのアクセシビリティツリーでは要素が見つかりませんでした。\",\n \"スクリーンショットを視覚的に分析して、操作対象の要素を特定してください。\",\n \"\",\n \"## スクリーンショットの見方\",\n \"- 各インタラクティブ要素に赤い枠線と番号ラベルが表示されています\",\n \"- 番号ラベルは各要素の左上に表示されます\",\n \"- 各番号は下記のアノテーション一覧の number フィールドに対応します\",\n \"\",\n \"## マッチングの指針\",\n \"1. ステップの説明から操作対象の要素の種類(ボタン、入力フィールド、リンク等)を推定\",\n \"2. スクリーンショット内で視覚的に最も一致する要素を探す\",\n \"3. 要素のテキスト、位置、外観を手がかりにする\",\n \"4. アノテーション一覧の role と name も参考にする\",\n \"5. A11y ツリーに表れない要素(canvas、Shadow DOM、iframe 内等)も対象\",\n \"6. 確信度が低い場合(0.5未満)は空文字を返す\",\n ].join(\"\\n\");\n\n const annotationList = annotations\n .map((a) => {\n const nameStr = a.name ? ` \"${a.name}\"` : \"\";\n return ` #${a.number} ref=${a.ref} ${a.role}${nameStr} @(${a.box.x},${a.box.y})`;\n })\n .join(\"\\n\");\n\n const selectorHints = pruneSelectorHints(selector);\n\n const parts: string[] = [\n \"## ステップの説明(最重要)\",\n stepDescription,\n \"\",\n \"## セレクタのヒント(参考情報)\",\n JSON.stringify(selectorHints),\n \"\",\n \"## 現在のURL\",\n url,\n \"\",\n \"## アノテーション一覧(スクリーンショット上の番号と対応)\",\n annotationList,\n ];\n\n if (failureHistory.length > 0) {\n const recent = failureHistory.slice(-3);\n parts.push(\n \"\",\n \"## テキストベース解決の失敗履歴(直近3件)\",\n ...recent.map((f, i) => ` ${i + 1}. ${f}`),\n );\n }\n\n return { system, userTextContent: parts.join(\"\\n\") };\n}\n\nfunction pruneSelectorHints(selector: Selector): Record<string, unknown> {\n const pruned: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(selector)) {\n if (value === null || value === undefined || value === \"\" || value === \"unknown\" || value === \":\") continue;\n pruned[key] = value;\n }\n return pruned;\n}\n","/**\n * Self-heal analyzer prompt — English\n */\n\nimport type { ParsedRunbook } from \"../../../runbook-executor/types\";\n\nexport function getSuggestionSystemPrompt(): string {\n return [\n \"You are an runbook debugger for browser automation.\",\n \"Analyze the failed steps from the debug execution and generate fix suggestions for the runbook and context.\",\n \"\",\n \"## Fix Suggestion Guidelines\",\n \"\",\n \"For each failed step, provide suggestions from these two perspectives:\",\n \"\",\n \"### 1. runbookFix (Runbook YAML Fix)\",\n \"- Selector changes (when element has moved/been renamed)\",\n \"- Step addition/removal (when the navigation flow has changed)\",\n \"- Action value updates (text or URL changes)\",\n \"- riskLevel or requiresConfirmation adjustments\",\n `Example: \"Step 3: Change selector ariaLabel from 'Submit' to 'Confirm and Submit'\"`,\n \"\",\n \"### 2. contextFix (Context Markdown Fix)\",\n \"- Document page structure changes (new modals, menu structure changes, etc.)\",\n \"- Add prerequisites (login state, permissions, environment conditions, etc.)\",\n \"- Add selector resolution hints (dynamic ID naming patterns, etc.)\",\n `Example: \"Add to context: 'Settings page has changed from tab UI to accordion UI'\"`,\n \"\",\n \"If context markdown is not provided, return empty string for contextFix.\",\n \"\",\n \"### severity Criteria\",\n \"- error: Selector completely not found, fundamental page structure change\",\n \"- warning: Succeeded with retry but unstable, element position or label slightly changed\",\n \"\",\n \"### Template Variable Protection\",\n \"- If step values contain {{varName}} template variables, preserve them as-is in fix suggestions\",\n \"- Template variables are dynamic references resolved at runtime. Do not suggest replacing them with literal values\",\n \"\",\n \"### failureCategory and suggestedStrategy\",\n \"If a failure category is provided, describe a specific fix strategy in suggestedStrategy:\",\n \"- element_not_found: Update selector ariaLabel/role/text to match current page structure\",\n \"- element_stale: Delete selector cache and re-execute\",\n \"- page_structure_changed: Document page structure changes in context.md and update all selectors\",\n \"- navigation_timeout: Add wait step or increase step-delay\",\n \"- action_failed: Consider changing action type (e.g., click → hover)\",\n \"- unknown: Analyze error details and propose specific remediation\",\n ].join(\"\\n\");\n}\n\nexport function buildSuggestionUserPrompt(\n failedInfo: string[],\n stepsInfo: string[],\n runbook: ParsedRunbook,\n contextMarkdown: string,\n): string {\n const parts: string[] = [\n \"## Instruction Information\",\n `Title: ${runbook.title}`,\n `Goal: ${runbook.metadata.goal}`,\n `Start URL: ${runbook.metadata.startUrl}`,\n \"\",\n \"## Instruction Steps\",\n stepsInfo.join(\"\\n\\n\"),\n \"\",\n \"## Failed Step Details\",\n failedInfo.join(\"\\n\\n\"),\n ];\n\n if (contextMarkdown) {\n parts.push(\n \"\",\n \"## Current Context (markdown)\",\n contextMarkdown,\n );\n } else {\n parts.push(\n \"\",\n \"## Context\",\n \"Context markdown is not provided. Return empty string for contextFix.\",\n );\n }\n\n return parts.join(\"\\n\");\n}\n","/**\n * Self-heal analyzer prompt — Japanese (current production)\n */\n\nimport type { ParsedRunbook } from \"../../../runbook-executor/types\";\n\nexport function getSuggestionSystemPrompt(): string {\n return [\n \"あなたはブラウザ自動操作の手順書デバッガーです。\",\n \"デバッグ実行で失敗したステップを分析し、手順書とコンテキストの修正提案を生成してください。\",\n \"\",\n \"## 修正提案の指針\",\n \"\",\n \"各失敗ステップについて、以下の2つの観点で修正提案を出してください:\",\n \"\",\n \"### 1. runbookFix(手順書 YAML の修正)\",\n \"- セレクタの変更(要素が移動/リネームされた場合)\",\n \"- ステップの追加/削除(導線が変わった場合)\",\n \"- アクション値の更新(テキストやURLの変更)\",\n \"- riskLevel や requiresConfirmation の調整\",\n '例: 「Step 3: selector の ariaLabel を \\'送信\\' → \\'確認して送信\\' に変更」',\n \"\",\n \"### 2. contextFix(context markdown の修正)\",\n \"- ページ構造変更の記載(新しいモーダル、メニュー構造の変更など)\",\n \"- 前提条件の追加(ログイン状態、権限、環境条件など)\",\n \"- セレクタ解決のヒント追加(動的IDの命名規則など)\",\n '例: 「context に\\'設定画面がタブUIからアコーディオンUIに変更された\\'旨を追記」',\n \"\",\n \"context markdown が未提供の場合、contextFix は空文字で返してください。\",\n \"\",\n \"### severity の判定基準\",\n \"- error: セレクタが完全に見つからない、ページ構造が根本的に変わっている\",\n \"- warning: リトライで成功したが不安定、要素の位置やラベルが微妙に変わっている\",\n \"\",\n \"### テンプレート変数の保護\",\n \"- ステップの値に {{varName}} 形式のテンプレート変数が含まれている場合、修正提案でもそのまま維持してください\",\n \"- テンプレート変数は実行時に動的に展開される変数参照です。リテラル値への置換を提案しないでください\",\n \"\",\n \"### failureCategory と suggestedStrategy\",\n \"エラー分類カテゴリが提供されている場合、それに基づいて具体的な修正戦略を suggestedStrategy に記載してください:\",\n \"- element_not_found: セレクタの ariaLabel/role/text を現在のページ構造に合わせて更新\",\n \"- element_stale: セレクタキャッシュの削除と再実行\",\n \"- page_structure_changed: context.md にページ構造変更を記録し、セレクタを全面更新\",\n \"- navigation_timeout: wait ステップの追加または step-delay の増加\",\n \"- action_failed: アクション種別の変更(例: click → hover)を検討\",\n \"- unknown: エラー内容を詳細に分析し、具体的な対処を提案\",\n ].join(\"\\n\");\n}\n\nexport function buildSuggestionUserPrompt(\n failedInfo: string[],\n stepsInfo: string[],\n runbook: ParsedRunbook,\n contextMarkdown: string,\n): string {\n const parts: string[] = [\n \"## 手順書情報\",\n `タイトル: ${runbook.title}`,\n `目的: ${runbook.metadata.goal}`,\n `開始URL: ${runbook.metadata.startUrl}`,\n \"\",\n \"## 手順書のステップ一覧\",\n stepsInfo.join(\"\\n\\n\"),\n \"\",\n \"## 失敗ステップの詳細\",\n failedInfo.join(\"\\n\\n\"),\n ];\n\n if (contextMarkdown) {\n parts.push(\n \"\",\n \"## 現在のコンテキスト(markdown)\",\n contextMarkdown,\n );\n } else {\n parts.push(\n \"\",\n \"## コンテキスト\",\n \"context markdown は未提供です。contextFix は空文字で返してください。\",\n );\n }\n\n return parts.join(\"\\n\");\n}\n","/**\n * i18n/prompts --- ロケール切替ディスパッチャー\n *\n * AI プロンプト(複雑な複数行テンプレート)をロケールごとに切り替える。\n * 各プロンプトモジュールは関数を export し、ディスパッチャーが getLocale() に\n * 基づいて適切なロケールの関数を呼び出す。\n */\n\nimport { getLocale } from \"../index\";\n\nimport { getAgentInstructions as getAgentInstructionsEn, getInitialUserMessage as getInitialUserMessageEn } from \"./en/exploration\";\nimport { getAgentInstructions as getAgentInstructionsJa, getInitialUserMessage as getInitialUserMessageJa } from \"./ja/exploration\";\n\nimport { getReviewSystemPrompt as getReviewSystemPromptEn, createReviewUserPrompt as createReviewUserPromptEn } from \"./en/review\";\nimport { getReviewSystemPrompt as getReviewSystemPromptJa, createReviewUserPrompt as createReviewUserPromptJa } from \"./ja/review\";\n\nimport { buildSelectorMessages as buildSelectorMessagesEn } from \"./en/selector\";\nimport { buildSelectorMessages as buildSelectorMessagesJa } from \"./ja/selector\";\n\nimport { buildFallbackMessages as buildFallbackMessagesEn } from \"./en/goal-agent\";\nimport { buildFallbackMessages as buildFallbackMessagesJa } from \"./ja/goal-agent\";\n\nimport { buildVisionMessages as buildVisionMessagesEn } from \"./en/vision\";\nimport { buildVisionMessages as buildVisionMessagesJa } from \"./ja/vision\";\n\nimport { getSuggestionSystemPrompt as getSuggestionSystemPromptEn, buildSuggestionUserPrompt as buildSuggestionUserPromptEn } from \"./en/self-heal\";\nimport { getSuggestionSystemPrompt as getSuggestionSystemPromptJa, buildSuggestionUserPrompt as buildSuggestionUserPromptJa } from \"./ja/self-heal\";\n\nimport type { SecretsData } from \"../../cli/secrets-loader\";\nimport type { RecordedStep, InterventionRecord } from \"../../runbook-generator/types\";\nimport type { Selector } from \"../../runbook-executor/types\";\nimport type { RetryContext } from \"../../harness/selector-resolver\";\nimport type { GoalAgentStep } from \"../../harness/goal-agent\";\nimport type { Annotation } from \"../../browser/engine\";\nimport type { ParsedRunbook } from \"../../runbook-executor/types\";\n\n// ── Exploration ──\n\nexport function getAgentInstructions(\n goal: string,\n contextMarkdown: string,\n secrets?: SecretsData,\n locale?: \"en\" | \"ja\",\n): string {\n const effectiveLocale = locale ?? getLocale();\n return effectiveLocale === \"ja\"\n ? getAgentInstructionsJa(goal, contextMarkdown, secrets)\n : getAgentInstructionsEn(goal, contextMarkdown, secrets);\n}\n\nexport function getInitialUserMessage(locale?: \"en\" | \"ja\"): string {\n const effectiveLocale = locale ?? getLocale();\n return effectiveLocale === \"ja\"\n ? getInitialUserMessageJa()\n : getInitialUserMessageEn();\n}\n\n// ── Review ──\n\nexport function getReviewSystemPrompt(locale?: \"en\" | \"ja\"): string {\n const effectiveLocale = locale ?? getLocale();\n return effectiveLocale === \"ja\"\n ? getReviewSystemPromptJa()\n : getReviewSystemPromptEn();\n}\n\nexport function createReviewUserPrompt(\n goal: string,\n recordedSteps: RecordedStep[],\n goalAchieved: boolean,\n interventions?: InterventionRecord[],\n locale?: \"en\" | \"ja\",\n): string {\n const effectiveLocale = locale ?? getLocale();\n return effectiveLocale === \"ja\"\n ? createReviewUserPromptJa(goal, recordedSteps, goalAchieved, interventions)\n : createReviewUserPromptEn(goal, recordedSteps, goalAchieved, interventions);\n}\n\n// ── Selector ──\n\nexport function buildSelectorMessages(\n snapshot: string,\n selector: Selector,\n stepDescription: string,\n url: string,\n contextMarkdown: string,\n retryContext?: RetryContext,\n workingMemorySummary?: string,\n): { system: string; userPrompt: string } {\n return getLocale() === \"ja\"\n ? buildSelectorMessagesJa(snapshot, selector, stepDescription, url, contextMarkdown, retryContext, workingMemorySummary)\n : buildSelectorMessagesEn(snapshot, selector, stepDescription, url, contextMarkdown, retryContext, workingMemorySummary);\n}\n\n// ── Goal Agent ──\n\nexport function buildFallbackMessages(\n snapshot: string,\n step: GoalAgentStep,\n failureHistory: string[],\n url: string,\n contextMarkdown: string,\n): { system: string; userPrompt: string } {\n return getLocale() === \"ja\"\n ? buildFallbackMessagesJa(snapshot, step, failureHistory, url, contextMarkdown)\n : buildFallbackMessagesEn(snapshot, step, failureHistory, url, contextMarkdown);\n}\n\n// ── Vision ──\n\nexport function buildVisionMessages(\n annotations: Annotation[],\n selector: Selector,\n stepDescription: string,\n url: string,\n failureHistory: string[],\n): { system: string; userTextContent: string } {\n return getLocale() === \"ja\"\n ? buildVisionMessagesJa(annotations, selector, stepDescription, url, failureHistory)\n : buildVisionMessagesEn(annotations, selector, stepDescription, url, failureHistory);\n}\n\n// ── Self-Heal ──\n\nexport function getSuggestionSystemPrompt(): string {\n return getLocale() === \"ja\"\n ? getSuggestionSystemPromptJa()\n : getSuggestionSystemPromptEn();\n}\n\nexport function buildSuggestionUserPrompt(\n failedInfo: string[],\n stepsInfo: string[],\n runbook: ParsedRunbook,\n contextMarkdown: string,\n): string {\n return getLocale() === \"ja\"\n ? buildSuggestionUserPromptJa(failedInfo, stepsInfo, runbook, contextMarkdown)\n : buildSuggestionUserPromptEn(failedInfo, stepsInfo, runbook, contextMarkdown);\n}\n"],"mappings":"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","names":["writeFile","path","writeFile","readFile","path","readFile","mkdir","readFile","join","execSync","path","os","existsSync","mkdirSync","readFileSync","statSync","writeFile","mkdir","page","fn","locator","el","os","join","page","locator","path","browser","stat","statSync","mkdirSync","os","profilePath","fs","existsSync","readFileSync","resolve","mkdir","writeFile","fs","path","mkdirSync","os","readFileSync","statSync","confirmCategories","command","randomBytes","command","existsSync","mkdirSync","readFileSync","writeFileSync","readdirSync","unlinkSync","path","os","path","os","existsSync","mkdirSync","p","readFileSync","writeFileSync","command","writeFile","mkdir","path","resolve","os","command","browser","locator","el","page","mkdirSync","element","path","page","script","command","path","join","readFile","page","mkdir","resolve","p","fn","locator","script","execSync","elements","item","resolve","COMMAND_SCHEMA","getAgentInstructions","getInitialUserMessage","getReviewSystemPrompt","createReviewUserPrompt","buildSelectorMessages","pruneSelectorHints","buildFallbackMessages","pruneSelectorHints","buildVisionMessages","pruneSelectorHints","getSuggestionSystemPrompt","buildSuggestionUserPrompt","getAgentInstructions","getInitialUserMessage","getReviewSystemPrompt","createReviewUserPrompt","buildSelectorMessages","buildFallbackMessages","buildVisionMessages","getSuggestionSystemPrompt","buildSuggestionUserPrompt"]}
|