lobster-cli 0.1.0

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.
Files changed (45) hide show
  1. package/README.md +389 -0
  2. package/dist/agent/core.js +1013 -0
  3. package/dist/agent/core.js.map +1 -0
  4. package/dist/agent/index.js +1027 -0
  5. package/dist/agent/index.js.map +1 -0
  6. package/dist/brain/index.js +60 -0
  7. package/dist/brain/index.js.map +1 -0
  8. package/dist/browser/dom/index.js +1096 -0
  9. package/dist/browser/dom/index.js.map +1 -0
  10. package/dist/browser/index.js +2034 -0
  11. package/dist/browser/index.js.map +1 -0
  12. package/dist/browser/manager.js +86 -0
  13. package/dist/browser/manager.js.map +1 -0
  14. package/dist/browser/page-adapter.js +1345 -0
  15. package/dist/browser/page-adapter.js.map +1 -0
  16. package/dist/cascade/index.js +138 -0
  17. package/dist/cascade/index.js.map +1 -0
  18. package/dist/config/index.js +110 -0
  19. package/dist/config/index.js.map +1 -0
  20. package/dist/config/schema.js +66 -0
  21. package/dist/config/schema.js.map +1 -0
  22. package/dist/discover/index.js +545 -0
  23. package/dist/discover/index.js.map +1 -0
  24. package/dist/index.js +5529 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/lib.js +4206 -0
  27. package/dist/lib.js.map +1 -0
  28. package/dist/llm/client.js +379 -0
  29. package/dist/llm/client.js.map +1 -0
  30. package/dist/llm/index.js +397 -0
  31. package/dist/llm/index.js.map +1 -0
  32. package/dist/llm/openai-client.js +214 -0
  33. package/dist/llm/openai-client.js.map +1 -0
  34. package/dist/output/index.js +93 -0
  35. package/dist/output/index.js.map +1 -0
  36. package/dist/pipeline/index.js +802 -0
  37. package/dist/pipeline/index.js.map +1 -0
  38. package/dist/router/decision.js +80 -0
  39. package/dist/router/decision.js.map +1 -0
  40. package/dist/router/index.js +3443 -0
  41. package/dist/router/index.js.map +1 -0
  42. package/dist/types/index.js +23 -0
  43. package/dist/types/index.js.map +1 -0
  44. package/logo.svg +11 -0
  45. package/package.json +65 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/types/router.ts","../../src/adapter/registry.ts","../../src/router/decision.ts","../../src/http/index.ts","../../src/browser/manager.ts","../../src/utils/logger.ts","../../src/browser/dom/flat-tree.ts","../../src/browser/dom/snapshot.ts","../../src/browser/dom/semantic-tree.ts","../../src/browser/dom/markdown.ts","../../src/browser/dom/form-state.ts","../../src/browser/interceptor.ts","../../src/browser/page-adapter.ts","../../src/agent/core.ts","../../src/llm/errors.ts","../../src/llm/openai-client.ts","../../src/llm/utils.ts","../../src/llm/client.ts","../../src/agent/tools/click.ts","../../src/agent/tools/type.ts","../../src/agent/tools/scroll.ts","../../src/agent/tools/select.ts","../../src/agent/tools/wait.ts","../../src/agent/tools/done.ts","../../src/agent/tools/ask-user.ts","../../src/agent/tools/execute-js.ts","../../src/agent/tools/index.ts","../../src/agent/macro-tool.ts","../../src/agent/auto-fixer.ts","../../src/pipeline/template.ts","../../src/pipeline/registry.ts","../../src/pipeline/steps/fetch.ts","../../src/pipeline/steps/browser.ts","../../src/pipeline/steps/transform.ts","../../src/pipeline/steps/intercept.ts","../../src/pipeline/steps/download.ts","../../src/pipeline/steps/tap.ts","../../src/pipeline/executor.ts","../../src/utils/timeout.ts","../../src/router/index.ts"],"sourcesContent":["import type { Adapter } from './adapter.js';\n\nexport enum ExecutionLevel {\n HTTP = 0,\n BROWSER = 1,\n ADAPTER = 2,\n AGENT = 3,\n}\n\nexport type OutputFormat = 'table' | 'json' | 'yaml' | 'markdown' | 'csv';\n\nexport interface RoutingDecision {\n level: ExecutionLevel;\n reason: string;\n adapter?: Adapter;\n}\n\nexport interface ExecutionRequest {\n task: string;\n url?: string;\n site?: string;\n command?: string;\n args?: Record<string, unknown>;\n format?: OutputFormat;\n}\n","import type { Adapter } from '../types/adapter.js';\nimport { Strategy } from '../types/adapter.js';\n\n// Global registry — shared across module instances (critical for plugins)\nconst REGISTRY_KEY = '__lobster_registry__';\nif (!(globalThis as any)[REGISTRY_KEY]) {\n (globalThis as any)[REGISTRY_KEY] = new Map<string, Adapter>();\n}\n\nfunction getRegistry(): Map<string, Adapter> {\n return (globalThis as any)[REGISTRY_KEY];\n}\n\nexport function cli(def: Partial<Adapter> & { site: string; name: string }): Adapter {\n const adapter: Adapter = {\n site: def.site,\n name: def.name,\n description: def.description || `${def.site} ${def.name}`,\n domain: def.domain,\n strategy: def.strategy || Strategy.PUBLIC,\n browser: def.browser ?? (def.strategy !== Strategy.PUBLIC),\n args: def.args || [],\n columns: def.columns,\n func: def.func,\n pipeline: def.pipeline,\n timeoutSeconds: def.timeoutSeconds,\n navigateBefore: def.navigateBefore,\n };\n\n const fullName = `${adapter.site}/${adapter.name}`;\n getRegistry().set(fullName, adapter);\n return adapter;\n}\n\nexport function getAdapter(site: string, name: string): Adapter | undefined {\n return getRegistry().get(`${site}/${name}`);\n}\n\nexport function getAdapterBySite(site: string): Adapter[] {\n const adapters: Adapter[] = [];\n for (const [key, adapter] of getRegistry()) {\n if (key.startsWith(`${site}/`)) adapters.push(adapter);\n }\n return adapters;\n}\n\nexport function getAdapterByDomain(domain: string): Adapter[] {\n const adapters: Adapter[] = [];\n for (const adapter of getRegistry().values()) {\n if (adapter.domain && domain.includes(adapter.domain)) adapters.push(adapter);\n }\n return adapters;\n}\n\nexport function getAllAdapters(): Adapter[] {\n return [...getRegistry().values()];\n}\n\nexport function getAllSites(): string[] {\n const sites = new Set<string>();\n for (const adapter of getRegistry().values()) {\n sites.add(adapter.site);\n }\n return [...sites].sort();\n}\n\nexport { Strategy };\n","import { ExecutionLevel } from '../types/router.js';\nimport type { RoutingDecision, ExecutionRequest } from '../types/router.js';\nimport { getAdapter, getAdapterByDomain } from '../adapter/registry.js';\n\nexport function makeRoutingDecision(request: ExecutionRequest): RoutingDecision {\n // 1. Explicit adapter match\n if (request.site && request.command) {\n const adapter = getAdapter(request.site, request.command);\n if (adapter) {\n return {\n level: ExecutionLevel.ADAPTER,\n reason: `Matched adapter: ${request.site}/${request.command}`,\n adapter,\n };\n }\n }\n\n // 2. URL-based adapter match\n if (request.url) {\n try {\n const domain = new URL(request.url).hostname;\n const adapters = getAdapterByDomain(domain);\n if (adapters.length > 0) {\n return {\n level: ExecutionLevel.ADAPTER,\n reason: `Found adapter for domain: ${domain}`,\n adapter: adapters[0],\n };\n }\n } catch {}\n }\n\n // 3. Simple HTTP check — URL-only request with no interaction task\n if (request.url && !request.task) {\n return {\n level: ExecutionLevel.HTTP,\n reason: 'Direct URL fetch (no task specified)',\n };\n }\n\n // 4. Simple fetch detection — URL looks like an API\n if (request.url) {\n const url = request.url;\n if (url.endsWith('.json') || url.includes('/api/') || url.includes('/v1/') || url.includes('/v2/')) {\n return {\n level: ExecutionLevel.HTTP,\n reason: 'URL appears to be an API endpoint',\n };\n }\n }\n\n // 5. Task requires interaction — use agent\n if (request.task) {\n const taskLower = request.task.toLowerCase();\n const interactionWords = ['click', 'scroll', 'fill', 'type', 'login', 'sign in', 'search', 'navigate', 'find', 'extract', 'get'];\n const needsInteraction = interactionWords.some((w) => taskLower.includes(w));\n\n if (needsInteraction || request.url) {\n return {\n level: ExecutionLevel.AGENT,\n reason: 'Task requires web interaction',\n };\n }\n }\n\n // Default: agent for anything unrecognized\n return {\n level: ExecutionLevel.AGENT,\n reason: 'Defaulting to AI agent for unrecognized task',\n };\n}\n","export interface HttpResult {\n url: string;\n status: number;\n headers: Record<string, string>;\n body: unknown;\n contentType: string;\n}\n\nexport async function directFetch(url: string, options?: {\n method?: string;\n headers?: Record<string, string>;\n timeout?: number;\n}): Promise<HttpResult> {\n const controller = new AbortController();\n const timeout = options?.timeout || 30000;\n const timer = setTimeout(() => controller.abort(), timeout);\n\n try {\n const resp = await fetch(url, {\n method: options?.method || 'GET',\n headers: options?.headers,\n signal: controller.signal,\n redirect: 'follow',\n });\n\n const contentType = resp.headers.get('content-type') || '';\n const headers: Record<string, string> = {};\n resp.headers.forEach((v, k) => { headers[k] = v; });\n\n let body: unknown;\n if (contentType.includes('json')) {\n body = await resp.json();\n } else {\n body = await resp.text();\n }\n\n return { url, status: resp.status, headers, body, contentType };\n } finally {\n clearTimeout(timer);\n }\n}\n\nexport async function batchFetch(urls: string[], concurrency = 5): Promise<HttpResult[]> {\n const results: HttpResult[] = [];\n\n for (let i = 0; i < urls.length; i += concurrency) {\n const batch = urls.slice(i, i + concurrency);\n const batchResults = await Promise.all(\n batch.map((url) => directFetch(url).catch((err) => ({\n url, status: 0, headers: {}, body: `Error: ${err}`, contentType: 'text/plain'\n } as HttpResult)))\n );\n results.push(...batchResults);\n }\n\n return results;\n}\n","import puppeteer, { type Browser, type Page } from 'puppeteer-core';\nimport { existsSync } from 'node:fs';\nimport { log } from '../utils/logger.js';\n\nexport interface BrowserManagerConfig {\n executablePath?: string;\n headless?: boolean;\n cdpEndpoint?: string;\n connectTimeout?: number;\n}\n\nexport class BrowserManager {\n private browser: Browser | null = null;\n private config: BrowserManagerConfig;\n\n constructor(config: BrowserManagerConfig = {}) {\n this.config = config;\n }\n\n async connect(): Promise<Browser> {\n if (this.browser?.connected) return this.browser;\n\n if (this.config.cdpEndpoint) {\n log.debug(`Connecting to CDP endpoint: ${this.config.cdpEndpoint}`);\n this.browser = await puppeteer.connect({\n browserWSEndpoint: this.config.cdpEndpoint,\n });\n return this.browser;\n }\n\n const executablePath = this.config.executablePath || findChrome();\n if (!executablePath) {\n throw new Error(\n 'Chrome/Chromium not found. Set LOBSTER_BROWSER_PATH or config browser.executablePath'\n );\n }\n\n log.debug(`Launching Chrome: ${executablePath}`);\n this.browser = await puppeteer.launch({\n executablePath,\n headless: this.config.headless ?? true,\n args: [\n '--no-sandbox',\n '--disable-setuid-sandbox',\n '--disable-dev-shm-usage',\n '--disable-gpu',\n ],\n });\n\n return this.browser;\n }\n\n async newPage(): Promise<Page> {\n const browser = await this.connect();\n return browser.newPage();\n }\n\n async close(): Promise<void> {\n if (this.browser) {\n await this.browser.close().catch(() => {});\n this.browser = null;\n }\n }\n}\n\nfunction findChrome(): string | undefined {\n const paths =\n process.platform === 'darwin'\n ? [\n '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',\n '/Applications/Chromium.app/Contents/MacOS/Chromium',\n '/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary',\n ]\n : process.platform === 'win32'\n ? [\n 'C:\\\\Program Files\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe',\n 'C:\\\\Program Files (x86)\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe',\n ]\n : [\n '/usr/bin/google-chrome',\n '/usr/bin/google-chrome-stable',\n '/usr/bin/chromium-browser',\n '/usr/bin/chromium',\n '/snap/bin/chromium',\n ];\n\n return paths.find((p) => existsSync(p));\n}\n","import chalk from 'chalk';\n\nexport const log = {\n info: (msg: string) => console.log(chalk.blue('ℹ'), msg),\n success: (msg: string) => console.log(chalk.green('✓'), msg),\n warn: (msg: string) => console.log(chalk.yellow('⚠'), msg),\n error: (msg: string) => console.error(chalk.red('✗'), msg),\n debug: (msg: string) => {\n if (process.env.LOBSTER_DEBUG) console.log(chalk.gray('⋯'), msg);\n },\n step: (n: number, msg: string) => console.log(chalk.cyan(`[${n}]`), msg),\n dim: (msg: string) => console.log(chalk.dim(msg)),\n};\n","/**\n * Script that runs inside the browser to extract a flat DOM tree\n * with indexed interactive elements — the format the AI agent uses.\n *\n * Based on Page Agent's DOM extraction approach.\n */\nexport const FLAT_TREE_SCRIPT = `\n(() => {\n const INTERACTIVE_TAGS = new Set([\n 'a', 'button', 'input', 'select', 'textarea', 'details', 'summary',\n 'label', 'option', 'fieldset', 'legend',\n ]);\n\n const INTERACTIVE_ROLES = new Set([\n 'button', 'link', 'textbox', 'checkbox', 'radio', 'combobox',\n 'listbox', 'menu', 'menuitem', 'tab', 'switch', 'slider',\n 'searchbox', 'spinbutton', 'option', 'menuitemcheckbox', 'menuitemradio',\n ]);\n\n const ATTR_WHITELIST = [\n 'type', 'role', 'aria-label', 'aria-expanded', 'aria-selected',\n 'aria-checked', 'aria-disabled', 'placeholder', 'title', 'href',\n 'value', 'name', 'alt', 'src',\n ];\n\n let highlightIndex = 0;\n const nodes = {};\n const selectorMap = {};\n\n function isVisible(el) {\n if (el.offsetWidth === 0 && el.offsetHeight === 0) return false;\n const style = getComputedStyle(el);\n if (style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0') return false;\n return true;\n }\n\n function isInteractive(el) {\n const tag = el.tagName.toLowerCase();\n if (INTERACTIVE_TAGS.has(tag)) return true;\n const role = el.getAttribute('role');\n if (role && INTERACTIVE_ROLES.has(role)) return true;\n if (el.getAttribute('contenteditable') === 'true') return true;\n if (el.getAttribute('tabindex') !== null && parseInt(el.getAttribute('tabindex')) >= 0) return true;\n if (el.onclick || el.getAttribute('onclick')) return true;\n return false;\n }\n\n function getAttributes(el) {\n const attrs = {};\n for (const attr of ATTR_WHITELIST) {\n const val = el.getAttribute(attr);\n if (val !== null && val !== '') attrs[attr] = val;\n }\n return attrs;\n }\n\n function getScrollable(el) {\n const style = getComputedStyle(el);\n const overflowY = style.overflowY;\n const overflowX = style.overflowX;\n const isScrollableY = (overflowY === 'auto' || overflowY === 'scroll') && el.scrollHeight > el.clientHeight;\n const isScrollableX = (overflowX === 'auto' || overflowX === 'scroll') && el.scrollWidth > el.clientWidth;\n if (!isScrollableY && !isScrollableX) return null;\n return {\n left: el.scrollLeft,\n top: el.scrollTop,\n right: el.scrollWidth - el.clientWidth - el.scrollLeft,\n bottom: el.scrollHeight - el.clientHeight - el.scrollTop,\n };\n }\n\n function walk(el, parentId) {\n if (!el || el.nodeType === 8) return; // skip comments\n\n if (el.nodeType === 3) { // text node\n const text = el.textContent.trim();\n if (!text) return;\n const id = 'text_' + Math.random().toString(36).slice(2, 8);\n nodes[id] = { id, tagName: '#text', text, parentId };\n if (parentId && nodes[parentId]) {\n nodes[parentId].children = nodes[parentId].children || [];\n nodes[parentId].children.push(id);\n }\n return;\n }\n\n if (el.nodeType !== 1) return; // only elements\n\n const tag = el.tagName.toLowerCase();\n if (['script', 'style', 'noscript', 'svg', 'path'].includes(tag)) return;\n if (!isVisible(el)) return;\n\n const id = tag + '_' + Math.random().toString(36).slice(2, 8);\n const interactive = isInteractive(el);\n const node = {\n id,\n tagName: tag,\n attributes: getAttributes(el),\n parentId,\n children: [],\n isInteractive: interactive,\n };\n\n if (interactive) {\n node.highlightIndex = highlightIndex;\n selectorMap[highlightIndex] = id;\n highlightIndex++;\n }\n\n const scrollable = getScrollable(el);\n if (scrollable) node.scrollable = scrollable;\n\n const text = [];\n for (const child of el.childNodes) {\n if (child.nodeType === 3 && child.textContent.trim()) {\n text.push(child.textContent.trim());\n }\n }\n if (text.length > 0) node.text = text.join(' ').slice(0, 200);\n\n nodes[id] = node;\n\n if (parentId && nodes[parentId]) {\n nodes[parentId].children.push(id);\n }\n\n for (const child of el.children) {\n walk(child, id);\n }\n }\n\n const rootId = 'root';\n nodes[rootId] = { id: rootId, tagName: 'body', children: [], attributes: {} };\n for (const child of document.body.children) {\n walk(child, rootId);\n }\n\n return { rootId, map: nodes, selectorMap };\n})()\n`;\n\n/**\n * Convert a FlatDomTree into the indexed text format that the LLM agent reads.\n * Example output:\n * [0]<button type=submit>Search</>\n * [1]<input type=text placeholder=\"Enter query\" />\n */\nexport function flatTreeToString(tree: { rootId: string; map: Record<string, any> }): string {\n const lines: string[] = [];\n\n function walk(nodeId: string, depth: number) {\n const node = tree.map[nodeId];\n if (!node) return;\n\n const indent = '\\t'.repeat(depth);\n\n if (node.tagName === '#text') {\n if (node.text) lines.push(`${indent}${node.text}`);\n return;\n }\n\n const attrs = node.attributes || {};\n const attrStr = Object.entries(attrs)\n .map(([k, v]) => (v === '' ? k : `${k}=\"${v}\"`))\n .join(' ');\n\n const prefix = node.highlightIndex !== undefined ? `[${node.highlightIndex}]` : '';\n const scrollInfo = node.scrollable\n ? ` |scroll: ${Math.round(node.scrollable.top)}px up, ${Math.round(node.scrollable.bottom)}px down|`\n : '';\n\n const text = node.text || '';\n const tag = node.tagName;\n\n if (prefix || text || node.children?.length > 0) {\n const opening = `${indent}${prefix}<${tag}${attrStr ? ' ' + attrStr : ''}${scrollInfo}>`;\n\n if (!node.children?.length || (node.children.length === 0 && text)) {\n lines.push(`${opening}${text}</>`);\n } else {\n lines.push(`${opening}${text}`);\n for (const childId of node.children || []) {\n walk(childId, depth + 1);\n }\n }\n } else {\n for (const childId of node.children || []) {\n walk(childId, depth);\n }\n }\n }\n\n walk(tree.rootId, 0);\n return lines.join('\\n');\n}\n","/**\n * Advanced DOM snapshot script — runs inside the browser.\n * Multi-stage pruning pipeline producing LLM-optimized output.\n *\n * Stages:\n * 1. Walk DOM, collect visibility + layout + interactivity signals\n * 2. Prune invisible, zero-area, non-content elements\n * 3. SVG & decoration collapse\n * 4. Shadow DOM traversal\n * 5. Same-origin iframe extraction\n * 6. Bounding-box parent-child dedup (link/button wrapping)\n * 7. Paint-order occlusion detection (overlay/modal coverage)\n * 8. Attribute whitelist filtering\n * 9. Ad/tracker filtering\n * 10. Scroll position info\n * 11. data-ref annotation for targeting\n * 12. Token-efficient serialization with interactive indices\n */\n/**\n * Build snapshot script with optional previous hashes for diff marking.\n * Elements new since last snapshot get a `*` prefix on their index.\n */\nexport function buildSnapshotScript(previousHashes?: string[]): string {\n return SNAPSHOT_SCRIPT_FN(previousHashes || []);\n}\n\nfunction SNAPSHOT_SCRIPT_FN(prevHashes: string[]): string {\n return `\n(() => {\n let idx = 0;\n const __prevHashes = new Set(${JSON.stringify(prevHashes)});\n const __currentHashes = [];\n`;\n}\n\nexport const SNAPSHOT_SCRIPT = `\n(() => {\n let idx = 0;\n const __prevHashes = (window.__lobster_prev_hashes) ? new Set(window.__lobster_prev_hashes) : null;\n const __currentHashes = [];\n\n const SKIP_TAGS = new Set([\n 'script','style','noscript','svg','path','meta','link','head',\n 'template','slot','colgroup','col',\n ]);\n\n const INTERACTIVE_TAGS = new Set([\n 'a','button','input','select','textarea','details','summary','label',\n ]);\n\n const INTERACTIVE_ROLES = new Set([\n 'button','link','textbox','checkbox','radio','combobox','listbox',\n 'menu','menuitem','tab','switch','slider','searchbox','spinbutton',\n 'option','menuitemcheckbox','menuitemradio','treeitem',\n ]);\n\n const ATTR_WHITELIST = [\n 'type','role','aria-label','aria-expanded','aria-selected','aria-checked',\n 'aria-disabled','aria-haspopup','aria-pressed','placeholder','title',\n 'href','value','name','alt','src','action','method','for',\n 'data-testid','data-id','contenteditable','tabindex',\n ];\n\n const AD_PATTERNS = /ad[-_]?banner|ad[-_]?container|google[-_]?ad|doubleclick|adsbygoogle|sponsored|^ad$/i;\n\n // ── Stage 1: Visibility check ──\n function isVisible(el) {\n if (el.offsetWidth === 0 && el.offsetHeight === 0 && el.tagName !== 'INPUT') return false;\n const s = getComputedStyle(el);\n if (s.display === 'none') return false;\n if (s.visibility === 'hidden' || s.visibility === 'collapse') return false;\n if (s.opacity === '0') return false;\n if (s.clipPath === 'inset(100%)') return false;\n // Check for offscreen positioning\n const rect = el.getBoundingClientRect();\n if (rect.right < 0 || rect.bottom < 0) return false;\n return true;\n }\n\n // ── Stage 2: Interactive detection ──\n function isInteractive(el) {\n const tag = el.tagName.toLowerCase();\n if (INTERACTIVE_TAGS.has(tag)) {\n // Skip disabled elements\n if (el.disabled) return false;\n // Skip hidden inputs\n if (tag === 'input' && el.type === 'hidden') return false;\n return true;\n }\n const role = el.getAttribute('role');\n if (role && INTERACTIVE_ROLES.has(role)) return true;\n if (el.contentEditable === 'true') return true;\n if (el.tabIndex >= 0 && el.getAttribute('tabindex') !== null) return true;\n if (el.onclick) return true;\n return false;\n }\n\n // ── Stage 8: Attribute filtering ──\n function getAttrs(el) {\n const parts = [];\n for (const name of ATTR_WHITELIST) {\n let v = el.getAttribute(name);\n if (v === null || v === '') continue;\n // Truncate long values\n if (v.length > 80) v = v.slice(0, 77) + '...';\n // Skip href=\"javascript:...\"\n if (name === 'href' && v.startsWith('javascript:')) continue;\n parts.push(name + '=' + v);\n }\n return parts.length ? ' ' + parts.join(' ') : '';\n }\n\n // ── Stage 9: Ad filtering ──\n function isAd(el) {\n const id = el.id || '';\n const cls = el.className || '';\n if (typeof cls === 'string' && AD_PATTERNS.test(cls)) return true;\n if (AD_PATTERNS.test(id)) return true;\n if (el.tagName === 'IFRAME' && AD_PATTERNS.test(el.src || '')) return true;\n return false;\n }\n\n // ── Stage 10: Scroll info ──\n function getScrollInfo(el) {\n const s = getComputedStyle(el);\n const overflowY = s.overflowY;\n const overflowX = s.overflowX;\n const scrollableY = (overflowY === 'auto' || overflowY === 'scroll') && el.scrollHeight > el.clientHeight;\n const scrollableX = (overflowX === 'auto' || overflowX === 'scroll') && el.scrollWidth > el.clientWidth;\n if (!scrollableY && !scrollableX) return '';\n\n const parts = [];\n if (scrollableY) {\n const up = Math.round(el.scrollTop);\n const down = Math.round(el.scrollHeight - el.clientHeight - el.scrollTop);\n if (up > 0) parts.push(up + 'px up');\n if (down > 0) parts.push(down + 'px down');\n }\n if (scrollableX) {\n const left = Math.round(el.scrollLeft);\n const right = Math.round(el.scrollWidth - el.clientWidth - el.scrollLeft);\n if (left > 0) parts.push(left + 'px left');\n if (right > 0) parts.push(right + 'px right');\n }\n return parts.length ? ' |scroll: ' + parts.join(', ') + '|' : '';\n }\n\n // ── Stage 6: Bounding-box dedup ──\n // If a parent and child are both interactive and have ~same bounding box,\n // skip the parent (e.g., <a><button>Click</button></a>)\n function isWrappingInteractive(el) {\n if (!isInteractive(el)) return false;\n const rect = el.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) return false;\n for (const child of el.children) {\n if (!isInteractive(child)) continue;\n const cr = child.getBoundingClientRect();\n const overlapX = Math.min(rect.right, cr.right) - Math.max(rect.left, cr.left);\n const overlapY = Math.min(rect.bottom, cr.bottom) - Math.max(rect.top, cr.top);\n const overlapArea = Math.max(0, overlapX) * Math.max(0, overlapY);\n const parentArea = rect.width * rect.height;\n if (parentArea > 0 && overlapArea / parentArea > 0.85) return true;\n }\n return false;\n }\n\n // ── Stage 7: Occlusion detection ──\n function isOccluded(el) {\n const rect = el.getBoundingClientRect();\n if (rect.width === 0 || rect.height === 0) return false;\n const cx = rect.left + rect.width / 2;\n const cy = rect.top + rect.height / 2;\n const topEl = document.elementFromPoint(cx, cy);\n if (!topEl) return false;\n if (topEl === el || el.contains(topEl) || topEl.contains(el)) return false;\n // Check z-index — if top element is a modal/overlay, mark as occluded\n const topZ = parseInt(getComputedStyle(topEl).zIndex) || 0;\n const elZ = parseInt(getComputedStyle(el).zIndex) || 0;\n return topZ > elZ + 10;\n }\n\n // ── Stage 5: Iframe content extraction ──\n function getIframeContent(iframe, depth, maxDepth) {\n try {\n const doc = iframe.contentDocument;\n if (!doc || !doc.body) return '';\n return '\\\\n' + walkNode(doc.body, depth, maxDepth);\n } catch { return ''; }\n }\n\n // ── Stage 4: Shadow DOM traversal ──\n function getShadowContent(el, depth, maxDepth) {\n if (!el.shadowRoot) return '';\n let out = '';\n for (const child of el.shadowRoot.childNodes) {\n out += walkNode(child, depth, maxDepth);\n }\n return out;\n }\n\n // ── Input value hint ──\n function getInputHint(el) {\n const tag = el.tagName.toLowerCase();\n if (tag === 'input') {\n const type = el.type || 'text';\n const val = el.value || '';\n const checked = el.checked;\n if (type === 'checkbox' || type === 'radio') {\n return checked ? ' [checked]' : ' [unchecked]';\n }\n if (val) return ' value=\"' + val.slice(0, 50) + '\"';\n }\n if (tag === 'textarea' && el.value) {\n return ' value=\"' + el.value.slice(0, 50) + '\"';\n }\n if (tag === 'select' && el.selectedOptions?.length) {\n return ' selected=\"' + el.selectedOptions[0].text.slice(0, 40) + '\"';\n }\n return '';\n }\n\n const MAX_DEPTH = 25;\n const MAX_TEXT = 150;\n\n function walkNode(node, depth, maxDepth) {\n if (depth > maxDepth) return '';\n if (!node) return '';\n\n // Text node\n if (node.nodeType === 3) {\n const t = node.textContent.trim();\n if (!t) return '';\n const text = t.length > MAX_TEXT ? t.slice(0, MAX_TEXT) + '...' : t;\n return ' '.repeat(depth) + text + '\\\\n';\n }\n\n // Comment node — skip\n if (node.nodeType === 8) return '';\n\n // Only element nodes from here\n if (node.nodeType !== 1) return '';\n\n const el = node;\n const tag = el.tagName.toLowerCase();\n\n // ── Stage 3: Skip tags ──\n if (SKIP_TAGS.has(tag)) return '';\n\n // ── Stage 2: Visibility ──\n if (!isVisible(el)) return '';\n\n // ── Stage 9: Ad filtering ──\n if (isAd(el)) return '';\n\n // ── Stage 6: Bbox dedup — skip wrapping interactive parent ──\n const skipSelf = isWrappingInteractive(el);\n\n const indent = ' '.repeat(depth);\n const inter = !skipSelf && isInteractive(el);\n let prefix = '';\n if (inter) {\n const thisIdx = idx++;\n // Hash: tag + text + key attributes for diff tracking\n const hashText = tag + ':' + (el.textContent || '').trim().slice(0, 40) + ':' + (el.getAttribute('href') || '') + ':' + (el.getAttribute('aria-label') || '');\n __currentHashes.push(hashText);\n const isNew = __prevHashes && __prevHashes.size > 0 && !__prevHashes.has(hashText);\n prefix = isNew ? '*[' + thisIdx + ']' : '[' + thisIdx + ']';\n }\n\n // ── Stage 11: Annotate with data-ref ──\n if (inter) {\n try { el.dataset.ref = String(idx - 1); } catch {}\n }\n\n // ── Stage 7: Occlusion check for interactive elements ──\n if (inter && isOccluded(el)) {\n // Still include but mark as occluded\n // (agent needs to know element exists but may need to scroll/close modal)\n }\n\n const a = getAttrs(el);\n const scrollInfo = getScrollInfo(el);\n const inputHint = inter ? getInputHint(el) : '';\n\n // Leaf text extraction\n let leafText = '';\n if (el.childNodes.length === 1 && el.childNodes[0].nodeType === 3) {\n const t = el.childNodes[0].textContent.trim();\n if (t) leafText = t.length > MAX_TEXT ? t.slice(0, MAX_TEXT) + '...' : t;\n }\n\n // ── Stage 5: Iframe ──\n if (tag === 'iframe') {\n const iframeContent = getIframeContent(el, depth + 1, maxDepth);\n if (iframeContent) {\n return indent + prefix + '<iframe' + a + '>\\\\n' + iframeContent;\n }\n return '';\n }\n\n // Build output\n let out = '';\n\n if (skipSelf) {\n // Skip self but render children\n for (const c of el.childNodes) out += walkNode(c, depth, maxDepth);\n out += getShadowContent(el, depth, maxDepth);\n return out;\n }\n\n if (inter || leafText || el.children.length === 0) {\n if (leafText) {\n out = indent + prefix + '<' + tag + a + scrollInfo + inputHint + '>' + leafText + '</' + tag + '>\\\\n';\n } else {\n out = indent + prefix + '<' + tag + a + scrollInfo + inputHint + '>\\\\n';\n for (const c of el.childNodes) out += walkNode(c, depth + 1, maxDepth);\n out += getShadowContent(el, depth + 1, maxDepth);\n }\n } else {\n // Non-interactive container — flatten depth if no useful info\n if (scrollInfo) {\n out = indent + '<' + tag + scrollInfo + '>\\\\n';\n for (const c of el.childNodes) out += walkNode(c, depth + 1, maxDepth);\n out += getShadowContent(el, depth + 1, maxDepth);\n } else {\n for (const c of el.childNodes) out += walkNode(c, depth, maxDepth);\n out += getShadowContent(el, depth, maxDepth);\n }\n }\n\n return out;\n }\n\n // ── Page-level scroll info header ──\n const scrollY = window.scrollY;\n const scrollMax = document.documentElement.scrollHeight - window.innerHeight;\n const scrollPct = scrollMax > 0 ? Math.round((scrollY / scrollMax) * 100) : 0;\n const vpW = window.innerWidth;\n const vpH = window.innerHeight;\n const pageH = document.documentElement.scrollHeight;\n\n let header = '';\n header += 'viewport: ' + vpW + 'x' + vpH + ' | page_height: ' + pageH + 'px';\n header += ' | scroll: ' + scrollPct + '%';\n if (scrollY > 50) header += ' (' + Math.round(scrollY) + 'px from top)';\n if (scrollMax - scrollY > 50) header += ' (' + Math.round(scrollMax - scrollY) + 'px more below)';\n header += '\\\\n---\\\\n';\n\n // Store current hashes for next diff comparison\n window.__lobster_prev_hashes = __currentHashes;\n\n return header + walkNode(document.body, 0, MAX_DEPTH);\n})()\n`;\n","/**\n * Semantic tree — W3C accessible name algorithm, XPath, listener detection.\n *\n * Based on Lightpanda's SemanticTree.zig approach:\n * - Accessible name: aria-labelledby → aria-label → alt → title → placeholder → text content\n * - XPath generation for element location\n * - Interactive classification: native, aria, contenteditable, listener, focusable\n * - Disabled state with fieldset inheritance\n * - Input value, option, checked state extraction\n */\nexport const SEMANTIC_TREE_SCRIPT = `\n(() => {\n const SKIP = new Set(['script','style','noscript','svg','head','meta','link','template']);\n\n const ROLE_MAP = {\n a: 'link', button: 'button', input: 'textbox', select: 'combobox',\n textarea: 'textbox', h1: 'heading', h2: 'heading', h3: 'heading',\n h4: 'heading', h5: 'heading', h6: 'heading', nav: 'navigation',\n main: 'main', header: 'banner', footer: 'contentinfo', aside: 'complementary',\n form: 'form', table: 'table', img: 'img', ul: 'list', ol: 'list', li: 'listitem',\n section: 'region', article: 'article', dialog: 'dialog', details: 'group',\n summary: 'button', progress: 'progressbar', meter: 'meter', output: 'status',\n label: 'label', legend: 'legend', fieldset: 'group', option: 'option',\n tr: 'row', td: 'cell', th: 'columnheader', caption: 'caption',\n };\n\n const INTERACTIVE_ROLES = new Set([\n 'button','link','textbox','checkbox','radio','combobox','listbox',\n 'menu','menuitem','tab','switch','slider','searchbox','spinbutton',\n 'option','menuitemcheckbox','menuitemradio','treeitem',\n ]);\n\n // ── W3C Accessible Name Algorithm (simplified) ──\n function getAccessibleName(el) {\n // 1. aria-labelledby (highest priority)\n const labelledBy = el.getAttribute('aria-labelledby');\n if (labelledBy) {\n const ids = labelledBy.split(/\\\\s+/);\n const parts = ids.map(id => {\n const ref = document.getElementById(id);\n return ref ? ref.textContent.trim() : '';\n }).filter(Boolean);\n if (parts.length > 0) return parts.join(' ').slice(0, 120);\n }\n\n // 2. aria-label\n const ariaLabel = el.getAttribute('aria-label');\n if (ariaLabel) return ariaLabel.slice(0, 120);\n\n // 3. alt (for images)\n const alt = el.getAttribute('alt');\n if (alt) return alt.slice(0, 120);\n\n // 4. title\n const title = el.getAttribute('title');\n if (title) return title.slice(0, 120);\n\n // 5. placeholder (for inputs)\n const placeholder = el.getAttribute('placeholder');\n if (placeholder) return placeholder.slice(0, 120);\n\n // 6. value (for buttons)\n if (el.tagName === 'INPUT' && (el.type === 'submit' || el.type === 'button')) {\n const val = el.getAttribute('value');\n if (val) return val.slice(0, 120);\n }\n\n // 7. Associated label\n if (el.id) {\n const label = document.querySelector('label[for=\"' + el.id + '\"]');\n if (label) return label.textContent.trim().slice(0, 120);\n }\n\n // 8. Direct text content (only for leaf-ish elements)\n if (el.children.length <= 2) {\n const text = el.textContent.trim();\n if (text && text.length < 120) return text;\n }\n\n return '';\n }\n\n // ── XPath generation ──\n function getXPath(el) {\n const parts = [];\n let current = el;\n while (current && current.nodeType === 1) {\n let index = 1;\n let sibling = current.previousElementSibling;\n while (sibling) {\n if (sibling.tagName === current.tagName) index++;\n sibling = sibling.previousElementSibling;\n }\n const tag = current.tagName.toLowerCase();\n parts.unshift(tag + '[' + index + ']');\n current = current.parentElement;\n }\n return '/' + parts.join('/');\n }\n\n // ── Interactivity classification ──\n function classifyInteractivity(el) {\n const types = [];\n const tag = el.tagName.toLowerCase();\n\n // Native\n if (['a','button','input','select','textarea','details','summary'].includes(tag)) {\n if (tag === 'a' && !el.href) {} // anchor without href is not interactive\n else if (tag === 'input' && el.type === 'hidden') {} // hidden inputs\n else types.push('native');\n }\n\n // ARIA role\n const role = el.getAttribute('role');\n if (role && INTERACTIVE_ROLES.has(role)) types.push('aria');\n\n // Contenteditable\n if (el.contentEditable === 'true') types.push('contenteditable');\n\n // Focusable\n if (el.tabIndex >= 0 && el.getAttribute('tabindex') !== null) types.push('focusable');\n\n // Event listeners (check onclick and common inline handlers)\n if (el.onclick || el.onmousedown || el.onkeydown || el.onkeypress ||\n el.getAttribute('onclick') || el.getAttribute('onmousedown')) {\n types.push('listener');\n }\n\n return types;\n }\n\n // ── Disabled state with fieldset inheritance ──\n function isDisabled(el) {\n if (el.disabled) return true;\n // Check fieldset disabled inheritance\n let parent = el.parentElement;\n while (parent) {\n if (parent.tagName === 'FIELDSET' && parent.disabled) {\n // Exception: elements inside the first legend child are NOT disabled\n const firstLegend = parent.querySelector(':scope > legend');\n if (firstLegend && firstLegend.contains(el)) return false;\n return true;\n }\n parent = parent.parentElement;\n }\n return false;\n }\n\n // ── Walk the DOM ──\n function walk(el, depth, maxDepth) {\n if (!el || depth > maxDepth) return '';\n\n if (el.nodeType === 3) {\n const t = el.textContent.trim();\n return t ? ' '.repeat(depth) + 'text \"' + t.slice(0, 100) + '\"\\\\n' : '';\n }\n\n if (el.nodeType !== 1) return '';\n const tag = el.tagName.toLowerCase();\n if (SKIP.has(tag)) return '';\n\n const style = getComputedStyle(el);\n if (style.display === 'none' || style.visibility === 'hidden') return '';\n\n const indent = ' '.repeat(depth);\n const role = el.getAttribute('role') || ROLE_MAP[tag] || '';\n const name = getAccessibleName(el);\n const interTypes = classifyInteractivity(el);\n const interactive = interTypes.length > 0;\n const disabled = interactive && isDisabled(el);\n\n let line = indent;\n line += role || tag;\n\n if (name) line += ' \"' + name.slice(0, 80) + '\"';\n\n if (interactive) {\n line += ' [' + interTypes.join(',') + ']';\n if (disabled) line += ' {disabled}';\n line += ' xpath=' + getXPath(el);\n }\n\n // Input state\n if (tag === 'input') {\n const type = el.type || 'text';\n line += ' type=' + type;\n if (type === 'checkbox' || type === 'radio') {\n line += el.checked ? ' [checked]' : ' [unchecked]';\n } else if (el.value) {\n line += ' value=\"' + el.value.slice(0, 50) + '\"';\n }\n }\n if (tag === 'textarea' && el.value) {\n line += ' value=\"' + el.value.slice(0, 50) + '\"';\n }\n if (tag === 'select') {\n const opts = Array.from(el.options || []).map(o => ({\n text: o.text.slice(0, 30),\n value: o.value,\n selected: o.selected,\n }));\n const selected = opts.find(o => o.selected);\n if (selected) line += ' selected=\"' + selected.text + '\"';\n if (opts.length <= 10) {\n line += ' options=[' + opts.map(o => o.text).join('|') + ']';\n }\n }\n\n line += '\\\\n';\n\n let out = line;\n for (const c of el.childNodes) {\n out += walk(c, depth + 1, maxDepth);\n }\n\n // Shadow DOM\n if (el.shadowRoot) {\n for (const c of el.shadowRoot.childNodes) {\n out += walk(c, depth + 1, maxDepth);\n }\n }\n\n return out;\n }\n\n return walk(document.body, 0, 20);\n})()\n`;\n","/**\n * DOM-to-Markdown converter — runs inside the browser.\n *\n * Full-featured conversion based on Lightpanda's markdown.zig:\n * - Table support with header separator rows\n * - URL resolution (relative → absolute)\n * - Nested ordered/unordered lists with proper indentation\n * - Character escaping for Markdown special chars\n * - Strikethrough, code blocks, blockquotes\n * - Smart anchor handling (inline vs block)\n * - Whitespace collapsing\n */\nexport const MARKDOWN_SCRIPT = `\n(() => {\n const SKIP = new Set(['script','style','noscript','svg','head','template']);\n const baseUrl = location.href;\n\n // Resolve relative URLs to absolute\n function resolveUrl(href) {\n if (!href || href.startsWith('javascript:') || href.startsWith('#')) return href;\n try { return new URL(href, baseUrl).href; } catch { return href; }\n }\n\n // Escape Markdown special chars in text\n function escapeText(text) {\n return text\n .replace(/\\\\\\\\/g, '\\\\\\\\\\\\\\\\')\n .replace(/([*_~\\`\\\\[\\\\]|])/g, '\\\\\\\\$1');\n }\n\n // State tracking\n let listDepth = 0;\n let orderedCounters = [];\n let inPre = false;\n let inTable = false;\n\n function listIndent() { return ' '.repeat(listDepth); }\n\n function walk(el) {\n if (!el) return '';\n\n // Text node\n if (el.nodeType === 3) {\n const text = el.textContent || '';\n if (inPre) return text;\n // Collapse whitespace\n const collapsed = text.replace(/\\\\s+/g, ' ');\n return collapsed === ' ' && !el.previousSibling && !el.nextSibling ? '' : collapsed;\n }\n\n if (el.nodeType !== 1) return '';\n const tag = el.tagName.toLowerCase();\n if (SKIP.has(tag)) return '';\n\n // Visibility check\n try {\n const s = getComputedStyle(el);\n if (s.display === 'none' || s.visibility === 'hidden') return '';\n } catch {}\n\n // Get children content\n function childContent() {\n let out = '';\n for (const c of el.childNodes) out += walk(c);\n return out;\n }\n\n switch (tag) {\n // ── Headings ──\n case 'h1': return '\\\\n\\\\n# ' + childContent().trim() + '\\\\n\\\\n';\n case 'h2': return '\\\\n\\\\n## ' + childContent().trim() + '\\\\n\\\\n';\n case 'h3': return '\\\\n\\\\n### ' + childContent().trim() + '\\\\n\\\\n';\n case 'h4': return '\\\\n\\\\n#### ' + childContent().trim() + '\\\\n\\\\n';\n case 'h5': return '\\\\n\\\\n##### ' + childContent().trim() + '\\\\n\\\\n';\n case 'h6': return '\\\\n\\\\n###### ' + childContent().trim() + '\\\\n\\\\n';\n\n // ── Block elements ──\n case 'p': return '\\\\n\\\\n' + childContent().trim() + '\\\\n\\\\n';\n case 'br': return '\\\\n';\n case 'hr': return '\\\\n\\\\n---\\\\n\\\\n';\n\n // ── Inline formatting ──\n case 'strong': case 'b': {\n const inner = childContent().trim();\n return inner ? '**' + inner + '**' : '';\n }\n case 'em': case 'i': {\n const inner = childContent().trim();\n return inner ? '*' + inner + '*' : '';\n }\n case 's': case 'del': case 'strike': {\n const inner = childContent().trim();\n return inner ? '~~' + inner + '~~' : '';\n }\n case 'code': {\n if (inPre) return childContent();\n const inner = childContent();\n return inner ? '\\\\x60' + inner + '\\\\x60' : '';\n }\n\n // ── Code blocks ──\n case 'pre': {\n inPre = true;\n const inner = childContent();\n inPre = false;\n const lang = el.querySelector('code')?.className?.match(/language-(\\\\w+)/)?.[1] || '';\n return '\\\\n\\\\n\\\\x60\\\\x60\\\\x60' + lang + '\\\\n' + inner.trim() + '\\\\n\\\\x60\\\\x60\\\\x60\\\\n\\\\n';\n }\n\n // ── Links ──\n case 'a': {\n const href = resolveUrl(el.getAttribute('href') || '');\n const inner = childContent().trim();\n const name = inner || el.getAttribute('aria-label') || el.getAttribute('title') || '';\n if (!name) return '';\n if (!href || href === '#' || href.startsWith('javascript:')) return name;\n return '[' + name + '](' + href + ')';\n }\n\n // ── Images ──\n case 'img': {\n const alt = el.getAttribute('alt') || '';\n const src = resolveUrl(el.getAttribute('src') || '');\n return src ? '![' + alt + '](' + src + ')' : '';\n }\n\n // ── Lists ──\n case 'ul': {\n listDepth++;\n orderedCounters.push(0);\n const inner = childContent();\n listDepth--;\n orderedCounters.pop();\n return '\\\\n' + inner;\n }\n case 'ol': {\n listDepth++;\n orderedCounters.push(0);\n const inner = childContent();\n listDepth--;\n orderedCounters.pop();\n return '\\\\n' + inner;\n }\n case 'li': {\n const parent = el.parentElement?.tagName?.toLowerCase();\n const isOrdered = parent === 'ol';\n const inner = childContent().trim();\n if (!inner) return '';\n if (isOrdered) {\n const counter = orderedCounters.length > 0\n ? ++orderedCounters[orderedCounters.length - 1] : 1;\n return listIndent() + counter + '. ' + inner + '\\\\n';\n }\n return listIndent() + '- ' + inner + '\\\\n';\n }\n\n // ── Blockquote ──\n case 'blockquote': {\n const inner = childContent().trim();\n if (!inner) return '';\n return '\\\\n\\\\n' + inner.split('\\\\n').map(line => '> ' + line).join('\\\\n') + '\\\\n\\\\n';\n }\n\n // ── Tables ──\n case 'table': {\n inTable = true;\n let out = '\\\\n\\\\n';\n const rows = el.querySelectorAll('tr');\n let headerDone = false;\n\n for (let i = 0; i < rows.length; i++) {\n const cells = rows[i].querySelectorAll('th, td');\n const isHeader = rows[i].querySelector('th') !== null;\n const cellTexts = [];\n for (const cell of cells) {\n let cellText = '';\n for (const c of cell.childNodes) cellText += walk(c);\n cellTexts.push(cellText.trim().replace(/\\\\|/g, '\\\\\\\\|').replace(/\\\\n/g, ' '));\n }\n\n out += '| ' + cellTexts.join(' | ') + ' |\\\\n';\n\n if (isHeader && !headerDone) {\n out += '| ' + cellTexts.map(() => '---').join(' | ') + ' |\\\\n';\n headerDone = true;\n }\n\n // First data row without headers — synthesize separator\n if (i === 0 && !isHeader && !headerDone) {\n out += '| ' + cellTexts.map(() => '---').join(' | ') + ' |\\\\n';\n headerDone = true;\n }\n }\n\n inTable = false;\n return out + '\\\\n';\n }\n case 'thead': case 'tbody': case 'tfoot':\n return childContent();\n case 'tr': case 'td': case 'th':\n // Handled by table walker above; fallback for orphaned elements\n return childContent();\n\n // ── Definition lists ──\n case 'dl': return '\\\\n\\\\n' + childContent() + '\\\\n\\\\n';\n case 'dt': return '\\\\n**' + childContent().trim() + '**\\\\n';\n case 'dd': return ': ' + childContent().trim() + '\\\\n';\n\n // ── Figure ──\n case 'figure': return '\\\\n\\\\n' + childContent().trim() + '\\\\n\\\\n';\n case 'figcaption': return '\\\\n*' + childContent().trim() + '*\\\\n';\n\n // ── Details/Summary ──\n case 'details': return '\\\\n\\\\n' + childContent() + '\\\\n\\\\n';\n case 'summary': return '**' + childContent().trim() + '**\\\\n\\\\n';\n\n // ── Generic blocks ──\n case 'div': case 'section': case 'article': case 'main': case 'aside':\n case 'header': case 'footer': case 'nav':\n return '\\\\n' + childContent() + '\\\\n';\n\n case 'span': case 'small': case 'sub': case 'sup': case 'abbr':\n case 'time': case 'mark': case 'cite': case 'q':\n return childContent();\n\n default:\n return childContent();\n }\n }\n\n const raw = walk(document.body);\n // Clean up: collapse 3+ newlines to 2, trim\n return raw.replace(/\\\\n{3,}/g, '\\\\n\\\\n').replace(/^\\\\n+|\\\\n+$/g, '').trim();\n})()\n`;\n","/**\n * Form state extraction — runs inside the browser.\n *\n * Extracts all form fields (including orphan fields not in <form> tags),\n * their types, labels, values, required/disabled state.\n *\n * Based on OpenCLI's getFormStateJs() pattern.\n */\nexport const FORM_STATE_SCRIPT = `\n(() => {\n function extractField(el) {\n const tag = el.tagName.toLowerCase();\n const type = (el.getAttribute('type') || tag).toLowerCase();\n\n // Skip non-user-facing inputs\n if (['hidden', 'submit', 'button', 'reset', 'image'].includes(type)) return null;\n\n const name = el.name || el.id || '';\n\n // Find label via multiple strategies\n const label =\n el.getAttribute('aria-label') ||\n (el.id ? document.querySelector('label[for=\"' + el.id + '\"]')?.textContent?.trim() : null) ||\n el.closest('label')?.textContent?.trim() ||\n el.placeholder ||\n '';\n\n // Extract value based on type\n let value;\n if (tag === 'select') {\n const selected = el.options[el.selectedIndex];\n value = selected ? selected.textContent.trim() : '';\n } else if (type === 'checkbox' || type === 'radio') {\n value = el.checked;\n } else if (type === 'password') {\n value = el.value ? '••••' : '';\n } else if (el.isContentEditable) {\n value = el.textContent?.trim()?.slice(0, 200) || '';\n } else {\n value = el.value || '';\n }\n\n return {\n tag,\n type,\n name,\n label: label.slice(0, 80),\n value: typeof value === 'string' ? value.slice(0, 200) : value,\n required: !!el.required,\n disabled: !!el.disabled,\n ref: el.dataset?.ref || null,\n };\n }\n\n const result = { forms: [], orphanFields: [] };\n\n // Collect forms\n for (const form of document.forms) {\n const fields = [];\n for (const el of form.elements) {\n const field = extractField(el);\n if (field) fields.push(field);\n }\n result.forms.push({\n id: form.id || '',\n name: form.name || '',\n action: form.action || '',\n method: (form.method || 'get').toUpperCase(),\n fields,\n });\n }\n\n // Collect orphan fields (not in a <form>)\n const allInputs = document.querySelectorAll(\n 'input, textarea, select, [contenteditable=\"true\"]'\n );\n for (const el of allInputs) {\n if (!el.form) {\n const field = extractField(el);\n if (field) result.orphanFields.push(field);\n }\n }\n\n return result;\n})()\n`;\n","/**\n * Network interceptor script — patches fetch and XHR to capture responses.\n * Based on OpenCLI's interception approach.\n */\nexport function buildInterceptorScript(pattern: string): string {\n return `\n(() => {\n if (window.__lobster_interceptor__) return;\n window.__lobster_interceptor__ = { requests: [] };\n const store = window.__lobster_interceptor__;\n const pattern = ${JSON.stringify(pattern)};\n\n // Patch fetch\n const origFetch = window.fetch;\n window.fetch = async function(...args) {\n const url = typeof args[0] === 'string' ? args[0] : args[0]?.url || '';\n const resp = await origFetch.apply(this, args);\n if (url.includes(pattern)) {\n const clone = resp.clone();\n try {\n const body = await clone.json();\n store.requests.push({ url, method: 'GET', status: resp.status, body, timestamp: Date.now() });\n } catch {}\n }\n return resp;\n };\n\n // Patch XHR\n const origOpen = XMLHttpRequest.prototype.open;\n const origSend = XMLHttpRequest.prototype.send;\n XMLHttpRequest.prototype.open = function(method, url, ...rest) {\n this.__url = url;\n this.__method = method;\n return origOpen.call(this, method, url, ...rest);\n };\n XMLHttpRequest.prototype.send = function(...args) {\n this.addEventListener('load', function() {\n if (this.__url && this.__url.includes(pattern)) {\n try {\n const body = JSON.parse(this.responseText);\n store.requests.push({ url: this.__url, method: this.__method, status: this.status, body, timestamp: Date.now() });\n } catch {}\n }\n });\n return origSend.apply(this, args);\n };\n})()\n`;\n}\n\nexport const GET_INTERCEPTED_SCRIPT = `\n(() => {\n const store = window.__lobster_interceptor__;\n if (!store) return [];\n const reqs = [...store.requests];\n store.requests = [];\n return reqs;\n})()\n`;\n","import type { Page } from 'puppeteer-core';\nimport type {\n IPage, WaitCondition, Cookie, NetworkEntry, TabInfo,\n SnapshotOptions, SemanticTreeOptions, FlatDomTree, BrowserState, FormState,\n} from '../types/page.js';\nimport { FLAT_TREE_SCRIPT, flatTreeToString } from './dom/flat-tree.js';\nimport { SNAPSHOT_SCRIPT } from './dom/snapshot.js';\nimport { SEMANTIC_TREE_SCRIPT } from './dom/semantic-tree.js';\nimport { MARKDOWN_SCRIPT } from './dom/markdown.js';\nimport { FORM_STATE_SCRIPT } from './dom/form-state.js';\nimport { buildInterceptorScript, GET_INTERCEPTED_SCRIPT } from './interceptor.js';\n\nexport class PuppeteerPage implements IPage {\n private page: Page;\n\n constructor(page: Page) {\n this.page = page;\n }\n\n get raw(): Page { return this.page; }\n\n async goto(url: string, options?: { waitUntil?: WaitCondition; timeout?: number }): Promise<void> {\n await this.page.goto(url, {\n waitUntil: (options?.waitUntil as any) || 'networkidle2',\n timeout: options?.timeout || 30000,\n });\n }\n\n async goBack(): Promise<void> {\n await this.page.goBack({ waitUntil: 'networkidle2' });\n }\n\n async url(): Promise<string> {\n return this.page.url();\n }\n\n async title(): Promise<string> {\n return this.page.title();\n }\n\n async evaluate<T = unknown>(js: string): Promise<T> {\n return this.page.evaluate(js) as Promise<T>;\n }\n\n async snapshot(_opts?: SnapshotOptions): Promise<string> {\n return this.page.evaluate(SNAPSHOT_SCRIPT) as Promise<string>;\n }\n\n async semanticTree(_opts?: SemanticTreeOptions): Promise<string> {\n return this.page.evaluate(SEMANTIC_TREE_SCRIPT) as Promise<string>;\n }\n\n async flatTree(): Promise<FlatDomTree> {\n const raw = await this.page.evaluate(FLAT_TREE_SCRIPT);\n return raw as FlatDomTree;\n }\n\n async markdown(): Promise<string> {\n return this.page.evaluate(MARKDOWN_SCRIPT) as Promise<string>;\n }\n\n async browserState(): Promise<BrowserState> {\n const state = await this.page.evaluate(`\n (() => {\n const scrollY = window.scrollY;\n const scrollX = window.scrollX;\n const vpW = window.innerWidth;\n const vpH = window.innerHeight;\n const pageW = document.documentElement.scrollWidth;\n const pageH = document.documentElement.scrollHeight;\n const maxScrollY = pageH - vpH;\n return {\n url: location.href,\n title: document.title,\n viewportWidth: vpW,\n viewportHeight: vpH,\n pageWidth: pageW,\n pageHeight: pageH,\n scrollX: scrollX,\n scrollY: scrollY,\n scrollPercent: maxScrollY > 0 ? Math.round((scrollY / maxScrollY) * 100) : 0,\n pixelsAbove: Math.round(scrollY),\n pixelsBelow: Math.round(Math.max(0, maxScrollY - scrollY)),\n };\n })()\n `) as BrowserState;\n return state;\n }\n\n async formState(): Promise<FormState> {\n return this.page.evaluate(FORM_STATE_SCRIPT) as Promise<FormState>;\n }\n\n async click(ref: string | number): Promise<void> {\n if (typeof ref === 'number') {\n await this.page.evaluate((idx) => {\n const el = document.querySelector('[data-ref=\"' + idx + '\"]') as HTMLElement;\n if (!el) throw new Error('Element with index ' + idx + ' not found');\n\n // Blur previously focused element\n const prev = document.activeElement as HTMLElement | null;\n if (prev && prev !== el && prev !== document.body) {\n prev.blur();\n prev.dispatchEvent(new MouseEvent('mouseout', { bubbles: true, cancelable: true }));\n prev.dispatchEvent(new MouseEvent('mouseleave', { bubbles: false, cancelable: true }));\n }\n\n // Scroll into view\n if (typeof (el as any).scrollIntoViewIfNeeded === 'function') {\n (el as any).scrollIntoViewIfNeeded();\n } else {\n el.scrollIntoView({ behavior: 'auto', block: 'center', inline: 'nearest' });\n }\n\n // Full mouse event sequence — required for React, analytics, custom handlers\n el.dispatchEvent(new MouseEvent('mouseenter', { bubbles: true, cancelable: true }));\n el.dispatchEvent(new MouseEvent('mouseover', { bubbles: true, cancelable: true }));\n el.dispatchEvent(new MouseEvent('mousedown', { bubbles: true, cancelable: true }));\n el.focus();\n el.dispatchEvent(new MouseEvent('mouseup', { bubbles: true, cancelable: true }));\n el.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true }));\n }, ref);\n // Wait for click processing (animations, state updates)\n await new Promise((r) => setTimeout(r, 200));\n } else {\n await this.page.click(ref);\n }\n }\n\n async typeText(ref: string | number, text: string): Promise<void> {\n if (typeof ref === 'number') {\n // First click the element (triggers full event sequence + focus)\n await this.click(ref);\n\n await this.page.evaluate((idx, txt) => {\n const el = document.querySelector('[data-ref=\"' + idx + '\"]') as HTMLElement;\n if (!el) throw new Error('Element with index ' + idx + ' not found');\n\n const isInput = el.tagName === 'INPUT' || el.tagName === 'TEXTAREA';\n const isContentEditable = el.isContentEditable;\n\n if (isContentEditable) {\n // ── Contenteditable: Plan A — synthetic InputEvents ──\n // Works for: React contenteditable, Quill\n // Clear existing content\n if (el.dispatchEvent(new InputEvent('beforeinput', {\n bubbles: true, cancelable: true, inputType: 'deleteContent',\n }))) {\n el.innerText = '';\n el.dispatchEvent(new InputEvent('input', {\n bubbles: true, inputType: 'deleteContent',\n }));\n }\n\n // Insert new text\n if (el.dispatchEvent(new InputEvent('beforeinput', {\n bubbles: true, cancelable: true, inputType: 'insertText', data: txt,\n }))) {\n el.innerText = txt;\n el.dispatchEvent(new InputEvent('input', {\n bubbles: true, inputType: 'insertText', data: txt,\n }));\n }\n\n // Verify Plan A worked\n const planAOk = el.innerText.trim() === txt.trim();\n\n if (!planAOk) {\n // ── Plan B — execCommand fallback ──\n // Works for: Slate.js, some rich-text editors\n el.focus();\n const doc = el.ownerDocument;\n const sel = (doc.defaultView || window).getSelection();\n const range = doc.createRange();\n range.selectNodeContents(el);\n sel?.removeAllRanges();\n sel?.addRange(range);\n doc.execCommand('delete', false);\n doc.execCommand('insertText', false, txt);\n }\n\n el.dispatchEvent(new Event('change', { bubbles: true }));\n el.blur();\n\n } else if (isInput) {\n // ── Input/Textarea: use native value setter to bypass React/Vue ──\n const inputEl = el as HTMLInputElement | HTMLTextAreaElement;\n const proto = Object.getPrototypeOf(inputEl);\n const descriptor =\n Object.getOwnPropertyDescriptor(proto, 'value') ||\n Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value') ||\n Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype, 'value');\n\n if (descriptor?.set) {\n descriptor.set.call(inputEl, txt);\n } else {\n inputEl.value = txt;\n }\n\n inputEl.dispatchEvent(new Event('input', { bubbles: true }));\n inputEl.dispatchEvent(new Event('change', { bubbles: true }));\n } else {\n // Fallback: try setting value anyway\n (el as any).value = txt;\n el.dispatchEvent(new Event('input', { bubbles: true }));\n el.dispatchEvent(new Event('change', { bubbles: true }));\n }\n }, ref, text);\n } else {\n // CSS selector path — click to focus, then use keyboard\n await this.page.click(ref, { count: 3 });\n await this.page.keyboard.type(text);\n }\n }\n\n async pressKey(key: string): Promise<void> {\n await this.page.keyboard.press(key as any);\n }\n\n async selectOption(ref: string | number, value: string): Promise<void> {\n const selector = typeof ref === 'number' ? '[data-ref=\"' + ref + '\"]' : ref;\n await this.page.select(selector, value);\n }\n\n async scroll(direction: 'up' | 'down' | 'left' | 'right', amount?: number): Promise<void> {\n const distance = amount || 500;\n const isVertical = direction === 'up' || direction === 'down';\n const positive = direction === 'down' || direction === 'right';\n const delta = positive ? distance : -distance;\n\n await this.page.evaluate((dy, dx, isVert) => {\n // Helper: check if element is a valid scroll container\n const canScroll = (el) => {\n if (!el) return false;\n const s = getComputedStyle(el);\n if (isVert) {\n return /(auto|scroll|overlay)/.test(s.overflowY) &&\n el.scrollHeight > el.clientHeight &&\n el.clientHeight >= window.innerHeight * 0.3;\n } else {\n return /(auto|scroll|overlay)/.test(s.overflowX) &&\n el.scrollWidth > el.clientWidth &&\n el.clientWidth >= window.innerWidth * 0.3;\n }\n };\n\n // Walk from active element up to find a scrollable container\n let el = document.activeElement;\n while (el && !canScroll(el) && el !== document.body) {\n el = el.parentElement;\n }\n\n // If no scrollable ancestor, search the DOM\n if (!canScroll(el)) {\n el = Array.from(document.querySelectorAll('*')).find(canScroll) || null;\n }\n\n const isPageLevel = !el || el === document.body ||\n el === document.documentElement || el === document.scrollingElement;\n\n if (isPageLevel) {\n // Page-level scroll\n if (isVert) {\n window.scrollBy(0, dy);\n } else {\n window.scrollBy(dx, 0);\n }\n } else {\n // Container scroll\n if (isVert) {\n el.scrollBy({ top: dy, behavior: 'smooth' });\n } else {\n el.scrollBy({ left: dx, behavior: 'smooth' });\n }\n }\n }, isVertical ? delta : 0, isVertical ? 0 : delta, isVertical);\n\n // Wait for smooth scroll to settle\n await new Promise((r) => setTimeout(r, 150));\n }\n\n async scrollToElement(ref: string | number): Promise<void> {\n const selector = typeof ref === 'number' ? '[data-ref=\"' + ref + '\"]' : ref;\n await this.page.evaluate((sel) => {\n const el = document.querySelector(sel);\n if (!el) return;\n if (typeof (el as any).scrollIntoViewIfNeeded === 'function') {\n (el as any).scrollIntoViewIfNeeded();\n } else {\n el.scrollIntoView({ behavior: 'auto', block: 'center', inline: 'nearest' });\n }\n }, selector);\n }\n\n async getCookies(opts?: { domain?: string }): Promise<Cookie[]> {\n const cookies = await this.page.cookies();\n const filtered = opts?.domain\n ? cookies.filter((c) => c.domain.includes(opts.domain!))\n : cookies;\n return filtered.map((c) => ({\n name: c.name,\n value: c.value,\n domain: c.domain,\n path: c.path,\n expires: c.expires,\n httpOnly: c.httpOnly,\n secure: c.secure,\n sameSite: c.sameSite as Cookie['sameSite'],\n }));\n }\n\n async wait(options: number | { text?: string; time?: number; timeout?: number }): Promise<void> {\n if (typeof options === 'number') {\n await new Promise((r) => setTimeout(r, options * 1000));\n return;\n }\n if (options.time) {\n await new Promise((r) => setTimeout(r, options.time! * 1000));\n }\n if (options.text) {\n await this.page.waitForFunction(\n (t) => document.body.innerText.includes(t),\n { timeout: options.timeout || 30000 },\n options.text\n );\n }\n }\n\n async networkRequests(includeStatic?: boolean): Promise<NetworkEntry[]> {\n // Use Performance API to extract network requests from the browser\n const entries = await this.page.evaluate(`\n (() => {\n const entries = performance.getEntriesByType('resource');\n const staticTypes = new Set(['img', 'font', 'css', 'script', 'link']);\n const includeStatic = ${!!includeStatic};\n\n return entries\n .filter(e => includeStatic || !staticTypes.has(e.initiatorType))\n .map(e => ({\n url: e.name,\n method: 'GET',\n status: 200,\n type: e.initiatorType || 'other',\n size: e.transferSize || e.encodedBodySize || 0,\n duration: Math.round(e.duration),\n }));\n })()\n `) as NetworkEntry[];\n return entries || [];\n }\n\n async installInterceptor(pattern: string): Promise<void> {\n await this.page.evaluate(buildInterceptorScript(pattern));\n }\n\n async getInterceptedRequests(): Promise<unknown[]> {\n return this.page.evaluate(GET_INTERCEPTED_SCRIPT) as Promise<unknown[]>;\n }\n\n async screenshot(opts?: { format?: 'png' | 'jpeg'; fullPage?: boolean }): Promise<Buffer> {\n const result = await this.page.screenshot({\n type: opts?.format || 'png',\n fullPage: opts?.fullPage ?? false,\n });\n return Buffer.from(result);\n }\n\n async tabs(): Promise<TabInfo[]> {\n const browser = this.page.browser();\n const pages = await browser.pages();\n return pages.map((p, i) => ({\n id: i,\n url: p.url(),\n title: '',\n active: p === this.page,\n }));\n }\n\n async close(): Promise<void> {\n await this.page.close();\n }\n}\n","import { readFileSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { IPage } from '../types/page.js';\nimport type {\n AgentConfig, AgentTool, ExecutionResult, HistoricalEvent,\n AgentStepEvent, ObservationEvent, AgentStatus,\n AgentEvent, AgentEventListener, AgentEventType,\n} from '../types/agent.js';\nimport { LLM } from '../llm/client.js';\nimport type { Message } from '../types/llm.js';\nimport { createDefaultTools } from './tools/index.js';\nimport { packMacroTool } from './macro-tool.js';\nimport { flatTreeToString } from '../browser/dom/flat-tree.js';\nimport { log } from '../utils/logger.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nexport class AgentCore {\n private page: IPage;\n private config: AgentConfig;\n private llm: LLM;\n private history: HistoricalEvent[] = [];\n private _status: AgentStatus = 'idle';\n private listeners = new Map<AgentEventType, Set<AgentEventListener>>();\n private previousElementHashes = new Set<string>();\n private totalWaitTime = 0;\n\n constructor(page: IPage, config: AgentConfig) {\n this.page = page;\n this.config = config;\n this.llm = new LLM(config.llm);\n }\n\n // ── Event system ──\n on(event: AgentEventType, listener: AgentEventListener): void {\n if (!this.listeners.has(event)) this.listeners.set(event, new Set());\n this.listeners.get(event)!.add(listener);\n }\n\n off(event: AgentEventType, listener: AgentEventListener): void {\n this.listeners.get(event)?.delete(listener);\n }\n\n private emit(event: AgentEvent): void {\n const listeners = this.listeners.get(event.type as AgentEventType);\n if (listeners) {\n for (const fn of listeners) {\n try { fn(event); } catch {}\n }\n }\n }\n\n get status(): AgentStatus { return this._status; }\n\n private setStatus(newStatus: AgentStatus): void {\n const prev = this._status;\n this._status = newStatus;\n this.emit({ type: 'statuschange', status: newStatus, previousStatus: prev });\n }\n\n private pushHistory(event: HistoricalEvent): void {\n this.history.push(event);\n this.emit({ type: 'historychange', history: this.history });\n }\n\n async execute(task: string, abortSignal?: AbortSignal): Promise<ExecutionResult> {\n this.setStatus('running');\n this.history = [];\n this.previousElementHashes.clear();\n this.totalWaitTime = 0;\n\n const maxSteps = this.config.maxSteps ?? 40;\n const stepDelay = this.config.stepDelay ?? 0.4;\n\n // Build tools\n const tools: Record<string, AgentTool> = {\n ...createDefaultTools(this.page),\n ...(this.config.customTools || {}),\n };\n for (const [name, tool] of Object.entries(tools)) {\n if (tool === null) delete tools[name];\n }\n\n const macroTool = packMacroTool(tools as Record<string, AgentTool>);\n\n // Load system prompt\n let systemPrompt: string;\n try {\n systemPrompt = readFileSync(join(__dirname, 'prompts', 'system.md'), 'utf-8');\n } catch {\n systemPrompt = 'You are an AI web agent that navigates web pages to complete tasks.';\n }\n\n if (this.config.instructions?.system) {\n systemPrompt += '\\n\\n' + this.config.instructions.system;\n }\n\n let lastURL = '';\n\n for (let step = 1; step <= maxSteps; step++) {\n if (abortSignal?.aborted) {\n this.setStatus('error');\n return { success: false, data: 'Aborted', history: this.history };\n }\n\n // ── Observe phase ──\n const browserState = await this.page.browserState().catch(() => ({\n url: '', title: '', viewportWidth: 0, viewportHeight: 0,\n pageWidth: 0, pageHeight: 0, scrollX: 0, scrollY: 0,\n scrollPercent: 0, pixelsAbove: 0, pixelsBelow: 0,\n }));\n\n const flatTree = await this.page.flatTree().catch(() => ({ rootId: '', map: {} }));\n const pageContent = flatTreeToString(flatTree);\n\n // ── New element tracking ──\n const currentHashes = new Set<string>();\n let newElementCount = 0;\n for (const node of Object.values(flatTree.map)) {\n if (node.isInteractive && node.highlightIndex !== undefined) {\n const hash = `${node.tagName}:${node.text || ''}:${JSON.stringify(node.attributes || {})}`;\n currentHashes.add(hash);\n if (!this.previousElementHashes.has(hash)) {\n newElementCount++;\n }\n }\n }\n this.previousElementHashes = currentHashes;\n\n // ── Build observations ──\n const observations: string[] = [];\n if (browserState.url !== lastURL && lastURL) {\n observations.push(`Navigated to ${browserState.url}`);\n }\n lastURL = browserState.url;\n\n if (newElementCount > 0 && step > 1) {\n observations.push(`${newElementCount} new interactive element(s) appeared`);\n }\n\n if (this.totalWaitTime > 3) {\n observations.push(`Total wait time: ${this.totalWaitTime.toFixed(1)}s — consider if page is still loading`);\n }\n\n if (step >= maxSteps - 5) {\n observations.push(`Warning: ${maxSteps - step} steps remaining`);\n }\n\n if (this.config.instructions?.getPageInstructions) {\n try {\n const pi = this.config.instructions.getPageInstructions(browserState.url);\n if (pi) observations.push(`Page instructions: ${pi}`);\n } catch {}\n }\n\n for (const obs of observations) {\n this.pushHistory({ type: 'observation', message: obs } as ObservationEvent);\n this.emit({ type: 'activity', kind: 'observation', message: obs, step });\n }\n\n // ── Assemble user prompt with browser state ──\n const userPrompt = assembleUserPrompt(\n task, pageContent, browserState, this.history, step, maxSteps,\n );\n\n // ── Think phase ──\n const messages: Message[] = [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: userPrompt },\n ];\n\n log.step(step, `Thinking... (${browserState.url})`);\n this.emit({ type: 'activity', kind: 'thinking', message: `Step ${step}: thinking`, step });\n\n if (this.config.onBeforeStep) await this.config.onBeforeStep(step);\n\n const startTime = Date.now();\n let result;\n try {\n result = await this.llm.invoke(messages, macroTool, abortSignal);\n } catch (err) {\n log.error(`LLM error at step ${step}: ${err}`);\n this.pushHistory({ type: 'error', error: String(err), step });\n this.emit({ type: 'activity', kind: 'error', message: String(err), step });\n continue;\n }\n const duration = Date.now() - startTime;\n\n // ── Act phase ──\n const args = result.toolCall.args;\n const action = (args.action || args) as Record<string, unknown>;\n const [actionName, actionInput] = Object.entries(action)[0] || ['unknown', {}];\n\n this.emit({ type: 'activity', kind: 'executing', message: actionName, step });\n\n // Track wait time\n if (actionName === 'wait') {\n const secs = (actionInput as any)?.seconds || 0;\n this.totalWaitTime += secs;\n }\n\n const stepEvent: AgentStepEvent = {\n type: 'step',\n step,\n reflection: {\n evaluation_previous_goal: (args.evaluation_previous_goal as string) || '',\n memory: (args.memory as string) || '',\n next_goal: (args.next_goal as string) || '',\n },\n action: { name: actionName, args: actionInput as Record<string, unknown> },\n output: result.toolResult,\n duration,\n };\n this.pushHistory(stepEvent);\n\n log.step(step, `Action: ${actionName} → ${result.toolResult.slice(0, 100)}`);\n this.emit({ type: 'activity', kind: 'executed', message: `${actionName}: ${result.toolResult.slice(0, 80)}`, step, duration });\n\n if (this.config.onAfterStep) await this.config.onAfterStep(this.history);\n\n // Check for done\n if (actionName === 'done') {\n try {\n const doneResult = JSON.parse(result.toolResult);\n this.setStatus('completed');\n return { success: doneResult.success, data: doneResult.text || result.toolResult, history: this.history };\n } catch {\n this.setStatus('completed');\n return { success: true, data: result.toolResult, history: this.history };\n }\n }\n\n if (stepDelay > 0) {\n await new Promise((r) => setTimeout(r, stepDelay * 1000));\n }\n }\n\n this.setStatus('error');\n return { success: false, data: `Reached maximum steps (${maxSteps})`, history: this.history };\n }\n}\n\nfunction assembleUserPrompt(\n task: string,\n pageContent: string,\n state: { url: string; title: string; viewportWidth: number; viewportHeight: number; pageHeight: number; scrollPercent: number; pixelsAbove: number; pixelsBelow: number },\n history: HistoricalEvent[],\n step: number,\n maxSteps: number,\n): string {\n let prompt = `# Task\\n${task}\\n\\n`;\n\n // Browser state header\n prompt += `# Current Page\\n`;\n prompt += `URL: ${state.url}\\n`;\n prompt += `Title: ${state.title}\\n`;\n prompt += `Viewport: ${state.viewportWidth}x${state.viewportHeight} | Page height: ${state.pageHeight}px\\n`;\n prompt += `Scroll: ${state.scrollPercent}%`;\n if (state.pixelsAbove > 50) prompt += ` | ${state.pixelsAbove}px above`;\n if (state.pixelsBelow > 50) prompt += ` | ${state.pixelsBelow}px below`;\n prompt += `\\nStep: ${step}/${maxSteps}\\n\\n`;\n\n prompt += `# Browser State\\n${pageContent}\\n\\n`;\n\n if (history.length > 0) {\n prompt += `# History\\n`;\n const recent = history.slice(-10);\n for (const event of recent) {\n if (event.type === 'step') {\n const s = event as AgentStepEvent;\n prompt += `<step_${s.step}>\\n`;\n if (s.reflection) {\n prompt += ` eval: ${s.reflection.evaluation_previous_goal}\\n`;\n prompt += ` memory: ${s.reflection.memory}\\n`;\n prompt += ` goal: ${s.reflection.next_goal}\\n`;\n }\n prompt += ` action: ${s.action.name}(${JSON.stringify(s.action.args)})\\n`;\n prompt += ` result: ${s.output.slice(0, 200)}\\n`;\n prompt += `</step_${s.step}>\\n`;\n } else if (event.type === 'observation') {\n prompt += `<sys>${(event as ObservationEvent).message}</sys>\\n`;\n }\n }\n }\n\n return prompt;\n}\n","export enum InvokeErrorType {\n NETWORK_ERROR = 'NETWORK_ERROR',\n AUTH_ERROR = 'AUTH_ERROR',\n RATE_LIMIT = 'RATE_LIMIT',\n SERVER_ERROR = 'SERVER_ERROR',\n CONTEXT_LENGTH = 'CONTEXT_LENGTH',\n CONTENT_FILTER = 'CONTENT_FILTER',\n NO_TOOL_CALL = 'NO_TOOL_CALL',\n INVALID_TOOL_ARGS = 'INVALID_TOOL_ARGS',\n TOOL_EXECUTION_ERROR = 'TOOL_EXECUTION_ERROR',\n UNKNOWN = 'UNKNOWN',\n}\n\nexport class InvokeError extends Error {\n type: InvokeErrorType;\n retryable: boolean;\n rawError?: unknown;\n rawResponse?: unknown;\n\n constructor(type: InvokeErrorType, message: string, opts?: { retryable?: boolean; rawError?: unknown; rawResponse?: unknown }) {\n super(message);\n this.name = 'InvokeError';\n this.type = type;\n this.retryable = opts?.retryable ?? isRetryable(type);\n this.rawError = opts?.rawError;\n this.rawResponse = opts?.rawResponse;\n }\n}\n\nfunction isRetryable(type: InvokeErrorType): boolean {\n switch (type) {\n case InvokeErrorType.NETWORK_ERROR:\n case InvokeErrorType.RATE_LIMIT:\n case InvokeErrorType.SERVER_ERROR:\n case InvokeErrorType.NO_TOOL_CALL:\n case InvokeErrorType.INVALID_TOOL_ARGS:\n case InvokeErrorType.TOOL_EXECUTION_ERROR:\n case InvokeErrorType.UNKNOWN:\n return true;\n case InvokeErrorType.AUTH_ERROR:\n case InvokeErrorType.CONTEXT_LENGTH:\n case InvokeErrorType.CONTENT_FILTER:\n return false;\n }\n}\n","import type { Message, ToolCall } from '../types/llm.js';\nimport type { LLMTool } from '../types/llm.js';\nimport { InvokeError, InvokeErrorType } from './errors.js';\nimport type { LLMProvider } from '../config/schema.js';\n\nexport interface OpenAIClientConfig {\n baseURL: string;\n model: string;\n apiKey?: string;\n temperature?: number;\n provider?: LLMProvider;\n}\n\nexport class OpenAIClient {\n private config: OpenAIClientConfig;\n\n constructor(config: OpenAIClientConfig) {\n this.config = config;\n }\n\n /**\n * Build auth headers based on the provider.\n * - OpenAI/Gemini/Ollama: Bearer token\n * - Anthropic: x-api-key header + anthropic-version\n */\n private buildHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n if (!this.config.apiKey) return headers;\n\n if (this.config.provider === 'anthropic') {\n headers['x-api-key'] = this.config.apiKey;\n headers['anthropic-version'] = '2023-06-01';\n } else {\n headers['Authorization'] = `Bearer ${this.config.apiKey}`;\n }\n\n return headers;\n }\n\n /**\n * Build the request body based on provider.\n * Anthropic Messages API is different from OpenAI chat completions.\n */\n private buildBody(\n messages: Message[],\n tools?: LLMTool[],\n opts?: { toolChoice?: string | { type: 'function'; function: { name: string } } },\n ): { url: string; body: Record<string, unknown> } {\n if (this.config.provider === 'anthropic') {\n return this.buildAnthropicBody(messages, tools, opts);\n }\n\n // OpenAI-compatible format (OpenAI, Gemini, Ollama all use this)\n const body: Record<string, unknown> = {\n model: this.config.model,\n messages,\n temperature: this.config.temperature ?? 0.1,\n };\n\n if (tools && tools.length > 0) {\n body.tools = tools;\n body.parallel_tool_calls = false;\n if (opts?.toolChoice) {\n body.tool_choice = typeof opts.toolChoice === 'string'\n ? opts.toolChoice\n : opts.toolChoice;\n }\n }\n\n return { url: `${this.config.baseURL}/chat/completions`, body };\n }\n\n /**\n * Build Anthropic Messages API request.\n * Converts OpenAI-style messages/tools to Anthropic format.\n */\n private buildAnthropicBody(\n messages: Message[],\n tools?: LLMTool[],\n opts?: { toolChoice?: string | { type: 'function'; function: { name: string } } },\n ): { url: string; body: Record<string, unknown> } {\n // Extract system message\n let system: string | undefined;\n const anthropicMessages: Record<string, unknown>[] = [];\n\n for (const msg of messages) {\n if (msg.role === 'system') {\n system = msg.content as string;\n } else {\n anthropicMessages.push({\n role: msg.role === 'assistant' ? 'assistant' : 'user',\n content: msg.content,\n });\n }\n }\n\n const body: Record<string, unknown> = {\n model: this.config.model,\n messages: anthropicMessages,\n max_tokens: 4096,\n temperature: this.config.temperature ?? 0.1,\n };\n\n if (system) body.system = system;\n\n // Convert OpenAI tools format to Anthropic tools format\n if (tools && tools.length > 0) {\n body.tools = tools.map((t) => {\n const fn = (t as any).function;\n return {\n name: fn.name,\n description: fn.description,\n input_schema: fn.parameters,\n };\n });\n\n if (opts?.toolChoice) {\n if (typeof opts.toolChoice === 'string') {\n body.tool_choice = opts.toolChoice === 'required'\n ? { type: 'any' }\n : { type: opts.toolChoice };\n } else {\n body.tool_choice = { type: 'tool', name: opts.toolChoice.function.name };\n }\n }\n }\n\n return { url: `${this.config.baseURL}/messages`, body };\n }\n\n /**\n * Parse Anthropic response into our unified format.\n */\n private parseAnthropicResponse(json: Record<string, unknown>): {\n toolCalls?: ToolCall[];\n content?: string;\n usage?: { promptTokens: number; completionTokens: number; totalTokens: number };\n } {\n const content = json.content as any[];\n if (!content || !Array.isArray(content)) {\n throw new InvokeError(InvokeErrorType.UNKNOWN, 'No content in Anthropic response', { rawResponse: json });\n }\n\n let textContent: string | undefined;\n const toolCalls: ToolCall[] = [];\n\n for (const block of content) {\n if (block.type === 'text') {\n textContent = block.text;\n } else if (block.type === 'tool_use') {\n toolCalls.push({\n id: block.id,\n type: 'function',\n function: {\n name: block.name,\n arguments: JSON.stringify(block.input),\n },\n });\n }\n }\n\n const usage = json.usage as Record<string, number> | undefined;\n\n return {\n toolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n content: textContent,\n usage: usage ? {\n promptTokens: usage.input_tokens ?? 0,\n completionTokens: usage.output_tokens ?? 0,\n totalTokens: (usage.input_tokens ?? 0) + (usage.output_tokens ?? 0),\n } : undefined,\n };\n }\n\n async chatCompletion(\n messages: Message[],\n tools?: LLMTool[],\n opts?: { toolChoice?: string | { type: 'function'; function: { name: string } } }\n ): Promise<{\n toolCalls?: ToolCall[];\n content?: string;\n usage?: { promptTokens: number; completionTokens: number; totalTokens: number };\n }> {\n const { url, body } = this.buildBody(messages, tools, opts);\n const headers = this.buildHeaders();\n\n let response: Response;\n try {\n response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n });\n } catch (err) {\n throw new InvokeError(InvokeErrorType.NETWORK_ERROR, `Network error: ${err}`, { rawError: err });\n }\n\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n if (response.status === 401) {\n throw new InvokeError(InvokeErrorType.AUTH_ERROR, `Authentication failed: ${text}`, { retryable: false, rawResponse: text });\n }\n if (response.status === 429) {\n throw new InvokeError(InvokeErrorType.RATE_LIMIT, `Rate limited: ${text}`, { rawResponse: text });\n }\n if (response.status >= 500) {\n throw new InvokeError(InvokeErrorType.SERVER_ERROR, `Server error ${response.status}: ${text}`, { rawResponse: text });\n }\n throw new InvokeError(InvokeErrorType.UNKNOWN, `HTTP ${response.status}: ${text}`, { rawResponse: text });\n }\n\n const json = await response.json() as Record<string, unknown>;\n\n // Route to provider-specific parser\n if (this.config.provider === 'anthropic') {\n return this.parseAnthropicResponse(json);\n }\n\n // OpenAI-compatible response parsing (OpenAI, Gemini, Ollama)\n const choice = (json.choices as any[])?.[0];\n if (!choice) {\n throw new InvokeError(InvokeErrorType.UNKNOWN, 'No choices in response', { rawResponse: json });\n }\n\n const message = choice.message;\n const finishReason = choice.finish_reason;\n\n if (finishReason === 'content_filter') {\n throw new InvokeError(InvokeErrorType.CONTENT_FILTER, 'Content filtered', { retryable: false, rawResponse: json });\n }\n\n if (finishReason === 'length') {\n throw new InvokeError(InvokeErrorType.CONTEXT_LENGTH, 'Context length exceeded', { retryable: false, rawResponse: json });\n }\n\n const usage = json.usage as Record<string, number> | undefined;\n\n return {\n toolCalls: message.tool_calls as ToolCall[] | undefined,\n content: message.content as string | undefined,\n usage: usage ? {\n promptTokens: usage.prompt_tokens ?? 0,\n completionTokens: usage.completion_tokens ?? 0,\n totalTokens: usage.total_tokens ?? 0,\n } : undefined,\n };\n }\n}\n","import type { z } from 'zod';\nimport type { LLMTool } from '../types/llm.js';\n\nexport function zodToJsonSchema(schema: z.ZodType): Record<string, unknown> {\n // Simplified Zod-to-JSON-Schema converter for common types\n if ('_def' in schema) {\n const def = (schema as any)._def;\n const typeName = def.typeName;\n\n if (typeName === 'ZodObject') {\n const shape = def.shape();\n const properties: Record<string, unknown> = {};\n const required: string[] = [];\n for (const [key, value] of Object.entries(shape)) {\n properties[key] = zodToJsonSchema(value as z.ZodType);\n if (!((value as any)._def?.typeName === 'ZodOptional')) {\n required.push(key);\n }\n }\n const result: Record<string, unknown> = { type: 'object', properties };\n if (required.length > 0) result.required = required;\n if (def.description) result.description = def.description;\n return result;\n }\n\n if (typeName === 'ZodString') {\n const result: Record<string, unknown> = { type: 'string' };\n if (def.description) result.description = def.description;\n return result;\n }\n\n if (typeName === 'ZodNumber') {\n const result: Record<string, unknown> = { type: 'number' };\n if (def.description) result.description = def.description;\n return result;\n }\n\n if (typeName === 'ZodBoolean') {\n const result: Record<string, unknown> = { type: 'boolean' };\n if (def.description) result.description = def.description;\n return result;\n }\n\n if (typeName === 'ZodEnum') {\n return { type: 'string', enum: def.values, ...(def.description ? { description: def.description } : {}) };\n }\n\n if (typeName === 'ZodArray') {\n return { type: 'array', items: zodToJsonSchema(def.type), ...(def.description ? { description: def.description } : {}) };\n }\n\n if (typeName === 'ZodOptional') {\n return zodToJsonSchema(def.innerType);\n }\n\n if (typeName === 'ZodDefault') {\n const inner = zodToJsonSchema(def.innerType);\n return { ...inner, default: def.defaultValue() };\n }\n\n if (typeName === 'ZodUnion') {\n return { oneOf: def.options.map((opt: z.ZodType) => zodToJsonSchema(opt)) };\n }\n\n if (typeName === 'ZodRecord') {\n return { type: 'object', additionalProperties: zodToJsonSchema(def.valueType) };\n }\n\n if (typeName === 'ZodLiteral') {\n return { const: def.value };\n }\n\n if (typeName === 'ZodAny') {\n return {};\n }\n }\n\n return { type: 'string' };\n}\n\nexport function zodToOpenAITool(name: string, description: string, schema: z.ZodType): LLMTool {\n return {\n type: 'function',\n function: {\n name,\n description,\n parameters: zodToJsonSchema(schema),\n },\n };\n}\n","import type { z } from 'zod';\nimport type { Message, InvokeResult, LLMTool } from '../types/llm.js';\nimport type { LLMConfig } from '../types/llm.js';\nimport { OpenAIClient } from './openai-client.js';\nimport { InvokeError, InvokeErrorType } from './errors.js';\nimport { zodToOpenAITool } from './utils.js';\n\nexport interface MacroTool {\n name: string;\n description: string;\n schema: z.ZodType;\n execute: (args: Record<string, unknown>) => Promise<string>;\n}\n\nexport class LLM {\n private client: OpenAIClient;\n private config: LLMConfig;\n\n constructor(config: LLMConfig) {\n this.config = config;\n this.client = new OpenAIClient({\n baseURL: config.baseURL,\n model: config.model,\n apiKey: config.apiKey,\n temperature: config.temperature,\n provider: config.provider as any,\n });\n }\n\n async invoke(\n messages: Message[],\n tool: MacroTool,\n abortSignal?: AbortSignal\n ): Promise<InvokeResult> {\n const openaiTool = zodToOpenAITool(tool.name, tool.description, tool.schema);\n\n return this.withRetry(async () => {\n if (abortSignal?.aborted) throw new Error('Aborted');\n\n const response = await this.client.chatCompletion(\n messages,\n [openaiTool],\n { toolChoice: { type: 'function', function: { name: tool.name } } }\n );\n\n // Extract tool call\n const toolCall = response.toolCalls?.[0];\n if (!toolCall) {\n // Try to extract from content (some models put JSON in content)\n if (response.content) {\n const extracted = extractJsonFromString(response.content);\n if (extracted) {\n const args = typeof extracted === 'string' ? JSON.parse(extracted) : extracted;\n const result = await tool.execute(args);\n return {\n toolCall: { name: tool.name, args },\n toolResult: result,\n usage: response.usage,\n };\n }\n }\n throw new InvokeError(InvokeErrorType.NO_TOOL_CALL, 'No tool call in response');\n }\n\n let args: Record<string, unknown>;\n try {\n args = JSON.parse(toolCall.function.arguments);\n } catch {\n // Try double-parse (some models double-stringify)\n try {\n args = JSON.parse(JSON.parse(toolCall.function.arguments));\n } catch {\n throw new InvokeError(InvokeErrorType.INVALID_TOOL_ARGS, `Invalid JSON in tool args: ${toolCall.function.arguments}`);\n }\n }\n\n let result: string;\n try {\n result = await tool.execute(args);\n } catch (err) {\n throw new InvokeError(InvokeErrorType.TOOL_EXECUTION_ERROR, `Tool execution failed: ${err}`, { rawError: err });\n }\n\n return {\n toolCall: { name: tool.name, args },\n toolResult: result,\n usage: response.usage,\n };\n });\n }\n\n private async withRetry<T>(fn: () => Promise<T>): Promise<T> {\n const maxRetries = this.config.maxRetries ?? 3;\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await fn();\n } catch (err) {\n lastError = err;\n if (err instanceof InvokeError && !err.retryable) throw err;\n if (err instanceof Error && err.name === 'AbortError') throw err;\n if (attempt < maxRetries) {\n await new Promise((r) => setTimeout(r, 100 * (attempt + 1)));\n }\n }\n }\n\n throw lastError;\n }\n}\n\nfunction extractJsonFromString(str: string): unknown | null {\n const start = str.indexOf('{');\n const end = str.lastIndexOf('}');\n if (start === -1 || end === -1 || end <= start) return null;\n try {\n return JSON.parse(str.slice(start, end + 1));\n } catch {\n return null;\n }\n}\n","import { z } from 'zod';\nimport type { AgentTool } from '../../types/agent.js';\nimport type { IPage } from '../../types/page.js';\n\nexport function createClickTool(page: IPage): AgentTool {\n return {\n description: 'Click on an interactive element by its index number from the page content.',\n inputSchema: z.object({\n index: z.number().describe('The index of the element to click'),\n }),\n execute: async (args) => {\n await page.click(args.index);\n return `Clicked element [${args.index}]`;\n },\n };\n}\n","import { z } from 'zod';\nimport type { AgentTool } from '../../types/agent.js';\nimport type { IPage } from '../../types/page.js';\n\nexport function createTypeTool(page: IPage): AgentTool {\n return {\n description: 'Type text into an input field identified by its index number.',\n inputSchema: z.object({\n index: z.number().describe('The index of the input element'),\n text: z.string().describe('The text to type'),\n }),\n execute: async (args) => {\n await page.typeText(args.index, args.text);\n return `Typed \"${args.text}\" into element [${args.index}]`;\n },\n };\n}\n","import { z } from 'zod';\nimport type { AgentTool } from '../../types/agent.js';\nimport type { IPage } from '../../types/page.js';\n\nexport function createScrollTool(page: IPage): AgentTool {\n return {\n description: 'Scroll the page in a given direction. Use to reveal more content.',\n inputSchema: z.object({\n direction: z.enum(['up', 'down', 'left', 'right']).describe('Scroll direction'),\n amount: z.number().optional().describe('Pixels to scroll (default 500)'),\n }),\n execute: async (args) => {\n await page.scroll(args.direction, args.amount);\n return `Scrolled ${args.direction}${args.amount ? ` ${args.amount}px` : ''}`;\n },\n };\n}\n","import { z } from 'zod';\nimport type { AgentTool } from '../../types/agent.js';\nimport type { IPage } from '../../types/page.js';\n\nexport function createSelectTool(page: IPage): AgentTool {\n return {\n description: 'Select an option from a dropdown/select element by its index.',\n inputSchema: z.object({\n index: z.number().describe('The index of the select element'),\n value: z.string().describe('The option text or value to select'),\n }),\n execute: async (args) => {\n await page.selectOption(args.index, args.value);\n return `Selected \"${args.value}\" in element [${args.index}]`;\n },\n };\n}\n","import { z } from 'zod';\nimport type { AgentTool } from '../../types/agent.js';\n\nexport function createWaitTool(): AgentTool {\n return {\n description: 'Wait for a specified number of seconds before continuing.',\n inputSchema: z.object({\n seconds: z.number().min(0.1).max(30).describe('Seconds to wait'),\n }),\n execute: async (args) => {\n await new Promise((r) => setTimeout(r, args.seconds * 1000));\n return `Waited ${args.seconds} seconds`;\n },\n };\n}\n","import { z } from 'zod';\nimport type { AgentTool } from '../../types/agent.js';\n\nexport function createDoneTool(): AgentTool {\n return {\n description: 'Signal that the task is complete. Call this when you have finished the task or cannot proceed further.',\n inputSchema: z.object({\n success: z.boolean().describe('Whether the task was completed successfully'),\n text: z.string().describe('Summary of the result or explanation of failure'),\n }),\n execute: async (args) => {\n return JSON.stringify({ done: true, success: args.success, text: args.text });\n },\n };\n}\n","import { z } from 'zod';\nimport type { AgentTool } from '../../types/agent.js';\nimport { createInterface } from 'node:readline';\n\nexport function createAskUserTool(): AgentTool {\n return {\n description: 'Ask the user a question when you need clarification or input to proceed.',\n inputSchema: z.object({\n question: z.string().describe('The question to ask the user'),\n }),\n execute: async (args) => {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n return new Promise<string>((resolve) => {\n rl.question(`\\n🤖 Agent asks: ${args.question}\\n> `, (answer) => {\n rl.close();\n resolve(`User answered: ${answer}`);\n });\n });\n },\n };\n}\n","import { z } from 'zod';\nimport type { AgentTool } from '../../types/agent.js';\nimport type { IPage } from '../../types/page.js';\n\nexport function createExecuteJsTool(page: IPage): AgentTool {\n return {\n description: 'Execute JavaScript code on the current page. Returns the result.',\n inputSchema: z.object({\n code: z.string().describe('JavaScript code to execute on the page'),\n }),\n execute: async (args) => {\n const result = await page.evaluate(args.code);\n return typeof result === 'string' ? result : JSON.stringify(result, null, 2);\n },\n };\n}\n","import type { AgentTool } from '../../types/agent.js';\nimport type { IPage } from '../../types/page.js';\nimport { createClickTool } from './click.js';\nimport { createTypeTool } from './type.js';\nimport { createScrollTool } from './scroll.js';\nimport { createSelectTool } from './select.js';\nimport { createWaitTool } from './wait.js';\nimport { createDoneTool } from './done.js';\nimport { createAskUserTool } from './ask-user.js';\nimport { createExecuteJsTool } from './execute-js.js';\n\nexport function createDefaultTools(page: IPage): Record<string, AgentTool> {\n return {\n click_element_by_index: createClickTool(page),\n input_text: createTypeTool(page),\n scroll: createScrollTool(page),\n select_dropdown_option: createSelectTool(page),\n wait: createWaitTool(),\n done: createDoneTool(),\n ask_user: createAskUserTool(),\n execute_javascript: createExecuteJsTool(page),\n };\n}\n","import { z } from 'zod';\nimport type { AgentTool } from '../types/agent.js';\nimport type { MacroTool } from '../llm/client.js';\nimport { normalizeResponse } from './auto-fixer.js';\n\nexport function packMacroTool(\n tools: Record<string, AgentTool>\n): MacroTool {\n // Build the action union schema\n const actionSchemas: z.ZodTypeAny[] = [];\n const toolNames: string[] = [];\n\n for (const [name, tool] of Object.entries(tools)) {\n toolNames.push(name);\n actionSchemas.push(\n z.object({ [name]: tool.inputSchema }).describe(tool.description)\n );\n }\n\n const actionSchema = actionSchemas.length === 1\n ? actionSchemas[0]\n : z.union(actionSchemas as [z.ZodTypeAny, z.ZodTypeAny, ...z.ZodTypeAny[]]);\n\n const macroSchema = z.object({\n evaluation_previous_goal: z.string().optional().describe('Evaluate whether the previous goal was achieved'),\n memory: z.string().optional().describe('Important information to remember for future steps'),\n next_goal: z.string().optional().describe('The next immediate goal to achieve'),\n action: actionSchema.describe('The action to take'),\n });\n\n return {\n name: 'AgentOutput',\n description: 'The agent\\'s output containing reflection and action. Must be called every step.',\n schema: macroSchema,\n execute: async (args: Record<string, unknown>) => {\n // Normalize messy LLM output\n const normalized = normalizeResponse(args, 'AgentOutput', toolNames, tools);\n const action = normalized.action as Record<string, unknown>;\n\n // Find the tool to execute\n const [toolName, toolInput] = Object.entries(action)[0];\n const tool = tools[toolName];\n\n if (!tool) {\n return `Error: Unknown tool \"${toolName}\". Available: ${toolNames.join(', ')}`;\n }\n\n try {\n const result = await tool.execute(toolInput as any);\n return result;\n } catch (err) {\n return `Error executing ${toolName}: ${err}`;\n }\n },\n };\n}\n","import type { z } from 'zod';\nimport type { AgentTool } from '../types/agent.js';\n\n/**\n * Normalize messy LLM responses into valid MacroTool output.\n * Uses tool schemas for validation instead of hardcoded tool names.\n */\nexport function normalizeResponse(\n raw: Record<string, unknown>,\n toolName: string,\n availableActions: string[],\n toolSchemas?: Record<string, AgentTool>,\n): Record<string, unknown> {\n let result = { ...raw };\n\n // Fix 1: Nested function wrapper — unwrap {type: 'function', function: {arguments}}\n if (result.type === 'function' && result.function) {\n const fn = result.function as Record<string, unknown>;\n if (typeof fn.arguments === 'string') {\n try { result = JSON.parse(fn.arguments); } catch {}\n } else if (typeof fn.arguments === 'object') {\n result = fn.arguments as Record<string, unknown>;\n }\n }\n\n // Fix 2: Double-stringified arguments\n for (const [key, value] of Object.entries(result)) {\n if (typeof value === 'string') {\n try {\n const parsed = JSON.parse(value);\n if (typeof parsed === 'object' && parsed !== null) {\n result[key] = parsed;\n }\n } catch {}\n }\n }\n\n // Fix 3: If no action field, try to infer one\n if (!result.action) {\n for (const actionName of availableActions) {\n if (actionName in result) {\n result = {\n ...result,\n action: { [actionName]: result[actionName] },\n };\n delete result[actionName];\n break;\n }\n }\n }\n\n // Fix 4: Still no action — fallback to wait\n if (!result.action) {\n result.action = { wait: { seconds: 1 } };\n }\n\n // Fix 5: Action is a string instead of object\n if (typeof result.action === 'string') {\n if (availableActions.includes(result.action)) {\n result.action = { [result.action]: {} };\n } else {\n result.action = { wait: { seconds: 1 } };\n }\n }\n\n // Fix 6: Schema-based validation & primitive coercion\n const action = result.action as Record<string, unknown>;\n for (const [name, input] of Object.entries(action)) {\n if (typeof input !== 'object' || input === null) {\n // Use schema to determine expected shape\n if (toolSchemas && toolSchemas[name]) {\n const schema = toolSchemas[name].inputSchema;\n const coerced = coercePrimitiveToSchema(input, schema);\n if (coerced !== null) {\n action[name] = coerced;\n continue;\n }\n }\n\n // Fallback: hardcoded coercion for known patterns\n if (typeof input === 'number') {\n action[name] = { index: input };\n } else if (typeof input === 'string') {\n action[name] = { text: input };\n } else {\n action[name] = {};\n }\n }\n\n // Fix 7: Validate action args against schema if available\n if (toolSchemas && toolSchemas[name] && typeof action[name] === 'object') {\n const schema = toolSchemas[name].inputSchema;\n const validation = schema.safeParse(action[name]);\n if (!validation.success) {\n // Try to fix common issues: wrong field names, missing required fields\n const fixed = attemptSchemaFix(action[name] as Record<string, unknown>, schema, validation.error);\n if (fixed) {\n action[name] = fixed;\n }\n }\n }\n }\n\n return result;\n}\n\n/**\n * Coerce a primitive value into an object matching a Zod schema.\n * Inspects the schema to find a single required field and wraps the value.\n */\nfunction coercePrimitiveToSchema(value: unknown, schema: z.ZodType): Record<string, unknown> | null {\n try {\n const def = (schema as any)._def;\n if (def?.typeName !== 'ZodObject') return null;\n\n const shape = def.shape();\n const keys = Object.keys(shape);\n\n // Single required field — wrap the primitive\n const requiredKeys = keys.filter((k) => {\n const fieldDef = (shape[k] as any)?._def;\n return fieldDef?.typeName !== 'ZodOptional';\n });\n\n if (requiredKeys.length === 1) {\n return { [requiredKeys[0]]: value };\n }\n\n // Multiple fields but value is a number — likely an index field\n const indexField = keys.find((k) => /index|idx|num|number/i.test(k));\n if (indexField && typeof value === 'number') {\n return { [indexField]: value };\n }\n\n // Value is a string — likely a text field\n const textField = keys.find((k) => /text|value|query|code|question|url/i.test(k));\n if (textField && typeof value === 'string') {\n return { [textField]: value };\n }\n } catch {}\n\n return null;\n}\n\n/**\n * Attempt to fix validation errors by mapping common mistakes.\n */\nfunction attemptSchemaFix(\n input: Record<string, unknown>,\n schema: z.ZodType,\n error: z.ZodError,\n): Record<string, unknown> | null {\n try {\n const def = (schema as any)._def;\n if (def?.typeName !== 'ZodObject') return null;\n\n const shape = def.shape();\n const expectedKeys = Object.keys(shape);\n const inputKeys = Object.keys(input);\n const fixed = { ...input };\n\n // Fix: wrong key names — try to map by position or type match\n for (const issue of error.issues) {\n if (issue.code === 'invalid_type' && issue.path.length === 1) {\n const key = String(issue.path[0]);\n const val = input[key];\n // Try type coercion\n if (issue.expected === 'number' && typeof val === 'string') {\n const num = Number(val);\n if (!isNaN(num)) fixed[key] = num;\n } else if (issue.expected === 'string' && typeof val === 'number') {\n fixed[key] = String(val);\n } else if (issue.expected === 'boolean' && typeof val === 'string') {\n fixed[key] = val === 'true';\n }\n }\n\n if (issue.code === 'unrecognized_keys') {\n // Remove unrecognized keys\n for (const k of (issue as any).keys || []) {\n delete fixed[k];\n }\n }\n }\n\n // Re-validate\n const result = schema.safeParse(fixed);\n if (result.success) return fixed;\n } catch {}\n\n return null;\n}\n\nexport function safeJsonParse(str: string): unknown {\n try {\n return JSON.parse(str);\n } catch {\n return str;\n }\n}\n\nexport function extractJsonFromString(str: string): unknown | null {\n const start = str.indexOf('{');\n const end = str.lastIndexOf('}');\n if (start === -1 || end === -1 || end <= start) return null;\n try {\n return JSON.parse(str.slice(start, end + 1));\n } catch {\n return null;\n }\n}\n","/**\n * Template expression engine for pipeline YAML.\n * Resolves ${{ expr }} expressions with context variables and filters.\n */\n\nconst EXPR_RE = /\\$\\{\\{\\s*(.*?)\\s*\\}\\}/g;\n\ninterface RenderContext {\n args: Record<string, unknown>;\n item?: unknown;\n data?: unknown;\n index?: number;\n}\n\nexport function renderTemplate(template: unknown, ctx: RenderContext): unknown {\n if (typeof template !== 'string') {\n if (typeof template === 'object' && template !== null) {\n if (Array.isArray(template)) return template.map((v) => renderTemplate(v, ctx));\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(template)) {\n result[k] = renderTemplate(v, ctx);\n }\n return result;\n }\n return template;\n }\n\n // Full expression: entire string is one expression — return raw value (not stringified)\n const fullMatch = template.match(/^\\$\\{\\{\\s*(.*?)\\s*\\}\\}$/);\n if (fullMatch) {\n return evaluateExpression(fullMatch[1], ctx);\n }\n\n // Partial: interpolate into string\n return template.replace(EXPR_RE, (_, expr) => {\n const val = evaluateExpression(expr, ctx);\n return val === null || val === undefined ? '' : String(val);\n });\n}\n\nfunction evaluateExpression(expr: string, ctx: RenderContext): unknown {\n // Handle pipe filters: expr | filter(arg)\n const parts = expr.split(/\\s*\\|\\s*/);\n let value = resolveValue(parts[0].trim(), ctx);\n\n for (let i = 1; i < parts.length; i++) {\n value = applyFilter(value, parts[i].trim());\n }\n\n return value;\n}\n\nfunction resolveValue(path: string, ctx: RenderContext): unknown {\n // Handle simple arithmetic: index + 1\n const arithMatch = path.match(/^(\\w[\\w.]*)\\s*([+\\-*])\\s*(\\d+)$/);\n if (arithMatch) {\n const base = Number(resolvePath(arithMatch[1], ctx));\n const op = arithMatch[2];\n const num = Number(arithMatch[3]);\n if (op === '+') return base + num;\n if (op === '-') return base - num;\n if (op === '*') return base * num;\n }\n\n // Handle logical OR: a || b\n const orMatch = path.match(/^(.+?)\\s*\\|\\|\\s*(.+)$/);\n if (orMatch) {\n const left = resolvePath(orMatch[1].trim(), ctx);\n if (left !== null && left !== undefined && left !== '' && left !== false) return left;\n // Right side: could be a string literal\n const right = orMatch[2].trim();\n if ((right.startsWith(\"'\") && right.endsWith(\"'\")) || (right.startsWith('\"') && right.endsWith('\"'))) {\n return right.slice(1, -1);\n }\n return resolvePath(right, ctx);\n }\n\n // String literal\n if ((path.startsWith(\"'\") && path.endsWith(\"'\")) || (path.startsWith('\"') && path.endsWith('\"'))) {\n return path.slice(1, -1);\n }\n\n // Number literal\n if (!isNaN(Number(path)) && path !== '') return Number(path);\n\n return resolvePath(path, ctx);\n}\n\nfunction resolvePath(path: string, ctx: RenderContext): unknown {\n // Resolve against context: args.*, item.*, data.*, index\n if (path === 'index') return ctx.index ?? 0;\n\n const parts = path.split('.');\n let root: unknown;\n\n if (parts[0] === 'args') {\n root = ctx.args;\n parts.shift();\n } else if (parts[0] === 'item') {\n root = ctx.item;\n parts.shift();\n } else if (parts[0] === 'data') {\n root = ctx.data;\n parts.shift();\n } else {\n // Try item first, then args, then data\n root = getNestedValue(ctx.item, parts);\n if (root !== undefined) return root;\n root = getNestedValue(ctx.args, parts);\n if (root !== undefined) return root;\n root = getNestedValue(ctx.data, parts);\n if (root !== undefined) return root;\n return undefined;\n }\n\n return getNestedValue(root, parts);\n}\n\nfunction getNestedValue(obj: unknown, parts: string[]): unknown {\n let current = obj;\n for (const part of parts) {\n if (current === null || current === undefined) return undefined;\n if (typeof current === 'object') {\n current = (current as Record<string, unknown>)[part];\n } else {\n return undefined;\n }\n }\n return current;\n}\n\nfunction applyFilter(value: unknown, filter: string): unknown {\n const match = filter.match(/^(\\w+)(?:\\((.+)\\))?$/);\n if (!match) return value;\n\n const name = match[1];\n const arg = match[2]?.replace(/^['\"]|['\"]$/g, '');\n\n switch (name) {\n case 'default':\n return value === null || value === undefined || value === '' ? arg : value;\n case 'join':\n return Array.isArray(value) ? value.join(arg || ', ') : value;\n case 'upper':\n return typeof value === 'string' ? value.toUpperCase() : value;\n case 'lower':\n return typeof value === 'string' ? value.toLowerCase() : value;\n case 'trim':\n return typeof value === 'string' ? value.trim() : value;\n case 'truncate': {\n const len = parseInt(arg || '100');\n if (typeof value === 'string' && value.length > len) return value.slice(0, len) + '...';\n return value;\n }\n case 'replace': {\n if (typeof value !== 'string' || !arg) return value;\n const [from, to] = arg.split(',').map((s) => s.trim().replace(/^['\"]|['\"]$/g, ''));\n return value.replaceAll(from, to || '');\n }\n case 'keys':\n return typeof value === 'object' && value !== null ? Object.keys(value) : [];\n case 'length':\n return Array.isArray(value) ? value.length : typeof value === 'string' ? value.length : 0;\n case 'first':\n return Array.isArray(value) ? value[0] : value;\n case 'last':\n return Array.isArray(value) ? value[value.length - 1] : value;\n case 'json':\n return JSON.stringify(value);\n case 'slugify':\n return typeof value === 'string' ? value.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '') : value;\n case 'sanitize':\n // Filename-safe: remove/replace dangerous chars\n return typeof value === 'string' ? value.replace(/[<>:\"/\\\\|?*\\x00-\\x1f]/g, '_').replace(/__+/g, '_').trim() : value;\n case 'ext': {\n // Extract file extension from URL/path\n if (typeof value !== 'string') return '';\n const extMatch = value.match(/\\.([a-zA-Z0-9]+)(?:\\?.*)?$/);\n return extMatch ? extMatch[1] : '';\n }\n case 'basename': {\n // Extract filename from URL/path\n if (typeof value !== 'string') return '';\n try { return new URL(value).pathname.split('/').pop() || ''; } catch {}\n return value.split('/').pop() || '';\n }\n default:\n return value;\n }\n}\n","import type { StepHandler } from '../types/pipeline.js';\n\nconst stepHandlers = new Map<string, StepHandler>();\n\nexport function registerStep(name: string, handler: StepHandler): void {\n stepHandlers.set(name, handler);\n}\n\nexport function getStep(name: string): StepHandler | undefined {\n return stepHandlers.get(name);\n}\n\nexport function getStepNames(): string[] {\n return [...stepHandlers.keys()];\n}\n","/**\n * Pipeline step: fetch — HTTP API requests with batch IPC optimization.\n *\n * When data is an array and URL references `item`, all per-item fetches\n * are batched into a single browser evaluate() call — eliminating N-1\n * cross-process IPC round trips.\n */\n\nimport type { PipelineContext } from '../../types/pipeline.js';\nimport { renderTemplate } from '../template.js';\nimport { registerStep } from '../registry.js';\n\n/**\n * Batch fetch: send all URLs into the browser as a single evaluate() call.\n * All fetches execute inside V8, results return as one JSON array.\n */\nasync function fetchBatchInBrowser(\n page: NonNullable<PipelineContext['page']>,\n urls: string[],\n method: string,\n headers: Record<string, string>,\n concurrency: number,\n): Promise<unknown[]> {\n const headersJs = JSON.stringify(headers);\n const urlsJs = JSON.stringify(urls);\n\n return page.evaluate<unknown[]>(`\n (async () => {\n const urls = ${urlsJs};\n const method = ${JSON.stringify(method)};\n const headers = ${headersJs};\n const concurrency = ${concurrency};\n\n const results = new Array(urls.length);\n let idx = 0;\n\n async function worker() {\n while (idx < urls.length) {\n const i = idx++;\n try {\n const resp = await fetch(urls[i], { method, headers, credentials: \"include\" });\n results[i] = await resp.json();\n } catch (e) {\n results[i] = { error: e.message };\n }\n }\n }\n\n const workers = Array.from({ length: Math.min(concurrency, urls.length) }, () => worker());\n await Promise.all(workers);\n return results;\n })()\n `);\n}\n\n/**\n * Concurrent pool for non-browser fetches.\n */\nasync function mapConcurrent<T, R>(\n items: T[],\n limit: number,\n fn: (item: T, index: number) => Promise<R>,\n): Promise<R[]> {\n const results: R[] = new Array(items.length);\n let index = 0;\n\n async function worker() {\n while (index < items.length) {\n const i = index++;\n results[i] = await fn(items[i], i);\n }\n }\n\n const workers = Array.from({ length: Math.min(limit, items.length) }, () => worker());\n await Promise.all(workers);\n return results;\n}\n\n/**\n * Single URL fetch — browser or direct.\n */\nasync function fetchSingle(\n page: PipelineContext['page'],\n url: string,\n method: string,\n headers: Record<string, string>,\n): Promise<unknown> {\n if (page) {\n const headersJs = JSON.stringify(headers);\n const urlJs = JSON.stringify(url);\n const methodJs = JSON.stringify(method);\n return page.evaluate(`\n (async () => {\n const resp = await fetch(${urlJs}, {\n method: ${methodJs}, headers: ${headersJs}, credentials: \"include\"\n });\n return await resp.json();\n })()\n `);\n }\n\n const resp = await fetch(url, { method, headers });\n return resp.json();\n}\n\nregisterStep('fetch', async (ctx: PipelineContext, params: unknown): Promise<unknown> => {\n const data = ctx.data;\n const urlOrObj = typeof params === 'string' ? params : ((params as any)?.url ?? '');\n const method = ((params as any)?.method as string) || 'GET';\n const rawHeaders: Record<string, unknown> = (params as any)?.headers ?? {};\n const rawParams: Record<string, unknown> = (params as any)?.params ?? {};\n const urlTemplate = String(urlOrObj);\n\n // Render headers\n const headers: Record<string, string> = {};\n for (const [k, v] of Object.entries(rawHeaders)) {\n headers[k] = String(renderTemplate(v, { args: ctx.args, data }));\n }\n\n // Per-item batch fetch when data is array and URL references `item`\n if (Array.isArray(data) && urlTemplate.includes('item')) {\n const concurrency = typeof (params as any)?.concurrency === 'number'\n ? (params as any).concurrency : 5;\n\n // Render all URLs upfront\n const renderedParams: Record<string, string> = {};\n for (const [k, v] of Object.entries(rawParams)) {\n renderedParams[k] = String(renderTemplate(v, { args: ctx.args, data }));\n }\n\n const urls = data.map((item: unknown, index: number) => {\n let url = String(renderTemplate(urlTemplate, { args: ctx.args, data, item, index }));\n if (Object.keys(renderedParams).length > 0) {\n const qs = new URLSearchParams(renderedParams).toString();\n url = `${url}${url.includes('?') ? '&' : '?'}${qs}`;\n }\n return url;\n });\n\n // BATCH IPC: if browser available, run all fetches in a single evaluate()\n if (ctx.page) {\n return fetchBatchInBrowser(ctx.page, urls, method.toUpperCase(), headers, concurrency);\n }\n\n // Non-browser: concurrent pool\n return mapConcurrent(urls, concurrency, async (url) => {\n return fetchSingle(null, url, method.toUpperCase(), headers);\n });\n }\n\n // Single URL fetch\n let url = String(renderTemplate(urlOrObj, { args: ctx.args, data }));\n\n // Append query params\n const renderedParams: Record<string, string> = {};\n for (const [k, v] of Object.entries(rawParams)) {\n renderedParams[k] = String(renderTemplate(v, { args: ctx.args, data }));\n }\n if (Object.keys(renderedParams).length > 0) {\n const qs = new URLSearchParams(renderedParams).toString();\n url = `${url}${url.includes('?') ? '&' : '?'}${qs}`;\n }\n\n return fetchSingle(ctx.page, url, method.toUpperCase(), headers);\n});\n","import type { PipelineContext } from '../../types/pipeline.js';\nimport { renderTemplate } from '../template.js';\nimport { registerStep } from '../registry.js';\n\nregisterStep('navigate', async (ctx: PipelineContext, params: unknown): Promise<unknown> => {\n if (!ctx.page) throw new Error('Browser page required for navigate step');\n const url = renderTemplate(params, { args: ctx.args, data: ctx.data }) as string;\n await ctx.page.goto(url);\n return ctx.data;\n});\n\nregisterStep('click', async (ctx: PipelineContext, params: unknown): Promise<unknown> => {\n if (!ctx.page) throw new Error('Browser page required for click step');\n const ref = renderTemplate(params, { args: ctx.args, data: ctx.data });\n await ctx.page.click(ref as string | number);\n return ctx.data;\n});\n\nregisterStep('type', async (ctx: PipelineContext, params: unknown): Promise<unknown> => {\n if (!ctx.page) throw new Error('Browser page required for type step');\n const p = renderTemplate(params, { args: ctx.args, data: ctx.data }) as Record<string, unknown>;\n await ctx.page.typeText(p.ref as string | number, p.text as string);\n if (p.submit) await ctx.page.pressKey('Enter');\n return ctx.data;\n});\n\nregisterStep('wait', async (ctx: PipelineContext, params: unknown): Promise<unknown> => {\n if (!ctx.page) throw new Error('Browser page required for wait step');\n const rendered = renderTemplate(params, { args: ctx.args, data: ctx.data });\n if (typeof rendered === 'number') {\n await ctx.page.wait(rendered);\n } else {\n await ctx.page.wait(rendered as { text?: string; time?: number; timeout?: number });\n }\n return ctx.data;\n});\n\nregisterStep('press', async (ctx: PipelineContext, params: unknown): Promise<unknown> => {\n if (!ctx.page) throw new Error('Browser page required for press step');\n const key = renderTemplate(params, { args: ctx.args, data: ctx.data }) as string;\n await ctx.page.pressKey(key);\n return ctx.data;\n});\n\nregisterStep('snapshot', async (ctx: PipelineContext, _params: unknown): Promise<unknown> => {\n if (!ctx.page) throw new Error('Browser page required for snapshot step');\n return ctx.page.snapshot();\n});\n\nregisterStep('evaluate', async (ctx: PipelineContext, params: unknown): Promise<unknown> => {\n if (!ctx.page) throw new Error('Browser page required for evaluate step');\n const js = renderTemplate(params, { args: ctx.args, data: ctx.data }) as string;\n const result = await ctx.page.evaluate(js);\n // Auto-parse JSON strings\n if (typeof result === 'string') {\n try { return JSON.parse(result); } catch { return result; }\n }\n return result;\n});\n","import type { PipelineContext } from '../../types/pipeline.js';\nimport { renderTemplate } from '../template.js';\nimport { registerStep } from '../registry.js';\n\nregisterStep('select', async (ctx: PipelineContext, params: unknown): Promise<unknown> => {\n const path = renderTemplate(params, { args: ctx.args, data: ctx.data }) as string;\n const parts = path.split('.');\n let current: unknown = ctx.data;\n for (const part of parts) {\n if (current === null || current === undefined) return undefined;\n\n // Array index: items[0], data[2]\n const indexMatch = part.match(/^(\\w+)\\[(\\d+)\\]$/);\n if (indexMatch) {\n current = (current as Record<string, unknown>)[indexMatch[1]];\n if (Array.isArray(current)) current = current[Number(indexMatch[2])];\n else return undefined;\n continue;\n }\n\n // Wildcard: items[*].title → flatten array\n const wildcardMatch = part.match(/^(\\w+)\\[\\*\\]$/);\n if (wildcardMatch) {\n current = (current as Record<string, unknown>)[wildcardMatch[1]];\n if (!Array.isArray(current)) return undefined;\n // If there are more parts, map into each item\n const remaining = parts.slice(parts.indexOf(part) + 1);\n if (remaining.length > 0) {\n return current.map((item) => {\n let val: unknown = item;\n for (const r of remaining) {\n if (val === null || val === undefined) return undefined;\n val = (val as Record<string, unknown>)[r];\n }\n return val;\n });\n }\n continue;\n }\n\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n});\n\nregisterStep('map', async (ctx: PipelineContext, params: unknown): Promise<unknown> => {\n if (!Array.isArray(ctx.data)) throw new Error('map requires array data');\n const template = params as Record<string, unknown>;\n return ctx.data.map((item, index) =>\n renderTemplate(template, { args: ctx.args, item, data: ctx.data, index })\n );\n});\n\nregisterStep('filter', async (ctx: PipelineContext, params: unknown): Promise<unknown> => {\n if (!Array.isArray(ctx.data)) throw new Error('filter requires array data');\n const expr = params as string;\n return ctx.data.filter((item, index) => {\n const result = renderTemplate(`\\${{ ${expr} }}`, { args: ctx.args, item, data: ctx.data, index });\n return Boolean(result);\n });\n});\n\nregisterStep('sort', async (ctx: PipelineContext, params: unknown): Promise<unknown> => {\n if (!Array.isArray(ctx.data)) throw new Error('sort requires array data');\n const p = params as { by: string; order?: 'asc' | 'desc' };\n const sorted = [...ctx.data].sort((a, b) => {\n const va = (a as Record<string, unknown>)[p.by];\n const vb = (b as Record<string, unknown>)[p.by];\n if (typeof va === 'number' && typeof vb === 'number') return va - vb;\n return String(va).localeCompare(String(vb));\n });\n return p.order === 'desc' ? sorted.reverse() : sorted;\n});\n\nregisterStep('limit', async (ctx: PipelineContext, params: unknown): Promise<unknown> => {\n if (!Array.isArray(ctx.data)) return ctx.data;\n const n = renderTemplate(params, { args: ctx.args, data: ctx.data });\n return ctx.data.slice(0, Number(n) || 20);\n});\n","import type { PipelineContext } from '../../types/pipeline.js';\nimport { renderTemplate } from '../template.js';\nimport { registerStep } from '../registry.js';\n\nregisterStep('intercept', async (ctx: PipelineContext, params: unknown): Promise<unknown> => {\n if (!ctx.page) throw new Error('Browser page required for intercept step');\n const p = params as { pattern: string; trigger?: string; select?: string; timeout?: number };\n const pattern = renderTemplate(p.pattern, { args: ctx.args, data: ctx.data }) as string;\n\n await ctx.page.installInterceptor(pattern);\n\n // Trigger action\n if (p.trigger) {\n const trigger = renderTemplate(p.trigger, { args: ctx.args, data: ctx.data }) as string;\n const [action, value] = trigger.split(':');\n switch (action) {\n case 'navigate': await ctx.page.goto(value); break;\n case 'click': await ctx.page.click(value); break;\n case 'evaluate': await ctx.page.evaluate(value); break;\n case 'scroll': await ctx.page.scroll('down'); break;\n }\n }\n\n // Wait for intercepted requests\n const timeout = p.timeout || 10;\n await ctx.page.wait(timeout);\n\n const requests = await ctx.page.getInterceptedRequests();\n if (requests.length === 0) return ctx.data;\n\n let result: unknown = requests.map((r: any) => r.body);\n if (result && Array.isArray(result) && result.length === 1) result = result[0];\n\n // Optional sub-selection\n if (p.select && result) {\n const parts = p.select.split('.');\n let current: unknown = result;\n for (const part of parts) {\n if (current && typeof current === 'object') {\n current = (current as Record<string, unknown>)[part];\n }\n }\n result = current;\n }\n\n return result;\n});\n","/**\n * Pipeline step: download — files, videos, documents.\n *\n * Features:\n * - HTTP download with concurrency control\n * - yt-dlp integration for video platforms\n * - Browser cookie forwarding (Netscape format)\n * - Document extraction (HTML/Markdown/JSON)\n * - Progress tracking\n * - Skip-existing support\n * - Filename templating\n */\n\nimport { writeFileSync, mkdirSync, existsSync, readFileSync } from 'node:fs';\nimport { join, basename } from 'node:path';\nimport { execSync } from 'node:child_process';\nimport { tmpdir } from 'node:os';\nimport type { PipelineContext } from '../../types/pipeline.js';\nimport { renderTemplate } from '../template.js';\nimport { registerStep } from '../registry.js';\n\ninterface DownloadParams {\n url?: string;\n dir?: string;\n filename?: string;\n concurrency?: number;\n skip_existing?: boolean;\n timeout?: number;\n // yt-dlp options\n video?: boolean;\n format?: string;\n // Document extraction\n content?: 'html' | 'markdown' | 'json' | 'text';\n metadata?: Record<string, unknown>;\n}\n\ninterface DownloadResult {\n url: string;\n file: string;\n success: boolean;\n size?: number;\n error?: string;\n content?: string;\n}\n\nclass DownloadProgressTracker {\n private total: number;\n private completed = 0;\n private failed = 0;\n private totalBytes = 0;\n\n constructor(total: number) { this.total = total; }\n\n success(bytes: number) {\n this.completed++;\n this.totalBytes += bytes;\n }\n\n fail() {\n this.completed++;\n this.failed++;\n }\n\n summary(): string {\n return `Downloaded ${this.completed - this.failed}/${this.total} files (${formatBytes(this.totalBytes)})${this.failed > 0 ? `, ${this.failed} failed` : ''}`;\n }\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes}B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;\n}\n\n/**\n * Export browser cookies in Netscape format for yt-dlp.\n */\nasync function exportCookiesNetscape(ctx: PipelineContext, domain: string): Promise<string | null> {\n if (!ctx.page) return null;\n try {\n const cookies = await ctx.page.getCookies({ domain });\n if (cookies.length === 0) return null;\n\n const lines = ['# Netscape HTTP Cookie File'];\n for (const c of cookies) {\n const httpOnly = c.httpOnly ? 'TRUE' : 'FALSE';\n const secure = c.secure ? 'TRUE' : 'FALSE';\n const expires = c.expires ? Math.floor(c.expires) : 0;\n lines.push(`${c.domain || domain}\\tTRUE\\t${c.path || '/'}\\t${secure}\\t${expires}\\t${c.name}\\t${c.value}`);\n }\n\n const tmpFile = join(tmpdir(), `lobster-cookies-${Date.now()}.txt`);\n writeFileSync(tmpFile, lines.join('\\n'));\n return tmpFile;\n } catch {\n return null;\n }\n}\n\n/**\n * Check if yt-dlp is available.\n */\nfunction hasYtDlp(): boolean {\n try {\n execSync('yt-dlp --version', { stdio: 'pipe' });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Download a video using yt-dlp.\n */\nfunction downloadWithYtDlp(url: string, dir: string, opts: {\n format?: string;\n cookieFile?: string | null;\n filename?: string;\n}): DownloadResult {\n const args = ['yt-dlp', '-o', join(dir, opts.filename || '%(title)s.%(ext)s')];\n\n if (opts.format) args.push('-f', opts.format);\n if (opts.cookieFile) args.push('--cookies', opts.cookieFile);\n args.push('--no-warnings', '--no-progress', url);\n\n try {\n execSync(args.join(' '), { stdio: 'pipe', timeout: 300000 });\n return { url, file: dir, success: true };\n } catch (err: any) {\n return { url, file: '', success: false, error: err.message?.slice(0, 200) };\n }\n}\n\n/**\n * Concurrent download worker pool.\n */\nasync function downloadPool<T>(\n items: T[],\n concurrency: number,\n fn: (item: T, index: number) => Promise<DownloadResult>,\n): Promise<DownloadResult[]> {\n const results: DownloadResult[] = new Array(items.length);\n let idx = 0;\n\n async function worker() {\n while (idx < items.length) {\n const i = idx++;\n results[i] = await fn(items[i], i);\n }\n }\n\n const workers = Array.from(\n { length: Math.min(concurrency, items.length) },\n () => worker(),\n );\n await Promise.all(workers);\n return results;\n}\n\nregisterStep('download', async (ctx: PipelineContext, params: unknown): Promise<unknown> => {\n const p = params as DownloadParams;\n const dir = renderTemplate(p.dir || './downloads', { args: ctx.args, data: ctx.data }) as string;\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n\n const concurrency = p.concurrency || 3;\n const skipExisting = p.skip_existing ?? false;\n const timeout = (p.timeout || 60) * 1000;\n\n // Collect URLs\n const items: { url: string; item?: unknown; index: number }[] = [];\n if (p.url) {\n items.push({\n url: renderTemplate(p.url, { args: ctx.args, data: ctx.data }) as string,\n index: 0,\n });\n } else if (Array.isArray(ctx.data)) {\n for (let i = 0; i < (ctx.data as unknown[]).length; i++) {\n const item = (ctx.data as unknown[])[i];\n const url = typeof item === 'string'\n ? item\n : (item as Record<string, unknown>).url as string;\n if (url) items.push({ url, item, index: i });\n }\n }\n\n if (items.length === 0) return [];\n\n const tracker = new DownloadProgressTracker(items.length);\n\n // ── Video download path (yt-dlp) ──\n if (p.video) {\n if (!hasYtDlp()) {\n throw new Error('yt-dlp not found. Install: brew install yt-dlp (mac) or pip install yt-dlp');\n }\n\n const cookieFile = await exportCookiesNetscape(ctx, new URL(items[0].url).hostname);\n\n const results = await downloadPool(items, Math.min(concurrency, 2), async (entry) => {\n const result = downloadWithYtDlp(entry.url, dir, {\n format: p.format,\n cookieFile,\n filename: p.filename\n ? renderTemplate(p.filename, { args: ctx.args, item: entry.item, data: ctx.data, index: entry.index }) as string\n : undefined,\n });\n if (result.success) tracker.success(0);\n else tracker.fail();\n return result;\n });\n\n // Clean up cookie file\n if (cookieFile) try { require('fs').unlinkSync(cookieFile); } catch {}\n\n if (ctx.debug) console.log(tracker.summary());\n return results;\n }\n\n // ── Document extraction path ──\n if (p.content) {\n const results = await downloadPool(items, concurrency, async (entry) => {\n try {\n const resp = await fetch(entry.url, {\n signal: AbortSignal.timeout(timeout),\n });\n if (!resp.ok) return { url: entry.url, file: '', success: false, error: `HTTP ${resp.status}` };\n\n let content: string;\n const html = await resp.text();\n\n if (p.content === 'html') {\n content = html;\n } else if (p.content === 'text') {\n // Strip tags\n content = html.replace(/<[^>]+>/g, ' ').replace(/\\s+/g, ' ').trim();\n } else if (p.content === 'json') {\n try { content = JSON.stringify(JSON.parse(html), null, 2); } catch { content = html; }\n } else {\n // markdown — basic conversion\n content = html\n .replace(/<h[1-6][^>]*>(.*?)<\\/h[1-6]>/gi, '\\n## $1\\n')\n .replace(/<p[^>]*>(.*?)<\\/p>/gi, '\\n$1\\n')\n .replace(/<a[^>]*href=\"([^\"]*)\"[^>]*>(.*?)<\\/a>/gi, '[$2]($1)')\n .replace(/<[^>]+>/g, '')\n .replace(/\\n{3,}/g, '\\n\\n')\n .trim();\n }\n\n // Save to file\n const filename = p.filename\n ? renderTemplate(p.filename, { args: ctx.args, item: entry.item, data: ctx.data, index: entry.index }) as string\n : basename(new URL(entry.url).pathname).replace(/\\.[^.]+$/, '') + (p.content === 'json' ? '.json' : '.md');\n const filepath = join(dir, filename);\n\n // Prepend metadata if provided\n if (p.metadata) {\n const meta = renderTemplate(p.metadata, { args: ctx.args, item: entry.item, data: ctx.data, index: entry.index }) as Record<string, unknown>;\n const header = Object.entries(meta).map(([k, v]) => `${k}: ${v}`).join('\\n');\n content = `---\\n${header}\\n---\\n\\n${content}`;\n }\n\n writeFileSync(filepath, content, 'utf-8');\n tracker.success(Buffer.byteLength(content));\n return { url: entry.url, file: filepath, success: true, size: Buffer.byteLength(content), content: content.slice(0, 200) };\n } catch (err: any) {\n tracker.fail();\n return { url: entry.url, file: '', success: false, error: err.message };\n }\n });\n\n if (ctx.debug) console.log(tracker.summary());\n return results;\n }\n\n // ── Standard HTTP download path ──\n const results = await downloadPool(items, concurrency, async (entry) => {\n try {\n const filename = p.filename\n ? renderTemplate(p.filename, { args: ctx.args, item: entry.item, data: ctx.data, index: entry.index }) as string\n : decodeURIComponent(basename(new URL(entry.url).pathname)) || `download-${entry.index}`;\n const filepath = join(dir, filename);\n\n if (skipExisting && existsSync(filepath)) {\n tracker.success(0);\n return { url: entry.url, file: filepath, success: true, size: 0 };\n }\n\n const resp = await fetch(entry.url, {\n signal: AbortSignal.timeout(timeout),\n });\n if (!resp.ok) {\n tracker.fail();\n return { url: entry.url, file: '', success: false, error: `HTTP ${resp.status}` };\n }\n\n const buffer = Buffer.from(await resp.arrayBuffer());\n writeFileSync(filepath, buffer);\n tracker.success(buffer.length);\n return { url: entry.url, file: filepath, success: true, size: buffer.length };\n } catch (err: any) {\n tracker.fail();\n return { url: entry.url, file: '', success: false, error: err.message };\n }\n });\n\n if (ctx.debug) console.log(tracker.summary());\n return results;\n});\n","/**\n * Pipeline step: tap — Vue store action bridge.\n *\n * Calls a Pinia/Vuex store action inside the browser and intercepts\n * the resulting network request to capture the response.\n *\n * This is the most powerful data extraction method for Vue apps — it\n * triggers the app's own data fetching logic and captures the result.\n *\n * Usage in YAML pipeline:\n * - tap:\n * store: searchStore\n * action: fetchResults\n * capture: /api/search\n * args:\n * - ${{ args.query }}\n * - page: 1\n * timeout: 5\n * select: data.items\n */\n\nimport type { PipelineContext } from '../../types/pipeline.js';\nimport { renderTemplate } from '../template.js';\nimport { registerStep } from '../registry.js';\n\ninterface TapParams {\n store: string;\n action: string;\n capture: string;\n args?: unknown[];\n timeout?: number;\n select?: string;\n}\n\nregisterStep('tap', async (ctx: PipelineContext, params: unknown): Promise<unknown> => {\n if (!ctx.page) throw new Error('Browser page required for tap step');\n\n const p = renderTemplate(params, { args: ctx.args, data: ctx.data }) as TapParams;\n const storeName = p.store;\n const actionName = p.action;\n const capturePattern = p.capture;\n const actionArgs = p.args || [];\n const timeoutSec = p.timeout || 5;\n const selectPath = p.select;\n\n // Build a self-contained JS block that:\n // 1. Patches fetch/XHR to intercept matching responses\n // 2. Finds the Pinia/Vuex store\n // 3. Calls the action with provided args\n // 4. Waits for the intercepted response\n // 5. Restores original fetch/XHR\n const result = await ctx.page.evaluate<unknown>(`\n (async () => {\n let captured = null;\n let captureResolve;\n const capturePromise = new Promise(r => { captureResolve = r; });\n const capturePattern = ${JSON.stringify(capturePattern)};\n const timeoutMs = ${timeoutSec * 1000};\n\n // 1. Patch fetch\n const origFetch = window.fetch;\n window.fetch = async function(...args) {\n const resp = await origFetch.apply(this, args);\n try {\n const url = typeof args[0] === 'string' ? args[0] : args[0]?.url || '';\n if (url.includes(capturePattern) && !captured) {\n captured = await resp.clone().json();\n captureResolve();\n }\n } catch {}\n return resp;\n };\n\n // 2. Patch XHR\n const origSend = XMLHttpRequest.prototype.send;\n const origOpen = XMLHttpRequest.prototype.open;\n XMLHttpRequest.prototype.open = function(method, url, ...rest) {\n this.__tapUrl = url;\n return origOpen.call(this, method, url, ...rest);\n };\n XMLHttpRequest.prototype.send = function(...args) {\n this.addEventListener('load', function() {\n if (this.__tapUrl?.includes(capturePattern) && !captured) {\n try {\n captured = JSON.parse(this.responseText);\n captureResolve();\n } catch {}\n }\n });\n return origSend.apply(this, args);\n };\n\n try {\n // 3. Find the store\n const app = document.querySelector('#app');\n let store = null;\n\n // Try Pinia via __vue_app__\n if (app?.__vue_app__) {\n const pinia = app.__vue_app__.config?.globalProperties?.$pinia;\n if (pinia?._s) {\n store = pinia._s.get(${JSON.stringify(storeName)});\n }\n // Try Vuex\n if (!store) {\n const vuex = app.__vue_app__.config?.globalProperties?.$store;\n if (vuex) store = vuex;\n }\n }\n\n // Fallback: global pinia\n if (!store && window.__pinia?._s) {\n store = window.__pinia._s.get(${JSON.stringify(storeName)});\n }\n\n if (!store) {\n return { error: 'Store not found: ' + ${JSON.stringify(storeName)} };\n }\n\n // 4. Call the action\n const actionFn = store[${JSON.stringify(actionName)}];\n if (typeof actionFn !== 'function') {\n return { error: 'Action not found: ' + ${JSON.stringify(actionName)} };\n }\n\n await actionFn.apply(store, ${JSON.stringify(actionArgs)});\n\n // 5. Wait for capture\n if (!captured) {\n await Promise.race([\n capturePromise,\n new Promise(r => setTimeout(r, timeoutMs)),\n ]);\n }\n } finally {\n // 6. Restore originals\n window.fetch = origFetch;\n XMLHttpRequest.prototype.send = origSend;\n XMLHttpRequest.prototype.open = origOpen;\n }\n\n return captured;\n })()\n `);\n\n if (!result) return null;\n if ((result as any)?.error) {\n throw new Error((result as any).error);\n }\n\n // Apply select path if specified (e.g., \"data.items\")\n if (selectPath) {\n let current: unknown = result;\n for (const part of selectPath.split('.')) {\n if (current === null || current === undefined) return null;\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n }\n\n return result;\n});\n","import type { IPage } from '../types/page.js';\nimport type { PipelineContext, PipelineStepDef } from '../types/pipeline.js';\nimport { getStep } from './registry.js';\nimport { log } from '../utils/logger.js';\n\nexport async function executePipeline(\n steps: PipelineStepDef[],\n page: IPage | null,\n args: Record<string, unknown>,\n debug = false\n): Promise<unknown> {\n const ctx: PipelineContext = { page, args, data: null, debug };\n\n for (let i = 0; i < steps.length; i++) {\n const stepDef = steps[i];\n const [stepName, params] = Object.entries(stepDef)[0];\n\n const handler = getStep(stepName);\n if (!handler) {\n throw new Error(`Unknown pipeline step: ${stepName}`);\n }\n\n if (debug) {\n log.step(i + 1, `${stepName}`);\n }\n\n ctx.data = await handler(ctx, params);\n\n if (debug && ctx.data !== undefined) {\n const preview = JSON.stringify(ctx.data)?.slice(0, 200);\n log.dim(` → ${preview}...`);\n }\n }\n\n return ctx.data;\n}\n","export function runWithTimeout<T>(\n promise: Promise<T>,\n timeoutMs: number,\n label = 'Operation'\n): Promise<T> {\n return new Promise((resolve, reject) => {\n const timer = setTimeout(\n () => reject(new Error(`${label} timed out after ${timeoutMs}ms`)),\n timeoutMs\n );\n promise\n .then((result) => { clearTimeout(timer); resolve(result); })\n .catch((err) => { clearTimeout(timer); reject(err); });\n });\n}\n\nexport function waitFor(seconds: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, seconds * 1000));\n}\n","import type { ExecutionRequest } from '../types/router.js';\nimport type { ExecutionResult } from '../types/agent.js';\nimport type { OutputFormat } from '../types/router.js';\nimport { ExecutionLevel } from '../types/router.js';\nimport { makeRoutingDecision } from './decision.js';\nimport { directFetch } from '../http/index.js';\nimport { BrowserManager } from '../browser/manager.js';\nimport { PuppeteerPage } from '../browser/page-adapter.js';\nimport { AgentCore } from '../agent/core.js';\nimport { executePipeline } from '../pipeline/index.js';\nimport type { LobsterConfig } from '../config/index.js';\nimport { log } from '../utils/logger.js';\nimport { runWithTimeout } from '../utils/timeout.js';\nimport { Strategy } from '../types/adapter.js';\n\nexport class SmartRouter {\n private config: LobsterConfig;\n private browserManager: BrowserManager;\n\n constructor(config: LobsterConfig) {\n this.config = config;\n this.browserManager = new BrowserManager({\n executablePath: config.browser.executablePath || undefined,\n headless: config.browser.headless,\n cdpEndpoint: config.browser.cdpEndpoint || undefined,\n });\n }\n\n async execute(request: ExecutionRequest): Promise<{ data: unknown; format: OutputFormat }> {\n const decision = makeRoutingDecision(request);\n log.debug(`Routing: Level ${ExecutionLevel[decision.level]} — ${decision.reason}`);\n\n try {\n switch (decision.level) {\n case ExecutionLevel.HTTP:\n return await this.executeHttp(request);\n\n case ExecutionLevel.ADAPTER:\n return await this.executeAdapter(request, decision);\n\n case ExecutionLevel.BROWSER:\n case ExecutionLevel.AGENT:\n return await this.executeAgent(request);\n }\n } catch (err) {\n // Escalation: if current level fails, try next\n if (decision.level < ExecutionLevel.AGENT) {\n log.warn(`Level ${ExecutionLevel[decision.level]} failed, escalating...`);\n return this.execute({\n ...request,\n task: request.task || `Fetch content from ${request.url}`,\n });\n }\n throw err;\n }\n }\n\n private async executeHttp(request: ExecutionRequest): Promise<{ data: unknown; format: OutputFormat }> {\n if (!request.url) throw new Error('URL required for HTTP execution');\n const result = await directFetch(request.url);\n return { data: result.body, format: request.format || 'json' };\n }\n\n private async executeAdapter(\n request: ExecutionRequest,\n decision: ReturnType<typeof makeRoutingDecision>\n ): Promise<{ data: unknown; format: OutputFormat }> {\n const adapter = decision.adapter!;\n const args = request.args || {};\n\n // Apply defaults\n for (const arg of adapter.args) {\n if (args[arg.name] === undefined && arg.default !== undefined) {\n args[arg.name] = arg.default;\n }\n }\n\n let data: unknown;\n\n if (adapter.pipeline) {\n // Pipeline execution\n let page = null;\n if (adapter.browser !== false && adapter.strategy !== Strategy.PUBLIC) {\n const rawPage = await this.browserManager.newPage();\n page = new PuppeteerPage(rawPage);\n if (adapter.domain) {\n await page.goto(`https://${adapter.domain}`);\n }\n }\n\n try {\n data = await executePipeline(adapter.pipeline, page, args);\n } finally {\n if (page) await page.close();\n }\n } else if (adapter.func) {\n // Function execution\n const rawPage = await this.browserManager.newPage();\n const page = new PuppeteerPage(rawPage);\n\n try {\n if (adapter.domain) {\n await page.goto(`https://${adapter.domain}`);\n }\n data = await runWithTimeout(\n adapter.func(page, args),\n (adapter.timeoutSeconds || this.config.browser.commandTimeout) * 1000,\n `${adapter.site}/${adapter.name}`\n );\n } finally {\n await page.close();\n }\n } else {\n throw new Error(`Adapter ${adapter.site}/${adapter.name} has neither func nor pipeline`);\n }\n\n return { data, format: request.format || 'table' };\n }\n\n private async executeAgent(request: ExecutionRequest): Promise<{ data: unknown; format: OutputFormat }> {\n if (!this.config.llm.apiKey) {\n throw new Error('LLM API key required for agent mode. Run: lobster config set llm.apiKey <key>');\n }\n\n const rawPage = await this.browserManager.newPage();\n const page = new PuppeteerPage(rawPage);\n\n try {\n if (request.url) {\n await page.goto(request.url);\n }\n\n const agent = new AgentCore(page, {\n llm: this.config.llm,\n maxSteps: this.config.agent.maxSteps,\n stepDelay: this.config.agent.stepDelay,\n });\n\n const task = request.task || `Extract content from ${request.url}`;\n const result = await agent.execute(task);\n\n return { data: result.data, format: request.format || 'json' };\n } finally {\n await page.close();\n }\n }\n\n async close(): Promise<void> {\n await this.browserManager.close();\n }\n}\n"],"mappings":"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AAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACzBxB,IAAM,uBAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACE7B,IAAM,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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","names":["ExecutionLevel","el","args","result","z","z","z","z","z","z","z","z","z","renderedParams","url","existsSync","join","join","existsSync","results"]}
@@ -0,0 +1,23 @@
1
+ // src/types/adapter.ts
2
+ var Strategy = /* @__PURE__ */ ((Strategy2) => {
3
+ Strategy2["PUBLIC"] = "public";
4
+ Strategy2["COOKIE"] = "cookie";
5
+ Strategy2["HEADER"] = "header";
6
+ Strategy2["INTERCEPT"] = "intercept";
7
+ Strategy2["UI"] = "ui";
8
+ return Strategy2;
9
+ })(Strategy || {});
10
+
11
+ // src/types/router.ts
12
+ var ExecutionLevel = /* @__PURE__ */ ((ExecutionLevel2) => {
13
+ ExecutionLevel2[ExecutionLevel2["HTTP"] = 0] = "HTTP";
14
+ ExecutionLevel2[ExecutionLevel2["BROWSER"] = 1] = "BROWSER";
15
+ ExecutionLevel2[ExecutionLevel2["ADAPTER"] = 2] = "ADAPTER";
16
+ ExecutionLevel2[ExecutionLevel2["AGENT"] = 3] = "AGENT";
17
+ return ExecutionLevel2;
18
+ })(ExecutionLevel || {});
19
+ export {
20
+ ExecutionLevel,
21
+ Strategy
22
+ };
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/types/adapter.ts","../../src/types/router.ts"],"sourcesContent":["import type { IPage } from './page.js';\n\nexport enum Strategy {\n PUBLIC = 'public',\n COOKIE = 'cookie',\n HEADER = 'header',\n INTERCEPT = 'intercept',\n UI = 'ui',\n}\n\nexport interface Arg {\n name: string;\n type?: 'string' | 'int' | 'float' | 'boolean';\n default?: unknown;\n required?: boolean;\n positional?: boolean;\n help?: string;\n choices?: string[];\n}\n\nexport interface Adapter {\n site: string;\n name: string;\n description: string;\n domain?: string;\n strategy: Strategy;\n browser: boolean;\n args: Arg[];\n columns?: string[];\n func?: (page: IPage, kwargs: Record<string, unknown>) => Promise<unknown>;\n pipeline?: Record<string, unknown>[];\n timeoutSeconds?: number;\n navigateBefore?: boolean | string;\n}\n","import type { Adapter } from './adapter.js';\n\nexport enum ExecutionLevel {\n HTTP = 0,\n BROWSER = 1,\n ADAPTER = 2,\n AGENT = 3,\n}\n\nexport type OutputFormat = 'table' | 'json' | 'yaml' | 'markdown' | 'csv';\n\nexport interface RoutingDecision {\n level: ExecutionLevel;\n reason: string;\n adapter?: Adapter;\n}\n\nexport interface ExecutionRequest {\n task: string;\n url?: string;\n site?: string;\n command?: string;\n args?: Record<string, unknown>;\n format?: OutputFormat;\n}\n"],"mappings":";AAEO,IAAK,WAAL,kBAAKA,cAAL;AACL,EAAAA,UAAA,YAAS;AACT,EAAAA,UAAA,YAAS;AACT,EAAAA,UAAA,YAAS;AACT,EAAAA,UAAA,eAAY;AACZ,EAAAA,UAAA,QAAK;AALK,SAAAA;AAAA,GAAA;;;ACAL,IAAK,iBAAL,kBAAKC,oBAAL;AACL,EAAAA,gCAAA,UAAO,KAAP;AACA,EAAAA,gCAAA,aAAU,KAAV;AACA,EAAAA,gCAAA,aAAU,KAAV;AACA,EAAAA,gCAAA,WAAQ,KAAR;AAJU,SAAAA;AAAA,GAAA;","names":["Strategy","ExecutionLevel"]}
package/logo.svg ADDED
@@ -0,0 +1,11 @@
1
+ <svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <rect width="100" height="100" rx="22" fill="url(#grad)"/>
3
+ <path d="M30 68V32h8v28h18v8H30z" fill="#0c0c0c"/>
4
+ <circle cx="72" cy="36" r="6" fill="#0c0c0c"/>
5
+ <defs>
6
+ <linearGradient id="grad" x1="0" y1="0" x2="100" y2="100">
7
+ <stop stop-color="#c9a84c"/>
8
+ <stop offset="1" stop-color="#e8c964"/>
9
+ </linearGradient>
10
+ </defs>
11
+ </svg>